setup() runs (pass both modules in TypeScript;
Python auto-detects installed SDKs), the agent run, its tool calls, handoffs,
and nested model calls are all captured automatically. Wrap the run in
agentSpan() / agent_span() when you want stable identity and session
grouping.
Three layers, in increasing order of effort:
setup()traces the whole run automatically (pass the SDK modules in TypeScript; Python auto-detects). Enough on its own.agentSpan()/agent_span()adds a stableagentId,agentName,role, andsessionIdso the Agents dashboard groups runs by conversation, plus your high-level input and output.manualSpan()/manual_span()captures steps the SDK never sees: your own retrieval, routing, or sub-steps inside a tool.
Install
Configure Export
Set the Catalyst endpoint and token before your app starts.setup() reads
these in every example below. Generate a token at
API Keys.
Minimal Setup
Pass the SDK modules tosetup() in TypeScript, or let it auto-detect in
Python, then run your agent. The run, any tool calls, and the nested model calls
are all captured with no further code. This is everything you need for a single
one-shot agent.
Group Under An Agent
Wrap the run inagentSpan() to give it stable identity and session grouping.
This is the recommended shape for anything beyond a one-shot script. Pass
userId to record user.id so you can filter traces by user on the dashboard,
just like sessionId. For arbitrary keys, attach any custom attributes you want
to filter traces by inside the callback (organization.id, chat.id,
order.id). See
Adding Custom Attributes.
Multi-Agent Handoff
Wrap the triage request once. The trace tree groups the triage agent, specialist agent, nested model calls, and tools under the customer request.agent.id, such as refunds-agent or billing-agent.
When To Add Manual Spans
The Agents SDK only captures the work it runs for you: the model calls, and the tools you register withtool(). Anything you do yourself inside the
agentSpan callback is invisible to it. You do not wrap the SDK’s own tool
calls in manualSpan(), those are already captured, and doing so would just
produce a duplicate span. You reach for manualSpan() for the steps the SDK
never sees.
Two common cases:
- A step around the run. You fetch context from a vector store before the
run, or validate and reshape the output after it. Neither is an SDK call, so
author a
RETRIEVERorCHAINspan yourself. - Sub-steps inside a tool. The SDK emits one TOOL span per tool
invocation. If that tool’s
executedoes something you want broken out (a vector search, a downstream API call, a transform), wrap it in a child span. It nests under the SDK’s TOOL span automatically.
manualSpan. See
Manual Spans for the full set of span
kinds and the handle API.
Flushing
Every example above ends withawait tracing.shutdown(), which flushes batched
spans before the process exits. Long-lived servers and serverless or edge
runtimes need a different flush strategy, since the process does not exit after
each run. See
Flushing and process lifecycle
for all three shapes.
Next Steps
Manual spans
Author TOOL, CHAIN, and RETRIEVER spans for work the SDK does not capture.
Agent identity
Pick stable
agent.id and session.id values for the Agents dashboard.Production agent example
A production-shaped agent with custom tool spans, end to end.
Attributes reference
Every
Attr.* constant and SpanKindValues value the SDK emits.