Three nodes into a flow that works, someone types two things in one message. One of them belongs to a different process entirely, and they want an answer to both. There is no branch for that.
Ask when to use an AI workflow and when to use an agent and you get the same answer five times over: hybrid. Deterministic boundaries where you need reliability, agent autonomy where you need flexibility. It is correct. It is also where the argument stops instead of where it starts, because the whole difficulty lives in the seam and nobody specifies the seam.
Watch what each side does with it. The workflow will not leave the path, so it re-asks for the account number, and then re-asks for the account number, and the person starts typing "human". The mono-prompt agent leaves immediately and has nowhere to come back to: it answers the second question, quietly drops the two identity checks it owed you, and buries them under forty turns nobody will ever read.
Every one of these systems has a way to stop. Almost none has a way to come back.
Escalation to a human queue, confidence thresholds, breakers that trip and terminate, guardrails, retries. All exits.
So here is the position, and I am not balancing it later: default to the structured workflow, and reach for the mono-prompt agent at exactly one point, the turn you could not enumerate in advance, and not even there if anything in that turn has to be provable later.
That is asserted, not earned. The next four sections earn it, starting with why the workflow gets the default.
A finite set of paths is the entire audit argument
A structured workflow's compliance strength is not a sign that somebody built it carefully. It is a property of the shape. The set of paths through it is finite by construction, so you can enumerate them, test them, and show them to somebody a year later.
That single property does two jobs. It is the audit trail, because a finite path set is a thing you can produce on request. And it is the debugging story, because failure lands somewhere with a name.
When a workflow breaks, a named node failed. When an agent breaks, a turn went bad. Only one of those goes in a ticket.
You do not need a statute to feel the weight of this. At some point a regulator, an auditor or a customer's legal team asks you to show what ran and in what order, and "the model handled it" is not an answer.
That is the whole argument for the default, and it is the least contested claim here. The interesting part is that the same finiteness is also the workflow's only real weakness.
The workflow's real failure is not rigidity, it is the turn it cannot represent
Most write-ups of the limitations of AI workflows land on "rigid". Rigid is an abstraction, and it lets everybody nod without picturing anything.
Here is the specific failure. The flow cannot represent the turn, so it does the only thing it can, which is ask again. The second request for the same field is the moment a person stops believing there is anything behind the screen. They do not file a bug. They type "human", or close the tab.
Branch proliferation is the same problem one level up. Every case off the happy path is a branch somebody writes, tests, and owns the next time the process changes. Add a second axis and the count multiplies rather than adds. That is not a maintenance smell, it is arithmetic.
Two mitigations, both real, both with a bill attached.
Park and return. Capture the out-of-workflow query as a queued item, say out loud that you have it, finish the obligation in front of you, then come back. The cost is that it only works on a user willing to be told to wait, which is precisely not the user about to type "human".
Hold branches to one axis. Pick the axis that genuinely changes the path and handle the rest as data on the node. The cost is that you trade per-branch testability for a classifier you now have to evaluate, and the failure moves from a visible missing branch to a silent misclassification, which is worse to discover six weeks later.
There is a third mitigation, which is to design the break rather than patch the branch. That one is the rest of this article.
The obvious answer to a turn you could not enumerate is a system that does not need it. So let me give that side its honest hearing.
What the agent actually buys you
The honest version of the agent's strength is smaller than the vendor version and considerably more useful.
The next turn does not have to be enumerated in advance. That is the whole of it. Nobody predicted the message with two things in it, and the agent handles it anyway, because handling turns it has not seen is what it is for.
The second half matters more than people admit: it changes by editing text. A branch is a release. A prompt is a paragraph you rewrite on a Tuesday and watch in production on Wednesday. When the process is still moving under you, that gap in iteration speed is the strongest argument on this side, and the workflow cannot match it at any price, though you pay for the flexibility in tokens on every turn.
So, when to use an AI agent instead of a workflow: when the space of next turns is genuinely open, and when you can afford to find out afterwards what it did.
That second clause is doing a lot of work. Two weaknesses make the exception narrow rather than general, and neither is fixable with a better prompt.
Context growth, and why "usually did the step" is not a property
Both of these are mechanical. That is what makes them arguments rather than complaints, and why I would rather reason them out than out-cite the pages asserting them louder.
Start with what happens to your instructions. Every turn appends, so by the twenty-fifth exchange the standing rules sit somewhere in the middle of a long transcript, competing with everything the conversation has accumulated since. Liu and colleagues' "Lost in the Middle" work found material is recovered most reliably from the beginning and the end of a context and least reliably from the middle, even for models built for long contexts. Context window degradation is not the model forgetting. It is the twenty-fifth turn not running under the same instructions as the third.
Two mitigations, neither free.
Compact rather than append. Summarise the history instead of carrying all of it. The cost is that naive summarisation drops things silently, so a validated compaction step buys bounded growth and charges you latency, engineering time, and a second system whose failures are invisible by design.
Re-assert the standing instructions at the end of every turn. Cheap to build, and it works, for the instructions. The cost is token spend on every turn forever, and it does nothing for the process data in the middle.
Now the second weakness, which is worse because it does not look like one. Nothing structurally requires the agent to have done the step. It usually does. "Usually" is the entire problem: a property is something a system cannot fail to have, and "usually" is a description of behaviour. The MAST taxonomy, built by annotating real multi-agent traces, makes failure to verify a nominally owned step one of its top-level failure categories, and nothing about that mechanism needs other agents present to bite.
The mitigation is not a better prompt. It is to move the obligation out of the prompt and into a check the workflow owns. The price is worth stating up front: the agent can never own a provable step.
Both weaknesses point at the same place, the moment control changes hands, and that moment has a name problem before it has a design problem.
Taking the term back, and what should actually fire it
I am going to call this a circuit breaker, and I need one sentence to stop you filing it where the term currently lives: in practitioner writing about AI agents a circuit breaker is the reliability pattern that watches itself, trips on a threshold, and terminates and logs, and that is not this, because this one hands control somewhere and then takes it back.
Keep the term anyway. It is the right metaphor for something that interrupts a circuit deliberately and can be closed again.
Now the harder half, which is what fires it. The best-argued page on this subject offers a confidence score: the model reports it is unsure, and the process routes to a human review queue. Look at what that concedes. The score comes from the same model whose judgment is in question. The destination is a person rather than the flexible side, which means the architecture never trusted the agent with the turn. And nothing describes control coming back.
A trigger worth building is a classification the workflow owns, not a self-report the agent volunteers. Three conditions, any of which fires it:
- The turn resolves to no enumerated intent for the current node, after a bounded number of attempts rather than on the first miss.
- The turn carries an intent that belongs to a different process.
- The user asks for it outright, in whatever words your users actually use.
Handing control from workflow to agent starts here, with the deterministic side deciding it cannot proceed. The trigger decides when control leaves. The next question is what leaves with it.
What the break captures, and what the other side is allowed to touch
A break is only a break if something survives it. So the captured state is a list, and I mean a literal list an engineer can implement:
- Position in the flow: the node that was executing, and the one that comes next.
- The obligations outstanding at the moment of the break, named individually.
- The process data collected so far, each item carrying the turn that produced it.
- The user-visible commitments already made, because the person on the other end remembers them even if the process does not.
- The permission set the workflow was holding when it let go.
None of this is exotic. LangGraph's interrupt and resume pair already checkpoints full graph state, pauses indefinitely, and picks up on command, so the primitive under a return path is something you can use rather than invent. Deterministic orchestration engines have had a version for years. What is missing is not the mechanism.
What is missing is the last item on that list, and it is the difference between a break and a hole.
When control passes to the flexible side mid-process, it inherits whatever the workflow was authorised to do, unless somebody decided otherwise. That decision is almost never deliberate. Worth noticing: the most widely used framework for this pattern documents captured state in detail and says nothing about what the paused actor may touch while it holds control, which makes this a gap in the practice rather than a point I am inventing.
The default should be the other way round. The flexible side inherits nothing. It gets a read scope and a narrow write scope, fixed per break point at design time, and specifically it may not discharge an obligation, mutate collected process data, or make a user-visible commitment. It can talk. It can look things up. It cannot spend the process's authority.
That is not human in the loop escalation wearing a different label. A queue is a destination. This is a loan.
Everything so far is still an exit, and the exit is the part everybody already has.
The return path
This is the half nobody wrote down, so it gets specified rather than gestured at. Three things, in order: the condition, the verification, and the fate of the obligations.
The return condition is a conjunction, not an event. A single event is how an exit gets mistaken for a break. All three of these hold before control comes back:
- The flexible side signals that it is done.
- The workflow re-validates its own preconditions rather than trusting the handback.
- A bound has not expired. Give the break a turn budget or a wall clock, because a break with no deadline is an exit with better branding.
The middle one is the one people skip. The agent saying "I have finished" is a claim about its own behaviour, and this entire article is about not accepting those. Re-check the state you care about against the state you left.
There is a real cost to building this on the primitive that already exists, and it is worth knowing before you design around it. A resumed node in LangGraph restarts from the beginning rather than from the line that paused, so any side effect you placed before the interrupt point fires a second time on resume. Charge the card before the break and you charge it twice. That is not a reason to avoid the pattern. It is a reason to put side effects after the interrupt point, and to know which of your nodes are not idempotent before production tells you.
Then the obligations, which is the part that closes the loop. The workflow comes back holding the list it had not discharged when it let go. For each item on it:
- Re-present it as a required step. Do not assume it got covered while control was out. It probably came up. "Probably" is the same word as "usually" and it is the same problem.
- Verify it structurally, from process state, rather than from the flexible side's account of what it did.
- If an obligation can no longer be discharged, because the process has moved past the point where it was meaningful, fail the return into an escalation rather than closing the loop with a hole in it.
This is the compliance mitigation I promised earlier, now cashed. The agent still cannot own a provable step and it never will. The workflow can own the check that the step happened, and that is what turns "usually did it" into something the process asserts rather than something the model tends to do.
With the seam specified, the rule stops being an assertion.
The rule, and where it runs out
Same words as the intro, and I am not walking any of it back: default to the structured workflow, and reach for the mono-prompt agent at exactly one point, the turn you could not enumerate in advance, and not even there if anything in that turn has to be provable later.
It is a consequence now rather than an assertion. The workflow gets the default because a finite set of paths is what makes a process showable afterwards. The agent gets exactly one turn because both of its weaknesses are mechanical rather than incidental. And the exception is safe only because the seam is specified, which was the part missing everywhere else.
Where it runs out, because a rule that covers everything decides nothing:
- Unattended backend automation. No user, so nothing diverges in the sense this article means. The triggers are different and the argument needs another shape.
- Anything with a third party in it. Once another system or another agent is in the loop this stops being one workflow against one agent, and becomes a question about single agent vs orchestrated workflow design.
- The process where every step has to be provable. The exception never fires. The answer is just the workflow, and you should be relieved rather than disappointed.
This is a position, not a framework. A hybrid AI agent workflow architecture is what you get when a page declines to choose, hands the decision back to you unchanged, and calls it balance. You already knew you could combine them. What you needed was where the line goes.
What you are actually building
Go back to the message with two things in it.
With the seam specified, that turn does not end anybody's afternoon. The workflow notices it cannot represent the request, which it knows because it owns the classification. It writes down where it is, what it owes, and what it already promised. It hands the turn out on a short leash with no authority to spend. The agent answers the other question, the one thing here it is genuinely better at. Then the workflow takes the turn back, checks its own preconditions rather than taking anyone's word, and asks for the two identity checks it still owes, because it kept the list.
Nobody types "human".
The thing you are building was never the handoff. Everybody builds the handoff. The thing worth building is the way back, and a system that hands control out and cannot take it back has not built a breaker. It has built a door, and it is standing there wondering why the room is empty.