Graphcoder - Parallel AI Coding Agent

11 min read Original article ↗

Plan mode has been a Claude Code mainstay since mid-2025, and it continues to be widely used for good reason: it gives the human and agent mutual understanding via a shared object before execution starts. So then what's with the title?

It's no secret that plan mode comes with inherent drawbacks: latency of plan generation, forced context switches on the user, high cognitive load with large complex plans, and approval fatigue. Some of these are solvable: Claude Code's HTML mode, for example, massively improves legibility for those larger, more complex plans. Many of these, however, aren't. This suggests that plan mode can't be the optimal protocol for mutual understanding.

So the question is not how to make plan mode prettier, faster, or less annoying. The question is how one might derive a better protocol between human and agent from first principles. A small reframe and inspiration from existing areas of computer science may give us an answer.

The Model

At its core, a coding agent is a function f:PCf: P \rightarrow C where:

  • PP is the set of prompts and
  • CC is the set of possible code outputs.

For a prompt pPp \in P, we can define the set of implementations consistent with the prompt to be Cp={cC:c satisfies p}C_p = \{c \in C : c \text{ satisfies } p\}.

The first piece of useful intuition we can then gain is via analysing the cardinality of these sets. For most prompts, we can estimate Cp1|C_p| \gg 1. For most prompts, the compatible set is large and many implementations satisfy the words the user typed. This could be down to variations in anything from algorithm choice and codebase structure to line-by-line ordering/formatting. At the other extreme, if pp is just "write this exactly in a file called example.txt: ..." then Cp=1|C_p| = 1 and the task can be considered fully specified.

Cardinality tells us how large the compatible set is, but it does not tell us how the agent is distributed over that set. Some compatible outputs may be much more likely than others, so we model the agent's output for prompt pp as a random variable over CpC_p:

XpCpX_p \in C_p

This lets us reframe generation as uncertainty reduction: XpX_p starts as a distribution over compatible outputs, and the agent's work is to collapse that distribution into one concrete output.

Formally, Shannon entropy measures the uncertainty of this output distribution:

H(Xp)=cCpPr(Xp=c)logPr(Xp=c)H(X_p) = -\sum_{c \in C_p} \Pr(X_p = c)\log \Pr(X_p = c)

where Pr(Xp=c)\Pr(X_p = c) is the probability assigned to a compatible output cc. High entropy means probability mass is spread across many outputs, so many implementations remain plausible. Low entropy means the mass is concentrated on a few outputs. Zero entropy means all probability mass is on one output. In this framing, code generation is the process of reducing H(Xp)H(X_p) until one concrete output is selected, and choices are the operations that perform that reduction.

A choice is any constraint that changes the agent's distribution over compatible outputs. Some choices remove part of the compatible output set:

CpCpCpC_p \rightarrow C'_p \subseteq C_p

Other choices may preserve CpC_p but redistribute the probability mass amongst the possibe outputs.

A useful choice concentrates the distribution around the relevant outputs, so the new output distribution has lower entropy:

H(Xp)>H(Xp)H(X_p) > H(X'_p)

Code generation is therefore a sequence of entropy-reducing choices, and the agent must either make them or ask the user for them.

The Communication Channel

You may have noticed that there's one core issue with our model we haven't yet dealt with; and that's the fact that puser intentp \ne \text{user intent}. A coding agent's job isn't actually to fulfill the prompt, it's to produce an implementation from user intent.

Let UU be the user's actual intent, PP be the prompt or message the user sends, KK be the shared context such as the repo, conversation history, files, conventions, and prior decisions, and XX be the code output. The real chain is:

UPXU \rightarrow P \rightarrow X

The user encodes intent into language, and the agent decodes from the prompt and context. The prompt thereby becomes a noisy and lossy compression of the user's intent: Ucompressed through languagePU \xrightarrow{\text{compressed through language}} P.

The agent observes (p,K)(p, K), not UU directly. It therefore has to maintain a posterior over intent:

Pr(Up,K)\Pr(U \mid p, K)

A posterior is the agent's distribution over what the user might have meant after observing the prompt and context. If that posterior is concentrated, one interpretation dominates. If it is spread out, many meanings remain plausible.

This lets us separate prompt-compatible code from intent-compatible code:

Cp={cC:c satisfies the prompt p}Cu={cC:c satisfies the user intent u}C_p = \{c \in C : c \text{ satisfies the prompt } p\} \qquad C_u = \{c \in C : c \text{ satisfies the user intent } u\}

The dangerous region is then set of implementations that satisfy the prompt but miss the intent: CpCuC_p \setminus C_u.

Mutual understanding means Pr(Up,K)\Pr(U \mid p, K) is concentrated enough that choosing from CpC_p is likely to also choose from CuC_u. In plainer terms, the human and agent are talking about the same region of the output space. Bad mutual understanding is what happens when the agent confidently selects one interpretation while the user silently assumes another.

Intent ambiguity is then the remaining entropy in the posterior:

H(Up,K)H(U \mid p, K)

At this point, the structure is exactly a noisy channel: a sender encodes a message, the channel drops, compresses, or distorts part of it, and the receiver infers the original from the signal it observes. Here, the user encodes intent UU into prompt PP, the prompt loses information, and the agent decodes intent by estimating Pr(Up,K)\Pr(U \mid p, K). If prompt-only interaction fails because the channel is too narrow, the obvious next move is to widen it before execution.

Compression And Plan Mode

Prompt-only interaction gives the agent exactly one pre-execution signal, pp, from which it derives its posterior. It works when Pr(Up,K)\Pr(U \mid p, K) is already concentrated; in plain terms, when the prompt and context already make the intended interpretation obvious.

It does, however, fail when H(Up,K)H(U \mid p, K) remains high. The agent still sees multiple plausible intents, but it has nothing else to help it collapse any further uncertainty. If it collapses in the wrong direction, it may produce something in CpCuC_p \setminus C_u: an output that is defensible from the prompt while still failing the user's actual intent.

If the failure is bad decoding before execution, the obvious fix is another communication step before execution. The point is not to ask the user to restate the whole prompt; it is for the agent to expose its current decoded interpretation so the human can compare it against their actual intent. This correction is cheap because no code has been written yet.

Plan mode is exactly this: the agent reads the prompt and context, forms an interpretation, writes that interpretation down as a plan, the human approves, modifies, or rejects it, and only then does the agent execute. To show why plan mode isn't the best we can do, we have to expand our abstraction a bit.

The Limits Of Plan Mode

Plan mode changes the channel from prompt-only to prompt-plus-plan. With LL as the plan, the chain becomes UPLXU \rightarrow P \rightarrow L \rightarrow X. That increases useful communication relative to prompt-only by giving the agent a way to expose its decoded intent before execution.

Rate-distortion gives us a way to say why this helps. It describes the tradeoff between how much information a compressed signal carries and how much error remains after decoding. Here, RR is useful communication rate: the amount of task-relevant information the human and agent exchange. DD is distortion: mismatch between intended and produced output. Higher useful rate tends to reduce expected distortion: D(R)D(R) \downarrow as RR \uparrow. Plan mode helps because it increases RR.

Distortion drops as the rate of bits the human spends per task rises. Plan mode sits at the low-rate end: one coarse approval, high distortion.
One coarse approval is a low-rate encoding of intent and distortion grows fast as rate falls.

Every useful signal before final source code is compressed, so compression alone is not the failure mode. What matters is allocation: when communication happens, how much is sent, and which uncertainty it targets. Plan mode communicates only before work begins.

That is only optimal if the important uncertainties are already visible. Real coding reveals new branch points during investigation and implementation; the relevant posterior changes as the agent observes more state, Pr(Up,K,St)\Pr(U \mid p, K, S_t). Some questions only become clear after reading files, running tests, or hitting constraints.

So the limit of plan mode is temporal and structural. It asks too early and too globally, bundling many future decisions into one initial review before the agent knows where communication would be most valuable.

Attention Limits

The obvious response is to communicate more, but every human-facing signal consumes attention. More communication can reduce distortion, but only under an attention budget.

Let A(q)A(q) be the attention cost of a human interaction qq. It includes task complexity, protocol overhead, and switching cost:

A=Atask+Aprotocol+AswitchA = A_{\text{task}} + A_{\text{protocol}} + A_{\text{switch}}

AtaskA_{\text{task}} is the cost of understanding the actual problem. AprotocolA_{\text{protocol}} is the cost of interpreting the agent's representation. AswitchA_{\text{switch}} is the cost of reloading context after interruption.

Plan mode overloads attention by concentrating many decisions into one review. The human has to simulate too many future consequences, so approval becomes shallow because AprotocolA_{\text{protocol}} is too high.

Chatty agents waste attention in the opposite direction. Each question may be locally reasonable, but every interruption carries AswitchA_{\text{switch}}. Bad timing can make even useful questions net-negative.

Iterative order pays a switch cost between almost every question; batching by topic pays it only at topic boundaries.
Same 12 iterations. Switching topics costs you every time.

The channel capacity CC defines the maximum reliable rate the channel can support. If R<CR \lt C, reliable communication is possible in principle; when R>CR \gt C, communication errors are unavoidable. Plan mode increases rate by adding a plan as a signal, but the bottleneck isn't just how much the agent can usefully convey. Giant plans exceed the capacity of the human-agent channel. Inaccuracies the human misses during review become noise, and the information gained from plan approval is diminished. Alongside human attention, interface bandwidth, timing, and representation quality of the plan, diff, or question all bound channel capacity. A better protocol matches rate to the available capacity over time.

A question is worth asking only when expected uncertainty reduction exceeds attention cost: E[ΔH(q)]>A(q)\mathbb{E}[\Delta H(q)] \gt A(q). The target is not maximum communication; it is adaptive communication under an attention budget.

This is where model intelligence matters. Task burden is the residual uncertainty the agent must collapse after reading the prompt and context. Stronger models resolve more low-value uncertainty autonomously and better identify which remaining questions have high value of information. Intelligence improves UX because it gives the system a better interruption policy, not just better code.

Plan mode spends too much attention in one early burst. Chatty agents spend it across too many interruptions. The better protocol must ask the right decision at the moment it becomes valuable.

The Better Protocol

This leaves three bad protocols. Prompt-only under-communicates. Plan-then-approve communicates too early and too globally. Constant clarification communicates too often. All three fail because they allocate the channel poorly.

The better objective is adaptive communication under an attention budget. A question should be asked only when its expected uncertainty reduction is worth the attention it consumes: E[ΔH(q)]>A(q)\mathbb{E}[\Delta H(q)] \gt A(q).

That gives a different loop:

prompt -> investigate -> estimate uncertainty -> ask high-value decisions -> execute

The agent should investigate before asking because investigation changes StS_t and reveals which uncertainties matter. It should ask when the answer removes a lot of uncertainty, avoid asking when it can safely infer, batch related decisions while the context is loaded, and escalate only when the next step commits to an important branch.

The primitive is the decision, not the plan. A plan is one way to spend communication; a decision is the thing communication is trying to resolve. Better models improve UX because they route uncertainty better: they resolve low-value ambiguity themselves and surface the questions with the highest value of information. This gets even more important with swarms, where bad routing multiplies interruptions instead of reducing work.

A flat pool of nine workers under one root with scattered domain colors, vs a tree where workers cluster under three domain forks.
In a flat pool, questions hop domains. In a tree, siblings keep the next question close.