Generative AI Architecture · Part 7 of 9
AI Agents in Production
The reasoning loop is the easy part. Deciding what it's allowed to do is the rest of the job.
Planning, tools, actions, memory, orchestration
An agent's planning is the model deciding, from the current state of a task, what to do next. Tools are the external functions it can request be run on its behalf; actions are those requests actually being carried out. Memory is whatever state persists across steps or across sessions, from the running transcript of the current task to longer-term storage the agent can write to and later retrieve. Orchestration is the surrounding system that ties all of this together: routing between multiple agents, retrying failed tool calls, and enforcing the rules that follow.
The loop, with the piece that isn't the model
flowchart TD
A[User request] --> B[Model reasoning]
B --> C[Tool selection]
C --> D{Authorization}
D -- allowed --> E[Execution]
D -- denied --> B
E --> F[Observation]
F --> B
B --> G[Result]
Every box in that loop except one is the model, or code that mechanically feeds the model's output back into itself. Authorization is the one box that must not be the model. A model can request that an action happen; whether it's allowed to happen is a decision made by code outside the model, using rules the model doesn't get to set or override. A model that decides for itself whether its own request is acceptable is describing what it already did, which is not authorization.
Designing the authorization boundary
A few concrete practices make that boundary enforceable:
- Tool schemas. Every tool an agent can call should have an explicit schema: exact parameters, types, and allowed values. A tool that accepts a free-text SQL string is a much larger authorization surface than one that accepts a customer ID and a fixed set of operations on it.
- Least privilege. An agent's tools should be scoped to what its task needs. An agent that only ever needs to read order status shouldn't be handed a tool that can also cancel orders, even if it never happens to ask for it.
- Confirmation. For consequential actions, irreversible ones especially, the authorization step can require explicit human approval before execution instead of deciding automatically. Cheap, reversible actions can be auto-approved; a refund over a certain amount, or anything that deletes data, is a reasonable place to require a person in the loop.
- Idempotency. A tool call that gets retried, whether because of a network error or because the model asks for the same thing twice, shouldn't cause the action to happen twice. Designing tools so that calling them again with the same input is safe (charging an order once even if the charge request is sent twice) prevents a class of bugs that only shows up under retry, which agent systems do constantly.
- Audit trails. Every tool call an agent makes, what it requested, whether it was authorized, and what actually happened, should be logged somewhere a person can review after the fact. When an agent does something wrong, the audit trail is what turns "we're not sure what happened" into "here's exactly which step went wrong and why."
- Sandboxing. Where possible, point an agent's tools at an isolated environment instead of production systems: a scratch database instead of the live one, a container with no network access for running untrusted code. A mistake contained to a sandbox is a bug; the same mistake against production is an incident.
All six practices hold regardless of which orchestration framework or which model is in use. They're the same authorization boundary Identity and Access Management covers for human and service accounts, applied to a caller whose next request nobody can know in advance, because a model is the one deciding what to ask for.