--- title: "02-工程化技术概括" created: 2026-05-13 aliases: - 工程化技术概括 tags: - 项目 --- # 工程化技术概括 说一个项目是企业级,肯定得看实际的工程质量。Super Agent 不是"能跑通就行"的 Demo 项目,而是在每一个工程细节上都对标真实生产系统的标准来做。从几个维度来评估: ### **工程规范** - **分层架构**:business / common / framework 三层职责清晰,AI 业务逻辑、通用 Web 能力、基础设施组件互不耦合 - **统一异常处理**:全局异常拦截 + 统一响应格式 ApiResponse,业务代码不需要到处 try-catch - **自动装配机制**:基础组件通过 Spring Boot Starter 方式封装,引入依赖即可使用,零配置代码 - **MyBatis-Plus 自动填充**:创建时间、更新时间等公共字段自动处理,不需要每个 Mapper 手动设置 - **API 文档规范**:Knife4j 增强的 Swagger 文档,接口定义即文档 > Super Agent 的代码组织不是简单的 MVC 三层,而是按照**领域职责**做了更细粒度的拆分: > > - **super-agent-business**:纯业务逻辑层,包含聊天、文档管理等业务模块 > - **super-agent-common**:通用能力层,包含 Web 框架能力和通用工具 > - **super-agent-\*-framework**:基础设施层,包含 Redis 分布式能力、ID 生成器等基础组件 > > 这种拆分方式使得每一层都可以独立演进和复用。比如 Redis 分布式能力框架,不仅在聊天场景中用于会话锁定,在文档处理场景中同样可以直接复用。 ### **分层架构的模块职责** | 模块 | 职责 | 关键组件 | | --- | --- | --- | | super-agent-business-chat | AI 对话业务 | Controller、执行器、编排器、检索服务 | | super-agent-common-frame | 框架层能力 | 统一响应、全局异常、自动填充 | | super-agent-common-web | Web 通用能力 | 请求拦截、跨域配置、参数校验 | | super-agent-id-generator-framework | 分布式 ID | 雪花算法、集群安全的 ID 生成 | | super-agent-redisson-framework | Redis 分布式 | 分布式锁、租约管理、延迟队列、重复执行限制 | ## **集群安全与并发控制** 这是很多开源项目完全忽略的部分,但在生产环境中至关重要。一个 AI 对话系统如果不做并发控制,很容易出现同一条消息被多个实例重复处理、长对话锁超时被其他实例抢占等问题。 - **Redis 租约互斥**:`RedisLeaseManager` 实现集群级别的会话锁定,防止同一条消息被多个实例重复处理 - **JVM 级任务注册**:`ChatRuntimeRegistry` 维护进程内的任务注册表,防止同进程重入 - **租约续期**:执行过程中自动续期,防止长对话超时导致锁释放后被其他实例抢占 - **优雅降级**:无论成功还是失败,统一触发清理流程,不会留下孤儿锁 > 只用 Redis 分布式锁能防止跨实例重复处理,但不能防止同一个 JVM 内的并发重入。只用 JVM 级锁能防止进程内重入,但不能防止集群间的重复。**两层锁配合使用**,才能在分布式环境下做到万无一失。 ### **并发控制的完整生命周期** 一次对话请求的并发控制流程如下: - **请求进入**:先在 `ChatRuntimeRegistry` 中注册 JVM 级任务,防止同进程重入 - **获取租约**:通过 `RedisLeaseManager` 获取集群级分布式租约,防止跨实例重复处理 - **自动续期**:对话执行过程中,后台线程自动续期租约,防止长对话超时 - **执行完毕**:主动释放 Redis 租约 + 注销 JVM 任务注册 - **异常保护**:任何环节出现异常,finally 块统一触发清理,不留孤儿锁 这套机制确保了在多实例部署的生产环境中,每条消息都只会被一个实例处理一次,即使实例宕机或重启也不会出现数据不一致。 ## **设计模式实战** 项目中落地了多种经典设计模式,不是为了用模式而用,每个都解决了实际的扩展性或解耦问题: | 设计模式 | 应用场景 | 解决的问题 | | --- | --- | --- | | 策略模式 | 三种会话记忆策略、四种切块策略 | 不同策略可插拔替换,新增策略不改已有代码 | | 工厂模式 | 检索通道创建、切块器创建 | 复杂对象的创建逻辑集中管理 | | 模板方法 | 文档处理流水线各节点 | 统一执行流程,子类只关注核心逻辑 | | 责任链模式 | RAG 前置编排器的五步决策链 | 多个处理步骤按顺序串联,灵活组合 | | 观察者模式 | SSE 流式输出回调 | 流式事件的异步通知与推送 | | AOP | 重复执行限制、全局异常拦截 | 横切关注点与业务代码解耦 | ### **设计模式的具体落地细节** > 会话记忆模块定义了统一的策略接口,三种实现(无记忆、滑动窗口、摘要压缩)各自独立。系统通过配置项决定使用哪种策略,运行时通过工厂方法获取对应实现。如果未来需要新增一种记忆策略(比如基于 RAG 的长期记忆),只需要新增一个实现类,不需要修改任何已有代码。这就是开闭原则在实际项目中的落地。 **责任链模式在前置编排器中的应用**尤为典型。五步决策链(路由判定 → 问题改写 → 歧义检测 → 子问题拆分 → 知识域收缩)的每一步都是一个独立的处理节点,节点之间通过链式调用串联。这种设计使得: - 每个节点可以独立开发和测试 - 可以灵活调整节点的执行顺序 - 可以按需跳过某些节点(比如简单问题不需要子问题拆分) - 新增决策步骤只需要加一个节点,不影响已有流程 **模板方法在文档处理中的应用**同样精巧。文档处理流水线的每个阶段(解析、策略推荐、切块、向量化、索引构建)都遵循统一的模板:前置检查 → 核心逻辑 → 状态更新 → 日志记录。子类只需要实现核心逻辑部分,其他环节由模板统一处理,确保了整个流水线的一致性和可追踪性。 ## **可扩展性** 核心模块都预留了扩展点,这是企业级项目和 Demo 项目最本质的区别: - **新增检索通道**:实现检索通道接口,注册为 Spring Bean,自动参与双通道检索 - **新增切块策略**:实现切块策略接口,可加入组合流水线的任意位置 - **新增记忆策略**:实现记忆策略接口,系统自动识别并可配置使用 - **新增工具调用**:给 ReactAgent 注册新的 Tool,自动参与工具选择 - **新增 MCP Server**:部署符合 MCP 协议的 Server,Agent 自动发现并注册 - **新增 Skill**:在 Skills 目录下放入 SKILL.md 配置文件,零配置即刻生效 不需要改框架代码,加个实现类或配置文件就完事了。这才是面向接口编程和插件化架构的正确打开方式。 > Super Agent 的可扩展性不是"留了几个接口"这么简单,而是贯穿整个系统的**依赖倒置**原则——核心逻辑依赖抽象而非具体实现。检索引擎不关心具体有几个通道、每个通道怎么实现,它只关心"通道接口"。切块引擎不关心具体有几种策略,它只关心"策略接口"。这种设计使得系统可以在不修改核心代码的前提下,持续扩展新能力。 ### **扩展点的完整清单** | 扩展点 | 接口 / 协议 | 扩展方式 | 生效方式 | | --- | --- | --- | --- | | 检索通道 | 检索通道接口 | 新增 Spring Bean | 自动参与检索 | | 切块策略 | 切块策略接口 | 新增实现类 | 加入组合流水线 | | 记忆策略 | 记忆策略接口 | 新增实现类 | 配置切换 | | Agent 工具 | Tool 注册 | 注册新 Tool | 自动参与工具选择 | | MCP 工具 | MCP 协议 | 部署 MCP Server | Agent 自动发现 | | Skills 能力 | SKILL.md | 放入目录 | 零配置生效 | ## **全链路可观测** 基于 AOP 的全链路追踪,每个环节的耗时、输入输出、决策结果都有记录。思考过程、检索通道使用情况、证据来源、工具调用记录——全部可视化呈现在管理后台的观测面板中。出了问题不用猜,直接看 Trace 就知道哪一步出了问题。 ### **可观测的具体维度** | 观测维度 | 记录内容 | 用途 | | --- | --- | --- | | 编排决策 | 路由结果、改写前后对比、子问题列表 | 分析编排逻辑是否合理 | | 检索过程 | 各通道命中数、分数分布、融合结果 | 优化检索参数 | | 证据评估 | 证据数量、质量评分、预算使用情况 | 调整证据阈值 | | 模型调用 | 输入 Token 数、输出 Token 数、响应延迟 | 成本分析和性能优化 | | 工具调用 | 调用次数、成功率、平均耗时 | 工具可靠性监控 | | 端到端延迟 | 各阶段耗时、总延迟 | 性能瓶颈定位 | > 在生产环境中,用户反馈"回答不准确"或"响应太慢"时,传统做法是翻日志、加断点、猜测问题。有了全链路追踪后,可以直接打开观测面板,看到这次请求的完整链路:编排器判断走了哪个分支、检索了哪些文档、证据评分是多少、模型用了多少 Token。问题根因一目了然,大幅缩短排查时间。 ## **和其他普通的 Agent 项目有什么区别** 市面上大多数 Agent 项目,说白了就是跑通一个示例就完事了。Super Agent 和这些项目的差距在哪?直接对比一下: | 对比维度 | 普通 RAG 项目 | Super Agent | | --- | --- | --- | | 检索方式 | 单路向量检索 | 双通道并行(PGVector + ES)+ RRF 融合 + 可选 Rerank | | 问题处理 | 原始问题直接检索 | 改写 + 子问题拆分 + 知识域收缩 | | 意图判断 | 无 | 前置编排器五步决策 + 歧义主动追问 | | 执行策略 | 所有问题走同一个模型 | 三层执行器按场景分流(追问 / 知识问答 / Agent) | | 会话记忆 | 全量塞给模型或不带 | 无记忆 / 滑动窗口 / 摘要压缩三种策略 | | 文档切块 | 固定长度一刀切 | 四种策略组合流水线 + 系统自动推荐 | | 文档入库 | 同步处理,无日志 | Kafka 异步流水线 + 分步骤任务日志 | | Agent 能力 | 无或仅简单对话 | ReAct 循环 + 联网搜索 + 工具调用 + Checkpoint 持久化 | | 证据控制 | 无 | 预算裁剪 + 无证据短路防幻觉 | | 检索粒度 | 命中什么用什么 | Parent-Child 块聚合,检索用小块、回答用大块 | | 流式输出 | 简单 SSE 推文本 | 正文 + 引用来源 + 推荐追问 + 停止生成 | | Agent 安全 | 无限制 | 模型调用次数 Hook + 工具调用次数 Hook + 重试兜底 | | MCP 协议 | 无或硬编码 Function Call | MCP 标准协议 + 动态发现 + 多工具编排 + 安全沙箱 | | 能力扩展 | 固定能力,改代码才能加 | Skills 声明式定义 + 自动加载 + 热插拔扩展 | | 集群安全 | 单机运行 | Redis 租约互斥 + JVM 任务注册 + 租约续期 | | 可观测性 | 无 | 全链路 Trace + 可视化观测面板 | | 知识路由 | 无,全库检索 | 三级漏斗(Scope → Topic → Document)+ 混合打分自动锁定文档 | | 文档结构 | 无 | Neo4j 图数据库构建 Document → Section → Item 层级图谱 | | 路由质量观测 | 无 | 影子路由静默对比 + 命中率追踪 + 持续优化闭环 | 一句话:**每个环节都不是调个 API 就完事的,而是有完整的设计和工程考量。** > 在面试中聊项目对比时,不要只列功能差异,更要讲清楚"为什么要这么做"。比如不是简单说"我们用了双通道检索",而是说"纯向量检索对精确匹配天然弱势,用户问一个订单号向量检索完全找不到,所以我们加了关键词检索通道,两路并行后用 RRF 融合排序"。**讲清楚问题 → 方案 → 权衡,比列功能清单有说服力得多。** ## **用到的技术一览** | 技术 | 说明 | 版本 | 官网 | | --- | --- | --- | --- | | JDK | 编译和运行版本 | 17 | [https://openjdk.org](https://openjdk.org/) | | Spring Boot | 应用框架 | 3.5.6 | | | Spring AI | AI 能力基础框架 | 1.1.0 | | | Spring AI Alibaba | 阿里云 AI 适配,提供 ReactAgent | 1.1.2.0 | | | MyBatis Plus | ORM 框架 | - | [https://baomidou.com](https://baomidou.com/) | | MySQL | 业务数据库 | - | [https://www.mysql.com](https://www.mysql.com/) | | PostgreSQL + PGVector | 向量数据库 | - | | | Elasticsearch | 关键词搜索引擎 | - | | | Neo4j | 图数据库,文档结构图谱与知识路由 | - | [https://neo4j.com](https://neo4j.com/) | | Redis | 分布式缓存 | - | [https://redis.io](https://redis.io/) | | Redisson | 分布式 Redis 工具 | - | [https://redisson.org](https://redisson.org/) | | Kafka | 异步消息队列 | - | [https://kafka.apache.org](https://kafka.apache.org/) | | MinIO | 对象存储 | - | [https://min.io](https://min.io/) | | Apache Tika | 多格式文档解析 | 3.2.3 | [https://tika.apache.org](https://tika.apache.org/) | | 阿里云百炼 DashScope | 大模型服务 | - | [https://dashscope.aliyun.com](https://dashscope.aliyun.com/) | | Tavily | 联网搜索服务 | - | [https://tavily.com](https://tavily.com/) | | SiliconFlow | Rerank 精排服务(可选) | - | [https://siliconflow.cn](https://siliconflow.cn/) | | Vue 3 + Vite | 前端框架 | - | [https://vuejs.org](https://vuejs.org/) | | Log4j2 | 日志框架 | - | | | Knife4j | Swagger 增强 | - | [https://doc.xiaominfo.com](https://doc.xiaominfo.com/) | | Lombok | Java 语言增强 | - | [https://projectlombok.org](https://projectlombok.org/) | | Hutool | Java 工具类库 | - | [https://hutool.cn](https://hutool.cn/) | | JWT | 登录认证 | - | | ### **技术选型背后的考量** 每个技术的选型都不是随意的,背后都有明确的工程考量: **为什么选 PGVector + Elasticsearch 双引擎,而不是只用一个?** 向量数据库擅长语义理解但对精确匹配弱,倒排索引擅长精确匹配但缺乏语义理解能力。两者互补才能覆盖用户检索的所有场景。PGVector 的优势是和 PostgreSQL 深度集成,既是关系型数据库又支持向量检索,运维成本低。Elasticsearch 则是倒排索引领域的工业标准,性能和功能都久经验证。 **为什么用 Kafka 做异步解耦?** 文档处理流水线是典型的长耗时任务(解析 → 切块 → 向量化 → 索引),如果同步处理用户要等很久。用 Kafka 做异步解耦后,上传操作秒级完成,后续处理在后台异步进行。同时 Kafka 提供了可靠的消息投递保证,即使处理实例宕机也不会丢失任务。 **为什么选 Spring AI 而不是 LangChain4j?** Spring AI 是 Spring 官方出品,和 Spring Boot 生态深度集成,自动配置、依赖注入等 Spring 开发者熟悉的能力都可以无缝使用。对于 Java 开发者来说,学习曲线最平滑。Spring AI Alibaba 在此基础上提供了阿里云 DashScope 适配和 ReactAgent 实现,进一步降低了接入门槛。 **为什么选 Redisson 做分布式能力?** Redisson 不仅提供了分布式锁,还有完善的租约(Lease)机制、看门狗(Watchdog)自动续期、可重入锁等高级特性。在 Super Agent 的集群并发控制场景中,这些能力都是必不可少的。相比直接用 Redis 命令手写分布式锁,Redisson 更安全、更稳定、经过了大量生产环境的验证。 ## **总结** Super Agent 的工程化水平体现在方方面面:从分层架构的模块解耦,到集群环境下的并发安全;从设计模式的恰当运用,到全链路可观测的调试能力;从面向接口的扩展性设计,到每一个技术选型背后的工程权衡。 **这不是一个"能跑通就行"的项目,而是一个你可以在面试中逐层展开、越聊越深的项目。** 不管面试官从哪个角度切入——架构设计、并发控制、设计模式、技术选型——你都能给出有深度、有细节的回答。这才是"企业级"三个字真正的含义。 --- **企业级项目导航**:⬅️ [[01-核心架构设计|01-核心架构设计]] | 02-工程化技术概括 | ➡️ [[03-图数据库与知识路由|03-图数据库与知识路由]]