叫来一队 Agent,不等于做过多角度评审

用风险驱动选择、不可变执行计划、隔离上下文、完成屏障和证据化报告控制多 Agent 协作。

本页目录 · 24 节

多 Agent 的价值不来自 Agent 数量,而来自独立信息增益。如果多个 Worker 读取同一份上下文、沿同一条推理路径、最后用不同角色名复述同一个结论,系统只是把一次偏差复制成多份。

Marshall 的 Worker 机制因此不是一个「虚拟团队名单」,而是一组可验证合同:Risk-based Selection 决定是否需要 Worker,Immutable Plan 决定每个实例能看什么和做什么,Barrier 决定什么时候可以综合,Worker Report 则把结论绑定到证据与不确定性。

flowchart LR
    R[Risk Profile] --> S[Worker Selection]
    S --> P[Immutable Worker Plan]
    P --> W1[Worker A]
    P --> W2[Worker B]
    P --> W3[Worker C]
    W1 --> B[Join Barrier]
    W2 --> B
    W3 --> B
    B --> M[Parent Synthesis]

Parent Agent 始终拥有目标解释、风险选择、计划签发、冲突综合和最终交付责任。Worker 只拥有一个窄问题、一份只读上下文和一个结构化输出位置。

第一步不是 Spawn,而是证明需要并行视角

WorkerSelectionV1 先生成 Risk Profile:

axes
domain_count / repo_count
path_clarity
deep_triggers
evidence

Risk Axis 包括 API、Data、Permission、Runtime、Migration、Backfill、IAM、Production Mutation、Cross-repo、Cross-domain、Source Authority、Security、Domain、Layer、Correctness、Scope 与 External Reference。它们不是标签装饰;每个 Axis 都要有 Locator、内容 Hash 与观察时间作为证据。

Selection 根据风险选择不同 Mode:

Mode 合同含义 Worker 数量 适合的任务形状
light 路径清楚、单仓单域、没有声明的风险轴与 Deep Trigger Parent 可直接完成和验证
standard 有少量需要独立检查的风险面 少量 主分析配窄评审,或少数互不依赖视角
deep 有多个风险轴,或命中 Migration、Backfill、IAM、生产写、跨仓、跨域、来源权威不明等 Trigger 按容量上限控制;Review 要求多个独立视角 高风险、宽搜索空间或多证据域

deep 是风险等级,不是「必须凑够预设人数」。通用合同只规定 Fan-out 容量,具体下限由 Stage Policy 决定;Local Review、PR Review 的 Deep 合同要求多个独立视角,用于覆盖不同评审面。

如果风险覆盖需要超过当前容量,Selection 不能悄悄截断实例。它必须进入 blocked_for_splitsplit_required = true,不生成可 Dispatch 的实例,先把 Design Unit 或 Slice 拆小。这一规则防止上下文、等待和综合成本在单层 Fan-out 中失控。

Role 必须匹配 Risk Axis

每个 Selected Instance 都要声明 matched_risk_axes,而角色只能认领自己支持的 Axis。例如权限评审不能因为名字听起来严格,就替代 Data Runtime 证据;领域 Worker 也不能对 IAM 结论投票。

Validator 检查三层关系:

  1. Worker 匹配的 Axis 必须来自当前 Risk Profile;
  2. 角色能力必须覆盖它认领的每一个 Axis;
  3. 除特定的必选 Critic 外,不能选择一个没有任何 Risk Match 的 Worker。

这把「为什么叫它」从 Prompt 中的解释,变成了机器可拒绝的 Selection 合同。

Worker Plan 是不可变的执行快照

Selection 只决定需要哪些视角,WorkerPlanV1 才决定怎样执行。Plan 绑定:

audit / workflow / stage / purpose
attempt / run / generation / resume_epoch
design_unit / slice
selection_id + selection_sha256
mode / max_parallel / max_dispatches / max_repair_rounds
instances / barriers
plan_sha256

plan_sha256 覆盖完整且有序的 Dispatch Payload。运行开始后,如果要更换 Prompt、Model、Context、权限、输出路径或 Worker 数量,就必须产生新 Plan,而不能在原 Plan 下口头补充。否则最终 Report 无法证明自己执行的到底是哪份指令。

每个 Worker Instance 还要绑定自己的细粒度合同:

instance_id / worker_id / node_id
role / phase / matched_risk_axes
context_refs / output_binding
agent_contract
depends_on_instance_ids / join_barrier_id

其中 Agent Contract 固化配置文件与 Prompt 的 Hash、请求与实际 Model、Reasoning Effort、Service Tier、Sandbox、Network Policy、Output Schema 及其 Hash。角色名称只描述语义责任,真正的能力边界来自这些字段。

Context Isolation 是获得独立证据的前提

Worker 不读取完整对话,也不继承 Parent 的全部推理。每个实例只获得一个生成后的 Dispatch Context,其引用包含:

  • Artifact Role、路径与 SHA-256;
  • access: read_only
  • Context Manifest ID、路径与 Hash;
  • Team Contract 的路径与 Hash;
  • 精确 Source Set 的 Hash。

这样可以回答「这个结论基于哪些字节」,而不是只知道「Worker 大概看过仓库」。Context Hash 变化后,旧 Report 不能继续复用。

隔离还要防止 Anchoring。Marshall 对 explorepre_draft 阶段设置了明确约束:它们的 Context 不能包含 design_draftfinal_design。先让 Worker 看完主方案,再请它「独立探索」,通常只能得到围绕主方案的小修小补。真正需要独立证据时,应隔离主结论,只给问题、源码与来源边界。

但隔离也不能过度。把所有上下文都拿走,会让 Worker 重新发现已知事实,制造重复成本。合理的 Context Pack 应共享目标、术语、当前源码版本和安全边界,同时隔离 Parent 的中间判断与无关材料。

Capability 限制 Worker 能修改什么

Parent 持有 Stage Lease,并按 Plan 给 Worker 签发短期 Capability。Capability 绑定 Run、Plan、Worker/Instance、允许角色、Context Path、TTL 与当前 Lease Fence。

Worker 对 State 的写入范围只有两类:

  • start:登记自己的 Run 与 Node 执行状态;
  • publish:发布 Worker Result、Selected Worker、Node 状态或 Late Result。

如果一次 Worker Mutation 改动 Approval、Delivery、Mutation Intent 或其他未授权 State 字段,Runtime 会拒绝整次 CAS。Worker 的 Markdown Prompt 写着「只读」只是意图,Capability、State Mutation Allowlist、Read-only Sandbox 与 Network Policy 才是技术边界。

这也明确了责任:Worker 可以报告「建议 Push」,却不能把建议转换成 Push 权限;可以发现生产数据风险,却不能因此获得数据查询或写入能力。

Parallelism 要受预算和依赖控制

Plan 同时限制 max_parallel_workersmax_total_dispatchesmax_repair_rounds。三者分别控制瞬时并发、整个计划的调用总量和失败后的修复轮数。

每个 Instance 可以声明对其他 Instance 的依赖,Plan 必须无环。真正独立的 Worker 可以并行;需要前一个结果的 Worker 必须显式排在后面。把有依赖的任务强行并行,不会提高吞吐,只会生成过时假设和后续返工。

Join Barrier 采用明确的成员列表与 kind: all。Parent 只能在 Barrier 的所有必需成员都有当前、有效、可验证的 Report 后进入综合。Barrier 不能靠「已经等了很久」自动放行,也不能把 Selection 没有选中的可选角色偷偷加入等待集合。

Review Stage 还直接禁用 Repair Round:评审 Worker 的职责是发现和证明问题,不是在自己的隔离上下文中反复修改主方案。修复由 Parent 重新规划,避免 Reviewer 同时成为自己问题的消解者。

Worker Report 不是自由格式总结

WorkerReportV1 把结果拆成机器状态与语义内容:

execution_status: completed | failed | timed_out | cancelled | stale
verdict: pass | findings | blocked | deferred
severity
findings[]
evidence_locators[]
blocking
recommended_route
missing_evidence[]
report_body

每个 Finding 都有 ID、摘要、严重度、是否阻塞和 Evidence Locator,还可以绑定 Uncertainty、Claim、Decision 与 Node。Report 的 Control 部分继续绑定 Selection/Plan、Attempt、Generation、Resume Epoch、Context Hash、Role Prompt Hash、Report Schema Hash 与 Worker Payload Hash。

因此「安全 Worker 说有问题」还不是可用结论。Parent 要能定位它读取的证据、确认 Report 属于当前 Plan,并判断 Finding 是否真正命中当前范围。

不确定性必须选择 Route

Worker 不应该用自信语气填补缺失信息。Report 把 Uncertainty 结构化为:类型、是否 Material、是否可发现、已经检查的证据、影响的 Node/Claim/Decision、最早失效节点,以及下一步 Route。

允许的 Route 包括:

  • continue:未知不影响当前决定;
  • bounded_explore:再做一次有边界的只读发现;
  • question_gate:需要用户做 Material Choice;
  • clarify_reentrydesign_reentry:使相关下游结果失效并回到更早阶段;
  • block:缺少必要证据,不能安全继续。

这一设计避免两种极端:Worker 遇到未知就全部阻塞,或把未知包装成推断继续推进。

Freshness 与 Late Result

并行系统最危险的不是 Worker 失败,而是 Worker 成功得太晚。

假设多个 Worker 基于 Generation n 同时运行,Parent 根据部分报告修订了输入并进入 Generation n + 1。其他 Worker 随后返回,即使它通过 Schema、结论也正确,仍然不是新 Generation 的当前证据。

Publication 必须重新核对:

plan / selection
attempt / run / generation / resume_epoch
lease fence / capability
context / prompt / schema hashes

不匹配的结果进入 Stale 或 late_results,保留审计价值,但不能满足当前 Barrier。把晚到结果直接「合并一下」会重新引入已经失效的输入。

Parent 综合不是多数投票

多个 Worker 返回冲突结论时,正确做法不是按 passfindings 数量投票。LLM 的错误往往相关:相同模型、相同上下文和相似 Prompt 可能让多数意见共享同一个盲点。

Parent 综合应按以下顺序:

  1. 去重相同 Evidence Locator 与实质相同的 Finding;
  2. 比较来源权威、版本和观察时间;
  3. 区分事实冲突、解释冲突和产品取舍;
  4. 对可发现的事实做一次有边界的 Readback;
  5. 对不可由代码或文档决定的取舍进入 Question Gate;
  6. 把采用、拒绝或延期的 Finding 绑定到 Decision。

Worker 提供的是专业证据,不是责任票。最终 Scope、Trade-off 和外部动作仍由 Parent 与用户授权决定。

多 Agent 的成本模型

并行可以降低 Wall-clock Time,却通常增加总 Token、工具调用、上下文复制和综合成本。可以用一个简单的不等式判断是否值得增加 Worker:

预期收益
= 独立发现概率 × 问题影响 × 提前发现价值

预期成本
= Dispatch + Context 打包 + 等待 + Report 校验
 + 重复探索 + Parent 综合 + Stale/Late 恢复

只有预期收益明显大于成本,Fan-out 才合理。独立搜索多个数据源、跨领域安全评审、并行读取互不依赖的仓库通常收益较高;围绕同一个函数反复做相似 Review,收益往往很低。

Anthropic 在自己的 Research 系统中报告,多 Agent 使用的 Token 达到普通 Chat 的一个数量级以上,并指出多数 Coding Task 的可并行部分少于 Research。这个量级来自其特定系统与评测,不是 Marshall 的性能基准;它说明的是方向:多 Agent 的能力提升主要通过投入更多独立计算获得,不能假设并行天然更省。

常见失败模式

Role Theater

角色名不同,但 Context、Prompt 和 Evidence Source 相同。解决点是 Risk Match、Context Isolation 与 Evidence Binding,而不是继续增加角色。

Duplicate Exploration

任务边界只写「调查这个问题」,多个 Worker 搜索完全相同的路径。Plan 应说明每个实例的子问题、来源范围、停止条件和输出合同。

Anchored Critic

Explore Worker 先看到 Design Draft,只在现有方案周围找小问题。需要独立发现时,Pre-draft Context 不应包含主方案。

Correlated Majority

多个 Worker 因共享模型与资料得出同一个错误结论。综合要比较证据质量,不能以票数替代 Readback。

Barrier Under-specification

Parent 在必需 Worker 未发布当前 Report 前继续。Barrier 必须绑定精确 Instance,而不是「已有部分返回」。

Barrier Over-specification

低风险任务等待所有可选角色,或已取消 Worker 仍阻塞阶段。Barrier 成员必须来自实际 Selection,并有明确的取消、超时和重新规划路径。

Late Result Accepted as Fresh

旧 Generation 的报告被纳入新设计。Publication 与 Barrier 必须重新校验完整执行身份。

Unbounded Hierarchy

Worker 再递归创建 Worker,协调成本指数增长。Marshall 用实例上限、Dispatch Budget、Repair Round 与 blocked_for_split 控制深度和宽度。

Worker Escapes Its Role

评审 Worker 直接修改代码或调用外部 Provider。只读 Sandbox、Capability 与 State Allowlist 要共同限制它,不能只依赖 Prompt。

Synthesis Becomes the Bottleneck

Worker 产出大量重复长文,Parent 的上下文被报告淹没。Report 应结构化 Finding 与 Locator,大正文保存在 Artifact 中,Parent 只加载会改变决定的部分。

适用边界与 Trade-off

Worker 编排适合子问题能独立探索、证据来源不同、结果可通过清晰接口汇合,而且遗漏代价足以覆盖额外成本的任务。例如跨仓库调用链、数据与权限同时变化、宽度优先的资料研究,或需要相互独立的设计 Critic 与 Deterministic Verification。

它不适合强共享上下文、步骤高度串行、多人会写同一片代码,或 Parent 一次读取就能验证的窄任务。此时拆分会增加上下文复制、同步和冲突,却没有增加新的证据。

多 Agent 的设计目标不是最大并发,而是最小充分独立视角:只派出能改变当前决定的 Worker,并让每份结论都可以追溯、过期、拒绝和重新计算。

参考资料

相关文章

在做类似的事情?

很乐意就分布式系统、交付流程和应用 AI 交换意见。

[email protected]