
30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度在实际 AI 应用开发中很多团队已经能够熟练调用大模型 API 完成单轮对话但一旦涉及多轮交互、工具调用、状态记忆和复杂任务分解就会遇到逻辑分散、难以维护的问题。这正是 AIGC Agent智能体要解决的核心痛点——它不是一个简单的聊天接口而是一个能理解用户意图、规划执行步骤、使用外部工具并保持会话状态的自主任务处理系统。从技术架构角度看AIGC Agent 通常包含感知、规划、行动、记忆等核心模块通过大语言模型LLM作为大脑协调整个任务执行流程。这种架构让 AI 系统从“问答机”升级为“执行者”在客服、旅行规划、数据分析和自动化流程等场景展现出强大潜力。本文将基于一个完整的开源 AIGC Agent 项目OTA 旅行助手深入讲解如何从零搭建一个可工作的 Agent 系统。你会看到具体的模块划分、Spring AI 集成方式、对话流管理和扩展开发方法最终获得一个可运行、可调试、可二次开发的 Agent 开发框架。1. 理解 AIGC Agent 的核心价值与工作机制1.1 为什么需要 Agent 而不只是聊天接口传统的大模型调用方式存在明显局限用户需要明确表达需求模型只能基于当前输入生成回复。对于“帮我规划一个三天的北京行程包含机票预订、酒店选择和景点安排”这类复杂请求单次交互无法完成。AIGC Agent 通过以下机制解决这个问题任务分解将复杂问题拆解为可执行的子任务查询航班、查找酒店、生成行程工具调用集成外部 API 或数据库查询获取实时信息状态保持在整个会话过程中记住用户偏好和已完成的步骤自主决策根据当前状态决定下一步操作无需用户反复提示1.2 Agent 系统的典型架构组件一个完整的 Agent 系统通常包含以下核心组件组件职责技术实现示例感知模块理解用户输入提取意图和参数意图识别、实体抽取规划模块制定任务执行计划决定步骤顺序LLM 思维链、工作流引擎行动模块执行具体操作调用工具或API函数调用、外部服务集成记忆模块存储会话历史、用户偏好和任务状态向量数据库、Redis缓存评估模块检查执行结果决定是否需要调整规则检查、LLM自我评估在 OTA 旅行助手项目中这些组件被具体化为 Spring Boot 中的不同模块和类通过统一的 Agent 接口进行协调。1.3 Agent 与普通 AI 应用的差异开发普通 AI 应用时重点往往放在 prompt 设计和模型调优上。而 Agent 开发需要额外关注状态管理如何在不同请求间保持会话连续性错误处理当某个工具调用失败时如何恢复或重试权限控制不同工具和 API 的访问权限管理性能优化减少不必要的 LLM 调用优化工具执行顺序理解了这些基础概念后我们开始搭建具体的开发环境。2. 环境准备与项目结构分析2.1 技术栈要求与版本兼容性OTA 旅行助手项目基于 Java 技术栈需要以下环境准备基础环境要求JDK 17 或更高版本必须Spring AI 对低版本 JDK 支持有限Maven 3.6 或 Gradle 7.x项目使用 MavenRedis 7.0用于会话状态存储MySQL 8.0可选用于数据持久化关键依赖版本!-- 在 pom.xml 中查看关键依赖 -- properties spring-boot.version3.2.0/spring-boot.version spring-ai.version0.8.1/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-openai-spring-boot-starter/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency /dependencies注意Spring AI 版本与 Spring Boot 版本存在兼容性要求如果使用其他大模型接入方式如本地部署的 Ollama需要调整相应的 starter 依赖。2.2 项目模块划分与职责项目采用多模块 Maven 结构这是大型 Agent 系统的典型组织方式aigc-agents/ ├── agents-opensource-core/ # 核心框架模块 │ ├── src/main/java/com/tuniu/agent/ │ │ ├── agent/ # Agent 定义与管理 │ │ ├── api/ # 接口定义 │ │ ├── chat/ # 会话管理 │ │ ├── model/ # 大模型集成 │ │ └── prompt/ # 提示词管理 │ └── src/main/resources/prompts/ # 提示词模板 ├── agents-opensource-app/ # 具体领域实现 │ ├── impl/base/ # 基础 Agent 实现 │ ├── impl/flight/ # 机票相关 Agent │ ├── impl/hotel/ # 酒店相关 Agent │ └── impl/train/ # 火车票相关 Agent ├── agents-opensource-tools/ # 工具集成模块 └── agents-opensource-web/ # Web 服务入口这种模块化设计的优势在于核心与实现分离core 模块定义接口和抽象app 模块提供具体实现领域职责清晰不同业务领域的 Agent 在独立包中维护易于扩展新增领域时只需在 app 模块添加相应实现部署灵活可以只部署需要的模块减少资源占用2.3 关键配置文件说明项目的主要配置集中在application.yml或application.properties中# 大模型配置以 OpenAI 为例 spring: ai: openai: base-url: https://api.openai.com/v1 # 或自定义代理地址 api-key: ${OPENAI_API_KEY:sk-your-key-here} # Redis 配置用于记忆存储 data: redis: host: localhost port: 6379 database: 0 # 工具 API 配置示例 aigc: agents: tools: hotel: hotelPoiListUrl: http://openapi.example.com/hts/agent/poi/hotel/list配置时需要注意API Key 等敏感信息应该通过环境变量注入不要硬编码在配置文件中Redis 连接参数需要根据实际部署环境调整工具 API 的 URL 和认证方式需要按照具体服务商要求配置3. 核心模块深入解析与代码实现3.1 Agent 管理机制的设计在agents-opensource-core模块中AgentManager是系统的核心调度器// 简化的 AgentManager 接口定义 public interface AgentManager { // 根据 ID 获取 Agent 实例 Agent getAgent(String agentId); // 注册新的 Agent void registerAgent(String agentId, Agent agent); // 获取所有已注册的 Agent MapString, Agent getAllAgents(); } // 基础实现 Component public class DefaultAgentManager implements AgentManager { private final MapString, Agent agentMap new ConcurrentHashMap(); Override public Agent getAgent(String agentId) { Agent agent agentMap.get(agentId); if (agent null) { throw new IllegalArgumentException(Agent not found: agentId); } return agent; } Override public void registerAgent(String agentId, Agent agent) { agentMap.put(agentId, agent); } }这种设计允许系统在运行时动态管理多个 Agent每个 Agent 负责特定领域的任务处理。3.2 基础 Agent 类的实现逻辑项目中的OptionsAgent是一个基础抽象类提供了通用的 Agent 能力public abstract class OptionsAgent implements Agent { protected final AgentManagerGroup agentManagerGroup; protected final AgentOptions agentOptions; protected final PromptManager promptManager; public OptionsAgent(AgentManagerGroup agentManagerGroup, AgentOptions agentOptions) { this.agentManagerGroup agentManagerGroup; this.agentOptions agentOptions; this.promptManager agentManagerGroup.getPromptManager(); } Override public String call(String conversationId, ListMessage messages, MapString, Object context) { // 1. 构建提示词 String prompt buildPrompt(messages, context); // 2. 调用大模型 String response callModel(prompt, context); // 3. 处理响应并返回 return processResponse(response, context); } protected abstract String buildPrompt(ListMessage messages, MapString, Object context); protected abstract String callModel(String prompt, MapString, Object context); protected abstract String processResponse(String response, MapString, Object context); }具体领域的 Agent如酒店查询 Agent继承这个基类实现特定的业务逻辑。3.3 提示词管理的最佳实践提示词管理是 Agent 系统的关键环节项目使用模板引擎实现动态提示词生成Component public class PromptManager { private final MapString, String promptTemplates new HashMap(); public String renderPrompt(String templateId, MapString, Object variables) { String template promptTemplates.get(templateId); if (template null) { throw new IllegalArgumentException(Prompt template not found: templateId); } // 简单的模板渲染逻辑 String rendered template; for (Map.EntryString, Object entry : variables.entrySet()) { rendered rendered.replace({{ entry.getKey() }}, String.valueOf(entry.getValue())); } return rendered; } }提示词模板文件示例resources/prompts/hotel-search.st你是一个专业的旅行助手专门帮助用户查询酒店信息。 用户问题{{question}} 用户偏好{{preferences}} 查询城市{{city}} 入住日期{{checkinDate}} 离店日期{{checkoutDate}} 请根据以上信息提供酒店推荐如果信息不完整请询问用户补充。这种模板化方式让提示词维护更加规范也支持多语言和国际化的需求。4. 具体领域 Agent 的实现示例4.1 酒店查询 Agent 的完整实现以酒店查询为例展示一个完整领域 Agent 的实现过程Component public class HotelSearchAgent extends OptionsAgent { private final HotelService hotelService; public HotelSearchAgent(AgentManagerGroup agentManagerGroup, AgentOptions agentOptions, HotelService hotelService) { super(agentManagerGroup, agentOptions); this.hotelService hotelService; } Override protected String buildPrompt(ListMessage messages, MapString, Object context) { // 从上下文中提取用户参数 String city (String) context.get(city); String checkinDate (String) context.get(checkinDate); String checkoutDate (String) context.get(checkoutDate); MapString, Object variables new HashMap(); variables.put(question, getLatestUserMessage(messages)); variables.put(city, city ! null ? city : 未指定); variables.put(checkinDate, checkinDate ! null ? checkinDate : 未指定); variables.put(checkoutDate, checkoutDate ! null ? checkoutDate : 未指定); return promptManager.renderPrompt(hotel-search, variables); } Override protected String callModel(String prompt, MapString, Object context) { // 使用 Spring AI 调用大模型 ChatResponse response chatClient.call( new Prompt(prompt, buildModelOptions(context)) ); return response.getResult().getOutput().getContent(); } Override protected String processResponse(String response, MapString, Object context) { // 如果响应中包含查询意图调用实际酒店服务 if (shouldSearchHotels(response)) { ListHotel hotels hotelService.searchHotels( (String) context.get(city), (String) context.get(checkinDate), (String) context.get(checkoutDate) ); return enhanceResponseWithHotels(response, hotels); } return response; } private boolean shouldSearchHotels(String response) { // 基于规则或模型判断是否需要实际查询 return response.contains(查询) || response.contains(搜索) || response.contains(推荐); } }4.2 对话状态管理与上下文传递多轮对话的关键在于状态管理项目通过 Redis 实现会话状态持久化Component public class ConversationStateManager { private final RedisTemplateString, Object redisTemplate; private static final String CONVERSATION_KEY_PREFIX conv:; public void saveConversationState(String conversationId, MapString, Object state) { String key CONVERSATION_KEY_PREFIX conversationId; redisTemplate.opsForHash().putAll(key, state); redisTemplate.expire(key, Duration.ofHours(24)); // 24小时过期 } public MapString, Object loadConversationState(String conversationId) { String key CONVERSATION_KEY_PREFIX conversationId; MapObject, Object entries redisTemplate.opsForHash().entries(key); MapString, Object state new HashMap(); for (Map.EntryObject, Object entry : entries.entrySet()) { state.put((String) entry.getKey(), entry.getValue()); } return state; } }在 Agent 调用时会自动加载和保存会话状态Override public String call(String conversationId, ListMessage messages, MapString, Object context) { // 加载历史状态 MapString, Object savedState stateManager.loadConversationState(conversationId); context.putAll(savedState); // 执行处理逻辑 String response super.call(conversationId, messages, context); // 保存更新后的状态 stateManager.saveConversationState(conversationId, context); return response; }4.3 工具调用与外部服务集成Agent 通过工具调用获取实时信息以下是酒店查询工具的集成示例Service public class HotelService { private final RestTemplate restTemplate; public ListHotel searchHotels(String city, String checkinDate, String checkoutDate) { // 构建请求参数 MapString, String params new HashMap(); params.put(city, city); params.put(checkinDate, checkinDate); params.put(checkoutDate, checkoutDate); try { // 调用外部酒店 API ResponseEntityHotelApiResponse response restTemplate.getForEntity( buildHotelApiUrl(params), HotelApiResponse.class); if (response.getStatusCode().is2xxSuccessful() response.getBody() ! null) { return response.getBody().getHotels(); } } catch (Exception e) { // 记录日志但不要让工具调用失败导致整个 Agent 失败 log.warn(酒店查询API调用失败: {}, e.getMessage()); } return Collections.emptyList(); } }工具调用的错误处理很重要Agent 应该能够优雅处理工具失败的情况而不是让整个会话中断。5. 系统运行与接口测试5.1 项目启动与健康检查完成代码开发后通过以下步骤启动系统# 1. 编译项目 ./mvnw clean package -DskipTests # 2. 启动 Redis 服务如果使用 Docker docker run -d -p 6379:6379 redis:7.0-alpine # 3. 启动应用 java -jar agents-opensource-web/target/agents-opensource-web-1.0.0.jar # 4. 验证服务状态 curl http://localhost:8080/actuator/health应用启动后可以通过内置的 Actuator 端点检查各组件状态检查项访问地址预期响应应用健康/actuator/health{status:UP}Redis 连接/actuator/health/redis包含连接状态已注册Agent自定义管理接口列出所有Agent5.2 Agent 接口调用测试系统提供统一的 HTTP 接口调用 Agent# 调用酒店查询 Agent curl -X POST http://localhost:8080/api/agent/call \ -H Content-Type: application/json \ -d { agentId: hotel-search-agent, conversationId: conv-123456, message: 我想在北京找一家五星级酒店入住日期是2024-06-01住两晚, context: {} }预期响应结构{ success: true, data: { response: 为您找到以下北京五星级酒店..., conversationId: conv-123456, updatedContext: { city: 北京, checkinDate: 2024-06-01, hotelClass: 5 } } }5.3 流式响应处理对于需要长时间处理的请求系统支持流式响应PostMapping(/stream) public FluxString streamAgentCall(RequestBody AgentRequest request) { return agentService.streamCall( request.getAgentId(), request.getConversationId(), request.getMessage(), request.getContext() ); }前端可以通过 SSEServer-Sent Events或 WebSocket 接收流式响应提升用户体验。6. 常见问题排查与性能优化6.1 典型错误场景与解决方案问题现象可能原因排查步骤解决方案Agent 调用返回空响应大模型 API 配置错误1. 检查 API Key 和 Base URL2. 查看模型响应日志3. 验证网络连接修正配置添加重试机制会话状态丢失Redis 连接问题或键过期1. 检查 Redis 服务状态2. 验证序列化配置3. 查看键过期时间确保 Redis 可用调整过期策略工具调用超时外部服务不可用或网络延迟1. 检查工具服务状态2. 验证网络连通性3. 查看超时配置添加超时控制实现降级策略提示词渲染错误模板变量不匹配或缺失1. 检查模板文件语法2. 验证传入变量3. 查看渲染日志完善变量检查添加默认值6.2 性能优化建议1. 提示词优化避免过长的上下文只保留必要的会话历史使用清晰的指令格式减少模型理解歧义对常用提示词进行预编译缓存2. 模型调用优化// 使用连接池和超时配置 Configuration public class RestTemplateConfig { Bean public RestTemplate restTemplate() { return new RestTemplateBuilder() .setConnectTimeout(Duration.ofSeconds(10)) .setReadTimeout(Duration.ofSeconds(30)) .build(); } }3. 缓存策略对频繁查询的工具结果进行缓存使用多级缓存内存 Redis减少外部调用设置合理的缓存过期时间4. 异步处理对于耗时的工具调用使用异步方式避免阻塞主线程Async public CompletableFutureListHotel searchHotelsAsync(String city, String dates) { return CompletableFuture.completedFuture(searchHotels(city, dates)); }6.3 监控与日志记录完善的监控是生产环境部署的必备条件Component public class AgentExecutionMonitor { private final MeterRegistry meterRegistry; public void recordAgentCall(String agentId, long duration, boolean success) { // 记录指标 Counter.builder(agent.calls) .tag(agentId, agentId) .tag(success, String.valueOf(success)) .register(meterRegistry) .increment(); Timer.builder(agent.duration) .tag(agentId, agentId) .register(meterRegistry) .record(Duration.ofMillis(duration)); } }关键监控指标包括Agent 调用次数和成功率每次调用的响应时间分布工具调用耗时和错误率令牌使用量和成本统计7. 扩展开发与生产部署建议7.1 自定义 Agent 开发流程基于现有框架开发新 Agent 的标准流程1. 定义业务需求明确 Agent 的职责范围确定需要集成的工具和服务设计对话流程和状态管理需求2. 创建 Agent 类Component public class CustomBusinessAgent extends OptionsAgent { // 实现具体业务逻辑 }3. 配置提示词模板在resources/prompts/目录下创建对应的模板文件。4. 注册 Agent通过配置类将 Agent 注册到管理系统Configuration public class CustomAgentConfig { Bean public CustomBusinessAgent customBusinessAgent( AgentManagerGroup agentManagerGroup, Qualifier(customOptions) ChatOptions chatOptions) { AgentOptions options new AgentOptions( custom-business-agent, custom-prompt-template, chatOptions ); return new CustomBusinessAgent(agentManagerGroup, options); } }7.2 生产环境部署清单基础设施准备[ ] 配置高可用 Redis 集群[ ] 设置 MySQL 主从复制如需持久化[ ] 部署应用监控Prometheus Grafana[ ] 配置日志收集系统ELK 或 Loki[ ] 设置反向代理和负载均衡安全配置[ ] API Key 通过密钥管理服务获取[ ] 启用 HTTPS 和网络隔离[ ] 配置访问控制和速率限制[ ] 实现审计日志记录性能调优[ ] 根据负载调整 JVM 参数[ ] 配置连接池大小[ ] 设置合理的超时时间[ ] 启用响应缓存7.3 后续学习方向掌握基础 Agent 开发后可以进一步探索多 Agent 协作让多个专业 Agent 协同完成复杂任务强化学习通过用户反馈优化 Agent 行为策略知识图谱集成增强 Agent 的背景知识和推理能力语音交互支持语音输入输出拓展应用场景移动端适配优化移动设备上的交互体验AIGC Agent 开发是一个快速发展的领域核心在于理解如何将大语言模型的能力与具体的业务逻辑、工具集成和状态管理有机结合。通过实际项目的动手实践逐步掌握从简单对话到复杂任务处理的完整开发流程为构建真正智能的应用系统打下坚实基础。 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度