• 有时候,把 AI 智能体需要的所有知识都交给它,并不是正确的做法。
  • 在 Meta,我们发现,有意让数据流水线智能体的编排层保持轻量,能显著提高效率和准确性:编排层负责分派工作并执行可靠性检查,领域推理由专门的智能体完成。
  • 我们将分享自己的实践过程和经验,以及任何团队如何将这一方法应用于生产环境中的 AI 智能体。

我们构建了一个 1,300 行的编排器,将 20+ 个工作流分派给 14 个专门的 AI 智能体。它自己不做任何领域工作。这正是关键所在。

当我们最初部署 AI 智能体,自动完成 Meta 推荐系统的数据列接入时——这个过程涉及三个代码仓库、三种编程语言,以及最多六个必须保持同步的流水线阶段——我们采取了大多数团队都会采用的做法:构建一个无所不知的聪明智能体。

演示时效果不错。到了生产环境,它开始产生幻觉。

解决办法不是更好的提示词,也不是更大的上下文窗口,而是让中央智能体少做一些事。我们把这种做法称为轻量编排器模式:一个负责步骤顺序和可靠性检查的路由器,把所有领域决策交给专家。

问题:上下文越多,结果越差

我们的流水线采用配置即代码的方式:Python 配置驱动 C++ 代码生成,生成的代码供数据处理服务使用,后者再将数据填充到分析系统中。接入一个数据列,需要协调修改配置注册表、后端服务和数据流水线,而且在数据到达之前,每个数据列最多要经过六个阶段。

我们最初的方案是使用单个 AI 智能体,向它加载所有领域知识、配置模式、代码生成规则、流水线路由逻辑、验证要求,以及 10+ 个数据源的数据填充模式。

智能体拥有它所需的一切。这正是问题所在。

超过某个上下文阈值后,更多知识非但没有改善表现,反而使表现变差。智能体会混淆不同概念,把一个子系统的字段命名规范用到另一个子系统,或者在从某个数据源填充数据时,使用本应属于另一个数据源的代码生成模式。Mount Sinai 的 Windreich Department of Artificial Intelligence and Human Health 的一篇预印本发现,在包含 80 个任务的批次中,经过编排的多智能体系统仍能保持 65.3% 的准确率,而单个智能体的准确率降至 16.6%;同时,前者的 token 用量最多可减少 65 倍。作者认为,这是因为该设计隔离了各项任务,避免了上下文干扰。我们遇到的则是相反的情况:单个智能体被自己的知识淹没了。

我们还评估了另一种单智能体方案。对每个任务手动进行提示词工程时,它的成功率为 70-80%:工程师必须为每项具体工作定制系统提示词。没有这种手把手的指导,成功率就会降至 10-20%。这不是提示词工程的问题,而是架构问题。

方法:轻量路由器搭配专门的执行智能体

我们将系统拆分为两层:

  • 一个确定性的编排器,不做任何领域工作。它识别意图、收集必填字段、执行可靠性检查,并将任务分派给合适的专家。它从不对代码进行推理,从不生成配置,也从不接触代码库。它是一个路由器。
  • 十四个专门的子智能体,每个都是上下文相互隔离的领域专家。模式管理智能体熟悉配置注册表。数据填充智能体知道如何为 10 个数据源中的每一个生成代码。验证智能体熟悉构建系统和质量检查。没有任何一个智能体能看到全局。这是特性,不是缺陷。

编排器对每个请求都遵循固定的 7 步流程:

  • 读取相关子智能体的指令文件。
  • 检查目标是否已存在(防止重复)。
  • 向用户收集必填字段。
  • 自动发现可以推断的信息(仓库类型、现有配置)。
  • 在可靠性关卡检查是否有尚未处理的警告或必需的审查人员。
  • 将完整上下文交给子智能体,委派任务。
  • 处理结果并呈现错误,确认成功。

步骤 1–5 和 7 都是确定性的。只有步骤 6 涉及大语言模型(LLM)推理,而且推理发生在隔离的子智能体内部,它只加载了自己领域的知识。

我们构建的系统:工作流模板,而非新智能体

一个架构上的关键认识是,将需要发生什么与每一步如何执行分开。编排器通过工作流模板定义阶段顺序——这些模板是确定性的状态机,用于约束 LLM 的决策空间:

  • 数据列接入:模式 → 验证 → 数据填充 → 测试
  • 事件接入:模式 → 数据填充 → 验证 → 测试 → 事件处理
  • 流水线迁移:评估 → 规划 → 数据填充 → 验证 → 监控

每个工作流模板都以不同顺序复用同一组 14 个子智能体。当我们需要支持流水线迁移这一全新的用例时,并没有构建新智能体,而是编写了一个新的工作流模板,以不同的顺序组织现有智能体。无需编写新的智能体代码,即可获得完整的生产环境能力。

每个子智能体都遵循标准化的结构:

  • 知识源:运行时需要加载哪些领域文件(通常每个文件有几千个 token)。
  • 预收集清单:编排器在委派之前必须收集哪些信息。
  • 逐步工作流:针对特定领域的执行计划。
  • 发现模式:如何在单体仓库中找到相关代码模式。
  • 故障排查:常见故障中错误与解决方法的对应关系。

这种统一性意味着,添加新的子智能体是一项按模板进行的工作,无需从头开发。第 15 个子智能体在结构上与第一个完全相同。

知识文件在子智能体执行时按需加载,而不是嵌入编排器。我们维护着 25+ 个按工作流领域组织的知识文件。知识文件更新后,下一个会话会自动使用最新版本,无需修改编排器。同一批知识文件还服务于我们智能体在多个平台上的实现。

结果

为一个新数据列准备配置,手动操作需要三到四天,使用我们早期的配置驱动系统则需要约一天。轻量编排器系统在一小时内就能完成。

从整体来看:系统所做的修改中,约有三分之二无需人工大幅编辑即可合入。它通过用深厚的领域知识换取通用性来做到这一点,这是有意为之的架构选择。编排器是通用的;子智能体则各有所长。

为什么这种方法有效(以及为什么重量级编排器无效)

传统做法是让编排器成为最聪明的组件——给它所有上下文,让它自行推理该做什么以及如何做。这种做法一开始有效,但最终会失效,而失效恰恰发生在你最需要它的时候——面对大规模、复杂的多步骤工作流,以及不同类型的子系统时。

轻量编排器之所以有效,是因为它让架构边界与计算边界保持一致:

  • 确定性的决策保持确定性。“哪个子智能体处理这件事?”是路由决策,不是推理任务。不要用 LLM 来做。
  • 上下文隔离可以防止相互混淆。处理数据源 A 的数据填充智能体永远不会看到数据源 B 的模式,因此不会错误地生成另一套模式。
  • 故障得到隔离。如果子智能体失败,编排器会重试或上报。故障不会破坏编排器的状态或其他子智能体的上下文。
  • 系统的每一层都可以独立改进。更好的模型能同时提升全部 14 个子智能体的表现。知识文件更新会立即生效。新的工作流模板无需修改智能体就能解锁新能力。没有任何单个组件需要承担全部重担。

如何将这一方法应用于你的 AI 智能体

这种模式并非数据流水线所独有。任何构建生产环境 AI 智能体的团队都能从中受益:

  • 将路由与推理分开。如果你的编排器正在做领域决策,那它承担的工作就太多了。路由应当是确定性的:关键词匹配、意图分类、收集字段。将所有领域推理交给相互隔离的子智能体。
  • 将子智能体设计为结构统一的专家。每个子智能体都应采用相同的结构:知识来源、必需输入、执行步骤和错误处理。这样,增加新能力就成了套用模板的工作,无须修改架构。
  • 使用工作流模板来扩展,而不是创建新智能体。需要支持新的用例时,先问一句:能否以不同顺序组合现有智能体?如果智能体无法在不同工作流之间复用,说明它们与特定用例的耦合过紧。
  • 在运行时加载知识,而不是在构建时加载。将知识嵌入编排器,每次更新都需要重新部署。按需加载知识,更新就能立即在所有平台生效。
  • 明确划定确定性与概率性的边界。对每个组件都要判断:这是路由决策(确定性),还是推理任务(概率性)?编排器应处于一侧,子智能体处于另一侧。不要混在一起。

支持采用轻量编排器的最有力论据,来自另一种方案出现故障时的表现。当重量级编排器产生幻觉时,错误会蔓延到下游的所有环节:它可能路由到错误的智能体、收集错误的字段,或跳过可靠性检查。轻量编排器的路由和可靠性检查步骤不依赖 LLM 推理,因此留给幻觉的空间很小。它遵循固定的协议。创造性工作发生在下游:在隔离且限定领域的上下文中,幻觉风险降到最低,故障也被限制在局部。

下一步

我们正在扩展这一架构,以应对新数据管道领域中不断增加的数据列。组合式架构的核心观点预示这一方法会奏效,因为扩展意味着增加工作流模板和知识文件,而不是重新构建智能体。我们也在探索如何让系统根据生产环境中的使用情况持续改进:利用自动化反馈循环识别故障模式,并针对子智能体的知识提出改进建议,所有更改都必须经过人工审核才能实施。

这个反直觉的经验是:在我们的 AI 智能体系统中,最重要的组件恰恰是做事最少的那个。让编排器保持轻量,让专家具备深厚的专业能力,整个系统就会变得更加可靠。

致谢

这项工作是团队共同努力的成果。参与贡献的其他人员包括:Mani Bhushan、Rahul Maliakkal、Jae Ha、Chakrapani Kumar、Vivek Tiwari 和 Amanda Yin。

文章 轻量编排器:我们如何通过减少路由器的工作量,让 AI 智能体更加可靠 最初发表于 Engineering at Meta。