一、ChatClient Fluent API 详解
1.1 Fluent API 设计哲学
ChatClient 的流畅 API 提供了三种初始化 Prompt 的方式,覆盖不同使用场景。这种设计体现了流畅接口模式(Fluent Interface Pattern),通过方法链式调用提高代码的可读性和表达力。
流畅接口的优势
-
可读性:代码更接近自然语言,易于理解
-
发现性:IDE 的自动补全功能可以帮助开发者发现可用的方法
-
类型安全:编译时检查,减少运行时错误
-
不可变性:每个方法返回新的实例,避免副作用
1.2 方式 1:无参 prompt () - 完全自定义 Prompt
适用于需要精细控制用户消息、系统消息、参数的场景:
java
@Component
class FluentApiDemo1 {
private final ChatClient chatClient;
public FluentApiDemo1(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public String customPromptDemo() {
return chatClient.prompt()
.system("你是一个专业的技术文档翻译助手,将英文技术文档翻译成中文,保持术语准确")
.user("把这段英文翻译成中文: 'Spring AI provides seamless integration with LLMs'")
.call()
.content();
}
}
系统消息的重要性
系统消息(System Message)在对话中起着关键的指导作用:
-
角色定义:明确 AI 助手的身份和专长领域
-
行为约束:设定回答的风格、格式和边界
-
质量保证:确保输出符合预期的标准和要求
1.3 方式 2:prompt (Prompt) - 传入预构建的 Prompt 对象
适用于已通过 Prompt API 构建好的复杂 Prompt:
java
package com.atg.ai_agent.demo;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.messages.SystemMessage;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.stereotype.Component;
@Component
class FluentApiDemo2 {
private final ChatClient chatClient;
public FluentApiDemo2(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public String prebuiltPromptDemo() {
// 预构建Prompt对象
Prompt prompt = new Prompt(
new SystemMessage("你是一个数学老师,用简单易懂的语言解释数学概念"),
new UserMessage("解释什么是斐波那契数列")
);
// 直接传入Prompt对象
return chatClient.prompt(prompt)
.call()
.content();
}
}
Prompt 对象的构建策略
预构建 Prompt 对象适用于以下场景:
-
复杂的多轮对话:需要维护对话历史和上下文
-
模板化内容:可复用的 Prompt 模板
-
动态内容生成:运行时根据条件构建不同的 Prompt
-
性能优化:避免重复的 Prompt 构建开销
1.4 方式 3:prompt (String) - 快速传入用户文本
适用于简单场景,直接将字符串作为用户消息:
java
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.stereotype.Component;
@Component
class FluentApiDemo3 {
private final ChatClient chatClient;
public FluentApiDemo3(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder.build();
}
public String simplePromptDemo() {
// 直接传入用户文本,简化调用
return chatClient.prompt("推荐3本Java编程入门书籍")
.call()
.content();
}
}
简洁性与灵活性的权衡
这种方式虽然简洁,但牺牲了一定的灵活性:
-优点 :代码简洁,适合快速原型开发
- 缺点 :无法设置系统消息、参数等高级选项
- 适用场景:简单的问答、快速测试、概念验证