Name the trigger, the context, the artifact, and the line it must not cross.
An agent is not a capability, it is a job description. Someone currently does this work, and you are writing down which part of it moves and which part does not.
Four questions cover almost all of it. What starts it. What it is allowed to read. What it hands back. And what it must never do, no matter how the situation looks to it. Answer those four and you have a design; leave any of them implicit and you have a demo.
Two habits separate designs that survive contact with users. Start draft-only, because a human reading the first hundred outputs is the cheapest evaluation you will ever run. And ground every factual claim in a source the reader can open, because an agent that cannot show its working is one that has to be checked from scratch, which costs more than doing the work.
The tour does not auto advance because your system asks for reduced motion. Next setting still works.
Written down, an agent design is a small object. If you cannot fill in every field, the design is not finished, and the empty field is where it will fail.
agent = {
"job": "follow up with prospects who asked to be contacted later",
"trigger": "daily at 08:00, for anyone whose follow-up date is today",
"reads": ["crm.notes", "email.thread", "pricing.public"], # nothing else
"writes": ["drafts folder"], # not the outbox
"output": "one draft per prospect, every claim carrying its source",
"never": ["send", "quote a price not on the pricing page",
"contact anyone who opted out"],
"human": "reads and sends, or edits and sends, or deletes",
"measure": "share of drafts sent unedited, and replies per hundred sent",
}
Note what reads and never are doing. They are not instructions to the model, they are the shape of the credential and the check in the code path. An instruction is a preference. A boundary is enforced somewhere the model cannot reach.
| Design choice | What it buys | What it costs |
|---|---|---|
| Draft only | Every output is reviewed, so evaluation is free | No time saved until a human reads it |
| Grounded claims | A reviewer checks a link instead of the whole draft | Retrieval, and prompts that refuse to assert without a source |
| Narrow read scope | A small, explainable blast radius | Cases it cannot handle, which become escalations |
| Acting alone | Real time saved, at last | Errors reach people before anyone sees them |
The honest version of the trade: everything that makes an agent safe also makes it slower to pay off. Say which one you are optimising for and why, because an interviewer is listening for whether you know you are choosing.
An account executive has forty open conversations and loses the ones that said "circle back next quarter".
The trigger is a date, not a person's memory: every prospect whose follow-up date is today. The context is three sources and no more: the CRM notes for that account, the email thread, and the public pricing page. The output is a draft in a drafts folder, one per prospect, where every factual sentence carries the source it came from. The boundary is that it has no send credential at all, so the worst failure mode is a draft that gets deleted.
Turn off the pricing source in the panel above and watch what happens to the draft. The claim about pricing does not disappear, it becomes unsourced, and that is exactly the failure a reviewer has to catch every time. The fix is not a better prompt. It is either giving the agent the source or forbidding the claim.
You are asked to design an agent that answers customer questions from your help centre. What is the first thing to pin down?