LangChain

Agents, chains, LCEL runnables, and tools auto-capture as a nested span tree.

Install the instrumentor and every chain, agent, and tool invocation inside wrap your agent becomes a span, with the underlying LLM calls nested below.

What's captured

ConstructSpan kindNested children
Agent invocationsagentllm per step, tool per tool call
RunnableSequence / LCEL pipellm workflow spanwhatever the pipe contains
@tool / StructuredTooltool
Retrievers (VectorStoreRetriever, BM25)retrieval
Embeddingsllm

Install

npm install langchain @langchain/core @traceloop/instrumentation-langchain
pip install langchain langchain-openai opentelemetry-instrumentation-langchain

Minimal example — LCEL chain

import os, trodo
from langchain_openai import ChatOpenAI
from langchain_core.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser

trodo.init(site_id=os.environ['TRODO_SITE_ID'])

chain = (
    PromptTemplate.from_template('Answer in one sentence: {question}')
    | ChatOpenAI(model='gpt-4o-mini')
    | StrOutputParser()
)

with trodo.wrap_agent('langchain-chain') as run:
    result = chain.invoke({'question': "What's the weather in SF?"})
    run.set_output(result)
import trodo from 'trodo-node';
import { ChatOpenAI } from '@langchain/openai';
import { PromptTemplate } from '@langchain/core/prompts';
import { StringOutputParser } from '@langchain/core/output_parsers';

trodo.init({ siteId: process.env.TRODO_SITE_ID });

const chain = PromptTemplate.fromTemplate('Answer in one sentence: {question}')
  .pipe(new ChatOpenAI({ model: 'gpt-4o-mini' }))
  .pipe(new StringOutputParser());

await trodo.wrapAgent('langchain-chain', async (run) => {
  const result = await chain.invoke({ question: "What's the weather in SF?" });
  run.setOutput(result);
});

The chain, its prompt/parse steps, and the LLM call appear as a nested tree under the run — each with the model's real token counts. Agent + tool invocations (LangChain's agent loop, @tool functions) nest the same way.

LangChain 1.x moved AgentExecutor / create_react_agent / hub out of the core langchain package (Python: langchain-classic; the current API is create_agent). If you're on the legacy agent API, install the package that provides it — the instrumentation captures either generation.

Double counting (Node only): the Node @traceloop/instrumentation-langchain records the model call itself, so if the provider's own instrumentor is also installed (e.g. @opentelemetry/instrumentation-openai) each chain model call is captured twice — once by the LangChain instrumentation and once at the provider transport — inflating run tokens/cost 2×. When LangChain is your primary Node framework, disable the provider instrumentor:

trodo.init({ siteId: process.env.TRODO_SITE_ID, disableInstrumentations: ['openai'] });

Python is different: the Python LangChain instrumentor records the chain/agent structure but the model call itself is captured by the provider instrumentor (opentelemetry-instrumentation-openai). They're complementary, not duplicated — so do not disable the provider instrumentor on Python, or you'll lose the LLM span entirely. (init(disable_instrumentations=[...]) exists on Python too, for the cases where you do want it.)

On this page