验证门与观察预算


文档摘要

验证门与观察预算 本节摘要:没有验证层的外壳就是套着风衣的许愿。本节建确定性门链,决定:工具调用是否允许触发、Agent 能看到多少它的输出、循环何时因「读太多」而停。门链是若干小而命名的门加一本「观察账本」(跟踪给模型看过的每个 token)的函数。真实使用头一小时会出现三类 bug:无界观察(grep 一个 20 万行仓库倒 50 万 token)、陈旧近因(第 47 轮编辑从不出现在第 3 轮读之后)、权限蔓延(研究任务从 websearch 蔓延到 shell)。验证门就是说「不」的外壳组件——它不是模型、不是评委,是 的确定性函数,返回 ALLOW 或 DENY 加理由。 对应原课程:Phase 19 · Lesson 25 · (原英文 )。

验证门与观察预算

本节摘要:没有验证层的外壳就是套着风衣的许愿。本节建确定性门链,决定:工具调用是否允许触发、Agent 能看到多少它的输出、循环何时因「读太多」而停。门链是若干小而命名的门加一本「观察账本」(跟踪给模型看过的每个 token)的函数。真实使用头一小时会出现三类 bug:无界观察(grep 一个 20 万行仓库倒 50 万 token)、陈旧近因(第 47 轮编辑从不出现在第 3 轮读之后)、权限蔓延(研究任务从 web_search 蔓延到 shell)。验证门就是说「不」的外壳组件——它不是模型、不是评委,是 (call, history, ledger) 的确定性函数,返回 ALLOW 或 DENY 加理由。

对应原课程:Phase 19 · Lesson 25 · verification-gates-observation-budget(原英文 phases/19-capstone-projects/25-verification-gates-observation-budget/docs/en.md)。本节属「Agent Harness 深度构建赛道」第六节。

学习目标

阅读完本节,你应当能够:

  1. 构建带确定性 evaluate(call) 方法的 VerificationGate 协议。
  2. 把预算门、近因门、白名单门、正则门组成带短路语义的链。
  3. 通过按工具与轮次键控的 ObservationLedger 跟踪每次观察。
  4. 在累计观察预算将超时拒绝工具调用。
  5. 呈现下游可观测性可摄取的结构化 GateDecision 记录。

一、问题与直觉

外壳让模型自由调工具时,真实使用头一小时出现三类 bug。

第一,无界观察。一个跨 20 万行仓库的 grep 把 50 万 token 输出倒进下一轮。模型每 KB 看一条匹配,上下文其余浪费了。token 账单大,Agent 在任务上反而更差。第二,陈旧近因。长跑任务攒 50 个工具调用,模型把第 3 轮的 read_file 当活状态重读,第 47 轮的编辑从不出场。第三,权限蔓延。研究任务从 web_search 开始,不知怎么跑起了 shell,因为模型发明了工具名而外壳默认宽松。等读 trace 时,/tmp 里躺了个垃圾文件,一个 curl 跑去了私有 API。

验证门就是说「不」的组件。它不是模型、不是评委,是 (call, history, ledger) 的确定性函数,返回 ALLOW 或 DENY 加理由。理由被记、被告诉模型、循环继续或中止。

二、从零实现

门是任何有 evaluate(call, ctx) -> GateDecision 方法的东西。链是有序列表,首个 deny 短路。顺序要紧:便宜的结构门先跑,贵的数 token 门后跑。

四个门:

  • 白名单门:允许的工具名是显式集合,集合外拒绝。最便宜,最先跑。
  • 正则门:工具参数匹配正则。拦带 rm -rf 的 shell 调用、拦去内网 IP 的 HTTP 调用。纯在调用 payload 上。
  • 近因门:模型只看最近 N 轮的观察,老的屏蔽。门拒绝会扩展已老化观察窗口的工具调用结果。
  • 预算门:会话内模型累计读过的 token 有上限。账本说触上限,后续每个工具调用都被拒。

观察账本(把账):

class ObservationLedger: def record(self, turn, tool, tokens): ... # 每成功调用写一行 def cumulative(self) -> int: ... # 模型总共看了多少 def per_tool(self, name) -> int: ... # 模型对工具 X 看了多少

账本回答两个问题:模型总共看了多少、对工具 X 看了多少。预算门读第一个,按工具预算门(练习)读第二个。

三、门链顺序为何要紧

deny 比 allow 便宜。白名单门 O(1) 哈希查;正则门 O(pattern × argv);近因门读消息存储小切片;预算门读整本账本。按成本升序排,被拒调用在做贵活前短路。也按影响半径排:白名单是最强主张(这工具不在契约里);正则其次(这参数不在契约里);近因再后(外壳还在乎但调用结构合法);预算最后(按定义只在前全过后才触发)。

四、可复用产物

实现是单个 main.py 加测试。ObservationToolCall 数据类定义线形状;ObservationLedger(turn, tool, tokens) 行并答 cumulative()per_tool(name);GateDecision(allow, reason, gate_name);VerificationGate 是协议,每门实现 evaluate(call, ctx);GateChain 包有序列表,逐门调,首个 deny 返回,全过返回 allow。

demo 跑一个微型合成 Agent 循环:三轮,第三轮触发预算门,循环报告一个干净的拒绝(非零 refusal_count)。token 计数器故意用 len(text) // 4 的蠢启发——本节重点是门管道不是分词器,生产里换真分词器。

五、与赛道其余的组合

前几节给了循环、工具注册表、消息存储、提示构造器、模型路由。本节加模型与工具之间的层。第 26 节发门链说 ALLOW 后分发器把工具调用交去的沙箱;第 27 节发把拒绝计数当质量信号记的评估套件;第 28 节把门决策接到 OpenTelemetry span;第 29 节把全部缝成一个能跑的编码 Agent。

六、练习

  1. 按工具预算门:写一个读 ledger.per_tool(name) 的门,对单工具设上限,超限拒绝。
  2. 正则拦 shell:写一个正则门,拦带 rm -rf 的 shell 调用,确认 DENY 带理由。
  3. 近因屏蔽:让近因门 N=3,确认第 1 轮观察在第 5 轮被屏蔽,模型重读时拿不到。
  4. 链顺序:把预算门放最前,确认性能下降(每次调用都读整本账本)。
  5. 拒绝计数阈值:让循环在 refusal_count 达 5 时中止,确认干净退出。

本节要点回顾

  1. 三类 bug:无界观察、陈旧近因、权限蔓延——门链就是治这三样的。
  2. 门是确定性函数:(call, history, ledger) → ALLOW/DENY + 理由,不是模型不是评委。
  3. 四个门:白名单(最便宜)/正则/近因/预算(最贵),短路语义。
  4. 观察账本:按 (turn, tool, tokens) 记,答累计与按工具。
  5. 顺序按成本与影响半径:deny 比 allow 便宜,贵的活被短路。
  6. 拒绝是质量信号:第 27 节把 refusal_count 当评估指标。

下一节,我们建「沙箱与拒绝清单」——门链说 ALLOW 后,工具调用实际跑在的隔离环境。


发布者: 作者: Rohit Gupta 转发
评论区 (0)
U