Skip to main content
Instrumenting an agent takes one call to start tracing, plus a decorator or context manager wherever you want a span. Auto-instrumentation of LLM libraries is covered in Auto-instrumentation.

Initialize tracing with one call

Call tracing.init() once at startup. It configures an OpenTelemetry tracer provider, connects to Surface Area from your environment, and instruments installed AI libraries.
init() finds your Surface Area project from three environment variables. Set them before the process starts. Copy the host and generate a key pair from your project’s Settings page. Project settings and API keys The project Settings page. Copy the Host Name into GATEWAY_HOST, and create your pk-lf-… / sk-lf-… keys under the API keys tab.
With the three required variables set, the SDK builds the export URL automatically by appending /api/public/otel/v1/traces to the host. Override that path only with GATEWAY_OTLP_ENDPOINT or the gateway_endpoint parameter. See Export to Surface Area for details.

Pass credentials directly instead of environment variables

Provide the host and keys as arguments when the environment is not an option. Read them from your own configuration. Never hardcode secrets in source.

Useful init parameters

init() is keyword-only.
Pass debug="INFO" while you set tracing up. It logs the init summary, instrumentor activation, and export success or failure, without the full firehose of True.

Flush spans before the process exits

Spans are batched and exported in the background. Call tracing.shutdown() before the process exits so pending spans are flushed; otherwise a short-lived script can drop its last traces.
Call tracing.flush() to force export at a checkpoint without ending the session.

Trace a function with a decorator

Apply @tracing.trace to a function to capture its input and output as a span. The span name defaults to the function name.
Pass a custom name, or turn off input or output capture, with keyword arguments.
The decorator works on async functions with no change.

Trace a block with a context manager

Use tracing.trace as a context manager to start a root span and set input and output explicitly. The block yields the OpenTelemetry span, so you can attach attributes to it.
Nest tracing.span() calls to record sub-steps as child spans. Each child appears under the active trace in the call tree.
Record a tool or API call with tracing.tool(). It marks the span as a client call and adds a tool.name attribute.
Async code has matching context managers: tracing.atrace() for a root span and tracing.aspan() for a child span. They behave like their synchronous counterparts.

Errors are recorded automatically

The trace, span, and tool context managers record exceptions for you. If the block raises, the exception is recorded on the span and its status is set to error before the exception propagates.
To mark a span as failed without raising, call set_status on the yielded span. It is a standard OpenTelemetry Span.

A complete traced agent

1

Set your Surface Area connection

2

Write the agent

3

Run it and open the dashboard

Run the script, then open your project in Surface Area. The faq-bot trace appears with its nested lookup span.

Where to go next