Control flow is how the agent loop is actually implemented in code — the mechanism that calls the LLM, routes its decision to the right action, and decides when to stop. This is framework-agnostic; the concept holds whether you write it by hand or use a library.
Pattern 1 — A Plain Loop
while not done and iteration < max_iterations:
decision = get_llm_decision(state)
if decision.action == "final_answer":
done = True
else:
result = execute_validated_tool(decision)
state = update_state(state, decision, result)
iteration += 1
Simple, transparent, and easy to reason about for straightforward agents — the whole control flow fits in a few lines.
Pattern 2 — A State Machine
states = {
"deciding": decide_next_step,
"executing_tool": run_tool,
"awaiting_approval": wait_for_human,
"done": finalize,
}
current_state = "deciding"
while current_state != "done":
current_state = states[current_state](context)
More structured — useful once an agent has genuinely distinct modes of operation (e.g. needing to pause for human approval), rather than a single uniform loop.
Pattern 3 — A Graph
Some frameworks (see LangGraph) model the agent as an explicit graph of nodes and edges — each node a step, each edge a possible transition, including conditional branches. This makes complex control flow (branching, loops, human-in-the-loop pauses) more visualizable and composable than a hand-rolled loop, at the cost of an added framework dependency and its own learning curve.
Choosing a Pattern
| Pattern | Best Fit |
|---|---|
| Plain loop | Simple, single-purpose agents; easiest to understand and debug from scratch |
| State machine | Agents with genuinely distinct modes (e.g. normal operation vs. awaiting approval) |
| Graph-based framework | Complex, branching, multi-agent, or long-running workflows where visualizing the flow is valuable |
Common Mistakes
- Reaching for a heavyweight graph framework for a simple, linear agent — adds complexity without a corresponding benefit
- Hand-rolling control flow for a genuinely complex, branching multi-agent system where a framework's tested primitives (checkpointing, conditional edges) would save significant effort and reduce bugs
- Putting business logic and safety checks directly inside the LLM-decision step instead of the control-flow layer, making both harder to test independently
Interview Relevance
"When would you use a state machine or graph framework instead of a simple while loop for an agent?" — a good answer weighs task complexity (branching, pausing, multi-agent coordination) against the added dependency and learning curve.
Practice Question
Sketch (in the plain-loop style above) the control flow for an agent that must pause and wait for human approval before executing any action that modifies data.