Skip to main content
Arize AX provides first-class support for observing LangChain applications. After instrumentation using OpenInference, you will have a full trace of every part of your LLM application, including input, embeddings, retrieval, tool usage, and output messages, all viewable in Arize AX. We follow a standardized format for trace data using OpenInference, an open-source standard based on OpenTelemetry. The arize-otel package is a lightweight convenience library to set up OpenTelemetry and send traces to Arize AX.

Tutorial on instrumenting a LangChain application (Python) and sending traces to Arize AX.

See here for more LangChain with Arize AX tutorials (Python).

This guide covers both Python and JavaScript/TypeScript.

Python Integration

API Key Setup

Before running your Python application, ensure you have the following environment variables set:
export ARIZE_SPACE_ID="YOUR_ARIZE_SPACE_ID"
export ARIZE_API_KEY="YOUR_ARIZE_API_KEY"
export OPENAI_API_KEY="YOUR_OPENAI_API_KEY" # For LangChain examples using OpenAI
# Add other LLM provider API keys if used by LangChain components
You can find your Arize AX Space ID and API Key in your Arize AX account settings.

Install

Install the necessary Python packages:
pip install openinference-instrumentation-langchain langchain langchain-openai arize-otel opentelemetry-sdk opentelemetry-exporter-otlp
(Add other langchain-* packages as needed, e.g., langchain-anthropic, langchain-google-genai)

Setup Tracing

Use arize.otel.register to configure the OpenTelemetry tracer and then apply the LangChainInstrumentor.
import os
from arize.otel import register
from openinference.instrumentation.langchain import LangChainInstrumentor

# Ensure your API keys are set as environment variables
# ARIZE_SPACE_ID = os.getenv("ARIZE_SPACE_ID")
# ARIZE_API_KEY = os.getenv("ARIZE_API_KEY")
# OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") # For the example

# Setup OTel via Arize AX's convenience function
tracer_provider = register(
    space_id=os.getenv("ARIZE_SPACE_ID"),    # or directly pass your Space ID
    api_key=os.getenv("ARIZE_API_KEY"),      # or directly pass your API Key
    project_name="my-langchain-app"        # Choose a project name
)

# Instrument LangChain
LangChainInstrumentor().instrument(tracer_provider=tracer_provider)

print("LangChain instrumented for Arize AX (Python).")

Run LangChain Example (Python)

By instrumenting LangChain, spans will be created whenever a chain, agent, or runnable is invoked and will be sent to Arize AX.
# Ensure OPENAI_API_KEY is set in your environment
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_template("Why is the {celestial_object} {color}?").partial(celestial_object="sky")
# model_name can be gpt-3.5-turbo, gpt-4, etc.
# Ensure your OPENAI_API_KEY has access to the model you choose.
chain = prompt | ChatOpenAI(model_name="gpt-3.5-turbo") 

response = chain.invoke({"color": "blue"})
print(response.content)

# Example with a different model (if you have access and the key set up)
# from langchain_anthropic import ChatAnthropic
# chain_anthropic = prompt | ChatAnthropic(model_name="claude-3-opus-20240229")
# response_anthropic = chain_anthropic.invoke({"color": "red"})
# print(response_anthropic.content)

Observe (Python)

Now that you have tracing set up, all invocations of LangChain components will be streamed to your Arize AX project for observability and evaluation.

JavaScript/TypeScript Integration

The OpenInference LangChain instrumentation is also available for JavaScript/TypeScript.

Check out the OpenInference JavaScript LangChain example.

Install (JS/TS)

Install the LangChain instrumentation package and OTLP gRPC exporter via npm:
npm install @arizeai/openinference-instrumentation-langchain @opentelemetry/exporter-trace-otlp-grpc @grpc/grpc-js @langchain/core @langchain/openai

Setup Tracing (JS/TS)

Below is an example instrumentation.ts file. You’ll need to install all imported packages.
/* instrumentation.ts */
import { LangChainInstrumentation } from "@arizeai/openinference-instrumentation-langchain";
import { ConsoleSpanExporter } from "@opentelemetry/sdk-trace-base"; // Optional: for console logging
import {
  NodeTracerProvider,
  SimpleSpanProcessor,
} from "@opentelemetry/sdk-trace-node";
import { resourceFromAttributes } from "@opentelemetry/resources";
import { OTLPTraceExporter as GrpcOTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-grpc";
import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api";
import { Metadata } from "@grpc/grpc-js";
import * as CallbackManagerModule from "@langchain/core/callbacks/manager"; // Critical for LangChain instrumentation

// For troubleshooting, set the log level to DiagLogLevel.DEBUG
// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO); // Or DiagLogLevel.DEBUG

const spaceId = process.env.ARIZE_SPACE_ID || "YOUR_ARIZE_SPACE_ID";
const apiKey = process.env.ARIZE_API_KEY || "YOUR_ARIZE_API_KEY";
const projectName = process.env.ARIZE_PROJECT_NAME || "my-langchain-js-app";

// Arize AX specific: Create metadata for OTLP exporter headers
const metadata = new Metadata();
metadata.set('space_id', spaceId);
metadata.set('api_key', apiKey);

// Optional: Console exporter for local debugging
const consoleExporter = new ConsoleSpanExporter();
const consoleProcessor = new SimpleSpanProcessor(consoleExporter);

// Arize AX OTLP gRPC exporter
const otlpExporter = new GrpcOTLPTraceExporter({
  url: "https://otlp.arize.com/v1", // Arize AX OTLP endpoint
  metadata,
});
const otlpProcessor = new SimpleSpanProcessor(otlpExporter);

const provider = new NodeTracerProvider({
  resource: resourceFromAttributes({
    // Arize AX specific: Define the project for your traces
    "project_name": projectName,
    // You can add other resource attributes here if needed
  }),
  // Add spanProcessors: otlpProcessor for Arize AX, consoleProcessor for local logs
  spanProcessors: [otlpProcessor, consoleProcessor] 
});

// Register the LangChain instrumentation
const lcInstrumentation = new LangChainInstrumentation();
// LangChain must be manually instrumented as it doesn't have a traditional module structure
// that OpenTelemetry auto-instrumentation typically relies on.
// The CallbackManagerModule is what OpenInference hooks into.
lcInstrumentation.manuallyInstrument(CallbackManagerModule);

provider.register();

console.log(\`LangChain instrumented for Arize AX (JS/TS). Project: \${projectName}\`);

// Example of how to run your LangChain code (e.g., in your main app.ts or server.ts)
// import { ChatOpenAI } from "@langchain/openai";
// import { HumanMessage } from "@langchain/core/messages";

// async function main() {
//   if (!process.env.OPENAI_API_KEY) {
//     throw new Error("OPENAI_API_KEY environment variable is not set.");
//   }
//   const chat = new ChatOpenAI({ modelName: "gpt-3.5-turbo", temperature: 0 });
//   const response = await chat.invoke([
//     new HumanMessage("Hello, how are you today?"),
//   ]);
//   console.log(response);
// }
// main().catch(console.error);
Note on instrumentation.ts: This file should be imported and run at the very beginning of your application’s lifecycle to ensure all LangChain operations are instrumented. For example, in a Node.js application, you might import it at the top of your main server file or use the node -r ./instrumentation.js your-app.js command.

Native Thread Tracking (JS/TS)

Arize AX supports native thread tracking with LangChain by enabling the use of session_id, thread_id, or conversation_id in the metadata of your LangChain calls. This allows for seamless tracking of multi-turn conversations.
// Example:
// import { ChatOpenAI } from "@langchain/openai";

// const chatModel = new ChatOpenAI({
//   openAIApiKey: "YOUR_OPENAI_API_KEY",
//   modelName: "gpt-3.5-turbo",
// });

// async function runConversation() {
//   const threadId = "my-unique-thread-id-123";

//   // First message invocation
//   const response1 = await chatModel.invoke("Hello, how are you?", {
//     metadata: {
//       thread_id: threadId,
//     },
//   });
//   console.log("Response 1:", response1.content);

//   // Second message invocation
//   const response2 = await chatModel.invoke("What can you do?", {
//     metadata: {
//       thread_id: threadId,
//     },
//   });
//   console.log("Response 2:", response2.content);
// }
// runConversation().catch(console.error);
For an executable example of native thread tracking, refer to the OpenInference JS examples or Arize AX tutorials.

Observe (JS/TS)

Once configured, your Node.js LangChain application will send traces to your Arize AX project.

General Resources