The Agent Responsibility Principle
One decision, one surface.
The refund that shouldn't have happened (opens in a new tab)
Picture a support team that ships an AI agent. It reads the customer's message, looks up the order, decides whether a refund is deserved, issues it, and sends a friendly email. One agent, end to end. Demos beautifully.
At 2:14pm on a Tuesday, a customer asks for a refund on an order four months outside the window. The agent reads the message, notes the customer sounds upset, reasons its way to "an exception seems fair here," refunds the full amount, and sends a warm apology.
The team's response is the obvious one: fix the prompt. A new rule goes in — never refund outside 30 days. Two weeks later a different edge case slips through, so another rule goes in. Then another. Six months on, the prompt is three pages of exceptions, and nobody is confident about what the agent will do with the next unusual message.
That loop — incident, prompt patch, new incident — is a signal that the problem lives at a different layer. Not in how the instructions are worded, but in how much one agent is allowed to decide and touch.
The principle (opens in a new tab)
Software engineers know the Single Responsibility Principle: one piece of code, one reason to change. Agents need a version of it with sharper edges, because agents don't just compute — they act. Call it the Agent Responsibility Principle:
An agent should own one decision and one interaction surface.
Two parts:
- One decision — the single question this agent answers. "Does this order qualify for a refund?" is one decision. "Handle customer service" is many.
- One interaction surface — the slice of the world it can touch: what it reads, what it writes, what it changes.
The decision defines the agent's decision rights. The surface defines its blast radius — how much damage a mistake can do. An agent that only reads documents can't do much harm. An agent that moves money can. The support agent in the story owned five decisions and one enormous surface, which is why one flawed line of reasoning went all the way to a payout.
What counts as a decision? (opens in a new tab)
In a complex workflow, this is the hard part — every step feels like it involves a hundred small choices. A working definition: a decision is a judgment call with consequences. Two things have to be true. The outcome could reasonably have gone another way, and the difference matters enough that someone might want to review or reverse it.
That test sorts every step in a workflow:
- Could differ, and someone cares — a decision. Give it an owner. Does this order qualify for a refund?
- Could differ, but nobody would challenge it — a style choice inside another decision, not its own. Word choice while drafting the email rolls up into "what to tell the customer."
- Couldn't differ, but someone cares — not a decision. An action that needs a guard. Issuing the refund: nothing to judge, everything to control.
- Neither — that's not an agent at all. That's code. Looking up an order or parsing a date involves no judgment, so it doesn't need a model that can improvise on it.
A quick heuristic when the workflow gets tangled: imagine it were a team, and someone kept meeting minutes. What would be recorded as decided? Nobody minutes "chose the word 'unfortunately.'" They minute "approved the refund." The minutes are your decision inventory — and each entry is a candidate boundary.
The clearest way to see what the principle buys you is to run the same incident again — with boundaries.
The same incident, replayed (opens in a new tab)
Split the support agent by decision:
- Intent agent — decides what is the customer asking for? Reads the message. Changes nothing.
- Policy agent — decides does this order qualify? Reads order history and the refund rules. Cannot move money.
- Execution gate — verifies the request carries a valid approval, then performs the refund. Its surface is the payment system, and only that.
- Notification agent — decides what to tell the customer. Sends messages tied to a logged outcome, and nothing else.
Notice the gate isn't an agent at all. Verifying an approval and calling a payment API take no judgment — once the decision is made, processing the refund is just a parameterized function call — so it's deterministic code. Not everything in the workflow deserves a model.
Now replay 2:14pm. The intent agent reads the message: customer wants a refund. The policy agent checks the order: four months outside the window, and — reading a sympathetic request — it still reasons its way to "an exception seems fair." Same flaw, same moment.
But this time the flaw is a recommendation, not a payout. The execution gate only accepts refunds carrying a valid policy code, and this one doesn't have one — so the request stops at the boundary. (The check can take other forms too: a stricter rule, or a human review queue for out-of-policy approvals.) The money never moves. The failure becomes a log line, and the notification agent — which only sends messages tied to a logged outcome — tells the customer their request is under review.
Nothing about the agent's reasoning improved. The same mistake happened in both versions. What changed is how far it traveled.
A boundary doesn't make an agent smarter. It decides how far a mistake can go.
This is the pattern finance teams have used for decades: the person who requests a payment doesn't approve it, and neither of them sends the money. Not because anyone is assumed dishonest — because mistakes are easier to catch when no single role can carry an action through alone. Agents warrant the same structure for an extra reason: the same input doesn't always produce the same output. A capable but unpredictable worker with direct access to real systems is exactly the role a well-run company surrounds with checks.
"Isn't the policy agent just as likely to be wrong?" (opens in a new tab)
Fair question — it's the same kind of model reading the same kind of request. Splitting doesn't make it smarter. Three things still change.
A bad outcome now takes two failures instead of one. In the monolith, one flawed thought equals money gone. In the split, a wrong payout requires the policy agent to be wrong and the check to miss it. That's ordinary defense in depth.
The split is what makes the check possible. The tempting alternative is "just add a validation step inside the one agent." But the moment a checkpoint stands between judging and paying, judgment and payment have been separated — that is the boundary. Inside a monolith, there's no seam to stand in.
A narrower surface means fewer ways to be led astray. A surface isn't just about what an agent can change — it's also about what it's allowed to see. The monolith read the customer's emotional message while judging eligibility — and got swayed. The policy agent doesn't need to see that message at all. The intent agent hands it a structured request ("refund, order #4412"), and it judges on order data and rules. The sob story never reaches the judge.
One honest caveat: this math only cuts the safe way for risky actions. Chaining agents that each must be right compounds errors rather than containing them. Boundaries protect you where a mistake is expensive; they don't make every pipeline more accurate. When chaining helps and when it hurts is a topic of its own — worth a separate post.
Boundaries aren't free (opens in a new tab)
Before splitting everything in sight, it's worth being honest about the price.
Every boundary is a handoff, and in agent systems a handoff usually means another model call: more latency, more cost, and one more place a message can be garbled or dropped. A relay team with fifty runners isn't faster — it just has fifty more chances to drop the baton.
So this is a tradeoff, not a rule to maximize. Two signals suggest a split is worth its price:
- Different scorecards. One job is graded on finding the right information, another on writing well. Jobs you measure differently, you tune differently.
- Different levels of trust. Reading public data and moving money live in different worlds. High-privilege actions belong behind the smallest agents possible — the vault and the mailroom shouldn't share a key.
Where neither diverges, the handoff tax buys you little. A reasonable default: start coarse, and split under pressure.
Why monolith agents happen anyway (opens in a new tab)
The one-agent-does-everything design is too common to blame on carelessness. It's the rational starting point.
A single agent is the fastest thing to build and the best thing to demo. Boundaries, meanwhile, are invisible in a demo — their value only shows up in the incident that doesn't happen. And the prompt feels like the control surface, because it's the part you can edit in five minutes and watch respond. So teams pull the lever that's in front of them, and each patch genuinely does fix the last incident. The loop isn't foolish; it's just aimed at the wrong layer.
"But what about the orchestrator?" (opens in a new tab)
The common objection: real systems have a user-facing agent that coordinates all the others. Doesn't an agent that can call everything break the rule?
It doesn't — as long as it's held to the same rule. An orchestrator owns one decision, routing: given this request, who goes next? And it has one surface: the other agents. The workers touch the world; the orchestrator only touches the workers.
Think of a general contractor. They coordinate the electrician and the plumber, but don't pick up the wiring themselves. The discipline that keeps the pattern honest: the orchestrator delegates actions; it doesn't perform them. And because it can invoke every worker, its reach is the sum of everything downstream — which is manageable only if business authorization lives at each worker (the execution gate enforces the payment rules). The coordinator still checks that messages are well-formed and runs on narrow permissions of its own, but it is never the authority on whether an action is allowed. A contractor schedules the electrician; they don't get to overrule the electrical code.
One warning sign: because the orchestrator sees the whole conversation, it attracts extra jobs — summarizing, validating, "just this once" calling an API directly. A coordinator that keeps growing responsibilities is usually a sign that another worker agent wants to exist.
A test for every agent (opens in a new tab)
None of this requires rebuilding a system from scratch, and that isn't the place to start anyway.
Pick one agent and write down, in one sentence each:
The decision it owns ← one sentence, or it's two agents
What it can read
What it can write or change ← this list is its blast radius
If the decision won't fit in a sentence, there are probably two agents wearing one coat. If the "can change" list is long and powerful, that agent deserves to be small, simple, and closely watched — ideally with a human or a deterministic check at its most dangerous edge.
Drawing the right lines (opens in a new tab)
The team in the opening story didn't need a better prompt. They had six months of increasingly better prompts. They needed a structure in which the agent that judges a refund isn't the agent that sends one.
So the next time an agent misbehaves, the prompt is worth a look — but ask the other question too: is one agent making too many decisions with too much power? The wording decides what an agent tries to do. The boundaries decide what happens when it's wrong.