---
title: "Google ADK Tracing"
description: Instrument LLM calls made using the Google ADK Python SDK
---

import RegisterTracerPython from "../../../../snippets/register-tracer-python.mdx";

<Card horizontal icon="https://storage.googleapis.com/arize-phoenix-assets/assets/images/phoenix-docs-images/adk.avif" href="https://google.github.io/adk-docs/observability/phoenix/" title="Agent Development Kit" >
  google.github.io
</Card>

### Install

```bash
pip install openinference-instrumentation-google-adk google-adk arize-phoenix-otel
```

### Setup <a href="#setup" id="setup"></a>

Set the `GOOGLE_API_KEY` environment variable. Refer to Google's [ADK documentation](https://google.github.io/adk-docs/) for more details on authentication and environment variables.

```bash
export GOOGLE_API_KEY=[your_key_here]
```

<RegisterTracerPython projectName="my-llm-app" />

### Observe <a href="#observe" id="observe"></a>

Now that you have tracing setup, all Google ADK SDK requests will be streamed to Phoenix for observability and evaluation.

```python expandable
import asyncio

from google.adk.agents import Agent
from google.adk.runners import InMemoryRunner
from google.genai import types

def get_weather(city: str) -> dict:
    """Retrieves the current weather report for a specified city.

    Args:
        city (str): The name of the city for which to retrieve the weather report.

    Returns:
        dict: status and result or error msg.
    """
    if city.lower() == "new york":
        return {
            "status": "success",
            "report": (
                "The weather in New York is sunny with a temperature of 25 degrees"
                " Celsius (77 degrees Fahrenheit)."
            ),
        }
    else:
        return {
            "status": "error",
            "error_message": f"Weather information for '{city}' is not available.",
        }

agent = Agent(
   name="test_agent",
   model="gemini-2.0-flash-exp",
   description="Agent to answer questions using tools.",
   instruction="You must use the available tools to find an answer.",
   tools=[get_weather]
)

async def main():
    app_name = "test_instrumentation"
    user_id = "test_user"
    session_id = "test_session"
    runner = InMemoryRunner(agent=agent, app_name=app_name)
    session_service = runner.session_service
    await session_service.create_session(
        app_name=app_name,
        user_id=user_id,
        session_id=session_id
    )
    async for event in runner.run_async(
        user_id=user_id,
        session_id=session_id,
        new_message=types.Content(role="user", parts=[
            types.Part(text="What is the weather in New York?")]
        )
    ):
        if event.is_final_response():
            print(event.content.parts[0].text.strip())

if __name__ == "__main__":
    asyncio.run(main())
```

### Agent Engine Deployment

<Warning>
When using **Vertex AI Agent Engine** for remote deployment, instrumentation must be configured **within the remote agent module**, not in the main application code.
</Warning>

When deployed to Agent Engine, the Vertex AI framework aggressively manages the OpenTelemetry global state. If Phoenix uses the global `TracerProvider`, Vertex AI will automatically shut down the Phoenix export pipeline during container initialization, resulting in dropped traces and warnings. To avoid this, Phoenix must use an isolated (non-global) provider.

**Main Application:**
```python expandable
from vertexai import agent_engines

remote_agent = agent_engines.create(
    agent_engine=ModuleAgent(module_name="adk_agent", agent_name="app"),
    requirements=[
        "google-cloud-aiplatform[agent_engines,adk]",
        "arize-phoenix-otel",
        "openinference-instrumentation-google-adk",
    ],
    extra_packages=["adk_agent.py"],
    env_vars={
        # Agent Engine reaches this URL, not your machine, so localhost will not work here.
        # Full OTLP traces URL, including the /v1/traces path
        "PHOENIX_COLLECTOR_ENDPOINT": "https://your-phoenix.example.com/v1/traces",
        "PHOENIX_API_KEY": "<your-phoenix-api-key>",
    },
)
```

**Agent Module (`adk_agent.py`):**
```python expandable
from phoenix.otel import register
from openinference.instrumentation.google_adk import GoogleADKInstrumentor

tracer_provider = register(
    project_name="adk-agent",
    batch=False,  # Use sync export because Agent Engine pauses CPU after requests
    set_global_tracer_provider=False,  # Required: avoids conflict with Agent Engine's global provider
    protocol="http/protobuf",  # Export over HTTPS — Agent Engine cannot reach a self-hosted gRPC port
)
GoogleADKInstrumentor().instrument(tracer_provider=tracer_provider)

# Your agent code here...
```

### Resources:

<CardGroup>
    <Card title="OpenInference Package" href="https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-google-adk" icon="github" horizontal description="OpenInference Python package"/>
    <Card title="Google ADK documentation" href="https://google.github.io/adk-docs/" icon="github" horizontal description="Google ADK docs"/>
</CardGroup>
