大模型开发 - 04 QuickStart_DeepSeek 模型调用流程源码解析:从 Prompt 到远程请求
文章目录
- Pre
- 概述
- 一、入口:`ChatModel.call(String message)`
- 二、模型实现层:`DeepSeekChatModel.internalCall`
- 步骤 a:`createRequest` —— 构建 API 请求体
- 步骤 b:`retryTemplate.execute(...)` —— 安全可靠的远程调用
- 步骤 c:`deepSeekApi.chatCompletionEntity` —— 实际 HTTP 请求
- 三、响应处理与返回
- 四、整体调用链路图
- 五、总结
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聊天模型实例,用于执行聊天调用*/@Testpublic 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() : "";
}
这个方法是开发者最常用的入口。它做了三件事:
-
将原始字符串消息封装为
Prompt
对象
Prompt
是 Spring AI 中表示“提示词”的核心数据结构,内部包含一个或多个Message
(如UserMessage
、SystemMessage
、AiMessage
等),用于构建对话上下文。 -
调用重载的
call(Prompt)
方法
该方法由具体实现类(如DeepSeekChatModel
)提供,返回一个ChatResponse
。 -
提取生成结果并返回纯文本
从响应中取出第一个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": "..."}
)temperature
、max_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 会:
- 从响应中提取生成的文本(通常在
choices[0].message.content
) - 封装为
Generation
对象 - 构建
ChatResponse
,包含:- 生成结果列表(
List<Generation>
) - Token 使用统计(
Usage
)
- 生成结果列表(
- 设置到
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 ChatCompletion → ChatResponse│▼
return "Hello! How can I help you?"
五、总结
- 抽象统一:Spring AI 通过
Prompt
/ChatModel
/Generation
等抽象,实现了“一次编写,多模型切换”的能力。 - 生产就绪:内置重试、可观测性(Observation)、错误处理,适合企业级应用。
- 扩展性强:开发者可自定义
PromptTemplate
、MessageFormatter
、甚至替换底层RestClient
。
理解这一调用流程,不仅能帮助你更好地调试和优化 AI 应用,也为后续集成其他模型(如通义千问、Moonshot)打下坚实基础。
建议:在实际项目中,可结合
ObservationRegistry
和 Micrometer 实现对 LLM 调用的耗时、Token 消耗、错误率等指标的监控。
参考:
- Spring AI 官方文档:https://docs.spring.io/spring-ai/reference/
- DeepSeek API 文档:https://platform.deepseek.com/api-docs/