The Full Architecture Fits in Seven Blocks
An agent isn't "a model in the browser." The browser doesn't talk to the model directly: the server gets the user's identity, runs a shared agent runtime, and a provider adapter translates the unified contract into a specific API format. The whole system fits in seven blocks with clear zones of responsibility.
Block · Responsibility · Must not pass to the model
- UI - Messages, streaming, the confirmation card; API keys
- API route - Session, rate limit, validation, request id; The authorization decision
- Agent runtime - Steps, tools, timeout, outcome, trace; An unbounded loop
- Provider adapter - The Responses, Messages, or Interactions format; Business rules
- Tool handlers - Access to RAG, orders, and preview; Secrets and extra fields
- Approval service - Checks of preview, nonce, version, and actor; Free text as permission
- Event store - Own history, usage, audit, and replay; Blind dependence on provider state
The point of the table is the "must not pass to the model" column. Each block keeps something to itself: the UI doesn't hand over API keys, the API route doesn't hand over the authorization decision, the runtime doesn't hand over an unbounded loop, the adapter doesn't hand over business rules, the tool handlers don't hand over secrets and extra fields. The model sees exactly what's needed for the next decision, and not a byte more.
In code this looks like two entry points, not one.
UI
POST /api/support/turn
session + validation
runCommerceAgent(context)
provider adapter
tool registry
event store
POST /api/support/approve
approval service
refund transactionWhy exactly two endpoints is a question of risk, not structure.
Why two endpoints. A conversation and the execution of a financial action carry different levels of risk. The second endpoint re-checks the user, the preview's freshness, and the idempotency key. It doesn't trust the text of the model's previous answer.
This is the main boundary made concrete: the agent runs the dialogue, and an irreversible action is performed by a separate trusted path. Later in the book we'll build both, but first we'll decide what to build them on - the direct API or a framework.