跳到主要内容

核心架构设计

用户在输入框里敲了一句话,点了发送。看起来很简单,但在 Super Agent 内部,这条消息要经过一条远比你想象中复杂的链路,才能变成一个靠谱的回答。

先看整体流程,后面再逐块拆解每个环节的设计细节:

核心对话总览
核心对话总览

核心思路是:不是让 Agent 自己决定所有事情,而是先用确定性的编排逻辑做好决策,再把执行交给最合适的引擎。 知识问答走稳定的证据驱动生成,开放式问题才走 Agent 自由探索。

架构核心理念

"确定性编排 + 场景化执行"是 Super Agent 区别于市面上其他 Agent 项目的根本设计哲学。大多数项目把所有问题都扔给一个 Agent 去处理,结果是不可控、不可解释。Super Agent 的做法是:能确定的事情先确定好,只把真正需要自主探索的部分交给 Agent

完整请求链路概述

一条用户消息从进入系统到返回回答,要经过以下核心阶段:

  1. 会话记忆加载:从 MySQL 中加载历史对话记忆,按配置的策略(无记忆 / 滑动窗口 / 摘要压缩)组装上下文
  2. 前置编排决策:LLM 分析用户意图,执行问题改写、路由判定、歧义检测、子问题拆分、知识域收缩五步决策
  3. 执行器分发:根据编排结果选择最合适的执行器——歧义追问、RAG 知识问答或 ReAct Agent
  4. 回答生成:执行器执行检索或推理,生成最终回答
  5. SSE 流式输出:正文分片推送、引用来源补发、推荐追问问题生成
  6. 会话记忆更新:将本轮对话持久化,触发摘要压缩(如需要)

整个链路中,每一步的输入输出、耗时、决策结果都有完整的 Trace 记录,出了问题可以精确定位到具体环节。

下面这张截图是对话观测中的会话链路面板,可以看到本次会话中每一轮问答的完整信息——执行模式(知识问答还是 Agent)、各阶段耗时、Token 消耗和费用,一目了然:

Agent 这块是怎么设计的

面试中聊 Agent,面试官不想听你说"我用了 ReactAgent",他想听的是你对这些问题的思考:

  • 用户提了一个问题,系统是怎么决定用哪种方式来回答的? 不是让模型自己选,而是先经过路由判定、问题改写、歧义检测这一整轮编排,最后才决定走哪个执行器。判断顺序是:歧义澄清 > 知识问答 > 开放式 Agent

  • 为什么不是所有问题都走 Agent? 知识问答追求"稳"和"可解释",让 Agent 自己探索反而容易不可控。只有真正需要联网搜索、多步推理的开放式问题,才适合走 Agent

  • Agent 死循环了怎么办? 用 ModelCallLimitHook 限制单次运行最多调用模型 8 次,用 ToolCallLimitHook 限制 Tavily 搜索最多调 6 次。单个会话线程累计也有上限,分别是 40 次和 30 次

  • 联网搜索调用失败了怎么处理? ToolRetryInterceptor 做指数退避重试,最多重试 2 次,初始延迟 200ms,最大延迟 1200ms,带随机抖动。如果最终还是失败,ToolErrorInterceptor 做兜底,不让异常直接抛给用户

  • 对话状态怎么持久化? 用 Spring AI Alibaba 的 MysqlSaver 把 ReactAgent 的 Checkpoint 存到 MySQL,应用重启后能继续之前的对话

  • 并行工具执行怎么做? ReactAgent 配置了 parallelToolExecution,最多 4 个工具并行执行

这些设计在代码里都能找到对应实现,不是概念上的东西。

ReAct Agent 执行
ReAct Agent 执行

三层执行器:不是所有问题都该交给 Agent

知识问答追求"稳"和"可解释"——用户问"退款规则是什么",你需要的是从文档中精准检索证据,然后让模型基于证据生成回答。这种场景让 Agent 自己探索反而容易不可控,可能跑去联网搜索一堆无关内容。

而"今天北京天气怎么样"这种问题,知识库里根本没有答案,必须让 Agent 调用搜索工具去获取实时信息。

所以 Super Agent 设计了三层执行器,按场景精准分流:

执行器触发条件处理方式
歧义追问执行器用户问题信息量不足,无法确定意图生成澄清问题,引导用户补充信息
RAG 知识问答执行器问题可以在知识库中找到答案证据驱动生成,引用来源可追溯
ReAct Agent 执行器需要联网搜索、多步推理的开放式问题自主决策 + 工具调用 + 多轮推理循环

判断顺序是:歧义澄清 > 知识问答 > 开放式 Agent。优先用最稳定的方式回答,只有确实需要自由探索时才启动 Agent。

为什么这个顺序很重要

歧义优先是因为在信息不足时,任何回答都可能是错的,不如先问清楚。知识问答优先于 Agent 是因为知识库的回答可控、可解释、可追溯来源,而 Agent 的自由探索虽然能力更强,但不可预测性也更高。在企业级系统中,可控比聪明更重要。

Agent 安全机制详解

在生产环境中,Agent 的自主决策能力是一把双刃剑。如果不加控制,Agent 可能会陷入无限推理循环、过度消耗搜索资源,甚至因为工具调用异常导致整个会话崩溃。Super Agent 在这方面做了多层防护:

安全机制配置参数作用
单次模型调用上限ModelCallLimitHook = 8 次防止 Agent 单次请求陷入死循环
单次工具调用上限ToolCallLimitHook = 6 次防止搜索工具被过度调用
会话模型调用累计上限40 次 / 线程防止长对话累积消耗过多资源
会话工具调用累计上限30 次 / 线程控制整体工具使用成本
工具重试机制最多 2 次,指数退避 200-1200ms容忍短暂网络抖动
异常兜底ToolErrorInterceptor工具彻底失败时优雅降级,不影响主流程

在观测面板的轮次详情中,可以直观看到每一轮对话的模型使用情况:输入 Token、输出 Token、总 Token、费用估算,以及当前模型调用次数和工具调用次数相对于上限的使用进度。这些数据让资源消耗完全透明可控:

前置编排器到底做了什么

前面说了系统不会把所有问题直接扔给模型,而是先做一轮完整的编排。它在每次对话中做的事情远比你想象的多:

路由判定

用户发进来的消息,首先要判断它属于哪种类型。是一个可以在知识库里找到答案的问题?还是需要联网搜索的开放式问题?还是信息不全需要先追问?这个判定不是靠关键词匹配,而是通过模型分析上下文后给出路由方向。

路由判定的技术细节

路由判定的本质是一次带结构化输出的 LLM 调用。系统会把用户的当前问题、最近几轮对话历史、以及知识库的元信息一起传给模型,让模型判断这个问题最适合走哪个执行器。这种方式比基于规则的路由更灵活,能处理各种模糊边界的情况。

问题改写

用户的问题往往不适合直接检索。比如"那它怎么配置?"——"它"指的是什么?得结合前几轮对话才知道。问题改写就是把这些省略的信息补回来,让检索能找到东西。

下面是观测面板中问题改写的实际效果。可以看到系统把用户的原始问题、结合对话历史改写后的完整问题、以及参考的历史上下文都记录了下来,改写前后的对比一目了然:

问题改写的典型场景:

原始问题改写后改写原因
那它怎么配置?MinIO 对象存储怎么配置?指代消解,补全主语
还有其他方案吗?除了向量检索,还有其他检索方案吗?补全省略的上下文
怎么用?Spring AI 的 ChatClient 怎么使用?结合前文话题补全完整问题

子问题拆分

"退款规则是什么?审批流程怎么走?"这种复合问题,如果直接拿去检索,两个意图互相干扰,效果很差。系统会拆成独立子问题,每个单独走检索链路,最后合并结果。单轮最多拆 4 个子问题,避免过度切碎。

意图解析与知识域收缩

拆完子问题后,还要分析每个子问题属于哪个知识域,把检索范围从"全库"缩小到"相关领域"。这一步直接影响检索的精准度和速度。

知识域收缩的价值

假设知识库里有"产品手册""开发文档""HR 制度"三个领域的文档。用户问"年假怎么申请",如果在全库范围内检索,可能会因为产品手册里也提到了"申请"这个词而引入噪声。知识域收缩会先判断这是 HR 相关问题,只在"HR 制度"领域内检索,大幅提升精准度。

歧义检测

如果用户的问题信息量不够,比如只说"查一下那个",系统不会硬着头皮去检索,而是先生成澄清问题让用户补充信息。这比返回一个不相关的答案体验好得多。

所有这些步骤完成后,编排器会产出一个 执行计划,里面包含执行多种执行编排模式、改写后的问题、拆分后的子问题列表、知识域范围等,交给对应的执行器去执行。

前置编排器决策链路
前置编排器决策链路

编排器的产出物:ConversationExecutionPlan

前置编排的最终产物是一个结构化的执行计划,包含以下关键信息:

字段说明示例
executionMode执行模式CLARIFY / RAG_CHAT / REACT_AGENT
rewrittenQuestion改写后的完整问题"MinIO 对象存储怎么配置连接参数?"
subQuestions拆分后的子问题列表["退款规则是什么", "审批流程怎么走"]
knowledgeDomains知识域范围["产品手册", "运维文档"]
clarifyQuestion澄清问题(仅 CLARIFY 模式)"请问你想了解的是哪个产品的配置?"

这个执行计划是编排层和执行层之间的标准契约,执行器只需要根据计划执行,不需要关心编排过程的细节。这种解耦设计使得编排逻辑和执行逻辑可以独立演进。

检索链路到底有多细

很多人以为检索过程就是"查个向量库 + 让模型回答",但实际上中间的环节比想象中多得多。下面列的这些问题,在项目中都有对应的设计:

问题进来之后怎么处理?

  • 用户问"那它怎么配置?"这种省略了主语的追问,直接拿去检索什么都找不到。所以要先做问题改写,结合最近几轮历史把指代补全
  • 一个问题里问了两件事,比如"退款规则是什么?审批流程怎么走?",不能一股脑去检索。要拆成独立子问题,每个子问题单独走检索链路
  • 单轮最多拆 4 个子问题,避免过度切碎

检索是怎么做的?

  • 不是只用向量检索。用户问一个订单号、一个配置项名,向量检索很可能找不到。所以用了双通道并行:向量检索走 + 关键词检索
  • 两路结果分数量纲完全不同,不能直接比大小。用 RRF(Reciprocal Rank Fusion) 按排名倒数法融合
  • 向量通道设了最低相似度,关键词通道用相对阈值,低于阈值的弱命中直接过滤掉
  • 融合后可以接外部 Rerank 精排(支持 SiliconFlow 兼容协议),在较干净的候选集上继续优化排序
  • 检索粒度用 Child 小块保证命中率,回答阶段通过 Parent-Child 聚合提升到 Parent 大块,保证上下文完整性

证据够不够怎么判断?

  • 如果最终没有任何有效证据,直接短路返回,告诉用户"当前文档中没有检索到足够证据"。不让模型凭空编造,这是防止幻觉最直接的手段
  • 如果证据太多,有预算控制:单个子问题字符、全部证据总预算,单个父块最大字符。防止把模型上下文窗口吃满

最终怎么组装回答?

  • 按子问题边界分别组织证据,注入到 Prompt 里,模型按编号逐一回答
  • 要求模型在引用证据时标注来源编号 [1][2]
  • 答案通过 SSE 实时流式推送,结束时补发引用来源和推荐追问问题
RAG 检索链路
RAG 检索链路

双通道并行检索

用户问一个订单号、一个配置项名,向量检索很可能找不到——语义相似度对精确匹配天然弱势。所以 Super Agent 用了双通道并行:向量检索 + 关键词检索,两路同时出发,互不阻塞。

两路结果的分数量纲完全不同,不能直接比大小。系统用 RRF(Reciprocal Rank Fusion) 按排名倒数法融合,向量通道设了最低相似度阈值,关键词通道用相对阈值,低于阈值的弱命中直接过滤。融合后还可以接外部 Rerank 精排,在较干净的候选集上继续优化排序。

RRF 融合排序的原理

RRF 的核心公式是:score = Σ 1/(k + rank_i),其中 k 是常数(通常为 60),rank_i 是文档在第 i 路检索结果中的排名。这个公式的巧妙之处在于:它不依赖原始分数的绝对值,只依赖排名,因此可以直接融合不同量纲的检索结果。一个文档如果在两路检索中排名都靠前,融合后的分数就会很高。

父子块聚合

这是整个检索链路中最精巧的设计之一。检索粒度用 Child 小块保证命中率——小块语义集中,更容易被向量检索命中。但回答阶段如果只用小块,上下文往往不完整。所以系统在命中 Child 块后,自动聚合提升到 Parent 大块,保证回答时有足够的上下文信息。

检索用小块保精度,回答用大块保完整性。 这个设计在业界也属于比较前沿的实践。

证据预算控制参数

参数默认值说明
单子问题证据上限2,200 字符防止单个子问题的证据过多
全部证据总预算5,200 字符控制注入 Prompt 的总证据量
单父块最大字符2,200 字符防止单个父块占用过多预算
向量检索最低相似度0.45过滤低质量向量匹配
关键词检索相对阈值0.35过滤弱命中的关键词结果

文档从上传到可检索经历了什么

很多项目的文档处理就是"切成固定长度 → 向量化 → 完事"。但实际上不同文档差异很大,一刀切的效果很难好。Super Agent 的文档处理是一条完整的异步流水线,每一步都有独立的状态追踪和任务日志:

文档处理流水线
文档处理流水线

第一步:上传和存储

文件上传到 MinIO 对象存储后,通过 Kafka 异步触发解析任务。Apache Tika 负责处理 PDF、Word、PPT 等多种格式,把五花八门的文档统一转成干净的文本。PDF 里的表格、扫描件、双栏排版——每一个都是坑,Tika 帮你踩过了。

并且可以配置 知识域编码知识域名称业务分类文档标签 等元信息,后续检索和分析都能用得上。

第二步:异步解析和策略推荐

解析完成后,系统不是让用户盲选切块算法,而是根据文档类型和内容特征自动推荐最优的切块策略组合。用户可以查看推荐结果,也可以手动调整——比如文档质量不太好,可以额外开启 LLM 智能切块。

第三步:组合式切块引擎

四种切块策略不是四选一,而是各司其职的组合流水线:

策略角色什么时候用
基于文档结构切块主干按标题/章节/段落切成语义完整的块
递归分块兜底结构块太大时继续往下裁剪,控制块大小
语义分块优化在结构切块基础上做边界精修
LLM 智能切块增强处理低质量文档和复杂文档,默认关闭

一句话:结构负责保留文档天然边界,递归负责控制块大小,语义负责优化块边界,大模型负责处理疑难场景。

策略组合示例

一份包含标题层级的产品手册,系统会推荐:结构切块(主干)+ 递归分块(兜底)。如果这份文档的段落非常长且话题跳跃频繁,系统还会自动开启语义分块来优化边界。而对于一份扫描后 OCR 识别的低质量文档,可以手动开启 LLM 智能切块来增强效果。

第四步:向量化与双引擎索引

确认策略后,系统通过 Kafka 异步执行向量化和索引构建。向量写入向量数据库,关键词写入倒排索引数据库,构建双通道检索的基础。每一步都有独立的任务日志,出了问题能精确定位到哪一步失败。

会话记忆:Token 成本和上下文完整性的博弈

20 轮对话全塞给模型?Token 成本扛不住。只带最近几轮?可能丢掉关键上下文。这是生产环境下绕不开的问题。

会话记忆摘要压缩
会话记忆摘要压缩

项目中设计了三种策略:

  • 无记忆:每轮独立,不携带历史。适合一次性查询
  • 滑动窗口:保留最近 N 轮完整对话。适合短期连续追问
  • 摘要压缩:长期摘要 + 最近原文窗口。这是生产环境最推荐的方案

摘要压缩的具体设计:

  • 最近 4 轮原文始终保留,不做压缩
  • 更早的历史增量摘要,单次最多推进 6 轮,避免一次处理超长历史
  • 最近原文窗口最大 2200 字符,长期摘要最大 1400 字符
  • 所有记忆数据持久化到 MySQL,应用重启不丢失
为什么选择增量摘要而不是一次性摘要

如果每次都对全部历史做摘要,随着对话越来越长,摘要的输入会越来越大,成本和延迟都会线性增长。增量摘要的做法是:每次只处理新增的几轮对话,把它们融合到已有的摘要中。这样不管对话多长,每次摘要的成本都是固定的。

三种策略的适用场景对比

策略Token 成本上下文完整性适用场景
无记忆最低一次性查询、FAQ 问答
滑动窗口中等最近 N 轮完整短期连续追问、调试场景
摘要压缩可控长期摘要 + 近期原文生产环境长对话

MCP 工具协议与 Skills 能力扩展

Agent 的价值不只是能聊天,更在于能调用外部工具完成实际任务。Super Agent 在工具集成这块做了两层设计:

MCP 工具协议

MCP(Model Context Protocol)是 Anthropic 提出的开放协议标准,定义了模型与外部工具之间的通信规范。Super Agent 基于 MCP 协议实现了完整的工具调用链路:

  • 动态工具发现:Agent 启动时自动扫描并注册可用的 MCP 工具,不需要硬编码工具列表
  • 标准化通信:工具的输入输出遵循 MCP 协议规范,支持 Stdio 和 SSE 两种传输模式,兼容主流 MCP Server 生态
  • 参数自动提取:模型根据用户意图自动识别需要调用的工具并提取参数,无需用户手动指定
  • 多工具编排:单次对话中可以串联调用多个 MCP 工具,前一个工具的输出可以作为后一个工具的输入
  • 安全沙箱:工具调用在受控环境中执行,有超时限制和异常隔离,防止恶意工具影响主流程

相比传统的 Function Call 硬编码方式,MCP 协议的优势在于标准化和可扩展性——新增一个工具不需要改任何业务代码,只需要部署一个符合 MCP 协议的 Server 即可。

Skills 能力扩展

Skills 是比 MCP 更上层的能力抽象,解决的是"Agent 怎么获得特定领域的专业能力"这个问题:

  • 声明式定义:每个 Skill 通过 SKILL.md 配置文件描述能力边界、触发条件、执行逻辑,结构清晰易维护
  • 目录化管理:Skills 按领域组织成目录结构,支持嵌套分类,方便大规模能力管理
  • 自动加载机制:系统启动时自动扫描 Skills 目录,新增 Skill 只需要放入对应目录,零配置生效
  • 引用脚本与参考资料:Skill 可以关联外部脚本(Python、Shell 等)和参考文档,执行时自动加载上下文
  • 能力组合:多个 Skills 可以组合使用,Agent 根据任务需求自动选择最合适的 Skill 组合

Skills 体系让 Agent 的能力边界不再是固定的,而是可以持续扩展的。今天加一个"数据分析"Skill,明天加一个"代码审查"Skill,Agent 的能力就跟着增长,核心代码一行不用改。

MCP 与 Skills 的关系

MCP 解决的是"工具怎么调"的问题——标准化工具的通信协议。Skills 解决的是"能力怎么扩"的问题——如何让 Agent 获得特定领域的专业知识和决策能力。两者互补:MCP 提供工具执行能力,Skills 提供领域知识和决策框架。一个 Skill 可以调用多个 MCP 工具来完成复杂任务。

全链路可观测:出了问题不用猜

前面讲了这么多环节,如果某一步出了问题怎么排查?Super Agent 基于 AOP 做了全链路追踪,每一轮对话的完整执行过程都能在观测面板中看到。

下面这张截图是轮次详情中的执行阶段时间线。可以看到一次对话请求经过了哪些阶段(会话记忆加载 → 问题改写 → 路由判定 → 结构图查询 → 推荐问题生成 → 收尾归档),每个阶段花了多长时间,关键决策结果是什么——整个链路一目了然:

🎁优惠