Documentation

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

terminalCopy
bash
pip install "tracellm[langchain]"

This installs langchain-core>=0.1.0. If you use a specific provider like langchain-openai, install it separately:

terminalCopy
bash
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:

langchain_setup.pyCopy
python
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.content

Example: Multi-Step Chain

For complex chains with multiple steps, the handler captures each one individually:

langchain_chain.pyCopy
python
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:

EventCallback MethodStep Captured
LLM start/endon_llm_start / on_llm_endPrompt text and response content
Chain start/endon_chain_start / on_chain_endChain name, inputs, outputs, duration per chain
Tool start/endon_tool_start / on_tool_endTool name, input string, output (truncated to 500 chars)
Retriever start/endon_retriever_start / on_retriever_endQuery, document count, document previews
Error eventson_*_error methodsError message and success=False status

Info

The handler keeps an internal chain stack to correctly pair nested start/end events, even when chains, tools, and retrievers are interleaved.

The flush_trace() Method

After the chain completes, flush_trace() finalizes and persists the trace. It accepts optional overrides:

ParameterTypeDefaultDescription
promptstr or NoneJoined LLM inputsOverride the trace prompt text
responsestr or NoneJoined LLM outputsOverride the trace response text
statusstr"success"Override status (success, warning, failed)

Verification

  1. Run the chain and confirm the trace summary appears in the console
  2. Open the dashboard and filter by the project name used in @trace
  3. Inspect the trace steps — each chain, LLM call, and tool invocation appears as a row
  4. Verify latency per step matches the actual execution duration

Troubleshooting

IssueCauseFix
No steps capturedCallbacks not passed in configAdd config={'callbacks': [handler]} to every chain/tool invocation
Trace not persistedflush_trace() was not calledCall handler.flush_trace() after the chain completes
LangChain import errorlangchain-core not installedRun pip install 'tracellm[langchain]'
Steps appear out of orderNested chains with shared handlerUse a separate handler instance per top-level @trace function

Tip

For LangChain agents and tool-using chains, each tool invocation generates a separate step. Use the dashboard step inspector to see the input/output of every tool call in the execution timeline.