From the editor
Graph engineering: giving each agent a job you can check
How I structure work across AI agents: clear responsibilities, explicit handoffs, independent checks, and a way to stop when the work stops improving.
A single AI agent can end up researching a question, deciding which sources to trust, writing the answer and judging whether it did a good job. Those responsibilities can blur together inside one long conversation. By the time something goes wrong, it can be difficult to tell where the mistake entered.
That was the problem behind my Graph Engineering repository. I kept running into tasks where the same agent was trying to be the researcher, writer and reviewer. Splitting the work made the responsibilities easier to describe. It also created a new responsibility: deciding exactly what one agent should hand to the next.
That is what I mean by graph engineering: organizing a task into distinct jobs, with explicit connections and a checkable result for each job.
First, decide whether the task needs a graph
There is a cost to every additional agent. It needs context, consumes time and tokens, and produces another result someone has to reconcile. Parallel work can reduce elapsed time, but the coordination still has a price.
The first step in the toolkit is therefore a fairly ordinary question: would a clearer instruction let one agent handle this well?
For a small copy edit or a straightforward bug fix, the answer may be yes. A graph becomes useful when the jobs need different tools or instructions, when genuinely independent work can happen at the same time, or when the route through the task needs to be predictable and inspectable.
That decision should come before assigning roles. Otherwise, it is easy to create a researcher, analyst, strategist and reviewer who all read the same material and produce slightly different versions of the same answer.
Three things to make explicit
A node owns a particular job. A security reviewer examines access and trust boundaries. A writer produces a draft from supplied evidence. Naming the responsibility helps define the limits of the work.
An edge describes a dependency or handoff. A writer might wait for the research to pass its check. A failed review might send a draft back for revision. Some connections can be fixed in advance; others depend on the result of a check.
A contract says what a node must return and how that result will be evaluated. This is where a diagram becomes a usable plan. “Review the change carefully” leaves too much room for interpretation. A concrete contract asks for an affected file, a line, an explanation of the problem and evidence of why it matters.
The graph here describes work and its dependencies. Inside each node there is still a smaller loop: understand the task, do the work, check it and repair a failure. Good coordination depends on those individual loops having a meaningful definition of done.
Take a code review as an example
Imagine a pull request that changes account permissions and adds a new API endpoint. Correctness, security and test coverage are related concerns, but each asks different questions.
A correctness reviewer follows the expected behavior. A security reviewer examines who can reach the endpoint and what they can access. A test-coverage reviewer checks whether the important behavior and failure cases are exercised. They can inspect the same diff independently because this review task gives them read-only work.
An illustrative plan looks like this:
Pull request
|
+-----------+-----------+
| | |
Correctness Security Test coverage
| | |
Each finding gets a separate check
|
Combine surviving findings
|
Check the report's coverageThat is one possible configuration. The repository's graph-review skill defaults to correctness, security, simplification and test coverage, and allows the dimensions to be specified. Its thorough mode adds ranking and a pass over what the review missed.
The important handoff happens after a reviewer raises a finding. A fresh checking pass receives the finding and the relevant evidence, then tries to disprove it. It does not inherit the first reviewer's reasoning. That separation gives the checker a clearer job, although two model passes can still share the same blind spot.
Here is an example contract for one reviewer. This is a planning template, rather than a configuration file the toolkit parses:
Job: review access control in the changed endpoint
Inputs: the diff and the existing authorization rules
Output for each finding:
- affected file and line
- caller or request that reaches the problem
- expected and observed behavior
- supporting code or test evidence
Check:
- a fresh pass attempts to disprove each finding
- an unsupported finding is excluded
Scope: report findings; leave the code unchangedThe final report also needs to say what was reviewed and what remained unresolved. A reviewer that could not complete its job leaves a coverage gap. That gap should remain visible to the person deciding whether to merge.
Check the combined result
Passing individual checks does not guarantee that the assembled result works.
Two implementation agents might each produce valid code while disagreeing about an interface. A research brief can cite accurate facts and still reach a conclusion those facts do not support. An integration check has to examine the finished deliverable.
For code, that can mean building the combined changes and running the relevant tests. For an article, it can mean checking the finished argument against its sources. The plan should name this check before execution starts.
Resource ownership belongs in the plan too. Two agents editing the same file are sharing a dependency, even when their task descriptions sound independent. Sequence that work or give each agent a genuinely separate area to change.
Repair the right part, and know when to stop
When a node fails, the useful response is specific feedback about the failed contract. Work that already passed can be retained, while dependent work waits for the failure to be resolved.
Sometimes the output is wrong. Sometimes the assignment is wrong. Repeatedly asking a writer to fix a claim will go nowhere if the necessary evidence was never gathered. That failure belongs back in planning.
The executor skill distinguishes completed work from blocked or stagnant work. It also calls for a hard attempt or spending ceiling underneath the judgment about whether another retry is worthwhile. The final report should expose repairs and unresolved work so that a reader can understand the result they received.
These are instructions in a skill set. A production system still needs its runtime to enforce permissions, budgets and durable state. Separate roles and a well-written plan help organize judgment; their presence alone cannot establish correctness.
What is in the repository
The implementation is a collection of Claude Code skills. The main entry point brings together graph-plan and graph-run. The ready-made shapes cover review, research, content revision, repeated migrations, competing approaches, sequential builds and approval-sensitive work.
Each shape serves a different task. A comparison needs a way to judge the completed alternatives. A migration needs ownership and a check for each affected item. An approval-sensitive change needs a prepared artifact that stays tied to the version a person reviewed.
For a first experiment, choose one task with an output you already know how to judge. Ask the planner whether it needs a graph. If it does, inspect the responsibilities, handoffs and checks before running it. Compare the result and effort with your usual approach.
The repository is open on GitHub under the MIT license. The planning rules, execution behavior and individual skills are there to read and adapt.