Graph Engineering: A Practical Guide to the Structure Behind Multi-Agent Systems
Graph engineering is the practice of designing the structure a group of AI agents runs inside — which nodes exist, which edges route work, and what state travels between them. A practical guide to when splitting one agent loop into a graph earns its complexity, and when it doesn't.
Graph engineering is the practice of designing the structure a group of AI agents runs inside: which specialised nodes exist, which edges route work between them, and what shared state travels along those edges. Where prompt engineering shapes one response and loop engineering shapes one agent's cycle, graph engineering shapes the topology — who does what, in what order, and who checks the result.
That is the whole idea. The rest of this guide is about when it earns its complexity, and when it is a diagram you drew to feel organised.
Where this came from
In 2025 the interesting question was how to write a good loop. You gave one agent a trigger, a task, and a success criterion, and let it run until the criterion was met. We wrote about that pattern when the head of Claude Code described giving up prompting in favour of loops, and our position then was deliberately unexcited: loops are real and directional, they work on bounded and verifiable work, and the confidence in the retelling outran the production evidence.
By mid-2026 the vocabulary moved again. The term "graph engineering" started circulating in July, reportedly kicked off by Peter Steinberger asking publicly whether the field had already moved past loops. Within weeks there were guides, framework retrospectives, and enterprise architecture posts. The claim in most of them is roughly: loops were the 2025 idea, graphs are the 2026 idea, and if you are still writing loops you are behind.
We do not think that is quite right, and the reason matters for how you build.
The disambiguation nobody does first
There are two different things called graph engineering, and mixing them up will waste a week.
Knowledge graph engineering is about data. Nodes are entities and facts, edges are relationships between them, usually carrying temporal and source information. You design an ontology, extract entities and relations from documents, resolve duplicates, and serve the result to a model as structured memory. This is a decades-old discipline that got a second life as a retrieval strategy for LLMs.
Task graph engineering is about systems. Nodes are units of work — an agent, a deterministic function, a router, a human approval step. Edges are execution dependencies. You are designing the org chart of a machine, not a database schema.
Some of the best public material deliberately covers both. The codejunkie99/graph-engineering repository — a genuinely useful resource, and the most practical of the sources we surveyed — is explicitly split into these two halves: knowledge graphs as agent memory, task graphs as agent workflow. That is a defensible way to teach it, because a serious agent system eventually needs both.
But when someone in 2026 says "we're doing graph engineering," they almost always mean the second thing. TrueFoundry's enterprise guide draws the line sharply: graph engineering structures the system — agents, roles, dependencies — rather than the data structures. This guide is about that second meaning. Where knowledge graphs come up, we will say so.
The four layers
The clearest way to place graph engineering is as the fourth in a stack, each layer controlling something the one below it cannot:
- Prompt engineering — What it controls: One model response · The unit you design: The instruction
- Context engineering — What it controls: What the model can see · The unit you design: Retrieval, memory, window budget
- Loop engineering — What it controls: One agent's observe–reason–act cycle · The unit you design: Trigger, task, success criterion
- Graph engineering — What it controls: Topology across many nodes · The unit you design: Nodes, edges, shared state
This framing is TrueFoundry's, and it is the single most useful thing to take away, because it makes clear that the layers stack rather than replace. You do not stop writing prompts because you discovered context engineering. You do not stop writing loops because you discovered graphs. A node in your graph is an agent running a loop, executing a prompt, reading a context window. Every layer is still there; you have just added a way to arrange them.
Anyone telling you to "forget loop engineering" is selling the headline, not the architecture.
The deflationary truth
Here is the part the excited posts skip, stated most bluntly by the people with the most reason to inflate it.
LangChain has spent three years building LangGraph, which is to say three years building the graph abstraction commercially. In their own retrospective, they say the distinction between loop engineering and graph engineering is semantic — a loop is simply the simplest cyclic graph. They point out that LangChain itself, built on basic loops, runs on top of LangGraph. The 2026 guide from AI Builder Club reaches the same conclusion from the other direction: "a loop is just a single-node graph with an edge back to itself."
So the honest version of the 2026 story is not loops were wrong, graphs are right. It is:
You were always building a graph. Most of the time it had one node. The question is whether adding nodes buys you anything.
That reframing changes what you should be doing. You are not migrating to a new paradigm. You are deciding, per system, whether to split one node into several — and paying a real cost when you do.
There is one genuine discontinuity worth naming, and LangChain identifies it well: coding agents got good enough to be nodes. An agent inside an agent used to be an unreliable idea. Now the sub-unit you compose with can itself be a capable agent rather than a single model call, which makes multi-layered systems viable in a way they were not two years ago. That is a real change. It is just not the same claim as "loops are obsolete."
Anatomy: nodes, edges, state
Three things to design. That is the whole surface area.
Nodes
A node is a unit of work with a clear owner and a clear output. It can be:
- Agentic — calls a model, uses tools, decides its own path within its scope
- Deterministic — a plain function, a database write, a formatter, a validator
- A router — inspects state and picks the next edge
- A human checkpoint — work stops until a person approves
The mistake beginners make is assuming every node must be an agent. Most good graphs are mostly deterministic, with agents at the points that genuinely need judgment. Every agentic node is a place where the system can be creative — which is another way of saying a place where it can be wrong.
The design rule that matters is atomicity. "Research everything" is not a node. "Research what this company announced in the last quarter" is a node. Small, focused, verifiable scope is what makes a node's output checkable, and checkability is the entire value proposition of splitting work up.
Edges
An edge is a permitted transition. The critical property of agent graphs — and this is the hardest-won lesson in the LangGraph retrospective — is that they need cycles. Production systems retry, pause for human input, and refine iteratively. That is fundamentally incompatible with a directed acyclic graph. If your orchestration tool cannot express "go back and try again," it will not survive contact with real work.
The second property is dynamic transitions. You often do not know at design time how much downstream work exists. A research step might find three sources or thirty. LangGraph's Send API exists for exactly this: a node creating a variable number of downstream tasks at runtime. Any map-reduce or supervisor-worker pattern needs this, and a framework without it forces you to hardcode fan-out width.
State
State is what travels along the edges. It is the least glamorous of the three and the one that ruins the most projects.
Two failure modes, opposite in direction:
- Too much state — you pass the entire accumulated context to every node, and you have rebuilt the single-agent context problem with more steps and more cost. Every node now reads everything, so every node degrades as the run grows.
- Too little state — nodes cannot see what they need, so they re-fetch, re-derive, or hallucinate the missing piece, and your parallel workers each independently discover the same fact.
The discipline is to define, per edge, the minimum payload the downstream node needs to do its job. This is genuinely hard and it is where most of the engineering time goes. If someone describes graph engineering as easy, they have not shipped one.
The same task, done both ways
Abstractions argue past each other. Here is one concrete task built twice.
The task: every weekday at 07:00, produce a briefing covering what happened overnight across four sources — a YouTube channel set, a subreddit, a set of X accounts, and an inbox — with links, deduplicated, and no filler.
As a loop
One agent. The trigger is the schedule. The task is "read all four sources and write the briefing." The success criterion is a checklist: covers all four sources, includes links, over a minimum length, no duplicate items. If the check fails, run again.
This works, and for a while it works well. Then it degrades in a specific and recognisable way:
- By the time the agent reaches the inbox, its context is full of Reddit threads. Quality on the fourth source is visibly worse than on the first.
- Everything is sequential, so the run takes as long as all four sources combined, even though nothing about the inbox depends on YouTube.
- When the briefing is wrong, you cannot tell where it went wrong. There is one blob of reasoning and one output.
- The success check is performed by the agent that wrote the thing, against criteria loose enough to always pass. "No filler" is not a check an author can run on itself.
Notice that none of these are fixed by a better prompt. They are structural.
As a graph
Four research nodes, one per source, running in parallel. Each has a narrow scope and its own success criterion — this node covers this source, with links, for this time window. Each starts with a clean context containing only what it needs.
Their outputs flow into a synthesis node, which does one job: merge, deduplicate, and draft. It never touches the sources directly, so its context holds four structured summaries rather than four raw feeds.
The draft then goes to a review node with a separate context — it sees the draft and the criteria, not the research reasoning that produced it. If it passes, the briefing ships. If it fails, the edge routes back to synthesis with the specific objection, capped at three attempts before it escalates to a human instead of looping forever.
What that bought, concretely:
- Context per unit of work — Loop: All four sources, accumulating · Graph: One source, clean
- Wall clock — Loop: Sum of all four · Graph: Slowest single source
- Failure localisation — Loop: "The briefing is wrong" · Graph: "Node 3 missed the window"
- Verification — Loop: Self-assessed · Graph: Independent context, can reject
And what it cost: four success criteria to maintain instead of one, a state schema between research and synthesis, a retry cap and an escalation path, and per-node tracing so the failure-localisation benefit is actually realisable rather than theoretical.
That trade is clearly worth it here, because all four splitting conditions below apply at once. For a briefing that reads one source, none of them do — and the same graph would be pure overhead.
When topology earns its complexity
A graph costs you something: more moving parts, more failure modes, harder debugging across boundaries, more tokens spent passing state, and a topology you have to keep accurate as requirements change. So the question is never "should I use a graph." It is "does this specific system pay for one."
Four conditions, any of which justifies splitting:
1. Context pressure. The single loop's context window is filling up with material relevant to only part of the task, and output quality degrades as it fills — the failure mode usually called context rot. Splitting into focused nodes means each one carries a smaller, more relevant window. This is the most common and most legitimate reason, and it is measurable: watch where quality drops off as a run gets longer. As a rough anchor, teams tend to feel this somewhere north of a few hundred thousand tokens in a single run, but the threshold is task-dependent and the honest test is your own output, not a number.
2. Independent verification. The work is high-stakes enough that you want a reviewer that did not do the work. This is the strongest structural argument for graphs and it is not achievable inside one loop, because an agent reviewing its own output shares the reasoning that produced the error. A separate verifier node with a clean context is a genuinely different check.
3. Real parallelism. Multiple sub-tasks are actually independent and the wall-clock time matters. Note actually — most work people describe as parallel has hidden ordering constraints. The codejunkie99 material has a sharp heuristic here: eliminate fake dependencies before you parallelise, because a dependency you invented is a serialisation you did not need.
4. Governance boundaries. You need per-node attribution — which agent spent what, who approved which action, what the audit trail says. This is the enterprise driver, and it is a topology question because attribution requires the boundaries to exist in the first place.
And the cases where you should not:
- The task fits comfortably in one context and completes reliably. Adding nodes adds failure modes and buys nothing.
- You cannot articulate the success criterion for each node. If you cannot check a node's output, splitting has not helped — you have distributed the ambiguity.
- The topology is genuinely unknown until runtime, and not in a fan-out way. If every run needs a different shape, you may want an agent that plans, not a graph you declared.
- You are doing it because it is what people are posting about.
Six steps to building one
This is the sequence we would follow, and roughly the sequence the better sources converge on.
Step 1 — Write the success criterion for the whole system first
Before any topology, state what "done and correct" means for the entire run, in terms you could check mechanically or by reading one artifact. If you cannot write this, stop. Every subsequent decision — where to split, what to verify, when to retry — derives from it, and a graph built without it becomes an elaborate way to produce unfalsifiable output.
Step 2 — Decompose into atomic tasks
List the units of work. Push toward smaller: "research YouTube," "research Reddit," "research Twitter" beats "research everything." For each one write its own success criterion. If a unit's criterion is vague, it is still too big.
At this stage, ignore ordering entirely. You are inventorying work, not sequencing it.
Step 3 — Find the real dependencies
Now sequence — but be aggressive about what genuinely depends on what. For each pair, ask whether B actually requires B's input from A, or whether you simply imagined them in that order. Fake dependencies are the main reason graphs run slower than they should.
What remains is your edge set. Whatever is left unordered can run in parallel.
Step 4 — Decide what each node sees
For each edge, define the payload. Be explicit and be minimal. Write it down as a schema if you can — untyped state passed between agents is where graphs rot.
This is also where you decide what is shared versus passed. A read-only reference the whole graph can consult (a knowledge graph, a spec, a set of brand rules) is different from a result flowing along one edge. Conflating them is how nodes end up with contexts nobody designed.
Step 5 — Put verification where errors are expensive
Add verifier nodes at the boundaries where a wrong answer costs the most. The pattern worth knowing is what the codejunkie99 material calls the diamond: parallel workers fan out, each doing focused work, then a verifier with a separate context checks the merged result, and one node owns the final output.
The separate context is the load-bearing part. A verifier that inherits the worker's reasoning is not an independent check — it is the same agent agreeing with itself.
Step 6 — Place the human checkpoints
Decide which actions require approval before they execute. Anything irreversible, anything customer-facing, anything that spends money. The graph should stop and wait, not notify and proceed.
This is the step people skip when they are excited, and it is the step that determines whether the system is deployable in an organisation that has consequences.
Patterns worth knowing
Diamond (fan-out, verify, merge) — parallel focused workers, an independent verifier, one owner of the result. The default shape for research and analysis.
Supervisor–worker — a coordinating node assesses the task and dispatches a variable number of workers, then synthesises. Needs dynamic transitions. Good when the amount of work is unknown until you look.
Map-reduce — the same operation across many items, then aggregation. The simplest genuine use of parallelism, and the easiest to get right.
Loop-until-criterion — a node cycles back to itself until its success criterion passes, with an iteration cap. This is loop engineering, correctly placed as one node inside a larger graph. The cap is not optional.
Human-in-the-loop gate — execution pauses at a node until approval. Note that this requires your framework to support genuine suspension and resumption, not just a blocking call, if runs can outlive a process.
A useful reality check from the enterprise side: deep research tools — the ones that work — spawn tens to hundreds of sub-agents in parallel rather than running one long loop. The pattern is proven at the high end. That does not mean your three-step internal workflow needs it.
The part that makes it compound
Everything above describes a graph that runs. What separates a graph that runs from a system that gets better is what you keep from each run.
Every node execution produces evidence: what it received, what it produced, whether its criterion passed, how long it took, what it cost. Most teams throw this away, or bury it in application logs nobody reads. That is the difference between automation and a system that improves.
Three things worth persisting per run:
- Per-node pass/fail against its criterion. Over weeks this tells you which node is your weak link — usually not the one you'd guess, and almost never the one you spent the most time designing.
- What the verifier rejected, and why. The rejection log is the highest-signal artifact the whole system produces. It is a list, in production's own words, of the ways your graph is wrong.
- Cost and latency per node. Without this you cannot tell whether splitting actually bought you the parallelism you designed for, and you cannot find the node quietly consuming most of the budget.
This is also where the two meanings of "graph engineering" finally meet. The run history — what was produced, by which node, from which source, when — is naturally a knowledge graph: entities, relationships, temporal and provenance metadata. Teams that get compounding value are usually the ones feeding a structured store of prior runs back in as context, so the system starts each run knowing what happened last time rather than starting cold.
Be honest about the sequencing, though. This is a later-stage concern. A first graph that produces a correct output with no learning loop is a success; a first graph with an elaborate telemetry pipeline and no working output is not.
What actually breaks
The honest section. These are the failure modes, and none of them are solved by picking a better framework.
State bloat. The most common. You start passing a little extra context "just in case," and six weeks later every node receives the full run history. Symptoms: cost climbing faster than usage, quality degrading late in long runs. Fix: audit the payload on every edge, and be ruthless.
Verification theatre. You added a reviewer node, so you feel covered. But the reviewer shares context with the worker, or its criterion is "does this look good," or it has no authority to reject. A verifier that has never failed anything is not verifying.
Topology drift. The graph you drew and the graph that runs diverge. Someone adds a conditional edge for an edge case, then another, and the diagram in the README stops being true. This is worse than having no diagram, because people trust it. Generate the topology from the code, or accept that the doc is fiction.
Debugging across boundaries. Splitting work makes each node easier to debug and the system harder. When the final output is wrong, you now have to determine which of nine nodes introduced the error, and the answer is often "node three produced something technically valid that node seven misread." You need per-node tracing before you need more nodes.
Comprehension debt. This carried over from our loop piece and it gets worse here, not better. A graph that produces good output while nobody on the team can explain the routing is a liability that compounds. Speed of output is not the constraint; speed of understanding is.
Complexity as procrastination. The one nobody writes about. Designing an elegant topology is genuinely enjoyable, and it feels like progress. Building the boring deterministic node that actually does the work does not. Watch for teams with beautiful graph diagrams and no shipped output.
Governance, if you are doing this in an organisation
If the system spends money, touches customer data, or takes actions someone will be accountable for, topology is not only an engineering concern. TrueFoundry's enterprise checklist is the most concrete public treatment; condensed, the questions worth answering are:
- Does every node that calls a model or tool have a resolved identity?
- Do calls carry stable graph, run, and node identifiers, so a trace can be reconstructed?
- Does the orchestrator record the actual runtime graph, not the intended one?
- Can execution traces be correlated with cost and policy records?
- Is budget attributable per node, so you know which part of the system is expensive?
- Are sensitive actions gated behind approval checkpoints?
- Are model changes isolated behind routing, so swapping a model does not require rewriting nodes?
Most teams building their first graph can answer none of these, which is fine for an internal experiment and disqualifying for anything else. The gap between the two is smaller than it looks, but it is not zero, and it is worth knowing which side of it you are on before someone asks.
The checklist
Before you build:
- [ ] The success criterion for the whole system is written down and checkable
- [ ] Each node has its own success criterion
- [ ] Every node's scope is small enough that its output can be verified
- [ ] Fake dependencies have been eliminated — everything that can run in parallel does
- [ ] The state payload on each edge is defined and minimal
- [ ] Read-only shared reference is distinguished from results flowing along edges
- [ ] Verifier nodes exist where errors are expensive, and they have separate contexts
- [ ] Verifiers have the authority to reject, and a defined path for what happens when they do
- [ ] Every cycle has an iteration cap
- [ ] Irreversible and customer-facing actions sit behind human approval
- [ ] Per-node tracing exists before the graph exceeds about five nodes
- [ ] You can state, in one sentence, what splitting bought you over a single loop
If the last box is the one you cannot tick, you do not have a graph problem. You have a loop that works.
Where this leaves you
Graph engineering is real, it is useful, and it is considerably older than the July 2026 vocabulary around it. What changed is not the idea but the substrate: agents got good enough to be composed as units rather than used as endpoints, which makes multi-layered systems worth building where they previously were not.
What has not changed is the constraint. Our read on loop engineering was that the limit is verification, not capability, and graphs do not lift that limit — they relocate it. A graph gives you better places to put checks. It does not tell you what to check, and it will happily route wrong answers between nine well-designed nodes at speed.
The teams getting value from this are not the ones with the most nodes. They are the ones who can say precisely what each node is responsible for, what its output has to satisfy, and what happens when it does not.
Sources: [LangChain, "3 Years of Graph Engineering with LangGraph"](https://www.langchain.com/blog/3-years-of-graph-engineering-with-langgraph); [AI Builder Club, "Graph Engineering Guide 2026"](https://www.aibuilderclub.com/blog/graph-engineering-guide-2026); [TrueFoundry, "Graph Engineering: Enterprise Guide"](https://www.truefoundry.com/blog/graph-engineering-enterprise-guide); [codejunkie99/graph-engineering](https://github.com/codejunkie99/graph-engineering).