Most AI coding agents are stuck in a loop.
Read a file → change it → see if tests pass → try again.
It feels productive. It isn't. And if you've ever watched an agent rename a function and forget to update 12 call sites, or hallucinate an import path, or "clean up" code it was never asked to touch — you've already felt the problem.
The loop ignores something fundamental: code is a graph.
Files import other files. Functions call other functions. Types reference
other types. When an agent modifies code without understanding this graph,
it's editing text. Not engineering software.
Introducing Graph Engineering
Graph Engineering is a methodology that forces AI agents to traverse your codebase the way a compiler does — as a web of connected nodes and edges —
before making any change.
The entire thing ships as a single file: CLAUDE.md.
Drop it into your project root. Done. Your agent now thinks in graphs.
bash
cp CLAUDE.md /your/project/CLAUDE.md
No install. No package manager. No version skew. It works with Claude Code, Copilot, Cursor, Windsurf, Aider — anything that reads an instruction file at the repo root.
The Five Principles
1. Map Before Moving
▎"If you don't know the graph, you don't know the code."
Before writing or modifying anything, the agent builds a mental model of the relevant subgraph. Which files are involved? What do they import? Who calls their exports? No code is written until this map exists.
2. Trace Dependencies
▎ "Every edge is a contract."
An import is a contract. A function call is a contract. A type reference is a contract. When you modify a node, every edge connected to it must be
honored.Trace upstream and downstream before changing anything.
3. Surgical Node-Level Changes
▎"Change the node, not the neighborhood."
One function. One type. One diff. The agent does not "refactor while it's in there." It does not clean up adjacent code. One task, one subgraph.
4. Parallel Subgraphs
▎"Independent subgraphs can run concurrently."
If two tasks touch disjoint parts of the codebase, they run in parallel. If they share edges, they sequence by dependency order. The graph structure itself tells you what can be parallelized — you don't guess.
5. Graph Memory
▎"The graph remembers what you've learned."
Every file the agent reads, every symbol it discovers, every dependency it traces — this knowledge persists. The agent never re-reads a file it has
already mapped.
What's in the Repo
Beyond the drop-in CLAUDE.md, the repo ships:
Agent definitions — runnable YAML graphs for real workflows:
- pr-reviewer.yml — blast-radius-aware PR review
- keep-ci-green.yml — detect CI failure, analyze logs, open a fix PR
- refactor-module.yml — map consumers before touching a single line
Templates — reusable graph patterns:
- Iterative refinement cycles with max iteration guards
- Verification/gate nodes (checkers)
- Long-running monitoring graphs
- Two-system sync workflows
Tooling:
bash templates/graph.sh my-workflow # scaffold a new graph
bash templates/lint-graph.sh my-graph.yml # validate it
bash tools/test-lint.sh # run the fixture test suite
The linter catches dead ends, missing failure edges, unreachable nodes, and graphs with no exit. We stress-tested it adversarially (the full findings are in research.md in the repo) before shipping.
Why Not Just Write Better Prompts?
A prompt tells the agent what to do.
A graph tells it in what order, with what checks, and where to go when something fails.
The difference shows up at failure time. A prompt-only agent that hits a
broken test retries the same action. A graph-based agent has an explicit
failure edge that routes to a diagnostic node — read the error output — before attempting a fix. The structure forces a better failure path, not just a better happy path.
Graph Engineering vs. Loop Engineering
┌────────────────┬───────────────────┬─────────────────────────┐
│ Dimension │ Loop Engineering │ Graph Engineering │
├────────────────┼───────────────────┼─────────────────────────┤
│ Mental model │ Linear cycle │ Directed graph │
├────────────────┼───────────────────┼─────────────────────────┤
│ First step │ Start coding │ Map the subgraph │
├────────────────┼───────────────────┼─────────────────────────┤
│ Error handling │ Retry the loop │ Follow the failure edge │
├────────────────┼───────────────────┼─────────────────────────┤
│ Parallelism │ Sequential │ Concurrent subgraphs │
├────────────────┼───────────────────┼─────────────────────────┤
│ Scope control │ "While I'm here…" │ One node, one edge │
└────────────────┴───────────────────┴─────────────────────────┘
Try It
Repo: https://gitlab.com/shashankchakraborty712005/devgraph
Three questions I'd love feedback on:
1. Did dropping CLAUDE.md actually change your agent's behavior?
2. Which of the five principles did the agent ignore most often?
3. What graph pattern is missing from the templates?
Drop a comment or open an issue — there's a feedback thread pinned in the repo. v1.0.0 is tagged. Path C (persistent graph memory as an actual
mechanism, not just a prompt instruction) is next.
Top comments (0)