For the last couple of years, most of us built chatbots. You send a message, the model sends text back, and the worst it can do is say something wrong. Agents are a different animal. An agent can search the web, run a SQL query, send an email, hit a payments API, or update a record in your CRM — often several steps in a row, deciding what to do next as it goes.
That shift from talking to doing is where responsible engineering stops being a nice-to-have. A chatbot that hallucinates gives a bad answer. An agent that hallucinates can take a bad action. This post is the checklist I actually use when I put an agent anywhere near a real system.
Why agents are different from chatbots
A chatbot is a function: text in, text out. An agent wraps a model in a loop — it reasons, picks a tool, runs it, reads the result, and decides whether it is done. That loop is what makes agents useful, and also what makes them risky. Every tool you connect is a new thing that can go wrong, and every step compounds the uncertainty of the step before it.
Goal
User states an intent.
Reason
Model plans the next step.
Act
It calls a tool or API.
Observe
It reads the result.
Repeat / Stop
Loop until the goal is met.
Notice there is no human in that loop by default. The whole design philosophy of responsible agents is about deciding, deliberately, where a human belongs — and what the agent is simply never allowed to do on its own.
The risk of autonomous decisions (and hallucinated actions)
When a model is uncertain, it does not stop — it guesses. In a chatbot that produces a confident-sounding wrong sentence. In an agent it can produce a confident-sounding wrong tool call: deleting the wrong record, emailing the wrong customer, or refunding the wrong amount. The model is not being malicious; it is doing exactly what it was trained to do, which is to produce a plausible next step.
The core rule I never break
The blast radius of an action should match how confident we can be in it. Reading data is low-risk. Writing, deleting, sending money, or contacting people is high-risk — and high-risk actions need confirmation, constraints, or a human.
Human-in-the-loop, done well
Human-in-the-loop does not mean a person babysits every step — that would defeat the point. It means the agent runs freely for safe, reversible work, and pauses for approval before anything consequential or irreversible. A good pattern is to let the agent draft the action (the email, the refund, the database change) and require one click to commit it.
Let the agent act alone
- Reading and summarising data
- Searching and retrieving documents
- Drafting content for review
- Reversible, low-cost operations
Require human approval
- Sending money or issuing refunds
- Emailing or messaging customers
- Deleting or overwriting records
- Anything that is hard to undo
Permission-based tool access
Give an agent the narrowest set of tools it needs, not your whole API surface. I treat agent permissions the same way I treat a new employee's access: least privilege by default. If an agent only needs to read orders, it gets a read-only credential — not an admin key that can also issue refunds because that was easier to wire up.
- Scope each tool to a single, well-defined job.
- Use read-only credentials wherever writing is not required.
- Put hard limits in the tool itself (max refund amount, allowed tables), not just in the prompt.
- Never rely on the system prompt alone to enforce a boundary — prompts can be talked around.
Guardrails belong in code
A limit written in the prompt is a suggestion. A limit written in the tool — a check that rejects a refund over a threshold — is a rule. Enforce the things that matter in code, where the model cannot argue with them.
Memory and privacy
Agents often keep memory — past turns, retrieved documents, user details — to stay coherent. That memory is also a privacy surface. Ask what actually needs to persist, for how long, and who can read it later. Personal data that lingers in a vector store or a logs table is a liability waiting to happen. Store the minimum, set retention, and keep sensitive fields out of anything you would not want to leak.
Logging, monitoring, and observability
With a chatbot you can eyeball a bad reply. With an agent you need a trace — the full record of what it decided, which tools it called, with what inputs, and what came back. When something goes wrong at 2am, that trace is the difference between a five-minute fix and a mystery. Log every tool call, its arguments, and its result, and make those traces searchable.
Inputs
The user goal and context.
Decisions
Each planned step and why.
Tool calls
Name, arguments, result.
Outcome
Final action and status.
Evaluation and testing
You cannot ship an agent on vibes. Build a set of realistic scenarios — the happy path plus the nasty edge cases — and run the agent against them every time you change a prompt, a tool, or a model. Test not just whether it succeeds, but whether it fails safely: does it refuse when it should, ask for help when unsure, and avoid destructive actions when confused?
A test suite I always include
Adversarial cases: a user trying to make the agent exceed its permissions, act on someone else's data, or take an irreversible action. If the agent can be talked into breaking a rule, the rule is not really there yet.
Enterprise best practices
- Start with a narrow, high-value use case before granting broad autonomy.
- Roll out with a human approving high-risk actions, then relax gradually as trust builds.
- Keep an audit trail good enough to answer 'what did the agent do, and why?'
- Version prompts and tools like code, so you can roll back a bad change.
- Give users a clear way to see, undo, and report agent actions.
“The goal is not an agent that can do anything. It is an agent that does the right things reliably, and asks for help before the things it should not do alone.”
The road ahead
Agents are getting more capable every quarter — longer horizons, more tools, multi-agent teams that coordinate. The engineering challenge is not making them do more; it is keeping them trustworthy as they do more. If you build the guardrails, observability, and evaluation in from day one, you get to enjoy the autonomy without lying awake wondering what your agent is doing while you sleep.
