当前位置: 首页 > news >正文

007-Spring AI Alibaba Agent 功能完整案例

本案例展示如何使用 Spring AI Alibaba 构建一个 AI 驱动的智能系统,该系统具备检索增强生成(RAG)、函数调用和与用户交互的能力。我们将通过一个航班预订助手示例来演示这些功能。

1. 案例目标

我们将创建一个智能航班预订助手,具备以下核心功能:

  1. 自然语言交互:用户可以通过自然语言与助手进行对话,无需学习特定的命令或界面操作。
  2. 检索增强生成(RAG):助手可以访问条款和条件文档,基于这些信息回答用户的问题。
  3. 函数调用:助手可以调用 Java 方法执行特定操作,如查询预订详情、更改预订和取消预订。
  4. 记忆能力:助手能够记住对话历史,实现上下文感知的多轮对话。

2. 技术栈与核心依赖

  • Spring Boot 3.x
  • Spring AI Alibaba (用于对接阿里云 DashScope 通义大模型)
  • Spring WebFlux (用于构建响应式 Web 应用)
  • Maven (项目构建工具)

在 pom.xml 中,你需要引入以下核心依赖:

<dependencies><!-- Spring AI Alibaba 核心启动器,集成 DashScope --><dependency><groupId>com.alibaba.cloud.ai</groupId><artifactId>spring-ai-alibaba-starter-dashscope</artifactId></dependency><!-- Spring WebFlux 用于构建响应式 RESTful API --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency><!-- Spring AI 向量存储顾问 --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-advisors-vector-store</artifactId></dependency><!-- Spring Boot 验证器 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
</dependencies>

3. 项目配置

在 src/main/resources/application.properties 文件中,配置你的 DashScope API Key 和其他设置。

# 设置服务器端口
server.port=9000# 启用虚拟线程
spring.threads.virtual.enabled=true# 配置 DashScope API Key
spring.ai.dashscope.api-key=${AI_DASHSCOPE_API_KEY}
spring.ai.dashscope.chat.options.model=qwen-max# 禁用 Thymeleaf 缓存(开发环境)
spring.thymeleaf.cache=false

重要提示:请将 AI_DASHSCOPE_API_KEY 环境变量设置为你从阿里云获取的有效 API Key。你也可以直接将其写在配置文件中,但这不推荐用于生产环境。

4. 核心组件实现

4.1 应用主类配置

在 AgentApplication.java 中,我们配置了向量存储、聊天记忆和文档摄取等核心组件:

@SpringBootApplication
public class AgentApplication {// 文档摄取到向量存储@BeanCommandLineRunner ingestTermOfServiceToVectorStore(VectorStore vectorStore,@Value("classpath:rag/terms-of-service.txt") Resource termsOfServiceDocs) {return args -> {// 将文档分割并存储到向量存储中vectorStore.write(new TokenTextSplitter().transform(new TextReader(termsOfServiceDocs).read()));// 测试相似性搜索vectorStore.similaritySearch("Cancelling Bookings").forEach(doc -> {logger.info("Similar Document: {}", doc.getText());});};}// 向量存储配置@Beanpublic VectorStore vectorStore(EmbeddingModel embeddingModel) {return SimpleVectorStore.builder(embeddingModel).build();}// 聊天记忆配置@Beanpublic ChatMemory chatMemory() {return MessageWindowChatMemory.builder().build();}
}

4.2 AI 助手服务

CustomerSupportAssistant.java 是本示例的核心组件,它整合了 RAG、函数调用和记忆能力:

@Service
public class CustomerSupportAssistant {private final ChatClient chatClient;public CustomerSupportAssistant(ChatClient.Builder modelBuilder, VectorStore vectorStore, ChatMemory chatMemory) {this.chatClient = modelBuilder.defaultSystem("""您是"Funnair"航空公司的客户聊天支持代理。请以友好、乐于助人且愉快的方式来回复。您正在通过在线聊天系统与客户互动。您能够支持已有机票的预订详情查询、机票日期改签、机票预订取消等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情。在提供有关机票预订详情查询、机票日期改签、机票预订取消等操作之前,您必须始终从用户处获取以下信息:预订号、客户姓名。在询问用户之前,请检查消息历史记录以获取预订号、客户姓名等信息,尽量避免重复询问给用户造成困扰。在更改预订之前,您必须确保条款允许这样做。如果更改需要收费,您必须在继续之前征得用户同意。使用提供的功能获取预订详细信息、更改预订和取消预订。如果需要,您可以调用相应函数辅助完成。请讲中文。今天的日期是 {current_date}.""").defaultAdvisors(PromptChatMemoryAdvisor.builder(chatMemory).build(), // Chat Memorynew QuestionAnswerAdvisor(vectorStore), // RAGnew SimpleLoggerAdvisor() // 日志记录).defaultToolNames("getBookingDetails","changeBooking","cancelBooking").build();}public Flux<String> chat(String chatId, String userMessageContent) {return this.chatClient.prompt().system(s -> s.param("current_date", LocalDate.now().toString())).user(userMessageContent).advisors(a -> a.param(CONVERSATION_ID, chatId).param(TOP_K, 100)).stream().content();}
}

4.3 工具函数实现

在 BookingTools.java 中,我们定义了可以被 AI 助手调用的工具函数:

@Configuration
public class BookingTools {@Autowiredprivate FlightBookingService flightBookingService;public record BookingDetailsRequest(String bookingNumber, String name) {}public record ChangeBookingDatesRequest(String bookingNumber, String name, String date, String from, String to) {}public record CancelBookingRequest(String bookingNumber, String name) {}@JsonInclude(Include.NON_NULL)public record BookingDetails(String bookingNumber, String name, LocalDate date, BookingStatus bookingStatus,String from, String to, String bookingClass) {}// 获取预订详情@Bean@Description("获取机票预定详细信息")public Function<BookingDetailsRequest, BookingDetails> getBookingDetails() {return request -> {try {return flightBookingService.getBookingDetails(request.bookingNumber(), request.name());}catch (Exception e) {logger.warn("Booking details: {}", NestedExceptionUtils.getMostSpecificCause(e).getMessage());return new BookingDetails(request.bookingNumber(), request.name(), null, null, null, null, null);}};}// 修改预订@Bean@Description("修改机票预定日期")public Function<ChangeBookingDatesRequest, String> changeBooking() {return request -> {flightBookingService.changeBooking(request.bookingNumber(), request.name(), request.date(), request.from(),request.to());return "";};}// 取消预订@Bean@Description("取消机票预定")public Function<CancelBookingRequest, String> cancelBooking() {return request -> {flightBookingService.cancelBooking(request.bookingNumber(), request.name());return "";};}
}

4.4 航班预订服务

FlightBookingService.java 实现了实际的业务逻辑,包括预订查询、修改和取消:

@Service
public class FlightBookingService {private final BookingData db;public FlightBookingService() {db = new BookingData();initDemoData();}// 初始化演示数据private void initDemoData() {// 创建5条模拟预订数据// ...}// 获取所有预订public List<BookingDetails> getBookings() {return db.getBookings().stream().map(this::toBookingDetails).toList();}// 获取预订详情public BookingDetails getBookingDetails(String bookingNumber, String name) {var booking = findBooking(bookingNumber, name);return toBookingDetails(booking);}// 修改预订public void changeBooking(String bookingNumber, String name, String newDate, String from, String to) {var booking = findBooking(bookingNumber, name);if (booking.getDate().isBefore(LocalDate.now().plusDays(1))) {throw new IllegalArgumentException("Booking cannot be changed within 24 hours of the start date.");}booking.setDate(LocalDate.parse(newDate));booking.setFrom(from);booking.setTo(to);}// 取消预订public void cancelBooking(String bookingNumber, String name) {var booking = findBooking(bookingNumber, name);if (booking.getDate().isBefore(LocalDate.now().plusDays(2))) {throw new IllegalArgumentException("Booking cannot be cancelled within 48 hours of the start date.");}booking.setBookingStatus(BookingStatus.CANCELLED);}// 辅助方法private Booking findBooking(String bookingNumber, String name) {return db.getBookings().stream().filter(b -> b.getBookingNumber().equalsIgnoreCase(bookingNumber)).filter(b -> b.getCustomer().getName().equalsIgnoreCase(name)).findFirst().orElseThrow(() -> new IllegalArgumentException("Booking not found"));}private BookingDetails toBookingDetails(Booking booking) {return new BookingDetails(booking.getBookingNumber(), booking.getCustomer().getName(), booking.getDate(),booking.getBookingStatus(), booking.getFrom(), booking.getTo(), booking.getBookingClass().toString());}
}

4.5 控制器层

AssistantController.java 提供了 REST API 接口:

@RestController
@RequestMapping("/api/assistant")
public class AssistantController {private final CustomerSupportAssistant agent;public AssistantController(CustomerSupportAssistant agent) {this.agent = agent;}@RequestMapping(path="/chat", produces = MediaType.TEXT_EVENT_STREAM_VALUE)public Flux<String> chat(@RequestParam(name = "chatId") String chatId,@RequestParam(name = "userMessage") String userMessage) {return agent.chat(chatId, userMessage);}
}

5. RAG 文档准备

在 src/main/resources/rag/terms-of-service.txt 中,我们准备了服务条款文档,用于 RAG 检索:

These Terms of Service govern your experience with Funnair. By booking a flight, you agree to these terms.1. Booking Flights
- Book via our website or mobile app.
- Full payment required at booking.
- Ensure accuracy of personal information (Name, ID, etc.) as corrections may incur a $25 fee.2. Changing Bookings
- Changes allowed up to 24 hours before flight.
- Change via online or contact our support.
- Change fee: $50 for Economy, $30 for Premium Economy, Free for Business Class.3. Cancelling Bookings
- Cancel up to 48 hours before flight.
- Cancellation fees: $75 for Economy, $50 for Premium Economy, $25 for Business Class.
- Refunds processed within 7 business days.

6. 运行与测试

  1. 启动应用:运行 AgentApplication.java 或使用命令 mvn spring-boot:run
  2. 访问前端界面:打开浏览器访问 http://localhost:9000。
  3. 与助手对话:在聊天界面中输入问题或请求。

测试 1:查询预订详情

在聊天界面中输入:

我想查询我的预订详情,我的预订号是101,姓名是云小宝。

预期响应:助手会调用 getBookingDetails 函数,并返回预订详情。

测试 2:修改预订

在聊天界面中输入:

我想修改我的预订,我的预订号是101,姓名是云小宝。我想把日期改为2024-12-25。

预期响应:助手会调用 changeBooking 函数,并修改预订。

测试 3:取消预订

在聊天界面中输入:

我想取消我的预订,我的预订号是101,姓名是云小宝。

预期响应:助手会调用 cancelBooking 函数,并取消预订。

测试 4:询问服务条款

在聊天界面中输入:

取消预订有什么规定?

预期响应:助手会使用 RAG 从服务条款文档中检索相关信息,并回答用户的问题。

7. 实现思路与扩展建议

实现思路

本案例的核心思想是"AI Agent 架构",通过以下组件实现智能助手:

  • 大语言模型(LLM):负责理解用户意图并生成响应。
  • 检索增强生成(RAG):使 AI 能够访问外部知识库,提供准确的信息。
  • 函数调用:使 AI 能够执行实际操作,如查询、修改和取消预订。
  • 记忆能力:使 AI 能够记住对话历史,实现上下文感知的多轮对话。

扩展建议

  • 集成更多数据源:可以集成数据库、API 等更多数据源,扩展助手的功能。
  • 增加更多工具函数:可以添加更多工具函数,如创建新预订、支付处理等。
  • 改进用户界面:可以改进前端界面,提供更好的用户体验。
  • 多语言支持:可以添加多语言支持,使助手能够与不同语言的用户交互。
  • 个性化推荐:可以基于用户历史和偏好,提供个性化的推荐和建议。
  • 情感分析:可以添加情感分析功能,使助手能够识别用户情绪并调整回复风格。
http://www.dtcms.com/a/533518.html

相关文章:

  • app定制开发商城长春seo培训
  • Boost.Iostreams 简介
  • S4.2.6.9 LTSSM 之 Disabled 状态
  • Rag优化 - 如何提升首字响应速度
  • 甘肃省建设厅质量投诉网站wordpress 没有注册
  • 怎么建立自己的网站?调用wordpress评论框
  • 外贸建站的公司京东网站注册
  • 用php做网站用到的工具app软件开发课程
  • 做的最好的微电影网站wordpress v电影
  • 整体设计 全面梳理复盘 之8 元数据标准库 + 原始模板设计与程序联动闭环(豆包助手)
  • 国内最大的开源网站wordpress友情联机
  • 中国flash网站模板中心中国网站名
  • SpringBoot的搭建方式
  • 【每天一个知识点】负二项分布(Negative Binomial Distribution, NB分布)
  • 管理网站建设义乌企业网站搭建首选
  • 重庆网站开发网站维护需要关闭网站么
  • 29-机器学习开发框架比较:分析不同框架的适用场景和优缺点
  • STM32F103C8T6--DMA
  • 佛山网站常见的问题大理州建设局官方网站
  • 做企业网站的研究现状简答题网络营销是什么
  • 阮一峰《TypeScript 教程》学习笔记——tsc 命令
  • pos机做网站推广上传文件到网站根目录
  • 德州王霞网站建设郑州企业建筑设计软件
  • 怎样建设简单的网站网站建设论文任务书
  • 最新电子电气架构(EEA)调研-1
  • 简述网站开发的工作流程企业运营模拟实践报告
  • 做外贸网站平台企业网站建设宣贯
  • 技术支持 湖北网站建设合肥seo公司
  • 如何快速建设推广网站创建手机网站
  • 服饰的网站建设晋江原创网