- Why did the agent choose that tool instead of this one?
- What context was actually passed to the LLM when it generated that response?
- Where is all the latency coming from - is it the model, the retrieval, or something else?
- The user got a wrong answer, but which step in the pipeline failed?
TypeScript Tutorial
Companion TypeScript project with runnable examples
Python Tutorial
Companion Python project with runnable examples
SupportBot
Our sample support agent for this tutorial:- Classifies incoming queries (order status vs. FAQ)
- Routes to the appropriate handler:
- Order Status: Use a tool to look up order information, then summarize for the customer
- FAQ: Search a knowledge base with embeddings, then generate an answer using RAG
Setting Up Tracing
First, install the dependencies and configure OpenTelemetry to send traces to Phoenix.Install Dependencies
- TypeScript
- Python
AI SDK v7 requires Node.js 22 or newer.
@arizeai/phoenix-otel bundles the OpenTelemetry setup and the @arizeai/openinference-vercel span processors that translate AI SDK spans for Phoenix; @ai-sdk/otel emits those spans.Start Phoenix
In order to send traces to Phoenix, you need a Phoenix instance running.- Self-Host
- Local
- Container
Run Phoenix on your own infrastructure, backed by PostgreSQL so traces persist beyond a single process. This is the option to reach for once Phoenix is shared across a team or environment.The self-hosting guide covers Kubernetes, Helm, Railway, AWS CloudFormation, Google Cloud Run, Azure, and Render, plus authentication and configuration.
- TypeScript
- Python
Create a
.env file in your project root:Pointing at a deployment with authentication enabled? Set
PHOENIX_COLLECTOR_ENDPOINT to that deployment’s hostname and PHOENIX_API_KEY to an API key from its Settings page. A local phoenix serve needs neither.Configure Tracing
- TypeScript
- Python
Create an Import this file at the top of your application to enable tracing.
instrumentation.ts file:Tracing LLM Calls
Every LLM call is a decision point. What prompt did the model receive? What did it output? How long did it take, and how many tokens did it use? Without tracing, you’re forced to build your own logging or debugging, and therefore miss out on key data that would block you from full observability. With tracing, you get a complete record of every LLM interaction, including- input messages (system, user, assistant prompt)
- LLM output
- model name, model provider
- invocation parameters
- token counts
- latency
- TypeScript
- Python
Once the Phoenix provider and AI SDK integration are registered at startup, AI SDK calls are traced without per-call configuration:
Tracing Tool Calls
Tools allow your agent to interact with databases, APIs, external systems. In order to gain insight into how your tools are performing, you need to answer questions like- Did the LLM decide to call the right tool?
- Did it extract the parameters correctly?
- Did the tool return what you expected?
- TypeScript
- Python
With the AI SDK, you can simply define your tools using the AI SDK configuration — tool executions are traced automatically:
- LLM Span: Model decides to call
lookupOrderStatus - Tool Span: Shows the tool name, input (
orderId), and output - LLM Span: Model summarizes the result
Tracing RAG Pipelines
RAG pipelines can fail in many places. The embedding might not capture the query’s intent, the retrieval might return irrelevant documents, or the LLM might misuse good context. When a user gets a bad answer, which step failed? With tracing, you can see the full pipeline, including which documents were retrieved, what context was injected into the prompt, and how the LLM used it. You can pinpoint exactly where things went wrong. For RAG, trace both the embedding calls and the generation call. Eachembed call becomes its own span:
- TypeScript
- Python
Grouping Operations with Parent Spans
A single user request might trigger multiple LLM calls, tool executions, and retrievals. Let’s allocate all of these under one parent span, so all operations for one request are nested together. Click on the parent span and see the entire execution tree: classification, tool calls, retrieval, generation, all in one view, with timing relationships visible at a glance.See the entire agent with grouped tracing here.
- TypeScript
- Python
Running the Demo
The final SupportBot agent combines the classifier, the order status tool, and the FAQ retrieval into a single agent. The tutorial code runs 7 test queries against the agent:Complete TypeScript Tutorial
Complete Python Tutorial
s) and focus on the traces.
Viewing Your Traces
Open Phoenix at http://localhost:6006. You’ll see 7support-agent traces - one for each query.
Click into any trace to see the full execution tree. Let’s look at two interesting cases:
Trace 1: “Can you help me with something random?”
Our support query classifier gave the following classification:Trace 2: “What’s the status of order ORD-99999?”
Our support query classifier gave us the following classification:Summary
Congratulations! In this tutorial, you learned how to:- Trace LLM calls - Capture inputs, outputs, tokens, and latency automatically once tracing is registered
- Trace tool calls - See tool decisions, parameters, and responses as child spans
- Trace RAG pipelines - Monitor embeddings and see retrieved context in generation prompts
- Group with parent spans - Nest all operations for a request into one trace
- View and analyze traces - Debug agent behavior by exploring execution trees in Phoenix
Next Steps
You can see inside your application now - every LLM call, tool execution, and retrieval is visible. We spent some time manually analyzing traces. But how can we automate this analysis, over thousands of traces? How can we store this analysis in Phoenix, so that we can build metrics that measure our application? In the next chapter, you’ll learn to:- Annotate traces to mark quality issues
- Capture user feedback (thumbs up/down) and attach it to traces
- Run automated LLM-as-Judge evaluations to find patterns in what’s failing

