在这里插入图片描述

Pre

大模型开发 - 01 Spring AI 核心特性一览

大模型开发 - 02 Spring AI Concepts

大模型开发 - 03 QuickStart_借助DeepSeekChatModel实现Spring AI 集成 DeepSeek

概述

在构建基于大语言模型(LLM)的 AI 应用时,Spring AI 提供了一套简洁而强大的抽象层,使得开发者可以轻松集成各类模型服务(如 DeepSeek、OpenAI、Anthropic 等)。本文将深入剖析 Spring AI 中调用 DeepSeek 模型的完整调用链路,帮助你理解从一句简单的 chatModel.call("Hello") 到实际发起远程 HTTP 请求的全过程。


一、入口:ChatModel.call(String message)

       /**
     * 测试DeepSeek聊天模型的功能
     *
     * @param deepSeekChatModel 自动注入的DeepSeek聊天模型实例,用于执行聊天调用
     */
    @Test
    public void testDeepSeek(@Autowired DeepSeekChatModel deepSeekChatModel){
        // 调用聊天模型并获取响应内容
        String content = deepSeekChatModel.call("你好");
        System.out.println(content);
    }

Spring AI 的 ChatModel 接口定义了一个默认方法:

default String call(String message) {
    Prompt prompt = new Prompt(new UserMessage(message));
    Generation generation = call(prompt).getResult();
    return (generation != null) ? generation.getOutput().getText() : "";
}

这个方法是开发者最常用的入口。它做了三件事:

  1. 将原始字符串消息封装为 Prompt 对象
    Prompt 是 Spring AI 中表示“提示词”的核心数据结构,内部包含一个或多个 Message(如 UserMessageSystemMessageAiMessage 等),用于构建对话上下文。

  2. 调用重载的 call(Prompt) 方法
    该方法由具体实现类(如 DeepSeekChatModel)提供,返回一个 ChatResponse

  3. 提取生成结果并返回纯文本
    从响应中取出第一个 Generation 的输出文本,若为空则返回空字符串。

关键点Prompt 是连接用户输入与模型 API 的桥梁,它将自然语言消息结构化为模型可理解的格式。


二、模型实现层:DeepSeekChatModel.internalCall

当调用 DeepSeekChatModel.call(Prompt) 时,实际执行的是其内部方法 internalCall

(省略部分无关代码)

public ChatResponse internalCall(Prompt prompt, ChatResponse previousChatResponse) {
    // a. 构建远程请求对象
    ChatCompletionRequest request = createRequest(prompt, false);

    // b. 通过 Spring Retry 发起带重试的远程调用
    ResponseEntity<ChatCompletion> completionEntity = this.retryTemplate
        .execute(ctx -> this.deepSeekApi.chatCompletionEntity(request));

    // c. 封装响应并返回
    var chatCompletion = completionEntity.getBody();
    ChatResponse chatResponse = new ChatResponse(generations, from(chatCompletion, accumulatedUsage));
    observationContext.setResponse(chatResponse);
    return chatResponse;
}

这个方法是整个调用流程的核心,可分为三个关键步骤:

步骤 a:createRequest —— 构建 API 请求体

在这里插入图片描述

createRequest(prompt, false) 将 Spring AI 的 Prompt 对象转换为 DeepSeek API 所需的 ChatCompletionRequest。该请求体通常包含:

  • model:指定使用的模型(如 deepseek-coder
  • messages:从 Prompt 中提取的 Message 列表,转换为 DeepSeek 兼容的格式(如 {"role": "user", "content": "..."}
  • temperaturemax_tokens 等可选参数

设计亮点:通过适配器模式,Spring AI 屏蔽了不同模型 API 的差异,开发者只需关注统一的 Prompt 结构。

步骤 b:retryTemplate.execute(...) —— 安全可靠的远程调用

Spring AI 利用 Spring Retry 模板封装了网络调用,确保在临时故障(如网络抖动、限流)时自动重试:

this.retryTemplate.execute(ctx -> this.deepSeekApi.chatCompletionEntity(request));

这行代码背后是健壮的容错机制,极大提升了生产环境的稳定性。

步骤 c:deepSeekApi.chatCompletionEntity —— 实际 HTTP 请求

DeepSeekApi 是一个基于 Spring 的 RestClient 封装的客户端:

public ResponseEntity<ChatCompletion> chatCompletionEntity(ChatCompletionRequest chatRequest) {
    return this.restClient.post()
        .uri(this.getEndpoint(chatRequest))  // 如 https://api.deepseek.com/chat/completions
        .body(chatRequest)
        .retrieve()
        .toEntity(ChatCompletion.class);
}

这里使用了现代、声明式的 RestClient(Spring 6+ 推荐),相比传统的 RestTemplate 更简洁、类型安全。


三、响应处理与返回

远程调用成功后,API 返回的 JSON 被反序列化为 ChatCompletion 对象。Spring AI 会:

  1. 从响应中提取生成的文本(通常在 choices[0].message.content
  2. 封装为 Generation 对象
  3. 构建 ChatResponse,包含:
    • 生成结果列表(List<Generation>
    • Token 使用统计(Usage
  4. 设置到 ObservationContext(用于指标监控、链路追踪等)

最终,call(Prompt) 返回 ChatResponse,而最外层的 call(String) 则提取纯文本返回给用户。


四、整体调用链路图

User Code
    │
    ▼
chatModel.call("Hello")
    │
    ▼
new Prompt(new UserMessage("Hello"))
    │
    ▼
DeepSeekChatModel.call(Prompt)
    │
    ▼
internalCall(Prompt, null)
    │
    ├── createRequest()ChatCompletionRequest
    │
    ├── retryTemplate.execute()
    │       │
    │       ▼
    │   deepSeekApi.chatCompletionEntity()
    │       │
    │       ▼
    │   RestClient POST → DeepSeek API
    │
    ▼
Parse ChatCompletionChatResponse
    │
    ▼
return "Hello! How can I help you?"

五、总结

  1. 抽象统一:Spring AI 通过 Prompt/ChatModel/Generation 等抽象,实现了“一次编写,多模型切换”的能力。
  2. 生产就绪:内置重试、可观测性(Observation)、错误处理,适合企业级应用。
  3. 扩展性强:开发者可自定义 PromptTemplateMessageFormatter、甚至替换底层 RestClient

理解这一调用流程,不仅能帮助你更好地调试和优化 AI 应用,也为后续集成其他模型(如通义千问、Moonshot)打下坚实基础。

建议:在实际项目中,可结合 ObservationRegistry 和 Micrometer 实现对 LLM 调用的耗时、Token 消耗、错误率等指标的监控。


参考

在这里插入图片描述

Logo

更多推荐