Overview
Laminar is an open-source, OpenTelemetry-native observability platform for AI agents. Trace, debug, and monitor every Microsoft Agent Framework agent run, model turn, and tool call with a singleLaminar.initialize() call. Self-host via Helm or use managed cloud.
Microsoft Agent Framework (GitHub) is Microsoft’s open-source framework for building agents and multi-agent workflows, the successor to Semantic Kernel and AutoGen. It emits its own OpenTelemetry GenAI semconv spans for agent runs, model calls, and tool executions. Laminar routes those spans to your project, turns on prompt and response capture, and nests everything your tools do under the right span, so you don’t call configure_otel_providers() or enable_instrumentation() yourself.
What Laminar captures:
- Every agent run, named after the agent, with its model turns and tool calls nested inside.
- Every
chat <model>turn with prompts, responses, tool definitions, token counts, latency, and cost. - Every tool call with arguments and return value, and failed tool calls as error spans.
- Sub-agents called as tools, workflow steps, and MCP tool calls nested under the call that spawned them.
Getting started
1
Install
Ensure you have The
lmnr version 0.7.66 or higher and agent-framework 1.x:agent-framework package installs the core framework plus every provider client. If you only install agent-framework-core, add the client package you use, such as agent-framework-openai.2
Set environment variables
3
Initialize Laminar
Laminar.initialize() auto-instruments Microsoft Agent Framework when agent-framework-core is installed. Importing agent_framework before or after initialize() both work.Wrapping your entry point in
@observe() is optional but recommended: it creates a root span that captures inputs and outputs and makes the trace easy to find in the UI. Sessions, user IDs, and metadata you set with Laminar.set_trace_session_id() and friends apply to the framework’s spans too.The framework’s
chat span already records the model call, so Laminar doesn’t trace the OpenAI or Anthropic SDK call underneath it a second time. Provider SDK calls you make directly, outside an agent run, are still traced as usual.See what happened in a trace
Each agent run shows up as a span named after the agent, with its model turns and tool calls inside it. Laminar extracts the inputs, LLM outputs, and tool calls into a transcript view, so you read the conversation instead of a span tree. Switch to tree view to see how sub-agents and tools nest. More on the trace UX: Viewing traces.Multi-agent with agents as tools
A coordinator agent can delegate to specialist agents by passing them as tools withagent.as_tool(). Each delegated run nests under the tool call that started it, so the hierarchy in the trace mirrors the conversation.
Streaming, workflows, and MCP tools
These are traced with no extra setup:- Streaming:
agent.run(..., stream=True)produces the same spans as a non-streaming run, with the full response recorded on thechatspan once the stream finishes. - Workflows: orchestrations such as
SequentialBuilderemit workflow and executor spans, with each participant agent’s run nested inside its step. - MCP tools: tools from
MCPStdioTooland the other MCP clients show up as tool calls, with the MCP session’s requests nested underneath. - Your own code: functions decorated with
@observe, and provider SDK calls made inside a tool, nest under that tool’s span.
Track outcomes with Signals
Traces answer what happened on this run. Signals answer the cross-trace question: how often does the concierge skip a sub-agent, when does a tool get called with a malformed date, how many runs end without a booking. 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 Microsoft Agent Framework 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 directly from Claude Code, Cursor, or Codex.
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 same process that runs the agent. agent-framework-coremust be installed whenLaminar.initialize()runs. The integration requiresagent-framework-core1.x andlmnr >= 0.7.66.- If you set
ENABLE_INSTRUMENTATION=falseor calledagent_framework.observability.disable_instrumentation(), the framework emits no spans of its own. Laminar respects that, and only the underlying provider SDK calls are traced.
Model calls have no prompts or responses
Model calls have no prompts or responses
Laminar turns on the framework’s sensitive-data capture so
chat spans carry messages and tool spans carry arguments and results. It leaves the setting alone if you set ENABLE_SENSITIVE_DATA yourself, so check that it isn’t set to false. Set ENABLE_SENSITIVE_DATA=false or LMNR_TRACE_CONTENT=false when you want to keep content out of traces on purpose.I want to disable the Microsoft Agent Framework integration
I want to disable the Microsoft Agent Framework integration
Pass
disabled_instruments={Instruments.MICROSOFT_AGENT_FRAMEWORK} to Laminar.initialize(). The framework’s spans are then exported as the framework emits them: no message content unless you enable sensitive data yourself, no nesting of your own spans under tool calls, and provider SDK calls traced as separate LLM spans.Self-hosting Laminar
Self-hosting Laminar
Set
base_url and the ports of your instance when initializing. For a local OSS deployment: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, metadata, and tags for deeper control.
Related integrations
OpenAI
Using the OpenAI SDK directly without an agent framework? Trace it here.
Anthropic
Trace the Anthropic SDK directly in TypeScript and Python.
OpenAI Agents SDK
Trace agent runs, handoffs, and tool calls.
Pydantic AI
Trace Pydantic AI agents, typed tools, and sub-agents.
LangChain / LangGraph
Trace LangChain chains and LangGraph graphs.
All integrations
Browse every provider, framework, coding agent, and browser integration Laminar supports.