Source: graph Β·
graph.mdΒ· updated 2026-08-02 Β· π secret gistSynced verbatim from gist.github.com/bl9.
Graph Engineering β A Field Guide from Zero
What the term means, which parts are real, and how to decide whether any of it is worth your time.
Written for someone with no graph database, Cypher, or GNN background. Every term is defined before use.
Table of Contents
- 0. Read This First
- Part I β The Primitive, From Nothing
- Part II β Where the Term Came From
- Part III β Meaning A: Knowledge and Memory Graphs
- Part IV β Meaning B: Orchestration Graphs
- Part V β Meaning C: Graphs of Loops
- Part VI β Where Graph Projects Actually Die
- Part VII β Scenarios on Your Systems
- Part VIII β A Concrete Evaluation Path
- Appendix β Glossary and Sources
0. Read This First
The 60-second version.
- "Graph engineering" is about five weeks old as a term. A quiet blog post on July 4, 2026 used it first; a twelve-word post by Peter Steinberger on July 18 made it viral. He was mocking the buzzword treadmill. The treadmill did not care.
- Within 48 hours it meant three different things. Conflating them is the main reason the discourse is confusing.
- Only one of the three has a decade of research, independent benchmarks, and production deployments behind it: graph-structured knowledge and memory. The term is new; that substance is not.
- The core finding from independent evaluation: graphs win multi-hop, temporal, and corpus-wide synthesis questions. They lose on simple fact lookup and on cost. The practitioner consensus is to route by question type, not to replace your retrieval stack.
- The thing that kills graph projects is not graph algorithms. It is entity resolution β deciding that two mentions are the same thing β and its errors compound multiplicatively across hops.
- A "$3.1M Stanford and Anthropic study" circulated widely in the discourse. It does not exist. If you see it cited, that is a signal about the source.
One sentence to keep: vector search finds things that sound like your question; graphs find things that are connected to your answer.
How to read this document. Part I builds the primitive from nothing. Parts IIβV cover the three meanings and how real each is. Part VI is the failure mode. Part VII applies it to retrieval and recommendation work. Part VIII is a decision procedure you can actually run.
Part I β The Primitive, From Nothing
1.1 Nodes and Edges
Strip every buzzword away and a graph is two things.
- Node β a thing you know about. A person, a document, a case, a decision, an incident, a product.
- Edge β a connection between two nodes.
That is the entire primitive. Everything else is engineering on top of it.
flowchart LR
A(("Case<br/>A v. B")) --- B(("Judge<br/>Smith"))
A --- C(("Statute<br/>s.12"))
C --- D(("Amendment<br/>2024"))
style A fill:#2a2a3d,color:#fff
style B fill:#2a2a3d,color:#fff
style C fill:#2a2a3d,color:#fff
style D fill:#2a2a3d,color:#fff
You already work with graphs constantly without calling them that:
| Thing you know | Nodes | Edges |
|---|---|---|
| A git history | commits | parent-of |
| An import tree | modules | imports |
| A citation network | papers | cites |
| Your service topology | services | calls |
| A legal corpus | cases, statutes, judges | cites, overturns, amends |
None of this requires a graph database. A graph is a shape, not a product.
Why it matters for AI specifically: an agent answering a question has to find the relevant knowledge before it can answer. The shape of your knowledge determines what is findable.
1.2 The One-Bit Problem β Typed vs. Untyped Edges
This is the single most important distinction in the whole field, and it is easy to miss.
An untyped edge says "these two things are related." That is one bit of information. Related how? Unknown.
A typed edge names the relationship: supersedes, depends_on, caused, cites, overturns, authored_by.
flowchart TB
subgraph U["UNTYPED β one bit"]
U1(("ADR-007")) --- U2(("ADR-003"))
U2 --- U3(("Incident"))
end
subgraph T["TYPED β meaning"]
T1(("ADR-007")) -->|supersedes| T2(("ADR-003"))
T2 -->|caused| T3(("Incident"))
end
style U fill:#3d2a2a,color:#fff
style T fill:#1f3d2a,color:#fff
Read the untyped version aloud: "a decision is related to another decision, which is related to an incident." Did ADR-007 replace ADR-003, or the reverse? Did the incident cause the decision, or the decision cause the incident? The chain survives; the meaning is gone. An agent has to open and re-read every node and guess.
The typed version is a sentence: ADR-007 supersedes ADR-003, which caused the incident. That is something you can reason over without reading the documents.
Practical rules that hold across every serious system:
- Keep the vocabulary small and controlled β roughly 10β20 verbs, not freeform strings. Freeform types are barely better than untyped, because nothing composes.
- Define inverses β if
supersedesexists,superseded_byshould be derivable. - Direction matters.
A cites BandB cites Aare different facts.
Hold onto this section. Nearly every disappointing graph project has untyped or freeform-typed edges at the bottom of it.
1.3 Hops, Multi-Hop, and Traversal
- Traversal β starting at one node and walking along edges to reach others.
- Hop β one step along one edge.
- Multi-hop question β a question whose answer requires following more than one edge.
An example in your domain:
Question: "Is the reasoning in Case A still good law?"
hop 1: [[Case A]] --relies_on--> [[Case B]]
hop 2: [[Case B]] --overturned_by-->[[Case C]]
hop 3: [[Case C]] --decided_in--> [[2024]]
Three hops. The answer β no, its foundation was overturned in 2024 β exists in none of the three documents individually. It exists in the structure between them.
This is the whole argument for graphs. Most genuinely interesting questions about any real body of knowledge are multi-hop. "Who decided X and what broke because of it" is two hops. "What replaced the thing this depends on" is two hops. Simple lookups β "what is the citation for Case A" β are zero hops, and graphs add nothing there.
1.4 The Only Three Ways to Find Anything
There are exactly three retrieval mechanisms. Each fails in a characteristic way.
| Mechanism | How it works | Fails when |
|---|---|---|
| Keyword search (BM25) | Finds documents containing your words | The answer uses different words. "Vehicle" won't find "automobile" |
| Vector search | Embeds the question, finds documents about similar things | The answer is spread across documents that are individually not similar to the question |
| Graph traversal | Starts at a node, walks the connections | The connections don't exist, or are wrong |
You already run the first two, and you already hybridise them β that is what a BM25-plus-dense pipeline is. Graph traversal is a third leg, not a replacement for either.
The vector failure mode deserves a concrete example, because it is not obvious:
Question: "Why did we drop Redis for the job queue?"
Vector search embeds that and returns the ten chunks most similar to it. You get ten documents that mention Redis and job queues. None of them explains the decision β because the explanation lives in a decision record, the thing it replaced, and the incident that triggered it. Three separate documents, none of which is individually very similar to your question.
Similarity search has no concept of "these three belong to one causal chain." It is not a tuning problem. There is no k large enough and no embedding model good enough to fix it, because the relationship being asked about is structural, not semantic.
1.5 Vocabulary So Far
| Term | Meaning |
|---|---|
| Node | A thing you know about β entity, document, decision |
| Edge | A connection between two nodes |
| Typed edge | An edge that names the relationship (supersedes, caused) |
| Untyped edge | An edge that only says "related" β one bit |
| Direction | Edges point; A cites B β B cites A |
| Traversal | Walking from node to node along edges |
| Hop | One step along one edge |
| Multi-hop | A question requiring more than one hop |
| Entity resolution | Deciding that two mentions refer to the same node |
| Knowledge graph | A graph of entities and typed relationships used as a knowledge store |
| GraphRAG | Retrieval-augmented generation where the retrieval step uses a graph |
| Bi-temporal | Tracking two timelines per fact β see 3.5 |
| Community detection | Clustering a graph into neighbourhoods of related nodes |
Part II β Where the Term Came From
2.1 The Treadmill
"Graph engineering" is the latest stop on a naming treadmill. Each name described a real shift in where practitioners were putting their attention, and each got turned into content slop within weeks.
timeline
title The naming treadmill
2023 : Prompt engineering<br/>craft the words you send
Mid-2025 : Context engineering<br/>curate everything in the window
June 2026 : Loop engineering<br/>design the act-observe-retry cycle
July 2026 : Graph engineering<br/>design what happens between loops
The honest read: these overlap heavily. They are not four disciplines; they are four zoom levels on the same problem β what information reaches the model, in what shape, at what point. Knowing that is useful inoculation against the next term.
2.2 The 48 Hours That Made the Term
The documented sequence, worth knowing so nobody can bluff you with it:
| Date | Event |
|---|---|
| July 4, 2026 | Josh Simmons publishes "We are entering the graph engineering phase" β the earliest documented use |
| July 18, 2026 | Peter Steinberger posts twelve words: "Are we still talking loops or did we shift to graphs yet?" Thousands of likes. He was mocking the treadmill |
| ~10 hours later | Carlos Perez publishes one of the first serious essays expanding it into a network-theory account |
| Same day | The backlash starts. The sharpest reply: "congrats, you reinvented LangGraph" |
| Within 48 hours | Three competing definitions in circulation, plus a fabricated "$3.1M Stanford and Anthropic study" that does not exist |
Two things worth taking from this:
- The term is a meme that landed on something real. Both halves of that sentence are true, and most commentary picks one.
- A fabricated study went viral inside 48 hours. If a source cites it, that source did not check. This is a useful filter for the rest of the discourse.
2.3 Three Meanings, Very Different Maturity
flowchart TD
T["'Graph engineering'<br/>July 2026"]
T --> A["<b>A. Knowledge and memory graphs</b><br/>Knowledge as typed nodes and edges<br/>an agent traverses<br/><i>GraphRAG, temporal agent memory</i>"]
T --> B["<b>B. Orchestration graphs</b><br/>Multi-agent systems as explicit graphs<br/>instead of single loops<br/><i>LangGraph, Temporal, AutoGen</i>"]
T --> C["<b>C. Graphs of loops</b><br/>Networks of feedback cycles<br/>watching and correcting each other"]
A --> A2["<b>Real and measurable.</b><br/>Decade of research, independent<br/>benchmarks, production systems"]
B --> B2["<b>Real but mostly prior art.</b><br/>Shipped in tools well before<br/>the name existed"]
C --> C2["<b>Interesting, not actionable.</b><br/>No tooling, no benchmarks,<br/>no agreed definition"]
style A2 fill:#1f3d2a,color:#fff
style B2 fill:#3d3a1f,color:#fff
style C2 fill:#3d2a2a,color:#fff
| A. Knowledge/memory | B. Orchestration | C. Graphs of loops | |
|---|---|---|---|
| The graph is made of | entities and relationships | agents and control flow | feedback loops |
| Traversed at | query time, to retrieve | run time, to execute | conceptually |
| Prior art | knowledge graphs, 1990s onward; GraphRAG 2024 | LangGraph, Temporal, AutoGen, Google ADK | control theory, cybernetics |
| Independent benchmarks | Yes β GraphRAG-Bench, HippoRAG 2, LongMemEval | Partial β framework benchmarks, not the paradigm | No |
| Production evidence | Yes β SAP shipped a knowledge graph as an agent context layer; enterprise deployments reported | Yes | No |
| Worth your time | Probably β see Part VII | Only if your agent work has outgrown a loop | Read it, don't build on it |
The rest of this document treats them separately, because the useful advice differs completely.
Part III β Meaning A: Knowledge and Memory Graphs
This is the one with substance behind it. Serious people were building it before the name existed, under other labels β Foundation Capital called it "context graphs" in December 2025.
3.1 Why Flat Retrieval Breaks β Structurally
Return to the failure from 1.4, because the reason matters more than the example.
Chunk-and-embed retrieval makes an assumption: that the answer to a question is semantically similar to the question. For a large class of questions that assumption simply does not hold.
flowchart TD
Q["Question:<br/>'Why did we drop Redis for the job queue?'"]
Q --> V["<b>Vector search</b><br/>embed question,<br/>retrieve top-k similar chunks"]
V --> VR["10 chunks mentioning<br/>Redis and job queues.<br/><b>None explains the decision.</b>"]
Q --> G["<b>Graph traversal</b><br/>start at the entity,<br/>walk typed edges"]
G --> G1["[[Job queue]] --decided_by--> [[ADR-007]]"]
G1 --> G2["[[ADR-007]] --supersedes--> [[ADR-003 Redis]]"]
G2 --> G3["[[ADR-003]] --caused--> [[Incident 2026-03-11]]"]
G3 --> GR["<b>3 documents, ~1,000 tokens,<br/>causal chain intact</b>"]
style VR fill:#3d2a2a,color:#fff
style GR fill:#1f3d2a,color:#fff
Note the token count in that comparison. Ten chunks that don't answer the question cost more than three that do. When the graph works, it is often cheaper at query time, not just better β which cuts against the usual assumption that graphs are the expensive option. The expense is at index time, and that is a different budget.
3.2 Microsoft GraphRAG β The Reference Architecture
The system that made GraphRAG a category, published by Microsoft Research in 2024. Worth understanding because everything since is a reaction to it.
flowchart LR
D[Documents] --> C[1. Chunk]
C --> E["2. LLM reads every chunk,<br/>extracts entities + relationships"]
E --> CD["3. Community detection<br/>clusters related entities"]
CD --> S["4. LLM writes a summary<br/>report per community"]
S --> I[(Index)]
I --> Q{"5. Query time"}
Q -->|"broad question"| MR["Map-reduce over<br/>community reports"]
Q -->|"specific question"| EX["Expand from a<br/>matched entity"]
It works. It also has two problems that shaped the whole field:
- Index cost. An LLM call per chunk. Microsoft Research's own LazyGraphRAG post positions full GraphRAG's indexing cost as roughly 1,000Γ that of vector RAG. Estimates of tens of thousands of dollars to index a single large enterprise corpus circulate widely; treat the specific dollar figures as illustrative rather than measured, but the order of magnitude is the vendor's own framing.
- Free-text edges don't compose. Relationships extracted as arbitrary natural-language strings can't be traversed reliably β this is 1.2 biting at scale.
Lesson one: the naive version is too expensive, and untyped extraction doesn't compose.
3.3 LazyGraphRAG β Microsoft's Own Correction
Microsoft Research published LazyGraphRAG in November 2024, inverting the design.
| Full GraphRAG | LazyGraphRAG | |
|---|---|---|
| Index time | LLM extracts entities and writes community summaries | Zero LLM calls. NLP noun-phrase extraction for concepts and co-occurrence, then graph statistics for community structure |
| Query time | Map-reduce over precomputed summaries | Iterative deepening β best-first plus breadth-first, LLM relevance tests on demand |
| Indexing cost | baseline | Identical to vector RAG β 0.1% of full GraphRAG |
| Tuning | fixed | one parameter: relevance test budget |
Microsoft's reported results: comparable answer quality to GraphRAG global search on global queries at more than 700Γ lower query cost; at 4% of GraphRAG global search's query cost, it outperformed all competing methods on both local and global queries β including vector RAG, RAPTOR, and GraphRAG's own local, global, and DRIFT search mechanisms.
Lesson two, and the most practically useful thing in this document: you do not need to pre-compute the graph's meaning. A cheap structural graph plus smart traversal at query time captures most of the value. If you pilot anything, pilot this shape.
(Caveat: these are the vendor's own numbers on the vendor's own evaluation. The direction is well-supported; the multipliers are not independently confirmed.)
3.4 HippoRAG 2 β Hybrid, and No Regression
From OSU's NLP group, published February 2025 as "From RAG to Memory: Non-Parametric Continual Learning for Large Language Models." It builds on Personalized PageRank β importance spreads outward along edges from wherever the query touched the graph β combined with deeper passage integration and online LLM use.
The paper's headline claim is a 7% improvement in associative memory tasks over a state-of-the-art embedding model, while also exceeding it on factual and sense-making memory.
The result that actually matters is the negative one. The paper's framing is explicit: earlier graph-augmented approaches improved sense-making and associativity but dropped considerably below standard RAG on basic factual memory. HippoRAG 2's contribution is fixing that regression β improving multi-hop and synthesis without sacrificing performance on simpler tasks.
Lesson three: the winning configuration is hybrid, never graph-only. Most graph systems buy multi-hop performance by giving up simple-lookup performance. That trade is usually a bad deal, because most production traffic is simple lookups.
Correction to what's circulating: several posts cite "HippoRAG 2 beats a strong embedding model by 9.5 F1 points on 2WikiMultiHopQA." I could not confirm that figure in the abstract or the OpenReview record. The 7% associative-memory improvement is the paper's own headline. Use that one.
3.5 Graphiti and Zep β Memory That Knows What Time It Is
GraphRAG answers questions about a fixed corpus. Agent memory is a harder problem: knowledge that changes while the agent is using it.
This is where graphs do something a vector store structurally cannot.
Graphiti β the open-source engine behind Zep, ~20,000 GitHub stars β is bi-temporal. Every edge carries two timelines:
- Valid time β when the fact was true in the world
- Transaction time β when the system learned it
flowchart TD
subgraph VS["Vector store"]
V1["Fact: 'Statute s.12 requires X'"]
V1 --> V2{"New info arrives:<br/>amended in 2024"}
V2 --> V3["<b>Overwrite</b> β old fact gone,<br/>can't answer 'what applied in 2023?'"]
V2 --> V4["<b>Or duplicate</b> β both facts present,<br/>agent cites whichever it retrieves"]
end
subgraph TKG["Temporal knowledge graph"]
T1["Edge: s.12 --requires--> X<br/>valid_from 2019"]
T1 --> T2{"New info arrives"}
T2 --> T3["<b>Close the interval</b><br/>valid_until 2024"]
T3 --> T4["<b>New edge</b><br/>s.12 --requires--> Y<br/>valid_from 2024"]
T4 --> T5["Both questions answerable.<br/><b>Facts are superseded, not deleted.</b>"]
end
style V3 fill:#3d2a2a,color:#fff
style V4 fill:#3d2a2a,color:#fff
style T5 fill:#1f3d2a,color:#fff
Reported results: on the Deep Memory Retrieval benchmark that the MemGPT team established as their own primary metric, Zep scored 94.8% against MemGPT's 93.4%, with further evaluation on LongMemEval. The margin on DMR is modest β the stronger claims are about temporal reasoning tasks that DMR doesn't test.
Why this section matters more than the rest of Part III for legal-domain work. Every long-lived knowledge base has this shape. Decisions supersede decisions. Claims go stale. A system that cannot represent "X replaced Y on this date" slowly fills with contradictions, and an agent reading it will confidently cite the stale half.
Legal information is the extreme case: rulings get overturned, statutes get amended, precedent gets distinguished, regulations have commencement dates. "What is true now" and "what was true when the events occurred" are different questions, and both get asked constantly. A vector store has no native way to express the difference.
Note the vocabulary this requires: supersedes, contradicts, valid_from, valid_until. Typed edges again.
3.6 The Scoreboard, Honestly
Half the numbers in this field are vendor-reported on vendor-designed benchmarks. What follows separates independent evaluation from self-evaluation.
The framing question, from an ICLR'26 paper by Xiang et al. β "When to use Graphs in RAG" β is worth quoting because it starts from the skeptical position: despite GraphRAG's conceptual promise, recent studies report that it frequently underperforms vanilla RAG on many real-world tasks. The paper builds GraphRAG-Bench specifically to find out when graphs help, across fact retrieval, complex reasoning, contextual summarisation, and creative generation.
Where graphs win:
| Task type | Result |
|---|---|
| Multi-hop reasoning | Reported ~53% vs ~43% for vector RAG on GraphRAG-Bench |
| Temporal reasoning | The most lopsided margins in the field β graph-backed memory variants far ahead of flat memory on time-dependent questions |
| Corpus-wide synthesis | Reported ~64% vs ~51% |
Where graphs lose:
| Task type | Result |
|---|---|
| Simple fact lookup | Roughly a tie, with plain vector RAG marginally ahead. The graph adds redundant context and wins nothing |
| Query cost | Microsoft GraphRAG global search has been measured in the hundreds of thousands of tokens per query against vector RAG's high hundreds. Efficient graph systems exist β HippoRAG 2 operates around 1,000 tokens per query β but the naive configuration is brutal |
Two warnings that are worth more than the numbers:
- LightRAG posted large wins on its own benchmark, then collapsed under independent evaluation β reported at 6.6 average F1 versus 59.8 for HippoRAG 2. Never trust a system evaluated only by its authors.
- In Mem0's own paper, the graph variant lost to the non-graph variant on multi-hop questions. Graphs are a tool, not a doctrine. A graph built badly is worse than no graph.
On the specific percentages above: these are widely reported from GraphRAG-Bench and related evaluations, but I have verified the papers' framing and abstracts rather than the individual table cells. Treat the direction and magnitude as well-supported and any single figure as needing a look at the paper before you put it in a slide. Note also that two different papers are both called "GraphRAG-Bench" (Xiang et al. 2506.05690 and Xiao et al. 2506.02404) β check which one a citation means.
The consensus that survives all of this: route by question type. Vector for lookups, graph for chains. The 2026 trend line across serious systems points the same way β lazy indexing, agentic traversal where the agent decides which hops to take live, small controlled edge vocabularies, and honest routing.
Part IV β Meaning B: Orchestration Graphs
The second meaning. Here the graph is not made of knowledge β it is made of your system's control flow.
4.1 Loops vs. Graphs
Loop engineering was the June 2026 framing: you stop hand-writing prompts and start designing the cycle one agent runs.
flowchart LR
subgraph LOOP["A LOOP β one agent"]
L1[Discover] --> L2[Plan]
L2 --> L3[Execute]
L3 --> L4[Verify]
L4 -->|not done| L1
L4 -->|"stop condition"| L5[Done]
end
Four moving parts: a variable you care about, a target, a way to measure the gap, and an action that shrinks it β repeated. The insight of loop engineering was that the verifier, not the model, is the bottleneck. A loop is only as good as its exit test.
Graph engineering in this sense is the layer above: instead of one agent looping, you wire several, each with its own loop, connected by explicit typed transitions over shared state.
flowchart TD
S[("Shared state")]
P[Planner] --> R{Route}
R -->|"needs research"| RE[Researcher]
R -->|"needs code"| CO[Coder]
RE --> RV[Reviewer]
CO --> RV
RV -->|pass| DONE[Done]
RV -->|"fail: rework"| R
P -.-> S
RE -.-> S
CO -.-> S
RV -.-> S
CP{{"Checkpoint β<br/>resume, inspect,<br/>human-in-the-loop"}}
S -.-> CP
The elements that make it a graph rather than a pile of agents:
- Typed nodes β each node has a declared role and contract
- Typed transitions β edges encode when control moves and why, including conditional routing
- Shared state β one state object flows through, rather than each agent holding private context
- Checkpoints β the run can be paused, inspected, resumed, or handed to a human
The best line from the original thread, from Luis Catacora: "Loops are forgiving. Graphs force you to admit how much of the workflow you haven't actually modeled yet." That is the honest value proposition β the discipline is in the modelling, not the runtime.
4.2 The Prior Art Problem
The reply "congrats, you reinvented LangGraph" is mostly correct, and pretending otherwise is exactly the hype the skeptics are calling out.
| Tool | What it already does |
|---|---|
| LangGraph | Officially described as a low-level orchestration framework and runtime for long-running, stateful agents, built from a StateGraph of nodes and edges over shared state. Shipped well before the term |
| Temporal | Durable execution β workflows as code with retries, timers, and full replay. Not AI-specific, and older |
| Microsoft AutoGen | Multi-agent conversation patterns with explicit topologies |
| Google ADK | Agent Development Kit with composable agent graphs |
| Airflow / Dagster / Step Functions | DAG orchestration. Decades of prior art on the general shape |
Nothing in "orchestration graphs" is new as a capability. What changed is that enough people hit the ceiling of single-loop agents in the same quarter to give the pattern a name.
4.3 What Is Genuinely New
Being fair to the position, three things did shift:
- Loops became the default, so their limits became visible. In 2025 most agent systems were one prompt. In 2026 most are a loop. The failure modes of one loop at scale β context exhaustion, no parallelism, no partial recovery, unbounded blast radius β are now common experience rather than theory.
- Checkpointing and durable state became table stakes. Long-running agent work needs resumability. That pushes you toward explicit state graphs whether or not you use the word.
- The modelling discipline is the actual product. Drawing the graph forces you to name every handoff, every failure route, and every piece of state that crosses a boundary. Most teams discover they had not decided those things.
Where this touches your BMAD work: BMAD's Phase 4 is a loop β bmad-build clarifies, plans, implements, reviews. bmad-build-auto is that loop iterated over an ordered stories.yaml. That is loop engineering, sequential. The deep-recon Run mode is closer to a graph: a lead orchestrator fans out isolated subagents in parallel, then converges through verification. Same primitives, drawn explicitly. See 7.5.
The honest recommendation on Meaning B: master the loop first, and split it into a graph only when the work forces your hand. The signals that it's forcing your hand are concrete β you need genuine parallelism, you need to resume mid-run after a failure, you need different models for different steps, or you need a human approval gate in the middle. Absent those, a graph is added complexity.
Part V β Meaning C: Graphs of Loops
5.1 The Idea
The most abstract reading. Here the nodes are not agents or entities β they are feedback loops, and the edges encode how loops watch, constrain, and correct one another.
The motivating observation is real, and it comes from control theory rather than AI: a single feedback loop optimised hard enough degrades. Push any metric and it stops measuring what it used to β Goodhart's law. A loop optimising latency will find ways to be fast that nobody wanted. A loop optimising engagement will find engagement nobody is glad about.
The proposed remedy is a network of loops with explicit edges encoding trust, authority, and cadence β a quality loop constraining a speed loop, an audit loop sampling both, a policy loop that can override.
flowchart TD
Q["Quality loop"] -->|constrains| S["Speed loop"]
A["Audit loop"] -->|samples| Q
A -->|samples| S
P["Policy loop"] -->|"can override"| Q
P -->|"can override"| S
S -->|"reports to"| A
5.2 Why It Is Not Actionable Yet
- No tooling. No framework implements "loops watching loops" as a first-class construct
- No benchmarks. Nothing measures whether a graph of loops outperforms well-designed individual loops
- No agreed definition. Different writers mean noticeably different things
- The prior art is old and not obviously transferable. Cybernetics, control theory, and organisational design have decades on this. Whether those results carry over to LLM agents is an open question nobody has answered empirically
Worth reading for the framing, not worth building on. The useful, portable idea inside it is smaller and older: any single metric you optimise hard will eventually stop measuring what you wanted. You already handle this with guardrail metrics in A/B tests. That is a graph of loops with two nodes.
Part VI β Where Graph Projects Actually Die
If graphs win benchmarks, why isn't everyone running one? Because of a number almost nobody leads with.
6.1 Entity Resolution
Entity resolution is deciding that two mentions refer to the same node.
- "Dr. John Smith," "J. Smith," and "John" β one node or three?
- "Mercury" the planet and "Mercury" the element β one node or two?
- In your domain: Smith v. Jones (1998), Smith v Jones, "the Smith decision," and the neutral citation
[1998] UKHL 12β all one node - Across languages:
Cour de cassation,Kassationshof, "the French Court of Cassation" β one institution
Extraction pipelines get this wrong constantly. Every wrong merge creates a false edge; every missed merge splits a node and breaks chains that should connect.
This, not graph algorithms, is where the engineering budget goes. Graph traversal is a solved problem with decades of literature. Deciding what is the same thing is not.
6.2 The Compounding Math
Here is the number that should govern your architecture decisions.
Entity resolution errors compound multiplicatively over hops. If each hop is independently correct with probability p, an n-hop chain is correct with probability pβΏ.
| Per-hop accuracy | 2 hops | 3 hops | 5 hops |
|---|---|---|---|
| 99% | 98% | 97% | 95% |
| 95% | 90% | 86% | 77% |
| 90% | 81% | 73% | 59% |
| 85% | 72% | 61% | 44% |
flowchart LR
A["85% per-hop<br/>accuracy"] --> B["5-hop traversal"]
B --> C["<b>44% trustworthy</b><br/>Your impressive multi-hop<br/>chain is a coin flip"]
style C fill:#3d2a2a,color:#fff
Three consequences that should shape any design:
- Shallow beats deep. Two- and three-hop questions are where the value/risk ratio is good. Five-hop reasoning demos are marketing.
- Per-hop accuracy dominates everything else. Going from 85% to 95% per-hop nearly doubles five-hop trustworthiness. No amount of clever traversal recovers from bad nodes.
- Where entity resolution is already solved, graphs get dramatically cheaper. This is the practical escape hatch β see below.
Where it is already solved for you:
| Source | Why resolution is free |
|---|---|
| Neutral legal citations | [1998] UKHL 12 is a canonical identifier by construction |
| Explicit link markup | A wikilink or a hyperlink is an author-asserted edge to a specific target β no fuzzy merging |
| Foreign keys | Your existing databases already resolved these entities |
| DOIs, ISBNs, ticker symbols, SKUs | Canonical identifier systems |
| Your own document IDs | You control them |
The strategic read: build your first graph out of edges you already have, not edges you extract. Citation networks, document metadata, foreign keys, taxonomy assignments. Per-hop accuracy near 100%, index cost near zero, and you learn whether traversal helps before spending anything on extraction.
6.3 Staleness and Index Cost
The other two killers, more briefly:
- Staleness. A graph built once and never updated diverges from the corpus. Every re-index is a re-extraction, which is why full GraphRAG's index cost is a structural problem rather than a one-off. This is exactly what bi-temporal modelling (3.5) addresses β close intervals rather than rebuild.
- Index cost. Covered in 3.2 and 3.3. The short version: an LLM call per chunk does not scale, and Microsoft's own correction shows you mostly don't need it.
Part VII β Scenarios on Your Systems
Five concrete applications to multilingual legal search, recommendation, and agent work. Each states what a graph would actually buy, and what it would cost.
7.1 Legal Multi-Hop Retrieval
The question class: "Is the reasoning in this case still good law?" "What line of authority supports this proposition?" "Which subsequent decisions distinguished this holding?"
Why vector retrieval struggles. These are two- and three-hop questions whose answers live in the citation structure, not in any single document's text. A case that was overturned does not say so; the later case says so. Similarity search retrieves the original case and misses the overturning entirely, because the overturning decision is often about different facts and shares little vocabulary.
flowchart LR
Q["'Is Case A still good law?'"]
Q --> A(("Case A"))
A -->|relies_on| B(("Case B"))
B -->|overturned_by| C(("Case C"))
C -->|decided| D["2024"]
A -.->|"vector search<br/>returns this only"| A
style C fill:#3d2a2a,color:#fff
What makes this the strongest case in your stack: the edges already exist. Citation relationships are explicit in the documents and already extracted by legal publishers. Entity resolution is near-solved by neutral citation. You are not building a knowledge graph from scratch β you are traversing one you already have.
Cost: low, if you build on existing citation metadata. High, if you try to LLM-extract relationships from opinion text.
What to measure: on a set of "still good law" style questions, does adding a two-hop citation expansion to your existing hybrid retrieval change answer correctness? That is a bounded experiment.
7.2 Temporal Supersession
The question class: "What did this regulation require in 2021?" "Has this statutory provision been amended since the contract was signed?"
This is the sharpest fit for bi-temporal modelling in your domain, and it is a class of question a vector store cannot represent at all β not "does poorly on," but cannot represent.
Flat retrieval has two options when a fact changes: overwrite the old version, or keep both. Overwriting makes historical questions unanswerable. Keeping both means the retriever returns whichever chunk it happens to rank higher, and the model cites the stale one with full confidence.
flowchart TD
R["Regulation s.12"]
R --> E1["Edge: requires --> X<br/>valid 2019-01 to 2024-06"]
R --> E2["Edge: requires --> Y<br/>valid 2024-06 to present"]
Q1["'What applies today?'"] --> E2
Q2["'What applied when the<br/>contract was signed in 2022?'"] --> E1
style E1 fill:#3a3a2a,color:#fff
style E2 fill:#1f3d2a,color:#fff
What it buys: point-in-time answers, contradiction-free retrieval, and auditable provenance β which in a legal product is not a nice-to-have, it is close to a requirement.
Cost: you need valid-time metadata on your content. If commencement dates, amendment dates, and repeal dates are already in your document metadata, most of the work is done. If they aren't, that is the project.
7.3 Multilingual Entity Linking
The question class: an English query that should surface French and German source documents about the same entity.
Where a graph helps in a way embeddings don't. A shared multilingual embedding space tries to make Cour de cassation and "French Court of Cassation" land near each other in vector space β a fuzzy, probabilistic, per-query bet. A graph makes them the same node, once, at index time.
flowchart TD
N(("Node:<br/>Cour de cassation"))
N --- L1["surface form: 'Cour de cassation' (fr)"]
N --- L2["surface form: 'Kassationshof' (de)"]
N --- L3["surface form: 'French Court of Cassation' (en)"]
N -->|decided| C1(("Case 1 β fr"))
N -->|decided| C2(("Case 2 β fr"))
Q["English query mentioning<br/>the French Court of Cassation"] --> N
Once the query resolves to the node, every document connected to it is reachable regardless of language β no cross-lingual similarity bet required.
This is a genuine alternative framing of the shared-vs-per-language indexing decision. Instead of choosing between a shared embedding space and per-language indices, you can keep per-language indices and add a language-agnostic entity layer over them. Entity resolution does the cross-lingual work; embeddings stay monolingual, where they're strongest.
Cost: entity linking across languages is real work, though authority files, legal identifier systems, and existing taxonomies do much of it. Worth costing before assuming the embedding route is the only option.
7.4 Recommendation and Cold Start
Where graphs are relevant to recommenders β and where they are oversold.
Genuinely useful:
- Cold start via structure. A brand-new item has no interaction history, but it has edges β author, court, jurisdiction, practice area, cited-by. Those edges are available at ingest, before any user has seen it. This directly addresses the failure where new items get no impressions
- Explainability. "Recommended because it cites a case you read" is a traversal path. That is a much better explanation than "high cosine similarity," and in a professional product, explainability has real commercial value
- Multi-hop discovery. "Documents cited by documents your colleagues in this practice area read" is a two-hop query over the interaction graph
Where it is oversold:
- Collaborative filtering is already a graph algorithm. A userβitem interaction matrix is a bipartite graph. Matrix factorisation, random walks, and PageRank-style propagation over it are decades old. Rebranding this as graph engineering adds nothing
- GNNs are a separate discipline with their own costs, and nothing in the July 2026 discourse is about them
- For the head of your traffic β popular items, obvious queries β graphs add latency and win nothing
The honest framing: for recommendation, "graph engineering" is mostly a new name for things your field already does. The genuinely new part is the retrieval side in 7.1β7.3, not the ranking side.
7.5 Agent Orchestration for Your BMAD Work
Mapping Meaning B onto something you already run.
| BMAD pattern | Graph reading |
|---|---|
bmad-build | A loop β clarify, plan, implement, review. One agent, one cycle |
bmad-build-auto | The same loop, iterated over an ordered stories.yaml. Sequential, not a graph |
bmad-deep-recon Run mode | Closest thing to a graph: a lead orchestrator fans out isolated subagents in parallel, digests converge to disk, verifiers run on landing, a red-team node attacks the conclusion |
| The plan gate | A checkpoint with human-in-the-loop approval |
| The research firewall | An edge constraint β it defines precisely what may cross from the lead node to the assistant nodes |
That last row is the interesting one. The research firewall is graph engineering in the orchestration sense, done well: it specifies what information is allowed to traverse a particular edge. Most agent systems have implicit edges where everything flows. Making the edge typed and constrained is exactly the discipline Meaning B is pointing at.
The practical takeaway: if you want to understand orchestration graphs, you already have a working reference implementation to read. references/run.md in deep-recon describes a fan-out/converge graph with typed edges and a checkpoint, without using any of the vocabulary.
Part VIII β A Concrete Evaluation Path
Concept done. This part is a decision procedure β four steps in increasing cost, each with a gate, plus explicit kill criteria. Total effort through Step 2 is roughly a week; Step 3 is a quarter.
flowchart TD
S0["<b>Step 0 β Question audit</b><br/>~1 day, no code<br/>What fraction of real traffic is multi-hop?"]
S0 --> G0{"Multi-hop or temporal<br/>share of questions<br/>that matter?"}
G0 -->|"under ~10%"| STOP1["<b>Stop.</b> Route better,<br/>improve reranking instead"]
G0 -->|"meaningful"| S1
S1["<b>Step 1 β Cheapest probe</b><br/>~2 days<br/>Hand-build 20 nodes from<br/>edges you already have"]
S1 --> G1{"Does traversal answer<br/>questions vector missed?"}
G1 -->|no| STOP2["<b>Stop.</b> The structure<br/>isn't carrying the answer"]
G1 -->|yes| S2
S2["<b>Step 2 β Routing baseline</b><br/>~3 days<br/>Classify query type,<br/>route to existing retrieval"]
S2 --> G2{"Does routing alone<br/>capture most of the gain?"}
G2 -->|yes| DONE["<b>Ship the router.</b><br/>You're done and it cost nothing"]
G2 -->|"gap remains"| S3
S3["<b>Step 3 β Bounded pilot</b><br/>~1 quarter<br/>LazyGraphRAG shape on one<br/>corpus slice, hybrid, measured"]
S3 --> G3{"Kill criteria met?"}
G3 -->|yes| STOP3["<b>Stop and write it up.</b>"]
G3 -->|no| SCALE["Scale deliberately"]
style STOP1 fill:#3d2a2a,color:#fff
style STOP2 fill:#3d2a2a,color:#fff
style STOP3 fill:#3d2a2a,color:#fff
style DONE fill:#1f3d2a,color:#fff
8.1 Step 0 β The Question Audit
Cost: about a day. No code. Do not skip this.
Everything in Part III says graphs win a specific slice of question types. So the first question is empirical and about your traffic, not about graphs.
Take 200 real queries from logs β sampled, not cherry-picked β and classify each:
| Class | Test | Graph value |
|---|---|---|
| Zero-hop lookup | The answer is in one document, findable by similarity | None. Graphs lose here |
| Two-hop | Answer requires connecting exactly two documents | High |
| Three-plus-hop | Requires a chain | High value, but see the compounding math |
| Temporal | "As of when" matters to the correct answer | Highest β flat retrieval can't represent it |
| Corpus-wide synthesis | "What are the themes across all X" | High |
| Aggregation | "How many," "list all" | Graphs help, but so would a database |
The gate. If multi-hop plus temporal is under roughly 10% of queries that matter β weight by business value, not volume β stop here. Your effort is better spent on reranking, query understanding, or routing. This is the most common honest outcome, and reaching it in a day is a good result.
A note on weighting. Volume and value diverge sharply in professional research tools. The 5% of queries that are multi-hop may be the ones where a user's alternative is billing three hours to an associate. Count both ways before deciding.
8.2 Step 1 β The Cheapest Possible Probe
Cost: about two days. No graph database. No LLM extraction. No new infrastructure.
The goal is to answer one question: does traversal reach answers that similarity misses, on my data?
The design:
- Take 20 questions from the multi-hop and temporal buckets in Step 0
- Build the relevant subgraph by hand or from metadata you already have β citations, foreign keys, document links, taxonomy assignments. A Python dict is a fine graph.
networkxif you want algorithms - Use only edges with near-100% accuracy. No extraction. This deliberately removes entity resolution as a variable
- For each question, compare: what does your current retrieval return, versus what does a two-hop expansion from the matched entity return?
What you are measuring: not answer quality yet β just reachability. Does the document containing the answer appear in the candidate set at all? A graph cannot help with documents your retrieval never surfaces, and it cannot help if similarity already surfaces them.
The gate. If two-hop expansion doesn't materially change the candidate set on questions vector retrieval got wrong, the structure isn't carrying the answer in your corpus. Stop.
Why this ordering matters. It isolates the one thing you actually want to know from the three things that make graph projects expensive β extraction, infrastructure, and entity resolution. Almost every failed graph project skipped this step and spent a quarter finding out.
8.3 Step 2 β The Routing Baseline
Cost: about three days. This is the step most teams skip, and it is often where the whole return lives.
Before building any graph, build the router that a graph system would need anyway.
flowchart LR
Q[Query] --> C{Classifier}
C -->|"zero-hop lookup"| V["Existing hybrid<br/>BM25 + dense"]
C -->|"temporal"| T["Existing retrieval<br/>+ date filter on metadata"]
C -->|"multi-hop"| M["Existing retrieval<br/>+ 2-hop citation expansion"]
C -->|synthesis| S["Existing retrieval<br/>+ wider k, rerank"]
Why this often captures most of the gain:
- A date filter over metadata you already have answers a large share of temporal questions without any bi-temporal graph
- A two-hop citation expansion over existing citation metadata is a join, not a knowledge graph
- Simply not running expensive retrieval on zero-hop queries improves latency and cost immediately
The gate. Measure the router against your current single-path retrieval. If routing plus cheap expansions closes most of the gap you found in Step 1, ship that and stop. You have captured the value of graph engineering without doing graph engineering, which is a legitimate and common outcome.
8.4 Step 3 β A Bounded Pilot
Cost: about a quarter. Only if Steps 0β2 left a real gap.
Six design commitments, each of which follows from something earlier in this document:
- One corpus slice, not the whole corpus. Pick the subdomain with the highest multi-hop share from Step 0
- LazyGraphRAG shape, not full GraphRAG. Cheap structural graph at index time, thinking deferred to query time (3.3). Index cost comparable to vector RAG
- Small controlled edge vocabulary. 10β20 typed verbs, defined up front, with inverses. Never freeform strings (1.2)
- Hybrid, never graph-only. The graph augments your existing retrieval. HippoRAG 2's lesson is that graph-only systems buy multi-hop performance with simple-lookup regressions (3.4)
- Bi-temporal from day one if temporal questions matter. Retrofitting valid-time onto an existing graph is painful; designing edges with validity intervals from the start is cheap (3.5)
- Instrument per-hop accuracy explicitly. Not just end-to-end quality. Given the compounding math (6.2), per-hop accuracy is the number that predicts whether this scales
What to measure β four metrics, and the second is the one that kills projects:
| Metric | Why |
|---|---|
| Answer quality on multi-hop and temporal questions | The reason you're doing this |
| Answer quality on simple lookups | The regression check. This is where most graph systems quietly lose |
| Query cost β tokens and latency, p50 and p99 | Graph query cost varies enormously by design |
| Index cost and re-index cadence | Staleness is a killer (6.3) |
On evaluation integrity: the two cautionary tales in 3.6 β LightRAG collapsing under independent evaluation, and Mem0's graph variant losing to its own non-graph variant β are both cases of a system evaluated by people who wanted it to win. Fix your question set and metrics before you build, hold out a test set, and have someone who didn't build it run the comparison. The discipline is the same one in the research-firewall appendix of the BMAD guide.
8.5 Kill Criteria
Write these down before starting Step 3, so the decision isn't made under sunk-cost pressure.
Kill the pilot if:
- Simple-lookup quality regresses more than a threshold you set in advance
- Per-hop accuracy lands below ~90% and you have no clear path to raise it β at 85%, three hops is already 61%
- Query cost exceeds the ceiling your product economics allow, at the quality level you need
- The re-index cadence your corpus requires costs more than the quality gain is worth
- Routing alone (Step 2) recovers most of the benefit at a fraction of the complexity
- You cannot articulate which specific question class improved. "Feels better" is the signature of a project that will not survive contact with a proper eval
A kill is a good outcome. You will have spent a quarter to learn something specific about your corpus, and you will be able to answer the question authoritatively for years. Compare that to the alternative: a graph pipeline in production that nobody can prove is earning its cost.
8.6 What to Skip Entirely
Based on everything above:
| Skip | Because |
|---|---|
| Full Microsoft GraphRAG at scale | Microsoft's own correction (LazyGraphRAG) reports comparable quality at 0.1% of index cost. Read GraphRAG for the architecture, build the lazy shape |
| Graph-only retrieval | Every serious result says hybrid. Graph-only regresses on the questions that make up most of your traffic |
| Freeform edge types | Barely better than untyped, and they don't compose. Small controlled vocabulary or nothing |
| Five-plus-hop reasoning | 85% per-hop makes it a coin flip. Demos, not products |
| "Graphs of loops" | No tooling, no benchmarks, no agreed definition. Read the framing, build nothing |
| Rebranding your recommender | Collaborative filtering is already a graph algorithm. New name, no new capability |
| Any vendor number you haven't traced to a paper | Half the figures in this field are self-reported. One of the most-cited studies in the discourse does not exist |
| A graph database, at first | You do not need Neo4j to test whether traversal helps. You need a dict and two days |
Appendix β Glossary and Sources
Glossary
| Term | Definition |
|---|---|
| Node | A thing you know about β an entity, document, decision, or event |
| Edge | A connection between two nodes |
| Typed edge | An edge naming the relationship: supersedes, cites, caused |
| Untyped edge | An edge that only asserts "related" β one bit of information |
| Hop | One step along one edge |
| Multi-hop question | A question whose answer requires following more than one edge |
| Traversal | Walking from node to node along edges |
| Entity resolution | Deciding that two mentions refer to the same node. The hard part |
| Knowledge graph | A graph of entities and typed relationships used as a knowledge store |
| GraphRAG | Retrieval-augmented generation where retrieval uses a graph |
| Community detection | Clustering a graph into neighbourhoods of related nodes |
| Personalized PageRank | Importance propagation from a seed set β how HippoRAG ranks |
| Bi-temporal | Tracking two timelines per fact: when it was true, and when the system learned it |
| Valid time | When a fact was true in the world |
| Transaction time | When the system recorded the fact |
| Supersession | Closing a fact's validity interval and opening a replacement, rather than deleting |
| Relevance test budget | LazyGraphRAG's single cost/quality dial β how many LLM relevance checks per query |
| Lazy indexing | Building a cheap structural graph at index time, deferring expensive reasoning to query time |
| Agentic traversal | The agent deciding which hops to take at query time, rather than a fixed traversal policy |
| StateGraph | LangGraph's construct: nodes and edges operating over shared state |
| Checkpoint | A durable point in an orchestration graph allowing pause, inspection, resume |
| Goodhart's law | A measure that becomes a target ceases to be a good measure |
Primary sources
Papers β the ones worth reading directly:
- "When to use Graphs in RAG: A Comprehensive Analysis for Graph Retrieval-Augmented Generation" β Xiang, Wu, Zhang, Chen, Hong, Huang, Su. arXiv:2506.05690, ICLR'26. The honest scoreboard: where graphs win and lose by task type. Starts from the observation that GraphRAG frequently underperforms vanilla RAG
- "From RAG to Memory: Non-Parametric Continual Learning for Large Language Models" (HippoRAG 2) β GutiΓ©rrez, Shu, Qi, Zhou, Su. arXiv:2502.14802. Personalized PageRank plus deeper passage integration; the key result is improving multi-hop without regressing on simple factual retrieval
- "HippoRAG: Neurobiologically Inspired Long-Term Memory for Large Language Models" β arXiv:2405.14831, NeurIPS'24. The predecessor
- "Zep: A Temporal Knowledge Graph Architecture for Agent Memory" β Rasmussen, Paliychuk, Beauvais, Ryan, Chalef. arXiv:2501.13956. The bi-temporal model; DMR 94.8% vs MemGPT 93.4%, plus LongMemEval
- Note: a second, different paper is also called GraphRAG-Bench (Xiao et al., arXiv:2506.02404). Check which one a citation means
Vendor and framework material β useful, self-reported:
- LazyGraphRAG: Setting a new standard for quality and cost β Microsoft Research, Nov 2024. Index cost identical to vector RAG and 0.1% of full GraphRAG; >700Γ lower query cost at comparable global-query quality
- Graphiti β open-source temporal knowledge graph engine behind Zep, ~20k GitHub stars
- LangGraph β LangChain's orchestration framework and runtime; StateGraph of nodes and edges over shared state
Origin of the term:
- Josh Simmons, "We are entering the graph engineering phase" β July 4, 2026, earliest documented use
- Peter Steinberger's July 18, 2026 post β the twelve words that made it viral
- Carlos Perez's essay, ~10 hours later β the first serious expansion
Confidence notes
Stated plainly, since this document mixes source types:
- High confidence: the primitive (Part I), the three-way split of the term, the timeline, the qualitative finding that graphs win multi-hop/temporal/synthesis and lose simple-lookup/cost, the entity-resolution compounding math (that one is arithmetic), the evaluation procedure in Part VIII
- Medium confidence: specific benchmark percentages in 3.6. I verified the papers' framing, abstracts, and existence rather than individual table cells. Check the paper before quoting a number in a decision document
- Vendor-reported, directionally supported: LazyGraphRAG's 0.1% and 700Γ multipliers, Zep's DMR margin. Self-evaluated, though the LazyGraphRAG direction is corroborated by the field's move toward lazy indexing
- Explicitly corrected: the "9.5 F1 on 2WikiMultiHopQA" figure circulating for HippoRAG 2 is not in the abstract or OpenReview record β the paper's own headline is a 7% associative-memory improvement. The "$3.1M Stanford and Anthropic study" cited in some posts does not exist
- My analysis, not sourced: everything in Part VII, the four-step evaluation path, the kill criteria, and the skip list. These are judgment calls built on the sourced material, and reasonable people could sequence them differently
Currency: this field is moving fast and the term is roughly five weeks old as of August 2026. Framework specifics and benchmark leaderboards will drift. The primitive in Part I and the failure modes in Part VI will not.