Side-Effecting Tools and Constraints
Side-Effecting Operations and System State
In software engineering, a side effect is any operation that modifies the state of the system or external environment. Common examples include writing to a database, updating a file, sending an email, or processing a credit card transaction. Exposing these operations to an autonomous agent loop introduces risk, as the execution of these actions has real-world financial, operational, or security implications.
Because large language models are probabilistic rather than deterministic, they cannot be trusted to self-regulate side effects. Exposing side-effecting operations requires a strict security boundary that separates reasoning from execution.
Prompts vs. Hard Code Constraints
A common mistake in agent development is relying on prompt-based safety rules (e.g., instructing the model: "Do not issue refunds larger than $100"). While prompt instructions establish guidelines, they are susceptible to:
- Prompt Injection: Adversarial user inputs that manipulate the agent into ignoring its system prompt constraints.
- Reasoning Failures: The model overlooking instructions when dealing with complex, multi-turn contexts.
[!WARNING] Never rely on prompts to enforce business invariants or security limits.
Business limits and safety invariants must be hardcoded directly into the tool's implementation inside the hosting application. The execution environment must validate parameters, enforce limits, and throw explicit errors if bounds are exceeded, returning those error signals back to the model.
Security Boundaries in Side Effects
The diagram below illustrates how code invariants protect the system state from unauthorized model actions:
- Model Attempt: The model attempts to execute a tool call that violates prompt guidelines (e.g., attempting a $1,000 refund).
- Native Guard: The application intercepts the request. The tool's native Python code evaluates the parameters and throws a parameter validation exception before modifying the system database.
- Error Recovery: The error message is passed back to the model, which is forced to handle the failure and report the system boundary to the user.
Interactive Playground: Enforcing Refund Limits
The following playground implements a refund execution tool with a hardcoded $100 limit. When the customer requests a $1,000 refund, the language model attempts the tool execution. The Python environment intercepts the parameter, raises an exception, blocks the write, and returns the error message to the model for graceful recovery.
Notice how the model attempts to invoke process_refund with an amount of $1,000, despite the system prompt rule. Because the guardrail was written in native Python, the write was blocked and a structured error was raised. The model processes the error details ("exceeds the maximum system authorization threshold of $100") and communicates the limitation to the customer.