Skip to main content
LangChain is an open-source framework for building LLM applications and agents, available in Python and TypeScript, with LangGraph as its low-level orchestration framework and runtime for agents. Learn how to instrument LangChain agents to capture every agent run, model call, and tool call so you can observe, evaluate, and improve quality. This guide attaches the OpenInference instrumentor for LangChain to a LangChain/LangGraph agent to send traces to Arize AX. Every agent run, model call, and tool call is captured as a structured trace without changing your agent logic. The same instrumentor covers the underlying LangChain primitives, so LangGraph agents, LCEL chains, and legacy AgentExecutor agents are all traced by one setup.

Overview

In this guide you will instrument a LangChain agent, run it, and read the resulting traces in Arize AX. The following steps apply to any app built on LangChain, whether it runs behind a web framework such as FastAPI or Express, in a background worker, or as a script. This guide assumes familiarity with:
  • Python or TypeScript, including async/await
  • Building an agent with LangChain’s create_agent and tools
  • Environment variables and package installation
By the end, you will be able to:
  • Capture agent runs, model calls, and tool calls as traces
  • Group traces by conversation using session IDs
  • Verify and read the trace tree in Arize AX

Before you start

You need:

Get your Arize AX credentials

Sign in to your Arize AX account and create a tracing project from Projects → New Tracing Project. The setup page shows the credentials you need: copy your Space ID, then click Create API Key to generate a key and save it somewhere safe. You set them as ARIZE_SPACE_ID and ARIZE_API_KEY when you configure your environment, and they route your traces to the correct space.
New Tracing Project setup page in Arize AX showing the Space ID and the Create API Key button
The steps below instrument a small example agent, a health coach with a single tool, so the trace shows the agent run, its model call, and its tool call end to end. Attach the instrumentor once at startup, and every agent run, model call, and tool call is then captured, with no manual spans and no change to your agent code.
Prerequisites: Python 3.10 or later.
1

Install the instrumentor

Install the OpenInference instrumentor for LangChain alongside the framework and tracing dependencies. This example uses Anthropic as the model provider; swap langchain-anthropic for the provider package your agent uses.
2

Configure credentials

Set your Arize AX and model-provider credentials as environment variables. The tracing setup reads them at startup, so you keep secrets out of your source.
ARIZE_PROJECT_NAME is the project your traces land in. Name it for the app so runs stay grouped where you expect them.
3

Initialize tracing before LangChain runs

Set up tracing in a dedicated module so it runs once, before your agent code imports LangChain. register() builds a tracer provider from your Arize credentials, and LangChainInstrumentor().instrument(...) connects that tracer to LangChain so every run emits spans.
tracing.py
Import this module before any langchain or langchain_anthropic import in your entry point, so LangChain is instrumented before your agent runs. Importing the tracing module first is the simplest way to guarantee that ordering.
main.py
If your app serves the agent from a web framework such as FastAPI or Flask, the LangChain instrumentor is still what captures the agent. Web-framework instrumentation only records HTTP requests, not the agent, model, and tool activity that make up an agent trace.
4

Run your agent

Run your app; either behind a web server, in a worker, or through the LangGraph dev server. Because you set up the instrumentation in the previous steps, the run is traced automatically. The example below is a small agent built with create_agent and one tool. Running this agent captures a full trace of the agent run, each model call, and the tool call.
Each tool the agent invokes appears as a child span under the run, with its inputs and outputs. The model is interchangeable: swap the anthropic:claude-sonnet-4-6 identifier for another provider string such as openai:gpt-5.5 or google_genai:gemini-3.5-flash, and the same instrumentor covers it.
5

Avoid losing traces when a script exits

A long-running service, such as a web server or worker, keeps exporting spans as it runs, so you can skip this step. It applies only to a process that exits right after a run, such as a script, a batch job, or a serverless function.Spans are sent to Arize AX in the background, in batches, and a short-lived process can quit before the last batch goes out. Force that final send, a step called flushing, before the process ends so no traces are lost. tracing.py exposes the provider it built, so import it and flush.
6

Group traces by conversation

Auto-instrumentation captures each run on its own. To follow a multi-turn conversation as a single thread, add a session ID to handle_turn and wrap the agent call in the using_session() context manager. Reuse the same ID across a conversation’s turns, such as the user or thread ID.
Every span emitted inside the block carries the same session.id, so both turns share one session and Arize AX groups them into a single conversation you can replay.
7

Verify in Arize AX

Open your Arize AX space and select the project you set in ARIZE_PROJECT_NAME. Within about 30 seconds of a run, a new trace appears with a LangGraph root span wrapping ChatAnthropic LLM spans and one TOOL span per tool the agent invoked. When you set a session ID, each span carries session.id. See What gets captured for the full breakdown.If no traces appear, see Troubleshooting.

What gets captured

The LangChain instrumentor records the full shape of each agent run:
  • Agent run. A LangGraph root span for the whole create_agent invocation, wrapping every step the graph takes. create_agent runs on LangGraph, so the root span carries the LangGraph name.
  • LLM spans. One span per model call, with the input messages, the response, the model name, and token counts. This is where each reasoning turn and each tool-calling decision is recorded.
  • Tool spans. One TOOL span per tool invocation, with the tool name, inputs, and outputs, so you can see what the agent decided to do and what each tool returned.
  • Chain spans. The graph nodes and runnable structure that connect the model and tool steps, so the trace tree mirrors your agent’s control flow.
  • Session grouping. The session.id you set, which threads related runs into one conversation.

Trace tool usage

Tool calls are traced automatically. Because create_agent runs the model-and-tools loop itself and every step flows through LangChain’s callback manager, the instrumentor captures both the model’s decision to call a tool and your application executing it. You do not add manual spans, unlike a raw provider SDK where the instrumentor sees only the model call. Each tool the agent invokes becomes its own TOOL span, a child of the agent run:
  • tool.name is the tool that ran, such as suggest_workout.
  • input.value holds the arguments the model passed, such as {"goal": "cardio"}.
  • output.value holds what the tool returned, so you can see the exact result fed back to the model.
This lets you audit tool selection and tool results directly in the trace. When you want to record work that happens outside a LangChain tool, such as a database call in your own code, add a manual span next to the automatic ones. See Combine auto and manual instrumentation.

Chains and legacy agents

The instrumentor from this guide covers the rest of LangChain with no extra setup. LCEL chains such as prompt | model | parser are traced as a RunnableSequence span wrapping the prompt, model, and parser steps. The prebuilt create_react_agent and legacy AgentExecutor agents are traced the same way, with no change to the setup.

Troubleshooting

  • No traces in Arize AX. Confirm ARIZE_SPACE_ID and ARIZE_API_KEY are set in the same shell that runs your app. Enable OpenTelemetry debug logs with export OTEL_LOG_LEVEL=debug and rerun.
  • Spans missing. LangChainInstrumentor().instrument(...) must run before any langchain import. Make sure your tracing module is the first import in your entry point.
  • Trace is cut off or empty in a script. Spans export in the background. Call tracing.tracer_provider.force_flush() before a short-lived script exits so the last batch is sent.
  • session.id not on spans. The instrumentor does not set session or user IDs on its own. Wrap the agent call in using_session() (and using_user() if needed) from openinference.instrumentation.
  • 401 or 404 from your model provider. Verify the provider API key is set and valid, and that your key has access to the model your agent requests.

Next steps

Set up sessions

Group multi-turn runs into conversations with session and user IDs.

Customize your traces

Attach metadata, tags, and custom attributes to your spans.

Evaluate agents

Score tool selection, tool results, and goal completion.

LangChain integration

The reference pages for the LangChain instrumentor in Python and TypeScript.