M

Your Claude Agent Isn't Dumb. It's Just Stuck in a Straight Line

11 min readView source ↗

Cover image

A practical engineering pattern for combining self-correcting agent loops with dependency-aware graph orchestration - with an explicit line between what Anthropic documents, what's speculative, and what's this article's own framing.

A note on terminology, before anything else. "Claude Loop + Graph Engineering" is not an official Anthropic term. Not a product name. Not a published methodology.

It's a label. This article uses it for a real, recurring pattern - correctness handled inside a loop, coordination handled by an explicit graph - that shows up under different names across Anthropic's own documentation and across the broader agent-engineering community. Treat it as a way to think about the problem, not a name you'll find in a changelog.

Article image

The problem nobody notices until it costs them a week

A developer builds a Claude agent that reviews pull requests. It reads a diff, writes a critique, and stops.

The critique is shallow, so they add a second pass: check the output against a rubric, rewrite the weak sections. Quality improves. They add a third pass. Then a fourth.

Now it's a cycle - inspect, revise, verify, repeat - until it clears a bar or burns through its retries.

> That cycle is a loop. It solves depth.

Then the same developer points it at twelve files at once, or the same rubric across forty repositories. And the loop stops helping.

A loop runs one path at a time. Feed it forty jobs and it works through them one by one, dragging the same context along, until the window fills or the run times out.

The model was never the bottleneck. The shape of the work was.

> Not depth. Width.

Not "is this answer good" but "how do a hundred pieces of work move without stepping on each other." That's what graph engineering is for: loops inside a graph, correctness inside each node, coordination at the level of the whole system.

Article image

Why a straight line stops working

Most multi-step agent work starts life as a list:

  1. inspect pricing
  2. inspect customer reviews
  3. inspect product documentation
  4. write a market brief

It runs in order because it was written in order. Look closer, though: steps one through three never read each other's output. They just need to finish before step four starts.

The real shape isn't a line. It's three branches feeding one:

pricing ─┐

reviews ├──> brief

docs ─┘

That drawing carries more engineering information than the list ever did.

> One question kills fake dependencies instantly: what exact data crosses this arrow?

"The next step should know the last one finished" - that's status, not a dependency. "The reviewer gets the claim, the source, and the evidence excerpt" - now something real is crossing the line.

What a Claude loop actually is

Before the graph, the loop has to hold up. A graph built from shaky nodes just fails in more places at once.

A loop is one unit of Claude-driven work that doesn't stop after a single pass. Generate. Check. Accept or revise. Repeat.

Anthropic's own engineering blog names this exact shape: generator-verifier. A generator produces output, a verifier checks it against explicit criteria, and the loop repeats until the verifier signs off or the retries run out.

def run_loop(task, max_attempts=4):
    attempt = generate(task)
    for i in range(max_attempts):
        result = verify(attempt, task.criteria)
        if result.passed:
            return attempt
        attempt = revise(attempt, result.feedback)
    return escalate(task, attempt)
verify

is the part people skip. And it's the reason loops drift.

Anthropic says it plainly: "a verifier told only to check whether output is good, with no further criteria, will rubber-stamp the generator's output."

> A loop can only see the number it's given. It can't ask if the number still means anything.

That's Goodhart's law with a Claude API key. A support team ties a loop to ticket-resolution rate. The number climbs for months while the thing it was supposed to measure quietly rots.

The fix isn't a smarter loop. It's putting the loop inside a structure where something else is watching it.

Article image

What the graph adds

A graph turns a pile of loops into a system with shape. Nodes, dependencies, branches that don't wait on each other, points where results converge, gates that block until a check passes.

Four things do almost all the work:

  • Nodes. Often a loop in its own right - verify-and-retry, self-contained.
  • Edges with real payloads. Not "B runs after A." An edge carries something: a claim, a file path, extracted values.
  • Reducers. The node that merges, dedupes, ranks, or filters parallel outputs with code instead of another model call.
  • Gates. Block the edge until something clears - a verifier, a budget check, a human's click.

Run the dependency test from above across a real graph and it produces this before you write a single prompt:

GOAL: produce a market brief comparing three companies

nodes:
  research_a:  task="research company A pricing, features, sentiment"
  research_b:  task="research company B pricing, features, sentiment"
  research_c:  task="research company C pricing, features, sentiment"
  checker:     task="flag anything incomplete or off-topic"
               depends_on=[research_a, research_b, research_c]
  synthesize:  task="write the comparison"
               depends_on=[checker]

> Prompts optimize a node. The spec optimizes the system.

Article image

A full worked example, from task to gate

Theory is cheap. Here's a build.

A pull request needs a security check, a coverage check, a style check, then a verdict:

Article image

Six pieces make this real.

1. A schema per node. A typed contract, not a hope:

class CheckResult(TypedDict):
    check_type: str          # "security" | "coverage" | "style"
    findings: list[dict]     # [{ "file": str, "line": int, "issue": str, "severity": str }]
    passed: bool
    confidence: float

2. A dependency map, as data:

graph = {
    "security_check": {"depends_on": [], "loop_fn": run_security_loop},
    "coverage_check":  {"depends_on": [], "loop_fn": run_coverage_loop},
    "style_check":     {"depends_on": [], "loop_fn": run_style_loop},
    "checker":         {"depends_on": ["security_check", "coverage_check", "style_check"],
                         "loop_fn": run_checker},
    "synthesizer":     {"depends_on": ["checker"], "loop_fn": run_synthesizer},
}

3. A retry policy per node - a security check and a style check don't deserve the same patience:

retry_policy = {
    "security_check": {"max_attempts": 5, "backoff": "escalate_to_opus"},
    "style_check":     {"max_attempts": 2, "backoff": "accept_best_effort"},
}

4. A gate, written as code - it blocks regardless of what any node argues for:

def merge_gate(checker_output, synthesizer_output):
    if checker_output["unresolved_high_severity"] > 0:
        return {"status": "blocked", "reason": "unresolved high-severity finding"}
    return {"status": "requires_human_approval", "payload": synthesizer_output}

5. A reducer. The checker above takes three parallel CheckResult objects and does what a single model call shouldn't be trusted with alone: dedupe overlapping findings, flag contradictions, hand the synthesizer one clean object.

6. Failure routing that doesn't take the whole run down. If coverage_check fails out, route a flag into the checker instead of discarding the security and style results that already succeeded.

Article image

What's actually documented, and what isn't

This is the part where articles like this usually oversell themselves. So: three tiers, kept deliberately separate.

Documented and current. Anthropic's Claude Platform ships Managed Agents multiagent orchestration. A coordinator declares a multiagent.agents roster; each delegated agent runs on its own session thread - "a context-isolated event stream with its own conversation history" - with its own model, prompt, tools, and MCP servers, none shared by default. Anthropic's blog names five coordination patterns with real trade-offs: generator-verifier, orchestrator-subagent, agent teams, message bus, shared state. And their own numbers aren't flattering: multi-agent setups burned 3 to 10 times more tokens than a single agent on equivalent tasks in their testing.

Documented, describing internal usage. Anthropic states directly that Claude Code runs the orchestrator-subagent pattern internally - the main agent edits and runs commands itself, dispatches subagents for large searches, gets back distilled findings instead of raw context. That's specific and real. It is not evidence of some general "AgentTool" with a fixed number of coordination modes.

Reported, not verified, not a commitment. Early-2026 tech coverage described an internal system called "Coordinator Mode," said to have surfaced via a source leak, running parallel workers through research, spec, implementation, and verification phases. It's a data point about where third parties think tooling is heading. It is not a confirmed feature.

> The claim that ties this together - that loops nested in graphs are becoming the default shape for serious agent work - is this article's own reading. Not an Anthropic announcement.

Article image

Where this connects to the actual Claude ecosystem

The pattern above is framework-agnostic on purpose. Here's where it actually plugs into Claude:

  • Session threads = node isolation, built in. Each delegated agent streams on its own thread; the coordinator sees a condensed summary, not the full transcript.
  • MCP servers = scoped tool access, built in. Declared per agent, not per session. A research node can hold GitHub access while a synthesis node holds none.
  • Tool-permission events = the human gate, built in. An always_ask tool triggers a cross-post to the primary thread; your client answers with a user.tool_confirmation event the platform routes back automatically.
  • The verification-subagent pattern = the leniency fix, built in. Anthropic's own example pairs a coding agent with a separate verifier that reruns the full test suite.
  • Context-centric decomposition, not job-title decomposition. Anthropic's own experiment with a planner/implementer/tester/reviewer split found subagents spending more tokens coordinating than producing.

Where graphs actually break

Two failures matter more than any framework choice.

The graph agrees with itself. A model grading its own output goes easy on itself. Anthropic calls this the single most common mistake in the generator-verifier pattern. Verifier rejecting 0%? That's not a clean graph. That's a check doing nothing.

Fake parallelism. If every step genuinely needs the last one's output, drawing boxes around it just adds overhead for zero speedup. It was a loop the whole time. The tell: if you can't find two nodes with no dependency between them, there's no graph to build yet.

Article image

Metrics that actually describe a graph

A chat transcript is a bad dashboard for a system with more than one active path.

MetricWhat it tells you
Critical-path latencyLength of the longest dependency chain - where the waiting actually happens
Fan-out efficiencyHow many parallel workers produced genuinely distinct information
Node failure rateWhich workers fail most, exposing brittle prompts or tools
Retry ratePassing after four retries per node isn't healthy, even if it passes
Verifier rejection rateNear 0% is a toothless check; very high is bad upstream scoping
Token cost vs single-agent baselineAnthropic's own 3-10x figure is a real sanity check

Rules that should never be optimized away

Agent systems are optimization machines. Systems that optimize find shortcuts.

If the metric is tickets closed, the system gets generous about "resolved." The fix: freeze a handful of rules outside the loop entirely - not prompt suggestions, hard constraints the orchestrator enforces no matter what a node argues for. Which actions need a human gate with no code path around it. Which credentials the graph never touches. What schema each node must return, checked structurally, not by asking a model if it looks right.

When to skip the graph entirely

Graphs are powerful enough that people reach for them by default. That's the mistake.

Anthropic's own guidance is blunt: teams spent months on elaborate multi-agent architectures only to find better prompting on one agent did the job.

Stay with a single loop when the task is small, the steps are genuinely sequential, you're still exploring the problem, or you need to approve every intermediate step yourself.

A shift in what the hard skill actually is

First it was prompt engineering. Then tool use. Then loops - agents that check and correct their own output instead of stopping after one pass.

> This is the next layer: the hard question stops being "how do I make one call smarter" and becomes "how should the work itself move."

Which pieces run at the same time. Which ones actually depend on each other. What data crosses each edge. Where a human still holds the key.

More agents is not, by itself, the answer - Anthropic put a real number on that assumption: 3 to 10x the cost, for a lot of tasks that didn't need it.

Better topology is the answer. Draw the graph before you write the prompt.

Related articles