目录
[四、通过function-call 进⾏⽅法回调](#四、通过function-call 进⾏⽅法回调)
[五、通过function-call 进⾏退订](#五、通过function-call 进⾏退订)
[六、通过function-call 获取预定信息](#六、通过function-call 获取预定信息)
[七、通过function-call 修改预定信息](#七、通过function-call 修改预定信息)
一、预设角色
我们做的是⼀个智能机票助⼿, 他主要的职责是给⽤户退票、改票、买票。 必须职责分明
java
// 构造方法:自动注入 Spring AI 的 ChatClient 建造器
public OpenAiController(ChatClient.Builder chatClientBuilder) {
this.chatClient = chatClientBuilder
// 给 AI 设置【系统提示词】(核心规则)
.defaultSystem("""
您是"ChaoMeng"航空公司的客户聊天支持代理。请以友好、乐于助人
且愉快的方式来回复。
您正在通过在线聊天系统与客户互动。
请讲中文。
今天的日期是 {current_date}.
""")
// 添加日志顾问:打印请求/响应日志
.defaultAdvisors(new LoggingAdvisor())
// 构建最终的 ChatClient 客户端
.build();
}
二、对话记忆
java
@Bean
public ChatMemory chatMemory() {
return new InMemoryChatMemory();
}
三、实现退订、更改预定
退订业务:
超过2天⽆法退订
退订后状态改为"取消"
难点:
需要获取当前航班信息( 需要⽤户提供 姓名,航班号)
在进⾏有关预订或取消预订的信息之前,您必须始终从⽤户处获取以下信息:预订号、客户姓名。
在询问⽤户之前,请检查消息历史记录以获取此信息。
解决: 加⼊提示词
java
@RestController
public class OpenAiController {
private final ChatClient chatClient;
// 构造注入:聊天客户端构建器、向量库、对话记忆
public OpenAiController(
ChatClient.Builder chatClientBuilder,
VectorStore vectorStore,
ChatMemory chatMemory
) {
this.chatClient = chatClientBuilder
// 系统提示词:定义 AI 角色、规则、语气
.defaultSystem("""
您是"ChaoMeng"航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。
您正在通过在线聊天系统与客户互动。
在提供有关预订或取消预订的信息之前,您必须始终从用户处获取以下信息:预订号、客户姓名。
在询问用户之前,请检查消息历史记录以获取此信息。
请讲中文。
今天的日期是 {current_date}.
""")
// 默认顾问:记忆 + RAG + 日志(Spring AI 核心增强)
.defaultAdvisors(
new PromptChatMemoryAdvisor(chatMemory), // 1. 对话记忆(记住上下文)
new QuestionAnswerAdvisor( // 2. RAG 检索增强(查知识库)
vectorStore,
SearchRequest.defaults()
),
new LoggingAdvisor() // 3. 日志顾问(打印请求/响应)
)
.build();
}
}
四、通过function-call 进⾏⽅法回调
- 需要告诉⼤模型:回调哪个⽅法
提供实现了Function接⼝Bean(调⽤apply) - 需要告诉⼤模型:什么对话才回调
配置Function作⽤(处理退订) - 需要告诉⼤模型:提取对话的什么关键字
Function的第⼀个泛型去指定提取关键字的变量名
五、通过function-call 进⾏退订
java
/**
* 取消机票预定函数(Spring Cloud Function 实现)
*/
@Bean
@Description("取消机票预定")
public Function<CancelBookingRequest, String> cancelBooking(FlightBookingService flightBookingService) {
return request -> {
// 执行业务逻辑:取消预定
flightBookingService.cancelBooking(
request.getBookingNumber(),
request.getName()
);
// 返回成功标识
return "取消预定成功";
};
}
六、通过function-call 获取预定信息
java
@Bean
@Description("获取机票预定详细信息")
public Function<BookingDetailsRequest, BookingDetails> getBookingDetails() {
return request -> {
try {
// 核心业务:调用服务查询预订详情
return flightBookingService.getBookingDetails(
request.bookingNumber(),
request.name()
);
} catch (Exception e) {
// 异常处理:记录最精准的异常信息
logger.warn("Booking details query failed: {}",
NestedExceptionUtils.getMostSpecificCause(e).getMessage());
// 异常降级:返回空数据,不中断流程
return new BookingDetails(
request.bookingNumber(),
request.name(),
null, null, null, null, null
);
}
};
}
七、通过function-call 修改预定信息
java
/**
* 修改机票预定日期
* 函数入参:ChangeBookingDatesRequest
* 函数出参:String
*/
@Bean
@Description("修改机票预定日期")
public Function<ChangeBookingDatesRequest, String> changeBooking() {
return request -> {
// 执行业务逻辑:修改预定日期
flightBookingService.changeBooking(
request.getBookingNumber(),
request.getName(),
request.getDate(),
request.getFrom(),
request.getTo()
);
// 返回成功标识
return "修改机票预定日期成功";
};
}
八、通过RAG(检索增强⽣成),外挂⼀个知识库
向量数据库:相似性检索,⼤数据领域(推荐、你喜欢的)
- 配置向量数据库
- 写⼊数据(Embedding)
- 查询
java
预订航班,即表示您同意这些条款。
1. 预订航班
- 通过我们的⽹站或移动应⽤程序预订。
- 预订时需要全额付款。
- 确保个⼈信息(姓名、ID 等)的准确性,因为更正可能会产⽣ 25 的费⽤。
2. 更改预订
- 允许在航班起⻜前 24 ⼩时更改。
- 通过在线更改或联系我们的⽀持⼈员。
- 改签费:经济舱 50,豪华经济舱 30,商务舱免费。
3. 取消预订
- 最晚在航班起⻜前 48 ⼩时取消。
- 取消费⽤:经济舱 75 美元,豪华经济舱 50 美元,商务舱 25 美元。
- 退款将在 7 个⼯作⽇内处理。
向量数据库
java
// 声明这是一个交给Spring容器管理的Bean
@Bean
// 方法名就是Bean名称:vectorStore
// 参数:自动注入Spring容器中的 EmbeddingModel(嵌入模型,用于生成向量)
public VectorStore vectorStore(EmbeddingModel embeddingModel) {
// 创建并返回 内存版简单向量存储
return new SimpleVectorStore(embeddingModel);
}
写⼊向量数据库
java
/**
* 项目启动时自动执行:读取服务条款 → 文本分块 → 向量化 → 存入向量库
*/
@Bean
CommandLineRunner ingestTermOfServiceToVectorStore(
EmbeddingModel embeddingModel, // 嵌入模型(生成向量)
VectorStore vectorStore, // 向量数据库(存储向量)
@Value("classpath:rag/terms-of-service.txt") Resource termsOfServiceDocs // 文档资源
) {
// CommandLineRunner:SpringBoot启动后自动执行
return args -> {
vectorStore.write(
// 2. 文本分块:把长文本切成适合AI处理的小段
new TokenTextSplitter().transform(
// 1. 读取本地文档:读取terms-of-service.txt文本内容
new TextReader(termsOfServiceDocs).read()
)
);
};
}
配置Advisor
java
this.chatClient = chatClientBuilder
.defaultSystem("""
您是航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。
您正在通过在线聊天系统与客户互动。
在提供有关预订或取消预订的信息之前,您必须始终从用户处获取以下信息:预订号、客户姓名。
在询问用户之前,请检查消息历史记录以获取此信息。
在更改预订之前,您必须确保条款允许这样做。
如果更改需要收费,您必须在继续之前征得用户同意。
使用提供的功能获取预订详细信息、更改预订和取消预订。
如果需要,可以调用相应函数调用完成辅助动作。
请讲中文。
今天的日期是 {current_date}.
""")
.defaultAdvisors(
new PromptChatMemoryAdvisor(chatMemory), // 对话记忆
new QuestionAnswerAdvisor(vectorStore, SearchRequest.defaults()), // RAG知识库检索
new LoggingAdvisor() // 日志记录
)
.defaultFunctions(
"getBookingDetails", // 查询预订详情
"changeBooking", // 修改预订
"cancelBooking" // 取消预订
)
.build();