多智能体协作的任务契约工程 2026:从意图对齐到生产闭环
把任务分解从自然语言派单提升为五元组契约 + Intent 四层栈 + 契约测试三件套 + 契约执行代理,让多智能体协作从 demo 走到生产。
约 35 分钟阅读10,361 字25 次阅读博主

把任务分解从自然语言派单提升为五元组契约 + Intent 四层栈 + 契约测试三件套 + 契约执行代理,让多智能体协作从 demo 走到生产。

当我们把视角从"单智能体的工具调用可靠性"切到"多智能体的协作闭环",会立刻撞上一个被广泛低估的事实:多智能体系统绝大多数"线上事故"不是来自模型能力本身,而来自任务分解与协作语义层面的契约缺失。一组 Agent 在对话中彼此"理解"了任务,但生产线上却产出了三种相互冲突的中间结果,然后互相覆写、互相丢弃、互相阻塞——这种事故的根因常常不是模型判断力不足,而是协作方之间从未对"这个子任务的边界、产物、可证伪的成功条件"达成可机读的共识。
更进一步说,2026 年的多智能体框架(LangGraph、CrewAI、AutoGen、Swarm、OpenAI Agents SDK、Claude Agent SDK 等)虽然都给出了"任务→子任务→执行→汇总"的编排模型,但它们的"任务分解"普遍停留在自然语言级别的派单——一个 planner 把一段中文描述拆成几个句子给 worker,worker 在自己的上下文里"解读"任务,然后产出。没有 schema,没有可机读的契约,没有可证伪的成功条件,没有偏离契约时的自动化恢复路径。这就把"协作失败"的检测成本推到了下游——往往要等到最终结果出错后,人工去做"是哪一步错了"的归因,而不是在子任务结束的瞬间就能识别契约违反。
这一篇想要做的,是把任务分解这件事从"自然语言派单"提升到"可机读的契约协作",并把整套契约设计、契约测试、契约违反检测与补救的工程闭环,与形式化的"意图语义"层和"博弈协议"层统一在一个框架下。我们的目标读者是正在搭建生产级多智能体系统的工程师与架构师:你不需要从零发明这套契约机制,但你需要知道哪些组件可以复用、哪些组件必须自研、哪些组件可以借用现有的契约测试理论、Pact、property-based testing、以及分布式系统协议形式化工具。
我们把"任务契约"(Task Contract)定义为一个五元组:
Contract := (Intent, Precondition, Obligation, Evidence, Remedy)
status、confidence、evidence_refs 三个字段"。get_customer_by_id API 并返回了 200 + 非空 customer",或"对原始 PDF 抽取了文本并 hash 校验通过"。这五元组不是装饰品。它的每一项都在生产线上对应一段可执行代码——Precondition 是 pre-hook,Obligation 是 schema 校验,Evidence 是证据补全 + 签名,Remedy 是异常分支。把"任务契约"从文档层下放到可执行代码层,等于把"协作"从一次性的善意沟通,转换为可以被持续验证、持续报警、持续回归的工程对象。
值得注意的是,这五元组之间是有顺序依赖的:Intent 是其他四项的解释上下文,没有 Intent,Precondition 校验无意义(为什么必须满足这个前置?);Obligation 是契约的核心可证伪对象;Evidence 是 Obligation 的证明链;Remedy 是契约失败时的逃生通道。顺序错了,契约就退化成"调用方写的代码注释"——人看得懂但机器不强制,生产事故再次回到"归因"环节。
Intent 是五元组里最被低估的一项,也是最难工程化的一项。绝大多数多智能体框架把 Intent 当成"任务描述字符串"塞给 worker——但 Intent 其实是分层结构,至少需要拆成四层:
四层 Intent 之间存在垂直依赖:业务意图是任务意图的合法性来源,任务意图是方法意图的上下文,方法意图是约束意图的执行环境。把四层合并成一段自然语言,看似简洁,实际上把"意图"压缩成了"任务派单字符串"——worker 拿到后无法区分哪些是硬约束、哪些是软目标、哪些只是上下文描述。
工程上,我们建议把 Intent 写成"意图栈"(Intent Stack),即一个数组,每层是一个带 schema 的对象:
{
"intent_stack": [
{"layer": "business", "value": "降低欺诈订单率", "metric": "fraud_rate", "target": "<=0.5%"},
{"layer": "task", "value": "对订单 X 执行欺诈评分", "subject": {"type": "order", "id": "X"}},
{"layer": "method", "value": "调用 fraud-score-v3 模型", "tool": "fraud_score", "params": {"threshold": 0.6, "feature_window_days": 30}},
{"layer": "constraint", "value": "硬延迟预算", "type": "latency_budget", "value_ms": 200}
]
}
worker 拿到 intent_stack 后,可以直接从 method 层读到执行参数,从 constraint 层读到硬延迟,从 business 层读到执行失败时的回退语义(欺诈评分失败时,是直接挂起订单,还是放行待人工审核?——业务层回答)。Intent 层的形式化不是"完整 LLM 时代之前的产物",而是让 LLM 在生产协作里被正确约束的工程基础。
Intent 栈的设计还有一个容易被忽略的语用学维度:不同层的"承诺强度"是不对称的。业务意图层表达的是"组织长期目标",其承诺强度在小时-天级别;任务意图层表达的是"本轮具体目标",承诺强度在分钟级别;方法意图层表达的是"本轮具体路径",承诺强度在秒级别;约束意图层表达的是"硬性边界",承诺强度在毫秒级别。
如果 worker 在执行中遇到约束与方法的冲突(例如约束说"200ms 内返回",方法说"必须调用 6 个外部 API 各取 200ms"),它该听哪个?答案是约束 > 方法 > 任务 > 业务——承诺强度高者覆盖承诺强度低者,但反过来不成立:任务意图不能违反业务意图,方法意图不能违反任务意图,约束意图是边界条件不构成"覆盖",而是说"在边界内执行方法"。
把承诺强度的层级关系写进 Intent Stack 的 schema(priority_layer 字段),worker 才能在冲突时做出可预测的选择,而不是根据自己的"理解"做隐式妥协。没有承诺强度标注的 Intent Stack,本质上是把冲突仲裁权让渡给 worker 的隐式偏好——这与"契约可控"的初衷相悖。
Intent Stack 的 schema 也必须版本化。同一个业务意图在不同时间可能由不同的版本承载——例如"降低欺诈订单率"在 v1 用 fraud-score-v3 模型,v2 用 fraud-score-v4 模型。如果不版本化,worker 拿到一份旧的 Intent Stack 但执行了新的方法,契约违反的根本原因会被掩埋在"哪个版本对哪个版本"的混乱中。
我们建议 Intent Stack 携带三类版本信息:schema_version(schema 自身的版本)、business_policy_version(业务策略版本,绑定策略审批记录)、model_version(若 method 层涉及模型调用,绑定模型版本)。三类版本一起支持回溯:任何契约违反事件都能反查到"在哪个 schema/策略/模型版本下发生",这是契约违反补救(回滚到上一个稳定版本)的前提。
契约写出来了,接下来是测试。我们推荐一个三件套组合:Pact 风格的"消费者驱动契约" + property-based testing 的"产物性质" + golden snapshot 的"主路径锁定"。
(1) 消费者驱动契约(Pact-style):执行方(worker)按契约声明其产物的 schema 与边界,调用方(planner)在测试期对 worker 的产物做 schema 校验与抽样断言。这一层的关键不是"校验 JSON Schema 合法",而是校验"业务上可接受的输入分布与边界"——例如"fraud_score 在 [0.0, 1.0] 区间、confidence 字段非空、evidence_refs 至少有 1 条指向真实的 API 调用"。如果 worker 升级后突然把 confidence 字段从枚举值改为自由文本,pact 测试立即 FAIL,不需要等到下游集成测试。
(2) 产物性质测试(property-based):对 Obligation 不只是"实例级断言",而是"性质级断言"。例如:
currency 字段非 CNY 的订单 X,fraud_score 必包含 currency_mismatch 风险标签"性质测试的本质是"用生成器造大量边界样本,把 worker 当成黑盒,验证业务级不变量"。这一层在多智能体协作里尤其重要,因为单个实例往往看起来对、性质层面才暴露系统性问题。
(3) Golden snapshot:把 worker 的"主路径"产物快照化(例如对一组 100 条固定订单的 fraud_score 输出),任何 schema 字段、字段顺序、字段语义的细微变化都会触发 snapshot diff。这层是"防止 silent regression"的最后一道防线。
三件套覆盖契约测试的不同切面:Pact 抓"接口级契约",property-based 抓"业务级不变量",golden snapshot 抓"主路径回归"。任何一件单独都不够——pact 通过但产物语义已经偏移;property 通过但接口 schema 已经变形;snapshot 通过但新边界未覆盖。三件套组合使用才是工业级契约测试。
把 pact + property + snapshot 三件套接入 CI 不是"开三个测试 runner"的简单工作,而是要约定三件套的失败语义:当某件套失败时,CI 应该 fail-fast 还是 fail-soft?
我们的建议是 fail-fast with differential signaling——任何一件套失败立即 fail CI,但失败信号里携带"是哪类契约失败"(接口 / 不变量 / 回归),便于工程师快速定位。pact fail 通常意味着接口 schema 变更,property fail 意味着业务规则变更,snapshot fail 意味着产物序列化变更——三类失败的修复路径完全不同,signal 必须区分。
更进一步,我们建议三件套的覆盖率指标也分开统计:pact_coverage(已签约契约覆盖率)、property_invariant_count(已表达不变量数)、snapshot_diff_rate(主路径产物变更率)。三个指标一起刻画"契约测试的工程成熟度",比单一的"测试覆盖率"更有信息量——覆盖率只是分母,这三件套的指标是分子。把这些指标接入团队的"工程成熟度看板",就能客观衡量每个 worker / 每个服务的契约健康度,而不是依赖资深工程师的"感觉"。
契约测试是离线/预发期的工程,生产环境是另一道工程——契约违反的实时检测与补救。
我们建议在 worker 与 planner 之间部署一个"契约执行代理"(Contract Enforcement Proxy, CEP)。CEP 是 worker 的 inbound 与 outbound 的中间网关,职责包括:
CEP 让"契约违反"从"worker 静默产出错误结果"升级为"CEP 在产物落库前拦截 + 触发补救"。这是生产级多智能体系统与 demo 级系统的分水岭。
CEP 不只是拦截器,也是契约违反的可观测性源头。每一个契约违反事件都应被 CEP 记录为结构化事件,字段包括:contract_id、worker_id、violation_type(precondition_fail / obligation_fail / evidence_missing / drift_detected)、remedy_path、latency_overhead_ms、upstream_trace_id。这些字段再被接入到现有 trace 系统(OpenTelemetry)、metric 系统(Prometheus)、log 系统(ELK),就构成了契约违反的完整可观测性面。
可观测性面的核心价值是"事后归因":一旦线上出现"最终结果错误",运维人员可以从最终结果反查到 CEP 的契约违反事件,再从 CEP 事件反查到 worker 的执行 trace,再从 trace 反查到上游 planner 的派单决策——形成一条完整的归因链。没有 CEP,归因只能依赖人工看日志和猜测;有 CEP,归因是查询式的。两者在事故响应时间上的差距是数量级。
CEP 必须运行在与 worker 隔离的进程中,而且最好运行在与 worker 不同的 trust domain——例如 worker 运行在容器 A,CEP 运行在容器 B(不同的 service account)。这一隔离的核心目的是防止 worker 被 prompt injection 或代码漏洞攻击后,把 CEP 也连带攻陷。如果 CEP 与 worker 共进程,worker 拿到 root 后能直接修改 CEP 的契约违反判定逻辑——契约防御就形同虚设。
隔离的实现代价并不高:用 sidecar 模式部署 CEP,worker 通过 localhost:port 调用,CEP 在 sidecar 容器里执行契约校验。sidecar 自身的代码量很小(几百行 Go/Rust),attack surface 极小,是工业界成熟的微服务模式。把 CEP 当成 worker 的"操作系统级 watchdog",而不是 worker 内部的库函数,是 CEP 设计的关键架构决策。
把五元组契约 + Intent 栈 + 契约测试 + CEP 串起来,我们可以从更高的视角看这件事:多智能体协作本质上是一个带类型系统的协议博弈。每个 worker 是一个 agent,契约是 agent 之间的"协议条款",Intent 栈是 agent 之间的"共享信念",CEP 是协议的"裁判与执行器"。
在这个视角下,契约违反不仅是工程错误,也是博弈论意义上的"协议失稳"——如果一个 worker 多次违反契约而 Remedy 没有强制执行,其他 worker 会"学会"这条契约不重要,进而整个协议系统的均衡点会从"按契约协作"漂移到"按自利执行",最终导致协作失败。
契约测试 + CEP 的本质,是把"协议博弈"约束在"按契约协作"这个均衡点附近,不让它漂移到自利均衡。这与分布式系统协议(2PC、Paxos、Raft)的形式化思路高度同源:协议正确性靠"不可绕过的执行器 + 可证伪的不变量"维持,而不是靠节点"自觉遵守"。
更进一步,我们可以借鉴协议组合性(Protocol Composition)的理论:小契约(单 worker 内的子任务契约)通过"协议组合算子"组合成大契约(多 worker 协作契约),组合过程保持可证伪性。生产上,这意味着我们可以对"fraud_score 子任务 + notification 子任务 + archive 子任务"三条小契约做笛卡尔积式测试,而不是只测每条小契约本身。
把以上讨论落到工程实践,我们推荐以下 6 条具体动作:
特别强调第 6 条:契约失败的默认 Remedy 应该是"升级到人"或"切换到备用 worker",而不是"重试"。重试只对瞬时错误有效,对契约违反(协议级错误)是浪费时间。把这写进契约是工程上低成本高回报的动作。
需要诚实承认这套框架的几个局限:
这些局限不是反对使用契约的理由,而是"哪些部分需要继续工程化"的路标。
如果今天要从零搭建一个生产级多智能体系统,我会按以下顺序落地:
契约工程不是"加几行代码"的事,而是"把协作语义当成一等公民"的事。当我们把任务契约当成可执行代码、当 Intent 栈当成 worker 的可机读上下文、当 CEP 当成协作的不可绕过裁判,多智能体系统才从"演示 demo"进入"生产系统"。
一句话摘要:多智能体协作的失败不是模型能力问题,而是协作语义缺乏可机读的契约——把任务契约从自然语言注释提升为五元组(意图/前置/义务/证据/补救)+ Intent 四层栈 + 契约测试三件套 + 契约执行代理,才能让多智能体从 demo 走到生产。
Conversation
0 条