LangChain
Trace LangChain chains, tools, and agents.
Overview
The LangChain integration uses a custom BaseCallbackHandler to instrument LangChain chains, LLM calls, tools, and retrievers. Every event — chain start/end, LLM invocation, tool execution, retriever query — is captured as a step in the trace timeline.
The handler collects steps throughout the chain execution. When the chain finishes, you call handler.flush_trace() to persist the complete trace to MongoDB.
Installation
pip install "tracellm[langchain]"
This installs langchain-core>=0.1.0. If you use a specific provider like langchain-openai, install it separately:
pip install "tracellm[langchain]" langchain-openai
Setup
Create a TracellmCallbackHandler instance and pass it via the LangChain config dictionary. After the chain completes, call flush_trace() to persist:
from tracellm import trace
from tracellm.integrations.langchain import TracellmCallbackHandler
from langchain_openai import ChatOpenAI
from langchain.schema import HumanMessage, SystemMessage
handler = TracellmCallbackHandler()
@trace(prompt="langchain_chain", project="langchain-demo")
def run_chain(prompt: str) -> str:
llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
messages = [
SystemMessage(content="You are a helpful assistant."),
HumanMessage(content=prompt),
]
result = llm.invoke(messages, config={"callbacks": [handler]})
handler.flush_trace(prompt=prompt, response=result.content)
return result.contentExample: Multi-Step Chain
For complex chains with multiple steps, the handler captures each one individually:
from tracellm import trace
from tracellm.integrations.langchain import TracellmCallbackHandler
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
handler = TracellmCallbackHandler()
@trace(
prompt="summarize_and_translate",
model_name="gpt-4o",
project="translation-service",
environment="production",
)
def summarize_and_translate(text: str, target_lang: str) -> str:
llm = ChatOpenAI(model="gpt-4o", temperature=0.3)
summarize_prompt = ChatPromptTemplate.from_messages([
("system", "Summarize the following text in 2-3 sentences."),
("user", "{text}"),
])
translate_prompt = ChatPromptTemplate.from_messages([
("system", "Translate the following to {language}."),
("user", "{summary}"),
])
summarize_chain = summarize_prompt | llm | StrOutputParser()
translate_chain = translate_prompt | llm | StrOutputParser()
summary = summarize_chain.invoke(
{"text": text},
config={"callbacks": [handler]},
)
translation = translate_chain.invoke(
{"summary": summary, "language": target_lang},
config={"callbacks": [handler]},
)
handler.flush_trace(prompt=text, response=translation)
return translation
result = summarize_and_translate(
"LangChain is a framework for developing applications powered by language models...",
"French",
)
print(result)What the Trace Captures
The TracellmCallbackHandler hooks into five LangChain event types:
| Event | Callback Method | Step Captured |
|---|---|---|
| LLM start/end | on_llm_start / on_llm_end | Prompt text and response content |
| Chain start/end | on_chain_start / on_chain_end | Chain name, inputs, outputs, duration per chain |
| Tool start/end | on_tool_start / on_tool_end | Tool name, input string, output (truncated to 500 chars) |
| Retriever start/end | on_retriever_start / on_retriever_end | Query, document count, document previews |
| Error events | on_*_error methods | Error message and success=False status |
Info
The flush_trace() Method
After the chain completes, flush_trace() finalizes and persists the trace. It accepts optional overrides:
| Parameter | Type | Default | Description |
|---|---|---|---|
| prompt | str or None | Joined LLM inputs | Override the trace prompt text |
| response | str or None | Joined LLM outputs | Override the trace response text |
| status | str | "success" | Override status (success, warning, failed) |
Verification
- Run the chain and confirm the trace summary appears in the console
- Open the dashboard and filter by the project name used in @trace
- Inspect the trace steps — each chain, LLM call, and tool invocation appears as a row
- Verify latency per step matches the actual execution duration
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| No steps captured | Callbacks not passed in config | Add config={'callbacks': [handler]} to every chain/tool invocation |
| Trace not persisted | flush_trace() was not called | Call handler.flush_trace() after the chain completes |
| LangChain import error | langchain-core not installed | Run pip install 'tracellm[langchain]' |
| Steps appear out of order | Nested chains with shared handler | Use a separate handler instance per top-level @trace function |
Tip