链载Ai

标题: Spring AI Alibaba搭建机票助手(实战篇) [打印本页]

作者: 链载Ai    时间: 3 小时前
标题: Spring AI Alibaba搭建机票助手(实战篇)
背景:Spring AI Alibaba 开源项目基于 Spring AI 构建,是阿里云通义系列模型及服务在 Java AI 应用开发领域的最佳实践,提供高层次的 AI API 抽象与云原生基础设施集成方案,帮助开发者快速构建 AI 应用。
步骤一:拉取项目
Spring AI Alibaba官方文档:https://java2ai.com/docs/1.0.0-M5.1/overview/?spm=4347728f.7a696532.0.0.55ca6e97w8zCXV
由于Github需要魔法,可以加入技术群获取。
步骤二:启动
后端:
前端:
页面:
步骤三:解读
pom.xml
<properties><java.version>17</java.version><vaadin.version>24.4.7</vaadin.version><maven-deploy-plugin.version>3.1.1</maven-deploy-plugin.version><spring-ai-alibaba.version>1.0.0-M6.1</spring-ai-alibaba.version></properties>
jdk版本不低于17,spring-ai-alibaba的版本为1.0.0-M6.1,基于Spring Boot 3.x开发。
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency>
基于响应式编程
AssistantConfig
@Configuration@Slf4jpublicclassAssistantConfig{ /**  * 航班助理  *  *@parammodelBuilder  *@paramvectorStore  *@paramchatMemory  */ @Bean publicChatClientgetChatClient(ChatClient.Builder modelBuilder, VectorStore vectorStore, ChatMemory chatMemory){    log.info("航班助理配置CustomerSupportAssistant()..");   ChatClientchatClient=modelBuilder        .defaultSystem("""            	您是“Flight-Booking”航空公司的客户聊天支持代理,请以友好、乐于助人且愉快的方式来回复.            	您正在通过在线聊天系统与客户互动.            	您能够支持已有机票的预订详情查询、机票日期改签、机票预订取消等操作,其余功能将在后续版本中添加,如果用户问的问题不支持请告知详情.              在提供有关机票预订详情查询、机票日期改签、机票预订取消等操作之前,您必须始终从用户处获取以下信息:预订号、客户姓名.              在为用户查询信息后,每个字段的内容都需要分行展示,分行显示内容时注意保持样式一致,需要使用-分行显示,其他格式不符合.              在询问用户之前,请检查消息历史记录以获取预订号、客户姓名等信息,尽量避免重复询问给用户造成困扰.              在更改预订之前,您必须确保条款允许这样做.              如果更改需要收费,您必须在继续之前征得用户同意.              使用提供的功能获取预订详细信息、更改预订和取消预订.              如果需要,您可以调用相应函数辅助完成.              请讲中文.              今天的日期是 {current_date}.            """)        .defaultAdvisors(           // 会话记忆           newPromptChatMemoryAdvisor(chatMemory),
// 存储,基于RAG newQuestionAnswerAdvisor(vectorStore, SearchRequest.builder().topK(4).similarityThresholdAll().build()),
// logger 日志打印 newSimpleLoggerAdvisor() ) .defaultFunctions( "getBookingDetails", "changeBooking", "cancelBooking" ) .build(); returnchatClient; }
@Bean CommandLineRunneringestTermOfServiceToVectorStore(EmbeddingModel embeddingModel, VectorStore vectorStore, @Value("classpath:rag/terms-of-service.txt")Resource termsOfServiceDocs) { log.info("向量数据存储.."); returnargs -> { // Ingest the document into the vector store vectorStore.write(newTokenTextSplitter().transform(newTextReader(termsOfServiceDocs).read()));
vectorStore.similaritySearch("Cancelling Bookings").forEach(doc -> { log.info("Similar Document: {}", doc.getText()); }); }; }
@Bean publicVectorStorevectorStore(EmbeddingModel embeddingModel){ log.info("vectorStore初始化.."); returnSimpleVectorStore.builder(embeddingModel).build(); }
@Bean publicChatMemorychatMemory(){ log.info("chatMemory().."); returnnewInMemoryChatMemory(); }
@Bean @ConditionalOnMissingBean publicRestClient.BuilderrestClientBuilder(){ log.info("restClientBuilder().."); returnRestClient.builder(); }}
这个配置在chatClient使用前配置系统角色,基于RAG的模式投喂给大模型机票助手应该具备哪些规则,ChatMemory使其具备聊天记忆功能,Function Calling支持函数调用.
AssistantController
@RequestMapping(path="/chat",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<String>chat(StringchatId,StringuserMessage){returnassistantService.chat(chatId,userMessage);}
这段基于流式回答,chatId标志一次对话,该演示项目为对接数据库,所有数据均为临时,可以基于业务需求,建表存储会话和消息记录。
AssistantServiceImpl
/***用户对话**@paramchatId*@paramuserMessageContent*@return*/publicFlux<String>chat(StringchatId,StringuserMessageContent){log.info("用户对话ID:{}",chatId);returnthis.chatClient.prompt().system(s->s.param("current_date",LocalDate.now().toString())).user(userMessageContent).advisors(a->a.param(CHAT_MEMORY_CONVERSATION_ID_KEY,chatId).param(CHAT_MEMORY_RETRIEVE_SIZE_KEY,100)).stream().content();}
注意点:current_date当做参数传递,细心的小伙伴注意到AssistantConfig的提示词中含有该参数,大家可以根据需求自行传递,如控制用户权限。
BookingTools[核心]
@Bean@Description("获取机票预定详细信息")publicFunction<BookingDetailsRequest,BookingDetails>getBookingDetails(){	log.info("获取机票预定详细信息1..");returnrequest->{		log.info("获取机票预定详细信息2..");try{returnflightBookingService.getBookingDetails(request.bookingNumber(),request.name());		}catch(Exceptione){			logger.warn("Bookingdetails:{}",NestedExceptionUtils.getMostSpecificCause(e).getMessage());returnnewBookingDetails(request.bookingNumber(),request.name(),null,null,null,null,null);		}	};}
publicrecordBookingDetailsRequest(StringbookingNumber,Stringname){}
以"获取机票信息"函数为例,其他函数同理;其BookingTools类添加了注解Configuration,意味着项目启动就会初始化,如果侧重于业务,@Service注解同样也可以实现!
其中请求体record是jdk17具备的,简化了实体类的创建,参数bookingNumber即为预约号,name即为用户名。
大家可以利用MCP功能,基于@Tool等注解改写代码,实现功能。
步骤四:使用
至此,使用Spring AI Alibaba搭建智能机票助手已实现。但应用到实际需求时,大模型处理用户提供的时间[时分秒]总是出错,欢迎大家提供解决方案!






欢迎光临 链载Ai (https://www.lianzai.com/) Powered by Discuz! X3.5