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

# OpenAI

You can use the Literal AI platform to instrument OpenAI API calls. This allows you to track and monitor the usage of the OpenAI API in your application and replay them in the Prompt Playground.

<Check>
  The OpenAI instrumentation supports **completions**, **chat completions**, and **image generation**. It handles both regular and streamed responses.
</Check>

## Instrumenting OpenAI API calls

<CodeGroup>
  ```python Python theme={null}
  import os
  from literalai import LiteralClient

  """
  You need to call the `instrument_openai` method from the Literal AI client to
  enable the integration. Call it before any OpenAI API call.
  """
  literalai_client = LiteralClient(api_key=os.getenv("LITERAL_API_KEY"))
  literalai_client.instrument_openai()

  # Now you can use the OpenAI API as you normally would
  ```

  ```typescript TypeScript theme={null}
  import { LiteralClient } from '@literalai/client';
  import OpenAI from 'openai';

  const literalAiClient = new LiteralClient();

  const openai = new OpenAI();

  // Instrument the OpenAI client
  literalAiClient.instrumentation.openai();

  async function main() {
    // This will be automagically logged by Literal AI
    const stream = await openai.chat.completions.create({
      model: 'gpt-4',
      stream: true,
      messages: [{ role: 'user', content: 'Say this is a test' }]
    });
  };
  main();
  ```
</CodeGroup>

### With Threads and Runs

You can use [Threads and Runs](/guides/logs) on top of the OpenAI API to create structured and organized logs.

<CodeGroup>
  ```python Python theme={null}
  import os
  from literalai import LiteralClient
  from openai import OpenAI

  openai_client = OpenAI()

  literalai_client = LiteralClient(api_key=os.getenv("LITERAL_API_KEY"))
  literalai_client.instrument_openai()

  @literalai_client.step(type="run")
  def my_assistant(user_query: str):
      completion = openai_client.chat.completions.create(
                  model="gpt-4o-mini",
                  messages=[
                      {
                          "role": "user",
                          "content": user_query,
                      }
                  ],
              )
      return completion.choices[0].message.content


  def main():
      with literalai_client.thread(name="Example") as thread:
          initial_user_query = "Hello, how are you?"
          my_assistant(initial_user_query)
          
          follow_up_query = "Follow up query"
          my_assistant(follow_up_query)

  main()
  # Network requests by the SDK are performed asynchronously.
  # Invoke flush to guarantee the completion of all requests prior to the process termination.
  # WARNING: If you run a continuous server, you should not use this method.
  literalai_client.flush()
  ```

  ```typescript TypeScript theme={null}
  import { LiteralClient, Thread } from '@literalai/client';
  import OpenAI from 'openai';

  const literalAiClient = new LiteralClient();

  const openai = new OpenAI();

  literalAiClient.instrumentation.openai();

  async function myAssistant(initialUserQuery: string) {
    return literalAiClient
      .run({
        name: 'My Assistant'
      })
      .wrap(async () => {
        // Because this call is wrapped, it will be logged in the right step
        const completion = await openai.chat.completions.create({
          model: 'gpt-4',
          messages: [{ role: 'user', content: initialUserQuery }]
        });

        return completion.choices[0].message;
      })
  }

  async function main() {
    await literalAiClient.thread({ name: 'Example' }).wrap(async () => {
      const initialUserQuery = 'Hello, how are you?';

      await myAssistant(initialUserQuery);

      const followUpQuery = 'Follow up query';

      await myAssistant(followUpQuery);
    });
  }
  ```
</CodeGroup>

### Adding Tags and Metadata

You can add tags and metadata to the Generations created by the instrumentation.

<CodeGroup>
  ```python Python theme={null}
  completion = openai_client.chat.completions.create(
      model="gpt-4o-mini",
      messages=[
          # ...
      ],
      # Only tags are supported right now on the Python client
      literalai_tags=["tag1", "tag2"],
      literalai_metadata={"key": "value"},
  )
  ```

  ```typescript TypeScript theme={null}
  import { v4 as uuidv4 } from 'uuid';

  const client = new LiteralClient({ apiKey, apiUrl });
  const openai_ = new OpenAI();

  const openai = client.instrumentation.openai({
    client: openai_
  });

  const literalaiStepId = uuidv4();

  await openai.chat.completions.create(
    {
      model: 'gpt-4o-mini',
      messages: [
        { role: 'system', content: 'You are a helpful assistant.' },
        { role: 'user', content: 'What is the capital of Canada?' }
      ]
    },
    {
      literalaiTags: ['tag3', 'tag4'],
      literalaiMetadata: { otherKey: 'otherValue' },
      // You can also specify a Step ID at the call level
      // When this generation is logged, it will be created with the given Step ID
      literalaiStepId
    }
  );

  ```
</CodeGroup>

## OpenAI Agents

<CodeGroup>
  ```python Python theme={null}
  import asyncio

  from agents import Agent, Runner, set_trace_processors, trace
  from dotenv import load_dotenv

  from literalai import LiteralClient

  load_dotenv()

  client = LiteralClient()


  async def main():
      agent = Agent(name="Joke generator", instructions="Tell funny jokes.")

      with trace("Joke workflow"):
          first_result = await Runner.run(agent, "Tell me a joke")
          second_result = await Runner.run(
              agent, f"Rate this joke: {first_result.final_output}"
          )
          print(f"Joke: {first_result.final_output}")
          print(f"Rating: {second_result.final_output}")


  if __name__ == "__main__":
      set_trace_processors([client.openai_agents_tracing_processor()])
      asyncio.run(main())

  ```
</CodeGroup>

## OpenAI Assistants

You can sync your OpenAI Assistant threads with Literal AI in a few lines of code.

<CodeGroup>
  ```ts TypeScript theme={null}
  import OpenAI from 'openai';

  import { LiteralClient, User } from '@literalai/client';

  const openai = new OpenAI();

  const literalAiClient = new LiteralClient({apiKey: process.env["LITERAL_API_KEY"]});
  const syncer = literalAiClient.openai(openai).assistant.syncer;

  async function main() {
    // You can sync a thread at any moment. We recommend to sync it once you get a `completed` run status.
    const threadId = 'THREAD_ID_TO_SYNC';

    // Optional: Add/update a user to the thread. Use any unique identifier you like.
    const user = new User({ identifier: 'willy', metadata: { name: 'Willy' } });
    await syncer.syncThread(threadId, user);
  }

  main();
  ```
</CodeGroup>
