Agent Handoff Protocol: Seamless Multi-Agent Coordination
Multi-agent systems are the future of AI automation. But there's a critical problem: how do agents hand off work to each other without losing context?
This article defines a complete handoff protocol that enables seamless work transfer between AI agents—regardless of framework, model, or instance.
The Handoff Problem
Consider a complex workflow handled by multiple specialized agents:
Without a proper handoff protocol:
- Context is lost — Each agent starts fresh
- Work is repeated — Agents re-discover the same information
- Failures are silent — No way to know if handoff succeeded
- Debugging is impossible — No trail of what happened
The Handoff Protocol
A proper handoff protocol must handle:
- Context Transfer — All relevant state moves with the work
- Acceptance/Rejection — Receiving agent can accept or decline
- Status Tracking — Know where work is at any time
- Failure Handling — Graceful recovery when handoffs fail
- Audit Trail — Complete history of all transfers
Handoff Data Structure
{
"handoff_id": "hnd_abc123",
"from_agent": "agent_triage_001",
"to_agent": "agent_research_002",
"workflow_id": "wf_customer_support",
"status": "pending", // pending → accepted → completed | rejected
"context": {
// Everything the receiving agent needs
"task": "Find relevant help articles for billing question",
"customer_id": "cust_789",
"conversation_summary": "Customer asking about invoice #456...",
"constraints": {
"max_articles": 3,
"language": "en"
}
},
"metadata": {
"created_at": "2026-02-13T10:30:00Z",
"priority": "high",
"timeout_seconds": 300,
"retry_count": 0
}
}
Protocol Flow
Step 1: Create Handoff
Source agent packages work and context, creates handoff request.
// Agent A creates handoff
const handoff = await agentmemo.handoffs.create({
to_agent: "research-agent",
workflow_id: "customer-support",
context: {
task: "Find relevant articles",
customer: customerContext,
summary: conversationSummary
},
timeout_seconds: 300
});
// handoff.status = "pending"
Step 2: Query Pending Handoffs
Receiving agent polls for work assigned to it.
// Agent B checks for pending work
const pending = await agentmemo.handoffs.list({
to_agent: myAgentId,
status: "pending"
});
// Returns array of handoff requests waiting for acceptance
Step 3: Accept or Reject
Receiving agent decides whether to take the work.
// Agent B accepts the handoff
await agentmemo.handoffs.accept(handoff.id, {
estimated_completion: "2026-02-13T10:35:00Z"
});
// Or rejects with reason
await agentmemo.handoffs.reject(handoff.id, {
reason: "Overloaded, try another instance",
suggest_retry: true
});
Step 4: Complete Handoff
After work is done, agent marks handoff complete with output.
// Agent B completes the work
await agentmemo.handoffs.complete(handoff.id, {
output: {
articles: [
{ id: "art_1", title: "Understanding Your Invoice", relevance: 0.95 },
{ id: "art_2", title: "Payment Methods", relevance: 0.82 }
],
summary: "Found 2 highly relevant articles about billing"
}
});
// Original agent can query completion
const result = await agentmemo.handoffs.get(handoff.id);
// result.status = "completed"
// result.output = { articles: [...] }
Handling Failures
Timeout Handling
// Handoff times out after 300 seconds
// Status automatically changes to "timeout"
// Source agent can retry
const pendingHandoff = await agentmemo.handoffs.get(handoffId);
if (pendingHandoff.status === "timeout") {
// Try different agent
const retryHandoff = await agentmemo.handoffs.create({
...pendingHandoff.context,
to_agent: "research-agent-backup",
metadata: { retry_of: pendingHandoff.id }
});
}
Rejection Handling
// Listen for rejections
const handoff = await agentmemo.handoffs.get(handoffId);
if (handoff.status === "rejected") {
if (handoff.reject_reason.suggest_retry) {
// Wait and retry same agent
await sleep(5000);
await agentmemo.handoffs.retry(handoffId);
} else {
// Find alternative agent
const alternatives = await agentmemo.agents.list({
capability: "research",
status: "available"
});
// ... handoff to alternative
}
}
Multi-Stage Pipelines
For complex workflows, chain handoffs together:
// Define a pipeline
const pipeline = [
{ agent: "triage", produces: "classified_request" },
{ agent: "research", needs: "classified_request", produces: "research_results" },
{ agent: "writer", needs: "research_results", produces: "draft_response" },
{ agent: "reviewer", needs: "draft_response", produces: "final_response" }
];
// Execute pipeline with automatic handoffs
async function executePipeline(initialContext) {
let context = initialContext;
for (const stage of pipeline) {
const handoff = await agentmemo.handoffs.create({
to_agent: stage.agent,
context: context,
wait_for_completion: true // Block until done
});
// Merge output into context for next stage
context = {
...context,
[stage.produces]: handoff.output
};
}
return context.final_response;
}
Model Downgrade via Handoff
One powerful pattern: use expensive models to design workflows, then hand off to cheap models for execution.
// Opus agent designs the approach
const designHandoff = await agentmemo.handoffs.create({
to_agent: "opus-designer",
context: {
task: "Design workflow for customer refund process",
requirements: [...]
}
});
// Opus returns detailed workflow
const workflow = designHandoff.output.workflow;
// Save workflow for future use
await agentmemo.workflows.create({
name: "customer-refund",
definition: workflow,
designed_by: "opus",
designed_at: new Date()
});
// Now Haiku can execute it forever
const executionHandoff = await agentmemo.handoffs.create({
to_agent: "haiku-executor",
workflow_id: "customer-refund",
context: { customer_id: "cust_123" }
});
// Same output, 1/60th the cost
Best Practices
1. Include Complete Context
Never assume the receiving agent knows anything. Include all relevant state.
2. Set Appropriate Timeouts
Different tasks need different timeouts. Research might need 5 minutes; triage needs 30 seconds.
3. Design for Rejection
Always have a fallback plan when agents reject work.
4. Log Everything
Every handoff should create an audit trail for debugging and compliance.
5. Test Failure Modes
Simulate timeouts, rejections, and crashes. Your protocol should handle them gracefully.
Implement Handoffs in Your Agent System
AgentMemo provides a complete handoff protocol out of the box.
Start Free Trial →