The OpenAI instrumentation supports completions, chat completions, and image generation. It handles both regular and streamed responses.
Instrumenting OpenAI API calls
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
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();
With Threads and Runs
You can use Threads and Runs on top of the OpenAI API to create structured and organized logs.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()
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);
});
}
Adding Tags and Metadata
You can add tags and metadata to the Generations created by the instrumentation.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"},
)
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
}
);
OpenAI Agents
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())
OpenAI Assistants
You can sync your OpenAI Assistant threads with Literal AI in a few lines of code.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();