Overview The Agent2Agent (A2A) protocol is an open standard designed to enable interoperability between disparate AI systems. It allows agents built on different frameworks to discover, negotiate, and collaborate on tasks securely. This skill guides the design and implementation of an orchestrating "Host Agent" using the Google Agent Development Kit (ADK) that delegates work dynamically to remote "Sub-Agents" via the A2A protocol.
Prerequisites
Python >= 3.12
google-adk[a2a]installed.Target remote agents must expose an
AgentCardat/.well-known/agent-card.jsonand accept A2A RPC endpoints (e.g.,SendMessage,GetTask).Workflow
Step 1: Initialize Project Structure Ensure your project contains the standard multi-agent package layout:
app/remote_agent_connection.py(A2A client wrap logic)app/host_agent.py(HostAgent wrapper logic)app/agent.py(Exports the instanced root ADK agent)Step 2: Implement A2A Remote Connections Inside
app/remote_agent_connection.py, create a class to manage low-level A2A sessions.Use
a2a.client.ClientFactoryto spawn connection clients from retrievedAgentCardspecifications.Keep track of A2A task states like
TaskState.completed,TaskState.input_required,TaskState.failed.Refer to
references/a2a-multiagent-python.mdSection 2 for the complete boilerplate.Step 3: Implement Host Agent Orchestration Inside
app/host_agent.py, define the orchestratingHostAgent.Run an asynchronous task
init_remote_agent_addressesduring boot to dynamically resolve the remote cards usinga2a.client.A2ACardResolver.Build the core ADK
Agentequipped with two tools:list_remote_agents: Queries and displays all available remote sub-agents with their names and descriptions.send_message: Sends prompts and tracks execution of remote tasks.
Refer to
references/a2a-multiagent-python.mdSection 3 for the complete boilerplate.Step 4: Wire Tools & Handle Task Progression Within the
send_messagetool:Dynamically track task state via the ADK
ToolContextstate dict (context_id,task_id,message_id).Check the sub-agent task state after calls. If
TaskState.input_required, settool_context.actions.escalate = Trueandtool_context.actions.skip_summarization = Trueto halt execution and return control to the parent or user.If
TaskState.failedorTaskState.canceled, raise an appropriateValueErrorto allow ADK's error-handling flows to recover or report the failure.Step 5: Convert and Extract Artifacts Convert all returned A2A message parts into ADK-friendly types:
Text Parts: Return directly.
Data/Form Parts: Return as raw JSON dictionaries.
File Parts: Decode base64 payloads and save using
await tool_context.save_artifact(file_id, file_part). Setescalate = Trueandskip_summarization = True.Examples
Example 1: Orchestration Prompt Example Input: "Delegate the audit report task to the specialist expense agent." Expected output / behavior:
- The Host Agent calls
list_remote_agentsto discover active cards:[{"name": "expense_reimbursement", "description": "Audits expense reports and generates summaries."}] - The Host Agent selects
expense_reimbursementand calls:await send_message(agent_name="expense_reimbursement", message="Review audit report...") - The tool tracks task updates over A2A and streams the result back to the host, who then reports the final success message to the user.
Error Handling
Sub-Agent Down or HTTP Timeout: If connection or resolution fails during
retrieve_card, catch thehttpx.HTTPErrorgracefully. Log the failure and continue with remaining active sub-agents.Sub-Agent Task Failure: Always catch
TaskState.failedinsend_messageand raise a descriptiveValueErrorcontaining the sub-agent's error reason so the LLM or user is informed.Input Validation
Remote Addresses: Validate remote agent addresses before calling
A2ACardResolver. Ensure they are valid URLs/domains and conform to safety specifications to prevent Server-Side Request Forgery (SSRF).Sub-Agent Cards: Check that retrieved
AgentCardschema fields (e.g.name,description) are non-empty and safe before registration.Anti-Patterns
Synchronous Blocking HTTP Calls: Never make synchronous or blocking network calls inside tools or background tasks, as this blocks the ADK event loop. Always use
httpx.AsyncClient.Static Host Configuration: Avoid hardcoding child agent capabilities or endpoints statically. Use
A2ACardResolverto resolve details dynamically via.well-known/agent-card.json.Missing Error Boundaries: Do not let a single failed remote agent connection crash the entire host orchestrator during startup or delegation. Catch and handle exceptions gracefully.
Fallback Instructions
Reference Offline Fallback: If reference files (
references/a2a-spec.mdorreferences/a2a-multiagent-python.md) are unavailable, refer to standard ADK orchestration tutorials or look up the general A2A specification protocol. You can construct custom communication wrappers around A2A RPC endpoints manually using the standard ADKWorkflowAPI or customTooldefinitions.Reference Files
references/a2a-spec.md: A2A protocol core objects (AgentCard, Task, Message, Artifact) and RPC methods.
references/a2a-multiagent-python.md: Detailed Python code boilerplate for
RemoteAgentConnectionsand the orchestratingHostAgent.Output Format This skill produces a fully functional, A2A-compliant, multi-agent host orchestrator. The resulting python code must compile with no syntax errors and conform to the file structure described in
references/a2a-multiagent-python.md.