> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inference.net/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI Traces

> Trace OpenAI Chat Completions, tool calls, structured outputs, and Responses API calls.

Catalyst instruments the OpenAI SDK in both TypeScript and Python. Initialize
tracing before constructing clients so the OpenAI prototypes are patched before
application calls start.

## What Is Captured

* Chat Completions request and response messages
* Responses API input and output text
* Tool call names, IDs, and JSON arguments
* Tool result messages passed back into later turns
* JSON schema response format in invocation parameters
* Model name, finish reason, usage, and token counts

## Install

<CodeGroup>
  <Metadata text="integrations/traces/openai-install-typescript" />

  ```bash TypeScript theme={"system"}
  bun add @inference/tracing openai
  ```

  <Metadata text="integrations/traces/openai-install-python" />

  ```bash Python theme={"system"}
  pip install 'inference-catalyst-tracing[openai]'
  ```
</CodeGroup>

## Basic Chat

<CodeGroup>
  <Metadata text="integrations/traces/openai-basic-chat" />

  ```typescript TypeScript theme={"system"}
  import { setup } from "@inference/tracing";
  import OpenAI from "openai";

  const tracing = await setup({
    serviceName: "checkout-agent",
    modules: { openai: OpenAI },
  });

  const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

  const response = await client.chat.completions.create({
    model: "gpt-4o-mini",
    messages: [
      { role: "system", content: "You answer in one short sentence." },
      { role: "user", content: "Summarize order ABC-123." },
    ],
    max_tokens: 80,
  });

  console.log(response.choices[0]?.message.content);
  await tracing.shutdown();
  ```

  <Metadata text="integrations/traces/openai-basic-chat" />

  ```python Python theme={"system"}
  import os

  from inference_catalyst_tracing import setup
  from openai import OpenAI

  tracing = setup(service_name="checkout-agent")
  client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

  response = client.chat.completions.create(
      model="gpt-4o-mini",
      messages=[
          {"role": "system", "content": "You answer in one short sentence."},
          {"role": "user", "content": "Summarize order ABC-123."},
      ],
      max_tokens=80,
  )

  print(response.choices[0].message.content)
  tracing.shutdown()
  ```
</CodeGroup>

## OpenAI Inside An Agent

<CodeGroup>
  <Metadata text="integrations/traces/openai-agent-identity" />

  ```typescript TypeScript theme={"system"}
  import { agentSpan } from "@inference/tracing";

  await agentSpan(
    {
      agentId: "checkout-agent",
      agentName: "Checkout Agent",
      spanName: "checkout-agent.run",
      sessionId: "conversation-checkout-1",
      role: "checkout",
      system: "openai",
    },
    async (span) => {
      const input = "Summarize order ABC-123.";
      span.setInput(input);
      const response = await client.responses.create({
        model: "gpt-4o-mini",
        input,
      });
      span.setOutput(response.output_text);
    },
  );
  ```

  <Metadata text="integrations/traces/openai-agent-identity" />

  ```python Python theme={"system"}
  from inference_catalyst_tracing import agent_span

  with agent_span(
      tracing.tracer,
      agent_id="checkout-agent",
      agent_name="Checkout Agent",
      span_name="checkout-agent.run",
      session_id="conversation-checkout-1",
      agent_role="checkout",
      system="openai",
  ) as span:
      user_input = "Summarize order ABC-123."
      span.set_input(user_input)
      response = client.responses.create(model="gpt-4o-mini", input=user_input)
      span.set_output(response.output_text)
  ```
</CodeGroup>

## Tool Calling

The first model call records the assistant tool call. The second model call
records the tool result message and the final answer.

<Tip>
  The capture below is the **model-side** view of tool calling — the
  request/response the LLM saw. To also capture the **caller-side** view (the
  actual function that ran, its input, output, and duration), wrap the tool
  function in a `TOOL` span using
  [Manual spans](/integrations/traces/manual-spans#tool-chain-and-retriever-spans).
  For a full agent loop, see the
  [Production Agent Example](/integrations/traces/production-agent-example).
</Tip>

<CodeGroup>
  <Metadata text="integrations/traces/openai-tool-calling" />

  ```typescript TypeScript theme={"system"}
  import { setup } from "@inference/tracing";
  import OpenAI from "openai";

  const tracing = await setup({ modules: { openai: OpenAI } });
  const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

  const tools = [
    {
      type: "function" as const,
      function: {
        name: "get_weather",
        description: "Look up the current weather in a city.",
        parameters: {
          type: "object",
          properties: { city: { type: "string" } },
          required: ["city"],
        },
      },
    },
  ];

  const messages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [
    { role: "user", content: "What's the weather in San Francisco?" },
  ];

  const first = await client.chat.completions.create({
    model: "gpt-4o-mini",
    messages,
    tools,
  });

  const toolCalls = first.choices[0]?.message.tool_calls ?? [];
  messages.push({ role: "assistant", content: null, tool_calls: toolCalls });

  for (const toolCall of toolCalls) {
    const args = JSON.parse(toolCall.function.arguments) as { city: string };
    messages.push({
      role: "tool",
      tool_call_id: toolCall.id,
      content: JSON.stringify({ city: args.city, tempF: 62 }),
    });
  }

  const final = await client.chat.completions.create({
    model: "gpt-4o-mini",
    messages,
    tools,
  });

  console.log(final.choices[0]?.message.content);
  await tracing.shutdown();
  ```

  <Metadata text="integrations/traces/openai-tool-calling" />

  ```python Python theme={"system"}
  import json
  import os

  from inference_catalyst_tracing import setup
  from openai import OpenAI
  from openai.types.chat import ChatCompletionMessageParam

  tracing = setup()
  client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

  tools = [
      {
          "type": "function",
          "function": {
              "name": "get_weather",
              "description": "Look up the current weather in a city.",
              "parameters": {
                  "type": "object",
                  "properties": {"city": {"type": "string"}},
                  "required": ["city"],
              },
          },
      },
  ]

  messages: list[ChatCompletionMessageParam] = [
      {"role": "user", "content": "What's the weather in San Francisco?"},
  ]

  first = client.chat.completions.create(
      model="gpt-4o-mini",
      messages=messages,
      tools=tools,
  )

  tool_calls = first.choices[0].message.tool_calls or []
  messages.append(
      {
          "role": "assistant",
          "content": None,
          "tool_calls": [tool_call.model_dump() for tool_call in tool_calls],
      },
  )

  for tool_call in tool_calls:
      args = json.loads(tool_call.function.arguments)
      messages.append(
          {
              "role": "tool",
              "tool_call_id": tool_call.id,
              "content": json.dumps({"city": args["city"], "temp_f": 62}),
          },
      )

  final = client.chat.completions.create(
      model="gpt-4o-mini",
      messages=messages,
      tools=tools,
  )

  print(final.choices[0].message.content)
  tracing.shutdown()
  ```
</CodeGroup>

## Structured Outputs

`response_format` is included in invocation parameters, so you can inspect which
schema constrained the model call.

<Metadata text="integrations/traces/openai-structured-output" />

```typescript TypeScript theme={"system"}
const response = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [
    {
      role: "user",
      content: "Extract the city, temperature, and unit from: 72F in Berlin.",
    },
  ],
  response_format: {
    type: "json_schema",
    json_schema: {
      name: "weather_report",
      strict: true,
      schema: {
        type: "object",
        additionalProperties: false,
        properties: {
          city: { type: "string" },
          temperature: { type: "number" },
          unit: { type: "string", enum: ["F", "C"] },
        },
        required: ["city", "temperature", "unit"],
      },
    },
  },
});

console.log(response.choices[0]?.message.content);
```

## Responses API

Responses API calls are traced with the same OpenInference attribute families as
Chat Completions.

<Metadata text="integrations/traces/openai-responses-api" />

```typescript TypeScript theme={"system"}
const response = await client.responses.create({
  model: "gpt-4o-mini",
  input: "In one sentence, what is OpenTelemetry?",
});

console.log(response.output_text);
```
