What This Agent Does
The Writer takes a structured pile of findings and produces a short, opinionated brief. It has no tools — no web access, no calculator, nothing. Its only input is the text the Orchestrator hands it.
Splitting research and writing into two agents has practical benefits:
- The Writer can be a smaller, cheaper model if you want — it has no search to do
- The Writer's instruction is shorter and more focused — clearer output
- You can swap the Writer later (a different team, a different style) without touching the Researcher
- Failures are easier to debug — bad findings vs bad prose are now two separate problems
Write the Agent
Open writer/agent.py:
# writer/agent.py
# ==========================================
# Brief writer — no tools, just composition
# Exposed over A2A on port 8002
# ==========================================
from google.adk import Agent
from google.adk.a2a.utils.agent_to_a2a import to_a2a
INSTRUCTION = """You are an executive brief writer.
You receive raw research findings as input. Each finding has a claim,
a source URL, and sometimes a quote.
Produce a brief in this exact structure:
# {Topic}
## Bottom Line
A two-sentence verdict. What is the current state of the topic?
## Key Findings
Three to five bullet points. Each bullet is one short sentence followed by
a source citation in markdown link form.
## What to Watch
One short paragraph on what is likely to change in the next 6 months,
grounded in the findings (no speculation beyond them).
Rules:
- Cite every claim. Use markdown links: [source](url).
- Do not invent information beyond what the findings provide.
- Keep the whole brief under 300 words.
- Plain prose. No marketing language. No hedging adverbs.
"""
root_agent = Agent(
model="gemini-flash-latest",
name="writer",
description="Turns raw research findings into a concise, cited executive brief.",
instruction=INSTRUCTION,
)
a2a_app = to_a2a(root_agent, port=8002)Notice what is missing: no tools= argument. This agent does not need any. Its work is pure transformation — text in, text out.
Run It Locally
Open a third terminal (leave the Researcher running in the second):
uv run uvicorn writer.agent:a2a_app --host localhost --port 8002You should see Uvicorn running on http://localhost:8002.
Verify the Agent Card
curl http://localhost:8002/.well-known/agent-card.json | jq .name
# "writer"Two agents, two cards, two ports.
Test the Writer in Isolation
You can drive the Writer directly with some fake research findings to confirm it does its job:
curl -X POST http://localhost:8002 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": "1",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Topic: AI agent observability in 2026.\n\nFindings:\n1. OpenTelemetry added a GenAI semantic convention in early 2026 — source: https://opentelemetry.io/docs/specs/semconv/gen-ai/\n2. Langfuse and Helicone both report 3-4x growth in agent traces - source: https://langfuse.com/blog/2026-recap\n3. A2A traces are now first-class citizens with their own span attributes - source: https://a2a-protocol.org/latest/observability/"}],
"messageId": "msg-1"
}
}
}'You should get back a 200-300 word brief with that exact three-section structure. If the structure drifts, sharpen the instruction — the Writer's instruction is the single point of control for output format.
The Pattern
You now have a pattern you will reuse:
- Define a focused
Agentwith one clear job. - Pass it to
to_a2a()with a unique port. - Run it under uvicorn.
- The Agent Card at
/.well-known/agent-card.jsonbecomes the public contract.
Add a new specialist — say, a fact-checker — and you repeat that pattern on port 8003. The Orchestrator (next step) does not care how many specialists you have.
Key Takeaways
- Specialists are smaller and sharper. The Writer has zero tools and a much shorter instruction than the Researcher.
- The A2A wrapper is identical regardless of what the agent does —
to_a2a(root_agent, port=N)and you are done. - Testing each agent in isolation with curl catches instruction bugs early, before the orchestrator's behavior makes them hard to diagnose.
Reference: ADK Agent class · A2A message/send spec