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
| Construct | Span kind | Nested children |
|---|---|---|
| Agent invocations | agent | llm per step, tool per tool call |
RunnableSequence / LCEL pipe | llm workflow span | whatever the pipe contains |
@tool / StructuredTool | tool | — |
Retrievers (VectorStoreRetriever, BM25) | retrieval | — |
| Embeddings | llm | — |
Install
npm install langchain @langchain/core @traceloop/instrumentation-langchainpip install langchain langchain-openai opentelemetry-instrumentation-langchainMinimal 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.)