ChatClient API 使用指南
什么是 ChatClient
ChatClient 是 Spring AI 提供的与 AI 模型交互的流式 API。它的设计灵感来自 WebClient 和 RestClient,支持同步和流式两种调用方式。
核心特点:
- 流式 API 设计,链式调用更优雅
- 支持 Prompt 模板和参数替换
- 自动将响应映射为 Java 对象
- 支持流式输出(像 ChatGPT 那样逐字显示)
快速开始
最简单的例子
Spring Boot 会自动配置好 ChatClient.Builder,直接注入就能用:
@RestController
class MyController {
private final ChatClient chatClient;
public MyController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/ai")
String chat(String userInput) {
return chatClient.prompt()
.user(userInput)
.call()
.content();
}
}
这个例子就实现了:
- 用户输入作为 Prompt
- 调用 AI 模型
- 返回结果字符串
使用多个 AI 模型
实际项目中常需要同时使用多个模型:
- 任务分类:简单问题用便宜模型,复杂推理用强大模型
- 容灾备份:一个模型挂了切换到另一个
- AB 测试:对比不同模型的效果
- 用户选择:让用户自己选模型
配置多个 ChatClient
首先关闭自动配置:
spring.ai.chat.client.enabled=false
场景 1:同一模型不同配置
ChatModel chatModel = ...; // Spring Boot 已经配置好的
// 方式一:简单创建
ChatClient client = ChatClient.create(chatModel);
// 方式二:自定义配置
ChatClient client = ChatClient.builder(chatModel)
.defaultSystem("你是一个 Java 专家")
.build();
场景 2:不同类型的模型
@Configuration
public class ChatClientConfig {
@Bean
public ChatClient openAiClient(OpenAiChatModel model) {
return ChatClient.create(model);
}
@Bean
public ChatClient claudeClient(AnthropicChatModel model) {
return ChatClient.create(model);
}
}
使用时用 @Qualifier 区分:
@Service
public class AIChatService {
@Autowired
@Qualifier("openAiClient")
private ChatClient openAi;
@Autowired
@Qualifier("claudeClient")
private ChatClient claude;
public String chat(String input, String modelType) {
ChatClient client = "openai".equals(modelType) ? openAi : claude;
return client.prompt(input).call().content();
}
}
场景 3:多个 OpenAI 兼容接口
有些国产模型兼容 OpenAI 接口,可以用 mutate() 方法切换:
@Service
public class MultiModelService {
@Autowired
private OpenAiChatModel baseModel;
@Autowired
private OpenAiApi baseApi;
public void useMultipleModels() {
// 创建 Groq API 客户端
OpenAiApi groqApi = baseApi.mutate()
.baseUrl("https://api.groq.com/openai")
.apiKey(System.getenv("GROQ_API_KEY"))
.build();
// 创建阿里云 API 客户端
OpenAiApi aliApi = baseApi.mutate()
.baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1")
.apiKey(System.getenv("DASHSCOPE_API_KEY"))
.build();
// 创建不同的模型
OpenAiChatModel groqModel = baseModel.mutate()
.openAiApi(groqApi)
.defaultOptions(
OpenAiChatOptions.builder()
.model("llama3-70b-8192")
.temperature(0.5)
.build()
)
.build();
OpenAiChatModel aliModel = baseModel.mutate()
.openAiApi(aliApi)
.defaultOptions(
OpenAiChatOptions.builder()
.model("qwen-turbo")
.temperature(0.7)
.build()
)
.build();
// 分别调用
String prompt = "介绍一下 Spring AI";
String groqResp = ChatClient.builder(groqModel)
.build()
.prompt(prompt)
.call()
.content();
String aliResp = ChatClient.builder(aliModel)
.build()
.prompt(prompt)
.call()
.content();
System.out.println("Groq: " + groqResp);
System.out.println("阿里云: " + aliResp);
}
}
流式 API 详解
三种初始化方式
ChatClient 提供了三种 prompt() 重载方法:
1. 无参数:使用流式 API 构建
chatClient.prompt()
.system("你是一个 Java 专家")
.user("介绍一下 Spring Boot")
.call()
.content();
2. 传入 Prompt 对象
Prompt prompt = new Prompt("Hello AI");
chatClient.prompt(prompt)
.call()
.content();
3. 直接传入文本(最简单)
chatClient.prompt("介绍一下 Spring AI")
.call()
.content();
提示模板与变量替换
ChatClient 支持在提示中使用变量,运行时自动替换。比如让 AI 列出某个作曲家配乐的电影:
String answer = chatClient.prompt()
.user(u -> u
.text("请列出由 {composer} 创作配乐的五部电影")
.param("composer", "约翰·威廉姆斯"))
.call()
.content();
内部使用 PromptTemplate 处理模板,默认基于 StringTemplate 引擎,变量用 {} 包裹。
自定义模板分隔符
如果提示中包含 JSON,可能会和 {} 冲突,可以改用其他分隔符:
String answer = chatClient.prompt()
.user(u -> u
.text("请列出由 <composer> 创作配乐的五部电影")
.param("composer", "约翰·威廉姆斯"))
.templateRenderer(StTemplateRenderer.builder()
.startDelimiterToken('<')
.endDelimiterToken('>')
.build())
.call()
.content();
这样就能避免 JSON 语法冲突了。