Chapter 4 · Part 2
Put a human in the loop
Least privilege shrinks the blast radius, but some actions are dangerous at any size — sending money, emailing a customer, deleting records. For those, the safe amount of autonomy is none: a person approves before it runs.
Tier your tools by risk
Not every tool needs a gate — approving a read_file on every call would make the agent useless.
Sort tools by blast radius and gate only the sharp ones:
- Safe (auto-run): read-only, confined, easily reversed —
calculate, a confinedread_file. - Needs approval: anything that changes the outside world or can't be undone —
send_email,delete_file,charge_card,run_code.
The test is reversibility: if undoing it is hard or impossible, a human approves it.
The gate
Keep a set of tools that require sign-off, and check it in the loop before running the tool. The agent proposes; a person disposes:
REQUIRES_APPROVAL = {"send_email", "delete_file", "charge_card"}
def run_tool(name, args):
if name in REQUIRES_APPROVAL:
print(f"\n⚠ The agent wants to call {name}({args})")
if input(" Approve? [y/N] ").strip().lower() != "y":
return "The user denied this action." # agent reads this and moves on
return TOOL_FUNCTIONS[name](**args)A denial isn't a crash — it comes back as a normal tool result, and the agent adapts ("I wasn't able to send the email; here's the draft instead"). Notice this also stops the injection attack: even if a hijacked agent decides to email your data out, the send never happens without you clicking yes.
The rule that ties it together
An agent requesting an action is not permission to take it — the request itself might be the attacker's. Authorization comes from your policy (this tool is safe / this one needs a human), enforced in your code. Never let the model's confidence stand in for a real check.
For unattended agents (no human watching), the same idea becomes an allow-list of auto-approved actions — anything not on it is refused rather than queued, because there's nobody to ask. When in doubt, an agent running alone should do less, not guess.
You've shrunk what the agent can do and gated what's dangerous. Now protect the crown jewels: your secrets. Next.