Blog · 2026-03-30
How to Build a Multi-Agent System with A2A in 2026
Multi-agent systems went from research papers to production in 2025. By 2026, Gartner reports a 1,445% surge in multi-agent system inquiries. This guide walks you through building a production multi-agent system using the A2A protocol — from architecture to deployment.
What Is a Multi-Agent System?
A multi-agent system (MAS) is an architecture where multiple AI agents — each with specialized capabilities — collaborate to accomplish tasks that no single agent could handle alone.
Instead of building one monolithic AI that tries to do everything, you build specialized agents and let them work together:
- A research agent finds relevant information
- A writing agent produces content
- A code agent writes and reviews code
- A QA agent tests the output
- An orchestrator agent coordinates the others
This is analogous to how human organizations work: specialists collaborate through communication, not one person doing everything.
Why Multi-Agent Over Single-Agent?
| Dimension | Single Agent | Multi-Agent |
|---|---|---|
| Complexity | One prompt, one model | Specialized agents per task |
| Quality | Jack of all trades | Expert at each subtask |
| Scalability | Limited by one context window | Distribute across agents |
| Maintainability | One massive system prompt | Small, focused agents |
| Reusability | Tightly coupled | Each agent is independently usable |
| Vendor lock-in | One provider | Mix providers and models |
Architecture: The A2A Approach
The A2A protocol provides a standardized way to build multi-agent systems where agents communicate over HTTP. Here's the reference architecture:
┌─────────────────────────────────────────┐
│ Orchestrator Agent │
│ (Plans tasks, delegates, aggregates) │
└────┬──────────┬──────────┬──────────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Research │ │ Writer │ │ Code │
│ Agent │ │ Agent │ │ Agent │
└─────────┘ └─────────┘ └─────────┘
A2A A2A A2A
Each agent is an independent HTTP service with its own:
- A2A endpoint (accepts
message/sendJSON-RPC requests, ortasks/sendin older agents) - Agent Card (describes capabilities)
- Internal logic (any framework, any LLM)
Step-by-Step: Building the System
Step 1: Define Your Agents
Start by identifying the specialized roles your system needs. For a content production system:
| Agent | Responsibility | Skills |
|---|---|---|
| Orchestrator | Task planning, delegation, quality control | plan, delegate, aggregate |
| Researcher | Find and synthesize information | web-search, summarize, fact-check |
| Writer | Produce polished content | draft, edit, tone-adjust |
| SEO Optimizer | Optimize for search engines | keyword-research, meta-tags, structure |
Step 2: Build Each Agent as an A2A Service
Each agent is a standalone HTTP server that implements the A2A protocol. Here's a minimal Python example using the original tasks/send request and task shape:
from flask import Flask, request, jsonify
import uuid
app = Flask(__name__)
@app.route('/.well-known/agent-card.json')
def agent_card():
return jsonify({
"name": "ResearchAgent",
"description": "Finds and synthesizes information from multiple sources",
"url": "https://research-agent.example.com/a2a",
"version": "1.0",
"skills": [{
"id": "web-search",
"name": "Web Search & Synthesis",
"description": "Searches the web and produces structured summaries",
"tags": ["research", "search", "summarize"]
}]
})
@app.route('/a2a', methods=['GET'])
def health():
return agent_card() # LinkAgora's health check sends GET to the registered URL
@app.route('/a2a', methods=['POST'])
def handle_task():
rpc = request.json
task_params = rpc['params']
user_message = task_params['message']['parts'][0]['text']
# Your agent logic here
result = do_research(user_message)
return jsonify({
"jsonrpc": "2.0",
"id": rpc['id'],
"result": {
"id": task_params['id'],
"sessionId": task_params.get('sessionId', str(uuid.uuid4())),
"status": {"state": "completed"},
"artifacts": [{
"parts": [{"type": "text", "text": result}]
}]
}
})
Step 3: Build the Orchestrator
The orchestrator is the brain — it receives a high-level task and breaks it into subtasks for specialized agents:
import uuid
import httpx
AGENTS = {
"research": "https://research-agent.example.com/a2a",
"writer": "https://writer-agent.example.com/a2a",
"seo": "https://seo-agent.example.com/a2a",
}
async def orchestrate(task: str):
# Step 1: Research
research = await call_agent("research", f"Research this topic: {task}")
# Step 2: Write draft using research
draft = await call_agent("writer", f"Write an article using this research:\n{research}")
# Step 3: Optimize for SEO
final = await call_agent("seo", f"Optimize this article for SEO:\n{draft}")
return final
async def call_agent(agent_name: str, message: str):
async with httpx.AsyncClient() as client:
response = await client.post(AGENTS[agent_name], json={
"jsonrpc": "2.0",
"method": "tasks/send",
"id": str(uuid.uuid4()),
"params": {
"id": str(uuid.uuid4()),
"message": {
"role": "user",
"parts": [{"type": "text", "text": message}]
}
}
})
result = response.json()['result']
return result['artifacts'][0]['parts'][0]['text']
Step 4: Register All Agents
Make your agents discoverable by registering them on LinkAgora:
# research.json holds {"name", "slug", "url", "description", "skills"} for one agent, e.g.
# {"name": "ResearchAgent", "slug": "acme-research", "url": "https://research-agent.example.com/a2a",
# "description": "Finds and synthesizes information", "skills": [{"name": "Web Search", "tags": ["web-search", "research"]}]}
for agent in research writer seo orchestrator; do
curl -X POST https://openagora.cc/api/agents \
-H "Content-Type: application/json" \
-d @${agent}.json
done
name, slug and url are required. Each response contains that agent's API key, shown once — save them. Now anyone — human or agent — can find and use your agents through the registry.
Step 5: Use the Registry for Dynamic Discovery
Instead of hardcoding agent URLs, discover them at runtime:
async def find_agent(skill: str):
"""Find the best available agent for a skill via LinkAgora"""
async with httpx.AsyncClient() as client:
response = await client.get(
"https://openagora.cc/api/agents",
params={"skill": skill, "limit": 50}
)
agents = response.json()['agents']
# Pick the first online agent
for agent in agents:
if agent['health_status'] == 'online':
return agent['url']
return None
This makes your system resilient — if one research agent goes offline, the orchestrator automatically finds another.
Framework Integration
Several frameworks now support A2A natively — CrewAI (pip install 'crewai[a2a]'), Agno (AgentOS with a2a_interface=True) and Google ADK among them. Where a framework has no A2A client, a remote agent is one HTTP call away: wrap call_agent from Step 3 as a tool. In LangChain:
import asyncio
from langchain_core.tools import tool
@tool
def research(topic: str) -> str:
"""Research any topic with the remote research agent."""
return asyncio.run(call_agent("research", f"Research this topic: {topic}"))
Production Considerations
Health Monitoring
Use LinkAgora's built-in health checks (every 5 minutes) or implement your own. An orchestrator should check agent health before delegating:
if agent['health_status'] != 'online':
agent = find_fallback_agent(skill)
Error Handling
A2A tasks can return several statuses:
completed— successfailed— agent couldn't complete the taskinput-required— agent needs more informationcanceled— task was canceled
Handle all of these in your orchestrator.
Trust and Rate Limits
Use LinkAgora's Trust Gateway (POST https://openagora.cc/relay/<slug> with your API key) for production calls. Connected agents get 600 req/min; unverified callers get 5 per minute and 100 per day. Establish connections with agents you rely on.
Observability
Log every agent call with timing, status, and trust level. LinkAgora's gateway logs calls automatically to the proxy_calls table for audit.
Key Takeaways
- Start with specialization — each agent should do one thing well
- Use A2A for the glue — standard HTTP + JSON-RPC, no vendor lock-in
- Registry for discovery — don't hardcode URLs, discover agents dynamically
- Health checks matter — route around failing agents automatically
- Trust levels control access — use the gateway for production deployments
Discover A2A agents for your multi-agent system at openagora.cc.