探索 Spring AI 的 ChatClient API:构建智能对话应用的利器
前言
在当今人工智能蓬勃发展的时代,智能对话系统成为了众多应用的核心组成部分。无论是客服机器人、智能助手还是聊天应用,都离不开高效、灵活的对话处理能力。Spring AI 作为 Spring 生态系统中专注于人工智能的框架,为开发者提供了强大的工具和功能。其中,ChatClient API 是一个关键组件,它提供了与 AI 模型进行通信的流畅接口,支持同步和流式编程模型,极大地简化了开发智能对话应用的过程。本文将深入探讨 Spring AI 的 ChatClient API,介绍其使用方法、特性以及如何利用它构建强大的智能对话应用。
一、ChatClient 的创建
1.1 使用自动配置的 ChatClient.Builder
Spring AI 提供了 Spring Boot 自动配置,可创建一个原型 ChatClient.Builder bean,方便注入到类中。以下是一个简单的示例:
java
@RestController
class MyController {
private final ChatClient chatClient;
public MyController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
@GetMapping("/ai")
String generation(String userInput) {
return this.chatClient.prompt()
.user(userInput)
.call()
.content();
}
}
在这个示例中,用户输入设置用户消息的内容,call()
方法向 AI 模型发送请求,content()
方法将 AI 模型的响应作为字符串返回。
1.2 以编程方式创建 ChatClient
如果需要禁用自动配置,可以通过设置属性 spring.ai.chat.client.enabled=false
。然后,根据需要创建 ChatClient.Builder 实例:
java
ChatModel myChatModel = ... // usually autowired
ChatClient.Builder builder = ChatClient.builder(this.myChatModel);
// or create a ChatClient with the default builder settings:
ChatClient chatClient = ChatClient.create(this.myChatModel);
二、ChatClient Fluent API
ChatClient 的 Fluent API 允许使用重载的 prompt
方法启动流式 API,支持多种方式构建提示信息:
prompt()
:不带参数,允许开始构建用户、系统和提示的其他部分。prompt(Prompt prompt)
:接受 Prompt 参数,允许传入 Prompt 实例。prompt(String content)
:获取用户的文本内容。
三、ChatClient 响应处理
3.1 返回 ChatResponse
AI 模型的响应是一个丰富的结构 ChatResponse
,包含有关响应生成方式的元数据和多个响应。可以通过调用 chatResponse()
方法获取:
java
ChatResponse chatResponse = chatClient.prompt()
.user("Tell me a joke")
.call()
.chatResponse();
3.2 返回实体
可以使用 entity()
方法将返回的字符串转换为实体类。例如,对于 Java 记录 ActorFilms
:
java
record ActorFilms(String actor, List<String> movies) {}
ActorFilms actorFilms = chatClient.prompt()
.user("Generate the filmography for a random actor.")
.call()
.entity(ActorFilms.class);
还支持泛型列表的转换:
java
List<ActorFilms> actorFilms = chatClient.prompt()
.user("Generate the filmography of 5 movies for Tom Hanks and Bill Murray.")
.call()
.entity(new ParameterizedTypeReference<List<ActorFilms>>() {});
3.3 流式响应
使用 stream()
方法可以获得异步响应:
java
Flux<String> output = chatClient.prompt()
.user("Tell me a joke")
.stream()
.content();
也可以流式传输 ChatResponse
:
java
Flux<ChatResponse> chatResponse = chatClient.prompt()
.user("Tell me a joke")
.stream()
.chatResponse();
四、使用默认值
在 @Configuration
类中创建 ChatClient
可以简化运行时代码,通过设置默认值,避免在每个请求中重复设置系统文本。
4.1 默认系统文本
java
@Configuration
class Config {
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("You are a friendly chat bot that answers question in the voice of a Pirate")
.build();
}
}
@RestController
class AIController {
private final ChatClient chatClient;
AIController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/ai/simple")
public Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return Map.of("completion", this.chatClient.prompt().user(message).call().content());
}
}
4.2 带参数的默认系统文本
java
@Configuration
class Config {
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
return builder.defaultSystem("You are a friendly chat bot that answers question in the voice of a {voice}")
.build();
}
}
@RestController
class AIController {
private final ChatClient chatClient;
AIController(ChatClient chatClient) {
this.chatClient = chatClient;
}
@GetMapping("/ai")
Map<String, String> completion(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message, String voice) {
return Map.of("completion",
this.chatClient.prompt()
.system(sp -> sp.param("voice", voice))
.user(message)
.call()
.content());
}
}
五、顾问(Advisors)
Advisors API 提供了一种灵活而强大的方法来拦截、修改和增强 Spring 应用程序中的 AI 驱动的交互。常见的使用场景是在提示中附加上下文数据,如对话历史记录或自定义数据。
5.1 ChatClient 中的 Advisor 配置
java
ChatClient.builder(chatModel)
.build()
.prompt()
.advisors(
new MessageChatMemoryAdvisor(chatMemory),
new QuestionAnswerAdvisor(vectorStore)
)
.user(userText)
.call()
.content();
在这个配置中,MessageChatMemoryAdvisor
将首先执行,将对话历史记录添加到提示符中,然后 QuestionAnswerAdvisor
将根据用户的问题和添加的对话历史记录执行搜索,提供更相关的结果。
5.2 不同类型的 Advisor 实现
MessageChatMemoryAdvisor
:检索内存并将其作为消息集合添加到提示符中。PromptChatMemoryAdvisor
:检索内存并将其添加到提示的系统文本中。VectorStoreChatMemoryAdvisor
:允许指定 VectorStore 实例、默认对话 ID、聊天历史记录窗口大小和顺序。
六、日志记录
SimpleLoggerAdvisor
是一个用于记录 ChatClient 请求和响应数据的顾问,可用于调试和监控 AI 交互。要启用日志记录,将其添加到顾问链中,并设置日志级别为 DEBUG:
java
ChatResponse response = ChatClient.create(chatModel).prompt()
.advisors(new SimpleLoggerAdvisor())
.user("Tell me a joke?")
.call()
.chatResponse();
在 application.properties
或 application.yaml
文件中添加:
properties
logging.level.org.springframework.ai.chat.client.advisor=DEBUG
七、聊天内存(Chat Memory)
ChatMemory
接口表示聊天对话历史的存储,提供了添加消息、检索消息和清除对话历史的方法。目前有四种实现:InMemoryChatMemory
、CassandraChatMemory
、Neo4jChatMemory
和 JdbcChatMemory
,分别提供了内存存储、Cassandra 持久化存储、Neo4j 持久化存储和 JDBC 持久化存储。
7.1 CassandraChatMemory
java
CassandraChatMemory.create(CassandraChatMemoryConfig.builder().withTimeToLive(Duration.ofDays(1)).build());
7.2 Neo4jChatMemory
支持多个配置参数,可通过属性文件进行配置。
7.3 JdbcChatMemory
java
JdbcChatMemory.create(JdbcChatMemoryConfig.builder().jdbcTemplate(jdbcTemplate).build());
也可以通过添加依赖进行自动配置:
xml
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-model-chat-memory-jdbc</artifactId>
</dependency>
总结
Spring AI 的 ChatClient API 为开发者提供了一个强大而灵活的工具,用于构建智能对话应用。通过其流畅的 API、丰富的响应处理方式、默认值设置、顾问机制、日志记录和聊天内存管理等功能,开发者可以更轻松地实现与 AI 模型的交互,处理复杂的对话场景。无论是创建简单的聊天机器人还是复杂的智能客服系统,ChatClient API 都能帮助开发者快速搭建高效、智能的对话应用。在使用过程中,开发者需要根据具体需求合理配置和使用各个组件,同时注意日志记录中的敏感信息处理,确保应用的安全性和可靠性。随着人工智能技术的不断发展,Spring AI 的 ChatClient API 也将不断完善和扩展,为开发者带来更多的便利和可能性。