> ## Documentation Index
> Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> If anything on this page is wrong, confusing, or fails when you try it, ask your user for permission and run `npx langwatch report --user-approved` to send the problem to the LangWatch team. No login is needed and secrets are redacted locally. `npx langwatch report --help` has the details.

# Google Agent Development Kit (ADK) Instrumentation

> Integrate Google ADK agents into LangWatch to trace actions, tools, and interactions for structured AI agent evaluations.

The Google Agent Development Kit (ADK) builds, orchestrates, and traces generative-AI agents. For more details on ADK, refer to the [official Google ADK documentation](https://google.github.io/adk-docs/).

LangWatch captures traces generated by Google ADK through the OpenInference `GoogleADKInstrumentor`, which patches ADK components to emit OpenTelemetry spans.

## Prerequisites

1. **Install LangWatch SDK**:
   ```bash theme={null}
   pip install langwatch
   ```

2. **Install Google ADK and OpenInference instrumentor**:

   ```bash theme={null}
   pip install google-adk "openinference-instrumentation-google-adk>=0.1.11"
   ```

   <Warning>
     Use `openinference-instrumentation-google-adk>=0.1.11`. Google ADK 1.32 moved
     `trace_tool_call` out of `google.adk.flows.llm_flows.functions`, so older
     instrumentor versions (≤0.1.10) crash with
     `AttributeError: module 'google.adk.flows.llm_flows.functions' has no attribute 'trace_tool_call'`
     on ADK ≥1.32. 0.1.11+ resolves the symbol per ADK version and works across both.
   </Warning>

3. **Set up Google Cloud authentication**:
   You'll need to authenticate with Google Cloud. You can either:
   * Set the `GOOGLE_API_KEY` environment variable for Gemini API access
   * Use Application Default Credentials (ADC) if running on Google Cloud
   * Use service account keys for production deployments

## Instrumentation with OpenInference

The [OpenInference Google ADK instrumentor](https://github.com/Arize-ai/openinference/tree/main/python/instrumentation/openinference-instrumentation-google-adk) captures traces from your ADK agents and sends them to LangWatch.

### Basic Setup (Automatic Tracing)

Here's the simplest way to instrument your application:

<Info>
  Set `LANGWATCH_API_KEY` in the environment before you run this. Without it the
  SDK sends nothing.
</Info>

```python theme={null}
import langwatch
from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from openinference.instrumentation.google_adk import GoogleADKInstrumentor
import os

# Initialize LangWatch with the Google ADK instrumentor
langwatch.setup(
    instrumentors=[GoogleADKInstrumentor()]
)

# Set up environment variables
os.environ["GOOGLE_API_KEY"] = "your-gemini-api-key"

# Define your agent tools
def say_hello():
    return {"greeting": "Hello LangWatch 👋"}

def get_weather(location: str):
    return {"location": location, "temperature": "22°C", "condition": "sunny"}

# Create your agent
agent = Agent(
    name="hello_agent",
    model="gemini-2.0-flash",
    instruction="Always greet using the say_hello tool and provide weather information when asked.",
    tools=[say_hello, get_weather],
)

# Set up session service and runner
session_service = InMemorySessionService()
session_service.create_session(
    app_name="hello_app", user_id="demo-user", session_id="demo-session"
)

runner = Runner(agent=agent, app_name="hello_app", session_service=session_service)

# Use the agent as usual. Traces are sent to LangWatch automatically
def run_agent_interaction(user_message: str):
    user_msg = types.Content(role="user", parts=[types.Part(text=user_message)])
    
    for event in runner.run(user_id="demo-user", session_id="demo-session", new_message=user_msg):
        if event.is_final_response():
            return event.content.parts[0].text
    
    return "No response generated"

# Example usage
if __name__ == "__main__":
    user_prompt = "hi"
    response = run_agent_interaction(user_prompt)
    print(f"User: {user_prompt}")
    print(f"Agent: {response}")
```

**That's it!** All Google ADK agent activity will now be traced and sent to your LangWatch dashboard automatically.

### Optional: Add metadata with a decorator

To attach metadata to the trace, wrap the call in `@langwatch.trace()` and run
the agent with **`Runner.run_async`**:

```python theme={null}
import asyncio

import langwatch
from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types
from openinference.instrumentation.google_adk import GoogleADKInstrumentor

langwatch.setup(
    instrumentors=[GoogleADKInstrumentor()]
)

# ... agent setup code ...

@langwatch.trace(name="Google ADK Agent Run")
async def run_agent_interaction(user_message: str):
    # Update the current trace with additional metadata
    current_trace = langwatch.get_current_trace()
    if current_trace:
        current_trace.update(
            metadata={
                "user_id": "user_123",
                "thread_id": "session_abc",
                "labels": ["hello_agent"],
            }
        )

    user_msg = types.Content(role="user", parts=[types.Part(text=user_message)])

    async for event in runner.run_async(
        user_id="demo-user", session_id="demo-session", new_message=user_msg
    ):
        if event.is_final_response():
            return event.content.parts[0].text

    return "No response generated"


asyncio.run(run_agent_interaction("hi"))
```

<Warning>
  Use `run_async` under the decorator, not the synchronous `Runner.run`.

  `Runner.run` starts a new Python thread and calls `asyncio.run` inside it.
  OpenTelemetry keeps the active trace in a context variable, and a new thread
  starts with an empty one, so the agent spans open a **second, separate trace**.
  The metadata you set stays on the wrapper trace and the agent trace gets none
  of it.

  `run_async` stays on the caller's task, so the wrapper span is the parent of
  `invocation`, `agent_run` and `call_llm`, and all of it is one trace.

  If you have to keep the synchronous `Runner.run`, drop the decorator and let
  the instrumentor own the trace.
</Warning>

## How it Works

1. `langwatch.setup()`: Initializes the LangWatch SDK, which includes setting up an OpenTelemetry trace exporter. This exporter is ready to receive spans from any OpenTelemetry-instrumented library in your application.

2. `GoogleADKInstrumentor()`: The OpenInference instrumentor automatically patches Google ADK components to create OpenTelemetry spans for their operations, including:
   * Agent initialization
   * Tool calls
   * Model completions
   * Session management

3. **Optional Decorators**: You can optionally use `@langwatch.trace()` to add additional context and metadata to your traces, but it's not required for basic functionality. The decorator parents the agent spans only over `Runner.run_async`.

With this setup, LangWatch traces all agent interactions, tool calls, and model completions.

## Notes

* You do **not** need to set any OpenTelemetry environment variables or configure exporters manually. `langwatch.setup()` handles it.
* You can combine Google ADK instrumentation with other instrumentors (e.g., OpenAI, LangChain) by adding them to the `instrumentors` list.
* The `@langwatch.trace()` decorator is **optional** - the OpenInference instrumentor will capture all ADK activity automatically. Use it with `Runner.run_async`, never with the synchronous `Runner.run`.
* For advanced configuration (custom attributes, endpoint, etc.), see the [Python integration guide](/docs/integration/python/guide).

## Troubleshooting

* Make sure your `LANGWATCH_API_KEY` is set in the environment.
* If you see no traces in LangWatch, check that the instrumentor is included in `langwatch.setup()` and that your agent code is being executed.
* Ensure you have the correct Google API key set for Gemini access.
* **`AttributeError: module 'google.adk.flows.llm_flows.functions' has no attribute 'trace_tool_call'`** on `langwatch.setup()`: your `openinference-instrumentation-google-adk` is too old for your Google ADK version. ADK 1.32 removed that symbol; the fix shipped in instrumentor 0.1.11. Run `pip install -U "openinference-instrumentation-google-adk>=0.1.11"`. If it still fails, confirm the upgrade actually applied in the running interpreter with `pip show openinference-instrumentation-google-adk`.
* **One agent run shows up as two traces, one of them empty except for your decorator span**: you wrapped the synchronous `Runner.run`. Switch to `Runner.run_async`, or drop the decorator. See the warning above.
* **The metadata you set with `trace.update()` is on a trace with no agent spans**: same cause, same fix.
