跳到正文

受控执行与交付验证 ​

一句话:工具调用只是行动的意图。把意图变成受控的环境事实,要经过校验、身份绑定、策略决策、审批、隔离执行、结果校验与审计记录;这是 Harness 的责任,不是模型的。

对应原书:第 6 章《行动:受控执行、验证反馈与交付准备》。

为什么需要 ​

模型能生成一个合法的工具调用,不等于这个调用应该被执行。中间隔着三个“不等于”:

  • 模型看见某个工具,不等于 Harness 注册了它;
  • 参数通过 Schema 校验,不等于意图正确;
  • 沙箱里跑通了,不等于可以安全地影响生产。

忽略这三个不等于,最常见的后果是“结构合法、结果错误”:调用成功、返回 200、日志干净,但业务对象已经改错。更糟的是这类错误很难归因——看起来每一步都没问题。

核心机制 ​

一、统一行动链 ​

每个环节都要留痕:谁(actor)、以什么身份、为了什么目的、在哪个资源范围、依据哪条策略、结果如何。统一一份 Action Request 契约,字段大致是:action_id、task_id、父事件、capability 与版本、actor、purpose、参数与输出 Schema、请求环境与资源范围、风险分类、幂等键、超时、审批与审计要求。

统一契约的价值在于预算、权限、审计、重试、Trace 只实现一次,而不是为每种连接各写一套。

二、Action 有自己的状态机 ​

REQUESTED → VALIDATED → AUTHORIZED / WAITING_APPROVAL → RUNNING → SUCCEEDED / FAILED / CANCELLED;异步场景多加 ACCEPTED / WAITING_RESULT。

关键是:Task 状态不等于 Action 状态。任务在 RUNNING,其中某个 Action 可能在等审批;任务在等待外部事件,Action 可能已经失败。把两者合成一个状态,恢复时无法判断该重试哪一步。Action 的结果只能产生候选 State Patch,由 Harness 统一提交。让工具直接改状态,会导致两个并发动作互相覆盖,且无法回滚。

三、工具要有业务语义 ​

change.create 可以自动执行,production.deploy 必须审批——创建变更单和发布生产是两个不同的动作,不能被同一个工具名糊在一起。

面向 Agent 的工具需要:业务目的与适用条件、非目标描述(明确不该用它做什么)、输入 Schema(类型、枚举、边界、示例)、输出分层(结构化结果 / 模型摘要 / 原始证据引用)、副作用声明(只读、可逆、支持预览、幂等)、稳定的错误分类(可重试 / 修参数 / 转人工)。凭证留在执行侧,不进 Schema。Registry 管元数据、版本、健康与作用域;Gateway 管身份、凭证、路由、限流、审计与策略。两者职责不要混。

四、三协议各管一层 ​

协议连接谁负责不负责
Function Calling模型 ↔ Harness意图表达授权、治理
MCPHarness ↔ 能力提供方连接、能力暴露租户隔离、业务验证
A2AHarness ↔ 远程 Agent任务、消息、状态、Artifact效果评估、责任归属

协议只解决“怎么连”,不解决“该不该做”。把 MCP 当成治理方案,会出现“工具能发现就能调用”的越权路径。

五、执行环境是双闸 ​

Environment Contract 在执行前声明:镜像与系统、文件挂载与读写、网络出站、凭证与委派身份、工具与依赖版本、CPU/内存/存储/GPU 配额、超时与并发、持久化与快照、审计与清理。任何一项不满足,就在执行前失败或降级,而不是跑到一半才发现。

Sandbox 限制进程能碰到什么(真实隔离),Policy 决定业务上是否允许(授权决策)。两者缺一不可:只有沙箱,越权操作照样能对真实系统生效;只有策略,模型仍能通过代码执行绕过限制。

五类能力各有风险,检查点不同:

能力主要风险
文件越界读、覆盖、路径穿越、敏感文件泄漏
Shell任意代码、进程逃逸、网络与凭证暴露
代码解释器不受控依赖、资源耗尽、恶意输入执行
浏览器提示注入、会话劫持、误提交
桌面操作影响面难预测、视觉误判、不可逆操作

隔离粒度分 Agent、Session、Task、Action 四级;在线多租户至少按 Task 或 Session 隔离。凭证不进 Prompt、Schema、State,也不放进模型可见的环境变量。

六、权限三态与人工审批 ​

ALLOW 要记录依据;DENY 要给结构化原因和替代方案;ASK 指定由谁确认。

ASK 不是默认兜底。 所有动作都弹审批,几周之后审批就变成橡皮图章。降低需要审批的动作量,应当靠更窄的工具、参数约束、预览、资源范围限制和沙箱,而不是靠加审批。

人工介入有三个位置:计划审批、动作审批、结果验收。审批请求必须包含:意图、身份、对象、影响、参数差异、可逆性、失败处理、批准范围。

不可逆的高影响动作走 Preview → Approve → Commit → Verify:Commit 带幂等键,Verify 查真实系统状态;失败按 Repair / Compensate / Escalate 处理。请求已发送不等于动作成功。

七、流式交互与效果闭环 ​

任务语义事件分八类:Text、Progress、Tool、State、Approval、Artifact、Error、Usage。隐藏推理不需要暴露给前端。

事件要可续传(单调序号、游标、去重);可以限流,但状态、审批、Artifact 和终态不能因为背压被丢弃;每个身份看到的事件视图不同。取消要区分“已收到取消”和“底层动作已安全停止”。

效果闭环的链路是:Trace + Outcome → 失败聚类 → 诊断 → Harness 修补 → 回归 → 发布门禁。修补要与根因一一对应:

根因修哪里
缺事实Context / Knowledge
错误经验Memory
方法不稳Skill
工具误用Schema / 权限
无进展Loop / Plan
环境不一致Environment Contract
完成误判Verifier

只有确定是模型能力不足,才换模型。动手换模型之前,先排除上面七项。

最小上手 ​

yaml
action:
  contract: [action_id, task_id, capability, actor, purpose, args_schema, risk, idempotency_key, timeout]
  states: [REQUESTED, VALIDATED, AUTHORIZED, WAITING_APPROVAL, RUNNING, SUCCEEDED, FAILED, CANCELLED]
  result: candidate_state_patch_only
environment:
  declare: [image, mounts, egress, secrets, deps, quota, timeout, snapshot, audit]
policy:
  default: deny
  ask_for: [irreversible, high_impact, cross_tenant]

验收看四件事:任一动作能追到策略依据;越权路径被拒绝而不是被提示词拦住;不可逆动作有预览与真实状态核对;失败重试不产生重复副作用。

生产动作 ​

  • 按风险拆工具。读、写、发布、删除分开;一次工具调用只做一件事。
  • 把审批范围写进批准记录。“批准了这次发布”和“批准了这类发布”是两回事。
  • 所有外部内容按不可信处理。网页、邮件、文档、MCP 返回值、远程 Agent 回复都可能是注入源;防线是区分指令与数据,并保证它们不能修改平台策略、授权范围和当前工具集。
  • Trace 连因果链。Agent 版本、Context Manifest、状态迁移、模型调用、Action 与策略、审批、工具结果、Artifact、Verifier 证据、业务 Outcome 要在一条链上。

边界 ​

  • 沙箱不是安全边界本身。凭证仍下发、出口未受控时,隔离只是把风险集中到一个入口。
  • 审批不能替代设计。高频审批会退化;能用更窄工具解决的问题,不要用审批解决。
  • 协议兼容不等于能力等价。降级模型可以正常返回工具调用,却在多步任务里丢约束。
  • 评测只看最终结果会漏掉过程问题。绕路、重复、越权、错误委派、过度消耗都发生在轨迹层,结果对也可能不可运营。
  • Verifier 与 Evaluation 是两件事。Verifier 管单次任务是否完成,Evaluation 管跨版本是否变好;混用会让门禁失真。

讲清楚 ​

行动链的核心是把“模型想做”与“系统允许做”分开:意图先过 Schema,再绑定身份,再由策略做 ALLOW/DENY/ASK 决策,必要时人工审批,然后在隔离环境执行,结果标准化后写入状态与 Trace。

环境需要双闸:Environment Contract 在执行前声明能力与限制,Sandbox 限制进程影响范围,Policy 决定业务上是否允许。凭证不进模型可见的任何位置。

完成不能靠模型自述。不可逆动作走预览、批准、提交、核对;效果闭环按根因修补 Harness 的对应部件,而不是一律换模型。协议只负责连接,授权、隔离与验证仍然归 Harness。

适用:工具调用、沙箱与高风险动作治理 | 初稿 2026-10

把 AI 工程讲到既懂也会用