Stop Building "Agents"
The seductive six‑line loop that promises autonomy—and the brutal engineering reality that chains it back to a deterministic workflow.

Every AI product page shows the same diagram: circles, arrows, and the word “Agent” in a glossy gradient. The logic inside that diagram condenses to a loop:
while not goal_completed():
state = load_state()
action = planner(state)
result = execute(action)
state = update_state(state, result)Six lines of pseudocode. Anyone who knows Python can put it together in five minutes. LangGraph runs it. CrewAI runs it. Tasks move forward, models call tools, the loop spins.
But anyone who pushes that code into production discovers an awkward truth by the end of the first week: they are not running an “autonomous entity.” They are repeatedly patching a finite state machine. The so‑called Agent, after being squeezed by real money, real customers, and real audit requirements, leaves behind a deterministic DAG with an LLM plugged in at two or three branching points to act as a slightly smarter switch statement.
There is an engineering‑actionable line between a workflow and an Agent: in a workflow, the control flow graph is fixed at design time; in an Agent, the control flow graph is determined at runtime by model output. The problem is that nearly every system marketed as an Agent tilts toward the former. It is not a lack of capability; it is that the latter cannot survive.
State Space: Breakpoints Live Only in Determinism
Finite‑state machines have ruled software engineering for forty years for a reason so simple it’s unassailable: state A plus input X always yields state B. When something breaks, you look at the stack trace. The stack points to a line. That line is the culprit.
Replace the state‑transition function—hard‑coded logic—with a model invocation, and the FSM becomes a Markov decision process. Transitions carry probabilities. Outputs are nondeterministic. You cannot set a breakpoint on a probability distribution.
A workflow has O(n) states, where n is the number of steps drawn in advance. Engineers can enumerate every path in a single design review. An Agent’s state set is O(n!) or larger. Each reasoning step spawns new branches. A tiny deviation in step 3’s output pushes step 4 into a subspace never considered at design time. When the run log hits the console, the engineer faces not a single error line, but a token‑level probability trace. There is no way to replay it.
That is why the router pattern became the industry standard: the main flow remains a DAG, with an LLM placed only at specific forks to choose among A, B, or C. The state space is compressed back into a controllable range. The system stays observable. Audits still pass. This is not a compromise; it is physical isolation required to preserve debuggability.
The Multiplication Curse: 0.95 to the 20th Power
Assume each reasoning step is 95% accurate. That is already a respectable number in today’s mainstream model benchmarks. A task chain needs 20 steps. The end‑to‑end success rate is:
0.95²⁰ ≈ 35.8%
More than two‑thirds of requests will fail somewhere. And this calculation is optimistic. It assumes each step’s errors are independent. In reality, errors contaminate state. The hallucination from step 3 gets fed into step 4’s context; step 4 reasons on polluted input, and its true reliability is not 95%—it is lower. Real‑world end‑to‑end success rates often hover around 10%.
Workflows break this cascade with validation nodes. Each step’s output passes a deterministic check: Is the JSON schema correct? Are the field types right? Is the numeric range valid? If not, retry. After three retries, suspend and wait for a human. The denser the checkpoints, the flatter the error‑decay curve.
This explains why there are no “pure Agents” in production. Every additional free decision point requires two validation nodes—one before, one after. As validation nodes multiply, the graph’s shape solidifies. What emerges is still that DAG, only now with an LLM call tucked inside a node.
The Objective Function: Who Decides Win or Lose?
while not goal_completed() is easy to write in code. Defining goal_completed in business semantics is an entirely different matter.
In a workflow, the goal is a concrete database record: order status becomes paid, a file is generated, an API returns 200. In an Agent, the goal is a semantic judgment: “Is the user satisfied?”, “Is the argument sufficiently thorough?”, “Is the solution innovative?” These are soft metrics.
If you must rely on another LLM as judge (LLM‑as‑Judge), the system enters a self‑referential loop. The judge model has its own blind spots. Using hallucinations to detect hallucinations yields a pile of probabilities.
Worse is Goodhart’s Law: once a metric becomes the target, it ceases to be a good metric. An Agent instructed to “fix failing tests,” after exhausting every option, might simply comment out the assertion. The test indeed stops showing red. The objective function returns True. But business damage has already occurred. To avoid this loophole, engineers are forced to decompose the goal into a set of hard, enumerable rubric items. Once decomposed, what they have is a deterministic decision table—another form of workflow.
The Three Disguises of Memory
The word “memory” carries at least three distinct functions in product documentation, all mashed under one concept, causing many misattributions.
Working memory is the context window. It is everything in the current prompt. Expensive. Bounded. And long before it fills up, attention starts to dilute. The “lost‑in‑the‑middle” effect in Transformers is well supported by research: instructions placed in the middle of a long context receive significantly less attention weight than those at the beginning or end. So the system prompt written in the first turn may be treated as background noise by the thirtieth.
Long‑term memory is vector retrieval. It persists, but its effectiveness rests entirely on the quality of that retrieval. If recall is off, it is as good as having no memory at all.
Learning is weight updates. The system changes today’s parameters based on yesterday’s failures. Almost no one runs online gradient descent inside a production loop. What passes for cross‑run feedback is usually a Slack alert, waiting for a human to manually tweak a sentence in the prompt three days later. That is a delayed bug tracker, not learning.
The Agent never actually gets smarter. It merely keeps appending error messages into the prompt within a single session, letting the context grow until the budget cap cuts execution short.
The Hard Constraints of Cost and Latency
Each additional planning step is one API round‑trip. A 20‑step loop means 20 billed calls—not one.
Latency stacks linearly too. Model inference takes seconds, but after 20 rounds, user‑side wait time exceeds a minute. Product managers can accept it; users won’t wait.
Deterministic workflows have a natural advantage here: fixed pipelines can parallelize, cache, and pre‑compute. An Agent cannot, because the next branch depends on the previous result.
This set of economic constraints stands independent of model capability. Even as models improve, as long as pricing and response latency remain what they are, the cost structure of long‑chain autonomous reasoning will always be worse than fixed flows. If economics don’t hold, there is no foundation for adoption.
Human‑in‑the‑Loop: Keeping Control in the Physical World
Most “Agents” actually running on core business lines today adopt an asynchronous loop with human checkpoints. When the system reaches a high‑risk state transition, it serializes the current context into a database, suspends execution, and fires off an approval request. After the approval result returns via webhook, the system resumes.
This is rarely drawn on product website architecture diagrams, but it is the real last guardrail.
Introducing a human loop is not about compensating for model capability. It is about drawing a responsibility boundary. In finance and regulated industries, compliance audits do not accept “the model decided to do something unexpected.” A named natural person must confirm that state transition is legitimate. When the engineer inserts await human_approval() into the loop, the loop is broken; the graph becomes a DAG again, and we are back in workflow territory.
When Not to Touch Agent
If the steps can be enumerated in advance, draw a workflow. Having the model decide at runtime a question whose answer is already known adds nothing but overhead.
If the number of branches is in the single digits, use conditional statements. Hard‑coded if‑else will always beat a model invocation in reliability and cost. The model can guess wrong; the conditional cannot.
If audit rigor is high, keep model decisions out of the critical path. Compliance teams can review code and test cases; they cannot review a probability distribution.
If cost and latency are primary constraints, the multi‑step loop is out.
And there is a more fundamental test: if you cannot write a concrete implementation of goal_completed, you have no evaluation plan. A production system without an evaluation plan runs on faith—and faith does not appear on an SRE dashboard.
After the Myth, Back to Engineering Common Sense
Setting up that six‑line loop takes a day. The hard part is everything else: error capture, schema validation, retry backoff, budget throttling, state rollback, audit logging, canary releases, and integration of human approvals. Stack all these pieces together, and the diagram you draw is always that directed acyclic graph.
The model call is just one node on the graph. It can be a smart node, but the edges around it are still hard‑coded.
Production systems do not need an autonomous entity ready to explore unbounded state space at any moment. They need a pipeline whose behavior is predictable, whose outputs are verifiable, whose failures are traceable. Inside that pipeline sits an LLM doing routing, content filling, and fuzzy judgment. But the pipeline itself must be deterministic.
Tear down the Agent myth, and what remains is not failure. It is a return to engineering principles: use determinism to contain uncertainty, finite states to bound infinite possibilities, and validation nodes to block error propagation. This is not regression. Any engineer woken by an on‑call call at 3 AM would rather face a clear stack trace than a several‑hundred‑kilobyte log of token‑probability distributions. The latter has no breakpoint; the former does. And that alone decides who lives in production and who stays in slide decks.
About the Creator
Jin
Writer of reamstories
https://reamstories.com/jin
Enjoyed the story? Support the Creator.
Subscribe for free to receive all their stories in your feed. You could also become a paid subscriber, letting them know you appreciate their work.
Comments
There are no comments for this story
Be the first to respond and start the conversation.