What Crosses the Handoff: Transcript, Summary, or Contract?
A triage agent spends eleven tool calls finding the bug, then hands off. Passing the transcript ships its dead ends; passing a summary strips the uncertainty. What a typed handoff contract gets right — and the one field teams always forget.
A triage agent spends eleven tool calls working out why last night's warehouse load dropped forty thousand rows. It hands off to a repair agent. What, exactly, moves across that boundary?
That question decides more about multi-agent reliability than the choice of framework, the supervisor topology, or the model tier. Three options are on the table — the raw transcript, a written summary, or a typed contract — and each one fails in a different, predictable way.
🔍 The scene
A nightly analytics pipeline runs a staging load, then a set of data-quality assertions. One assertion fails: row count for orders_stg is 12% below the trailing median. A triage agent picks it up. It queries the warehouse, inspects the upstream extract logs, compares partition counts across three days, checks whether a source system's schema changed, and concludes the extractor silently truncated at a pagination boundary.
Now a repair agent takes over — it can re-run the extract for a partition range, open a ticket, or page a human.
The triage agent's context at handoff time holds roughly: the original alert, eleven tool calls with their results, two dead-end hypotheses it abandoned, and one conclusion. The repair agent starts with nothing.
Option 1 — Pass the whole transcript
Serialize the triage agent's message list, prepend it to the repair agent's context, and let it read.
This is the most common first implementation because it feels lossless. It is not lossless in the way that matters.
What actually goes wrong: the dead ends come along for the ride. The triage agent's second hypothesis — that a DBT model's incremental predicate was wrong — was investigated and discarded, but the transcript contains four turns of the agent reasoning about incremental predicates and only one short turn dismissing them. The repair agent reads a context that is 60% about a theory that turned out to be false, and re-litigates it. This shows up as the repair agent "helpfully" proposing a fix to the wrong layer.
There's a subtler version too. Tool results in a transcript carry no confidence marking. A query the triage agent ran against a stale replica reads identically to one it ran against the primary. The first agent knew the difference and weighted accordingly; that knowledge lived in its reasoning, not in the record.
✅ Use it when the receiver's job is genuinely to continue the same investigation — an escalation to a stronger model on the same task, not a handoff to a different role.
❌ Don't use it when the receiver has a different job. Different job means different relevance, and the transcript encodes the sender's relevance judgments, not the receiver's.
Option 2 — Pass a written summary
Ask the triage agent to write a paragraph, hand that over.
Summaries fix the dead-end problem — a competent summarizer drops the discarded hypothesis. They introduce a worse one: they are unfalsifiable at the receiving end.
Consider the summary the triage agent might produce:
The
orders_stgload is short by roughly 12%. The upstream extractor appears to have stopped early at a pagination boundary, likely around page 40. Recommend re-running the extract for 2026-08-26.
Every clause reads as fact. "Appears to," "likely," and "around" are hedges the receiving model will flatten, because downstream reasoning has no mechanism for propagating uncertainty through prose. The repair agent re-runs the extract for one day. If the real boundary was two days wide, nothing in the summary told it to check.
Worse, prose summaries fail silently under routing. If your orchestrator has three possible receivers, the summary was written without knowing which one would get it — so it either over-includes (drifting back toward transcript) or gets tuned to the most likely receiver and starves the others.
Option 3 — Pass a typed contract
Define the handoff as a schema. The triage agent doesn't write a report; it fills out a form.
{
"finding": "truncated_extract",
"confidence": "high",
"affected_table": "analytics.orders_stg",
"affected_partitions": ["2026-08-26"],
"partition_range_certain": false,
"evidence": [
{"claim": "row count 12% below trailing median",
"source_call": "warehouse_query#3", "freshness": "primary"},
{"claim": "extract log ends mid-page",
"source_call": "read_log#7", "freshness": "primary"}
],
"ruled_out": ["incremental_predicate", "source_schema_change"],
"raw_transcript_ref": "trace://run/8812/agent/triage"
}
Four things this buys that prose cannot:
ruled_outis load-bearing. It's a negative assertion the receiver can act on — a single field that does the job the transcript did badly and the summary dropped entirely.partition_range_certain: falsesurvives the trip. A boolean does not get flattened by a downstream model the way "likely" does.- Evidence carries provenance. The receiver can tell a primary read from a replica read without having read the transcript.
- The raw transcript is still reachable — by reference, not by inclusion. The receiver pulls it only if it needs to disagree.
That last point is the one teams skip. A contract without an escape hatch is a lossy channel with no appeal. A contract with a pointer to the full record is a compression scheme: cheap in the common case, complete when it isn't.
The rule that decides it
The handoff payload should be shaped by what the receiver must decide, not by what the sender happened to learn.
Write the receiver's decision first. The repair agent chooses among re-run, ticket, or page — so it needs: what's broken, how sure are we, what's the blast radius, and what's already been eliminated. Four fields. Everything else in the triage agent's context is the sender's working memory, and working memory is not an artifact.
⚠️ Where contracts actually break
They break when the sender discovers something the schema has no slot for. The triage agent finds that the extractor truncated and that the source system's pagination cursor is nondeterministic — a second, deeper finding with no field to live in.
Two mitigations, both worth having:
- A required
unmodeled_observationsfree-text field, explicitly documented as "things the schema couldn't hold." It gets read, but it's quarantined from the structured decision path. - A schema-miss counter in your traces. Every time that field is non-empty, the schema is a little wrong. Three hits on the same theme is a new field.
The short version
Transcripts hand over the sender's confusion along with its conclusions. Summaries hand over conclusions with the uncertainty quietly stripped. Contracts hand over exactly the fields the receiver's decision consumes — plus a pointer back to everything else, for the rare case where the receiver needs to check the work rather than trust it.
Design the form before you design the agents that fill it in.