Observability for LangChain (JavaScript) with Opik
Opik provides seamless integration with LangChain through the opik-langchain package, allowing you to trace, monitor, and debug your LangChain applications.
Features
Section titled “Features”- Comprehensive Tracing: Automatically trace LLM calls, chains, tools, retrievers, and agents
- Hierarchical Visualization: View your LangChain execution as a structured trace with parent-child relationships
- Detailed Metadata Capture: Record model names, prompts, completions, usage statistics, and custom metadata
- Error Handling: Capture and visualize errors at every step of your LangChain execution
- Custom Tagging: Add custom tags to organize and filter your traces
Installation
Section titled “Installation”Option 1: Using npm
Section titled “Option 1: Using npm”npm install opik-langchainOption 2: Using yarn
Section titled “Option 2: Using yarn”yarn add opik-langchainRequirements
Section titled “Requirements”- Node.js ≥ 18
- LangChain (
@langchain/core≥ 0.3.78) - Opik SDK (
opikpeer dependency)
Basic Usage
Section titled “Basic Usage”Using with LLM Calls
Section titled “Using with LLM Calls”You can add the OpikCallbackHandler in two ways in LangChain: at construction time and at execution time. Here's how to use both approaches:
import { OpikCallbackHandler } from "opik-langchain";
import { ChatOpenAI } from "@langchain/openai";
// Create the Opik callback handler
const opikHandler = new OpikCallbackHandler();
// Option 1: Add the handler at model initialization time
const llm = new ChatOpenAI({
callbacks: [opikHandler], // Will be used for all calls to this model
});
// Run LLM
const response = await llm.invoke("Hello, how can you help me today?");
// Option 2: Add the handler at invocation time (or both)
const llmWithoutHandler = new ChatOpenAI();
const response2 = await llmWithoutHandler.invoke("What's the weather like today?", {
callbacks: [opikHandler], // Will be used just for this specific call
});
// You can also combine both approaches
const anotherResponse = await llm.invoke("Tell me a joke", {
callbacks: [opikHandler], // Will use both the constructor handler and this one
});
// Ensure all traces are sent before your app terminates
await opikHandler.flushAsync();Configuring for All Components
Section titled “Configuring for All Components”You can also set up the handler to be used across all LangChain components in your application:
import { OpikCallbackHandler } from "opik-langchain";
import { ChatOpenAI } from "@langchain/openai";
import { PromptTemplate } from "@langchain/core/prompts";
import { LLMChain } from "langchain/chains";
import { setGlobalCallbacks } from "@langchain/core/callbacks/manager";
// Create the Opik callback handler
const opikHandler = new OpikCallbackHandler({
tags: ["global"],
projectName: "langchain-app",
});
// Set as global handler (will be used for all LangChain components)
setGlobalCallbacks([opikHandler]);
// These components will now automatically use the global handler
const llm = new ChatOpenAI();
const template = PromptTemplate.fromTemplate("Answer this question: {question}");
const chain = new LLMChain({ llm, prompt: template });
// Global handlers are used automatically
const result = await chain.call({ question: "What is 2+2?" });
// Flush before your app exits
await opikHandler.flushAsync();Advanced Configuration
Section titled “Advanced Configuration”The OpikCallbackHandler constructor accepts several options to customize the integration:
const opikHandler = new OpikCallbackHandler({
// Optional array of tags to apply to all traces
tags: ["langchain", "production", "user-query"],
// Optional metadata to include with all traces
metadata: {
environment: "production",
version: "1.0.0",
},
// Optional project name for Opik
projectName: "my-langchain-project",
// Optional pre-configured Opik client
// If not provided, a new client will be created automatically
client: customOpikClient,
});Troubleshooting
Section titled “Troubleshooting”Missing Traces: Ensure you're providing the OpikCallbackHandler to both the component constructor and each invoke call.
Incomplete Hierarchies: For proper parent-child relationships, use the same handler instance throughout your application.
Performance Impact: The Opik integration adds minimal overhead to your LangChain application.