DeepSeek チャット

Spring AI は、DeepSeek のさまざまな AI 言語モデルをサポートしています。DeepSeek 言語モデルと対話し、DeepSeek モデルに基づいて多言語会話アシスタントを作成できます。

前提条件

DeepSeek 言語モデルにアクセスするには、DeepSeek で API キーを作成する必要があります。

DeepSeek 登録ページ (英語) でアカウントを作成し、API キーページ (英語) でトークンを生成します。

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

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

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

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

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

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

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

リポジトリと BOM の追加

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

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

自動構成

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

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-deepseek</artifactId>
</dependency>

または、Gradle build.gradle ファイルに追加します。

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

チャットのプロパティ

再試行プロパティ

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

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

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

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

false

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

再試行をトリガーすべきではない HTTP ステータスコードのリスト (NonTransientAiException をスローするなど)。

spring.ai.retry.on-http-codes

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

接続プロパティ

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

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

spring.ai.deepseek.base-url

接続先の URL

https://api.deepseek.com

spring.ai.deepseek.api-key

API キー

-

プロパティの構成

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

有効にするには、spring.ai.model.chat=deepseek を設定します。(デフォルトで有効になっています)

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

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

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

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

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

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

true

spring.ai.model.chat

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

ディープシーク

spring.ai.deepseek.chat.base-url

オプションで spring.ai.deepseek.base-url をオーバーライドして、チャット固有の URL を提供します。

https://api.deepseek.com/

spring.ai.deepseek.chat.api-key

オプションで spring.ai.deepseek.api-key をオーバーライドして、チャット固有の API キーを提供します

-

spring.ai.deepseek.chat.completions-path

チャット補完エンドポイントへのパス

/chat/completions

spring.ai.deepseek.chat.beta-prefix-path

ベータ関数エンドポイントへのプレフィックスパス

/beta

spring.ai.deepseek.chat.model

使用するモデルの ID。deepseek-v4-flash、deepseek-v4-pro、deepseek-chat、deepseek-reasoner を使用できます。

deepseek-v4-flash

spring.ai.deepseek.chat.frequency-penalty

-2.0 から 2.0 までの数値。正の値を指定すると、これまでのテキスト内の既存の頻度に基づいて新しいトークンにペナルティが課され、モデルが同じ行をそのまま繰り返す可能性が低くなります。

0.0f

spring.ai.deepseek.chat.max-tokens

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

-

spring.ai.deepseek.chat.presence-penalty

-2.0 から 2.0 までの数値。正の値を指定すると、これまでにテキストに出現したかどうかに基づいて新しいトークンにペナルティが課され、モデルが新しいトピックについて話す可能性が高まります。

0.0f

spring.ai.deepseek.chat.stop

API がさらなるトークンの生成を停止する最大 4 つのシーケンス。

-

spring.ai.deepseek.chat.temperature

使用するサンプリング温度(0 ~ 2)を指定します。0.8 のような高い値を指定すると出力はよりランダムになり、0.2 のような低い値を指定すると出力はより集中的かつ決定論的になります。通常は、この値か top_p のいずれか一方を変更することを推奨しますが、両方を変更することは推奨しません。

1.0F

spring.ai.deepseek.chat.top-p

温度によるサンプリングの代わりに、核サンプリングと呼ばれる手法があります。この手法では、モデルは top_p の確率質量を持つトークンの結果を考慮します。つまり、0.1 は、上位 10% の確率質量を構成するトークンのみを考慮することを意味します。通常は、この方法か温度のいずれか一方を変更することを推奨しますが、両方を変更することは推奨しません。

1.0F

spring.ai.deepseek.chat.logprobs

出力トークンの対数確率を返すかどうか。true の場合、メッセージの内容で返される各出力トークンの対数確率を返します。

-

spring.ai.deepseek.chat.top-logprobs

各トークン位置で返される可能性が最も高いトークンの数を指定する 0 から 20 までの整数。各トークンには、関連付けられた対数確率があります。このパラメーターを使用する場合は、logprobs を true に設定する必要があります。

-

spring.ai.deepseek.chat.tool-callbacks

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

-

ChatModel 実装では、共通の spring.ai.deepseek.base-url および spring.ai.deepseek.api-key プロパティをオーバーライドできます。spring.ai.deepseek.chat.base-url および spring.ai.deepseek.chat.api-key プロパティが設定されている場合は、共通プロパティよりも優先されます。これは、異なるモデルや異なるモデルエンドポイントに異なる DeepSeek アカウントを使用する場合に便利です。
spring.ai.deepseek.chat で始まるすべてのプロパティは、リクエスト固有のランタイムオプションを Prompt 呼び出しに追加することによって実行時にオーバーライドできます。

ランタイムオプション

DeepSeekChatOptions.java [GitHub] (英語) は、使用するモデル、温度、周波数ペナルティなどのモデル構成を提供します。

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

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

ChatResponse response = chatModel.call(
    new Prompt(
        "Generate the names of 5 famous pirates. Please provide the JSON response without any code block markers such as ```json```.",
        DeepSeekChatOptions.builder()
            .withModel(DeepSeekApi.ChatModel.DEEPSEEK_V4_PRO.getValue())
            .withTemperature(0.8f)
        .build()
    ));
モデル固有の DeepSeekChatOptions [GitHub] (英語) に加えて、ChatOptions#builder() [GitHub] (英語) で作成されたポータブル ChatOptions [GitHub] (英語) インスタンスも使用できます。

サンプルコントローラー (自動構成)

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

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

spring.ai.deepseek.api-key=YOUR_API_KEY
spring.ai.deepseek.chat.model=deepseek-v4-pro
spring.ai.deepseek.chat.temperature=0.8
api-key を DeepSeek の資格情報に置き換えます。

これにより、クラスに注入できる DeepSeekChatModel 実装が作成されます。以下は、チャットモデルを使用してテキストを生成するシンプルな @Controller クラスの例です。

@RestController
public class ChatController {

    private final DeepSeekChatModel chatModel;

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

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

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

ツール呼び出し

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

DeepSeekChatModel はツール呼び出しを内部的に実行しません。ツール実行は、サポートされている 2 つの方法のいずれかを使用して外部で処理する必要があります。

  • ChatClient と ToolCallingAdvisor — ほとんどのユースケースにおいて推奨されるアプローチです。ToolCallingAdvisor はツールが存在する場合に自動的に登録され、ツール呼び出しループを透過的に管理します。

  • ユーザー制御によるツール実行 — ループを完全に制御する必要がある場合(たとえば、ツール呼び出しと ChatModel への直接アクセスを組み合わせる場合など)は、DefaultToolCallingManager を直接使用してください。

同期ツール実行とストリーミングツール実行の両方に ChatClient を使用します。ツールが存在する場合、ToolCallingAdvisor は自動的に登録されるため、アドバイザーの明示的な設定は不要です。

ToolCallback weatherCallback = FunctionToolCallback.builder("getCurrentWeather", new WeatherService())
    .description("Get the weather in location")
    .inputType(WeatherService.Request.class)
    .build();

// Synchronous
String response = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather in Paris, Tokyo, and New York?")
    .tools(weatherCallback)
    .call()
    .content();

// Streaming
Flux<String> stream = ChatClient.create(chatModel)
    .prompt()
    .user("What's the weather in Paris, Tokyo, and New York?")
    .tools(weatherCallback)
    .stream()
    .content();

ユーザー制御ツールの実行

ChatModel API に直接アクセスする必要があり、ツール呼び出しループを完全に制御したい場合は、このパターンを使用してください。ToolCallingAdvisor を使用せずに ChatModel を直接呼び出し、ツール呼び出しを自分でチェックし、ToolCallingManager を使用してループを駆動します。

ToolCallingManager toolCallingManager = ToolCallingManager.builder().build();

DeepSeekChatOptions options = DeepSeekChatOptions.builder()
    .toolCallbacks(ToolCallbacks.from(new WeatherService()))
    .build();

Prompt prompt = new Prompt("What's the weather in Paris, Tokyo, and New York?", options);
ChatResponse response = chatModel.call(prompt);

while (response.hasToolCalls()) {
    ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, response);
    prompt = new Prompt(result.conversationHistory(), options);
    response = chatModel.call(prompt);
}

ストリーミングの場合、各ストリーミングレスポンスを MessageAggregator で集約して、チャンクをまたいだツール呼び出しを検出します。

AtomicReference<ChatResponse> aggregatedRef = new AtomicReference<>();
new MessageAggregator()
    .aggregate(chatModel.stream(prompt), aggregatedRef::set)
    .collectList().block();

while (aggregatedRef.get().hasToolCalls()) {
    ToolExecutionResult result = toolCallingManager.executeToolCalls(prompt, aggregatedRef.get());
    prompt = new Prompt(result.conversationHistory(), options);
    aggregatedRef.set(null);
    new MessageAggregator()
        .aggregate(chatModel.stream(prompt), aggregatedRef::set)
        .collectList().block();
}

String content = aggregatedRef.get().getResult().getOutput().getText();

チャットプレフィックス補完

チャットプレフィックスの補完は Chat Completion API に準拠しており、ユーザーがアシスタントのプレフィックスメッセージを提供すると、モデルがメッセージの残りを補完します。

プレフィックス補完を使用する場合、ユーザーはメッセージリスト内の最後のメッセージが DeepSeekAssistantMessage であることを確認する必要があります。

以下は、チャットプレフィックス補完の完全な Java コード例です。この例では、モデルによる追加の説明を防ぐために、アシスタントのプレフィックスメッセージを「```python\n" to force the model to output Python code, and set the stop parameter to [‘` ’ ]」に設定しています。

@RestController
public class CodeGenerateController {

    private final DeepSeekChatModel chatModel;

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

    @GetMapping("/ai/generatePythonCode")
    public String generate(@RequestParam(value = "message", defaultValue = "Please write quick sort code") String message) {
		UserMessage userMessage = new UserMessage(message);
		Message assistantMessage = DeepSeekAssistantMessage.builder().content("```python\\n").prefix(true).build();
		Prompt prompt = new Prompt(List.of(userMessage, assistantMessage), ChatOptions.builder().stopSequences(List.of("```")).build());
		ChatResponse response = chatModel.call(prompt);
		return response.getResult().getOutput().getText();
    }
}

推論支援

DeepSeekAssistantMessage を使用すると、その機能をサポートするモデルによって生成された CoT コンテンツを取得できます。

public void deepSeekReasoningExample() {
    DeepSeekChatOptions promptOptions = DeepSeekChatOptions.builder()
            .build();
    Prompt prompt = new Prompt("9.11 and 9.8, which is greater?", promptOptions);
    ChatResponse response = chatModel.call(prompt);

    // Get the CoT content generated by the model
    DeepSeekAssistantMessage deepSeekAssistantMessage = (DeepSeekAssistantMessage) response.getResult().getOutput();
    String reasoningContent = deepSeekAssistantMessage.getReasoningContent();
    String text = deepSeekAssistantMessage.getText();
}

推論モデル複数ラウンドの会話

会話の各ラウンドで、モデルは CoT(reasoning_content)と最終回答(content)を出力します。次の会話ラウンドでは、前のラウンドの CoT はコンテキストに連結されません。これは次の図に示されています。

Multimodal Test Image

手動構成

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

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

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

または、Gradle build.gradle ファイルに追加します。

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

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

DeepSeekApi deepSeekApi = DeepSeekApi.builder()
        .apiKey(System.getenv("DEEPSEEK_API_KEY"))
        .build();
DeepSeekChatOptions options = DeepSeekChatOptions.builder()
        .model(DeepSeekApi.ChatModel.DEEPSEEK_V4_PRO.getValue())
        .temperature(0.4)
        .maxTokens(200)
        .build();
DeepSeekChatModel chatModel = DeepSeekChatModel.builder()
        .deepSeekApi(deepSeekApi)
        .options(options)
        .build();
ChatResponse response = chatModel.call(
    new Prompt("Generate the names of 5 famous pirates."));

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

DeepSeekChatOptions はチャットリクエストの設定情報を提供します。DeepSeekChatOptions.Builder は柔軟なオプションビルダーです。

低レベル DeepSeekApi クライアント

DeepSeekApi [GitHub] (英語) は、DeepSeek API (英語) 用の軽量 Java クライアントです。

以下は、API をプログラムで使用する方法を示す簡単なスニペットです。

DeepSeekApi deepSeekApi =
    new DeepSeekApi(System.getenv("DEEPSEEK_API_KEY"));

ChatCompletionMessage chatCompletionMessage =
    new ChatCompletionMessage("Hello world", Role.USER);

// Sync request
ResponseEntity<ChatCompletion> response = deepSeekApi.chatCompletionEntity(
    new ChatCompletionRequest(List.of(chatCompletionMessage), DeepSeekApi.ChatModel.DEEPSEEK_V4_FLASH.getValue(), 0.7, false));

// Streaming request
Flux<ChatCompletionChunk> streamResponse = deepSeekApi.chatCompletionStream(
    new ChatCompletionRequest(List.of(chatCompletionMessage), DeepSeekApi.ChatModel.DEEPSEEK_V4_FLASH.getValue(), 0.7, true));

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

DeepSeekApi サンプル