Anthropic チャット

Anthropic Claude (英語) は、さまざまなアプリケーションで使用できる基礎的な AI モデルのファミリーです。開発者や企業は、API アクセスを活用して、Anthropic の AI インフラ (英語) 上に直接構築できます。

Spring AI は、同期およびストリーミングテキスト生成のために Anthropic メッセージング API (英語) をサポートします。

Anthropic の Claude モデルは、Amazon Bedrock Converse を通じても利用できます。Spring AI は専用の Amazon Bedrock コンバース Anthropic クライアント実装も提供します。

前提条件

Anthropic ポータルで API キーを作成する必要があります。

Anthropic API ダッシュボード (英語) でアカウントを作成し、API キーを取得する (英語) ページで API キーを生成します。

Spring AI プロジェクトは、spring.ai.anthropic.api-key という名前の構成プロパティを定義します。このプロパティは、anthropic.com から取得した API Key の値に設定する必要があります。

この構成プロパティは、application.properties ファイルで設定できます。

spring.ai.anthropic.api-key=<your-anthropic-api-key>

API キーなどの機密情報を扱う際のセキュリティを強化するために、Spring 式言語 (SpEL) を使用してカスタム環境変数を参照できます。

# In application.yml
spring:
  ai:
    anthropic:
      api-key: ${ANTHROPIC_API_KEY}
# In your environment or .env file
export ANTHROPIC_API_KEY=<your-anthropic-api-key>

この構成は、アプリケーションコード内でプログラム的に取得することもできます。

// Retrieve API key from a secure source or environment variable
String apiKey = System.getenv("ANTHROPIC_API_KEY");

リポジトリと BOM の追加

Spring AI アーティファクトは、Maven Central リポジトリと Spring スナップショットリポジトリに公開されています。これらのリポジトリをビルドシステムに追加するには、アーティファクトリポジトリセクションを参照してください。

依存関係の管理を支援するために、Spring AI は BOM (部品表) を提供し、一貫したバージョンの Spring AI がプロジェクト全体で使用されるようにします。Spring AI BOM をビルドシステムに追加するには、"依存関係管理" セクションを参照してください。

自動構成

Spring AI 自動構成、スターターモジュールのアーティファクト名に大きな変更がありました。詳細については、アップグレードノートを参照してください。

Spring AI は、Anthropic チャットクライアント用の Spring Boot 自動構成を提供します。これを有効にするには、プロジェクトの Maven pom.xml または Gradle build.gradle ファイルに次の依存関係を追加します。

  • Maven

  • Gradle

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-anthropic</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-starter-model-anthropic'
}
Spring AI BOM をビルドファイルに追加するには、"依存関係管理" セクションを参照してください。

チャットのプロパティ

再試行プロパティ

プレフィックス spring.ai.retry は、Anthropic チャットモデルの再試行メカニズムを構成できるプロパティプレフィックスとして使用されます。

プロパティ 説明 デフォルト

spring.ai.retry.max-attempts

再試行の最大回数。

10

spring.ai.retry.backoff.initial-interval

指数関数的バックオフポリシーの初期スリープ期間。

2 秒

spring.ai.retry.backoff.multiplier

バックオフ間隔の乗数。

5

spring.ai.retry.backoff.max-interval

最大バックオフ期間。

3 分

spring.ai.retry.on-client-errors

false の場合、NonTransientAiException をスローし、4xx クライアントエラーコードの再試行を試行しません。

false

spring.ai.retry.exclude-on-http-codes

再試行をトリガーしない HTTP ステータスコードのリスト (例: NonTransientAiException をスローする)。

spring.ai.retry.on-http-codes

再試行をトリガーする必要がある HTTP ステータスコードのリスト (例: TransientAiException をスローする)。

現在、再試行ポリシーはストリーミング API には適用されません。

接続プロパティ

接頭辞 spring.ai.anthropic は、Anthropic への接続を可能にするプロパティ接頭辞として使用されます。

プロパティ 説明 デフォルト

spring.ai.anthropic.base-url

接続先の URL

api.anthropic.com (英語)

spring.ai.anthropic.completions-path

ベース URL に追加するパス。

/v1/chat/completions

spring.ai.anthropic.version

Anthropic API バージョン

2023-06-01

spring.ai.anthropic.api-key

API キー

-

spring.ai.anthropic.beta-version

新しい / 実験的な機能を有効にします。max-tokens-3-5-sonnet-2024-07-15 に設定すると、出力トークンの制限が 4096 トークンから 8192 トークンに増加されます (claude-3-5-sonnet のみ)。

tools-2024-04-04

プロパティの構成

チャットの自動構成の有効化と無効化は、プレフィックス spring.ai.model.chat を持つ最上位プロパティを介して設定されるようになりました。

有効にするには、spring.ai.model.chat=anthropic (デフォルトで有効になっています)

無効にするには、spring.ai.model.chat=none (または人類学的に一致しない値)

この変更は、複数のモデルの構成を可能にするために行われます。

プレフィックス spring.ai.anthropic.chat は、Anthropic のチャットモデル実装を構成できるプロパティプレフィックスです。

プロパティ 説明 デフォルト

spring.ai.anthropic.chat.enabled (削除され、無効になりました)

Anthropic チャットモデルを有効にします。

true

spring.ai.model.chat

Anthropic チャットモデルを有効にします。

人類的な

spring.ai.anthropic.chat.options.model

使用する Anthropic チャットモデルです。サポート: claude-sonnet-4-5claude-opus-4-5claude-haiku-4-5claude-opus-4-1claude-opus-4-0claude-sonnet-4-0claude-3-7-sonnet-latestclaude-3-5-sonnet-latestclaude-3-5-haiku-latestclaude-3-opus-latestclaude-3-haiku-20240307

claude-sonnet-4-5

spring.ai.anthropic.chat.options.temperature

生成される補完の見かけの創造性を制御するために使用するサンプリング温度。値を高くすると出力がよりランダムになり、値を低くすると結果がより集中的で決定的になります。これら 2 つの設定の相互作用を予測するのは難しいため、同じ完了リクエストに対して温度と top_p を変更することはお勧めできません。

0.8

spring.ai.anthropic.chat.options.max-tokens

チャット補完で生成するトークンの最大数。入力トークンと生成されたトークンの合計の長さは、モデルのコンテキストの長さによって制限されます。

500

spring.ai.anthropic.chat.options.stop-sequence

モデルの生成を停止させるカスタムテキストシーケンス。モデルは通常、自然にターンを完了すると停止し、その結果、レスポンス stop_reason は "end_turn" になります。モデルがカスタムテキスト文字列に遭遇したときに生成を停止する場合は、stop_sequences パラメーターを使用できます。モデルがカスタムシーケンスの 1 つに遭遇すると、レスポンス stop_reason 値は "stop_sequence" になり、レスポンス stop_sequence 値には一致する停止シーケンスが含まれます。

-

spring.ai.anthropic.chat.options.top-p

核サンプリングを使用します。核サンプリングでは、後続の各トークンのすべてのオプションの累積分布を確率の降順で計算し、top_p で指定された特定の確率に達するとそれをカットオフします。温度または top_p のいずれかを変更する必要がありますが、両方を変更することはできません。高度な使用例にのみ推奨されます。通常は温度のみを使用する必要があります。

-

spring.ai.anthropic.chat.options.top-k

後続の各トークンについて、上位 K 個のオプションからのみサンプリングします。「ロングテール」の低確率レスポンスを削除するために使用されます。技術的な詳細については、こちらを参照してください。高度な使用例にのみ推奨されます。通常は温度のみを使用する必要があります。

-

spring.ai.anthropic.chat.options.tool-names

単一のプロンプトリクエストでツール呼び出しを有効にする、名前で識別されるツールのリスト。これらの名前のツールは、toolCallbacks レジストリに存在する必要があります。

-

spring.ai.anthropic.chat.options.tool-callbacks

ChatModel に登録するツールコールバック。

-

spring.ai.anthropic.chat.options.toolChoice

モデルがどのツールを呼び出すか(ある場合)を制御します。none は、モデルが関数を呼び出さずにメッセージを生成することを意味します。auto は、モデルがメッセージを生成するかツールを呼び出すかを選択できることを意味します。{"type: "tool", "name": "my_tool"} で特定のツールを指定すると、モデルはそのツールを強制的に呼び出します。関数が存在しない場合は none がデフォルトです。関数が存在する場合は auto がデフォルトです。

-

spring.ai.anthropic.chat.options.internal-tool-execution-enabled

False の場合、Spring AI はツール呼び出しを内部で処理せず、クライアントにプロキシします。その後、ツール呼び出しを処理し、適切な関数にディスパッチして、結果を返すのはクライアントの責任です。True (デフォルト) の場合、Spring AI は関数呼び出しを内部で処理します。関数呼び出しをサポートするチャットモデルにのみ適用されます。

true

spring.ai.anthropic.chat.options.http-headers

チャット補完リクエストに追加されるオプションの HTTP ヘッダー。

-

モデルエイリアスの最新リストとその説明については、公式の Anthropic モデルエイリアスのドキュメント (英語) を参照してください。
spring.ai.anthropic.chat.options というプレフィックスが付いたすべてのプロパティは、リクエスト固有のランタイムオプションを Prompt 呼び出しに追加することで実行時にオーバーライドできます。

ランタイムオプション

AnthropicChatOptions.java [GitHub] (英語) は、使用するモデル、温度、最大トークン数などのモデル構成を提供します。

起動時に、AnthropicChatModel(api, options) コンストラクターまたは spring.ai.anthropic.chat.options.* プロパティを使用してデフォルトのオプションを構成できます。

実行時に、新しいリクエスト固有のオプションを Prompt 呼び出しに追加することで、デフォルトのオプションをオーバーライドできます。たとえば、特定のリクエストのデフォルトのモデルと温度をオーバーライドするには、次のようにします。

ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the names of 5 famous pirates.",
        AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-latest")
            .temperature(0.4)
        .build()
    ));
モデル固有の AnthropicChatOptions [GitHub] (英語) に加えて、ChatOptions#builder() [GitHub] (英語) で作成されたポータブル ChatOptions [GitHub] (英語) インスタンスを使用できます。

プロンプトキャッシュ

Anthropic のプロンプトキャッシュ機能 (英語) を使用すると、頻繁に使用されるプロンプトをキャッシュすることで、コストを削減し、繰り返し発生するインタラクションのレスポンス時間を短縮できます。プロンプトをキャッシュすると、後続の同一リクエストでキャッシュされたコンテンツが再利用されるため、処理される入力トークンの数が大幅に削減されます。

対応モデル

プロンプトキャッシュは現在、Claude Sonnet 4.5、Claude Opus 4.5、Claude Haiku 4.5、Claude Opus 4、Claude Sonnet 4、Claude Sonnet 3.7、Claude Sonnet 3.5、Claude Haiku 3.5、Claude Haiku 3、および Claude Opus 3 でサポートされています。

トークン要件

異なるモデルには、キャッシュの有効性に関する最小トークンしきい値が異なります。- Claude Sonnet 4: 1024+ トークン - Claude Haiku モデル: 2048+ トークン - その他のモデル: 1024+ トークン

キャッシュ戦略

Spring AI は、AnthropicCacheStrategy 列挙型を通じて戦略的なキャッシュ配置を提供します。各戦略は、Anthropic の 4 つのブレークポイント制限内で、最適な位置にキャッシュブレークポイントを自動的に配置します。

戦略 使用されたブレークポイント ユースケース

NONE

0

プロンプトキャッシュを完全に無効にします。リクエストが一度限りの場合や、コンテンツが小さすぎてキャッシュのメリットが得られない場合に使用します。

SYSTEM_ONLY

1

システムメッセージの内容をキャッシュします。ツールは、Anthropic の約 20 ブロックの自動ルックバックメカニズムによって暗黙的にキャッシュされます。システムプロンプトが大きく、ツールが 20 個未満で安定している場合に使用します。

TOOLS_ONLY

1

ツール定義のみをキャッシュします。システムメッセージはキャッシュされず、リクエストごとに新しく処理されます。ツール定義が大きく安定している(5000+ トークン)ものの、システムプロンプトが頻繁に変更されるか、テナント / コンテキストごとに異なる場合に使用します。

SYSTEM_AND_TOOLS

2

ツール定義(ブレークポイント 1)とシステムメッセージ(ブレークポイント 2)の両方を明示的にキャッシュします。ツールが 20 個以上(自動ルックバックでは対応しきれない)ある場合、または両方のコンポーネントを確定的にキャッシュしたい場合に使用します。システム変更によってツールキャッシュが無効化されることはありません。

CONVERSATION_HISTORY

1-4

現在のユーザーの質問までの会話履歴全体をキャッシュします。チャットメモリを使用して複数ターンの会話を行う場合、会話履歴が時間の経過とともに増加します。

Anthropic のカスケード無効化により、ツール定義を変更すると、下流のキャッシュブレークポイント(システム、メッセージ)がすべて無効化されます。SYSTEM_AND_TOOLS または CONVERSATION_HISTORY 戦略を使用する場合、ツールの安定性は非常に重要です。

プロンプトキャッシュを有効にする

AnthropicChatOptions に cacheOptions を設定し、strategy を選択してプロンプトキャッシュを有効にします。

システムのみのキャッシュ

最適な用途: 安定したシステムは 20 個未満のツール (自動ルックバックによって暗黙的にキャッシュされたツール) をプロンプトします。

// Cache system message content (tools cached implicitly)
ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are a helpful AI assistant with extensive knowledge..."),
            new UserMessage("What is machine learning?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

ツールのみのキャッシュ

最適な用途: 動的なシステムプロンプト (マルチテナントアプリ、A/B テスト) を備えた大規模で安定したツールセット。

// Cache tool definitions, system prompt processed fresh each time
ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are a " + persona + " assistant..."), // Dynamic per-tenant
            new UserMessage("What's the weather like in San Francisco?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.TOOLS_ONLY)
                .build())
            .toolCallbacks(weatherToolCallback) // Large tool set cached
            .maxTokens(500)
            .build()
    )
);

システムとツールのキャッシュ

最適な用途: 20 以上のツール (自動ルックバックを超える) または両方のコンポーネントを個別にキャッシュする必要がある場合。

// Cache both tool definitions and system message with independent breakpoints
// Changing system won't invalidate tool cache (but changing tools invalidates both)
ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are a weather analysis assistant..."),
            new UserMessage("What's the weather like in San Francisco?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_AND_TOOLS)
                .build())
            .toolCallbacks(weatherToolCallback) // 20+ tools
            .maxTokens(500)
            .build()
    )
);

会話履歴のキャッシュ

// Cache conversation history with ChatClient and memory (cache breakpoint on last user message)
ChatClient chatClient = ChatClient.builder(chatModel)
    .defaultSystem("You are a personalized career counselor...")
    .defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory)
        .conversationId(conversationId)
        .build())
    .build();

String response = chatClient.prompt()
    .user("What career advice would you give me?")
    .options(AnthropicChatOptions.builder()
        .model("claude-sonnet-4")
        .cacheOptions(AnthropicCacheOptions.builder()
            .strategy(AnthropicCacheStrategy.CONVERSATION_HISTORY)
            .build())
        .maxTokens(500)
        .build())
    .call()
    .content();

ChatClient Fluent API の使用

String response = ChatClient.create(chatModel)
    .prompt()
    .system("You are an expert document analyst...")
    .user("Analyze this large document: " + document)
    .options(AnthropicChatOptions.builder()
        .model("claude-sonnet-4")
        .cacheOptions(AnthropicCacheOptions.builder()
            .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
            .build())
        .build())
    .call()
    .content();

高度なキャッシュオプション

メッセージごとの TTL (5 分または 1 時間)

デフォルトでは、キャッシュされたコンテンツは 5 分間の TTL を使用します。特定のメッセージ型には 1 時間の TTL を設定できます。1 時間の TTL を使用すると、Spring AI は必要な Anthropic ベータヘッダーを自動的に設定します。

ChatResponse response = chatModel.call(
    new Prompt(
        List.of(new SystemMessage(largeSystemPrompt)),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .messageTypeTtl(MessageType.SYSTEM, AnthropicCacheTtl.ONE_HOUR)
                .build())
            .maxTokens(500)
            .build()
    )
);
拡張 TTL は Anthropic ベータ機能 extended-cache-ttl-2025-04-11 を使用します。

キャッシュ適格性フィルター

最小コンテンツ長とオプションのトークンベースの長さ関数を設定して、キャッシュブレークポイントが使用されるタイミングを制御します。

AnthropicCacheOptions cache = AnthropicCacheOptions.builder()
    .strategy(AnthropicCacheStrategy.CONVERSATION_HISTORY)
    .messageTypeMinContentLength(MessageType.SYSTEM, 1024)
    .messageTypeMinContentLength(MessageType.USER, 1024)
    .messageTypeMinContentLength(MessageType.ASSISTANT, 1024)
    .contentLengthFunction(text -> MyTokenCounter.count(text))
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        List.of(/* messages */),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(cache)
            .build()
    )
);
SYSTEM_AND_TOOLS 戦略が使用される場合、コンテンツの長さに関係なく、ツール定義は常にキャッシュ対象として考慮されます。

使用例

以下は、コスト追跡を伴うプロンプトキャッシュを示す完全な例です。

// Create system content that will be reused multiple times
String largeSystemPrompt = "You are an expert software architect specializing in distributed systems...";

// First request - creates cache
ChatResponse firstResponse = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(largeSystemPrompt),
            new UserMessage("What is microservices architecture?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

// Access cache-related token usage
AnthropicApi.Usage firstUsage = (AnthropicApi.Usage) firstResponse.getMetadata()
    .getUsage().getNativeUsage();

System.out.println("Cache creation tokens: " + firstUsage.cacheCreationInputTokens());
System.out.println("Cache read tokens: " + firstUsage.cacheReadInputTokens());

// Second request with same system prompt - reads from cache
ChatResponse secondResponse = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(largeSystemPrompt),
            new UserMessage("What are the benefits of event sourcing?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(500)
            .build()
    )
);

AnthropicApi.Usage secondUsage = (AnthropicApi.Usage) secondResponse.getMetadata()
    .getUsage().getNativeUsage();

System.out.println("Cache creation tokens: " + secondUsage.cacheCreationInputTokens()); // Should be 0
System.out.println("Cache read tokens: " + secondUsage.cacheReadInputTokens()); // Should be > 0

トークン使用状況の追跡

Usage レコードは、キャッシュ関連のトークン消費に関する詳細な情報を提供します。Anthropic 固有のキャッシュメトリクスにアクセスするには、getNativeUsage() メソッドを使用します。

AnthropicApi.Usage usage = (AnthropicApi.Usage) response.getMetadata()
    .getUsage().getNativeUsage();

キャッシュ固有のメトリクスには次のものが含まれます。

  • cacheCreationInputTokens(): キャッシュエントリを作成するときに使用されるトークンの数を返します

  • cacheReadInputTokens(): 既存のキャッシュエントリから読み取られたトークンの数を返します

キャッシュされたプロンプトを初めて送信する場合: - cacheCreationInputTokens() は 0 より大きくなります - cacheReadInputTokens() は 0 になります

同じキャッシュされたプロンプトを再度送信すると、次のようになります。- cacheCreationInputTokens() は 0 になります - cacheReadInputTokens() は 0 より大きくなります

実際のユースケース

複数の質問にわたってドキュメントのコンテンツをキャッシュすることで、大規模な法的契約書やコンプライアンスドキュメントを効率的に分析します。

// Load a legal contract (PDF or text)
String legalContract = loadDocument("merger-agreement.pdf"); // ~3000 tokens

// System prompt with legal expertise
String legalSystemPrompt = "You are an expert legal analyst specializing in corporate law. " +
    "Analyze the following contract and provide precise answers about terms, obligations, and risks: " +
    legalContract;

// First analysis - creates cache
ChatResponse riskAnalysis = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(legalSystemPrompt),
            new UserMessage("What are the key termination clauses and associated penalties?")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(1000)
            .build()
    )
);

// Subsequent questions reuse cached document - 90% cost savings
ChatResponse obligationAnalysis = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage(legalSystemPrompt), // Same content - cache hit
            new UserMessage("List all financial obligations and payment schedules.")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .maxTokens(1000)
            .build()
    )
);

バッチコードレビュー

レビューガイドラインをキャッシュしながら、一貫したレビュー条件で複数のコードファイルを処理します。

// Define comprehensive code review guidelines
String reviewGuidelines = """
    You are a senior software engineer conducting code reviews. Apply these criteria:
    - Security vulnerabilities and best practices
    - Performance optimizations and memory usage
    - Code maintainability and readability
    - Testing coverage and edge cases
    - Design patterns and architecture compliance
    """;

List<String> codeFiles = Arrays.asList(
    "UserService.java", "PaymentController.java", "SecurityConfig.java"
);

List<String> reviews = new ArrayList<>();

for (String filename : codeFiles) {
    String sourceCode = loadSourceFile(filename);

    ChatResponse review = chatModel.call(
        new Prompt(
            List.of(
                new SystemMessage(reviewGuidelines), // Cached across all reviews
                new UserMessage("Review this " + filename + " code:\n\n" + sourceCode)
            ),
            AnthropicChatOptions.builder()
                .model("claude-sonnet-4")
                .cacheOptions(AnthropicCacheOptions.builder()
                    .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                    .build())
                .maxTokens(800)
                .build()
        )
    );

    reviews.add(review.getResult().getOutput().getText());
}

// Guidelines cached after first request, subsequent reviews are faster and cheaper

共有ツールを備えたマルチテナント SaaS

ツールは共有されるが、システムプロンプトはテナントごとにカスタマイズされるマルチテナントアプリケーションを構築します。

// Define large shared tool set (used by all tenants)
List<FunctionCallback> sharedTools = Arrays.asList(
    weatherToolCallback,    // ~500 tokens
    calendarToolCallback,   // ~800 tokens
    emailToolCallback,      // ~700 tokens
    analyticsToolCallback,  // ~600 tokens
    reportingToolCallback,  // ~900 tokens
    // ... 20+ more tools, totaling 5000+ tokens
);

@Service
public class MultiTenantAIService {

    public String handleTenantRequest(String tenantId, String userQuery) {
        // Get tenant-specific configuration
        TenantConfig config = tenantRepository.findById(tenantId);

        // Dynamic system prompt per tenant
        String tenantSystemPrompt = String.format("""
            You are %s's AI assistant. Company values: %s.
            Brand voice: %s. Compliance requirements: %s.
            """, config.companyName(), config.values(),
                 config.brandVoice(), config.compliance());

        ChatResponse response = chatModel.call(
            new Prompt(
                List.of(
                    new SystemMessage(tenantSystemPrompt), // Different per tenant, NOT cached
                    new UserMessage(userQuery)
                ),
                AnthropicChatOptions.builder()
                    .model("claude-sonnet-4")
                    .cacheOptions(AnthropicCacheOptions.builder()
                        .strategy(AnthropicCacheStrategy.TOOLS_ONLY) // Cache tools only
                        .build())
                    .toolCallbacks(sharedTools) // Cached once, shared across all tenants
                    .maxTokens(800)
                    .build()
            )
        );

        return response.getResult().getOutput().getText();
    }
}

// Tools cached once (5000 tokens @ 10% = 500 token cost for cache hits)
// Each tenant's unique system prompt processed fresh (200-500 tokens @ 100%)
// Total per request: ~700-1000 tokens vs 5500+ without TOOLS_ONLY

ナレッジベースによるカスタマーサポート

一貫性のある正確なレスポンスを実現するために、製品ナレッジベースをキャッシュする顧客サポートシステムを作成します。

// Load comprehensive product knowledge
String knowledgeBase = """
    PRODUCT DOCUMENTATION:
    - API endpoints and authentication methods
    - Common troubleshooting procedures
    - Billing and subscription details
    - Integration guides and examples
    - Known issues and workarounds
    """ + loadProductDocs(); // ~2500 tokens

@Service
public class CustomerSupportService {

    public String handleCustomerQuery(String customerQuery, String customerId) {
        ChatResponse response = chatModel.call(
            new Prompt(
                List.of(
                    new SystemMessage("You are a helpful customer support agent. " +
                        "Use this knowledge base to provide accurate solutions: " + knowledgeBase),
                    new UserMessage("Customer " + customerId + " asks: " + customerQuery)
                ),
                AnthropicChatOptions.builder()
                    .model("claude-sonnet-4")
                    .cacheOptions(AnthropicCacheOptions.builder()
                        .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                        .build())
                    .maxTokens(600)
                    .build()
            )
        );

        return response.getResult().getOutput().getText();
    }
}

// Knowledge base is cached across all customer queries
// Multiple support agents can benefit from the same cached content

ベストプラクティス

  1. 適切な戦略を選択する :

    • 20 個未満のツールで安定したシステムプロンプトを実行するには、SYSTEM_ONLY を使用します。(自動ルックバックによって暗黙的にキャッシュされたツール)

    • 動的なシステムプロンプトを備えた大規模な安定したツールセット(5000+ トークン)には TOOLS_ONLY を使用します (マルチテナント、A/B テスト)

    • 20 個以上のツールがある場合(自動ルックバックを超える場合)、または両方を個別にキャッシュしたい場合は、SYSTEM_AND_TOOLS を使用します。

    • 複数ターンの会話には CONVERSATION_HISTORY と ChatClient メモリを使用します

    • NONE を使用してキャッシュを明示的に無効にする

  2. カスケード無効化を理解する : Anthropic のキャッシュ階層 (tools → system → messages) は、変更が下方向に流れることを意味します。

    • ツールを変更すると無効になります: ツール + システム + メッセージ(すべてのキャッシュ)❌❌❌

    • システムの変更は無効になる: システム + メッセージ(ツールキャッシュは有効なまま)✅❌❌

    • メッセージを変更すると無効になります: メッセージのみ(ツールとシステムキャッシュは有効なまま)✅✅❌

      **Tool stability is critical** when using `SYSTEM_AND_TOOLS` or `CONVERSATION_HISTORY` strategies.
  3. SYSTEM_AND_TOOLS の独立性 SYSTEM_AND_TOOLS を使用すると、システムメッセージを変更してもツールキャッシュが無効にならないため、システムプロンプトが変化する場合でも、キャッシュされたツールを効率的に再利用できます。

  4. トークン要件を満たす : 最小トークン要件 (Sonnet の場合は 1024+ トークン、Haiku モデルの場合は 4, 2048+) を満たすコンテンツのキャッシュに重点を置きます。

  5. 同一コンテンツの再利用 : キャッシュはプロンプトの内容が完全に一致する場合に最適に機能します。小さな変更でも、新しいキャッシュエントリが必要になります。

  6. トークンの使用状況を監視する : キャッシュ使用統計を使用してキャッシュの有効性を追跡する: java AnthropicApi.Usage usage = (AnthropicApi.Usage) response.getMetadata().getUsage().getNativeUsage(); if (usage != null) { System.out.println("Cache creation: " + usage.cacheCreationInputTokens()); System.out.println("Cache read: " + usage.cacheReadInputTokens()); }

  7. 戦略的なキャッシュ配置 : この実装では、選択した戦略に基づいて最適な場所にキャッシュブレークポイントを自動的に配置し、Anthropic の 4 つのブレークポイント制限に準拠します。

  8. キャッシュの有効期間 : デフォルトの TTL は 5 分です。messageTypeTtl(…​) を使用して、メッセージ型ごとに 1 時間の TTL を設定できます。キャッシュにアクセスするたびにタイマーがリセットされます。

  9. ツールキャッシュの制限 : ツールベースのインタラクションでは、レスポンスにキャッシュ使用メタデータが提供されない場合があることに注意してください。

実装の詳細

Spring AI のプロンプトキャッシュの実装は、次の主要な設計原則に従います。

  1. 戦略的なキャッシュ配置 : キャッシュブレークポイントは、選択された戦略に基づいて最適な場所に自動的に配置され、Anthropic の 4 つのブレークポイント制限に準拠します。

    • CONVERSATION_HISTORY は、ツール(存在する場合)、システムメッセージ、最後のユーザーメッセージにキャッシュブレークポイントを配置します。

    • これにより、Anthropic のプレフィックスマッチングは、増加する会話履歴を段階的にキャッシュできるようになります。

    • 各ターンは前回のキャッシュされたプレフィックスに基づいて構築され、キャッシュの再利用が最大化されます。

  2. プロバイダーのポータビリティ : キャッシュ構成は個別のメッセージではなく AnthropicChatOptions を通じて行われるため、異なる AI プロバイダー間で切り替えるときに互換性が維持されます。

  3. スレッドセーフ : キャッシュブレークポイントトラッキングは、同時リクエストを正しく処理するためのスレッドセーフメカニズムを使用して実装されています。

  4. 自動コンテンツ順序付け : この実装により、Anthropic の API 要件に従って、JSON コンテンツブロックとキャッシュコントロールの適切なオンザワイヤ順序が保証されます。

  5. 総合的な適格性確認 CONVERSATION_HISTORY の場合、実装では、結合されたコンテンツがキャッシュの最小トークンしきい値を満たしているかどうかを判断するときに、最後の約 20 個のコンテンツブロック内のすべてのメッセージ型 (ユーザー、アシスタント、ツール) を考慮します。

将来の機能強化

現在のキャッシュ戦略は、一般的なユースケースの 90% を効果的に処理するように設計されています。よりきめ細かな制御を必要とするアプリケーション向けに、今後以下のような機能強化が予定されています。

  • 細粒度のブレークポイント配置のためのメッセージレベルのキャッシュ制御

  • 個々のメッセージ内のマルチブロックコンテンツキャッシュ

  • 複雑なツールシナリオ向けの高度なキャッシュ境界選択

  • 最適化されたキャッシュ階層のための混合 TTL 戦略

これらの機能強化により、完全な下位互換性が維持され、特殊なユースケース向けに Anthropic の完全なプロンプトキャッシュ機能が利用できるようになります。

考え

Anthropic Claude モデルは、「思考」機能をサポートしており、最終的な答えを出す前にモデルが推論プロセスを示すことができます。この機能により、特に段階的な推論を必要とする複雑な問題において、より透明性が高く詳細な問題解決が可能になります。

対応モデル

思考機能は、次の Claude モデルでサポートされています。

  • Claude 4 モデル (claude-opus-4-20250514claude-sonnet-4-20250514)

  • Claude 3.7 ソネット (claude-3-7-sonnet-20250219)

モデルの機能:

  • Claude 3.7 ソネット : 完全な思考出力を返します。動作は一貫していますが、要約された思考やインターリーブされた思考には対応していません。

  • Claude 4 モデル : 要約思考、インターリーブ思考、強化されたツール統合をサポートします。

API リクエスト構造はサポートされているすべてのモデルで同じですが、出力動作は異なります。

思考構成

サポートされている Claude モデルで思考を有効にするには、リクエストに次の構成を含めます。

必要な構成

  1. thinking オブジェクトを追加する :

    • "type": "enabled"

    • budget_tokens: 推論のためのトークン制限 (1024 から始めることをお勧めします)

  2. トークン予算ルール :

    • budget_tokens は通常 max_tokens より小さくなければなりません

    • Claude は割り当てられたトークンよりも少ないトークンを使用する場合があります

    • 予算が大きいほど推論の深さは増しますが、レイテンシに影響する可能性があります

    • インターリーブ思考でツールの使用を使用する場合 (Claude 4 のみ)、この制約は緩和されますが、Spring AI ではまだサポートされていません。

重要な考慮事項

  • Claude 3.7 は完全な思考内容をレスポンスで返します

  • Claude 4 は、モデルの内部推論の要約版を返すことで、レイテンシを削減し、機密コンテンツを保護します。

  • 出力トークンの一部としての思考トークンは課金可能 (たとえすべての反応が目に見えなくても)

  • インターリーブ思考は Claude 4 モデルでのみ使用可能で、ベータヘッダー interleaved-thinking-2025-05-14 が必要です。

ツールの統合とインターリーブ思考

Claude 4 モデルはツールの使用とインターリーブされた思考をサポートし、モデルがツールの呼び出し間で推論できるようにします。

現在の Spring AI 実装では、基本的な思考とツールの使用が個別にサポートされていますが、ツールの使用とインターリーブされた思考 (複数のツール呼び出しにわたって思考が継続される) はまだサポートされていません。

ツールの使用とインターリーブ思考の詳細については、Anthropic ドキュメント (英語) を参照してください。

非ストリーミングの例

ChatClient API を使用して非ストリーミングリクエストで思考を有効にする方法は次のとおりです。

ChatClient chatClient = ChatClient.create(chatModel);

// For Claude 3.7 Sonnet - explicit thinking configuration required
ChatResponse response = chatClient.prompt()
    .options(AnthropicChatOptions.builder()
        .model("claude-3-7-sonnet-latest")
        .temperature(1.0)  // Temperature should be set to 1 when thinking is enabled
        .maxTokens(8192)
        .thinking(AnthropicApi.ThinkingType.ENABLED, 2048)  // Must be ≥1024 && < max_tokens
        .build())
    .user("Are there an infinite number of prime numbers such that n mod 4 == 3?")
    .call()
    .chatResponse();

// For Claude 4 models - thinking is enabled by default
ChatResponse response4 = chatClient.prompt()
    .options(AnthropicChatOptions.builder()
        .model("claude-opus-4-0")
        .maxTokens(8192)
        // No explicit thinking configuration needed
        .build())
    .user("Are there an infinite number of prime numbers such that n mod 4 == 3?")
    .call()
    .chatResponse();

// Process the response which may contain thinking content
for (Generation generation : response.getResults()) {
    AssistantMessage message = generation.getOutput();
    if (message.getText() != null) {
        // Regular text response
        System.out.println("Text response: " + message.getText());
    }
    else if (message.getMetadata().containsKey("signature")) {
        // Thinking content
        System.out.println("Thinking: " + message.getMetadata().get("thinking"));
        System.out.println("Signature: " + message.getMetadata().get("signature"));
    }
}

ストリーミングの例

ストリーミングレスポンスで思考を使用することもできます。

ChatClient chatClient = ChatClient.create(chatModel);

// For Claude 3.7 Sonnet - explicit thinking configuration
Flux<ChatResponse> responseFlux = chatClient.prompt()
    .options(AnthropicChatOptions.builder()
        .model("claude-3-7-sonnet-latest")
        .temperature(1.0)
        .maxTokens(8192)
        .thinking(AnthropicApi.ThinkingType.ENABLED, 2048)
        .build())
    .user("Are there an infinite number of prime numbers such that n mod 4 == 3?")
    .stream();

// For Claude 4 models - thinking is enabled by default
Flux<ChatResponse> responseFlux4 = chatClient.prompt()
    .options(AnthropicChatOptions.builder()
        .model("claude-opus-4-0")
        .maxTokens(8192)
        // No explicit thinking configuration needed
        .build())
    .user("Are there an infinite number of prime numbers such that n mod 4 == 3?")
    .stream();

// For streaming, you might want to collect just the text responses
String textContent = responseFlux.collectList()
    .block()
    .stream()
    .map(ChatResponse::getResults)
    .flatMap(List::stream)
    .map(Generation::getOutput)
    .map(AssistantMessage::getText)
    .filter(text -> text != null && !text.isBlank())
    .collect(Collectors.joining());

ツール使用の統合

Claude 4 モデルは思考力とツール使用機能を統合します。

  • Claude 3.7 ソネット : 思考とツールの使用の両方をサポートしますが、それらは別々に動作し、より明示的な設定が必要です。

  • Claude 4 モデル : 思考とツールの使用をネイティブにインターリーブし、ツールのインタラクション中に深い推論を提供します。

思考を使うことの利点

思考機能にはいくつかの利点があります。

  1. 透過性 : モデルの推論プロセスと結論に至った経緯を確認する

  2. デバッグ : モデルが論理エラーを起こしている可能性がある場所を特定する

  3. 教育 : 段階的な推論を教材として使う

  4. 複雑な問題の解決 : 数学、論理、推論の課題でより良い結果が得られる

思考を有効にするには、思考プロセス自体が割り当てられたトークンを消費するため、より高いトークン予算が必要になることに注意してください。

ツール / 関数の呼び出し

AnthropicChatModel にカスタム Java ツールを登録し、Anthropic Claude モデルで、登録された関数の 1 つまたは複数を呼び出すための引数を含む JSON オブジェクトをインテリジェントに出力するように選択できます。これは、LLM 機能を外部ツールや API に接続するための強力な手法です。ツール呼び出しの詳細については、こちらを参照してください。

ツールの選択

tool_choice パラメーターを使用すると、モデルが提供ツールをどのように使用するかを制御できます。この機能により、ツールの実行動作をきめ細かく制御できます。

完全な API の詳細については、Anthropic ツール選択ドキュメント (英語) を参照してください。

ツール選択オプション

Spring AI は、AnthropicApi.ToolChoice インターフェースを通じて 4 つのツール選択戦略を提供します。

  • ToolChoiceAuto (default): モデルはツールを使用するかテキストで応答するかを自動的に決定します

  • ToolChoiceAny : モデルは利用可能なツールの少なくとも 1 つを使用する必要があります

  • ToolChoiceTool : モデルは特定のツールを名前で使用しなければならない

  • ToolChoiceNone : モデルはツールを使用できません

並列ツールの使用を無効にする

すべてのツール選択オプション(ToolChoiceNone を除く)は disableParallelToolUse パラメーターをサポートしています。true に設定すると、モデルは最大 1 つのツール使用を出力します。

使用例

自動モード (デフォルトの動作)

ツールを使用するかどうかをモデルに決定させます。

ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather in San Francisco?",
        AnthropicChatOptions.builder()
            .toolChoice(new AnthropicApi.ToolChoiceAuto())
            .toolCallbacks(weatherToolCallback)
            .build()
    )
);
強制ツール使用 (任意)

モデルに少なくとも 1 つのツールの使用を要求します。

ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather?",
        AnthropicChatOptions.builder()
            .toolChoice(new AnthropicApi.ToolChoiceAny())
            .toolCallbacks(weatherToolCallback, calculatorToolCallback)
            .build()
    )
);
強制専用ツール

モデルに特定のツールを名前で使用させる:

ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather in San Francisco?",
        AnthropicChatOptions.builder()
            .toolChoice(new AnthropicApi.ToolChoiceTool("get_weather"))
            .toolCallbacks(weatherToolCallback, calculatorToolCallback)
            .build()
    )
);
ツールの使用を無効にする

モデルがツールを使用できないようにします。

ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather in San Francisco?",
        AnthropicChatOptions.builder()
            .toolChoice(new AnthropicApi.ToolChoiceNone())
            .toolCallbacks(weatherToolCallback)
            .build()
    )
);
並列ツールの使用を無効にする

モデルが一度に 1 つのツールのみを使用するように強制します。

ChatResponse response = chatModel.call(
    new Prompt(
        "What's the weather in San Francisco and what's 2+2?",
        AnthropicChatOptions.builder()
            .toolChoice(new AnthropicApi.ToolChoiceAuto(true)) // disableParallelToolUse = true
            .toolCallbacks(weatherToolCallback, calculatorToolCallback)
            .build()
    )
);

ChatClient API の使用

流れるような ChatClient API を使用してツール選択を使用することもできます。

String response = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather in San Francisco?")
    .options(AnthropicChatOptions.builder()
        .toolChoice(new AnthropicApi.ToolChoiceTool("get_weather"))
        .build())
    .call()
    .content();

ユースケース

  • 検証 ToolChoiceTool を使用して、重要な操作に特定のツールが呼び出されるようにします。

  • 効率 : 不要なテキスト生成を避けるためにツールを使用しなければならないことが分かっている場合は、ToolChoiceAny を使用します。

  • コントロール ToolChoiceNone を使用すると、ツール定義を登録したままツールアクセスを一時的に無効にすることができます。

  • 順次処理 disableParallelToolUse を使用して、依存する操作のツールの連続実行を強制します。

マルチモーダル

マルチモーダル性とは、テキスト、PDF、イメージ、データ形式など、さまざまなソースからの情報を同時に理解して処理するモデルの機能を指します。

イメージ

現在、Anthropic、Claude 3 は、images の base64 ソース型と、image/jpegimage/pngimage/gifimage/webp メディア型をサポートしています。詳細については、ビジョンガイド (英語) を確認してください。Anthropic、Claude 3.5 Sonnet は、application/pdf ファイルの pdf ソース型もサポートしています。

Spring AI の Message インターフェースは、メディア型を導入することでマルチモーダル AI モデルをサポートします。この型には、生のメディアデータに Spring の org.springframework.util.MimeType および java.lang.Object を使用して、メッセージ内のメディア添付ファイルに関するデータと情報が含まれます。

以下は、AnthropicChatModelIT.java [GitHub] (英語) から抽出された簡単なコード例で、ユーザーテキストとイメージの組み合わせを示しています。

var imageData = new ClassPathResource("/multimodal.test.png");

var userMessage = new UserMessage("Explain what do you see on this picture?",
        List.of(new Media(MimeTypeUtils.IMAGE_PNG, this.imageData)));

ChatResponse response = chatModel.call(new Prompt(List.of(this.userMessage)));

logger.info(response.getResult().getOutput().getContent());

入力イメージ multimodal.test.png :

Multimodal Test Image

「この写真に何が写っているか説明してください」というテキストメッセージとともに、次のようなレスポンスが生成されます。

The image shows a close-up view of a wire fruit basket containing several pieces of fruit.
...

PDF

Sonnet 以降では 3.5 と PDF サポート (ベータ) (英語) が提供されています。メッセージに PDF ファイルを添付するには、application/pdf メディア型を使用します。

var pdfData = new ClassPathResource("/spring-ai-reference-overview.pdf");

var userMessage = new UserMessage(
        "You are a very professional document summarization specialist. Please summarize the given document.",
        List.of(new Media(new MimeType("application", "pdf"), pdfData)));

var response = this.chatModel.call(new Prompt(List.of(userMessage)));

引用

Anthropic の引用 API (英語) により、Claude はレスポンスを生成する際に、提供されたドキュメントの特定の部分を参照できます。プロンプトに引用ドキュメントが含まれている場合、Claude はソース資料を引用することができ、引用メタデータ(文字範囲、ページ番号、コンテンツブロック)がレスポンスメタデータに返されます。

引用は次のような改善に役立ちます:

  • 精度検証 : ユーザーは Claude の回答をソース資料と照らし合わせて検証できる

  • 透過性 : 回答の根拠となったドキュメントの正確な部分を確認する

  • 準拠 : 規制対象産業における情報源帰属の要件を満たす

  • 信頼 : 情報の出所を示すことで信頼を築く

対応モデル

引用は、Claude 3.7 Sonnet および Claude 4 モデル (Opus および Sonnet) でサポートされています。

ドキュメントタイプ

3 種類の引用ドキュメントがサポートされています。

  • プレーンテキスト : 文字レベルの引用を含むテキストコンテンツ

  • PDF : ページレベルの引用を含む PDF ドキュメント

  • カスタムコンテンツ : ブロックレベルの引用を含むユーザー定義のコンテンツブロック

引用ドキュメントの作成

CitationDocument ビルダーを使用して、引用可能なドキュメントを作成します。

プレーンテキストドキュメント

CitationDocument document = CitationDocument.builder()
    .plainText("The Eiffel Tower was completed in 1889 in Paris, France. " +
               "It stands 330 meters tall and was designed by Gustave Eiffel.")
    .title("Eiffel Tower Facts")
    .citationsEnabled(true)
    .build();

PDF ドキュメント

// From file path
CitationDocument document = CitationDocument.builder()
    .pdfFile("path/to/document.pdf")
    .title("Technical Specification")
    .citationsEnabled(true)
    .build();

// From byte array
byte[] pdfBytes = loadPdfBytes();
CitationDocument document = CitationDocument.builder()
    .pdf(pdfBytes)
    .title("Product Manual")
    .citationsEnabled(true)
    .build();

カスタムコンテンツブロック

きめ細かな引用制御を行うには、カスタムコンテンツブロックを使用します。

CitationDocument document = CitationDocument.builder()
    .customContent(
        "The Great Wall of China is approximately 21,196 kilometers long.",
        "It was built over many centuries, starting in the 7th century BC.",
        "The wall was constructed to protect Chinese states from invasions."
    )
    .title("Great Wall Facts")
    .citationsEnabled(true)
    .build();

リクエストでの引用の使用

チャットオプションに引用ドキュメントを含めます。

ChatResponse response = chatModel.call(
    new Prompt(
        "When was the Eiffel Tower built and how tall is it?",
        AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-latest")
            .maxTokens(1024)
            .citationDocuments(document)
            .build()
    )
);

複数のドキュメント

Claude が参照できるドキュメントを複数提供できます。

CitationDocument parisDoc = CitationDocument.builder()
    .plainText("Paris is the capital city of France with a population of 2.1 million.")
    .title("Paris Information")
    .citationsEnabled(true)
    .build();

CitationDocument eiffelDoc = CitationDocument.builder()
    .plainText("The Eiffel Tower was designed by Gustave Eiffel for the 1889 World's Fair.")
    .title("Eiffel Tower History")
    .citationsEnabled(true)
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        "What is the capital of France and who designed the Eiffel Tower?",
        AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-latest")
            .citationDocuments(parisDoc, eiffelDoc)
            .build()
    )
);

引用へのアクセス

引用はレスポンスメタデータで返されます。

ChatResponse response = chatModel.call(prompt);

// Get citations from metadata
List<Citation> citations = (List<Citation>) response.getMetadata().get("citations");

// Optional: Get citation count directly from metadata
Integer citationCount = (Integer) response.getMetadata().get("citationCount");
System.out.println("Total citations: " + citationCount);

// Process each citation
for (Citation citation : citations) {
    System.out.println("Document: " + citation.getDocumentTitle());
    System.out.println("Location: " + citation.getLocationDescription());
    System.out.println("Cited text: " + citation.getCitedText());
    System.out.println("Document index: " + citation.getDocumentIndex());
    System.out.println();
}

引用の種類

引用には、ドキュメントの種類に応じて異なる場所の情報が含まれます。

キャラクターの位置 (プレーンテキスト)

プレーンテキストドキュメントの場合、引用には文字インデックスが含まれます。

Citation citation = citations.get(0);
if (citation.getType() == Citation.LocationType.CHAR_LOCATION) {
    int start = citation.getStartCharIndex();
    int end = citation.getEndCharIndex();
    String text = citation.getCitedText();
    System.out.println("Characters " + start + "-" + end + ": " + text);
}

ページの場所 (PDF)

PDF ドキュメントの場合、引用にはページ番号が含まれます。

Citation citation = citations.get(0);
if (citation.getType() == Citation.LocationType.PAGE_LOCATION) {
    int startPage = citation.getStartPageNumber();
    int endPage = citation.getEndPageNumber();
    System.out.println("Pages " + startPage + "-" + endPage);
}

コンテンツブロックの場所 (カスタムコンテンツ)

カスタムコンテンツの場合、引用は特定のコンテンツブロックを参照します。

Citation citation = citations.get(0);
if (citation.getType() == Citation.LocationType.CONTENT_BLOCK_LOCATION) {
    int startBlock = citation.getStartBlockIndex();
    int endBlock = citation.getEndBlockIndex();
    System.out.println("Content blocks " + startBlock + "-" + endBlock);
}

完全な例

引用の使用箇所を示す完全な例を以下に示します。

// Create a citation document
CitationDocument document = CitationDocument.builder()
    .plainText("Spring AI is an application framework for AI engineering. " +
               "It provides a Spring-friendly API for developing AI applications. " +
               "The framework includes abstractions for chat models, embedding models, " +
               "and vector databases.")
    .title("Spring AI Overview")
    .citationsEnabled(true)
    .build();

// Call the model with the document
ChatResponse response = chatModel.call(
    new Prompt(
        "What is Spring AI?",
        AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-latest")
            .maxTokens(1024)
            .citationDocuments(document)
            .build()
    )
);

// Display the response
System.out.println("Response: " + response.getResult().getOutput().getText());
System.out.println("\nCitations:");

// Process citations
List<Citation> citations = (List<Citation>) response.getMetadata().get("citations");

if (citations != null && !citations.isEmpty()) {
    for (int i = 0; i < citations.size(); i++) {
        Citation citation = citations.get(i);
        System.out.println("\n[" + (i + 1) + "] " + citation.getDocumentTitle());
        System.out.println("    Location: " + citation.getLocationDescription());
        System.out.println("    Text: " + citation.getCitedText());
    }
} else {
    System.out.println("No citations were provided in the response.");
}

ベストプラクティス

  1. 説明的なタイトルを使用する : ユーザーが引用内のソースを識別できるように、引用ドキュメントに意味のあるタイトルを付けます。

  2. null 引用をチェックする : すべてのレスポンスに引用が含まれるわけではないため、アクセスする前に引用のメタデータが存在することを必ず検証してください。

  3. ドキュメントサイズを考慮する : ドキュメントが大きいほどコンテキストは多くなりますが、消費される入力トークンも多くなり、レスポンス時間に影響する可能性があります。

  4. 複数のドキュメントを活用する : 複数のソースにまたがる質問に答える場合は、複数回呼び出すのではなく、1 回のリクエストですべての関連ドキュメントを提供してください。

  5. 適切なドキュメント型を使用する : シンプルなコンテンツにはプレーンテキスト、既存のドキュメントには PDF、引用の粒度を細かく制御する必要がある場合はカスタムコンテンツブロックを選択します。

実際のユースケース

ソースの帰属を維持しながら契約書や法的ドキュメントを分析します。

CitationDocument contract = CitationDocument.builder()
    .pdfFile("merger-agreement.pdf")
    .title("Merger Agreement 2024")
    .citationsEnabled(true)
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        "What are the key termination clauses in this contract?",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .maxTokens(2000)
            .citationDocuments(contract)
            .build()
    )
);

// Citations will reference specific pages in the PDF

カスタマーサポートナレッジベース

検証可能なソースを使用して正確な顧客サポート回答を提供します。

CitationDocument kbArticle1 = CitationDocument.builder()
    .plainText(loadKnowledgeBaseArticle("authentication"))
    .title("Authentication Guide")
    .citationsEnabled(true)
    .build();

CitationDocument kbArticle2 = CitationDocument.builder()
    .plainText(loadKnowledgeBaseArticle("billing"))
    .title("Billing FAQ")
    .citationsEnabled(true)
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        "How do I reset my password and update my billing information?",
        AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-latest")
            .citationDocuments(kbArticle1, kbArticle2)
            .build()
    )
);

// Citations show which KB articles were referenced

研究とコンプライアンス

コンプライアンスのためにソースの引用を必要とするレポートを生成します。

CitationDocument clinicalStudy = CitationDocument.builder()
    .pdfFile("clinical-trial-results.pdf")
    .title("Clinical Trial Phase III Results")
    .citationsEnabled(true)
    .build();

CitationDocument regulatoryGuidance = CitationDocument.builder()
    .plainText(loadRegulatoryDocument())
    .title("FDA Guidance Document")
    .citationsEnabled(true)
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        "Summarize the efficacy findings and regulatory implications.",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4")
            .maxTokens(3000)
            .citationDocuments(clinicalStudy, regulatoryGuidance)
            .build()
    )
);

// Citations provide audit trail for compliance

引用ドキュメントオプション

コンテキストフィールド

必要に応じて、引用はされないものの、Claude の理解を手助けするドキュメントのコンテキストを提供します。

CitationDocument document = CitationDocument.builder()
    .plainText("...")
    .title("Legal Contract")
    .context("This is a merger agreement dated January 2024 between Company A and Company B")
    .build();

引用の制御

デフォルトでは、すべてのドキュメントの引用は無効になっています(オプトイン動作)。引用を有効にするには、明示的に citationsEnabled(true) を設定します。

CitationDocument document = CitationDocument.builder()
    .plainText("The Eiffel Tower was completed in 1889...")
    .title("Historical Facts")
    .citationsEnabled(true)  // Explicitly enable citations for this document
    .build();

背景コンテキストについては、引用のないドキュメントを提供することもできます。

CitationDocument backgroundDoc = CitationDocument.builder()
    .plainText("Background information about the industry...")
    .title("Context Document")
    // citationsEnabled defaults to false - Claude will use this but not cite it
    .build();

Anthropic では、リクエスト内のすべてのドキュメントで一貫した引用設定が必要です。引用が有効になっているドキュメントと無効になっているドキュメントを同じリクエストに混在させることはできません。

スキル

Anthropic のスキル API (英語) は、Claude の機能を継承し、ドキュメント生成に特化したパッケージ化された機能を提供します。これらのスキルにより、Claude は、ドキュメントの内容を説明するだけでなく、Excel スプレッドシート、PowerPoint プレゼンテーション、Word ドキュメント、PDF など、ダウンロード可能なファイルを作成できます。

スキルは従来の LLM の根本的な限界を解決します。

  • 伝統的な Claude : 「売上レポートは次のようになります。…」 (テキスト説明のみ)

  • スキルがあれば : ダウンロードして Excel で開くことができる実際の sales_report.xlsx ファイルを作成します

対応モデル

スキルは、Claude Sonnet 4、Claude Sonnet 4.5、Claude Opus 4 以降のモデルでサポートされています。

要件

  • スキルにはコード実行機能が必要 (Spring AI によって自動的に有効化)

  • リクエストごとに最大 8 つのスキル

  • 生成されたファイルは、ファイル API 経由で 24 時間ダウンロードできます。

プリビルド Anthropic スキル

Spring AI は、AnthropicSkill 列挙型を通じて Anthropic の事前構築されたスキルへの型安全なアクセスを提供します。

スキル 説明 生成されたファイルの種類

XLSX

Excel スプレッドシートの生成と操作

.xlsx (Microsoft Excel)

PPTX

PowerPoint プレゼンテーション作成

.pptx (Microsoft PowerPoint)

DOCX

Word ドキュメントの生成

.docx (Microsoft Word)

PDF

PDF ドキュメントの作成

.pdf (Portable Document Format)

Basic Usage

Enable skills by adding them to your AnthropicChatOptions:

ChatResponse response = chatModel.call(
    new Prompt(
        "Create an Excel spreadsheet with Q1 2025 sales data. " +
        "Include columns for Month, Revenue, and Expenses with 3 rows of sample data.",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .maxTokens(4096)
            .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
            .build()
    )
);

// Claude will generate an actual Excel file
String responseText = response.getResult().getOutput().getText();
System.out.println(responseText);
// Output: "I've created an Excel spreadsheet with your Q1 2025 sales data..."

Multiple Skills

You can enable multiple skills in a single request (up to 8):

ChatResponse response = chatModel.call(
    new Prompt(
        "Create a sales report with both an Excel file containing the raw data " +
        "and a PowerPoint presentation summarizing the key findings.",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .maxTokens(8192)
            .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
            .anthropicSkill(AnthropicApi.AnthropicSkill.PPTX)
            .build()
    )
);

Using SkillContainer for Advanced Configuration

For more control, use SkillContainer directly:

AnthropicApi.SkillContainer container = AnthropicApi.SkillContainer.builder()
    .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
    .anthropicSkill(AnthropicApi.AnthropicSkill.PPTX, "20251013") // Specific version
    .build();

ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the quarterly report",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .maxTokens(4096)
            .skillContainer(container)
            .build()
    )
);

Using ChatClient Fluent API

Skills work seamlessly with the ChatClient fluent API:

String response = ChatClient.create(chatModel)
    .prompt()
    .user("Create a PowerPoint presentation about Spring AI with 3 slides: " +
          "Title, Key Features, and Getting Started")
    .options(AnthropicChatOptions.builder()
        .model("claude-sonnet-4-5")
        .maxTokens(4096)
        .anthropicSkill(AnthropicApi.AnthropicSkill.PPTX)
        .build())
    .call()
    .content();

Streaming with Skills

Skills work with streaming responses:

Flux<ChatResponse> responseFlux = chatModel.stream(
    new Prompt(
        "Create a Word document explaining machine learning concepts",
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .maxTokens(4096)
            .anthropicSkill(AnthropicApi.AnthropicSkill.DOCX)
            .build()
    )
);

responseFlux.subscribe(response -> {
    String content = response.getResult().getOutput().getText();
    System.out.print(content);
});

Downloading Generated Files

When Claude generates files using Skills, the response contains file IDs that can be used to download the actual files via the Files API. Spring AI provides the SkillsResponseHelper utility class for extracting file IDs and downloading files.

Extracting File IDs

import org.springframework.ai.anthropic.SkillsResponseHelper;

ChatResponse response = chatModel.call(prompt);

// Extract all file IDs from the response
List<String> fileIds = SkillsResponseHelper.extractFileIds(response);

for (String fileId : fileIds) {
    System.out.println("Generated file ID: " + fileId);
}

Getting File Metadata

Before downloading, you can retrieve file metadata:

@Autowired
private AnthropicApi anthropicApi;

// Get metadata for a specific file
String fileId = fileIds.get(0);
AnthropicApi.FileMetadata metadata = anthropicApi.getFileMetadata(fileId);

System.out.println("Filename: " + metadata.filename());     // e.g., "sales_report.xlsx"
System.out.println("Size: " + metadata.size() + " bytes");  // e.g., 5082
System.out.println("MIME Type: " + metadata.mimeType());    // e.g., "application/vnd..."

Downloading File Content

// Download file content as bytes
byte[] fileContent = anthropicApi.downloadFile(fileId);

// Save to local file system
Path outputPath = Path.of("downloads", metadata.filename());
Files.write(outputPath, fileContent);

System.out.println("Saved file to: " + outputPath);

Convenience Method: Download All Files

The SkillsResponseHelper provides a convenience method to download all generated files at once:

// Download all files to a target directory
Path targetDir = Path.of("generated-files");
Files.createDirectories(targetDir);

List<Path> savedFiles = SkillsResponseHelper.downloadAllFiles(response, anthropicApi, targetDir);

for (Path file : savedFiles) {
    System.out.println("Downloaded: " + file.getFileName() +
                       " (" + Files.size(file) + " bytes)");
}

Complete File Download Example

Here’s a complete example showing Skills usage with file download:

@Service
public class DocumentGenerationService {

    private final AnthropicChatModel chatModel;
    private final AnthropicApi anthropicApi;

    public DocumentGenerationService(AnthropicChatModel chatModel, AnthropicApi anthropicApi) {
        this.chatModel = chatModel;
        this.anthropicApi = anthropicApi;
    }

    public Path generateSalesReport(String quarter, Path outputDir) throws IOException {
        // Generate Excel report using Skills
        ChatResponse response = chatModel.call(
            new Prompt(
                "Create an Excel spreadsheet with " + quarter + " sales data. " +
                "Include Month, Revenue, Expenses, and Profit columns.",
                AnthropicChatOptions.builder()
                    .model("claude-sonnet-4-5")
                    .maxTokens(4096)
                    .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
                    .build()
            )
        );

        // Extract file IDs from the response
        List<String> fileIds = SkillsResponseHelper.extractFileIds(response);

        if (fileIds.isEmpty()) {
            throw new RuntimeException("No file was generated");
        }

        // Download the generated file
        String fileId = fileIds.get(0);
        AnthropicApi.FileMetadata metadata = anthropicApi.getFileMetadata(fileId);
        byte[] content = anthropicApi.downloadFile(fileId);

        // Save to output directory
        Path outputPath = outputDir.resolve(metadata.filename());
        Files.write(outputPath, content);

        return outputPath;
    }
}

Files API Operations

The AnthropicApi provides direct access to the Files API:

Method Description

getFileMetadata(fileId)

ファイル名、サイズ、MIME 型、有効期限などのメタデータを取得します。

downloadFile(fileId)

ファイルの内容をバイト配列としてダウンロードする

listFiles(limit, page)

ページ区切りをサポートするリストファイル

deleteFile(fileId)

ファイルをすぐに削除する (ファイルは 24 時間後に自動的に期限切れになります)

ファイルの一覧表示

// List files with pagination
AnthropicApi.FilesListResponse files = anthropicApi.listFiles(20, null);

for (AnthropicApi.FileMetadata file : files.data()) {
    System.out.println(file.id() + ": " + file.filename());
}

// Check for more pages
if (files.hasMore()) {
    AnthropicApi.FilesListResponse nextPage = anthropicApi.listFiles(20, files.nextPage());
    // Process next page...
}

コンテナー ID の抽出

スキルを使用した複数ターンの会話では、コンテナー ID を抽出する必要がある場合があります。

String containerId = SkillsResponseHelper.extractContainerId(response);

if (containerId != null) {
    System.out.println("Container ID for reuse: " + containerId);
}

ベストプラクティス

  1. 適切なモデルを使用する : スキルは Claude Sonnet 4 以降のモデルで最も効果的に機能します。サポートされているモデルを使用していることをご確認ください。

  2. 十分な最大トークンを設定する : ドキュメント生成には大量のトークンが必要になる場合があります。複雑なドキュメントの場合は、maxTokens(4096) 以上のトークンを使用してください。

  3. プロンプトは具体的に: ドキュメントの構造、コンテンツ、書式設定に関する明確で詳細な指示を提供します。

  4. ファイルのダウンロードを迅速に処理する : 生成されたファイルは 24 時間後に期限切れになります。生成後すぐにファイルをダウンロードしてください。

  5. ファイル ID を確認する : ダウンロードを試みる前に、必ずファイル ID が返されていることを確認してください。一部のプロンプトでは、ファイルが生成されずにテキストレスポンスが表示される場合があります。

  6. 守備的なエラー処理を使用する : ネットワークの課題や期限切れのファイルを適切に処理するには、ファイル操作を try-catch ブロックで囲みます。

List<String> fileIds = SkillsResponseHelper.extractFileIds(response);

if (fileIds.isEmpty()) {
    // Claude may have responded with text instead of generating a file
    String text = response.getResult().getOutput().getText();
    log.warn("No files generated. Response: {}", text);
    return;
}

try {
    byte[] content = anthropicApi.downloadFile(fileIds.get(0));
    // Process file...
} catch (Exception e) {
    log.error("Failed to download file: {}", e.getMessage());
}

実際のユースケース

自動レポート生成

データからフォーマットされたビジネスレポートを生成します。

@Service
public class ReportService {

    private final AnthropicChatModel chatModel;
    private final AnthropicApi anthropicApi;

    public byte[] generateMonthlyReport(SalesData data) throws IOException {
        String prompt = String.format(
            "Create a PowerPoint presentation summarizing monthly sales performance. " +
            "Total Revenue: $%,.2f, Total Expenses: $%,.2f, Net Profit: $%,.2f. " +
            "Include charts and key insights. Create 5 slides: " +
            "1) Title, 2) Revenue Overview, 3) Expense Breakdown, " +
            "4) Profit Analysis, 5) Recommendations.",
            data.revenue(), data.expenses(), data.profit()
        );

        ChatResponse response = chatModel.call(
            new Prompt(prompt,
                AnthropicChatOptions.builder()
                    .model("claude-sonnet-4-5")
                    .maxTokens(8192)
                    .anthropicSkill(AnthropicApi.AnthropicSkill.PPTX)
                    .build()
            )
        );

        List<String> fileIds = SkillsResponseHelper.extractFileIds(response);
        return anthropicApi.downloadFile(fileIds.get(0));
    }
}

データエクスポートサービス

構造化データを Excel 形式にエクスポートします。

@RestController
public class ExportController {

    private final AnthropicChatModel chatModel;
    private final AnthropicApi anthropicApi;
    private final CustomerRepository customerRepository;

    @GetMapping("/export/customers")
    public ResponseEntity<byte[]> exportCustomers() throws IOException {
        List<Customer> customers = customerRepository.findAll();

        String dataDescription = customers.stream()
            .map(c -> String.format("%s, %s, %s", c.name(), c.email(), c.tier()))
            .collect(Collectors.joining("\n"));

        ChatResponse response = chatModel.call(
            new Prompt(
                "Create an Excel spreadsheet with customer data. " +
                "Columns: Name, Email, Tier. Format the header row with bold text. " +
                "Data:\n" + dataDescription,
                AnthropicChatOptions.builder()
                    .model("claude-sonnet-4-5")
                    .maxTokens(4096)
                    .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
                    .build()
            )
        );

        List<String> fileIds = SkillsResponseHelper.extractFileIds(response);
        byte[] content = anthropicApi.downloadFile(fileIds.get(0));
        AnthropicApi.FileMetadata metadata = anthropicApi.getFileMetadata(fileIds.get(0));

        return ResponseEntity.ok()
            .header(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename=\"" + metadata.filename() + "\"")
            .contentType(MediaType.parseMediaType(metadata.mimeType()))
            .body(content);
    }
}

マルチフォーマットドキュメント生成

単一のリクエストから複数のドキュメント形式を生成します。

public Map<String, byte[]> generateProjectDocumentation(ProjectInfo project) throws IOException {
    ChatResponse response = chatModel.call(
        new Prompt(
            "Create project documentation for: " + project.name() + "\n" +
            "Description: " + project.description() + "\n\n" +
            "Generate:\n" +
            "1. An Excel file with the project timeline and milestones\n" +
            "2. A PowerPoint overview presentation (3-5 slides)\n" +
            "3. A Word document with detailed specifications",
            AnthropicChatOptions.builder()
                .model("claude-sonnet-4-5")
                .maxTokens(16384)
                .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
                .anthropicSkill(AnthropicApi.AnthropicSkill.PPTX)
                .anthropicSkill(AnthropicApi.AnthropicSkill.DOCX)
                .build()
        )
    );

    Map<String, byte[]> documents = new HashMap<>();
    List<String> fileIds = SkillsResponseHelper.extractFileIds(response);

    for (String fileId : fileIds) {
        AnthropicApi.FileMetadata metadata = anthropicApi.getFileMetadata(fileId);
        byte[] content = anthropicApi.downloadFile(fileId);
        documents.put(metadata.filename(), content);
    }

    return documents;
}

スキルと他の機能を組み合わせる

スキルは、プロンプトキャッシュなどの他の Anthropic 機能と組み合わせることができます。

ChatResponse response = chatModel.call(
    new Prompt(
        List.of(
            new SystemMessage("You are an expert data analyst and document creator..."),
            new UserMessage("Create a financial summary spreadsheet")
        ),
        AnthropicChatOptions.builder()
            .model("claude-sonnet-4-5")
            .maxTokens(4096)
            .anthropicSkill(AnthropicApi.AnthropicSkill.XLSX)
            .cacheOptions(AnthropicCacheOptions.builder()
                .strategy(AnthropicCacheStrategy.SYSTEM_ONLY)
                .build())
            .build()
    )
);

カスタムスキルについて

上記の構築済みスキルに加えて、Anthropic は、特殊なドキュメントテンプレート、書式設定ルール、ドメイン固有の動作用に組織が作成できるカスタムスキルをサポートしています。

重要 : カスタムスキルを使用するには、Anthropic のプラットフォーム(コンソールまたは API)を通じて作成およびアップロードする必要があります。Spring AI は現在、カスタムスキルの設定後は使用をサポートしていますが、カスタムスキルの作成または管理用の API は提供していません。

Anthropic ワークスペースでカスタムスキルが設定されている場合は、スキル ID で参照できます。

AnthropicApi.SkillContainer container = AnthropicApi.SkillContainer.builder()
    .customSkill("skill_abc123") // Your custom skill ID from Anthropic
    .build();

ワークスペースでカスタムスキルを作成および管理する方法の詳細については、Anthropic スキル API ドキュメント (英語) を参照してください。

サンプルコントローラー

新しい Spring Boot プロジェクトを作成し、spring-ai-starter-model-anthropic を pom (または gradle) の依存関係に追加します。

src/main/resources ディレクトリに application.properties ファイルを追加して、Anthropic チャットモデルを有効にして構成します。

spring.ai.anthropic.api-key=YOUR_API_KEY
spring.ai.anthropic.chat.options.model=claude-3-5-sonnet-latest
spring.ai.anthropic.chat.options.temperature=0.7
spring.ai.anthropic.chat.options.max-tokens=450
api-key を Anthropic の資格情報に置き換えます。

これにより、クラスに挿入できる AnthropicChatModel 実装が作成されます。以下は、テキスト生成にチャットモデルを使用する単純な @Controller クラスの例です。

@RestController
public class ChatController {

    private final AnthropicChatModel chatModel;

    @Autowired
    public ChatController(AnthropicChatModel chatModel) {
        this.chatModel = chatModel;
    }

    @GetMapping("/ai/generate")
    public Map generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        return Map.of("generation", this.chatModel.call(message));
    }

    @GetMapping("/ai/generateStream")
	public Flux<ChatResponse> generateStream(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
        Prompt prompt = new Prompt(new UserMessage(message));
        return this.chatModel.stream(prompt);
    }
}

手動構成

AnthropicChatModel [GitHub] (英語) は ChatModel と StreamingChatModel を実装し、低レベル AnthropicApi クライアントを使用して Anthropic サービスに接続します。

spring-ai-anthropic 依存関係をプロジェクトの Maven pom.xml ファイルに追加します。

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-anthropic</artifactId>
</dependency>

または、Gradle build.gradle ビルドファイルに保存します。

dependencies {
    implementation 'org.springframework.ai:spring-ai-anthropic'
}
Spring AI BOM をビルドファイルに追加するには、"依存関係管理" セクションを参照してください。

次に、AnthropicChatModel を作成し、テキスト生成に使用します。

var anthropicApi = new AnthropicApi(System.getenv("ANTHROPIC_API_KEY"));
var anthropicChatOptions = AnthropicChatOptions.builder()
            .model("claude-3-7-sonnet-20250219")
            .temperature(0.4)
            .maxTokens(200)
        .build()
var chatModel = AnthropicChatModel.builder().anthropicApi(anthropicApi)
                .defaultOptions(anthropicChatOptions).build();

ChatResponse response = this.chatModel.call(
    new Prompt("Generate the names of 5 famous pirates."));

// Or with streaming responses
Flux<ChatResponse> response = this.chatModel.stream(
    new Prompt("Generate the names of 5 famous pirates."));

AnthropicChatOptions は、チャットリクエストの構成情報を提供します。AnthropicChatOptions.Builder は流れるようなオプションビルダーです。

低レベル AnthropicApi クライアント

AnthropicApi [GitHub] (英語) が提供するのは、Anthropic メッセージ API (英語) 用の軽量 Java クライアントです。

次のクラス図は、AnthropicApi チャットインターフェースと構成要素を示しています。

AnthropicApi Chat API Diagram
AnthropicApi Event Model

API をプログラムで使用する方法の簡単なスニペットを次に示します。

AnthropicApi anthropicApi =
    new AnthropicApi(System.getenv("ANTHROPIC_API_KEY"));

AnthropicMessage chatCompletionMessage = new AnthropicMessage(
        List.of(new ContentBlock("Tell me a Joke?")), Role.USER);

// Sync request
ResponseEntity<ChatCompletionResponse> response = this.anthropicApi
    .chatCompletionEntity(new ChatCompletionRequest(AnthropicApi.ChatModel.CLAUDE_3_OPUS.getValue(),
            List.of(this.chatCompletionMessage), null, 100, 0.8, false));

// Streaming request
Flux<StreamResponse> response = this.anthropicApi
    .chatCompletionStream(new ChatCompletionRequest(AnthropicApi.ChatModel.CLAUDE_3_OPUS.getValue(),
            List.of(this.chatCompletionMessage), null, 100, 0.8, true));

詳細については、AnthropicApi.java [GitHub] (英語) の JavaDoc を参照してください。

低レベル API の例