Trace OpenAI calls

Trace OpenAI chat completions and embeddings in Future AGI using traceAI-openai for Python or JavaScript.

Trace OpenAI client calls in Future AGI Observe to inspect model requests, responses and usage reported by the API. Tool-call arguments can appear on a model span; instrument your tool’s execution separately if you need its own span.

Install

pip install traceAI-openai openai
npm install @traceai/openai@0.1.13 @traceai/fi-core@0.1.13 @opentelemetry/instrumentation@^0.202.0 openai@^5.0.0

Set environment variables

Set the API keys and a chat model ID available to your OpenAI account. For self-hosted Future AGI, also set FI_BASE_URL to your collector origin.

export OPENAI_API_KEY="your-openai-api-key"
export OPENAI_MODEL="your-chat-model-id"
export FI_API_KEY="your-futureagi-api-key"
export FI_SECRET_KEY="your-futureagi-secret-key"

Tracing captures request and response content by default, including messages, tool arguments and request parameters. Review trace masking settings before sending sensitive data. Input/output switches are not a general error-text filter: exception events and status messages need separate error-detail controls supported by your installed instrumentation version. OpenAI still receives the content you send to its API.

Register the trace provider

Use one provider per application process.

from fi_instrumentation import register
from fi_instrumentation.fi_types import ProjectType

trace_provider = register(
    project_type=ProjectType.OBSERVE,
    project_name="openai_project",
)
import { register, ProjectType } from "@traceai/fi-core";

const tracerProvider = register({
    projectType: ProjectType.OBSERVE,
    projectName: "openai_project",
});

Instrument the client

Initialize instrumentation before creating a client or making a request. For JavaScript ESM, manually instrument the imported OpenAI module as shown; do not rely on CommonJS module-load hooks for a static ESM import.

from traceai_openai import OpenAIInstrumentor

OpenAIInstrumentor().instrument(tracer_provider=trace_provider)
import OpenAI from "openai";
import { OpenAIInstrumentation } from "@traceai/openai";
import { registerInstrumentations } from "@opentelemetry/instrumentation";

const openaiInstrumentation = new OpenAIInstrumentation({});
registerInstrumentations({
    instrumentations: [openaiInstrumentation],
    tracerProvider,
});
openaiInstrumentation.manuallyInstrument(OpenAI);

The JavaScript instrumentor exposes manuallyInstrument for modules not loaded through require.

Run a chat completion

Add this after the setup above. The examples flush and shut down telemetry before the short script exits. In a long-running application, shut down the provider only when the application stops.

import os
from openai import OpenAI

client = OpenAI()

try:
    response = client.chat.completions.create(
        model=os.environ["OPENAI_MODEL"],
        messages=[{"role": "user", "content": "What is the capital of South Africa?"}],
    )
    print(response.choices[0].message.content)
finally:
    trace_provider.force_flush()
    trace_provider.shutdown()
// OpenAI was imported in the instrumentation step.
const client = new OpenAI();

try {
    const response = await client.chat.completions.create({
        model: process.env.OPENAI_MODEL!,
        messages: [{ role: "user", content: "What is the capital of South Africa?" }],
    });
    console.log(response.choices[0].message.content);
} finally {
    await tracerProvider.shutdown();
}

Open Observe, select openai_project, and open the model span to inspect the request and response.

Stream a Python chat completion

Use this request instead of the non-streaming example, after the same provider and instrumentation setup. Consume the stream before flushing telemetry. Usage-only chunks can have no choices, and content deltas can be empty.

import os
from openai import OpenAI

client = OpenAI()

try:
    completion = client.chat.completions.create(
        model=os.environ["OPENAI_MODEL"],
        stream=True,
        stream_options={"include_usage": True},
        messages=[{"role": "user", "content": "Explain OpenTelemetry in one sentence."}],
    )
    for chunk in completion:
        if chunk.choices and chunk.choices[0].delta.content:
            print(chunk.choices[0].delta.content, end="")
finally:
    trace_provider.force_flush()
    trace_provider.shutdown()

For endpoint and model-specific request options, see the OpenAI API reference.

Was this page helpful?

Questions & Discussion