Documentation Index
Fetch the complete documentation index at: https://laminar.sh/docs/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Vercel AI SDK exposes OpenTelemetry hooks viaexperimental_telemetry. Laminar is OpenTelemetry-native, so you get full traces of generateText, streamText, generateObject, streamObject, tool calls, and provider-level request and response payloads with a single tracer wired in.
What Laminar captures:
- Prompts, messages, and system instructions sent to the model.
- Model output, reasoning, and structured object results.
- Tool calls, arguments, and tool results.
- Token counts, latency, and cost per call.
- Provider identity (OpenAI, Anthropic, Google, Mistral, and others) and model name.
Node.js setup
Install
@ai-sdk/openai for any provider adapter you use (full list).Set environment variables
Laminar initialization. If not specified,
Laminar will look for the key in the LMNR_PROJECT_API_KEY environment variable.Initialize Laminar
Call
Laminar.initialize() once at the entry point of your application, before any AI SDK call runs.Next.js setup
Update next.config.ts
Tell Next.js to treat Laminar as an external server package. Laminar depends on OpenTelemetry, which uses Node-specific APIs Next.js cannot bundle.More on this option in the Next.js docs.
next.config.ts
Initialize Laminar in instrumentation.ts
Create
instrumentation.ts at the project root. Next.js auto-loads this file before any route or server component runs.instrumentation.ts
Laminar only runs in the
nodejs runtime. The guard skips Edge runtime routes automatically.If you already use
@vercel/otel or @sentry/nextjs, initialize them first, then Laminar. See Coexisting with @vercel/otel below.Tracing a multi-step agent
The AI SDK runs the tool-calling loop for you: the model calls a tool, the SDK runs the tool’sexecute, feeds the result back, and repeats until the model stops calling tools or a stop condition trips. Laminar records every step as a span under one trace, so the transcript shows each tool call and its result in order.
Two shapes are common. generateText with tools and stopWhen is the workhorse. ToolLoopAgent is a thin wrapper if you want to reuse the same tools and instructions across many calls.
generateText with tools
stopWhen: stepCountIs(5) caps the loop at five model-and-tool rounds. You can combine conditions (stopWhen: [stepCountIs(20), hasToolCall('finalize')]) or pass a custom predicate.
ToolLoopAgent
Reuse the same configuration across calls by constructing aToolLoopAgent once:
See what happened in a trace
Open the trace in Laminar and you get the transcript view: system prompt, user messages, model output, tool calls, and tool results laid out as a conversation. Sub-agents collapse to their input and final output so you read what mattered, not a tree of span names.
Track outcomes with Signals
Traces answer what happened on this run. Signals answer the cross-trace question: how often does the agent recommend a product that wasn’t in stock, when does a tool call return an empty result, which generateText calls fan out into more steps than expected. A Signal pairs a plain-language prompt with a JSON output schema. Laminar runs it live on new traces (Triggers) or backfills it across history (Jobs) and records a structured event every time it matches. From there you query, cluster, and alert on events across every trace.Every new project ships with a Failure Detector Signal that categorizes issues on any trace over 1000 tokens. Open it from the Signals sidebar to see events as soon as your AI SDK traces arrive.
Query across traces
- SQL editor for ad-hoc queries across traces, spans, signals, and evals.
- SQL API for programmatic access from scripts and pipelines.
- CLI (
lmnr-cli sql query) for terminal-driven queries and piping JSON into shell tools or coding agents. - MCP server to query Laminar from Claude Code, Cursor, or Codex.
Grouping calls inside one route
If a single route makes multiple LLM calls, wrap them inobserve to group them under one parent span.
app/api/chat/route.ts
@vercel/otel or @sentry/nextjs) is already wrapping your handler.
See the full observe reference for session IDs, user IDs, metadata, and tags.
Coexisting with @vercel/otel
If you already register a tracer provider with@vercel/otel, do not call Laminar.initialize() (that would register a second provider). Plug Laminar’s span processor into the existing one instead:
instrumentation.ts
Troubleshooting
I don't see any traces in Laminar
I don't see any traces in Laminar
- Confirm
LMNR_PROJECT_API_KEYis set in the runtime environment, not just your shell. Laminar.initialize()must run before the first AI SDK call. In Next.js, that means it lives ininstrumentation.ts.experimental_telemetryis opt-in per call. If you forget to pass{ isEnabled: true, tracer: getTracer() }, the call is not traced.- Edge runtime is not supported. Make sure your route runs in
nodejs.
Build fails with OpenTelemetry / require errors
Build fails with OpenTelemetry / require errors
Add
@lmnr-ai/lmnr to serverExternalPackages in next.config.ts. OpenTelemetry uses Node-specific APIs that Next.js cannot bundle.Using Next.js < 15
Using Next.js < 15
instrumentation.ts is experimental before Next.js 15. Enable it in next.config.js:next.config.js
Mixing the AI SDK with a direct OpenAI or Anthropic client
Mixing the AI SDK with a direct OpenAI or Anthropic client
Direct SDK calls are auto-instrumented by
Laminar.initialize() in Node.js. In Next.js, imports inside instrumentation.ts are not visible to the rest of the app, so auto-instrumentation may miss them. Call Laminar.patch({ OpenAI, anthropic }) where you construct the client:lib/llm-clients.ts
What’s next
Viewing traces
Read the transcript view, filter, and search across traces.
Signals
Detect behaviors and failures across every run, then query, cluster, and alert on them.
SQL editor and MCP server
Query traces programmatically from the UI, API, or your IDE.
Tracing structure
Sessions, user IDs, metadata, and tags.
OpenAI
Mixing AI SDK with the OpenAI SDK directly? Trace it here.
Anthropic
Mixing AI SDK with the Anthropic SDK directly? Trace it here.
