Agent Loops vs Deterministic Workflows
An AI agent does not need a complicated graph to be useful.
At its simplest, an agent is a model inside a loop:
- receive a goal and the current context
- choose the next action
- run the requested tool
- return the tool result to the model
- continue until the model returns a final answer or reaches a stop condition
This simple design works well for coding, research, troubleshooting, and other tasks where the correct route cannot be known before the work begins.
It is not the right design for every part of a system. Payments, authorization, approvals, retries, data retention, and destructive operations should not depend only on whether a model remembers an instruction.
The practical architecture is usually a hybrid:
- let the model make ambiguous, semantic decisions
- let trusted code enforce business rules and security boundaries
- place deterministic workflows around agent runs where order, recovery, or auditability matters
Three Different Control Models
Section titled “Three Different Control Models”The important question is not whether a system contains an LLM. It is who decides what happens next.
| Control model | Who chooses the next step? | Best fit |
|---|---|---|
| Deterministic function | Application code | One known transformation or rule |
| Workflow | Application code or workflow engine | Known stages, branches, retries, and approvals |
| Agent loop | Model, within code-defined limits | Open-ended work where the route depends on discoveries |
Deterministic function
Section titled “Deterministic function”A normal function is the best option when the input, operation, and output are already known.
calculate_tax(invoice) -> tax_amountThere is no benefit in asking a model to decide which arithmetic operation to perform when the rule is already encoded and testable.
Workflow
Section titled “Workflow”A workflow coordinates a known process:
validate order -> reserve inventory -> charge payment -> arrange shipmentThe workflow may contain LLM calls, but code still controls the major stages and failure behavior.
Agent loop
Section titled “Agent loop”An agent loop is useful when the sequence emerges from the task:
investigate failing test -> inspect code -> search history -> form hypothesis-> edit implementation -> run focused test -> revise if neededThe number and order of these actions cannot always be predicted in advance. The model adapts after every observation.
The Basic Agent Loop
Section titled “The Basic Agent Loop”flowchart TD
G["Goal and current context"] --> M["Model chooses next action"]
M -->|"Final answer"| F["Return result"]
M -->|"Tool request"| P["Policy and permission checks"]
P -->|"Denied"| D["Return denial or request approval"]
D --> M
P -->|"Allowed"| T["Execute tool"]
T --> O["Observation or error"]
O --> C["Update context and task state"]
C --> M
The loop is conceptually small, but a production agent also needs:
- a model and instructions
- a bounded tool surface
- context and task state
- permission and authorization checks
- turn, time, token, and cost limits
- logging and traces
- stop, escalation, and approval rules
- an execution environment or sandbox
The model proposes actions. The surrounding harness decides whether and how those actions can run.
Why Simple Loops Work
Section titled “Why Simple Loops Work”Older agent systems often tried to encode every anticipated model failure as another branch:
if request is a bug: classify frontend or backend select investigation prompt select framework prompt select test prompt ...This can become difficult to maintain. A new task shape may fall between categories, and every additional branch creates another state transition to test.
A capable tool-using model can instead:
- inspect the repository
- decide which evidence matters
- use a search or execution tool
- interpret the result
- correct its approach
The loop remains stable while the model handles variations inside it.
Simple does not mean unstructured. A useful loop still has explicit tools, limits, permissions, and observable state. It simply avoids converting every uncertain judgment into a hardcoded route.
Where Model-Directed Control Is Strong
Section titled “Where Model-Directed Control Is Strong”Let the model choose the route when:
- the task is open-ended
- the required steps depend on what the agent discovers
- semantic judgment is more useful than exact matching
- several valid approaches may exist
- tool errors require flexible recovery
- the work happens in a reversible or sandboxed environment
- success can be checked against evidence
Examples:
- investigating an unfamiliar codebase
- debugging a failure with several plausible causes
- gathering and comparing current documentation
- deciding which files are relevant to a refactor
- selecting focused tests after inspecting a change
For these tasks, a rigid graph can force the agent through irrelevant stages or prevent it from following unexpected evidence.
Where Deterministic Control Is Strong
Section titled “Where Deterministic Control Is Strong”Use trusted code or a workflow when:
- the route is already known
- order is a business requirement
- a step has financial, legal, security, or external consequences
- exactly-once or idempotent behavior matters
- the process must survive restarts or long waits
- authorization must be checked against current identity and policy
- every state transition must be auditable
- failure and compensation behavior must be predictable
Examples:
- issuing a refund
- approving access to production data
- rotating credentials
- deploying to production
- applying a database migration
- collecting required consent
- enforcing a retention policy
The model can help gather information or recommend an action. It should not be the only component deciding whether the action is permitted.
A Hybrid Architecture
Section titled “A Hybrid Architecture”Most useful production systems combine both styles.
flowchart LR
R["User request"] --> V["Deterministic validation"]
V --> A["Agent explores and proposes"]
A --> C{"Requested action type"}
C -->|"Read-only or reversible"| X["Run inside bounded agent loop"]
C -->|"Sensitive side effect"| H["Deterministic policy and approval"]
H -->|"Approved"| E["Execute trusted operation"]
H -->|"Denied"| N["Return safe explanation"]
X --> Q["Verify outcome"]
E --> Q
Q --> Z["Persist result and audit record"]
In this design:
- code validates the request and identity
- the agent explores the problem and chooses tools
- policy classifies the requested action
- sensitive operations cross an approval boundary
- trusted code performs the final side effect
- verification checks the resulting state
The agent retains flexibility without becoming the security boundary.
Example: Fixing A Production Bug
Section titled “Example: Fixing A Production Bug”A bug-fix process contains both uncertain and deterministic work.
Model-directed part
Section titled “Model-directed part”The agent can:
- reproduce the failure
- inspect logs and code
- compare likely causes
- choose relevant files
- propose and implement a patch
- select focused tests
Deterministic part
Section titled “Deterministic part”The system should:
- restrict which repository and branch can be modified
- block access to unrelated secrets
- require tests and static checks
- prevent direct production deployment
- create a pull request instead of merging automatically
- record tool calls and changed files
Trying to encode the investigation as a fixed graph would reduce flexibility. Letting the model deploy its patch directly would remove an important control.
Example: Travel Planning
Section titled “Example: Travel Planning”Travel research is open-ended:
- destinations have different transport systems
- current availability changes
- the user may value price, time, accessibility, or convenience differently
An agent is useful for research and comparison.
The final booking process is more structured:
- confirm traveler identity
- show exact itinerary and price
- collect explicit approval
- execute the booking once
- store the reservation identifier
- send confirmation
The same application can use an agent for exploration and a deterministic workflow for commitment.
DAGs Are Not Obsolete
Section titled “DAGs Are Not Obsolete”A directed acyclic graph, or DAG, represents tasks as nodes and dependencies as edges. DAGs remain useful when dependencies are real rather than invented to control model behavior.
Good uses include:
- data pipelines
- build systems
- dependency-aware migrations
- parallel work with explicit prerequisites
- fixed review and approval stages
- fan-out and fan-in processing
A DAG is less helpful when every task creates a unique path that cannot be listed ahead of time.
The choice is not “DAG or agent.” A workflow node can run an agent, and an agent can call a deterministic workflow as a tool.
Put Determinism At The Tool Boundary
Section titled “Put Determinism At The Tool Boundary”One effective pattern is to give the agent a small set of high-quality tools whose internal behavior is deterministic.
Weak tool:
admin_action(config)Better tools:
preview_refund(order_id, reason)request_refund_approval(preview_id)execute_approved_refund(approval_id)The model decides when a refund workflow is relevant. The tools enforce:
- typed arguments
- authorization
- amount limits
- approval requirements
- idempotency
- logging
- valid state transitions
This gives the agent useful freedom without asking it to recreate business logic from instructions.
Prompts Guide; Code Enforces
Section titled “Prompts Guide; Code Enforces”Instructions such as these can improve behavior:
Read a file before editing it.Run focused tests after making a change.Ask before performing a destructive action.They are not guarantees. Models can misunderstand, forget, or lose instructions during long sessions.
If a rule must always hold, enforce it outside the prompt:
| Requirement | Enforcement |
|---|---|
| Never read production credentials | Filesystem and secret-store policy |
Never merge directly to main | Repository permissions and branch protection |
| Always run formatting after edits | Deterministic hook or CI job |
| Require approval before deployment | Deployment workflow and authorization service |
| Stop after a fixed budget | Runner limit |
| Do not issue duplicate refunds | Idempotency key and transaction constraint |
Current Claude Code documentation illustrates this distinction: a skill contains instructions the model interprets, while a hook fires at a defined lifecycle event. A permission rule or sandbox can block access even if the model requests it.
Task Lists Are State, Not Authority
Section titled “Task Lists Are State, Not Authority”A task list helps an agent:
- break work into smaller units
- show progress to the user
- resume after interruption
- remember unresolved items
- avoid silently stopping after the first change
But a model-maintained task list is not a transaction log. The agent may mark an item complete prematurely or fail to update it.
For critical workflows, persist authoritative state in application code:
requested -> validated -> approved -> executing -> completed -> failedThe agent may explain or propose transitions. The workflow engine owns them.
Small Tool Surface, Not One Universal Tool
Section titled “Small Tool Surface, Not One Universal Tool”A small, composable tool surface is easier for an agent to understand and evaluate. Shell tools are especially effective for coding work because they compose well and coding models have extensive exposure to command-line workflows.
The durable lesson is not literally “Bash is all you need.”
Shell access is powerful because it can:
- compose existing programs
- inspect files
- run tests
- create temporary scripts
- use standard development tools
It is also broad and difficult to secure. Purpose-built tools are preferable when:
- the action has sensitive side effects
- arguments need strong validation
- authorization varies by resource
- outputs must be bounded and structured
- the operation needs idempotency or audit semantics
Use general tools for exploration inside a sandbox. Use narrow tools for important commitments.
Failure Modes
Section titled “Failure Modes”| Failure | Why it happens | Better design |
|---|---|---|
| Huge routing graph for every task variation | The system tries to predict open-ended work | Use one bounded loop for exploration |
| Agent decides authorization from prompt text | Instructions are mistaken for policy | Enforce identity and policy in trusted code |
| One universal shell with full host access | Convenience becomes unlimited authority | Sandbox it and restrict credentials/network |
| Workflow used for ambiguous research | Fixed stages force irrelevant work | Let an agent select investigative steps |
| Agent used for known arithmetic or validation | Model variance replaces a reliable function | Use deterministic code |
| Task list treated as durable state | Model-managed progress is not authoritative | Persist critical state separately |
| More agents added without a need | Coordination and context costs increase | Start with one agent and split deliberately |
Architecture Decision Checklist
Section titled “Architecture Decision Checklist”For each decision in the system, ask:
- Is the correct action already known?
- Does the choice require semantic judgment?
- Can a wrong action be reversed?
- Does the action cross a security or financial boundary?
- Must the process survive a restart?
- Is exact ordering required?
- Can success be checked automatically?
- Does a human need to approve the commitment?
- What state is authoritative?
- What is the maximum acceptable cost, time, and number of turns?
If the route is unknown but the environment is bounded and verifiable, an agent loop is a good candidate.
If the route is known or the action is consequential, keep control in deterministic code.
Key Takeaways
Section titled “Key Takeaways”- An agent can be implemented as a simple model-tool loop.
- Simple loops fit open-ended tasks whose steps emerge from evidence.
- Workflows and DAGs remain useful for known dependencies, approvals, recovery, and auditability.
- Production systems usually combine a flexible agent inside deterministic boundaries.
- The model proposes actions; permissions, policy, and trusted code authorize them.
- Put business invariants, idempotency, and irreversible side effects behind narrow tools.
- Prompts improve behavior, but only code and infrastructure can enforce a rule.
- Add architectural complexity only when evaluation shows that it improves the outcome.