---
title: "Google ADK Tracing"
description: "Automatically trace Google Agent Development Kit (ADK) executions, tool calls, and agent interactions."
sidebar:
  label: "Google ADK"
seo:
  title: "Google ADK Tracing with Judgment | Agent Framework Integration Docs"
  description: "Trace Google ADK agent executions with Judgment, including tool calls, handoffs, spans, and behavior for production agent monitoring."
---

**Google ADK integration** captures traces from your Google Agent Development Kit applications, including agent execution flow, LLM interactions, and tool calls. Since ADK uses the global OpenTelemetry tracer provider, Judgment captures spans out of the box with zero additional instrumentation.

{/* @test-flow
  id: integration-google-adk
  lang: python
  env: JUDGMENT_API_KEY, JUDGMENT_ORG_ID
  skip: Requires GOOGLE_API_KEY which is not available in CI
*/}

## Quickstart

1. ### Install Dependencies

    **uv**

    ```bash
    uv add google-adk judgeval python-dotenv
    ```

    **pip**

    ```bash
    pip install google-adk judgeval python-dotenv
    ```

2. ### Initialize Integration

    ```python title="setup.py"
    from judgeval.trace import JudgmentTracerProvider, Tracer

    Tracer.init(project_name="adk-demo")
    JudgmentTracerProvider.install_as_global_tracer_provider()
    ```

    > **Info**
    >
    > Google ADK uses the **global OpenTelemetry tracer provider** internally.
    > By installing `JudgmentTracerProvider` as the global provider, every span
    > ADK creates is automatically routed to Judgment — no extra instrumentation
    > library required.

3. ### Add to Existing Code

    Add these lines to your existing Google ADK application:

    ```python
    import asyncio
    from dotenv import load_dotenv

    load_dotenv()

    from google.adk.agents import Agent
    from google.adk.runners import InMemoryRunner
    from google.genai import types
    from judgeval.trace import JudgmentTracerProvider, Tracer  # [!code ++]

    Tracer.init(project_name="adk-demo")  # [!code highlight]
    JudgmentTracerProvider.install_as_global_tracer_provider()  # [!code highlight]

    def get_current_time(city: str) -> dict:
        """Returns the current time in a specified city."""
        return {"status": "success", "city": city, "time": "10:30 AM"}

    root_agent = Agent(
        model="gemini-2.0-flash",
        name="time_agent",
        description="Tells the current time in a specified city.",
        instruction=(
            "You are a helpful assistant. Use the get_current_time tool "
            "when asked about the time in a city."
        ),
        tools=[get_current_time],
    )

    async def main():
        runner = InMemoryRunner(agent=root_agent, app_name="demo")
        session = await runner.session_service.create_session(
            app_name="demo", user_id="user1"
        )
        msg = types.Content(
            role="user", parts=[types.Part(text="What time is it in Tokyo?")]
        )
        async for event in runner.run_async(
            user_id="user1", session_id=session.id, new_message=msg
        ):
            if event.content and event.content.parts:
                for p in event.content.parts:
                    if p.text:
                        print(p.text)

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

    All agent executions and tool calls are automatically traced.

## Example: Multi-Agent Delegation

```python title="multi_agent_example.py"
from dotenv import load_dotenv

load_dotenv()

from judgeval.trace import JudgmentTracerProvider, Tracer
from google.adk.agents import Agent
from google.adk.runners import InMemoryRunner
from google.genai import types

Tracer.init(project_name="adk-demo")
JudgmentTracerProvider.install_as_global_tracer_provider()


def get_current_time(city: str) -> dict:
    """Returns the current time in a specified city."""
    return {"status": "success", "city": city, "time": "10:30 AM"}


def get_weather(city: str) -> dict:
    """Returns the current weather in a specified city."""
    return {"status": "success", "city": city, "weather": "sunny", "temp": "72°F"}


# Define specialized agents
time_agent = Agent(
    model="gemini-2.0-flash",
    name="time_agent",
    description="Provides the current time for a given city.",
    instruction="Use the get_current_time tool to answer time-related questions.",
    tools=[get_current_time],
)

weather_agent = Agent(
    model="gemini-2.0-flash",
    name="weather_agent",
    description="Provides current weather information for a given city.",
    instruction="Use the get_weather tool to answer weather-related questions.",
    tools=[get_weather],
)

# Define a coordinator agent that delegates to sub-agents
coordinator = Agent(
    model="gemini-2.0-flash",
    name="coordinator",
    description="Routes user questions to the appropriate specialized agent.",
    instruction=(
        "You are a coordinator. Delegate time questions to the time_agent "
        "and weather questions to the weather_agent."
    ),
    sub_agents=[time_agent, weather_agent],
)


@Tracer.observe(span_type="function")  # [!code highlight]
async def main():
    runner = InMemoryRunner(agent=coordinator, app_name="demo")
    session = await runner.session_service.create_session(
        app_name="demo", user_id="user1"
    )

    questions = [
        "What time is it in Tokyo?",
        "What's the weather like in Paris?",
    ]

    for question in questions:
        msg = types.Content(
            role="user", parts=[types.Part(text=question)]
        )
        print(f"Question: {question}")
        async for event in runner.run_async(
            user_id="user1", session_id=session.id, new_message=msg
        ):
            if event.content and event.content.parts:
                for p in event.content.parts:
                    if p.text:
                        print(f"Response: {p.text}")
        print()


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

> **Info**
>
> **Tracking Additional Operations**: Use `@Tracer.observe()` to track any function or method outside the ADK workflow. This is especially useful for monitoring utility functions, API calls, or other operations that are part of your overall application flow.
>
> ```python title="complete_example.py"
> from google.adk.agents import Agent
> from google.adk.runners import InMemoryRunner
> from google.genai import types
> from judgeval.trace import JudgmentTracerProvider, Tracer
>
> Tracer.init(project_name="adk-demo")
> JudgmentTracerProvider.install_as_global_tracer_provider()
>
> @Tracer.observe(span_type="function")
> def preprocess_input(data: str) -> str:
>     return f"Preprocessed: {data}"
>
> async def run_agent(user_input: str):
>     # Preprocess input (traced with @Tracer.observe)
>     processed_input = preprocess_input(user_input)
>
>     agent = Agent(
>         model="gemini-2.0-flash",
>         name="assistant",
>         description="A helpful assistant.",
>         instruction="You are a helpful assistant.",
>     )
>
>     runner = InMemoryRunner(agent=agent, app_name="demo")
>     session = await runner.session_service.create_session(
>         app_name="demo", user_id="user1"
>     )
>     msg = types.Content(
>         role="user", parts=[types.Part(text=processed_input)]
>     )
>     async for event in runner.run_async(
>         user_id="user1", session_id=session.id, new_message=msg
>     ):
>         if event.content and event.content.parts:
>             for p in event.content.parts:
>                 if p.text:
>                     print(p.text)
>
> # Execute - both helper functions and agents are traced
> asyncio.run(run_agent("Hello World"))
> ```

## Next Steps

- [Monitor a behavior](/documentation/monitoring) - Monitor your Google ADK agents in production with behavioral scoring.
- [Instrument your agent](/documentation/tracing/instrumentation) - Configure and verify Judgment tracing beyond this integration.
