> ## Documentation Index
> Fetch the complete documentation index at: https://docs.braintrust.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# LangChain

> Trace LangChain applications in Braintrust to debug prompts, evaluate models, and monitor production usage

[LangChain](https://www.langchain.com/) is a framework for developing applications powered by language models. Braintrust traces LangChain applications from your code.

**TypeScript**

## Setup

Install Braintrust alongside the LangChain JS packages.

```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
pnpm add braintrust @langchain/core@^1 @langchain/openai@^1
```

```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
npm install braintrust @langchain/core@^1 @langchain/openai@^1
```

## Auto-instrumentation

To trace LangChain calls without modifying your application code, initialize Braintrust normally, then run your app with Braintrust's import hook to patch `@langchain/core` at runtime. Requires `@langchain/core` v0.3.42 or later. The same hook traces [LangGraph](https://docs.braintrust.dev/integrations/agent-frameworks/langgraph.md) graphs, which run through the LangChain callback path.

**1. Initialize Braintrust and call LangChain**

```javascript title="trace-langchain-auto.js" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { initLogger } from "braintrust";
import { ChatOpenAI } from "@langchain/openai";

initLogger({
  projectName: "My Project",
  apiKey: process.env.BRAINTRUST_API_KEY,
});

const model = new ChatOpenAI({ model: "gpt-5-mini" });

const response = await model.invoke("What is the capital of France?");
console.log(response.content);
```

**2. Run with the import hook**

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
node --import braintrust/hook.mjs trace-langchain-auto.js
```

The auto-instrumentation example uses plain JavaScript so `node --import` can run the file directly. The Braintrust APIs work the same in TypeScript projects. Compile your TypeScript to JavaScript and run the compiled file with the import hook, or [run TypeScript directly](https://docs.braintrust.dev/instrument/trace-llm-calls.md#auto-instrumentation) with a TypeScript loader.

> [!NOTE]
>
> If you're using a bundler, see [Trace LLM calls](https://docs.braintrust.dev/instrument/trace-llm-calls.md#auto-instrumentation) for plugin and loader setup.

## Manual instrumentation

To trace LangChain calls manually, attach `BraintrustLangChainCallbackHandler` to each call's `callbacks` option yourself.

```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import { ChatOpenAI } from "@langchain/openai";
import { BraintrustLangChainCallbackHandler, initLogger } from "braintrust";

initLogger({
  projectName: "My Project",
  apiKey: process.env.BRAINTRUST_API_KEY,
});

const handler = new BraintrustLangChainCallbackHandler();

async function main() {
  const model = new ChatOpenAI({ modelName: "gpt-5-mini" });

  await model.invoke("What is the capital of France?", {
    callbacks: [handler],
  });
}

main();
```

Run it:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
npx ts-node trace-langchain.ts
```

## What Braintrust traces

Braintrust captures:

* LLM and chat model calls, chains, agents, tools, and retrievers as separate spans, with inputs and outputs preserved
* Token usage on LLM spans (`prompt_tokens`, `completion_tokens`, `total_tokens`, `prompt_cached_tokens`, `prompt_cache_creation_tokens`, `completion_reasoning_tokens`)
* `time_to_first_token` on streaming responses, captured on the first new-token callback
* Model name and serialized invocation parameters in span metadata
* Errors from any callback captured on the span

## Tracing resources

* [LangChain JS documentation](https://js.langchain.com/docs/introduction/)
* [`BraintrustLangChainCallbackHandler` reference](https://docs.braintrust.dev/sdks/typescript/versions/latest#braintrustlangchaincallbackhandler)

**Python**

## Setup

Install Braintrust alongside the LangChain Python packages.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
pip install braintrust langchain-core langchain-openai
```

## Auto-instrumentation

To trace LangChain calls without modifying your application code, call `braintrust.auto_instrument()` before importing LangChain.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import braintrust

braintrust.auto_instrument()
braintrust.init_logger(project="My Project")

from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

prompt = ChatPromptTemplate.from_template("What is 1 + {number}?")
model = ChatOpenAI(model="gpt-5-mini")
chain = prompt | model

response = chain.invoke({"number": "2"})
print(response.content)
```

## Manual instrumentation

To register the callback handler yourself instead of using auto-instrumentation, configure `BraintrustCallbackHandler` and pass it to `set_global_handler`.

```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import asyncio
import os

from braintrust import init_logger
from braintrust.integrations.langchain import BraintrustCallbackHandler, set_global_handler
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI

async def main():
    init_logger(project="My Project", api_key=os.environ["BRAINTRUST_API_KEY"])

    handler = BraintrustCallbackHandler()
    set_global_handler(handler)

    prompt = ChatPromptTemplate.from_template("What is 1 + {number}?")
    model = ChatOpenAI(model="gpt-5-mini")
    chain = prompt | model

    response = await chain.ainvoke({"number": "2"})
    print(response.content)

if __name__ == "__main__":
    asyncio.run(main())
```

Run it:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
python trace-langchain.py
```

The same callback handler also works with [LangGraph](https://docs.braintrust.dev/integrations/agent-frameworks/langgraph.md) and [Deep Agents](https://docs.braintrust.dev/integrations/agent-frameworks/deepagents.md).

## What Braintrust traces

Braintrust captures:

* LLM and chat model calls, chains, agents, tools, and retrievers as separate spans, with inputs and outputs preserved
* Token usage on LLM spans (`prompt_tokens`, `completion_tokens`, `total_tokens`, `tokens`, `prompt_cached_tokens`)
* Anthropic prompt cache creation tokens, broken out by TTL as `prompt_cache_creation_5m_tokens` and `prompt_cache_creation_1h_tokens` when available, or `prompt_cache_creation_tokens` otherwise
* `time_to_first_token` on streaming responses, captured on the first new-token callback
* Model name and serialized invocation parameters in span metadata
* Errors from any callback captured on the span

## Tracing resources

* [Deep Agents integration](https://docs.braintrust.dev/integrations/agent-frameworks/deepagents.md)
* [LangGraph integration](https://docs.braintrust.dev/integrations/agent-frameworks/langgraph.md)
* [LangChain callback documentation](https://python.langchain.com/docs/how_to/#callbacks)
* [LangChain official documentation](https://python.langchain.com/docs/introduction/)

**Go**

## Setup

Install the Braintrust Go SDK alongside LangChainGo.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
go get github.com/braintrustdata/braintrust-sdk-go
go get github.com/braintrustdata/braintrust-sdk-go/trace/contrib/langchaingo
go get github.com/tmc/langchaingo
```

## Manual instrumentation

To trace LangChainGo calls, create a `tracelangchaingo.NewHandlerWithOptions` callback handler and pass it as a callback option on your LLM.

```go Go theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/tmc/langchaingo/llms"
	"github.com/tmc/langchaingo/llms/openai"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/sdk/trace"

	"github.com/braintrustdata/braintrust-sdk-go"
	tracelangchaingo "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/langchaingo"
)

func main() {
	// Initialize Braintrust tracing with blocking login
	tp := trace.NewTracerProvider()
	defer tp.Shutdown(context.Background())
	otel.SetTracerProvider(tp)

	bt, err := braintrust.New(tp,
		braintrust.WithProject("My Project"),
		braintrust.WithBlockingLogin(true),
	)
	if err != nil {
		log.Fatal(err)
	}

	// Create the Braintrust callback handler
	handler := tracelangchaingo.NewHandlerWithOptions(tracelangchaingo.HandlerOptions{
		Model:          "gpt-5-mini",
		Provider:       "openai",
		TracerProvider: tp,
	})

	// Create LangChainGo LLM with the callback handler
	llm, err := openai.New(openai.WithCallback(handler))
	if err != nil {
		log.Fatal(err)
	}

	// Create a root span to group operations
	tracer := otel.Tracer("langchain-example")
	ctx, rootSpan := tracer.Start(context.Background(), "trace-langchain")
	defer rootSpan.End()

	// Use LangChainGo as normal - all calls will be logged to Braintrust
	messages := []llms.MessageContent{
		llms.TextParts(llms.ChatMessageTypeHuman, "What is the capital of France?"),
	}
	resp, err := llm.GenerateContent(ctx, messages)
	if err != nil {
		log.Fatal(err)
	}
	if len(resp.Choices) > 0 {
		fmt.Printf("Answer: %s\n", resp.Choices[0].Content)
	}

	// Print the permalink to view traces
	fmt.Printf("\nView traces: %s\n", bt.Permalink(rootSpan))
}
```

Run it:

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
go run trace-langchain.go
```

### Tracing embeddings

LangChainGo's callback system does not fire for embedding calls, so the standard `tracelangchaingo.NewHandlerWithOptions` handler used above does not cover embeddings. To trace embeddings, explicitly wrap your embedder with `tracelangchaingo.WrapEmbedder`. The wrapped value implements `embeddings.Embedder` and is a drop-in replacement for the original — `EmbedDocuments` and `EmbedQuery` calls are captured as LLM spans.

```go #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import (
	"github.com/tmc/langchaingo/embeddings"
	"github.com/tmc/langchaingo/llms/openai"

	tracelangchaingo "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/langchaingo"
)

llm, err := openai.New()
if err != nil {
	log.Fatal(err)
}

inner, err := embeddings.NewEmbedder(llm)
if err != nil {
	log.Fatal(err)
}

embedder := tracelangchaingo.WrapEmbedder(inner,
	tracelangchaingo.WithEmbedderTracerProvider(tp),
	tracelangchaingo.WithEmbedderProvider("openai"),
	tracelangchaingo.WithEmbedderModel("text-embedding-ada-002"),
)

vectors, err := embedder.EmbedDocuments(ctx, []string{"hello", "world"})
```

## What Braintrust traces

Braintrust captures:

* LLM `GenerateContent` calls, chains, tools, agents, and retrievers as separate spans, with inputs converted to OpenAI-format messages and outputs in OpenAI-format choices (role, content, finish\_reason)
* Streaming output reconstructed by accumulating chunks delivered through `HandleStreamingFunc`
* Token usage on LLM spans (`prompt_tokens`, `completion_tokens`, `tokens`, `prompt_cached_tokens`, `prompt_cache_creation_tokens`)
* Reasoning content, function calls, tool calls, and stop reasons in LLM output
* Embedding calls via `WrapEmbedder`: input texts, embedding count, and embedding dimensions
* Errors from any handler captured on the span

## Tracing resources

* [LangChainGo documentation](https://github.com/tmc/langchaingo)
* [Go SDK example](https://github.com/braintrustdata/braintrust-sdk-go/tree/main/examples/langchaingo)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.