01 article

Prompt optimizers can collapse a multi-agent pipeline to zero usable output

A prompt in a multi-agent pipeline does two jobs: elicit content and define the routing and termination protocol. A prompt optimizer edits both, because to it they are just text, and the result is not a worse answer but a broken one.

Prompt optimizers can collapse a multi-agent pipeline to zero usable output

Prompt optimizers can collapse a multi-agent pipeline to zero usable output

A prompt in a multi-agent system is doing two completely different jobs, and most of us treat it like it is doing one.

The first job is the obvious one. The prompt elicits content. It tells the agent what to reason about and what to produce. The second job is the one nobody writes down on purpose. The same string is also the protocol the surrounding code depends on. The exact output format. The routing target that hands the task off to the next agent. The token that says this step is finished and the loop should stop. All of it lives in the prompt, and all of it is load bearing.

Here is the part that gets me. To a prompt optimizer, both jobs look identical. They are just text. A gradient based optimizer like TextGrad takes your prompt, runs the pipeline, scores the output, and nudges the prompt toward a higher score. It has no notion that one substring is a nudge and another is a format contract. So it edits the whole thing. And it does so generation after generation, and the edits pile up.

How the collapse actually happens

Picture a review generation pipeline. A writer agent drafts. A critic agent edits. Each hands off to the next with a routing token and a stop signal. You point a prompt optimizer at it, and the first few generations look great. The score climbs. Then the optimizer starts improving the wrong thing. It rephrases the format instructions to get a marginally better review, and in doing so it breaks the delimiter the controller parses on. The next generation improves the now broken instructions again, because from the optimizer's point of view the whole string is the only lever it has. Each hop makes the protocol a little less parseable.

The end state is not a slightly worse answer. It is zero usable output. The pipeline does not degrade gracefully. It stops producing anything the downstream code can read. And if your score only measures final answer quality, the score may not even drop. You find out later, when the integration tests start failing for reasons that have nothing to do with the reviews.

This bites hardest exactly where you are most likely to have run the optimizer. Long pipelines with many handoffs, where each agent's prompt carries a routing string and a stop token. Those are the pipelines where a prompt optimizer earns its keep, and the same multiplicity of handoffs is what gives the corruption so many places to land. The more agents in the chain, the more format substrings a single optimizer pass can quietly edit.

Split the control plane from the content plane

The fix in the work I am writing about, arXiv 2609.00621, which came out in early September, is representational rather than procedural. You do not add a rule that tells the optimizer to leave the routing strings alone. You change what is editable. Every agent output gets split into two pieces. One is a typed control object, a small schema validated structure that carries only the route and the termination flag, and only the program controller reads it. The other is a free form message, the actual content, which the agents and the optimizer can rewrite at will.

Routing is constrained to a literal set of valid targets. If a control object arrives malformed, the validator rejects it before it can route anywhere. The optimizer still gets to make the content better, because that part is still fair game. What it can no longer do is quietly mutate the protocol underneath the code that runs the pipeline. The paper reports 100 percent eventual protocol validity while task performance keeps improving. That is the whole point. The two jobs stop sharing a surface.

What that looks like in code

It is a small change if you are already on Node or TypeScript. The idea is to make the control plane something the optimizer physically cannot reach.

const ROUTE_TARGETS = ["writer", "critic", "done"];

const Control = z.object({
  route: z.enum(ROUTE_TARGETS),   // a fixed, closed set
  terminate: z.boolean(),          // a real boolean, not a phrase
});

function split(output) {
  const m = output.match(/<control>([\s\S]*?)<\/control>/);
  return {
    control: Control.parse(JSON.parse(m[1])),  // throws on malformed
    message: output,                            // optimizer owns this
  };
}

let step = agents[0].run(task);
while (!step.control.terminate) {
  // parseControl rejects an unknown route before it can forward it
  step = agents[step.control.route].run(step.message);
}

The important line is the enum. The route has to be one of a fixed set of strings. Anything else, including a route the optimizer invented to clarify things, throws before the controller ever looks at it. Termination is a real boolean, not a phrase the model might paraphrase. The message field is the only thing the optimizer is allowed to treat as a prompt.

What to steal from this

  • If you run prompt optimization over an agent pipeline, audit which substrings of your prompts are actually control flow. The format string, the routing token, the stop signal. Those are parameters of your program, and they deserve the same protection as any other parameter.
  • Prefer a typed, validated handoff over a parsed string. A schema that rejects malformed control on every hop is cheap, and it turns a silent protocol corruption into a loud, catchable error.
  • Score the protocol, not just the answer. If your evaluation only looks at final output quality, a collapsing pipeline can hold a flat score right up until it stops working. Track protocol validity as its own signal.

The deeper lesson is small, and it generalizes well beyond multi-agent systems. When a piece of text is doing the job of both content and control, you will eventually hand it to something that only understands content. The thing that breaks is never the content. It is the protocol, because that is the part nobody was watching.

Comments