LLM/AI Tracking
Track AI model usage, costs, and latency with zero-effort wrappers.
Install @deeptracer/ai alongside your main SDK package:
npm install @deeptracer/aiVercel AI SDK
import { createLogger } from "@deeptracer/node"
import { wrapVercelAI } from "@deeptracer/ai"
import { generateText, streamText } from "ai"
import { openai } from "@ai-sdk/openai"
const logger = createLogger({ /* ... */ })
const ai = wrapVercelAI(logger, { generateText, streamText })
// Use ai.generateText / ai.streamText exactly like the originals
const { text } = await ai.generateText({
model: openai("gpt-4o"),
prompt: "Explain distributed tracing in one sentence.",
})Works with generateText, streamText, generateObject, and streamObject. Streaming is handled automatically -- usage is reported after the stream completes.
OpenAI SDK
import { createLogger } from "@deeptracer/node"
import { wrapOpenAI } from "@deeptracer/ai"
import OpenAI from "openai"
const logger = createLogger({ /* ... */ })
const openai = wrapOpenAI(logger, new OpenAI())
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Hello!" }],
})The wrapper intercepts chat.completions.create() for both streaming and non-streaming calls. For streaming, pass stream: true and the wrapper tracks usage from stream chunks.
const stream = await openai.chat.completions.create({
model: "gpt-4o",
messages: [{ role: "user", content: "Write a haiku." }],
stream: true,
stream_options: { include_usage: true },
})
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "")
}
// Usage is reported automatically after the stream endsAnthropic SDK
import { createLogger } from "@deeptracer/node"
import { wrapAnthropic } from "@deeptracer/ai"
import Anthropic from "@anthropic-ai/sdk"
const logger = createLogger({ /* ... */ })
const anthropic = wrapAnthropic(logger, new Anthropic())
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello!" }],
})Both messages.create() (with and without stream: true) and messages.stream() are wrapped.
Manual tracking
For providers without a built-in wrapper, or for custom LLM integrations:
const start = Date.now()
const result = await myCustomLLM.generate(prompt)
const latencyMs = Date.now() - start
logger.llmUsage({
model: "my-model-v2",
provider: "custom",
operation: "generate",
inputTokens: result.usage.input,
outputTokens: result.usage.output,
latencyMs,
costUsd: 0.002, // optional
})What gets tracked
Every LLM call -- wrapped or manual -- sends this data to DeepTracer:
| Field | Description |
|---|---|
model | Model identifier (e.g., gpt-4o, claude-sonnet-4-20250514) |
provider | Provider name (e.g., openai, anthropic, google) |
operation | What was called (e.g., generateText, chat.completions.create) |
inputTokens | Prompt/input token count |
outputTokens | Completion/output token count |
latencyMs | End-to-end latency in milliseconds |
costUsd | Estimated cost in USD (optional, manual only) |
Provider auto-detection works for OpenAI (gpt-*, o1*, o3*, o4*), Anthropic (claude-*), Google (gemini-*), Mistral (mistral*, mixtral*), and Meta (llama*) models.