| Graph Engineering | |
|---|---|
| Room | Systems |
| Field | Agent architecture, systems engineering, control theory |
| Known for | Loop→graph topology, verifier nodes, fan-out/fan-in, routing & self-correction |
| Key figures | Harrison Chase, Shann Holmberg, Andrew Ng, Carlos E. Perez, Peter Steinberger |
Graph Engineering — Systems Master Brief
Graph engineering is the discipline of turning a single autonomous loop into a directed graph of typed, verifiable nodes — so that agentic pipelines can verify their own inputs, fan out into parallel work, fan back in through checks, route on the outcome, and act without a human in the loop. The loop finds the path; the graph defines it. This page is the baseline reference: what it is, the canonical patterns, the audit checklist, the tool landscape, and how the pattern maps onto the enc1/MemPalace/Nordisk stack.
Graph engineering is the discipline of structuring an autonomous agent so that work moves through a fixed, typed graph of nodes rather than a single free-running loop. Each node does one job, declares its inputs and outputs, and is connected to the next by explicit edges. Branches allow parallel fan-out; verifier nodes gate whether a branch may proceed; router nodes choose the next edge based on the outcome. The result is a machine that can start without you, work until a stop condition, survive failure, and leave evidence.
The core contrast comes from Shann Holmberg’s framing (July 2026): "the loop finds the path; the graph defines the path." A loop is one linear execution that iterates until it finds the correct answer for the current run. A graph is the topology every run traverses — the set of possible paths, the branch conditions, and the gates between them. Engineering the loop optimizes the run. Engineering the graph optimizes the machine that produces runs.
Harrison Chase — creator of LangGraph — pushed the field to earn the name when he asked publicly whether "graph engineering" is a real category or simply "langgraph". The honest answer that emerged is that the graph is a system design layer, not a library: LangGraph, Temporal, Dagster, and Airflow implement it; the skill is designing the nodes, contracts, verifiers, and gates independent of the runtime.
| Loop simple | Graph topology |
| One linear execution path | Fixed topology of nodes and edges |
| Iterates to find the answer per run | Every run traverses the defined structure |
| No branch, no verification step | Branches, verifiers, conditional edges |
| Cheap to build, hard to trust | Costlier to build, auditable and survivable |
| Good for a single fluent task | Good for production multi-step machines |
The field’s own shorthand: a one-shot agent is a demo; a production agent is a graph. When outputs matter and failures are costly, you reach for verifiers and gates. When the task is deterministic and single-step, a loop is enough.
Anthropic’s graph engineering guidance defines five patterns that recur across every well-built agent graph. Treat these as the vocabulary of the discipline.
Every node declares three things up front:
Contracts are what let a graph fail loudly and predictably. If a node cannot meet its contract, it returns a bounded error (never an untyped crash) and the graph either retries, routes, or halts. Example:
A verifier is a guard that checks actual output against expected output. It answers one question: did the upstream node actually do what it claimed? It can compare to a schema, an invariant, or a downstream confirmation (e.g., a rank check in search). If it fails, the graph retries, escalates, or stops — it never silently passes broken output downstream. This is the node that turns "trust the agent" into "trust but verify."
When a graph fans out into parallel work, the fan-in point must guard what it recombines: cap the number of concurrent branches, merge redundant or partial results, and order or dedupe sub-fragments before synthesis. Without a guard, parallel fan-out produces unbounded token usage, duplicate work, and incoherent merges.
Edges are not always fixed. A conditional edge routes to the next node based on the content of the current output, not a hard-coded order. This is what makes a graph an adaptive decision machine rather than a fixed pipeline. The router node in the Nordisk revenue graph is a conditional edge: it reads the metrics and picks diagnose, alert, create-task, or log-brief.
For large outputs, fuse results hierarchically rather than all at once: group branches by category, summarize each batch, then synthesize a final report from the batch summaries. This controls token usage and keeps large fan-out outputs coherent. This is the dedupe → synthesize pair in a many-agent graph.
This is the order the content-ops graph and the Nordisk revenue graph both followed: build the loop, then level it up pattern by pattern.
Applied live to the 47-post Nordisk Shopify blog on a weekly cron. All nodes are implemented under /root/loops/nordisk-content-graph/: observe, discover, research, draft, verify, publish, revert, and record, plus research_node.py, test_nodes.py, spec.md, and a .circuit_breaker guard.
For the heavier scheduling end of the discipline, see the MoH page: a typed DAG with heterogeneous executors, runtime-schedulable as a graph rather than a fixed pipe. Graph engineering and typed DAG scheduling share their spine — nodes, contracts, edges, and gates — but a DAG is compile-time scheduled while a graph is runtime-routed.
Every audit of a graph should check for these recurring failure modes:
| Stale-decision bug | A conditional edge routes on data that has gone stale since it was read. Fix: timestamp every decision input and verify freshness. |
| Phantom nodes | Nodes that exist in the manifest but are never reached, or edges that point to deleted nodes. Fix: validate graph topology at load. |
| Hash-based change-detection bugs | Change detection keyed on content hashes that ignores semantic change. Fix: verify the actual semantic invariant, not the hash. |
| Non-atomic state writes | State written in pieces so a crash leaves the graph in a half-applied state. Fix: make each state transition atomic (single transaction). |
| Silent verifier pass | A verifier that always returns true because its invariant is weak or never exercised. Fix: unit-test verifiers with known-bad inputs. |
| Unbounded fan-out | Parallel branches with no cap or merging, blowing the token budget. Fix: hard cap + fan-in guard. |
To review any agent graph, run it through the five-pattern lens and the playbook order. Two audit modes are standard:
| Use a graph | Use a loop |
| Many heterogeneous steps | Single fluent task |
| You want verification / cross-checking | Deterministic single answer |
| Parallel work with fan-out | Sequential by nature |
| Complex shared state | Stateless, ephemeral |
| Failure is costly, must survive | Low cost of a bad run |
Most production machines need a graph. Most individual agent calls need only a loop. The skill is knowing when a run must become a machine.
| Category | Tools | Role |
| Agent graph runtimes | LangGraph, Meridian, Prefect | Node/edge execution, conditional routing |
| Durable orchestration | Temporal, Dagster, Airflow, AWS Step Functions | Long-running, retrying, scheduled DAGs |
| Declarative graph engines | Fluxtion, FLAME | Compile graphs statically for performance |
| Graph DBs / knowledge graphs | Neo4j, Memgraph, MemPalace, enc1 | Store the knowledge graph agents traverse |
"Graph engineering needs a compiler" (Fluxtion, Jul 2026) argues the next step is statically compiling a graph’s nodes and edges into a runtime that is not re-parsed on every run. That is the frontier: from interpreted graph to compiled graph.
Graph engineering is not abstract here — it is the load-bearing pattern behind the whole system. The mapping:
The frontier of graph engineering — and what makes this stack self-learning — is GraphOpt: the outer loop that watches run history and re-tunes how the next run is orchestrated. A graph defines the topology of one run; GraphOpt learns the topology from the accumulated ledger of runs. This is the concrete implementation of Karpathy's "two loops" and Gloqo's "outer hill-climb from production traces."
live-graph.json version N+1.Where it lands on this stack: the revenue-ops graph (harvest → verify → fan-out → analyze → dedupe → synthesize → router → act) currently has its retry counts, fan-out width, and alert thresholds hardcoded in the script. GraphOpt learns those from run history — e.g. "the verifier needed a retry on 4/5 runs, so raise retry_max;" "fan-out cost blew the token cap, so lower fan_out_width." The same applies to the content-ops and skillopt graphs.
GraphOpt is designed for safe self-modification. Three fences rest on the self-modifying-systems literature (arXiv 2606.23075 guardrail erosion; eval-collapse / drift analysis):
TUNE deltas on safe tunables (retries, fan-out width, timeouts, caps) — and only when the replay guard shows the new topology wins on real traces.pending-review.json for explicit approval. A self-rewriting system must not rewrite its own guardrails.Implementation: /root/skill-opt/graphopt/ — lib/ledger.py, lib/deltas.py, lib/analyzer.py, lib/guard.py, lib/replay.py, lib/drift_anchor.py, and orchestrator.py. Skill: graphopt (installed in both Hermes compound-engineering and Pi). Run python3 orchestrator.py --demo to see the full loop, including the three safety fences.
/root/skill-opt/graphopt/