Course → Module 9: Multi-Agent Workflows
Session 2 of 7

The Handoff Problem

Agent chains break at the handoffs. Agent 1 produces output. Agent 2 consumes it. If Agent 1's output is in a format Agent 2 cannot parse, the chain fails. If Agent 1 includes information Agent 2 does not need (noise), Agent 2's context window wastes capacity. If Agent 1 omits information Agent 2 requires (gaps), Agent 2 hallucinates to fill the void.

Designing agent chains is contract design. Each agent promises a deliverable to the next. The contract specifies the exact format, the required fields, and the quality criteria of that deliverable.

Data Contracts Between Agents

A data contract is a specification that defines what one agent outputs and the next agent expects. It functions like an API contract in software engineering: both parties agree on the schema.

flowchart LR A["Agent 1
Research"] -- "Contract A→B
(JSON research brief)" --> B["Agent 2
Writer"] B -- "Contract B→C
(Markdown draft)" --> C["Agent 3
Editor"] style A fill:#222221,stroke:#c8a882,color:#ede9e3 style B fill:#222221,stroke:#6b8f71,color:#ede9e3 style C fill:#222221,stroke:#c47a5a,color:#ede9e3
Handoff Format Required Fields Validation Check
Research Agent to Writer JSON topic_summary, key_findings[], sources[], data_points[], gaps[] Valid JSON, key_findings has 5+ items, sources has 3+ items
Writer to Editor Markdown H1 title, H2 sections matching outline, word count 900-1100 Contains all expected headings, word count in range
Editor to Human Markdown with annotations Original text, inline [TAGS], score per dimension, overall verdict All 5 dimensions scored, verdict is PASS/REWORK/FAIL

Structured Output Is Non-Negotiable

Free-form text between agents is a recipe for failure. When the Research Agent returns a wall of prose, the Writing Agent has to parse it, decide what is a fact versus an opinion, figure out which claims have sources, and extract data points. That parsing step introduces errors.

Structured output (JSON, YAML, or well-defined Markdown with consistent headings) eliminates parsing ambiguity. The Writing Agent does not interpret. It reads fields. The field data_points[0].value is "61%." The field data_points[0].source is "Deloitte 2025 Survey." No interpretation needed.

To enforce structured output, include the exact schema in each agent's system prompt:

Output your research brief as JSON with this exact structure:
{
  "topic_summary": "string (2-3 sentences)",
  "key_findings": ["string", "string", ...],
  "sources": [
    {"title": "string", "url": "string", "tier": 1|2|3}
  ],
  "data_points": [
    {"claim": "string", "value": "string", "source": "string"}
  ],
  "gaps": ["string", ...]
}

Handling Schema Violations

Agents will sometimes violate the schema. They add extra fields. They omit required fields. They return prose instead of JSON. Your pipeline needs a validation step between every handoff.

flowchart LR A["Agent 1 Output"] --> B{"Schema Validation"} B -- "Valid" --> C["Agent 2 Input"] B -- "Invalid" --> D["Retry Agent 1
(modified prompt)"] D --> A style A fill:#222221,stroke:#c8a882,color:#ede9e3 style B fill:#222221,stroke:#c47a5a,color:#ede9e3 style C fill:#222221,stroke:#6b8f71,color:#ede9e3 style D fill:#222221,stroke:#8a8478,color:#ede9e3

Schema validation can be automated. For JSON output, a Python script checks: Is it valid JSON? Does it contain all required keys? Are the types correct (string vs. array vs. number)? For Markdown output, a script checks: Does it contain the expected headings? Is the word count in range?

On validation failure, retry the agent with a modified prompt that includes the specific error: "Your previous output was missing the 'gaps' field. Please regenerate with all required fields." Most schema violations resolve in one retry.

Minimizing Context Bloat

Each handoff should pass only what the next agent needs. The Research Agent's output includes source URLs and tier ratings. The Writing Agent does not need URLs (it is not generating citations at this stage). Passing them wastes context tokens.

Build a filter between each handoff that strips unnecessary fields. The Writing Agent receives: topic_summary, key_findings, data_points. It does not receive: source URLs, tier ratings, gap analysis. Those fields are preserved in the pipeline's metadata store for use by the Editor or by human reviewers, but they do not enter the Writer's context window.

Every token in an agent's context window that is not directly relevant to its task reduces the quality of its output. Keep handoffs lean. Pass what is needed. Store everything else separately.

Further Reading

Assignment

Take the 3-agent chain you designed in Session 9.1. Define the exact data contract for each handoff:

  1. Specify the output format (JSON schema or Markdown structure) for Agent 1.
  2. Specify the input requirements for Agent 2 (which fields from Agent 1's output does it need?).
  3. Specify the output format for Agent 2.
  4. Specify the input requirements for Agent 3.
  5. Define one validation check per handoff (what constitutes valid output?).

Test the chain manually: run each agent separately, verify the output matches the contract, and feed it to the next agent. Where do the handoffs break? Document every break point.