Role (user, agent) Parts (text, file, or JSON) Message Role (user, agent) Part (text, file, or JSON) HTTP(S) Option 1: Messages for trivial interactions Message - A single turn of communication between a client and an agent, containing content and a role ("user" or "agent")
(Client) Agent B (Remote) HTTP(S) Message Role (user, agent) Parts (text, file, or JSON) Message Role (user, agent) Part (text, file, or JSON) HTTP(S) AgentExecutor A2A Starlette Application
core logic of the agent, executing tasks based on requests and publishing updates to an event queue. """ @abstractmethod async def execute(self, context: RequestContext, event_queue: EventQueue ) -> None: """Execute the agent's logic for a given request context. ) @abstractmethod async def cancel( self, context: RequestContext, event_queue: EventQueue ) -> None:
unit of work initiated by an agent, with a unique ID and defined lifecycle Client User Agent A (Client) Message Role (user, agent) Parts (text, file, or JSON) Task ID Status HTTP(S) Agent B (Remote) ⚙ Processing…. Task Status: - Unspecified - Submitted - Working - Completed - Failed - Cancelled - Input required - Rejected - Auth Required
(user, agent) Parts (text, file, or JSON) JSON-RPC Task ID Status HTTP(S) Artifact Parts (text, file, or JSON) JSON-RPC Option 2: Tasks for stateful interactions Artifact - A tangible output generated by an agent during a task (for example, a document, image, or structured data) Task Status: - Unspecified - Submitted - Working - Completed - Failed - Cancelled - Input required - Rejected - Auth Required
async for item in self.agent.stream(query, task.contextId): is_task_complete = item['is_task_complete'] require_user_input = item['require_user_input'] if not is_task_complete and not require_user_input: updater.update_status(...) elif require_user_input: updater.update_status(..., final=True) break else: updater.add_artifact(...) updater.complete() break 27 Agent Executor Example
async for item in self.agent.stream(query, task.contextId): is_task_complete = item['is_task_complete'] require_user_input = item['require_user_input'] if not is_task_complete and not require_user_input: updater.update_status(...) elif require_user_input: updater.update_status(..., final=True) break else: updater.add_artifact(...) updater.complete() break 28 Agent Executor Example
async for item in self.agent.stream(query, task.contextId): is_task_complete = item['is_task_complete'] require_user_input = item['require_user_input'] if not is_task_complete and not require_user_input: updater.update_status(...) elif require_user_input: updater.update_status(..., final=True) break else: updater.add_artifact(...) updater.complete() break 29 Agent Executor Example
async for item in self.agent.stream(query, task.contextId): is_task_complete = item['is_task_complete'] require_user_input = item['require_user_input'] if not is_task_complete and not require_user_input: updater.update_status(...) elif require_user_input: updater.update_status(..., final=True) break else: updater.add_artifact(...) updater.complete() break 30 Agent Executor Example
async for item in self.agent.stream(query, task.contextId): is_task_complete = item['is_task_complete'] require_user_input = item['require_user_input'] if not is_task_complete and not require_user_input: updater.update_status(...) elif require_user_input: updater.update_status(..., final=True) break else: updater.add_artifact(...) updater.complete() break 31 Agent Executor Example
Agent B (Remote) HTTPS Message Role (user, agent) Parts (text, file, or JSON) JSON-RPC Agent Card streaming: true Push updates Initial task Messages Artifacts Best suited for: - Real-time progress monitoring of long-running tasks - Receiving large results (artifacts) incrementally. - Interactive, conversational exchanges where immediate feedback or partial responses are beneficial with low latency
B (Remote) HTTPS Message Role (user, agent) Parts (text, file, or JSON) JSON-RPC Agent Card pushNotifications : true Best suited for: - Very long-running tasks that can take minutes, hours, or days to complete. - Clients that cannot or prefer not to maintain persistent connections, such as mobile applications. - Clients only need to be notified of significant state changes rather than continuous updates.
currency_agent = RemoteA2aAgent( name="currency_agent", description="Agent that can convert from one currency to another.", agent_card=f"http://localhost:8080/{AGENT_CARD_WELL_KNOWN_PATH}" ) 40 In ADK, use RemoteA2aAgent
to enable communication & collaboration between AI agents. Vertex AI Agent Engine Managed platform to deploy, manage, and scale AI agents in production. Model Context Protocol Open protocol that standardizes how applications provide context to LLMs. Agent Development Kit Open-source, code-first toolkit for building, evaluating, and deploying AI agents.