Deterministic Agent Workflows Beat Context-Rot Coding
I’ve seen this too many times to pretend it’s random.
The first 20 minutes of an agent coding session feel superhuman.
Then the context gets heavy, the model gets fuzzy, and the session starts eating its own tail.
You get duplicated helpers, dropped constraints, and “done” reports on things that aren’t done.
That’s context rot. The fix is architectural, not motivational.
The key shift
I stopped letting one long LLM conversation run the control plane.
Now I use deterministic orchestration: a script — Python, TypeScript, or a workflow DSL like Claude Code’s .claude/workflows/ format — controls the graph. Agents do bounded subtasks. Outputs must match a schema. Loops stop on explicit budget and gate conditions.
This is the same direction I argued in I Trusted the Workflow Until It Broke Trust: separate trust boundaries, make behavior inspectable.
Why it works better in real projects
When orchestration is deterministic, four things improve immediately:
- Cost predictability — you know which model runs how many times
- Debuggability — you can trace why a route happened without reconstructing the model’s state at token 73,000
- Scope discipline — workers can’t creep because their IO is fixed
- Team handoff — the workflow is code, not a prompt buried in conversation history
The pattern
1) Split orchestrator from workers
The orchestrator owns routing, retries, escalation, and budgets.
Workers own one reasoning task with fixed input and output types.
In practice: your orchestrator is a JavaScript or Python script. Your workers are LLM calls with a schema argument. Nothing clever in the control plane — just if/else and for loops.
2) Put a schema at every boundary
No schema, no handoff.
If output fails validation, branch deterministically:
- retry the same model
- escalate to a stronger model (Haiku → Sonnet → Opus)
- route to a human gate
The model doesn’t decide what happens on failure. Your code does.
3) Enforce budget-aware loops
Every loop needs three hard stops:
- token cap
- iteration cap
- wall-clock cap
Pick them before you run. Without caps, a loop that stalls in production runs until you get a billing alert at 2am.
4) Make context explicit
Narrow context by default. Pass only what the current step needs — usually the last step’s output plus any named dependencies. Only accumulate full context when a synthesis step genuinely needs the whole thread.
Accumulated context is where context rot starts. Treat it like heap allocation: use it consciously, not by default.
The misunderstanding
People hear “deterministic” and assume rigid.
It’s the opposite. Deterministic orchestration is what makes richer workflows safe to ship.
You can do fan-out, model mixing, and budget-aware loops without an opaque mess — because when something breaks, you know exactly which node failed and why. That predictability isn’t a constraint. It’s the prerequisite for confidence.
What to do first
If your current setup is one long agent session, here’s the upgrade path:
- Add output schema contracts. Even simple ones — JSON Schema or Zod. If the model returns invalid output, you need to know at the handoff, not three steps later.
- Move routing into code. One
if/elsein Python beats 200 tokens of system prompt telling the model to decide. - Add max-iteration and max-token stops. Hard caps, not suggestions.
- Add one verification gate before completion. A second agent that checks the first agent’s work, with a pass/fail schema output.
One week in, you’ll stop debugging why the model ignored a constraint you set four exchanges ago.
Next in this series:
Sources
- Conductor blog post (Microsoft Open Source, May 2026): https://opensource.microsoft.com/blog/2026/05/14/conductor-deterministic-orchestration-for-multi-agent-ai-workflows/
- Conductor repository: https://github.com/microsoft/conductor
- Related deterministic systems framing (research direction): https://arxiv.org/abs/2604.05150