Noveum docs
Productsnoveum-traceConnect an applicationPython tracing SDK

noveum-trace Python SDK

Reference for initialization, context managers, span payloads, status, and delivery.

The noveum-trace package instruments Python LLM applications, RAG pipelines, tool-calling agents, voice agents, and multi-agent systems.

The core package supports Python 3.9 through 3.13. A framework can impose a narrower Python range; for example, CrewAI integration requires Python 3.10 or later.

Installation

Code
pip install noveum-trace

Framework packages belong to the application and do not need to be reinstalled when tracing is added.

Initialization

Code
import os

import noveum_trace

noveum_trace.init(
    api_key=os.environ["NOVEUM_API_KEY"],
    project=os.environ["NOVEUM_PROJECT"],
    environment=os.getenv("NOVEUM_ENVIRONMENT", "production"),
    service_version=os.environ["NOVEUM_SERVICE_VERSION"],
)
SettingPurpose
api_keyAuthenticates trace delivery for the organization.
projectGroups traces for one application or agent.
environmentSeparates production, staging, development, and other traffic.
service_versionIdentifies the agent behavior that produced a trace and enables release comparisons.

Initialize once before instrumented work starts. NOVEUM_SERVICE_VERSION should change when prompts, models, tools, retrieval, or agent logic change, not for an infrastructure-only redeploy.

LLM context manager

Code
from noveum_trace import trace_llm_call

with trace_llm_call(model="gpt-4o-mini", provider="openai") as span:
    span.set_input_attributes(messages=messages)
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
    )
    output = response.choices[0].message.content or ""
    span.set_output_attributes(response=output)
    span.capture_response(response)
MethodRecords
set_input_attributes(**values)each value as llm.input.<name>, such as llm.input.messages
set_output_attributes(**values)each value as llm.output.<name>, such as llm.output.response
capture_response(response)model, provider, token counts, estimated cost, and finish reason from an OpenAI, Anthropic, or Google response
set_usage_attributes(input_tokens=..., output_tokens=...)token counts and estimated cost when the response object is not available

Capture both input and output on the same decision span. Latency and status alone are not enough for evaluation.

Generic operations

Code
from noveum_trace import trace_operation

with trace_operation("retrieval.search") as span:
    documents = search(query)
    span.set_attributes({
        "function.type": "retrieval",
        "retrieval.query": query,
        "retrieval.documents": documents,
    })

Use child operations for retrieval, tools, routing, and agent stages. Preserve the parent-child relationship so the trace reconstructs the complete request path.

Status and exceptions

Code
from noveum_trace import trace_operation
from noveum_trace.core.span import SpanStatus

with trace_operation("tool.lookup") as span:
    try:
        result = lookup(arguments)
        span.set_attribute("tool.result", result)
        span.set_status(SpanStatus.OK)
    except Exception as exc:
        span.record_exception(exc)
        span.set_status(SpanStatus.ERROR, str(exc))
        raise

Use SpanStatus.OK and SpanStatus.ERROR; string status values are not valid for SDK spans.

Delivery lifecycle

The client batches spans in the background. Call noveum_trace.flush() before a short-lived script, worker, or test process exits:

Code
noveum_trace.flush()

For a long-running service, flush during graceful shutdown after new work has stopped.

Framework integrations

The framework guides show only the adapter required for an application that already uses that framework:

For custom Python applications, continue with the capture contract. For another language, use REST trace ingestion.

PII redaction

Configure PII redaction before capturing production prompts, responses, or transcripts, then verify the redacted payload still contains the evidence your evaluations need.

Source