1. Spring AI 是什么?它解决了什么问题?
考察点:框架理解
参考答案:
Spring AI 是 Spring 官方出的 AI 应用开发框架,可以理解为"Spring Boot 版的 LangChain"。它解决的核心问题是:统一不同大模型的调用方式。
以前调 OpenAI 要用 OpenAI 的 SDK,调通义千问要用阿里的 SDK,代码写法完全不一样。Spring AI 抽象了一层 ChatModel 接口,不管底层是哪个模型,上层代码都一样:
ChatResponse response = chatModel.call(new Prompt("你好"));
换模型只需要改配置,代码不用动。另外它还提供了 RAG、Function Calling、向量数据库这些 AI 应用常用的能力,而且和 Spring 生态无缝集成,对 Java 开发者很友好。
参考答案版本 2
Spring AI 是 Spring 官方推出的 AI 应用开发框架,目标是让 Java 开发者能像用 Spring Data、Spring Security 一样方便地接入 AI 能力。
LLM 的提供商很多——OpenAI、Google、阿里、百度——每家 API 格式都不一样。没有统一抽象的话,业务代码会和具体厂商绑死,换一家要改一堆代码。Spring AI 提供了统一的 ChatClient 接口,屏蔽了底层差异:
// 不管底层是 OpenAI 还是其他,调用方式一样
@Autowired
private ChatClient chatClient;
String response = chatClient.prompt()
.user("帮我写一首诗")
.call()
.content();
第二,简化 Prompt,Spring AI 提供了模板机制,Prompt 可以放到文件中,然后通过变量替换。
@Value("classpath:/prompts/podcast.st")
private Resource promptTemplate;
String prompt = new PromptTemplate(promptTemplate)
.create(Map.of("topic", "人工智能", "style", "轻松幽默"))
.getContents();
第三,Spring AI 内置了向量数据库集成,支持 PGVector、Milvus、Pinecone 等多种向量库。
// 文档切分、向量化、存储
vectorStore.add(documents);
// 检索相关内容
List relevant = vectorStore.similaritySearch("用户问题");
第四,Spring AI 封装了 Function Calling,能用注解让 LLM 调用外部工具:
@Bean
@Description("查询天气信息")
public Function weatherFunction() {
return request -> weatherService.getWeather(request.getCity());
}
2. 你是怎么用 Spring AI 对接 DeepSeek 的?配置了哪些参数?
考察点:实际使用经验
参考答案:
DeepSeek 的 API 是兼容 OpenAI 格式的,所以用 Spring AI 的 OpenAI 模块就能对接。主要配置:
spring:
ai:
openai:
api-key: ${DEEPSEEK_API_KEY}
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat
temperature: 0.7
max-tokens: 4096
关键参数说明:
-
base-url:改成 DeepSeek 的地址
-
model:DeepSeek 的模型名,比如 deepseek-chat、deepseek-coder
-
temperature:控制输出的随机性,0 最确定,1 最随机
-
max-tokens:最大输出长度
代码里直接注入 ChatModel 就能用:
@Autowired
private ChatModel chatModel;
public String chat(String message) {
return chatModel.call(message);
}
参考答案版本 2
DeepSeek 的 API 是兼容 OpenAI 格式的,所以用 Spring AI 对接很简单,走 OpenAI 的适配器就行,只需要在 application.yml 里配置base-url 指向 DeepSeek,model 用 DeepSeek 的模型名。
spring:
ai:
openai:
api-key: ${DEEPSEEK_API_KEY}
base-url: https://api.deepseek.com
chat:
options:
model: deepseek-chat
temperature: 0.7
max-tokens: 4096
temperature 用于控制输出的随机性,0 最确定,1 最随机。我们播客场景用 0.7,希望有点创意但不要太跳脱。
不同地方对这个参数的定义有所不同,LangGraph4J 认为是 0-2,SpringAI 认为是 0-1。
这是 SpringAI 官方给出的参考,0-1。
这是 LangGraph4J 官方给出的 0-2。
这是 DeepSeek 官方给出的,默认值为 1,取值范围 0-2。
DeepSeek 官方的建议是翻译 1.3,coding 0,数据清晰/分析 1.0。
max-tokens 为最大输出长度。DeepSeek 支持到 8K 甚至更长,可以根据业务设置。top-p 为另一种控制随机性的方式,和 temperature 二选一即可。presence-penalty / frequency-penalty:控制重复内容的惩罚,避免 AI 翻来覆去说一样的话。
配置好之后,注入 ChatClient 就能用:
@Service
public class LLMService {
private final ChatClient chatClient;
public LLMService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public String chat(String userMessage) {
return chatClient.prompt()
.user(userMessage)
.call()
.content();
}
// 流式输出
public Flux chatStream(String userMessage) {
return chatClient.prompt()
.user(userMessage)
.stream()
.content();
}
}
3. Spring AI 中的 ChatModel 和 ChatClient 有什么区别?你用的是哪个?
考察点:API 理解
参考答案:
ChatModel 是底层接口,直接和大模型 API 交互。用起来比较原始:
ChatResponse response = chatModel.call(new Prompt(messages));
String text = response.getResult().getOutput().getContent();
ChatClient 提供了流式 API,用起来更优雅:
String response = ChatClient.create(chatModel)
.prompt()
.system("你是一个助手")
.user("你好")
.call()
.content();
ChatClient 还支持链式调用、Advisor 插件、流式响应等高级特性。我们项目里两个都用了:
-
底层的 ModelServiceClient 封装了 ChatModel,做流式调用
-
上层业务代码有时用 ChatClient 做简单的一次性调用
选择的原则是:需要细粒度控制用 ChatModel,追求开发效率用 ChatClient。
参考答案版本 2:
ChatModel 是直接和 LLM 交互的底层接口,定义了最基础的调用方法:
public interface ChatModel {
ChatResponse call(Prompt prompt);
Flux stream(Prompt prompt);
}
它关注的是:把 Prompt 发给 LLM,拿回 Response。很原始,很直接。使用时要自己构建 Prompt、解析 Response:
@Autowired
private ChatModel chatModel;
public String chat(String message) {
Prompt prompt = new Prompt(new UserMessage(message));
ChatResponse response = chatModel.call(prompt);
return response.getResult().getOutput().getContent();
}
ChatClient 是 Spring AI 1.0 引入的 API,提供了流式(Fluent)调用方式,用起来更舒服:
@Autowired
private ChatClient chatClient;
public String chat(String message) {
return chatClient.prompt()
....真诚点赞 诚不我欺
回复