大模型开发 - 04 QuickStart_DeepSeek 模型调用流程源码解析:从 Prompt 到远程请求
本文深入解析了Spring AI框架调用DeepSeek大语言模型的完整流程。从最简入口chatModel.call("Hello")开始,通过封装Prompt对象、构建API请求体,最终通过RestClient发起远程调用。文章重点剖析了三个核心环节:(1)Prompt消息结构化处理,(2)Spring Retry的容错重试机制,(3)响应结果的反序列化封装。整体架构采用统一
文章目录
Pre
大模型开发 - 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() : "";
}
这个方法是开发者最常用的入口。它做了三件事:
-
将原始字符串消息封装为
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/
更多推荐
所有评论(0)