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
pip install noveum-traceFramework packages belong to the application and do not need to be reinstalled when tracing is added.
Initialization
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"],
)| Setting | Purpose |
|---|---|
api_key | Authenticates trace delivery for the organization. |
project | Groups traces for one application or agent. |
environment | Separates production, staging, development, and other traffic. |
service_version | Identifies 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
from noveum_trace import trace_llm_call
with trace_llm_call(model="gpt-4o-mini", provider="openai") as span:
span.set_attributes({
"function.type": "llm_call",
"llm.system_prompt": system_prompt,
"llm.input.messages": messages,
"llm.prompt": user_input,
})
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=messages,
)
output = response.choices[0].message.content or ""
span.set_attributes({
"llm.output.response": output,
"llm.completion": output,
"llm.usage.input_tokens": response.usage.prompt_tokens,
"llm.usage.output_tokens": response.usage.completion_tokens,
"llm.usage.total_tokens": response.usage.total_tokens,
})Capture both input and output on the same decision span. Latency and status alone are not enough for evaluation.
Generic operations
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
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))
raiseUse 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:
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.
