Tracing Fundamentals
A trace records one end-to-end run of your application. Inside it, observations record each step: spans for work, generations for LLM calls and events for points in time. This page shows how to create them with the SDKs. Install and configure an SDK first (see Installation).
Both SDKs are built on OpenTelemetry. Every observation is an OpenTelemetry span, so spans from other OpenTelemetry libraries in your process nest into the same trace.
Creating a trace
The first observation you start becomes the root of a new trace. Observations started inside it become its children.
The Python SDK requires agent_name on the root observation of every
trace. Without it, the SDK raises ValueError: agent_name is required.
Child observations inherit the agent from their parent.
Decorators and wrappers
Trace whole functions without context managers:
@observe captures the function's arguments and return value. Turn this
off with capture_input=False and capture_output=False, or globally with
ANTS_PLATFORM_OBSERVE_DECORATOR_IO_CAPTURE_ENABLED=false. A decorated
function must run inside an observation that has an agent_name.
Observation types
The SDKs accept span, generation, event, agent, tool, chain,
retriever, evaluator, guardrail and embedding. ANTS Platform stores
three types: span, generation and event. generation and
embedding are stored as generations, event as an event, and the rest as
spans. Give observations clear names so you can tell steps apart.
Sessions and users
Set trace-level attributes from anywhere inside the trace:
- Session ID groups traces into a session, for example every turn of one conversation.
- User ID attributes the trace to an end user on the Users page.
- Tags are short labels for filtering. Metadata is a JSON object for any other context.
- Environment is set on the client (
environment=in Python) or withANTS_PLATFORM_TRACING_ENVIRONMENT. Use lowercase names. - Release is set with
release=orANTS_PLATFORM_RELEASE.
With OpenTelemetry, use the user.id and session.id span attributes. See
OpenTelemetry.
Tokens and cost
Record token counts on generations with usage_details (Python) or
usageDetails (JS/TS), using keys such as input and output. If you do not
send a cost, ANTS Platform calculates it from the model name and your
model definitions. To send your own cost, use
cost_details / costDetails.
The OpenAI and LangChain integrations record model, tokens and timing for you:
See Python SDK, JS/TS SDK and LangChain & LangGraph.
Errors
Mark failed steps with a level and a status message:
Levels are DEBUG, DEFAULT, WARNING and ERROR. The trace table shows
counts per level, and you can filter on them. In JS/TS, pass
{ level: "ERROR", statusMessage } to update().
Distributed tracing
To continue a trace in another service, pass the trace ID and parent observation ID along with the request.
- Python:
ants.get_current_trace_id()andants.get_current_observation_id()in the caller;start_as_current_span(..., trace_context={"trace_id": ..., "parent_span_id": ...})in the callee. - JS/TS:
getActiveTraceId()andgetActiveSpanId()in the caller;parentSpanContextin the options ofstartObservationin the callee. - OpenTelemetry: standard W3C
traceparentpropagation works, because the SDKs use OpenTelemetry context.
Use create_trace_id(seed=...) (Python) or createTraceId(seed) (JS/TS) to
derive a trace ID from your own request ID.
Sampling
Sampling is set in the SDK and applies per trace, so a sampled trace is always complete.
Unsampled traces are never sent and use no credits.
Flushing
The SDKs send data in the background in batches. In short-lived processes (scripts, serverless functions, CLI tools), flush before exit:
- Python:
ants.flush(), orants.shutdown()at the end of the process. - JS/TS:
await provider.forceFlush()orawait provider.shutdown().
Masking sensitive data
Both SDKs accept a mask function that runs on input, output and metadata
before data leaves your process. See
Data Privacy.
Best practices
- Name steps by what they do (
retrieve-docs,classify-intent), not by implementation details. - Use a stable agent name per application. It identifies the agent across releases. Change the display name, not the agent name.
- Always set session and user IDs in chat applications.
- Record tokens on every generation so cost is accurate.
- Use lowercase environment names, such as
productionandstaging. - Flush in short-lived processes.
Next steps
- Traces & Observations: explore traces in the UI.
- Observability Model: how the data fits together.
- OpenTelemetry (OTLP): send spans from any OTel exporter.