多智能体系统如何学会可靠委派:从任务契约到动态质疑

2026-08-22 19 预计阅读时间: 1 分钟
来源: cloud.google.com AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:13 分钟

多智能体系统的难点并不只是让多个模型同时工作,而是让一个编排智能体把复杂目标拆成可验证、成本合适、权限受控的任务,并在意图模糊或风险升高时主动停下来质疑。Google DeepMind 关于智能委派的研究指出,委派本身就是一种智能行为:它需要协商、正式契约、安全边界,以及恰到好处的人类监督。

委派之前,先定义可验收的任务契约

简单地把一句自然语言请求转发给子智能体,不算可靠的任务分解。下游模型可能误解目标、遗漏约束,或者生成表面合理但无法验收的结果。随着委派链变长,这些偏差还会逐级放大。

更稳健的方法是采用“契约优先分解”:编排智能体先定义任务的输入、输出、验收标准、数据权限、预算和升级条件,再选择执行者。一个可执行的任务契约至少应回答这些问题:

  • 子智能体究竟要交付什么结构化结果?
  • 哪些条件可以由程序自动验证?
  • 哪些判断具有主观性,必须交给领域专家?
  • 子智能体能读取哪些数据,又明确禁止读取哪些数据?
  • 最多允许消耗多少令牌、时间或费用?
  • 出现歧义、冲突或低置信度时,应该拒绝、追问还是升级给人类?

例如,“分析员工薪资是否合理”过于宽泛,而且涉及敏感信息。它可以继续拆成“按部门计算薪资中位数”“检查结果是否满足匿名化阈值”“由薪酬专家解释异常”等子任务。前两项容易自动验证,最后一项则明确保留人工判断。

关键不是强行把所有工作都变成机器评分题,而是尽早识别不能可靠自动验收的部分。这样,人类时间才会投入真正需要专业判断的位置。

模型路由不能只看能力,也要看验证成本

企业工作流通常不应该把每项任务都交给最强、最贵的推理模型。表格格式转换、字段提取和固定模式分类,可以尝试使用轻量模型;跨文档推理、财务规则解释或高风险决策,则可能需要更强的模型和人工复核。

路由决策可以抽象为一个受约束的优化问题:在满足可靠性、权限和延迟目标的前提下,选择总成本最低的执行端点。实际成本不只包括模型调用费用,还包括:

  • 验证输出所需的额外调用;
  • 失败后的重试与回滚;
  • 人工审核时间;
  • 因错误结果引发的业务损失;
  • 向模型发送冗余上下文造成的令牌浪费。

因此,小模型只有在任务足够简单、输出容易验证时才真正便宜。反过来,一个难以检查的复杂任务即使由廉价模型完成,也可能因为反复重试和人工检查而提高总成本。

模型路由可以放在 API 网关中,也可以由客户端代理或编排层实现。无论采用哪种位置,都应记录任务类型、所选模型、估算成本、验证结果和升级原因,否则系统无法根据历史数据改进路由策略。

最小权限也适用于上下文窗口

多智能体委派中的权限控制,不应停留在“能否调用某个工具”。传给子智能体的提示词、检索结果和中间状态同样属于权限边界。

以薪资分析为例,负责生成部门统计摘要的子智能体通常不需要员工姓名、银行账号或完整工资记录。编排层应先做字段裁剪和聚合,只发送完成任务所需的最小数据。这同时带来两项收益:减少敏感信息泄露面,并缩短上下文以改善成本和模型表现。

研究还讨论了零知识证明等高级密码学机制:执行方可以证明某项计算满足指定性质,而不披露原始数据。这个方向适合需要强验证和数据隔离的场景,但它不是给普通大模型调用套上一层配置就能获得的能力。证明电路、可信实现、密钥管理和性能成本都需要独立的安全工程评估。

在大多数现阶段项目中,更现实的起点是字段白名单、短期凭证、工具级授权、审计日志和隔离执行环境。

可以这样实践:用契约、路由和升级规则搭一个最小编排器

下面是一个不依赖第三方库的 Python 示例。它不是某个云产品的真实 SDK,而是可以直接运行和改造的最小项目,用来展示四个机制:契约优先、按风险路由、敏感字段裁剪,以及遇到歧义时升级给人类。

将代码保存为 delegator.py,然后运行 python delegator.py。接入真实模型时,替换 cheap_workerreasoning_worker,同时保留契约校验与审计逻辑。

from dataclasses import dataclass
from statistics import median
from typing import Any, Callable


@dataclass(frozen=True)
class TaskContract:
    name: str
    required_fields: tuple[str, ...]
    allowed_fields: tuple[str, ...]
    risk: str
    max_cost_units: int
    verifier: Callable[[dict[str, Any]], bool]


def verify_department_summary(result: dict[str, Any]) -> bool:
    return (
        isinstance(result.get("department"), str)
        and isinstance(result.get("employee_count"), int)
        and result["employee_count"] >= 3
        and isinstance(result.get("median_salary"), (int, float))
        and result["median_salary"] > 0
    )


def cheap_worker(payload: dict[str, Any]) -> dict[str, Any]:
    salaries = payload["salaries"]
    return {
        "department": payload["department"],
        "employee_count": len(salaries),
        "median_salary": median(salaries),
    }


def reasoning_worker(payload: dict[str, Any]) -> dict[str, Any]:
    result = cheap_worker(payload)
    result["review_note"] = "High-risk result requires compensation-team approval."
    return result


def delegate(contract: TaskContract, source: dict[str, Any]) -> dict[str, Any]:
    missing = set(contract.required_fields) - source.keys()
    if missing:
        raise ValueError(f"Human input required; missing fields: {sorted(missing)}")

    # Build a new payload instead of forwarding the full source object.
    payload = {key: source[key] for key in contract.allowed_fields if key in source}

    if len(payload.get("salaries", [])) < 3:
        raise PermissionError("Human review required: anonymity threshold not met")

    worker = reasoning_worker if contract.risk == "high" else cheap_worker
    estimated_cost = 5 if worker is reasoning_worker else 1
    if estimated_cost > contract.max_cost_units:
        raise RuntimeError("Budget exceeded; renegotiate the task contract")

    result = worker(payload)
    if not contract.verifier(result):
        raise RuntimeError("Verification failed; do not pass result downstream")

    return {
        "status": "verified",
        "worker": worker.__name__,
        "estimated_cost_units": estimated_cost,
        "result": result,
    }


if __name__ == "__main__":
    contract = TaskContract(
        name="department_salary_summary",
        required_fields=("department", "salaries"),
        allowed_fields=("department", "salaries"),
        risk="low",
        max_cost_units=2,
        verifier=verify_department_summary,
    )

    payroll_record = {
        "department": "Platform",
        "salaries": [92000, 101000, 97000, 110000],
        "employee_names": ["A", "B", "C", "D"],
        "bank_accounts": ["REDACTED"] * 4,
    }

    print(delegate(contract, payroll_record))

这个示例有意不把 payroll_record 整体传给执行者。allowed_fields 形成字段白名单,姓名和银行账号不会进入子任务上下文。verifier 检查机器可判定的验收条件;匿名样本不足、预算超限或输出不合格时,流程停止,而不是继续向下游传播结果。

生产实现还应加入契约版本、超时、重试上限、幂等键、调用追踪和不可篡改的审计记录。涉及真实敏感数据时,也不能只依赖提示词约束,必须由服务端权限系统执行字段过滤和工具授权。

给智能体增加必要的“认知摩擦”

传统模型通常在请求没有触发明确安全禁令时倾向于执行。多智能体网络中,这种顺从会形成“无异议区”:每个智能体都认为自己只是在完成职责范围内的小任务,却没有检查上游意图是否已经偏移。

解决办法不是让每个步骤都等待人工批准,而是设置动态质疑条件。下面这些信号适合触发澄清、拒绝或人工复核:

  • 任务目标与原始用户目标不一致;
  • 所需数据超出契约允许范围;
  • 上游要求绕过验证器、审计或访问控制;
  • 高风险结论无法由证据支持;
  • 多个指令互相冲突;
  • 任务不可逆,或失败影响范围明显扩大;
  • 模型置信度低,但下游准备把结果当作事实使用。

这种摩擦也要控制成本。低风险、可逆、容易自动验证的任务可以直接执行;高风险、不可逆或主观性强的任务才升级给人类。人工审核界面应同时展示原始目标、任务契约、最小必要证据、验证失败原因和拟执行动作,避免让审核者重新阅读整条智能体对话。

上线前的委派检查清单

一个多智能体工作流是否成熟,可以从以下问题开始检查:

  • 每个子任务是否都有明确的输入、输出和验收标准?
  • 验证失败时,结果是否会被阻止进入下游?
  • 模型路由是否同时考虑可靠性、验证成本和失败代价?
  • 子智能体是否只获得完成任务所需的数据与工具权限?
  • 委派链中的每一步是否保留来源、契约版本和执行记录?
  • 系统是否能识别意图偏移、指令冲突和权限扩张?
  • 人类审核是否集中在主观、高风险或不可逆的环节?

可靠的多智能体系统不是一群自动互相转发消息的模型,而是一套有契约、有证据、有权限边界,也允许执行者提出异议的协作机制。任务拆得越细,并不必然越安全;只有每个分解步骤都可验证、可追踪,并且能在必要时停下来,委派才真正创造业务价值。


相关推荐