跳转至

当一个复杂任务需要多个 Skill 协作完成时,编排逻辑应该放在哪里?Agent 核心还是 Skill 内部?

面试官:“当一个复杂任务需要多个 Skill 协作完成时,编排逻辑应该放在 Agent 核心还是 Skill 内部?你怎么设计?”

候选人:

“这是我设计多 Skill 协作时反复权衡过的问题。结论是:宏观的流程编排一定要放在 Agent 核心,Skill 内部只保留自己粒度的微观步骤。 如果反过来,让 Skill 之间互相调用做串联,短期看似灵活,长期一定会失控。

我分三层把这个决策逻辑讲清楚。


一、为什么编排不能下沉到 Skill 内部?

如果把编排逻辑写死在 Skill 内部,比如“机票预订 Skill”里硬编码调用“酒店预订 Skill”和“支付 Skill”,会有三个致命问题:

  1. 可复用性崩塌:同一个“支付 Skill”,在订机票、点外卖、买电影票时都要被编排,如果每个上游 Skill 都自己写调用逻辑,代码重复且不一致。支付 Skill 改了接口,所有调用它的 Skill 都得改。

  2. 维护成本爆炸:编排链路的修改(比如双十一要在预订机票前增加“风险校验”)如果是 Skill 内部硬编码,就需要找到并修改所有相关 Skill,而它们可能由不同团队维护,改一个流程动全身。

  3. 缺乏全局视野:Agent 无法在宏观层面看到完整的任务执行图,不能做全局优化(比如并行调用多个无关 Skill、提前预加载资源),也无法统一处理异常和超时。错误恢复逻辑散落在各个 Skill 里,容易遗漏或相互冲突。


二、正确的分层:Agent 核心做指挥,Skill 做执行

我推荐的架构是:Agent 核心内建一个“编排引擎”,它负责将复杂意图分解成 Skill 调用 DAG,并调度执行。Skill 只暴露自己的能力和参数,完全不关心自己会被谁调用、在什么顺序中被调用。

这个编排引擎的工作流程如下:

  1. 意图解析与规划:收到用户复杂意图(如“帮我规划一个三天上海出差行程”),编排引擎调用大模型或规则引擎,将意图分解成一系列子任务,每个子任务对应一个 Skill。生成一个有向无环图(DAG),节点是 Skill,边是依赖关系(如“订酒店”依赖“确认机票时间”)。

  2. 动态调度与并行:编排引擎根据 DAG 拓扑排序执行。无依赖的 Skill 自动并行调用(比如同时查天气和查疫情政策),有依赖的串行。这是 Skill 内部做不到的全局优化。

  3. 异常处理与补偿:编排引擎在 DAG 每个节点上挂载统一的异常处理策略(重试、降级、跳过、人工介入)。如果某个 Skill 失败,引擎根据 DAG 决定是否执行补偿 Skill(如“取消已订的机票”)。这种跨 Skill 的补偿逻辑,放在任何一个 Skill 内部都不得体。

  4. 上下文传递与状态持久化:编排引擎维护一个全局的“任务上下文”对象,上游 Skill 的输出自动成为下游 Skill 的输入的一部分,不需要 Skill 之间直接传参耦合。这个上下文可以被持久化,支持长任务暂停和恢复。


三、Skill 内部的“微观编排”

Skill 内部当然也可以有自己的步骤,比如“支付 Skill”内部可能包含“风控检查 → 扣款 → 发送账单”等子步骤。但这种编排是该 Skill 自己业务域内部的流程,不涉及其他 Skill。它的边界是:只编排自己域内的工具和 API,绝不直接调用另一个 Skill。

用一句话区分:Agent 编排“谁来做”,Skill 编排“怎么做”。


两种编排模式对比

维度 编排在 Skill 内部(去中心化) 编排在 Agent 核心(中心化)
复用性 差,每个 Skill 重复写调用逻辑 好,Skill 只暴露能力,被任意编排
全局优化 无,各 Skill 各自为政 可并行、预加载、全局超时控制
异常处理 分散,易遗漏 统一重试、降级、补偿策略
可维护性 改流程需改多个 Skill 只需调整编排 DAG 配置
动态适应性 无法根据上下文改变流程 可根据用户画像、历史动态调整 DAG
开发体验 Skill 开发者需了解全局 Skill 开发者只关心自己域