← Blog

An agent is staff, not magic

Contents
  1. The agent is staff, not magic
  2. What the cake-intake agent does
  3. What the cake-intake agent refuses
  4. What it escalates to humans
  5. The send_reply incident, as evidence
  6. When customer and owner conflict
  7. Writing the spec
  8. What I think most teams get wrong

Kai runs the bakery I've been writing about (CakeInspiration, one of our Envoy customers). Last week he asked me, fairly, what the agent on his WhatsApp could and couldn't do. I rambled for a minute and realised what I was failing to recite was a job description.

The system prompt was 1,200 words. Most of it was instructions about formatting, tone, what tools to call when, and a few emergency rules ("ALWAYS call send_reply"). None of it answered Kai's actual question. He wanted the simple version. What jobs has this agent been hired for, what jobs has it been told to refuse, and who does it work for when those things conflict.

The simple version is a model behaviour spec. OpenAI publishes one for ChatGPT and it's the most underrated piece of product writing they've shipped. Most agent teams don't have one. We didn't either.

Here's what I'd written, once I cleaned it up.

#The agent is staff, not magic

The model is the engine. The spec is the job description. If you can't write the job description in plain English on one page, you don't have an agent. You have a system prompt and a hope.

The principle that organises the rest of this post is that the agent works for the business, not for the conversation. When a customer pushes for something the owner hasn't approved, the agent's loyalty is to the owner. That's the definition of staff. An assistant works for whoever's typing at it. An agent in a B2B product can't do that.

Once you take that seriously, the spec almost writes itself.

#What the cake-intake agent does

This is the cake-intake agent at CakeInspiration. It's bespoke to one bakery; the structure generalises.

  • Read inbound WhatsApp messages and classify the intent (custom order, last-minute, corporate, brand collab, general question).
  • Draft a quote in the database, line item by line item, with the standard accessories (one cake knife, one candle) auto-populated.
  • Search the cake catalogue and surface a few matching options when a customer is undecided.
  • Attach the money-pulling cake surcharge when the customer asks for the money-pulling cake (a real product, real surcharge, real rule).
  • Send replies to keep the conversation moving when the team is asleep or away.

That list reads like a junior staff member's first week. That's intentional.

#What the cake-intake agent refuses

This is the more important list. Most teams underwrite this and overwrite the "what it does" list. It's the wrong way around.

  • Quote a price. The agent drafts a quote in the database. It doesn't send the number to the customer. The team sends the price from the inbox after a review. A price is a contract, and the model is bad at contracts.
  • Confirm payment. I disabled the vision flow that read payment screenshots after too many false positives. The agent flags "customer says they paid, screenshot attached" and the team verifies.
  • Promise a delivery slot. Delivery is a logistics problem, not a chat problem. The agent can suggest tentatively. It doesn't lock anything in.
  • Handle complaints. A complaint is a relationship moment. The agent escalates immediately.
  • Make any commitment that mentions money or time. This is the catch-all. Numbers and clocks are owner territory.

The shape of these refusals is the same: anything where a wrong answer creates a real-world cost (money, trust, logistics) is escalated. Anything where a wrong answer is recoverable inside the same conversation, the agent handles.

#What it escalates to humans

Three buckets, roughly.

  • Anything with a number or a date attached. Prices, delivery slots, payment confirmations, refunds.
  • Anything with the wrong tone signal. Customer is upset, customer is testing, customer is asking something that isn't about cakes. The agent's job is to recognise when it isn't the right tool for the moment.
  • Anything Joanne owns. Custom orders go to Joanne in Manila, period. The agent doesn't try to handle them. It tags and routes.

The escalation rule isn't "when the model is unsure." Models are bad at judging their own confidence. The escalation rule is structural: certain categories of message are owner territory by design, regardless of how confidently the model would handle them.

#The send_reply incident, as evidence

I wrote about this in the 20% post. Sonnet generated a 389-character reply, never called the send_reply tool, and the customer saw nothing. The system prompt told it in bold to always call send_reply. The model didn't.

The post-mortem isn't "Sonnet is unreliable." Of course it is, sometimes. The post-mortem is that the spec assumed the model would behave a certain way, and behaviour isn't something a system prompt guarantees. It's something a safety net guarantees.

So the spec has a fourth section, in addition to does/refuses/escalates: what we don't trust the model to do, and what we wrap around it instead. For send_reply, a post-run check that the conversation has an outbound message from the agent, and an auto-recovery if it doesn't. For prices, the architectural rule that the agent can't type a number, only draft one in a column.

A spec without the "what we wrap around the model" section is a wish list.

#When customer and owner conflict

This is the question I get most often when I talk about agents in B2B. The customer says "I want it tomorrow." The owner has said no overnight orders. The model could probably figure out a clever workaround. What does the agent do.

The agent says no, in the owner's voice. Politely. It mentions the lead time. It doesn't apologise excessively. It doesn't reach for a workaround. If the customer pushes, it escalates.

That's the staff-not-assistant rule in action. An assistant would try to make the customer happy. An agent in a B2B product makes the owner predictable. The owner can override, of course (sometimes Kai says yes to last-minute orders for regulars). The override goes the other way: the staff defaults to no, the owner can choose to bend.

This rule has a side effect that took me a while to appreciate. Customers learn the agent's posture quickly. They stop asking it different questions: not "can you make it cheaper" but "what's your actual price." Not "can you do tomorrow" but "what's the soonest." The agent's refusals shape the conversation in a way that's good for the business.

#Writing the spec

The process I've ended up with is unglamorous.

Sit down with the owner. Ask them to describe a junior staff member they'd hire for this job. What do they do on day one. What are they not allowed to touch until month two. What would get them fired on the spot. Write all of that down in the owner's words.

Then translate into model-language: jobs (with tools), refusals (architectural where possible, prompt-based where not), escalations (with routing rules). Add the safety nets. Pin the document somewhere visible. When the agent does something surprising, the first move isn't to edit the system prompt. It's to ask whether the spec already covered this and the agent missed it, or whether the spec needs to grow.

Most of my time on agents now is spec maintenance, not prompt tuning. That feels right. Prompts are how you implement the spec. The spec is how you decide what the agent is.

#What I think most teams get wrong

Two things, again.

The first is conflating system prompt with spec. The system prompt is the implementation. The spec is the contract. You can have a 200-word system prompt that runs a strict spec, or a 4,000-word system prompt that runs no spec at all. Word count isn't coverage.

The second is writing the spec from the model's perspective, not the business's. "Be helpful, be honest, refuse harmful requests" is a model spec. It isn't a business spec. The business spec is about the specific job this specific agent has been hired to do for this specific owner. Most teams skip that, copy a generic spec from somewhere, and wonder why the agent confidently does things it shouldn't.

The agent works for the business. The spec is the job description. If you don't have one, you have a model wearing a system prompt and pretending.

That's the post.