OpenLLMetry (Traceloop SDK) Integration with Future AGI Tracing
Send OpenLLMetry traces to Future AGI by pointing the Traceloop SDK at the collector with environment variables. No traceAI package needed.
OpenLLMetry (the Traceloop SDK) already exports OTLP over HTTP, so there is no traceAI package for it. Point TRACELOOP_BASE_URL at the Future AGI collector, pass your keys in TRACELOOP_HEADERS, set a project_name resource attribute, and turn content capture off if you do not want prompts stored.
1. Installation
pip install traceloop-sdk==0.62.4 openai httpx requests
traceloop-sdk 0.62.4 imports httpx and requests without declaring them, so install both.
2. Set environment variables
export FI_API_KEY="your-futureagi-api-key"
export FI_SECRET_KEY="your-futureagi-secret-key"
export OPENAI_API_KEY="your-openai-api-key" # model-provider key, separate from Future AGI keys
# Future AGI Cloud. The SDK appends /v1/traces.
# Self-hosted: use your collector origin, without /v1/traces.
export TRACELOOP_BASE_URL="https://api.futureagi.com/tracer"
# Percent-encode the values: the SDK splits this variable on every comma.
export TRACELOOP_HEADERS="$(python -c 'import os; from urllib.parse import quote; print("x-api-key={0},x-secret-key={1}".format(quote(os.environ["FI_API_KEY"], safe=""), quote(os.environ["FI_SECRET_KEY"], safe="")))')"
# Does not suppress exception/status text or the OpenAI base URL; see Privacy.
export TRACELOOP_TRACE_CONTENT=false # the SDK default is true
export TRACELOOP_METRICS_ENABLED=false # the collector serves no /v1/metrics
unset TRACELOOP_API_KEY # that key is for Traceloop's own host
3. Initialize the SDK
Set the Future AGI project as resource attributes. The collector rejects a batch whose resource has no project_name (HTTP 400) and creates the project on first use.
from traceloop.sdk import Traceloop
Traceloop.init(
app_name="my-app", # exported as service.name
resource_attributes={
"project_name": "openllmetry_project",
"project_type": "observe",
},
telemetry_enabled=False,
)
4. Run your app
In the same Python script, after the initialization above, use the Traceloop decorators and your model client. The OpenAI() client reads OPENAI_API_KEY from step 2; Future AGI keys authenticate trace export only and cannot authorize model calls.
from openai import OpenAI
from traceloop.sdk.decorators import agent, tool, workflow
@tool(name="lookup_policy")
def lookup_policy(question: str) -> str:
return "Refunds are accepted within 30 days of purchase."
@agent(name="support_agent")
def support_agent(question: str) -> str:
facts = lookup_policy(question)
response = OpenAI().chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Answer using only these facts: " + facts},
{"role": "user", "content": question},
],
)
return response.choices[0].message.content or ""
@workflow(name="support_request")
def support_request(question: str) -> str:
return support_agent(question)
print(support_request("What is the refund window?"))
A short script exports on normal exit (the SDK registers an atexit flush). See the complete example.
What is captured
Open Observe in Future AGI and select openllmetry_project to inspect the trace. Each decorated function and model call becomes a span, with parent links matching your code.
| Span | Stored type | Model and tokens |
|---|---|---|
@workflow, @task, @agent, @tool | unknown | none |
| OpenAI chat call | llm | model, prompt tokens, completion tokens |
- The model call is typed
llmfromgen_ai.operation.name=chat. Its model and token counts come from thegen_ai.*keys that 0.62.4 emits. - The collector does not read
traceloop.span.kind, so the decorator spans show asunknown. Everytraceloop.*key is kept as a span attribute, so you can still filter ontraceloop.span.kind. - A failed model call or a decorated function that raises is stored with status
ERRORon the whole path up to the workflow span. - With content on, the text stays in the span attributes (
gen_ai.input.messages,gen_ai.output.messages,traceloop.entity.input,traceloop.entity.output). The Input and Output columns of the trace view stay empty.
Privacy
The Traceloop SDK captures content unless TRACELOOP_TRACE_CONTENT is false. This page sets it to false.
- Content off: prompts, answers, tool arguments and tool results are not exported by this setup.
- Content on (unset or
true): content appears in attributes on decorated spans and model calls. - Not covered by the switch: when a call fails, the SDK sets the exception message as the span status message, so the provider’s error text is stored. The collector stores the
exceptionevent with its name and timestamp only. The OpenAI base URL is stored asgen_ai.openai.api_baseon the model-call span. - With content on, a base64 image in a prompt makes the OpenAI instrumentor upload it to
<TRACELOOP_BASE_URL>/v2/traces/.... The collector has no such route. Keep content off, or keep base64 images out of prompts.
Troubleshooting
- Unexpected collector path: omit
/v1/tracesfromTRACELOOP_BASE_URL; usehttps://api.futureagi.com/tracerfor Future AGI Cloud. - HTTP 400 from the collector: the resource has no
project_name. Add it toresource_attributes. - HTTP 401: check
TRACELOOP_HEADERS. An unencoded comma in a key cuts the value short, and a value with a space, quote, semicolon or backslash is dropped with a warning that prints the whole pair. ModuleNotFoundError: httpx: installhttpxandrequestsnext to the SDK.- A
/v1/metricsrequest fails: setTRACELOOP_METRICS_ENABLED=false. - No spans in a short script: the SDK flushes on exit. Make sure the process exits normally, or call
Traceloop.init(disable_batch=True)while debugging. - The SDK switches to gRPC: a base URL without
http://orhttps://selects gRPC. Use an HTTP or HTTPS collector origin for this setup.
Limitations
- Decorator spans are stored as
unknown;traceloop.span.kindremains available as a filterable attribute. - Input and Output columns are empty even with content on, because the collector fills them only from
input.valueandoutput.value. - gRPC, Traceloop’s hosted dashboard, datasets and prompt registry are not part of this integration.
- This example covers OpenAI Chat Completions; it does not establish support for every OpenLLMetry instrumentor.
How this differs from traceAI instrumentors
traceAI packages (for example traceAI-openai) wrap the client library and set Future AGI span kinds themselves. OpenLLMetry is a separate instrumentation that exports its own attributes. This recipe sends them as they are, with no mapping of its own, so span kinds follow what the collector reads. If you want Future AGI kinds on every span, use the traceAI instrumentor for your library instead.
Questions & Discussion