How I think about agent design
When I first started tinkering with agents my first instinct was to keep making the agent more capable. I’d give it more tools, let it handle more of the job, trust it to figure out the rest. That instinct is probably right for an agent you interact with all the time but the more I thought about it, the more I felt that was the wrong way to look at it for deliberate, repeatable production workflows.
One prompt, then five
Section titled “One prompt, then five”My first pass at the alert-triage workflow that eventually became the samples in this repo was, predictably, one prompt. Look up the service doc, raise the ticket, query the metrics, work out a probable cause, propose a remediation, mark your own confidence - all of it, one agent, one soul.md trying to be a first-responder, an SRE and a reviewer at the same time.
It sort of worked. For a production workflow it also fell over in exactly the way you’d expect. The confidence number meant something different every time depending on which part of the job the model happened to be doing when it wrote it, so gating on it was close to useless. Splitting the same job into five smaller steps - triage, investigate, verify, decide, act - wasn’t a refactor I did after finding problems. It’s the thing that made the whole approach work at all, almost immediately. I didn’t have to fix the giant prompt. I just had to stop asking one agent to be five people.
That’s not really an accident, and it’s not really a discovery either. Once I stopped trying to design the “right” agent architecture from scratch and started asking how this job already gets done by people, most of the decisions made themselves.
Everyone’s already doing this, just not with LLMs
Section titled “Everyone’s already doing this, just not with LLMs”So how does an incident actually get triaged today, on a team that is already doing this without an LLM in the process?
A senior engineer doesn’t open a raw alert and start hand-typing service context into a Jira ticket. That’s not what they’re there for, and it would be a waste of what they are there for. There’s a first-line function - call it L1, call it whoever’s on the on-call rota this week - whose entire job is to look at the alert, pull up the service documentation, and raise a ticket with enough context that a senior engineer isn’t starting from a blank page.
And a senior SRE doesn’t sit refreshing a Jira board waiting to write problem reports off the back of raw pages either. They get handed a ticket that already has a shape to it - a service, a summary, a link to the doc - and their job starts from there. They query the metrics, work out what’s actually going on, decide whether this needs someone even more senior.
Once you start thinking like that, splitting a pipeline into first-line-triage and
sre-investigation isn’t a design decision I had to invent. It’s just how
this already works, everywhere I’ve ever been on-call. The process already
exists. I didn’t design it - I just started copying it.
The same is true one level up. Nobody senior double-checks every single
ticket L1 raises - that would defeat the point of having an L1. But for the
things where being wrong actually costs something, someone more senior generally
reviews before it goes further ad this is true of any business process, not just in software engineering or the IT world. It’s not a special AI safety mechanism,
that’s just an org chart. In VectorStep, and our sameple use-case it shows up as a principal-sre
agent sitting in the verifier slot on a step - sometimes triggered
conditionally, sometimes wired to fire on every run when the stakes justify
it - but the shape of the idea predates the software by decades.
This is the bit I’d want a reader to take away more than any specific YAML field. You don’t need to invent an organisational structure for your agents. Look at how the humans doing this job today are already organised - who’s allowed to decide what, who checks whose work, who escalates to whom and build the pipeline to match. The org chart is the spec. It’s a lot easier to draw a process that already exists than to guess at a new one.
Grant only the tools the job needs
Section titled “Grant only the tools the job needs”That same division of labour is exactly why tools: in agent.yaml matters
as much as it does. L1 has access to Confluence and Jira. They don’t have a
Grafana login, and they definitely don’t have a way to push a change to
production - not because anyone doubts their competence, but because it’s
not their job, and giving them that access wouldn’t make them faster at the
job they do have. The senior SRE can query Grafana and comment on the
ticket, but they don’t get to skip the ticket and go straight to
remediation off their own initiative in most places I’ve worked in.
An agent’s tool list is the same thing, just enforced by the gateway instead
of by an access request form (and a long drawnt out manual human process getting in the way). first-line-triage can reach Confluence and
Jira and nothing else. sre-investigation can reach Grafana and the ticket,
and nothing else. Neither can reach anything genuinely dangerous, so whatever
the model’s reasoning does under pressure - or under a prompt injection
buried in a tool result - there’s a hard ceiling on how much damage it can
do. That’s not a courtesy. It’s the actual security boundary, and it falls
out for free once you’ve split the job the way the humans already split it.
Confidence has to mean one thing
Section titled “Confidence has to mean one thing”A triage agent’s sense of “how bad does this look” isn’t the same signal as an SRE’s sense of “how confident am I in this probable cause,” and neither of those is “how completely did I do my job” which is the only one of the three that’s actually safe to gate a pipeline on. Bundle triage, investigation and remediation into one agent and its confidence score ends up quietly averaging across three different questions. Split them, and each agent’s confidence has to answer exactly one question, because it’s the only question that agent ever gets asked. Calibration only works once that’s true - see how confidence and calibration work for the mechanics.
Worth establishing now, while it’s still cheap
Section titled “Worth establishing now, while it’s still cheap”There’s a cost argument for all of this too, and I think it’s really important to think about this now before (hopefully!) it becomes an obviously good idea rather than a forward-looking one.
Token costs right now are, relatively speaking, a rounding error for most of the workloads I’m describing. That’s a honeymoon, not a permanent state of affairs. Anyone who was around for the early days of cloud compute has seen this before. “Just call the biggest model, it’s cheap enough not to matter” is actually a fairly reasonable thing to say today and a completely unreasonable habit to have baked into your architecture in two years’ time, once someone in finance starts asking how much we’re spending on AI (I am already seeing these conversations coming up).
Splitting a workflow into steps is what makes it possible to do anything
about that at all. A first-line-triage step that runs two hundred times a
day looking up a doc and raising a ticket doesn’t need the same model as a
principal-sre verifier whose entire job is catching the primary’s
mistakes on the handful of runs where it’s worth paying for a second,
genuinely independent opinion. That’s not a distinction you can make once
everything is one prompt and one model. It’s a direct consequence of having
five smaller jobs instead of one big one, each cheap enough to reason about
in isolation, including reasoning about what it should cost. See cost
accounting for what that actually looks
like once you want real numbers instead of intuition.
I’d rather build the habit of matching the model to the job while it barely matters than wait until it very much does.
The practical version
Section titled “The practical version”The engineering checklist version of this post lives at Writing good agents — this post is the “why,” that page is the “how.”