gogo-agent 不是"一个大模型干所有事",而是把一次差旅全生命周期拆成一条流水线,让不同职责的智能体各管一段。全项目共 9 个智能体,按角色分成三层: | 分析层 | QueryRewritingAgent | 多轮问题改写与指代消除 | | --- | --- | --- | | | IntentRecognitionAgent | 三层意图识别(规则/向量/LLM) | | 协调层 | MasterAgent | 总入口,路由/多意图编排/结果整合 | | 业务层 | ItineraryManageAgent | 行程单全生命周期管理 | | | ItineraryPlanAgent | 行程规划 + 交通酒店比价预订 | | | ItineraryReviewAgent | 行程方案五维审核(Plan 的下级) | | | InfoAgent | 政策/景点/签证/通用信息查询 | | | BookingAgent | 预订执行(出票/订房/订火车票/取消) | | | ReimbursementAgent | 报销 |
它们的协作链路是:

分析层:把话理清楚
这两个智能体在用户消息进入编排前跑,产物是"改写后的问题"和"结构化意图 JSON"。它们继承 AgentBase,不套 ReActAgent。
✅为什么问题改写/意图识别不用ReAct Agent?
问题改写和意图识别,我们是需要借助大模型的,依靠他的语言理解能力和总结能力帮我们做意图识别和问题改写。但是这两个工作我们没有使用ReAct Agent,而是选择了其他的方式实现。这也是有意为之的。 (除了这两个Agent,其实还有标题生成、 LLMentor
QueryRewritingAgent(问题改写)
- 职责:"多轮对话用户问题改写与指代消除"。把"那第二个方案帮我定了""还是改到周五吧"这类带指代、依赖上文的话,结合会话历史补全成一句自包含、可独立理解的问题,供后续意图识别和子智能体使用。
- 为什么需要它:意图识别和子智能体若直接看省略/指代的原句,很容易判错;先改写能显著提升下游准确率。
- 一个省钱细节:流水线会先用原始问题撞 L1/L2 意图识别,命中就跳过改写(改写也要调大模型)。跳过时会补写一条"影子历史"回 Session,保证下一轮仍有上下文
✅意图识别与问题改写的流水线编排
前面我们讲了三层意图识别,他们不是孤立存在的,它嵌在 AgentPipelineService 这条主流水线里。这里有两个精彩的工程优化。 先用原始问题快筛,未命中再改写 LLMentor
IntentRecognitionAgent(意图识别)
✅基于规则+RAG+LLM构建三层意图识别
意图识别嘛,把用户的话丢给大模型,让它输出一个分类 JSON 不就行了?能跑,但是实际企业里面用起来,这个"纯 LLM"方案有三个致命成本: gogo-agent 的解法是把意图识别做成一条短路流水线:先用最便宜、最快、最确定的手段试,试 LLMentor - 职责:"差旅对话意图识别与路由决策(L1 规则 → L2 向量 → L3 LLM 三层)"。产出与下游同构的意图 JSON:intents[](每项含意图、目标子智能体、置信度、理由)、primary_intent、multi_intent、overall_reason。 - 产物去向:意图 JSON 交给 MasterAgent 决定路由;其中的有序 intents 数组是多意图执行顺序的依据。
协调层:MasterAgent
- 职责:系统的唯一总入口与协调者。它读"改写结果 + 意图识别结果",把业务子智能体当作"工具"调用,负责单意图路由、多意图按顺序依次编排、以及把各子结果整合成一次连贯回复;同时直接处理 greeting/unknown 意图和 ask_user(Human-in-the-Loop)确认。
- 模型:strongModel(强模型,编排决策要准),maxIters=15(一轮里足够连续调多个子智能体),工具超时放宽到 15 分钟。
- 核心机制:Agent as Tool。build() 里用 toolkit.registration().subAgent(...) 把 4 个业务子智能体注册成工具:
toolkit.registration().subAgent(() -> context.getBean("itineraryManageAgent", ReActAgent.class),
SubAgentConfig.builder().toolName("itinerary_manage_agent").description("…").forwardEvents(false).build()).apply();
toolkit.registration().subAgent(() -> context.getBean("itineraryPlanAgent", ReActAgent.class),
SubAgentConfig.builder().toolName("itinerary_plan_agent").description("…").forwardEvents(false).build()).apply();
toolkit.registration().subAgent(() -> context.getBean("infoAgent", ReActAgent.class),
SubAgentConfig.builder().toolName("info_agent").description("…").forwardEvents(false).build()).apply();
toolkit.registration().subAgent(() -> context.getBean("bookingAgent", ReActAgent.class),
SubAgentConfig.builder().toolName("booking_agent").description("…").forwardEvents(false).build()).apply();
- 它自己的工具:InfoQueryTools(通用信息)、UserInteractionTools(ask_user)。
- 行为契约(master-agent-system.md):禁止重复改写/识别意图;多意图按 intents 顺序依次调度、不预先征求同意;结果优先透传子智能体的完整方案(保留确认问句),只有子智能体在索要缺失信息时才 ask_user;面向用户绝不暴露内部子智能体名与字段名。
业务层:专业执行
这些智能体都继承 ReActAgent,各管一块领域能力。
ItineraryManageAgent(行程管理)
- 职责:行程单全生命周期——收集信息、提交审批、查询差旅单/审批状态、取消出差申请、修改出差申请。所有"申请/审批相关变更与查询"都走它。
- 模型/迭代:strongModel,maxIters=10。
- 工具:TravelOrderWriteTools(提交/查审批/取消/修改)、TravelOrderReadTools(查差旅单)、BookingReadTools(查预订记录)、PolicyTools(差旅政策)、TravelOrderConflictTools(行程冲突检测:时间重叠+跨城衔接)、BookingWriteTools(取消预订)、QueryUserInfoTools。
- 提示词:itinerary-manage-agent-system.md。
ItineraryPlanAgent(行程规划)
- 职责:审批通过后的行程规划、交通/酒店搜索比价与预订方案生成;内部含"生成→审核→修复"闭环。
- 模型/迭代:strongModel,maxIters=15,工具超时放宽到分钟级(因内部还要调审核子智能体)。
- 特色能力:开启并行工具执行;带 ItineraryPlannerTool(候选 + LLM 偏好分 → 组合/客观分/合成排序 → 存 Redis);接入天气、签证 MCP;用 SkillBox + ShellCommandTool 接入 tuniu-cli 等技能;用 PlanNotebook 向前端推送任务进度。
- 子智能体:把 ItineraryReviewAgent 注册成 itinerary_review_agent 工具,形成嵌套编排。
- 提示词:itinerary-plan-agent-system.md。
ItineraryReviewAgent(行程审核)
- 职责:对规划好的方案做五维结构化审核(完整性/时间/出发目的地/预算/路径),输出审核报告与具体修改建议。
- 模型:stableModel(与规划用不同模型,交叉校验、降本)。
- 定位:它是 ItineraryPlanAgent 的子智能体,不直接对 MasterAgent 暴露;体现"子智能体也能有子智能体"的可递归编排。
InfoAgent(信息查询)
- 职责:查询差旅政策标准、目的地景点、签证入境政策及天气/交通等通用公共信息。是唯一被列入"可直跳白名单"的子智能体(无副作用、判错代价低)。
- 模型:stableModel。
- 特色能力:挂了三个 RAG 知识库(景点 attractionKnowledge、差旅政策 corporateTravelPolicyKnowledge、差旅指南 corporateTravelGuidelinesKnowledge),并启用 RAGMode.AGENTIC(由智能体自主决定何时检索);接入天气、签证 MCP;对易抖动的实况工具启用熔断分组。
- 提示词:info-agent-system.md。
BookingAgent(预订执行)
- 职责:用户确认方案后的出票/订房/订火车票,以及已有预订的取消。是差旅链条里真正产生"下单"副作用的一环。
- 模型/能力:strongModel;开启并行工具;带 SkillBox(途牛等预订能力);接入第三方 API Key 管理(FlightApiKeyHook/TuniuApiKeyHook)与用户隔离(RghUserIsolationHook);启用长期记忆 AGENT_CONTROL 模式。
- 工具:TravelOrderReadTools(查已审批单获取预订上下文)、BookingReadTools、BookingWriteTools(取消)、QueryUserInfoTools、ApiKeyTools。
3.6 ReimbursementAgent(报销 · 待实现)
- 设计职责:报销、识别发票、生成报销单。
- 现状:占位/未实现。build() 直接 return null,源码标注 todo 这里考虑用 A2A 接入远端 agent。因此它既没被真正构建,也没在 MasterAgent 里注册成工具——这与 MasterAgent 提示词里写的 reimbursement_agent 路由存在不一致,是需要补齐的缺口。
公共基座与协作范式
BaseSubAgent:业务子智能体的公共底座
所有业务子智能体都继承它,集中沉淀了复用的依赖与配置,避免每个 Agent 重复写一遍: - 公共 Hook:AgentExecutionLoggerHook(执行日志)、ProgressNotifierHook(前端进度)、SessionPersistenceHook(会话记忆持久化)、ActiveAgentPersistenceHook(活跃 Agent 态)、ToolCircuitBreakerHook(工具熔断)、CliResultCompressHook(结果去重压缩)、DynamicTimeInjectionHook(每轮注入当前时间且保持前缀稳定以吃缓存)。 - 公共工具:PolicyTools、TravelOrderReadTools、BookingReadTools、InfoQueryTools、QueryUserInfoTools、DestinationLiveTools,以及天气/签证 MCP 客户端(可选注入)。 - 双模型:strongModel(强,决策/规划/预订)与 stableModel(稳,信息/审核/记忆压缩)按需选用。 - 公共方法:createToolCtx()(从 ThreadLocal 取会话上下文注入工具执行)、createLongTermMemory()(按用户构造长期记忆)、getToolConfig()(默认 1 分钟超时、3 次尝试、3 秒退避、仅网络错误重试)。
三条贯穿全局的协作范式
- prototype + 会话隔离:每个会话独立实例,AgentSessionContextHolder(TransmittableThreadLocal)把会话上下文自动传播到工作线程。
- 子智能体即工具(可递归):MasterAgent 把业务子智能体当工具;业务子智能体(如 Plan)又能把更细的智能体(Review)当工具,同一套机制层层复用。
- 记忆分层:短时上下文靠各 Agent 的 AutoContextMemory(自动压缩历史与大工具结果);跨轮上下文由 MasterAgent 维护;差旅偏好等靠百炼长期记忆(AGENT_CONTROL)。