1. 概述
本文将深入探讨 Spring AI 1.0.0 M1 版本中 ChatClient 的流式 API 设计。这个接口作为 Spring AI 模块的核心组件,提供了与 AI 模型交互的标准化方式,支持发送提示词并接收结构化响应。其设计遵循构建器模式,API 风格与 WebClient、RestClient 和 JdbcClient 保持一致,让 Spring 开发者能快速上手。
2. 通过 ChatClient 执行提示词
在 Spring Boot 中,我们可以直接使用自动配置的 bean,或通过编程方式创建实例。首先添加依赖:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
</dependency>
然后在组件中注入 ChatClient.Builder:
@RestController
@RequestMapping("api/articles")
class BlogsController {
private final ChatClient chatClient;
public BlogsController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
// ...
}
创建一个简单接口接收用户问题并转发给 AI:
@GetMapping("v1")
String askQuestion(@RequestParam(name = "question") String question) {
return chatClient.prompt()
.user(question)
.call()
.chatResponse()
.getResult()
.getOutput()
.getContent();
}
核心优势:流式 API 让我们能用链式调用完成从用户输入到响应提取的全流程。如果只需要响应文本内容,可以用 content() 方法简化最后四步:
@GetMapping("v1")
String askQuestion(@RequestParam(name = "question") String question) {
return chatClient.prompt()
.user(question)
.call()
.content();
}
发送 GET 请求后,会收到类似 ChatGPT 浏览器界面的非结构化响应:
3. 将响应映射为特定格式
实际开发中,我们通常需要结构化输出(如 JSON)。ChatClient 提供了 entity() 方法实现这个需求。下面改造代码返回 Article 对象列表:
record Article(String title, Set<String> tags) {
}
@GetMapping("v2")
List<Article> askQuestionAndRetrieveArticles(@RequestParam(name = "question") String question) {
return chatClient.prompt()
.user(question)
.call()
.entity(new ParameterizedTypeReference<List<Article>>() {});
}
现在接口会返回符合规范的 JSON 列表:
4. 提供额外上下文
直接调用 AI 模型可能返回虚构数据。解决方案是使用 RAG(检索增强生成)模式,结合向量存储提供真实数据。实现步骤:
4.1 初始化向量存储
@RestController
@RequestMapping("api/articles")
public class BlogsController {
private final ChatClient chatClient;
private final VectorStore vectorStore;
public BlogsController(ChatClient.Builder chatClientBuilder, EmbeddingModel embeddingModel) throws IOException {
this.chatClient = chatClientBuilder.build();
this.vectorStore = new SimpleVectorStore(embeddingModel);
initContext();
}
void initContext() throws IOException {
List<Document> documents = Files.readAllLines(Path.of("src/main/resources/articles.txt"))
.stream()
.map(Document::new)
.toList();
vectorStore.add(documents);
}
// ...
}
⚠️ 注意:这里从本地文件加载文档,实际项目中可替换为数据库/API 等数据源。
4.2 集成 RAG 顾问
@GetMapping("v3")
List<Article> askQuestionWithContext(@RequestParam(name = "question") String question) {
return chatClient.prompt()
.advisors(new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()))
.user(question)
.call()
.entity(new ParameterizedTypeReference<List<Article>>() {});
}
现在响应完全基于提供的上下文数据:
5. 总结
本文系统介绍了 Spring AI 的 ChatClient 使用方法:
- ✅ 基础用法:发送简单提示词并获取文本响应
- ✅ 结构化输出:通过 entity() 方法映射响应到特定格式
- ✅ 上下文增强:使用 RAG 模式结合向量存储提供真实数据
核心优势在于其流式 API 设计,既保持了 Spring 生态的统一性,又简化了 AI 集成开发。实际应用中,建议优先考虑 RAG 模式避免"一本正经地胡说八道"的问题。