Specs for AI Agents Are Not Specs for Code: Eight Sections That Each Block One Failure

Most teams start an agent project with one sentence in a meeting: “We need an agent that reads new support tickets and puts them in the right queue.” Then they open a prompt box and start typing. A better approach puts a short document between that sentence and production, and it is faster in the long run.

The key idea

Spec-first tooling already exists, but it is aimed at code. GitHub’s Spec Kit and AWS’s Kiro both produce requirements, plans and task lists before implementation. That works when you know the implementation path.

An agent is different. Anthropic describes agents as systems where the model directs its own steps and tool use, suited to open-ended problems where you cannot hardcode a fixed path. So you do not specify the path. You fence the space. That fence is the spec, and a post by u/Virtual_Hair_1987 on r/PromptEngineering lays out eight sections for it. Each one exists to stop a specific failure.

Old way vs. new way

The old way: write a friendly prompt (“You are a helpful support assistant, route tickets well”), run it, and discover the problems in production.

The new way: write the failure modes down first, and let each section answer one of them. The prompt becomes a byproduct of the spec, not a replacement for it.

The difference shows up in what you can check. A prompt is a suggestion. A spec has lines a reviewer can test, lines you can enforce in code, and lines that tell the next engineer why a rule exists.

The eight sections, with what each prevents

  1. Identity at a stated level. Not “helpful assistant” but “senior support operations specialist for a B2B billing product.” This stops the model from falling back on its own defaults. Arize AI’s field analysis lists pre-training bias overriding supplied context as a recurring failure mode.
  2. Mission with a not-doing clause. State the goal, the success condition, and what the agent does NOT do: reply to customers, issue refunds, close tickets, change a queue a human already set. This stops slow scope creep. Nobody writes “and also reply to the customer” into a prompt. It happens because the model decided it was helpful.
  3. Reasoning loop with a ceiling. Name the pattern, set a max number of iterations (say 5), and say what happens at the wall: stop, escalate, attach everything gathered. A ceiling with nothing after it makes an agent that silently stops mid-thought. Without one you get loops that return correct answers after hundreds of calls, a path that Arize notes still shows up as a stream of 200 OK responses.
  4. One contract per tool, failure path included. Five parts each: what it does, when to use it, what it returns (with real field names), what to do on failure, and an example. This blocks the quiet failure. If the agent guesses user_id when the schema says customer_uuid, the database returns zero rows, not an error, and the agent reports it found no data.
  5. A decision tree. Each branch tests something the agent can see and ends in one action. The final ELSE matters most. Without it, an unmatched ticket goes wherever the model’s judgement lands.
  6. Stop conditions a machine can check. “Stop when the ticket is handled” is a hope. “Stop when queue is set AND reason is non-empty” is a boolean. That is the bar.
  7. An output contract. A fixed record: ticket id, one queue, a reason under 20 words, an escalated flag, tools called. Downstream code stops breaking, and you can finally evaluate the agent by diffing a week of its routing against a human’s.
  8. Guardrails, each with its reason. “Never issue a refund, because that moves money and cannot be undone from inside this agent.” The reason gives the model something to generalize from on cases you did not list.

Practical steps

  1. Write your one sentence, then list five ways it could go wrong.
  2. Draft the not-doing clause first. It is the least satisfying section and usually the most valuable.
  3. Write stop conditions as predicates you could code without asking a model to interpret them.
  4. Give every tool a failure path, especially for empty results.
  5. Fix the output shape before you test anything.
  6. Add a reason to every guardrail.

One caveat from the post is worth keeping. Guardrails in a spec are not enforcement. Arize puts it bluntly: prompts are suggestions, and safety needs a deterministic layer in code. Your spec tells the reviewer what to enforce there.

A commenter added a smart extension: put an explicit evidence or unknown field in the output, so a reviewer can see which routing claim came from the ticket and which the agent inferred.

Call to action

Pick one agent you are running or planning. If you write only two sections today, make them the not-doing clause and the machine-checkable stop conditions. They are the only parts that constrain the agent when it does something you did not expect. Then add the rest, one failure at a time!

Frequently Asked Questions

Q: Should the evidence and unknown fields be part of the first spec?

Yes, and it’s cheap to add now. Ask the agent to split every routing claim into what came straight from the ticket and what it inferred, plus a list of things it could not determine. A reviewer can then check the evidence in seconds instead of trusting a confident summary.

Q: Who decides what the agent works on first?

You do, and the spec is where that call has to live. An agent will build the wrong thing very fast if the brief doesn’t rank the goals. Put the priority order at the top, so both the agent and the reviewer know which trade-off wins when two goals clash.

Q: What should the brief cover beyond the agent’s logic?

Describe the finished result from the user’s side: how the flow runs from start to end, what data they see and where it shows up, the layout, and whether this is a first version or a redesign. These feel too obvious to write down, which is exactly why they get skipped, and a model will guess them wrong.

How to write a spec for an AI agent, before you prompt anything
by u/Virtual_Hair_1987 in PromptEngineering

Scroll to Top