Get started with A2A on Agent Engine

Source notebook

Repo path: agents/agent_engine/tutorial_a2a_on_agent_engine.ipynb · Open on GitHub · advanced

Builds, deploys, and queries an A2A Q&A agent on Vertex AI Agent Engine.

Summary

The notebook teaches how to wrap an ADK Gemini Q&A agent as an A2A-compliant agent with an Agent Card and AgentExecutor. It tests the agent locally, deploys it to Agent Engine with a staging bucket, then queries the managed endpoint via the Agent Platform SDK, the A2A SDK, and direct HTTP requests.

Key code patterns

Initialize Vertex AI client

vertexai.init(
    project=PROJECT_ID,
    location=LOCATION,
    staging_bucket=BUCKET_URI,
    api_endpoint=ENDPOINT,
)
client = vertexai.Client(
    project=PROJECT_ID,
    location=LOCATION,
    http_options=types.HttpOptions(api_version="v1beta1", base_url=f"{ENDPOINT}/"),
)

Configures project, region, staging bucket, and v1beta1 endpoint for Agent Engine operations.

Create ADK agent

qna_agent = LlmAgent(
    model="gemini-2.5-flash",
    name="qa_assistant",
    description="I answer questions using web search.",
    instruction="""You are a helpful Q&A assistant...""",
    tools=[google_search_tool.google_search],
)

Defines the Gemini-backed agent logic and gives it Google Search as a tool.

Create A2A agent card

qna_agent_skill = a2a_types.AgentSkill(
    id="web_qa",
    name="Web Q&A",
    description="Answer questions using current web search results",
    tags=["question-answering", "search", "research"],
    input_modes=["text/plain"],
    output_modes=["text/plain"],
)
qna_agent_card = create_agent_card(
    agent_name="Q&A Agent",
    description="A helpful assistant agent that can answer questions.",
    skills=[qna_agent_skill],
)

Advertises the agent capability, examples, and text input/output modes for A2A discovery.

Bridge A2A to ADK

async def execute(self, context, event_queue):
    query = context.get_user_input()
    updater = TaskUpdater(event_queue, context.task_id, context.context_id)
    await updater.start_work()
    session = await self._get_or_create_session(context.context_id, user_id)
    content = types.Content(role="user", parts=[types.Part(text=query)])
    async for event in self.runner.run_async(session_id=session.id, user_id=user_id, new_message=content):
        if event.is_final_response():
            await updater.add_artifact([a2a_types.Part(text=self._extract_answer(event))], name="answer", last_chunk=True)
            await updater.complete()

Implements the AgentExecutor lifecycle: read A2A input, run ADK, emit an artifact, and complete the task.

Deploy to Agent Engine

remote_a2a_agent = client.agent_engines.create(
    agent=a2a_agent,
    config={
        "display_name": a2a_agent.agent_card.name,
        "requirements": ["a2a-sdk>=1.0.0", "google-cloud-aiplatform[agent_engines,adk]>=1.156.0"],
        "staging_bucket": BUCKET_URI,
        "min_instances": 1,
        "max_instances": 1,
    },
)

Packages the local A2aAgent and deploys it as a managed Agent Engine endpoint.

Direct HTTP A2A call

headers = {
    "Authorization": f"Bearer {get_bearer_token()}",
    "Content-Type": "application/json",
    "A2A-Version": "1.0",
}
payload = {"message": {"messageId": f"msg-{os.urandom(8).hex()}", "role": "ROLE_USER", "parts": [{"text": "Who is the current UN Secretary-General?"}]}}
response = httpx.post(f"{remote_agent_card_url}/message:send", json=payload, headers=headers)

Shows the protocol-level request shape for clients without the Agent Platform or A2A Python SDK.

Models & APIs used

  • Models: gemini-2.5-flash
  • APIs / services: Vertex AI, Agent Engine, Agent Platform API, Cloud Storage
  • SDKs / libraries: a2a-sdk, google-cloud-aiplatform, google-adk, google-genai, httpx, starlette

When to use this

Use this pattern when you need to expose an ADK agent as an A2A-compliant managed endpoint on Agent Engine.

Gotchas & caveats

  • Requires a Google Cloud project with the Agent Platform API enabled.
  • Colab authentication is handled with google.colab.auth.authenticate_user, while direct HTTP uses Application Default Credentials with the cloud-platform scope.
  • A Cloud Storage staging bucket is required for deployment packaging.
  • The notebook uses v1beta1 http_options to access new, pre-release features.
  • create_agent_card is described as having current integration limitations: streaming is off and authenticated extended card support is on.
  • The remote task polling cells may need a few seconds and include retries for HTTP 400 responses.
  • The A2A client section includes a temporary workaround replacing test-agent-engine in returned interface URLs.

Best practices

  • Test the A2A agent locally with set_up before deploying to Agent Engine.
  • Define an AgentSkill with id, name, description, tags, examples, input modes, and output modes.
  • Use context_id as the Vertex session_id to preserve continuity across A2A interactions.
  • Use VertexAiSessionService when GOOGLE_CLOUD_AGENT_ENGINE_ID is present and InMemorySessionService for local execution.
  • Return final answers as A2A artifacts and update task state through TaskUpdater.
  • Poll tasks until TASK_STATE_COMPLETED or TASK_STATE_FAILED before reading artifacts.
  • Cleanly provide multiple client paths: Agent Platform SDK, A2A SDK, and direct HTTP.