> ## 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.

# Spring AI

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

[Spring AI](https://spring.io/projects/spring-ai) is a framework for building AI applications in Java. Braintrust traces chat calls made to OpenAI and Anthropic through Spring AI.

**Java**

## Setup

Install the Braintrust Java SDK alongside the Spring AI module for each provider you use, then configure your API keys.

> [!NOTE]
>
> Braintrust instruments Spring AI 1.0.0 to 2.0.0 and requires Java 17 or later. Calls made with an unsupported Spring AI version still run, but produce no spans.

**1. 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>'

# add the Spring AI module for each provider you use
implementation 'org.springframework.ai:spring-ai-openai:<version-goes-here>'
implementation 'org.springframework.ai:spring-ai-anthropic:<version-goes-here>'
```

**2. Set environment variables**

```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
OPENAI_API_KEY=<your-openai-api-key>
ANTHROPIC_API_KEY=<your-anthropic-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>
```

## Auto-instrumentation

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

**1. 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}"
}
```

**2. Run your app**

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
./gradlew run
```

Spring AI chat model builds in your application code are now intercepted automatically. No call to `BraintrustSpringAI.wrap()` is required. For Spring Boot, use `./gradlew bootRun` instead.

## Manual instrumentation

To trace Spring AI calls manually, build your chat model as usual, then wrap it with `BraintrustSpringAI.wrap()`, which instruments the model in place and returns it so every `call()` emits a span.

```java Java #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
import dev.braintrust.Braintrust;
import dev.braintrust.instrumentation.springai.v2_0_0.BraintrustSpringAI;
import io.opentelemetry.api.OpenTelemetry;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;

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

        // Build your Spring AI chat model as usual
        var chatModel = OpenAiChatModel.builder()
            .options(OpenAiChatOptions.builder()
                .apiKey(System.getenv("OPENAI_API_KEY"))
                .model("gpt-5-mini")
                .build())
            .build();

        // Instrument the chat model in place
        var model = BraintrustSpringAI.wrap(openTelemetry, chatModel);

        // Every call() is now traced
        var response = model.call(new Prompt("What is machine learning?"));
    }
}
```

`AnthropicChatModel` is instrumented the same way: build it, then pass it to `BraintrustSpringAI.wrap()`.

> [!NOTE]
>
> Spring AI 2.x builds its provider client inside `build()`, so you wrap the finished chat model. For Spring AI 1.x, import `dev.braintrust.instrumentation.springai.v1_0_0.BraintrustSpringAI` and wrap the builder before calling `.build()` instead.

> [!NOTE]
>
> Async and streaming calls are traced, and each LLM span is parented to the caller's active span even when the request runs on a different thread. `BraintrustSpringAI.wrap()` is idempotent and returns the same model instance. Only `OpenAiChatModel` and `AnthropicChatModel` are instrumented; other Spring AI chat models are logged and skipped.

## What Braintrust traces

Braintrust traces each Spring AI chat model call that routes to a supported provider backend. Spring AI 2.x delegates HTTP to the official OpenAI and Anthropic Java SDKs, so spans carry the same fields as those integrations.

Braintrust captures:

* Chat model call spans for `OpenAiChatModel` (OpenAI backend) and `AnthropicChatModel` (Anthropic backend), with the request messages, model, and parameters.
* Response content for each call.
* Token usage metrics, including prompt and completion tokens.

## Resources

* [Braintrust Java SDK](https://github.com/braintrustdata/braintrust-sdk-java)
* [Spring AI reference](https://docs.spring.io/spring-ai/reference/)


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