Graph Engineering for AI Agents: Beyond Linear Chains
When one agent loop is not enough, the control flow becomes a graph. A practical guide to nodes, edges, state reducers, parallel fan-out, checkpoints and human-in-the-loop interrupts.
A single agent loop is a fine architecture until the work has structure. The moment you have a research step that must finish before a drafting step, three checks that can run in parallel, and one decision that requires human approval, a linear chain starts encoding that structure implicitly in the prompt โ and implicit structure is untestable.
Graph engineering makes the structure explicit. Instead of one model deciding everything, you declare nodes, edges and shared state, and let the model make decisions only where a decision is genuinely needed.
Loop versus graph: choosing the abstraction
| Signal | Use a loop | Use a graph |
|---|---|---|
| Task shape | Open-ended exploration | Known stages with dependencies |
| Parallelism | Rare, opportunistic | Deliberate fan-out and join |
| Approval points | None or one at the end | Mid-flow human review |
| Resumability | Restart is cheap | Long-running, must resume |
| Auditability | Transcript is enough | Need per-stage provenance |
Most real systems are hybrids: a graph at the top level, with individual nodes containing bounded agent loops.
The four primitives
1. Nodes are pure-ish functions over state
A node takes the shared state and returns a state delta. Keep them single-purpose โ classify, retrieve, draft, verify, publish โ and keep side effects at the edge of the node so it can be retried. A node that does three things cannot be retried, cached or tested independently.
2. Edges encode routing, not reasoning
Three edge types cover nearly everything:
- Static โ always A then B. Use these wherever possible; they are free and deterministic.
- Conditional โ route on a value already in state (a classification label, a score threshold, an error flag). The model may have produced the value in an earlier node, but the routing itself is code.
- Dynamic fan-out โ spawn one branch per item in a list, then join.
The discipline: decide with the model, route with code. Routing logic in a prompt is a coin flip you cannot unit-test.
3. State needs reducers, not overwrites
Shared state is where parallel graphs break. Define per-key merge semantics up front:
- Append for messages, findings and logs.
- Last-write-wins for scalars owned by exactly one node.
- Set union for discovered entities and URLs, to deduplicate naturally.
- Custom merge for scored candidates โ keep the top N, not the last N.
If two parallel branches can write the same key without a reducer, you have a race condition with a language model in it.
4. Checkpoints make graphs resumable
Persist state after every node with a thread identifier. Three capabilities fall out immediately: resume after a crash or a serverless timeout, replay from any node while debugging, and pause indefinitely for human input. For long-running agentic work this is the difference between a demo and a product.
Parallel fan-out: the biggest latency win
Independent work should never be sequential. An audit graph that checks DNS, TLS, headers, performance and metadata runs those five nodes concurrently and joins the results. The rules that keep fan-out safe:
- Cap concurrency explicitly โ fan-out multiplies rate-limit pressure.
- Give every branch its own timeout and treat a slow branch as a partial result.
- Join on settled, not all-succeeded: one failed branch should degrade the report, not fail the run.
- Record per-branch status in state so the final node can say which checks were skipped.
Human-in-the-loop as a graph feature
Approval is not an if-statement. Model it as an interrupt: the graph reaches an await_approval node, persists a checkpoint, emits a notification, and halts. A later resume call carries the decision into state and routing continues. Because the checkpoint is durable, the wait can be minutes or days โ and the approval is auditable, which is what compliance actually asks for.
Common graph anti-patterns
- The god node. One node with every tool and a 4,000-word prompt. Split by responsibility.
- Chatty supervisors. A router that calls a model to decide something already present in state.
- Unbounded cycles. Every cycle needs a visit counter and a forced exit edge; graphs inherit loop discipline, they do not replace it.
- State as a dumping ground. If everything is in state, nothing can run in parallel safely. Type it and scope it.
- Invisible edges. If you cannot draw the graph from the code, neither can the engineer debugging it at 2am.
Testing a graph
Graphs are far more testable than chains, and that is the main reason to adopt them. Test nodes in isolation with fixture state. Test routing functions as pure functions over state โ no model calls needed. Then run a small set of golden end-to-end threads with recorded tool responses, asserting the visited-node path rather than exact output text.
Putting it together
The pattern that holds up in production: a top-level graph for structure, bounded loops inside nodes for open-ended work, reducers for safe parallelism, checkpoints for resumability, and code for every routing decision. Start with loop discipline, add graph structure when dependencies appear, and manage the growing transcript with context engineering.
If you are mapping agentic workflows onto an existing marketing stack, our marketing automation and AI app development practices do exactly this kind of orchestration design.
Free calculators: ROAS calculator ยท LTV calculator ยท CPM calculator ยท CTR calculator ยท CPC calculator
Want to implement these strategies?
Book a free consultation with our AI Engineering experts.
Get Started