Distributed agent system using Google's A2A protocol for autonomous research and summarization of ArXiv papers.
A production-ready implementation of Google's Agent-to-Agent (A2A) protocol demonstrating distributed AI agents that discover capabilities, delegate tasks, and collaborate via HTTP to perform research and summarization workflows.
Implements a distributed multi-agent system where autonomous agents communicate via Google's A2A protocol. The ResearchAgent searches arXiv for academic papers, then delegates summarization work to a specialized SummarizerAgent via standardized Task objects. The system showcases true agent-to-agent communication with capability discovery, stateful task management, and typed artifacts.
Demonstrates scalable AI agent architecture that separates data retrieval (ResearchAgent) from LLM processing (SummarizerAgent). Unlike monolithic AI systems, this architecture enables:
- Independent scaling of specialized agents
- Capability discovery without hardcoded dependencies
- Agent delegation for complex multi-step workflows
- Fault isolation and distributed processing
Unlike typical AI applications that make direct LLM calls, this system:
- Uses standardized A2A protocol for agent interoperability
- Implements capability discovery via Agent Cards (no hardcoded URLs)
- Maintains stateful task lifecycle (SUBMITTED → WORKING → COMPLETED/FAILED)
- Demonstrates agent delegation via HTTP with retry logic and polling
- Features modular architecture where agents can be developed, deployed, and scaled independently
| Feature | Description |
|---|---|
| 🤖 A2A Protocol Implementation | Full implementation of Google's Agent-to-Agent protocol with Agent Cards, Tasks, and Artifacts |
| 🔄 Agent Delegation | ResearchAgent discovers and delegates work to SummarizerAgent dynamically |
| 📊 Stateful Task Lifecycle | Tasks progress through SUBMITTED → WORKING → COMPLETED with status tracking |
| 🔍 Capability Discovery | Agents advertise capabilities via /agent-card endpoints (JSON metadata) |
| 📦 Typed Artifacts | Structured data exchange with artifact_type fields (papers, summary, json) |
| 🌐 HTTP-based Communication | Agents communicate via RESTful endpoints (discovery and task delegation) |
| ⚡ Async Processing | Asynchronous HTTP client with timeout handling and retry logic |
| 🖥️ Streamlit UI | Optional web interface for user-friendly interaction (CLI also available) |
| 🔗 arXiv Integration | Direct API access to 2M+ academic papers with metadata |
| 🧠 LLM Summarization | Groq-powered extraction of insights and follow-up questions |
┌──────────────────────────┐ HTTP GET ┌──────────────────────────┐
│ User Input │ ─────────────────────► │ ResearchAgent │
│ (Streamlit / CLI) │ │ (Port 8000) │
└──────────────────────────┘ └───────────┬──────────────┘
│
│ 1. Query arXiv API
│ (External Tool)
▼
┌──────────────────────┐
│ arXiv API │
│ (REST Tool) │
└───────────┬──────────┘
│
│ 2. Papers Retrieved
│ (List[Dict])
▼
3. Create Task
with Papers
as Artifact
│
│ 4. HTTP POST
│ to SummarizerAgent
▼
┌──────────────────────┐
│ SummarizerAgent │
│ (Port 8001) │
└───────────┬──────────┘
│
│ 5. Process Papers
│ via Groq LLM
▼
6. Generate Summary
+ Questions
│
│ 7. Update Task
│ → COMPLETED
▼
┌──────────────────────┐
│ Return Task to │
│ ResearchAgent │
└───────────┬──────────┘
│
│ 8. Aggregate Results
│ (Papers + Summary)
▼
┌──────────────────────────┐ HTTP Response ┌──────────────────────┐
│ Display Results │ ◄─────────────────────── │ Final Output │
│ (CLI / Streamlit) │ │ (JSON) │
└──────────────────────────┘ └──────────────────────┘
a2a-research-agent/
├── agents/
│ ├── __init__.py # Package exports
│ ├── research_agent.py # FastAPI server: Queries arXiv, delegates to Summarizer
│ └── summarizer_agent.py # FastAPI server: Generates summaries via Groq LLM
│
├── shared/
│ ├── __init__.py # Shared package exports
│ ├── schemas.py # Pydantic models: Tasks, Artifacts, Agent Cards
│ ├── logger.py # Centralized logging configuration
│ └── utils.py # Helper functions
│
├── frontend/
│ └── app.py # Streamlit UI (optional client interface)
│
├── cli/
│ └── client.py # Command-line interface client
│
├── artifacts/
│ ├── screenshots/ # Project screenshots and demo images
│ │ ├── a2a_terminal_startup.jpg
│ │ ├── streamlit_frontend.jpg
│ │ ├── research_agent_card.jpg
│ │ ├── summarizer_agent_card.jpg
│ │ ├── task_delegation_flow.jpg
│ │ └── results_display.jpg
│ └── docs/ # Documentation
│
├── .env # Environment variables)
├── .gitignore # Git exclusion rules
├── pyproject.toml # Project dependencies (uv-based)
├── uv.lock # Locked dependency versions
└── README.md # This file
⚠️ Prerequisites:
Create a.envfile in the root directory with the following variables:GROQ_API_KEY=your_groq_api_key_here RESEARCH_AGENT_URL=http://localhost:8000 SUMMARIZER_AGENT_URL=http://localhost:8001 GROQ_MODEL=llama-3.3-70b-versatileNotes:
GROQ_API_KEY→ Required for LLM summarizationRESEARCH_AGENT_URL→ Default:http://localhost:8000SUMMARIZER_AGENT_URL→ Default:http://localhost:8001GROQ_MODEL→ Default:llama-3.3-70b-versatile
git clone https://github.com/inv-fourier-transform/a2a-research-agent.git
cd a2a-research-agentIf you don't have uv installed:
pip install uvInstall project dependencies:
uv syncCreate a .env file in the project root:
GROQ_API_KEY=your_groq_api_key_here
RESEARCH_AGENT_URL=http://localhost:8000
SUMMARIZER_AGENT_URL=http://localhost:8001
GROQ_MODEL=llama-3.3-70b-versatileuv run agents/summarizer_agent.pyWaits on port 8001, exposes /agent-card endpoint.
uv run agents/research_agent.pyWaits on port 8000, delegates to SummarizerAgent on port 8001.
uv run cli/client.pyuv run streamlit run frontend/app.py| Reason | Explanation |
|---|---|
| Standardization | A2A provides a common language for agents to communicate, regardless of implementation details |
| Interoperability | Agents built by different teams can discover and work with each other via standardized endpoints |
| Capability Discovery | No hardcoded URLs or dependencies—agents advertise what they can do via Agent Cards |
| Scalability | Each agent can be scaled independently (e.g., 3 SummarizerAgents behind a load balancer) |
| Fault Isolation | If SummarizerAgent fails, ResearchAgent can retry or fail gracefully without crashing |
| Modularity | ResearchAgent focuses on data retrieval, SummarizerAgent on LLM processing—separation of concerns |
# ResearchAgent fetches SummarizerAgent's capabilities before delegating
GET http://localhost:8001/agent-cardReturns JSON metadata advertising skills like text_summarization and insight_extraction.
# ResearchAgent creates a Task with arXiv papers as input artifact
POST http://localhost:8001/tasks/send
{
"task": {
"id": "task_001",
"status": "SUBMITTED",
"input_artifacts": [
{"artifact_type": "papers", "data": [...]}
]
}
}- SummarizerAgent receives task → Status: WORKING
- Processes via Groq LLM → Generates summary
- Updates task → Status: COMPLETED
- ResearchAgent polls
/tasks/{task_id}or receives immediate response (sync mode)
ResearchAgent combines:
- Original papers (from arXiv)
- Generated summary (from SummarizerAgent)
- Follow-up questions (from SummarizerAgent)
| Approach | Direct LLM Call | A2A Delegation |
|---|---|---|
| Coupling | High – ResearchAgent must know LLM details | Low – ResearchAgent only knows SummarizerAgent's interface |
| Scaling | ResearchAgent becomes bottleneck | Can add more SummarizerAgents independently |
| Flexibility | Hard to switch from Groq to OpenAI | Easy – just point to different SummarizerAgent |
| Complexity | Monolithic, harder to maintain | Modular, easier to test and deploy |
| Failure Handling | Single point of failure | Retry logic at delegation layer |
| Expertise Separation | One agent does everything | Research focuses on retrieval, Summarizer on LLM |
Key Insight:
ResearchAgent shouldn't care how summarization happens—only that a capable agent exists to do it. This is the delegation pattern in distributed systems.
| Component | Purpose | Implementation Details |
|---|---|---|
| Agent Card | Capability advertisement | JSON served at GET /agent-card; includes skills array (e.g., text_summarization), name, url, version |
| Task | Work unit with lifecycle | Pydantic model with id, status (SUBMITTED, WORKING, COMPLETED, FAILED), input_artifacts, output_artifacts, timestamps |
| TaskSendRequest | Task submission wrapper | Pydantic model wrapping Task with sync_mode boolean |
| Artifact | Typed data container | Contains artifact_type (papers, summary, json, text), data, optional description and metadata |
| Status Updates | Lifecycle management | SummarizerAgent updates status internally; ResearchAgent polls /tasks/{task_id} or receives immediate response |
- Accept user queries via
POST /tasks/send - Query arXiv API for academic papers
- Create Task with papers artifact
- Delegate to SummarizerAgent (port 8001)
- Aggregate results (papers + summary)
- Return final response to client
arxiv_searchresearch_orchestration
- Accept Task with papers artifact
- Extract text from paper metadata
- Call Groq LLM for summarization
- Generate summary points and follow-up questions
- Update Task status to COMPLETED
- Return Task with summary artifact
text_summarizationinsight_extractionjson_processing
Shows both ResearchAgent (port 8000) and SummarizerAgent (port 8001) starting and exposing their respective endpoints
Demonstrates A2A protocol's discovery mechanism—ResearchAgent fetching SummarizerAgent's advertised capabilities via /agent-card endpoint
ResearchAgent Card (Port 8000):

SummarizerAgent Card (Port 8001):

Clean web UI for entering research topics—replaces CLI with an interactive interface while maintaining the same A2A backend architecture
HTTP POST request from ResearchAgent to SummarizerAgent showing Task submission with papers artifact and COMPLETED response with summary artifact
Final aggregated output showing: arXiv papers with metadata, LLM-generated summary bullet points, and follow-up questions
Watch the demo
Complete walkthrough of the A2A protocol in action: discovery, delegation, and aggregation.
Click the preview below to download the video (~21 MB) and watch it locally.
- Python 3.10+ – Core language
- FastAPI – High-performance HTTP servers
- Pydantic – Data validation and serialization
- Groq – High-speed LLM inference
- arXiv API – Academic paper source
- HTTPX – Async HTTP client
- Uvicorn – ASGI server
- Streamlit – Optional web interface
- Python-dotenv – Environment configuration
- UV – Modern Python package manager
- Agent Registry (centralized discovery)
- Async Callbacks (true async task completion)
- Authentication (JWT-based security)
- Multi-Agent Orchestration (CitationAgent, FactCheckAgent, etc.)
- Docker Deployment
- Kubernetes Scaling for SummarizerAgent
- Google for the A2A Protocol specification
- arXiv.org for open access to academic papers
- Groq for fast LLM inference
- Streamlit team for the excellent web interface
This is a demonstration project showcasing the power of A2A protocol.
For production use, implement proper authentication, rate limiting, and error handling.
This project is licensed under the MIT License.
See the LICENSE.md file for full details.
Because why build one monolithic AI… when you can orchestrate an army?







