Files
2026-07-13 13:30:30 +08:00

1550 lines
69 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ur8xi4C7S06n"
},
"outputs": [],
"source": [
"# Copyright 2024 Google LLC\n",
"#\n",
"# Licensed under the Apache License, Version 2.0 (the \"License\");\n",
"# you may not use this file except in compliance with the License.\n",
"# You may obtain a copy of the License at\n",
"#\n",
"# https://www.apache.org/licenses/LICENSE-2.0\n",
"#\n",
"# Unless required by applicable law or agreed to in writing, software\n",
"# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
"# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
"# See the License for the specific language governing permissions and\n",
"# limitations under the License."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "JAPoU8Sm5E6e"
},
"source": [
"# Debugging and Optimizing Agents: A Guide to Tracing in Agent Engine\n",
"\n",
"<table align=\"left\">\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://colab.research.google.com/github/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://www.gstatic.com/pantheon/images/bigquery/welcome_page/colab-logo.svg\" alt=\"Google Colaboratory logo\"><br> Open in Colab\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/colab/import/https:%2F%2Fraw.githubusercontent.com%2FGoogleCloudPlatform%2Fgenerative-ai%2Fmain%2Fgemini%2Fagent-engine%2Ftracing_agents_in_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://lh3.googleusercontent.com/JmcxdQi-qOpctIvWKgPtrzZdJJK-J3sWE1RsfjZNwshCFgE_9fULcNpuXYTilIR2hjwN\" alt=\"Google Cloud Colab Enterprise logo\"><br> Open in Colab Enterprise\n",
" </a>\n",
" </td> \n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://console.cloud.google.com/vertex-ai/workbench/deploy-notebook?download_url=https://raw.githubusercontent.com/GoogleCloudPlatform/generative-ai/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\">\n",
" <img src=\"https://lh3.googleusercontent.com/UiNooY4LUgW_oTvpsNhPpQzsstV5W8F7rYgxgGBD85cWJoLmrOzhVs_ksK_vgx40SHs7jCqkTkCk=e14-rj-sc0xffffff-h130-w32\" alt=\"Vertex AI logo\"><br> Open in Workbench\n",
" </a>\n",
" </td>\n",
" <td style=\"text-align: center\">\n",
" <a href=\"https://github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\">\n",
" <img width=\"32px\" src=\"https://raw.githubusercontent.com/primer/octicons/refs/heads/main/icons/mark-github-24.svg\" alt=\"GitHub logo\"><br> View on GitHub\n",
" </a>\n",
" </td>\n",
"</table>\n",
"\n",
"<div style=\"clear: both;\"></div>\n",
"\n",
"<b>Share to:</b>\n",
"\n",
"<a href=\"https://www.linkedin.com/sharing/share-offsite/?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/8/81/LinkedIn_icon.svg\" alt=\"LinkedIn logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://bsky.app/intent/compose?text=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/7/7a/Bluesky_Logo.svg\" alt=\"Bluesky logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://twitter.com/intent/tweet?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/5a/X_icon_2.svg\" alt=\"X logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://reddit.com/submit?url=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://redditinc.com/hubfs/Reddit%20Inc/Brand/Reddit_Logo.png\" alt=\"Reddit logo\">\n",
"</a>\n",
"\n",
"<a href=\"https://www.facebook.com/sharer/sharer.php?u=https%3A//github.com/GoogleCloudPlatform/generative-ai/blob/main/gemini/agent-engine/tracing_agents_in_agent_engine.ipynb\" target=\"_blank\">\n",
" <img width=\"20px\" src=\"https://upload.wikimedia.org/wikipedia/commons/5/51/Facebook_f_logo_%282019%29.svg\" alt=\"Facebook logo\">\n",
"</a> "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "84f0f73a0f76"
},
"source": [
"| | |\n",
"|-|-|\n",
"| Author(s) | [Kristopher Overholt](https://github.com/koverholt) |"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "tvgnzT1CKxrO"
},
"source": [
"## Overview\n",
"\n",
"[Agent Engine](https://cloud.google.com/vertex-ai/generative-ai/docs/agent-engine/overview) helps you build and deploy agent-based AI applications that use LLMs and custom tools. Understanding your agent's decision-making process is essential for debugging and optimization, and [Cloud Trace](https://cloud.google.com/trace) is a great tool for exploring this tracing data to get insights.\n",
"\n",
"<img src=\"https://storage.googleapis.com/github-repo/generative-ai/gemini/agent-engine/images/cloud-trace-agent.png\">\n",
"\n",
"This notebook demonstrates how to:\n",
"\n",
"- **Learn Key Concepts**: Learn about the fundamental building blocks of tracing.\n",
"- **Deploy Your Agent**: Make your tracing-enabled agent available in a production-like environment on Agent Engine.\n",
"- **Enable Tracing**: Enable tracing in a simple agent\n",
"- **Examine Traces**: Use the Cloud Console and Cloud Trace SDK to access and analyze a specific trace.\n",
"\n",
"By the end of this notebook, you'll be able to leverage tracing to build more robust and efficient AI agents on Vertex AI."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d38b3d918526"
},
"source": [
"## Concepts\n",
"\n",
"Here are some of the key concepts and terminology related to tracing, which will be helpful to understand as we explore traces generated by an agent in Agent Engine:\n",
"\n",
"Below is an example of a trace in JSON format, showing a single span. This span represents a call to a large language model (LLM). Notice how the trace data captures important details:\n",
"\n",
"### Example trace\n",
"\n",
"```json\n",
"{\n",
" \"name\": \"llm\",\n",
" \"context\": {\n",
" \"trace_id\": \"ed7b336d-e71a-46f0-a334-5f2e87cb6cfc\",\n",
" \"span_id\": \"ad67332a-38bd-428e-9f62-538ba2fa90d4\"\n",
" },\n",
" \"span_kind\": \"LLM\",\n",
" \"parent_id\": \"f89ebb7c-10f6-4bf8-8a74-57324d2556ef\",\n",
" \"start_time\": \"2023-09-07T12:54:47.597121-06:00\",\n",
" \"end_time\": \"2023-09-07T12:54:49.321811-06:00\",\n",
" \"status_code\": \"OK\",\n",
" \"status_message\": \"\",\n",
" \"attributes\": {\n",
" \"llm.input_messages\": [\n",
" {\n",
" \"message.role\": \"system\",\n",
" \"message.content\": \"You are an expert Q&A system that is trusted around the world.\\nAlways answer the query using the provided context information, and not prior knowledge.\\nSome rules to follow:\\n1. Never directly reference the given context in your answer.\\n2. Avoid statements like 'Based on the context, ...' or 'The context information ...' or anything along those lines.\"\n",
" },\n",
" {\n",
" \"message.role\": \"user\",\n",
" \"message.content\": \"Hello?\"\n",
" }\n",
" ],\n",
" \"output.value\": \"assistant: Yes I am here\",\n",
" \"output.mime_type\": \"text/plain\"\n",
" },\n",
" \"events\": [],\n",
"}\n",
"```\n",
"\n",
"### Trace\n",
"\n",
"You can think of a [trace](https://opentelemetry.io/docs/concepts/signals/traces/) like a timeline of requests as they travel through your application. A trace is composed of individual spans, with the first span representing the overall request. Each span provides details about a specific operation within the request.\n",
"\n",
"### Span\n",
"\n",
"A [span](https://opentelemetry.io/docs/concepts/signals/traces/#spans) represents a single unit of work, like a function call or an interaction with an LLM. It captures information such as the operation's name, start and end times, and any relevant attributes (metadata). Spans can be nested, showing parent-child relationships between operations.\n",
"\n",
"### Span Attribute\n",
"\n",
"[Span attributes](https://opentelemetry.io/docs/concepts/signals/traces/#attributes) are key-value pairs that provide additional context about a span. For instance, an LLM span might have attributes like the model name, prompt text, and token count.\n",
"\n",
"### Span Kind\n",
"\n",
"[Span kind](https://opentelemetry.io/docs/concepts/signals/traces/#span-kind) categorizes the type of operation a span represents. Common kinds include:\n",
"\n",
"- `CHAIN`: Links between LLM application steps or the start of a request.\n",
"- `LLM`: A call to a large language model.\n",
"- `TOOL`: An interaction with an external tool (API, database, etc.).\n",
"- `AGENT`: A reasoning block that combines LLM and tool interactions."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "61RBz8LLbxCR"
},
"source": [
"## Get started"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "No17Cw5hgx12"
},
"source": [
"### Install Vertex AI SDK and extra packages"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"id": "tFy3H3aPgx12"
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet \\\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\" \\\n",
" google-cloud-trace"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "DF4l8DTdWgPY"
},
"source": [
"### Set Google Cloud project information and initialize Vertex AI SDK\n",
"\n",
"To get started using Vertex AI, you must have an existing Google Cloud project and [enable the Vertex AI API](https://console.cloud.google.com/flows/enableapi?apiid=aiplatform.googleapis.com).\n",
"\n",
"Learn more about [setting up a project and a development environment](https://cloud.google.com/vertex-ai/docs/start/cloud-environment)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "Nqwi-5ufWp_B"
},
"outputs": [],
"source": [
"PROJECT_ID = \"[your-project-id]\" # @param {type:\"string\"}\n",
"LOCATION = \"us-central1\" # @param {type:\"string\"}\n",
"STAGING_BUCKET = f\"gs://{PROJECT_ID}-agent-engine-staging\" # @param {type:\"string\"}\n",
"\n",
"import vertexai\n",
"\n",
"vertexai.init(project=PROJECT_ID, location=LOCATION)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "dmWOrTJ3gx13"
},
"source": [
"### Authenticate your notebook environment (Colab only)\n",
"\n",
"If you're running this notebook on Google Colab, run the cell below to authenticate your environment."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"id": "NyKGtVQjgx13"
},
"outputs": [],
"source": [
"import sys\n",
"\n",
"if \"google.colab\" in sys.modules:\n",
" from google.colab import auth\n",
"\n",
" auth.authenticate_user(project_id=PROJECT_ID)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "EdvJRUWRNGHE"
},
"source": [
"## Build and deploy an agent\n",
"\n",
"Let's dive into building a simple agent that utilizes tracing. This agent will use a few custom tools to demonstrate how tracing can provide insights into its workflow."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "4c5e77496259"
},
"source": [
"### Import libraries\n",
"\n",
"Before you start building your agent, you'll import the necessary libraries. These include the Vertex AI SDK, pandas for data analysis, and the Cloud Trace SDK for working with trace data."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"id": "5a2198c40f52"
},
"outputs": [],
"source": [
"from datetime import datetime, timedelta\n",
"\n",
"import pandas as pd\n",
"from google.cloud import trace_v1 as trace\n",
"from vertexai.agent_engines import LangchainAgent\n",
"from vertexai.agent_engines._agent_engines import _utils"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6f73957911c3"
},
"source": [
"### Define tools\n",
"\n",
"You'll define a few Python functions to act as tools for your agent. These tools will simulate actions or API calls that a real-world agent might perform. For this example, you'll create tools to classify a customer support ticket, query a knowledge base, and escalate a ticket to a human agent."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "0e7c7732f26f"
},
"outputs": [],
"source": [
"def classify_ticket(ticket_text: str) -> str:\n",
" \"\"\"Classifies a support ticket into a category.\"\"\"\n",
" # Simulate a call to a classification model\n",
" categories = {\n",
" \"general\": \"Questions and information\",\n",
" \"billing\": \"Payment and invoices\",\n",
" \"technical\": \"API and SDK developer documentation\",\n",
" }\n",
" if \"payment\" in ticket_text:\n",
" category = \"billing\"\n",
" description = categories[category]\n",
" elif \"settings\" in ticket_text:\n",
" category = \"technical\"\n",
" description = categories[category]\n",
" else:\n",
" category = \"general\"\n",
" description = categories[category]\n",
"\n",
" return f\"This ticket is in the {category} category for questions related to {description}\"\n",
"\n",
"\n",
"def search_knowledge_base(category: str) -> list[dict]:\n",
" \"\"\"Searches a knowledge base for relevant articles and documentation links.\"\"\"\n",
" # Simulate a knowledge base search\n",
" articles = {\n",
" \"general\": [\n",
" {\n",
" \"title\": \"Contacting support\",\n",
" \"url\": \"https://example.com/contact\",\n",
" }\n",
" ],\n",
" \"billing\": [\n",
" {\n",
" \"title\": \"How to update your payment information\",\n",
" \"url\": \"https://example.com/billing/update\",\n",
" },\n",
" ],\n",
" \"technical\": [\n",
" {\n",
" \"title\": \"Troubleshooting common login issues\",\n",
" \"url\": \"https://example.com/technical/help\",\n",
" },\n",
" ],\n",
" }\n",
" return articles.get(category, [])\n",
"\n",
"\n",
"def escalate_to_human(ticket_text: str) -> str:\n",
" \"\"\"Initiates escalation to a human agent for outage reports.\"\"\"\n",
" return \"Your ticket has been escalated to a human agent. Please expect a response within 1-2 hours.\""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "bd55dbf42903"
},
"source": [
"### Define agent and enable tracing\n",
"\n",
"Now, let's define your agent using the LangChain template in Agent Engine and the Vertex AI SDK. Enable tracing by setting the `enable_tracing` parameter to `True`, which allows you to capture detailed information about the agent's execution."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"id": "78fb7ab21e3a"
},
"outputs": [],
"source": [
"agent = LangchainAgent(\n",
" model=\"gemini-2.5-flash\",\n",
" model_kwargs={\"temperature\": 0},\n",
" tools=[classify_ticket, search_knowledge_base, escalate_to_human],\n",
" enable_tracing=True,\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "6d714e7d8432"
},
"source": [
"### Test your agent locally (with traces!)\n",
"\n",
"Let's test your agent locally by sending it a query. Since you've enabled tracing, you'll be able to see how the agent processes this request and interacts with its tools."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"id": "d2e9ac4ab9e9"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING:opentelemetry.exporter.cloud_trace:Span has more then 32 attributes, some will be truncated\n",
"WARNING:opentelemetry.exporter.cloud_trace:Span has more then 32 attributes, some will be truncated\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"The ticket has been classified as **Billing**.\n",
"\n",
"Here is a relevant documentation link:\n",
"**How to update your payment information**: https://example.com/billing/update\n"
]
}
],
"source": [
"response = agent.query(\n",
" input=\"\"\"\n",
" Classify the following ticket into a category and give me a relevant documentation link.\n",
"\n",
" Support ticket text:\n",
" I need to update my billing information since my payment method has expired.\n",
" \"\"\"\n",
")\n",
"\n",
"print(response[\"output\"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "82b1fbdafe7c"
},
"source": [
"### Get your first trace\n",
"\n",
"Before diving deeper into trace analysis, let's use the Cloud Trace SDK to retrieve a specific trace generated by your local agent. This will give you a concrete example to work with."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"id": "d4894bb6a2d1"
},
"outputs": [],
"source": [
"trace_client = trace.TraceServiceClient()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"id": "ea72cdb247ec"
},
"outputs": [],
"source": [
"result = [\n",
" r\n",
" for r in trace_client.list_traces(\n",
" request=trace.types.ListTracesRequest(\n",
" project_id=PROJECT_ID,\n",
" # Return all traces containing `labels {key: \"openinference.span.kind\" value: \"AGENT\"}`\n",
" filter=\"openinference.span.kind:AGENT\",\n",
" )\n",
" )\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"id": "c56a32df5305"
},
"outputs": [
{
"data": {
"text/plain": [
"span_id: 16482795484355138422\n",
"name: \"AgentExecutor\"\n",
"start_time {\n",
" seconds: 1775255962\n",
" nanos: 560381952\n",
"}\n",
"end_time {\n",
" seconds: 1775255968\n",
" nanos: 827016960\n",
"}\n",
"labels {\n",
" key: \"output.value\"\n",
" value: \"The ticket has been classified as **Billing**.\\n\\nHere is a relevant documentation link:\\n**How to update your payment information**: https://example.com/billing/update\"\n",
"}\n",
"labels {\n",
" key: \"openinference.span.kind\"\n",
" value: \"AGENT\"\n",
"}\n",
"labels {\n",
" key: \"input.value\"\n",
" value: \"\\n Classify the following ticket into a category and give me a relevant documentation link.\\n\\n Support ticket text:\\n I need to update my billing information since my payment method has expired.\\n \"\n",
"}\n",
"labels {\n",
" key: \"g.co/agent\"\n",
" value: \"opentelemetry-python 1.38.0; google-cloud-trace-exporter 1.11.0\"\n",
"}"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"trace_data = trace_client.get_trace(\n",
" project_id=PROJECT_ID, trace_id=result[0].trace_id\n",
").spans[0]\n",
"trace_data"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "19aa87abae0a"
},
"source": [
"After you deploy your agent and make remote queries in the following sections, you'll dive into the details for working with trace data in the Cloud Console or using the Python SDK for Cloud Trace."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NdGcHqUv8THp"
},
"source": [
"### Deploy your agent\n",
"\n",
"Now that you've seen how tracing works locally, let's deploy your agent to Agent Engine. This will allow you to send it queries in a production-like environment and observe its behavior through traces."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "NrTI0_1j8E7w"
},
"outputs": [],
"source": [
"client = vertexai.Client(project=PROJECT_ID, location=LOCATION)\n",
"\n",
"remote_agent = client.agent_engines.create(\n",
" agent=agent,\n",
" config={\n",
" \"staging_bucket\": STAGING_BUCKET,\n",
" \"requirements\": [\n",
" \"google-cloud-aiplatform[agent_engines,langchain]\",\n",
" ],\n",
" },\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "019c774a18fd"
},
"source": [
"### Query your deployed agent\n",
"\n",
"With your agent deployed, you can interact with it remotely. Let's send a query and generate some trace data to explore."
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"id": "zZjdFQ_Z_J43"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Your ticket has been escalated to a human agent. Please expect a response within 1-2 hours.\n"
]
}
],
"source": [
"response = remote_agent.query(\n",
" input=\"\"\"\n",
" Classify the following ticket into a category and route the customer accordingly:\n",
"\n",
" Support ticket text:\n",
" I am unable to make any API calls and I need to report an outage in the system\n",
" \"\"\",\n",
")\n",
"\n",
"print(response[\"output\"])"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "RYwmTcdgIlza"
},
"source": [
"## Exploring traces in the Cloud Console\n",
"\n",
"The Cloud Trace console provides a powerful and intuitive visual interface for exploring trace data, including visualizing, filtering, and analyzing your traces.\n",
"\n",
"Accessing the Trace Console:\n",
"\n",
"- **Project-Level View**: To see all traces for your Google Cloud project (replace `your-project-id` with your actual project ID), go to: https://console.cloud.google.com/traces/list?project=your-project-id\n",
"\n",
"- **Specific Trace**: If you know the unique Trace ID for a specific trace you want to examine, you can view it directly (replace your-trace-id with the actual Trace ID): https://console.cloud.google.com/traces/list?project=your-project-id&tid=your-trace-id\n",
"\n",
"Features to Explore in the Console:\n",
"\n",
"- **Trace List**: View a list of traces, sorted by start time, along with summary information (duration, number of spans).\n",
"- **Waterfall View**: Visualize the spans within a trace as a timeline, showing the duration of each operation and their relationships.\n",
"- **Span Details**: Click on a span to view its attributes, including the input and output data, and any custom metadata you've added.\n",
"- **Filtering and Search**: The console provides powerful options for filtering traces by time range, service, span name, and other criteria. You can also search for specific traces using keywords or attributes.\n",
"\n",
"For a detailed guide to working with traces in the console, refer to the [Cloud Trace documentation on finding traces](https://cloud.google.com/trace/docs/finding-traces). Experiment with the Cloud Trace console to gain a deeper understanding of your agent's behavior and how it's executing within Agent Engine."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "761e2e6121f6"
},
"source": [
"## Working with traces using `pandas`\n",
"\n",
"For more programmatic analysis, you can use the pandas library to work with trace data. You'll fetch traces, convert them to DataFrames, and then use pandas' functionality to explore the trace data."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"id": "e68cf66f2b2c"
},
"outputs": [],
"source": [
"result = [\n",
" r\n",
" for r in trace_client.list_traces(\n",
" request=trace.types.ListTracesRequest(\n",
" project_id=PROJECT_ID,\n",
" # Return all traces containing `labels {key: \"openinference.span.kind\" value: \"AGENT\"}`\n",
" filter=\"openinference.span.kind:AGENT\",\n",
" )\n",
" )\n",
"]"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"id": "0ee427fa9cb3"
},
"outputs": [],
"source": [
"trace_data = trace_client.get_trace(project_id=PROJECT_ID, trace_id=result[0].trace_id)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"id": "73a61c86fc7c"
},
"outputs": [
{
"data": {
"application/vnd.google.colaboratory.intrinsic+json": {
"summary": "{\n \"name\": \"spans\",\n \"rows\": 24,\n \"fields\": [\n {\n \"column\": \"span_id\",\n \"properties\": {\n \"dtype\": \"string\",\n \"num_unique_values\": 24,\n \"samples\": [\n \"4864877108742681759\",\n \"14244969276198895665\",\n \"16482795484355138422\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"name\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 9,\n \"samples\": [\n \"classify_ticket\",\n \"RunnableSequence\",\n \"ChatVertexAI\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"start_time\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 24,\n \"samples\": [\n \"2026-04-03T22:39:24.476187904Z\",\n \"2026-04-03T22:39:26.624027136Z\",\n \"2026-04-03T22:39:22.560381952Z\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"end_time\",\n \"properties\": {\n \"dtype\": \"object\",\n \"num_unique_values\": 24,\n \"samples\": [\n \"2026-04-03T22:39:24.476950784Z\",\n \"2026-04-03T22:39:26.624876032Z\",\n \"2026-04-03T22:39:28.827016960Z\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"labels\",\n \"properties\": {\n \"dtype\": \"object\",\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"parent_span_id\",\n \"properties\": {\n \"dtype\": \"category\",\n \"num_unique_values\": 7,\n \"samples\": [\n \"16482795484355138422\",\n \"18320895560218625209\",\n \"9055069022241508560\"\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}",
"type": "dataframe",
"variable_name": "spans"
},
"text/html": [
"\n",
" <div id=\"df-5c315ed8-31f7-4d81-ac59-70b60bff29e2\" class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>span_id</th>\n",
" <th>name</th>\n",
" <th>start_time</th>\n",
" <th>end_time</th>\n",
" <th>labels</th>\n",
" <th>parent_span_id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>16482795484355138422</td>\n",
" <td>AgentExecutor</td>\n",
" <td>2026-04-03T22:39:22.560381952Z</td>\n",
" <td>2026-04-03T22:39:28.827016960Z</td>\n",
" <td>{'g.co/agent': 'opentelemetry-python 1.38.0; g...</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>18320895560218625209</td>\n",
" <td>RunnableSequence</td>\n",
" <td>2026-04-03T22:39:22.561595904Z</td>\n",
" <td>2026-04-03T22:39:24.315962112Z</td>\n",
" <td>{'g.co/agent': 'opentelemetry-python 1.38.0; g...</td>\n",
" <td>16482795484355138422</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>5318547256719963820</td>\n",
" <td>RunnableParallel&lt;input,agent_scratchpad&gt;</td>\n",
" <td>2026-04-03T22:39:22.562603008Z</td>\n",
" <td>2026-04-03T22:39:22.797123072Z</td>\n",
" <td>{'g.co/agent': 'opentelemetry-python 1.38.0; g...</td>\n",
" <td>18320895560218625209</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>6013497365941041661</td>\n",
" <td>RunnableLambda</td>\n",
" <td>2026-04-03T22:39:22.563587072Z</td>\n",
" <td>2026-04-03T22:39:22.566780928Z</td>\n",
" <td>{'g.co/agent': 'opentelemetry-python 1.38.0; g...</td>\n",
" <td>5318547256719963820</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2333482926590071987</td>\n",
" <td>RunnableLambda</td>\n",
" <td>2026-04-03T22:39:22.564288Z</td>\n",
" <td>2026-04-03T22:39:22.564934912Z</td>\n",
" <td>{'g.co/agent': 'opentelemetry-python 1.38.0; g...</td>\n",
" <td>5318547256719963820</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-5c315ed8-31f7-4d81-ac59-70b60bff29e2')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-5c315ed8-31f7-4d81-ac59-70b60bff29e2 button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-5c315ed8-31f7-4d81-ac59-70b60bff29e2');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
" </div>\n",
" </div>\n"
],
"text/plain": [
" span_id name \\\n",
"0 16482795484355138422 AgentExecutor \n",
"1 18320895560218625209 RunnableSequence \n",
"2 5318547256719963820 RunnableParallel<input,agent_scratchpad> \n",
"3 6013497365941041661 RunnableLambda \n",
"4 2333482926590071987 RunnableLambda \n",
"\n",
" start_time end_time \\\n",
"0 2026-04-03T22:39:22.560381952Z 2026-04-03T22:39:28.827016960Z \n",
"1 2026-04-03T22:39:22.561595904Z 2026-04-03T22:39:24.315962112Z \n",
"2 2026-04-03T22:39:22.562603008Z 2026-04-03T22:39:22.797123072Z \n",
"3 2026-04-03T22:39:22.563587072Z 2026-04-03T22:39:22.566780928Z \n",
"4 2026-04-03T22:39:22.564288Z 2026-04-03T22:39:22.564934912Z \n",
"\n",
" labels parent_span_id \n",
"0 {'g.co/agent': 'opentelemetry-python 1.38.0; g... NaN \n",
"1 {'g.co/agent': 'opentelemetry-python 1.38.0; g... 16482795484355138422 \n",
"2 {'g.co/agent': 'opentelemetry-python 1.38.0; g... 18320895560218625209 \n",
"3 {'g.co/agent': 'opentelemetry-python 1.38.0; g... 5318547256719963820 \n",
"4 {'g.co/agent': 'opentelemetry-python 1.38.0; g... 5318547256719963820 "
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spans = pd.DataFrame.from_records([_utils.to_dict(span) for span in trace_data.spans])\n",
"spans.head()"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"id": "a5fdff97b29f"
},
"outputs": [
{
"data": {
"application/vnd.google.colaboratory.intrinsic+json": {
"repr_error": "0",
"type": "dataframe"
},
"text/html": [
"\n",
" <div id=\"df-bb2ebcd9-9f87-4918-af4c-1d3e624a8274\" class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>span_id</th>\n",
" <th>name</th>\n",
" <th>start_time</th>\n",
" <th>end_time</th>\n",
" <th>labels</th>\n",
" <th>parent_span_id</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>8043405965634465053</td>\n",
" <td>ChatVertexAI</td>\n",
" <td>2026-04-03T22:39:23.177999872Z</td>\n",
" <td>2026-04-03T22:39:24.041608960Z</td>\n",
" <td>{'llm.invocation_parameters': '{\"model_name\": ...</td>\n",
" <td>18320895560218625209</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>13701164588012977072</td>\n",
" <td>ChatVertexAI</td>\n",
" <td>2026-04-03T22:39:25.359444992Z</td>\n",
" <td>2026-04-03T22:39:26.071641088Z</td>\n",
" <td>{'llm.invocation_parameters': '{\"model_name\": ...</td>\n",
" <td>18096436531831632048</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>61932334341180327</td>\n",
" <td>ChatVertexAI</td>\n",
" <td>2026-04-03T22:39:27.309551872Z</td>\n",
" <td>2026-04-03T22:39:28.198946048Z</td>\n",
" <td>{'llm.invocation_parameters': '{\"model_name\": ...</td>\n",
" <td>9055069022241508560</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-bb2ebcd9-9f87-4918-af4c-1d3e624a8274')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-bb2ebcd9-9f87-4918-af4c-1d3e624a8274 button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-bb2ebcd9-9f87-4918-af4c-1d3e624a8274');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
" </div>\n",
" </div>\n"
],
"text/plain": [
" span_id name start_time \\\n",
"6 8043405965634465053 ChatVertexAI 2026-04-03T22:39:23.177999872Z \n",
"14 13701164588012977072 ChatVertexAI 2026-04-03T22:39:25.359444992Z \n",
"22 61932334341180327 ChatVertexAI 2026-04-03T22:39:27.309551872Z \n",
"\n",
" end_time \\\n",
"6 2026-04-03T22:39:24.041608960Z \n",
"14 2026-04-03T22:39:26.071641088Z \n",
"22 2026-04-03T22:39:28.198946048Z \n",
"\n",
" labels parent_span_id \n",
"6 {'llm.invocation_parameters': '{\"model_name\": ... 18320895560218625209 \n",
"14 {'llm.invocation_parameters': '{\"model_name\": ... 18096436531831632048 \n",
"22 {'llm.invocation_parameters': '{\"model_name\": ... 9055069022241508560 "
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spans[spans[\"name\"] == \"ChatVertexAI\"]"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"id": "691fe8935660"
},
"outputs": [
{
"data": {
"application/vnd.google.colaboratory.intrinsic+json": {
"type": "dataframe"
},
"text/html": [
"\n",
" <div id=\"df-3bbcfda6-f014-4589-b0e7-a69e40483b8a\" class=\"colab-df-container\">\n",
" <div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>llm.invocation_parameters</th>\n",
" <th>g.co/agent</th>\n",
" <th>llm.provider</th>\n",
" <th>metadata</th>\n",
" <th>output.mime_type</th>\n",
" <th>llm.input_messages.0.message.role</th>\n",
" <th>llm.token_count.total</th>\n",
" <th>output.value</th>\n",
" <th>llm.output_messages.0.message.tool_calls.0.tool_call.function.arguments</th>\n",
" <th>llm.output_messages.0.message.tool_calls.0.tool_call.function.name</th>\n",
" <th>...</th>\n",
" <th>llm.input_messages.3.message.tool_calls.0.tool_call.id</th>\n",
" <th>llm.input_messages.3.message.tool_calls.0.tool_call.function.name</th>\n",
" <th>llm.input_messages.4.message.role</th>\n",
" <th>llm.output_messages.0.message.content</th>\n",
" <th>llm.input_messages.3.message.function_call_arguments_json</th>\n",
" <th>llm.input_messages.3.message.function_call_name</th>\n",
" <th>llm.input_messages.4.message.content</th>\n",
" <th>llm.input_messages.3.message.tool_calls.0.tool_call.function.arguments</th>\n",
" <th>llm.input_messages.4.message.tool_call_id</th>\n",
" <th>llm.input_messages.3.message.role</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>{\"model_name\": \"gemini-2.5-flash\", \"temperatur...</td>\n",
" <td>opentelemetry-python 1.38.0; google-cloud-trac...</td>\n",
" <td>google</td>\n",
" <td>{\"ls_provider\": \"google_vertexai\", \"ls_model_n...</td>\n",
" <td>application/json</td>\n",
" <td>user</td>\n",
" <td>230</td>\n",
" <td>{\"generations\": [[{\"text\": \"\", \"generation_inf...</td>\n",
" <td>{\"ticket_text\": \"I need to update my billing i...</td>\n",
" <td>classify_ticket</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>14</th>\n",
" <td>{\"model_name\": \"gemini-2.5-flash\", \"temperatur...</td>\n",
" <td>opentelemetry-python 1.38.0; google-cloud-trac...</td>\n",
" <td>google</td>\n",
" <td>{\"ls_provider\": \"google_vertexai\", \"ls_model_n...</td>\n",
" <td>NaN</td>\n",
" <td>user</td>\n",
" <td>215</td>\n",
" <td>NaN</td>\n",
" <td>{\"category\": \"billing\"}</td>\n",
" <td>search_knowledge_base</td>\n",
" <td>...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>22</th>\n",
" <td>{\"model_name\": \"gemini-2.5-flash\", \"temperatur...</td>\n",
" <td>opentelemetry-python 1.38.0; google-cloud-trac...</td>\n",
" <td>google</td>\n",
" <td>{\"ls_provider\": \"google_vertexai\", \"ls_model_n...</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>299</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>...</td>\n",
" <td>570380c2-da43-462d-a03d-87b2848a006b</td>\n",
" <td>search_knowledge_base</td>\n",
" <td>tool</td>\n",
" <td>The ticket has been classified as **Billing**....</td>\n",
" <td>{\"category\": \"billing\"}</td>\n",
" <td>search_knowledge_base</td>\n",
" <td>[{\"title\": \"How to update your payment informa...</td>\n",
" <td>{\"category\": \"billing\"}</td>\n",
" <td>570380c2-da43-462d-a03d-87b2848a006b</td>\n",
" <td>assistant</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>3 rows × 46 columns</p>\n",
"</div>\n",
" <div class=\"colab-df-buttons\">\n",
"\n",
" <div class=\"colab-df-container\">\n",
" <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-3bbcfda6-f014-4589-b0e7-a69e40483b8a')\"\n",
" title=\"Convert this dataframe to an interactive table.\"\n",
" style=\"display:none;\">\n",
"\n",
" <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n",
" <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n",
" </svg>\n",
" </button>\n",
"\n",
" <style>\n",
" .colab-df-container {\n",
" display:flex;\n",
" gap: 12px;\n",
" }\n",
"\n",
" .colab-df-convert {\n",
" background-color: #E8F0FE;\n",
" border: none;\n",
" border-radius: 50%;\n",
" cursor: pointer;\n",
" display: none;\n",
" fill: #1967D2;\n",
" height: 32px;\n",
" padding: 0 0 0 0;\n",
" width: 32px;\n",
" }\n",
"\n",
" .colab-df-convert:hover {\n",
" background-color: #E2EBFA;\n",
" box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n",
" fill: #174EA6;\n",
" }\n",
"\n",
" .colab-df-buttons div {\n",
" margin-bottom: 4px;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert {\n",
" background-color: #3B4455;\n",
" fill: #D2E3FC;\n",
" }\n",
"\n",
" [theme=dark] .colab-df-convert:hover {\n",
" background-color: #434B5C;\n",
" box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n",
" filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n",
" fill: #FFFFFF;\n",
" }\n",
" </style>\n",
"\n",
" <script>\n",
" const buttonEl =\n",
" document.querySelector('#df-3bbcfda6-f014-4589-b0e7-a69e40483b8a button.colab-df-convert');\n",
" buttonEl.style.display =\n",
" google.colab.kernel.accessAllowed ? 'block' : 'none';\n",
"\n",
" async function convertToInteractive(key) {\n",
" const element = document.querySelector('#df-3bbcfda6-f014-4589-b0e7-a69e40483b8a');\n",
" const dataTable =\n",
" await google.colab.kernel.invokeFunction('convertToInteractive',\n",
" [key], {});\n",
" if (!dataTable) return;\n",
"\n",
" const docLinkHtml = 'Like what you see? Visit the ' +\n",
" '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n",
" + ' to learn more about interactive tables.';\n",
" element.innerHTML = '';\n",
" dataTable['output_type'] = 'display_data';\n",
" await google.colab.output.renderOutput(dataTable, element);\n",
" const docLink = document.createElement('div');\n",
" docLink.innerHTML = docLinkHtml;\n",
" element.appendChild(docLink);\n",
" }\n",
" </script>\n",
" </div>\n",
"\n",
"\n",
" </div>\n",
" </div>\n"
],
"text/plain": [
" llm.invocation_parameters \\\n",
"6 {\"model_name\": \"gemini-2.5-flash\", \"temperatur... \n",
"14 {\"model_name\": \"gemini-2.5-flash\", \"temperatur... \n",
"22 {\"model_name\": \"gemini-2.5-flash\", \"temperatur... \n",
"\n",
" g.co/agent llm.provider \\\n",
"6 opentelemetry-python 1.38.0; google-cloud-trac... google \n",
"14 opentelemetry-python 1.38.0; google-cloud-trac... google \n",
"22 opentelemetry-python 1.38.0; google-cloud-trac... google \n",
"\n",
" metadata output.mime_type \\\n",
"6 {\"ls_provider\": \"google_vertexai\", \"ls_model_n... application/json \n",
"14 {\"ls_provider\": \"google_vertexai\", \"ls_model_n... NaN \n",
"22 {\"ls_provider\": \"google_vertexai\", \"ls_model_n... NaN \n",
"\n",
" llm.input_messages.0.message.role llm.token_count.total \\\n",
"6 user 230 \n",
"14 user 215 \n",
"22 NaN 299 \n",
"\n",
" output.value \\\n",
"6 {\"generations\": [[{\"text\": \"\", \"generation_inf... \n",
"14 NaN \n",
"22 NaN \n",
"\n",
" llm.output_messages.0.message.tool_calls.0.tool_call.function.arguments \\\n",
"6 {\"ticket_text\": \"I need to update my billing i... \n",
"14 {\"category\": \"billing\"} \n",
"22 NaN \n",
"\n",
" llm.output_messages.0.message.tool_calls.0.tool_call.function.name ... \\\n",
"6 classify_ticket ... \n",
"14 search_knowledge_base ... \n",
"22 NaN ... \n",
"\n",
" llm.input_messages.3.message.tool_calls.0.tool_call.id \\\n",
"6 NaN \n",
"14 NaN \n",
"22 570380c2-da43-462d-a03d-87b2848a006b \n",
"\n",
" llm.input_messages.3.message.tool_calls.0.tool_call.function.name \\\n",
"6 NaN \n",
"14 NaN \n",
"22 search_knowledge_base \n",
"\n",
" llm.input_messages.4.message.role \\\n",
"6 NaN \n",
"14 NaN \n",
"22 tool \n",
"\n",
" llm.output_messages.0.message.content \\\n",
"6 NaN \n",
"14 NaN \n",
"22 The ticket has been classified as **Billing**.... \n",
"\n",
" llm.input_messages.3.message.function_call_arguments_json \\\n",
"6 NaN \n",
"14 NaN \n",
"22 {\"category\": \"billing\"} \n",
"\n",
" llm.input_messages.3.message.function_call_name \\\n",
"6 NaN \n",
"14 NaN \n",
"22 search_knowledge_base \n",
"\n",
" llm.input_messages.4.message.content \\\n",
"6 NaN \n",
"14 NaN \n",
"22 [{\"title\": \"How to update your payment informa... \n",
"\n",
" llm.input_messages.3.message.tool_calls.0.tool_call.function.arguments \\\n",
"6 NaN \n",
"14 NaN \n",
"22 {\"category\": \"billing\"} \n",
"\n",
" llm.input_messages.4.message.tool_call_id llm.input_messages.3.message.role \n",
"6 NaN NaN \n",
"14 NaN NaN \n",
"22 570380c2-da43-462d-a03d-87b2848a006b assistant \n",
"\n",
"[3 rows x 46 columns]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"spans[spans[\"name\"] == \"ChatVertexAI\"].labels.apply(pd.Series)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "450a154ab035"
},
"source": [
"## Exploring traces with the Python SDK for Cloud Trace\n",
"\n",
"The Cloud Trace Python SDK provides even more flexibility for working with trace data. We'll use it to demonstrate how to filter traces by date, time, labels, and view types."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "d1e6ec298a2e"
},
"source": [
"**Filter by date and time**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "7593b0dd5ab1"
},
"outputs": [],
"source": [
"# Calculate the start and end times\n",
"now = datetime.utcnow()\n",
"yesterday = now - timedelta(hours=24)\n",
"\n",
"# Format the dates as ISO 8601 strings with 'Z' for UTC\n",
"end_time = now.isoformat() + \"Z\"\n",
"start_time = yesterday.isoformat() + \"Z\"\n",
"\n",
"# Request a filtered list of traces by date and time\n",
"result = trace_client.list_traces(\n",
" request=trace.types.ListTracesRequest(\n",
" project_id=PROJECT_ID,\n",
" start_time=start_time,\n",
" end_time=end_time,\n",
" )\n",
")\n",
"\n",
"for count, r in enumerate(result):\n",
" if count >= 5:\n",
" break\n",
" print(r)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "0241dfa7e78e"
},
"source": [
"**Filter by label**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "42f9490f60e5"
},
"outputs": [],
"source": [
"result = trace_client.list_traces(\n",
" request=trace.types.ListTracesRequest(\n",
" project_id=PROJECT_ID,\n",
" # Return traces where any root span's name starts with AgentExecutor\n",
" filter=\"root:AgentExecutor\",\n",
" )\n",
")\n",
"\n",
"for count, r in enumerate(result):\n",
" if count >= 5:\n",
" break\n",
" print(r)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "b13e8cc93b5d"
},
"source": [
"**Filter by view type**"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "154dfc32ae35"
},
"outputs": [],
"source": [
"result = trace_client.list_traces(\n",
" request=trace.types.ListTracesRequest(\n",
" project_id=PROJECT_ID,\n",
" # view=trace.types.ListTracesRequest.ViewType.ROOTSPAN,\n",
" view=trace.types.ListTracesRequest.ViewType.MINIMAL,\n",
" # view=trace.types.ListTracesRequest.ViewType.COMPLETE,\n",
" )\n",
")\n",
"\n",
"for count, r in enumerate(result):\n",
" if count >= 5:\n",
" break\n",
" print(r)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2a4e033321ad"
},
"source": [
"## Cleaning up\n",
"\n",
"After you've finished experimenting, it's a good practice to clean up your cloud resources. You can delete the deployed Agent Engine instance and optionally remove the staging bucket to avoid any unexpected charges on your Google Cloud account."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "6327bf9c6ca9"
},
"outputs": [],
"source": [
"# Delete the deployed agent\n",
"client.agent_engines.delete(name=remote_agent.api_resource.name)\n",
"\n",
"# Optionally, delete the staging bucket\n",
"# from google.cloud import storage\n",
"# storage.Client().bucket(STAGING_BUCKET.replace(\"gs://\", \"\")).delete(force=True)"
]
}
],
"metadata": {
"colab": {
"name": "tracing_agents_in_agent_engine.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
}
},
"nbformat": 4,
"nbformat_minor": 0
}