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

# LangChain4j

> Trace LangChain4j calls in Braintrust to debug prompts, evaluate models, and monitor production usage

[LangChain4j](https://docs.langchain4j.dev/) is a library for building LLM-powered applications in Java. It is an independent project designed around Java conventions, not a port of Python LangChain. Braintrust traces LangChain4j applications that call OpenAI, including the OpenAI Responses API.

<View title="Java" icon="https://img.logo.dev/docs.langchain4j.dev?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-java">
    Setup
  </h2>

  Install the Braintrust Java SDK alongside LangChain4j and its OpenAI module, then configure your API keys.

  <Note>
    Braintrust instruments LangChain4j 1.8.0 or later and requires Java 17 or later. The OpenAI Responses API models (`OpenAiResponsesChatModel`, `OpenAiResponsesStreamingChatModel`) require LangChain4j 1.14.0 or later.
  </Note>

  <Steps>
    <Step title="Install packages">
      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      # add to build.gradle dependencies{} block
      implementation 'dev.braintrust:braintrust-sdk-java:<version-goes-here>'

      # LangChain4j and its OpenAI module
      implementation 'dev.langchain4j:langchain4j:<version-goes-here>'
      implementation 'dev.langchain4j:langchain4j-open-ai:<version-goes-here>'
      ```
    </Step>

    <Step title="Set environment variables">
      ```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      OPENAI_API_KEY=<your-openai-api-key>
      BRAINTRUST_API_KEY=<your-braintrust-api-key>

      # For organizations on the EU data plane, use https://api-eu.braintrust.dev
      # For self-hosted deployments, use your data plane URL
      # BRAINTRUST_API_URL=<your-braintrust-api-url>
      ```
    </Step>
  </Steps>

  <h2 id="auto-instrumentation-java">
    Auto-instrumentation
  </h2>

  To trace LangChain4j calls without modifying your application code, attach the [`braintrust-java-agent`](/docs/instrument/trace-llm-calls#auto-instrumentation) at JVM startup. The agent intercepts every LangChain4j OpenAI model build and applies Braintrust instrumentation automatically.

  <Steps>
    <Step title="Add the agent dependency">
      The agent is a separate artifact from the SDK. Add it as its own dependency configuration:

      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      # build.gradle
      configurations {
          braintrustAgent
      }

      dependencies {
          braintrustAgent 'dev.braintrust:braintrust-java-agent:+'
      }

      tasks.withType(JavaExec).configureEach {
          jvmArgs "-javaagent:${configurations.braintrustAgent.asPath}"
      }
      ```
    </Step>

    <Step title="Run your app">
      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      ./gradlew run
      ```

      LangChain4j OpenAI model builds in your application code are now intercepted automatically. No call to `BraintrustLangchain.wrap()` is required. For Spring Boot, use `./gradlew bootRun` instead.
    </Step>
  </Steps>

  <h2 id="manual-instrumentation-java">
    Manual instrumentation
  </h2>

  To trace LangChain4j calls manually, get an `OpenTelemetry` instance from Braintrust, then wrap your OpenAI model with `BraintrustLangchain.wrap()`. The wrap instruments the model in place and returns it, so every call emits a span.

  <CodeGroup>
    ```java Java #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import dev.braintrust.Braintrust;
    import dev.braintrust.instrumentation.langchain.v1_14_0.BraintrustLangchain;
    import dev.langchain4j.data.message.UserMessage;
    import dev.langchain4j.model.chat.ChatModel;
    import dev.langchain4j.model.openai.OpenAiChatModel;
    import io.opentelemetry.api.OpenTelemetry;

    class LangchainTracing {
        public static void main(String[] args) {
            var braintrust = Braintrust.get();
            OpenTelemetry openTelemetry = braintrust.openTelemetryCreate();

            // Build the OpenAI model and instrument it in place
            ChatModel model = BraintrustLangchain.wrap(
                openTelemetry,
                OpenAiChatModel.builder()
                    .apiKey(System.getenv("OPENAI_API_KEY"))
                    .modelName("gpt-5-mini"));

            // Every chat() call is now traced
            var response = model.chat(UserMessage.from("What is the capital of France?"));
            System.out.println(response.aiMessage().text());
        }
    }
    ```
  </CodeGroup>

  `OpenAiStreamingChatModel`, `OpenAiResponsesChatModel`, and `OpenAiResponsesStreamingChatModel` are instrumented the same way: build the model, then pass it (or its builder) to `BraintrustLangchain.wrap()`. The Responses API models require LangChain4j 1.14.0 or later.

  <Note>
    For LangChain4j 1.8.0 through 1.13.x, import `dev.braintrust.instrumentation.langchain.v1_8_0.BraintrustLangchain` instead. That module traces `OpenAiChatModel` and `OpenAiStreamingChatModel`, but not the Responses API models, which do not exist before 1.14.0.
  </Note>

  <h3 id="ai-services-java">
    AiServices agents and tools
  </h3>

  Pass an `AiServices` builder to `BraintrustLangchain.wrap()` to trace a declarative agent. Braintrust instruments the underlying model, every `@Tool` method, and each service method call, and keeps concurrent tool calls linked to the parent trace.

  <CodeGroup>
    ```java Java #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import dev.braintrust.Braintrust;
    import dev.braintrust.instrumentation.langchain.v1_14_0.BraintrustLangchain;
    import dev.langchain4j.agent.tool.Tool;
    import dev.langchain4j.model.openai.OpenAiResponsesChatModel;
    import dev.langchain4j.service.AiServices;
    import io.opentelemetry.api.OpenTelemetry;

    class LangchainAgentTracing {
        interface Assistant {
            String chat(String userMessage);
        }

        static class WeatherTools {
            @Tool("Get current weather for a location")
            public String getWeather(String location) {
                return String.format("The weather in %s is sunny with 72°F.", location);
            }
        }

        public static void main(String[] args) {
            var braintrust = Braintrust.get();
            OpenTelemetry openTelemetry = braintrust.openTelemetryCreate();

            // Wrap the AiServices builder: the service, its tools, and the model are all traced
            Assistant assistant = BraintrustLangchain.wrap(
                openTelemetry,
                AiServices.builder(Assistant.class)
                    .chatModel(OpenAiResponsesChatModel.builder()
                        .apiKey(System.getenv("OPENAI_API_KEY"))
                        .modelName("gpt-5-mini")
                        .build())
                    .tools(new WeatherTools())
                    .executeToolsConcurrently());

            System.out.println(assistant.chat("What is the weather in Paris?"));
        }
    }
    ```
  </CodeGroup>

  Each service method call is traced as a span named `<Interface>.<method>` (for example, `Assistant.chat`), with a child LLM span for the model call and a `tool` span for each `@Tool` invocation.

  <h2 id="what-traced-java">
    What Braintrust traces
  </h2>

  Braintrust traces LangChain4j OpenAI models: `OpenAiChatModel` and `OpenAiStreamingChatModel`, plus `OpenAiResponsesChatModel` and `OpenAiResponsesStreamingChatModel` on LangChain4j 1.14.0 or later.

  Braintrust captures:

  * LLM calls as separate spans, with request messages (or the Responses API `input`), model name, and serialized generation parameters in span metadata.
  * Response content, reconstructed by accumulating chunks on streaming calls.
  * Token usage on LLM spans (`prompt_tokens`, `completion_tokens`, `tokens`, `prompt_cached_tokens`, `completion_reasoning_tokens`).
  * `time_to_first_token` on streaming responses, measured from the first chunk that carries generated output.
  * The OpenAI request ID (`x-request-id`) from the response headers and the response object ID (`response_id`), so you can correlate a span with OpenAI's API logs.
  * `AiServices` method calls as spans named `<Interface>.<method>`, with each `@Tool` invocation as a nested `tool` span that records its arguments and result.
  * Server-side tool calls in the Responses API (web search, file search, code interpreter, and MCP) as nested `tool` spans.
  * Errors captured on the span.

  <h2 id="resources-java">
    Resources
  </h2>

  * [Braintrust Java SDK](https://github.com/braintrustdata/braintrust-sdk-java)
  * [LangChain4j examples](https://github.com/braintrustdata/braintrust-sdk-java/tree/main/examples)
  * [LangChain4j documentation](https://docs.langchain4j.dev/)
</View>
