【Spring AI】ChatClient 使用详解
SpringAI的ChatClient简单使用
目录
Spring AI 中的 ChatClient
是一个核心接口,它通过流畅的 API(Fluent API)简化了与大型语言模型(LLM)的交互过程,支持同步和流式编程模型。
先看看最简单的对话:
@Resource
private ChatClient.Builder chatClient;
public String simpleChat(String message) {
return chatClient.build()
.prompt()
.user(message)
.call()
.content();
}
我们可以从创建ChatClient、构建提示、处理响应、使用默认配置、使用Advisors、参数配置这几个方面来进行拓展~
1.创建一个ChatClient
1)使用 Spring Boot 自动配置(推荐)
Spring Boot 提供了开箱即用的自动配置,你可以直接注入 ChatClient.Builder
来构建 ChatClient
实例
@RestController
public class MyController {
private final ChatClient chatClient;
// 1.注入自动配置的 Builder
public MyController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
// 2.使用特定的 ChatModel 配置 chatClient
// public MyController(ChatModel dashscopeChatModel) {
// this.chatClient = ChatClient.create(dashscopeChatModel);
// // 或者使用 builder 方式
// // this.chatClient = ChatClient.builder(dashscopeChatModel).build();
// }
@GetMapping("/ai")
public String generateResponse(String userInput) {
return chatClient.prompt()
.user(userInput)
.call()
.content();
}
}
在这种方式下,ChatClient.Builder
是一个原型(Prototype)Bean,每次注入时都会创建一个新的实例,通常基于应用配置文件中配置的默认模型(如 OpenAI)
2)编程式创建
当需要更精细的控制,或者应用中需要与多个不同的模型交互时,你可以编程式地创建 ChatClient
@Configuration
public class ChatClientConfig {
// 假设已经通过 Spring Boot 自动配置了某个 ChatModel
@Bean
public ChatClient openAiChatClient(OpenAiChatModel chatModel) {
return ChatClient.create(chatModel);
// 或者使用 Builder 进行更多配置
// return ChatClient.builder(chatModel).defaultSystem("你是一个助手").build();
}
@Bean
public ChatClient anthropicChatClient(AnthropicChatModel chatModel) {
return ChatClient.create(chatModel);
}
}
在这种情况下,通常需要在配置文件中禁用默认的 ChatClient.Builder
自动配置:spring.ai.chat.client.enabled=false
2.构建提示(Prompt)
ChatClient
提供了灵活的链式调用来构建提示信息
1)基本用户提示:
最简单的方式是直接发送用户消息。
String response = chatClient.prompt()
.user("解释一下人工智能")
.call()
.content();
2)添加系统消息:
系统消息用于引导模型的行为、角色设定或输出限制
String response = chatClient.prompt()
.system("你是一个专业的技术文档翻译助手") // 固定系统消息
.user("将 'Hello World' 翻译成中文")
.call()
.content();
3)带参数的系统消息:
系统消息中可以包含占位符,并在运行时动态替换
String response = chatClient.prompt()
.system(s -> s.text("以{style}风格回答").param("style", "古风"))
.user("解释什么是人工智能")
.call()
.content();
4)使用预构建的 Prompt 对象:
对于复杂的或需要复用的提示结构,可以预先构建 Prompt
对象
Prompt promptTemplate = Prompt.builder()
.systemMessage("你是一个幽默的助手")
.userMessage("讲一个{topic}相关的笑话")
.build();
Prompt dynamicPrompt = promptTemplate.replaceParams(Map.of("topic", "程序员"));
ChatResponse response = chatClient.prompt(dynamicPrompt).call().chatResponse();
3.处理响应
ChatClient
提供了多种方法来处理和解析模型的响应
1)获取文本内容(content()
):
最直接的方式,返回生成的文本字符串。
String text = chatClient.prompt().user("你好").call().content();
2)获取完整响应对象(chatResponse()
):
返回 ChatResponse
对象,包含响应内容、元数据(如令牌使用情况)等信息
ChatResponse chatResponse = chatClient.prompt().user("讲个笑话").call().chatResponse();
String text = chatResponse.getResult().getOutput().getText();
// 获取元数据,如令牌消耗
// Metadata metadata = chatResponse.getMetadata();
3)映射到 Java 对象(entity()
):
如果模型输出是结构化的(如 JSON),可以将其自动映射到自定义的 Java 类或记录(Record)中
record Recipe(String dish, List<String> ingredients) {}
Recipe recipe = chatClient.prompt()
.user("生成一份蔬菜沙拉食谱,以JSON格式输出")
.call()
.entity(Recipe.class);
4)流式响应(stream()
):
对于需要实时输出或处理较长文本的场景,可以使用流式响应,返回一个 Flux<String>
Flux<String> flux = chatClient.prompt()
.user("讲述一个长篇故事")
.stream()
.content();
// 在 WebFlux 控制器中可以直接返回 Flux
4.使用默认配置
你可以在创建 ChatClient
时定义一些默认配置,简化每次请求的代码
1)默认系统提示词:
这样,每次请求都会自动带上这个系统消息。
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder
.defaultSystem("你是一个乐于助人的助手,以海盗风格回答所有问题")
.build();
}
2)默认模型选项:
可以设置默认的模型参数,如温度(temperature)、最大令牌数(maxTokens)等
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
return builder
.defaultOptions(OpenAiChatOptions.builder()
.model("gpt-3.5-turbo")
.temperature(0.7)
.maxTokens(1024)
.build())
.build();
}
5.使用 Advisors(顾问)
Advisors 提供了一种拦截和增强 AI 交互的强大方式,常用于集成聊天记忆(Chat Memory) 和检索增强生成(RAG) 等功能
1)聊天记忆(多轮对话):
让模型记住之前的对话历史。聊天记忆通常通过 CONVERSATION_ID
来区分不同用户的对话
// 通常需要配置 ChatMemory Bean (如 InMemoryChatMemory)
ChatResponse response = chatClient.prompt()
.user(userInput)
.advisors(new MessageChatMemoryAdvisor(chatMemory)) // 添加聊天记忆顾问
.call()
.chatResponse();
2)检索增强生成(RAG):
从向量存储中检索相关信息来增强提示。
ChatResponse response = chatClient.prompt()
.user(query)
.advisors(new QuestionAnswerAdvisor(vectorStore)) // 添加 RAG 顾问
.call()
.chatResponse();
6.参数配置
在 application.yml
中,你可以配置底层模型的相关参数
1)openai:
spring:
ai:
openai:
api-key: your-openai-api-key
base-url: https://api.openai.com
chat:
options:
model: gpt-3.5-turbo
temperature: 0.7
max-tokens: 1000
2)阿里百炼
spring:
ai:
dashscope:
api-key: xxx
chat:
options:
model: qwen-plus
7.综合示例
结合了系统消息、参数、流式响应和异常处理的示例:
@RestController
@RequestMapping("/chat")
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder
.defaultSystem("你是一个友好的助手,擅长用{style}风格回答问题。")
.build();
}
@GetMapping(produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<String> chat(@RequestParam String message,
@RequestParam(defaultValue = "通俗易懂") String style) {
return chatClient.prompt()
.system(s -> s.param("style", style)) // 动态设置风格参数
.user(message)
.stream()
.content();
}
@PostMapping("/structured")
public ResponseEntity<?> getStructuredRecipe(@RequestParam String dish) {
try {
record Recipe(String name, List<String> ingredients, String steps) {}
Recipe recipe = chatClient.prompt()
.user("请提供一道{ dish }的详细菜谱,以JSON格式输出,包含菜名、食材列表和步骤。")
.param("dish", dish)
.call()
.entity(Recipe.class);
return ResponseEntity.ok(recipe);
} catch (Exception e) {
return ResponseEntity.badRequest().body("生成菜谱时出错: " + e.getMessage());
}
}
}
看到这里了,如果对你有帮助,可以点个赞么~
更多推荐
所有评论(0)