
简介本资源是一个基于Spring AI与Langchain4j构建的旅游行程规划智能体完整工程面向Java后端开发者、AI应用实践者及高校课程设计学习者解决个性化旅游方案生成、自然语言交互与多阶段行程动态优化等核心问题。压缩包共69个文件涵盖12个Java服务模块含Agent编排、LLM调用与工具链集成、15个Vue前端组件行程可视化、偏好配置与实时对话界面、5个JSON配置与示例数据、以及UML类图/用例图/部署图等5张系统设计图辅以项目文档PDF/DOCX与LICENSE说明整体大小为5.74MB。已有113人学习下载提供从Prompt工程、RAG增强到天气服务对接的端到端实现结构清晰、模块解耦适合快速理解AI智能体在垂直场景中的落地路径与工程组织方式。1. 项目概述当大语言模型遇上行程规划最近在捣鼓一个挺有意思的玩意儿一个能帮你规划旅游行程的智能体。听起来是不是有点像升级版的“马蜂窝”或者“穷游行程助手”但底层逻辑完全不同。传统的行程规划工具要么是基于规则引擎比如“第一天必须去A景点因为它在B景点附近”要么是简单的信息聚合与模板填充灵活性和个性化程度有限。而这个项目核心是让大语言模型LLM来担任那个“见多识广的旅行策划师”。我们不再依赖死板的规则而是利用LLM对自然语言的深刻理解、丰富的世界知识以及一定的推理能力让它根据用户模糊的、口语化的需求比如“我想带爸妈去个暖和的地方玩5天不要太累预算中等”生成一份结构清晰、合理可行的行程计划。为什么用“智能体”这个词因为它不是一次性的问答。一个完整的智能体Agent应该具备感知理解用户输入、规划拆解任务、调用工具、行动执行具体操作如查询信息、计算和反思评估结果、调整策略的能力。我们的旅游行程规划正是一个典型的智能体应用场景它需要理解用户意图规划出“查天气、找景点、算距离、排时间”等一系列子任务并调用相应的工具或能力来逐一完成最终整合成一份报告。技术栈上我选择了Spring AI和Langchain4j这两个目前Java生态里最炙手可热的AI应用框架来搭建。Spring AI提供了与Spring Boot无缝集成的AI能力让注入一个“ChatClient”就像注入一个“DataSource”一样简单而Langchain4j则提供了丰富的、用于构建智能体的“乐高积木”比如工具调用Tool、记忆Memory、提示词模板Prompt Template等。两者的结合能让开发者更专注于业务逻辑而非底层API的繁琐调用。这个项目适合谁呢如果你是一名Java后端开发者对AI应用开发感兴趣想了解如何将LLM能力融入传统业务系统或者你是一名产品经理、创业者在构思基于AI的下一代旅行产品那么通过这个项目的拆解你能获得从技术选型、架构设计到具体实现的全景视图。即使你对AI底层算法不甚了解也能跟着一步步搭建出一个可运行、可演示的智能体原型。2. 核心架构与组件选型解析2.1 为什么是Spring AI Langchain4j在Java世界里构建AI应用框架选择不少比如直接调用各大厂商的SDK或者使用早期的LangChain Java版。但Spring AI和Langchain4j的组合在当前时间点显得尤为合理。Spring AI的核心价值在于“标准化”和“集成”。它定义了一套统一的AI模型访问接口如ChatClientEmbeddingClientImageClient无论底层是OpenAI的GPT、Anthropic的Claude还是阿里云的通义千问、智谱AI的GLM你都可以通过更换一个spring-ai-*starter依赖和配置项来切换代码几乎不用改动。这对于需要保障服务稳定性、可能面临模型供应商切换的场景至关重要。此外它天然融入Spring生态依赖注入、配置管理、Actuator监控等都开箱即用大大降低了运维复杂度。Langchain4j则胜在“工具链”的丰富性。它专为构建复杂的、多步骤的AI智能体而生。虽然Spring AI也提供了基础的Prompt模板和函数调用支持但Langchain4j在以下方面更加强大工具Tools可以非常方便地将任何Java方法封装成AI可调用的工具并自动生成描述供LLM理解。我们的行程规划需要查询天气、搜索景点、计算距离这些都可以封装成独立的Tool。记忆Memory支持对话历史、实体记忆等多种记忆方式能让智能体在多轮对话中记住关键信息比如用户说过对海鲜过敏。链Chains虽然本项目以智能体为主但Langchain4j的链式调用对于标准化处理流程如提取用户信息 - 生成搜索关键词 - 执行搜索 - 格式化输出也非常有用。与Spring AI的兼容性Langchain4j最新版本已经能够直接使用Spring AI提供的ChatClient等作为其底层LLM实现了强强联合。因此我们的架构基调定为以Spring Boot为底座使用Spring AI管理模型连接与核心AI能力使用Langchain4j构建智能体的高级逻辑工具、记忆、规划。这样既能享受Spring生态的便利又能利用Langchain4j强大的智能体构建能力。2.2 智能体工作流设计一个旅游行程规划智能体不能只是让LLM凭空想象。它需要可靠的数据和计算能力作为支撑。我们设计的工作流如下需求解析与澄清用户输入自然语言需求。智能体首先调用LLM提取结构化信息如目的地、出行人数、出行日期、天数、预算范围、兴趣标签美食、古迹、购物等、特殊要求带老人、孩子等。如果信息不足智能体会主动发起提问澄清。信息获取与验证根据解析出的结构化信息智能体规划并执行一系列工具调用天气查询工具获取目标日期、目的地的天气情况这对户外活动安排至关重要。景点/POI搜索工具根据兴趣标签从本地数据库或第三方API如高德、百度地图的POI接口获取景点列表、开放时间、门票价格、评分等信息。地理与路线工具计算景点之间的通勤距离与时间步行、驾车、公共交通这是合理排程的基础。预算估算工具结合酒店、餐饮、门票的均价数据对总花费进行粗略估算。行程编排与优化LLM作为“总调度师”拿到所有工具返回的原始数据后进行综合编排。它需要考虑时间约束每天合理的活动时长如上午、下午、晚上各1-2个主要活动。地理邻近将地理位置靠近的景点安排在同一个半天。体力分配劳逸结合避免连续安排高强度活动。兴趣匹配优先安排用户高兴趣标签的活动。突发情况预留一定的缓冲时间和备选方案。输出与交互生成一份格式友好、细节丰富的行程单通常以Markdown格式输出包含每日概览、时间点、活动详情、费用预估、注意事项等。并可以支持后续交互如“把第二天下午的博物馆换成科技馆”、“预算再压缩10%”等调整。注意这里的关键是让LLM负责“思考”和“决策”而让工具负责提供“事实”和“计算”。LLM可能会犯“事实性错误”比如记错某个景点的开放时间但工具提供的数据是准确的。LLM也可能不擅长复杂计算比如最优路径规划但可以调用专门的路线计算工具。这种“大脑”与“手脚”的分工是构建可靠AI智能体的核心模式。3. 环境搭建与核心依赖配置3.1 初始化Spring Boot项目使用你熟悉的IDE如IntelliJ IDEA或 Spring Initializr 创建项目。核心依赖选择Spring Boot 3.x建议使用3.2.x或以上版本对Java 17有更好的支持。Spring AI选择对应的BOMBill of Materials来管理版本。在pom.xml中首先引入Spring AI的BOM。dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version0.8.1/version !-- 请使用最新稳定版 -- typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement然后添加你选定的AI模型供应商的starter。例如我们使用OpenAIGPT模型作为LLM引擎dependencies !-- Spring Boot Web (用于提供REST API) -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI OpenAI -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency !-- Langchain4j 核心 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId version0.31.0/version !-- 请使用最新稳定版 -- /dependency !-- Langchain4j 与 Spring AI 集成 -- dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-spring-ai/artifactId version0.31.0/version /dependency !-- 其他工具类依赖如JSON处理、HTTP客户端等 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-json/artifactId /dependency !-- 示例中用于调用外部API -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-webflux/artifactId /dependency /dependencies如果你想使用阿里云的通义千问则替换spring-ai-openai-starter为spring-ai-alibaba-ai-spring-boot-starter并配置相应的AK/SK。3.2 关键配置详解在application.yml中我们需要配置AI模型连接和基础参数。spring: ai: openai: api-key: ${OPENAI_API_KEY:你的OpenAI-API-KEY} # 强烈建议通过环境变量注入 chat: options: model: gpt-4o-mini # 根据成本和性能选择gpt-4-turbo, gpt-4o等 temperature: 0.2 # 温度值调低让行程规划更稳定、可重复 max-tokens: 4000 # 根据输出行程的详细程度调整 # 自定义配置第三方服务示例 travel: amap: api-key: ${AMAP_API_KEY} # 高德地图Web服务API Key用于地理编码和路径规划 weather: api-key: ${WEATHER_API_KEY} # 和风天气等服务的API Key配置要点解析API密钥安全绝对不要将API密钥硬编码在代码或配置文件中提交到Git。使用环境变量${VAR_NAME}或配置中心管理。模型选择gpt-4o-mini或gpt-4-turbo在成本、速度和能力上比较平衡适合此类任务。temperature设置为较低值如0.1-0.3可以减少LLM的随机性让生成的行程更稳定可靠。Token限制行程规划输出可能较长需要预留足够的max-tokens。同时输入用户需求工具返回数据也可能很长需注意总token数不要超过模型上下文长度限制。3.3 基础Bean配置与Langchain4j集成我们需要配置一个Bean将Spring AI的ChatClient桥接到Langchain4j的ChatLanguageModel接口以便Langchain4j使用我们配置的模型。import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.spring.AiPlatformChatModel; import org.springframework.ai.chat.ChatClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class AiConfig { Bean public ChatLanguageModel chatLanguageModel(ChatClient chatClient) { // 将Spring AI的ChatClient适配为Langchain4j的ChatLanguageModel return new AiPlatformChatModel(chatClient); } }这样我们就可以在后续的Service中注入ChatLanguageModel并使用Langchain4j的全套功能了。4. 核心工具Tools的实现与封装智能体的“手脚”就是各种工具。我们将行程规划中需要的几个关键能力封装成独立的Tool。4.1 天气查询工具这个工具调用外部天气API获取指定城市和日期的天气预报。import dev.langchain4j.agent.tool.Tool; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import java.time.LocalDate; Component public class WeatherTool { private final WebClient webClient; Value(${travel.weather.api-key}) private String apiKey; public WeatherTool(WebClient.Builder webClientBuilder) { this.webClient webClientBuilder.baseUrl(https://api.weather.com/v3).build(); } Tool(根据城市名称和日期查询天气预报信息。返回天气状况、最高最低温度、降水概率等。) public String getWeatherForecast(String cityName, LocalDate date) { // 构建请求逻辑这里以伪代码和简化的响应处理为例 // 实际应调用和风天气、OpenWeatherMap等服务的API String response webClient.get() .uri(uriBuilder - uriBuilder .path(/weather/forecast/daily) .queryParam(city, cityName) .queryParam(date, date.toString()) .queryParam(key, apiKey) .build()) .retrieve() .bodyToMono(String.class) .block(); // 生产环境建议使用非阻塞式这里简化 // 解析JSON响应提取关键信息并格式化为自然语言描述 // 例如解析出 weatherText, tempMax, tempMin, precipProbability // return String.format(%s%s日天气%s气温%d°C到%d°C降水概率%d%%。, cityName, date, weatherText, tempMin, tempMax, precipProb); // 模拟返回 return String.format(%s在%s的天气预计为晴转多云最高气温28°C最低气温20°C降水概率10%%。, cityName, date); } }关键点Tool注解是Langchain4j的核心它会把该方法描述注解中的字符串注入给LLM让LLM知道在什么情况下调用这个工具。工具方法应尽量设计为纯函数输入输出明确。返回的字符串应简洁、信息量大便于LLM理解并用于后续推理。生产环境中需要考虑API调用的频率限制、失败重试、降级策略如返回缓存数据或默认值。4.2 景点搜索工具这个工具从数据源可以是本地数据库、Elasticsearch或第三方POI API搜索景点。import dev.langchain4j.agent.tool.Tool; import org.springframework.stereotype.Component; import java.util.List; import java.util.stream.Collectors; Component public class PoiSearchTool { // 假设我们有一个本地的景点信息服务层 private final PointOfInterestService poiService; public PoiSearchTool(PointOfInterestService poiService) { this.poiService poiService; } Tool(根据城市和兴趣标签如博物馆、自然风光、美食、亲子搜索景点。返回景点名称、简介、建议游玩时长、门票价格和评分。) public String searchPointsOfInterest(String city, ListString tags) { ListPointOfInterest pois poiService.searchByCityAndTags(city, tags); if (pois.isEmpty()) { return String.format(在%s未找到标签为%s的景点。, city, tags); } // 将POI列表格式化为LLM易于处理的文本 return pois.stream() .map(poi - String.format(- 【%s】%s。建议游玩%s小时。门票%s。评分%s/5。, poi.getName(), poi.getDescription(), poi.getSuggestedDuration(), poi.getTicketPrice(), poi.getRating())) .collect(Collectors.joining(\n)); } }实操心得POI数据的质量直接决定行程的吸引力。初期可以爬取公开数据或使用免费API但要做好数据清洗去重、纠正地址、补充开放时间。后期可以考虑接入商业化的POI数据服务。4.3 路线规划与时间估算工具这是行程合理性的核心。我们调用地图服务的路径规划API。import dev.langchain4j.agent.tool.Tool; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.reactive.function.client.WebClient; Component public class RoutingTool { private final WebClient webClient; Value(${travel.amap.api-key}) private String apiKey; public RoutingTool(WebClient.Builder webClientBuilder) { this.webClient webClientBuilder.baseUrl(https://restapi.amap.com/v3).build(); } Tool(计算两个地点之间的通勤距离和时间。地点可以是具体地址或景点名称。返回驾驶距离公里、驾驶时间分钟和公共交通时间分钟估算。) public String calculateRoute(String origin, String destination) { // 1. 地理编码将地址转换为经纬度 (这里省略假设已有经纬度或直接使用地名搜索) // 2. 路径规划 // 调用高德地图路径规划API String response webClient.get() .uri(uriBuilder - uriBuilder .path(/direction/driving) .queryParam(origin, origin) .queryParam(destination, destination) .queryParam(key, apiKey) .build()) .retrieve() .bodyToMono(String.class) .block(); // 解析JSON提取 distance米和 duration秒 // 简化为模拟数据 int drivingDistanceMeters 5000; // 5公里 int drivingDurationSeconds 1200; // 20分钟 // 公共交通时间通常为驾驶时间的1.5-3倍这里简单估算 int transitDurationSeconds (int)(drivingDurationSeconds * 2.5); return String.format(从【%s】到【%s】。驾车距离%.1f公里约%d分钟。公共交通约%d分钟。, origin, destination, drivingDistanceMeters / 1000.0, drivingDurationSeconds / 60, transitDurationSeconds / 60); } }注意地图API通常有每日调用限额。在智能体规划行程时可能会频繁调用此工具为多个景点对计算距离。因此需要实现一个简单的缓存层对相同的(origin, destination)对缓存计算结果有效期内直接返回避免不必要的API调用和费用。5. 智能体Agent的组装与提示词工程有了工具接下来就是组装大脑——智能体。5.1 构建智能体并注入工具我们使用Langchain4j的AiServices来便捷地创建一个智能体。import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; import dev.langchain4j.service.V; import dev.langchain4j.service.spring.AiService; // 定义智能体接口 interface TravelPlanningAgent { SystemMessage( 你是一个专业的、经验丰富的旅行规划师。你的任务是根据用户的需求为他们制定详细、可行、个性化的旅行行程。 在规划时请务必遵循以下原则 1. **充分利用工具**你必须使用提供的工具来获取准确的天气、景点信息和路线时间不得凭空捏造数据。 2. **合理性与舒适度**每天安排3-4个主要活动为宜劳逸结合。景点间移动要预留充足时间。 3. **个性化**紧密围绕用户的兴趣、预算和特殊要求如带老人、孩子进行规划。 4. **输出格式**最终行程请以清晰的Markdown格式输出包含每日概览、时间线、活动详情、费用预估和温馨提示。 规划步骤建议 1. 解析用户需求明确关键要素目的地、时间、人数、兴趣、预算、要求。 2. 查询目的地天气。 3. 根据兴趣搜索景点。 4. 基于景点位置和开放时间结合路线工具计算的时间进行每日编排。 5. 生成最终行程。 如果用户需求信息不足请主动、友好地提问澄清。 ) String planTrip(UserMessage String userRequest); } Service public class TravelAgentService { private final TravelPlanningAgent agent; public TravelAgentService(ChatLanguageModel chatLanguageModel, WeatherTool weatherTool, PoiSearchTool poiSearchTool, RoutingTool routingTool) { // 使用AiServices创建智能体实例并绑定工具和模型 this.agent AiServices.builder(TravelPlanningAgent.class) .chatLanguageModel(chatLanguageModel) .tools(weatherTool, poiSearchTool, routingTool) // 注入所有工具 .build(); } public String invokePlanning(String userRequest) { return agent.planTrip(userRequest); } }代码解析SystemMessage定义了智能体的“角色”和“行为准则”。这是提示词工程的关键直接决定了智能体的输出质量和风格。我们在这里详细规定了它的身份、原则、步骤和输出格式。AiServices.builder(...)这是Langchain4j的核心API它自动将工具、模型和接口绑定起来。当LLM在执行planTrip方法时如果认为需要调用工具它会自动生成相应的工具调用请求执行工具后再将结果返回给LLM继续推理。V注解如果需要将复杂对象作为参数可以使用V注解来指定映射关系本例中简化使用了字符串。5.2 设计高效的系统提示词System Prompt系统提示词是智能体的“灵魂”。上面示例中的提示词已经包含了很多要点这里再深入拆解一下设计技巧明确角色与目标“你是一个专业的、经验丰富的旅行规划师”——开门见山定下基调。规定强制性动作“你必须使用提供的工具...”——这是确保输出基于事实而非幻觉的关键指令。灌输领域知识“每天安排3-4个主要活动为宜劳逸结合。”——将人类专家的经验编码进去。结构化输出要求“以清晰的Markdown格式输出包含每日概览、时间线...”——让输出规整便于前端渲染或用户阅读。提供思维链Chain-of-Thought指引“规划步骤建议1. 解析... 2. 查询... 3. 搜索... 4. 编排... 5. 生成...”——引导LLM进行有序的、分步的思考这能显著提升复杂任务的成功率。处理边界情况“如果用户需求信息不足请主动、友好地提问澄清。”——让智能体具备交互能力。实操心得提示词的优化是一个迭代过程。初期可以简单些然后通过大量真实用户query测试观察智能体在哪里“犯傻”比如同一天安排两个距离很远的景点、忽略了用户的预算限制然后针对性修改和强化提示词。可以将常见的“错误模式”和“正确示例”以Few-Shot的方式加入到提示词中效果更佳。6. 服务层与API暴露智能体组装好后我们需要通过一个REST API来暴露它的能力。import org.springframework.web.bind.annotation.*; RestController RequestMapping(/api/travel) public class TravelPlanningController { private final TravelAgentService travelAgentService; public TravelPlanningController(TravelAgentService travelAgentService) { this.travelAgentService travelAgentService; } PostMapping(/plan) public ResponseEntityTravelPlanResponse createTravelPlan(RequestBody TravelPlanRequest request) { // 1. 参数基础校验 if (request null || StringUtils.isBlank(request.getUserRequest())) { return ResponseEntity.badRequest().body(new TravelPlanResponse(用户请求不能为空)); } try { // 2. 调用智能体服务 String planMarkdown travelAgentService.invokePlanning(request.getUserRequest()); // 3. 构造响应 TravelPlanResponse response new TravelPlanResponse(); response.setStatus(success); response.setPlanMarkdown(planMarkdown); response.setGeneratedAt(LocalDateTime.now()); return ResponseEntity.ok(response); } catch (Exception e) { // 4. 异常处理可能是LLM API超时、工具调用失败等 log.error(行程规划失败用户请求{}, request.getUserRequest(), e); return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) .body(new TravelPlanResponse(行程规划服务暂时不可用请稍后重试。)); } } } // 简单的请求响应对象 Data class TravelPlanRequest { private String userRequest; // 未来可以扩展更多结构化字段如userId用于记忆 } Data class TravelPlanResponse { private String status; // success, error private String planMarkdown; private String errorMessage; private LocalDateTime generatedAt; public TravelPlanResponse(String errorMessage) { this.status error; this.errorMessage errorMessage; } }注意事项异步处理行程规划可能耗时较长多次LLM调用多次工具调用。对于生产环境应考虑将请求异步化立即返回一个任务ID然后通过WebSocket或轮询接口让客户端获取结果。限流与降级AI服务调用成本较高且可能有速率限制。需要在API网关或Controller层添加限流如使用Resilience4j或Sentinel防止恶意或过高频率的调用。上下文管理目前的实现是无状态的。为了实现多轮对话例如用户说“把第二天下午的行程改一下”需要引入对话Memory。可以为每个会话创建一个独立的智能体实例并关联一个持久化的ChatMemory如使用Redis存储在后续请求中传入ConversationId来恢复上下文。7. 效果测试、优化与问题排查7.1 测试用例设计如何验证智能体是否工作良好需要设计多维度的测试用例功能正确性输入“帮我规划一个北京3日游喜欢历史和美食。”验证点输出是否包含故宫、天坛等历史景点是否推荐了烤鸭、炸酱面等美食行程天数是否为3天工具调用验证输入“下周末杭州天气如何有什么适合孩子的室内景点”验证点日志中是否出现了对WeatherTool和PoiSearchTool带“亲子”标签的调用约束条件满足输入“预算5000元两人上海玩4天。”验证点生成的行程末尾是否有大致的费用估算总费用是否在预算附近异常与边界处理输入“明天去火星旅行。”验证点智能体是生成了一个荒谬的行程还是合理地回复“无法查询到火星的旅行信息”或要求用户提供有效目的地输入空输入或乱码验证点服务是否返回了清晰的错误提示而非崩溃7.2 常见问题与优化策略在实际开发和测试中你可能会遇到以下典型问题问题现象可能原因排查与优化策略智能体不调用工具全靠LLM幻想系统提示词中“必须使用工具”的指令不够强工具描述不清晰。1. 强化系统提示词例如“严禁凭空猜测数据所有天气、景点、距离信息必须通过调用相应工具获得。”2. 检查工具方法上的Tool注解描述确保清晰、准确包含关键参数说明。工具调用顺序混乱或多余LLM的规划能力不足。1. 在系统提示词中提供更详细的“思维链”指引明确步骤顺序。2. 考虑使用更高级的“规划智能体”模式如使用Langchain4j的PlanAndExecuteAgent或将复杂规划拆分成多个按顺序执行的小智能体。生成的行程时间安排不合理LLM对时间、距离的感知能力弱路线工具返回的数据未被有效利用。1. 在提示词中强调“结合路线工具计算出的具体时间进行安排”。2. 让工具返回的数据更结构化、更突出例如“驾车需45分钟”便于LLM捕捉。3. 在后处理阶段可以增加一个“行程合理性校验”环节用规则简单检查是否存在明显的时间冲突。处理长上下文时性能差、费用高用户需求复杂或工具返回数据量大导致token消耗剧增。1.精简工具输出让工具只返回最核心的信息去掉冗余描述。2.摘要与过滤在将大量POI数据喂给LLM前先让另一个LLM调用或使用简单算法根据相关性进行筛选和摘要。3.使用更大上下文窗口的模型如GPT-4 Turbo128K。但成本需权衡。多轮对话中忘记之前的信息未启用或正确配置ChatMemory。1. 为智能体配置ChatMemory如MessageWindowChatMemory并确保每次对话使用相同的memoryId。2. 在提示词中提醒智能体参考对话历史例如“以下是之前的对话历史[历史]”。7.3 引入记忆Memory实现多轮对话要让智能体记住上下文修改TravelAgentServiceimport dev.langchain4j.memory.ChatMemory; import dev.langchain4j.memory.chat.MessageWindowChatMemory; Service public class TravelAgentService { private final ChatLanguageModel chatLanguageModel; private final WeatherTool weatherTool; // ... 其他工具 // 用于存储不同会话的记忆 private final MapString, ChatMemory memoryStore new ConcurrentHashMap(); public TravelAgentService(ChatLanguageModel chatLanguageModel, WeatherTool weatherTool /*, ... */) { this.chatLanguageModel chatLanguageModel; this.weatherTool weatherTool; // ... } public String chat(String sessionId, String userMessage) { // 获取或创建该会话的记忆 ChatMemory memory memoryStore.computeIfAbsent(sessionId, id - MessageWindowChatMemory.withMaxMessages(20)); // 保留最近20条消息 // 创建带有记忆的智能体 TravelPlanningAgent agent AiServices.builder(TravelPlanningAgent.class) .chatLanguageModel(chatLanguageModel) .tools(weatherTool, poiSearchTool, routingTool) .chatMemory(memory) // 关键注入记忆 .build(); return agent.planTrip(userMessage); // 这次调用会自动包含历史消息 } }这样当同一sessionId的用户再次提问“那预算能不能再减少一点”时智能体就能回忆起之前生成的行程并进行调整了。8. 项目总结与进阶思考通过这个项目我们完成了一个从需求理解、工具调用到行程生成的完整AI智能体闭环。它不再是简单的聊天机器人而是一个能够执行复杂任务、具备一定自主性的数字助手。我个人在实现过程中的几点深刻体会提示词的质量决定智能体的上限模型和工具是“硬实力”提示词是“软实力”。花在打磨提示词上的时间往往比调试代码的回报率更高。多观察、多测试、多迭代。工具的设计要“傻瓜化”给LLM用的工具其接口和返回应该尽可能简单、明确、无歧义。复杂的对象结构、嵌套的JSON很容易让LLM解析出错。返回纯文本的自然语言描述往往是最可靠的。成本与延迟是工程化的核心挑战每一次工具调用和LLM调用都意味着时间和金钱。需要精心设计流程避免不必要的调用引入缓存对于非实时性要求高的场景考虑异步处理和结果推送。评估体系不可或缺如何判断智能体生成的行程是“好”的除了人工评审需要建立自动化的评估基线比如检查是否包含了用户提到的关键兴趣点、行程时间是否逻辑自洽、费用是否超预算等。这是将原型推进为产品的关键一步。这个项目还可以从哪些方向扩展集成更丰富的工具加入酒店预订查询工具、机票比价工具、当地活动/演出日历工具让行程规划更全面。实现多模态利用Spring AI的ImageClient让智能体不仅能规划行程还能根据行程生成分享海报或者根据用户描述的风景偏好推荐匹配的景点图片。个性化推荐与学习引入向量数据库存储用户的历史行程和反馈。当新用户提出需求时可以寻找相似用户的历史行程作为参考实现协同过滤式的推荐。部署与监控将智能体打包成Docker容器使用Kubernetes部署。利用Spring Boot Actuator和Micrometer监控LLM API的调用延迟、成功率、Token消耗等核心指标并设置告警。构建AI智能体的过程就像在教导一个拥有强大学习潜力但缺乏领域知识的孩子。我们通过清晰的指令提示词、可靠的工具和正确的反馈记忆与评估来引导它最终让它成为一个能够独立解决特定领域问题的专业助手。希望这个基于Spring AI和Langchain4j的旅游行程规划智能体项目能为你打开AI应用开发的大门。本文还有配套的精品资源点击获取