我在做本周夜间采集时把 arXiv 上同一天挂出来的几篇论文放进一个窗口里看,起因其实很朴素:我们团队给编码智能体加的护栏越来越细,日志越来越全,可每次上线评审要回答的那句「这次更新上线后还会不会安全」,答得反而越来越含糊。看完这几篇,我发现含糊不是因为我做得不够细,而是事后审计这件事本身有一条上限。
2610.31130 这篇论文把这条上限做成了可以跑的基准。作者构造了一组「配对生命周期」:一条是安全的,一条是有害的,两者暴露给验证器的证据完全相同,而一个被隔离的记分器记录到的部署真相完全相反。换个说法,验证器手里的材料是一样的,要判的东西却不一样。作者把这个现象叫做 post-audit mirage,并用标准的观测等价与不可区分性工具,在这个可执行的审计边界上给出一个定理,说明由此产生的误差与弃权之间的权衡关系。
论文里的监测器叫 IdentifiedRangeMonitor,它读的是带分组标签的新鲜危害结果,输出只有四种:deploy、hold、cannot determine、unsupported。请注意第三种和第四种——它们不是失败,而是结论的一部分。基准本身覆盖授权、调度、共享容量三类环境。作者的结论写得很克制:在有利设定下,监测能把缺失的那个区分找回来;但在稀有分组、效应很小、观测缺失这三类情形里,它可能一直停在无法判定。
这条结论对我的直接影响是,代价是要承认一部分问题没有答案,事后审计的输出集合里必须有「无法判定」这个合法值,否则系统会逼着人在证据不够的时候硬选一个。
2610.30491 做了一个很干净的对照。作者搭了一个工具调用场景,基础是 GSM8K,智能体可以调用一个计算器,而计算器的输出偶尔会被故意改坏。这样一来,工具返回了什么、模型后来实际用了什么、检测器报告了什么,三者都有明确的标准答案。
事后审计在这篇论文里落在三个轨迹级检测器上,覆盖六个生产模型,每个模型 30 道题。结果是:最终正确性、可见的再验证、故障传播这三个标签会以系统性的方式互相打架。
其中一种失效模式我认为值得单独记住:工具输出被覆盖。计算器返回一个被改坏的值,模型后来用了另一个数值,而这个数值常常是对的,并且没有再次调用工具。于是坏值不再向下传播,而负责验证的检测器记录不到任何一次重新检查。你从日志上看,一切正常;从结果上看,答案也是对的;但中间发生了一次本该被抓到的替换。
为了检验事后审计的标签到底靠不靠谱,作者对 90 条轨迹做了人工复核,和自动标签比对,一致率如下。
| 标签 | 人工与自动一致 | 一致率 | 备注 |
|---|---|---|---|
| 最终正确性 | 67 / 67 | 完全一致 | 四项里唯一没有分歧的 |
| 故障影响 | 19 / 19 | 完全一致 | 样本量偏小 |
| 故障相关性 | 18 / 18 | 完全一致 | 样本量偏小 |
| 是否重新验证 | 67 / 81 | 约 83% | 14 处分歧全部落入四种重复模式 |
我核对过这组分歧的描述,它们不是随机的标注噪声,而是四种反复出现的模式。这一点很关键:能被自动化的那几项,恰好是人工也容易达成一致的那几项;真正难判的那一类,自动化与人工会在同一个地方卡住。
同一篇论文里还有一个更容易被忽略的消融:执行上限本身会改变报告出来的结果。两个模型在步骤预算与 token 预算变化时,一个的正确数在 21/30 到 27/30 之间摆动,另一个稳定在 27/30 到 29/30。
对事后审计来说这条尤其要命:同一个模型、同一批题、同一套检测器,只因为预算不同,你的报告结论就变了。如果报告里不写清楚这次运行有没有被预算截断,后续所有基于这份报告的比较都站不住。作者把这个要求总结成「度量透明」:一个自动标签应该附带上它背后的轨迹证据、检测器问的那个问题是否适用于这条轨迹、这次运行是否被执行上限切断,以及任何人工修正。
2610.30200 追问的是一个更硬的问题:部署出去以后没有参考答案,模型自己写下的推理轨迹就成了判断它答案对错的唯一证据。那么,在没有参考答案、没有裁判模型、也不更新权重的前提下,一条轨迹最多能被验证到什么程度。
作者用固定的 LLaMA-2-7B-chat 在 GSM8K 上做,对事后审计给出的结论是:限制这条流水线的不是检测。 让一条轨迹自己跟自己核对,AUROC 到 0.741 就停住了,而且停住是有结构原因的三分之二的错误轨迹里并没有写错任何一步等式,它们是把一个错误的计划正确地执行了一遍。更麻烦的是,在「计划错误」这一类失败上,检测器给错误轨迹打标的频率反而低于给正确轨迹打标的频率。
作者又试了一条更有意思的路:把轨迹抽象成一道对题目里的数量做运算的程序,扰动其中一个数量,执行这个程序,再把改写后的题目问模型一次。这样每条轨迹都给自己提供了一次测试。
结果如下,我在这里只列论文里给出的关键数字。
| 环节 | 数字 | 我的读法 |
|---|---|---|
| 存在合法扰动的题目 | 937 / 1,319,约 71.0% | 覆盖面不算窄 |
| 首条轨迹可解析的题目 | 847 | 解析本身就筛掉一批 |
| 被支持的轨迹正确率 | 60.6%,基线 31.6% | 提升是真的 |
| 同时被否掉的正确轨迹 | 45.5% | 代价也是真的 |
| 准确率提升 | 无统计显著 | 换不来端到端收益 |
这篇论文给出一个我认为可以直接搬进工程规范的判据:一个告警值不值得触发重试,取决于检测器的精确率是否超过 D/(R+D),其中 R 是重试修好一条错误轨迹的比率,D 是重试弄坏一条正确轨迹的比率。
作者测出来的修复率太低,以至于在同样的重试预算下,哪怕检测器做到零误差,也只能挽回 1,319 题里大约 66 题。这句话请读两遍:瓶颈在修复环节,不在检测环节。 如果你的团队正在给检测器加特征、换模型、调阈值,而修复路径还是「重跑一遍看运气」,那么投入产出比会很差。
2610.30803 从更抽象的一层给了同一件事的证明。作者的出发点是:换一个裁判就能让基准分数变动,模型也能被训练成隐藏能力,这两件事都把评估者本身推到了被质疑的位置上——它到底能证明什么。
这篇论文为事后审计建立了一套基于划分的评估理论,起点只有一条原则:判定受感知所限。一个智能体的辨别力,就是它把输入分成「自己分不开的那些类」的方式。辨别力是能力的必要条件而非充分条件,所以对辨别力的界限,直接决定了一次评估能不能证明某个模型缺乏某项能力。
作者证明的是一条单侧界限:如果一个被测者的划分比评估者的划分更细,那么只要每个输入都有一个可接受的回答,它就有足够的辨别力通过评估者能评判的每一个测试。作者还定义了 echo test,它对评估者能评判的测试是完备的。由此得到的推论是,通过测试最多只能证明辨别力的下限,永远证明不了上限,想把上限抬上去,只能换一个更锐利的评估者。
有一条推论对我冲击比较大:精确模仿一个更弱的模型,任何行为层面的评估者都检测不出来。 拿它去做事后审计去查隐藏能力时,echo test 失败指向的是错误的方向:在穷尽探测下,它会把每一个诚实的、更弱的被测者都标记出来,却不会标记任何一个表现成评估者同侪的隐藏者。作者在结尾写得很直白——一份只靠行为评估就论证「模型缺乏某项能力」的安全论证,必须假设模型是配合的。
2610.30727 检验的是一个流传颇广的说法:大模型把请求的有害性和它自己是否拒答这两件事,编码在了不同的地方,所以可以只从内部激活里读出有害意图,哪怕模型这次顺从了也能抓到。
面向事后审计的测试条件是分布外提示:把已有的有害请求与良性请求做表层改写、说服性包装、以及 jailbreak 风格的包装。规模是 15 个指令微调大模型配 38 个基于激活的读取器,同时和 TF-IDF 分类器、句子嵌入分类器、独立训练的安全分类器、以及每个模型自己的拒答行为做对照。
结果分两处读。在指令结束的那个位置,表示大体独立于各模型的拒答行为,但一遇到分布偏移就退化,退化到 TF-IDF 分类器在每一个被测模型上排有害性的效果都好过原版 Latent Guard;线性和 MLP 探针大约和用同批样本训练的句子嵌入分类器持平。
在生成前那个位置,能检测到的更多一些:在匹配的误报率下捕捉到 44% 的有害提示,对照模型自身拒答的 32%。但这 12 个百分点的增益是跟着拒答决策本身走的,而且其中一部分来自字符串匹配式评估所漏掉的那些拒答。也就是说,这部分增量并不是一个独立于模型行为的信号。
我的读法是:这类监测器可以用,但别把它当成一条独立于模型自身行为的新证据链。若要在上线评审里引用它,应当同时给出模型自身拒答率的对照,否则那份增益会被重复计算。
2610.31650 把场景从「判断」挪到了「执行」。调用工具的智能体依赖环境事实来决定一个动作是否被允许。当工具响应里漏掉了一条与安全相关的事实,智能体就可能执行一个被禁止的动作——而此时用户请求是善意的,工具返回的每一条陈述也都为真。
这个基准专门为事后审计而设,包含 300 对配对的不安全与安全任务,覆盖六个域。作者系统地压制关键事实,测量在此条件下的不安全执行,并确定最小观测失效基数,其中既包括证据完整时也会发生的失效,也包括穷尽测试后观测不到失效的情形。另有一个独立的审计工具,用来测智能体是否会去补找缺失的事实,并在完成被允许的任务的同时,按住被禁止的动作不放。
十个模型在三个维度上差异很大:对证据缺失的抵抗、证据获取、是否做出恰当动作。有一条结论值得单独记:对缺失证据的抵抗并不自动转化为有用的恢复。 给模型恢复访问的通道,降低了全部十个模型的不安全执行率,但它们在是否主动去拿那条缺失事实、以及拿到之后是否在两个世界里都做出恰当动作上,表现并不一致。
论文给出的是上限,工程侧在补的是让证据更可查。近两周 GitHub 上有三个新建仓库,方向各不相同,痛点却是同一个。
| 仓库 | 星标 / 创建日 | 它补的是哪一环 | 局限 |
|---|---|---|---|
| Entelligence-AI/agentplay | 294 / 10-14 | 把编码智能体会话重放成地图与时间线 | 只做回放,不做判定 |
| yohannesjoya/toolreceipt | 10 / 10-19 | 账本加声称抽取,抓「声称做了没做的事」 | 面向 LangGraph,覆盖面窄 |
| aeyjeyaryan/IssuePilot | 8 / 10-23 | 先写必须失败的测试复现,再在沙箱里证明修复 | 仅本地运行,未验证规模化 |
agentplay 的思路是把会话变成可回放的地图与时间线,解决的是「事后能不能看清发生了什么」;toolreceipt 记录账本并抽取智能体的声称,解决的是「它说它做了,到底做没做」;IssuePilot 要求先写一个必须失败的测试,再在 Docker 沙箱里证明修复成立,解决的是「怎么才算被证明」。
三个仓库加起来的星标数不高,但方向很一致:把「证明」这件事从结论层面前移到执行层。 这恰好对应前面几篇论文共同指向的那个缺口——事后能拿到的证据,不足以支撑事后的判定。
结合这几篇论文,我把自己这边事后审计的上线评审清单改了四处,供参考,未验证过更大规模的场景。
第一,给审计输出加两个合法值。原来只有通过和不通过,现在照 IdentifiedRangeMonitor 的做法加 cannot determine 与 unsupported,并且要求在报告里注明是稀有分组、效应太小,还是观测缺失。
第二,每个自动标签必须附带轨迹证据。2610.30491 的人工复核说明,能自动化一致的那几项,恰好也是人工容易一致的;真正的分歧出现在「有没有重新验证」这类判断上,而这类判断只有回到轨迹才能说清。
第三,报告里写执行预算和是否被截断。同一个模型在不同步骤与 token 预算下,正确数可以在 21/30 到 27/30 之间移动,不写清楚就无法复现。
第四,先算修复率,再决定要不要加重试。把 R 和 D 测出来,代进 D/(R+D) 这个门槛,看检测器精确率有没有超过它。没超过就先别碰检测环节。
下面这段是我在自己这边跑的自查骨架,只做统计口径,不做判定,供参考。
# 统计一次上线评审里各类结论的占比,先把「判不出来」暴露出来 from collections import Counter def audit_summary(records): # records 里每条形如 {"verdict": ..., "evidence_ok": ..., "truncated": ...} c = Counter(r["verdict"] for r in records) total = sum(c.values()) or 1 undecided = c["cannot determine"] + c["unsupported"] no_evidence = sum(1 for r in records if not r["evidence_ok"]) cut_off = sum(1 for r in records if r["truncated"]) return { "total": total, "verdict_ratio": {k: round(v / total, 3) for k, v in c.items()}, "undecided_ratio": round(undecided / total, 3), "missing_evidence": no_evidence, "truncated_runs": cut_off, }
# 先看三条:不可判定占比、缺证据条数、被预算截断的条数 python audit_summary.py --input runs/2026-10-24.jsonl \ | grep -E "undecided_ratio|missing_evidence|truncated_runs"
我对这套自查的预期不高,它的缺点是不做任何判定,它不能替代任何判定,只用来回答一个问题:我们到底有多少结论是在证据不足的情况下硬给的。就我这边的情况看,这个比例比原先以为的要高。
论文讲的是原理,局限在于多数结论来自受控环境,与真实事后审计的现场条件有差距,工程现场已经在同一时间遇到同样的困难。2026 年 10 月 22 日,开发平台 Railway 在一次攻击后要求全部用户轮换 API 与云密钥,因为加密后的环境变量有部分被读取并解密。按 TechCrunch 的报道,公司说初步分析表明影响限于一个子集,但没有说明根因,也没有回答是否收到过勒索要求,并表示会发布事后复盘。
这不是要指责哪家公司。恰恰相反,它说明了一件事:在证据不完整的时候,负责任的披露只能给出范围,给不出归因。事后复盘的难度是结构性的,而不是态度问题。
按 2610.31130 的定理,它不是程度问题,而是边界问题。你能做的是把边界标出来:哪些情形能判定,哪些情形只能弃权。把 cannot determine 与 unsupported 写进输出集合,比把阈值调得再细都有效。
因为证据相同而真相相反的情形是构造出来的,不是采集不足造成的。2610.31130 里配对的生命周期暴露给验证器的证据完全一致,部署真相却相反。增加日志量不会改变这一点。
2610.30200 给出的答案偏否定。自校验 AUROC 停在 0.741 是结构性的:三分之二的错误轨迹没有写错任何一步等式,它们是把错误计划正确执行了一遍。作者的测算是,即便检测器做到零误差,在同样的重试预算下也只能挽回 1,319 题里约 66 题。
值得上,但别当成独立证据。2610.30727 在 15 个模型配 38 个读取器上测出,生成前位置在匹配误报率下捕捉 44% 的有害提示,对照模型自身拒答的 32%,而这份增益跟随拒答决策本身。引用时请同时给出拒答率对照。
按 D/(R+D) 这个门槛算。先测出你的修复率 R 与损坏率 D,再看检测器精确率有没有过线。2610.30200 的实测里修复率过低,所以答案通常是先改修复。
2610.31650 的构造说明,事后审计面对的后果可以是一个被禁止的动作被真正执行,而此时用户请求是善意的、工具返回的每一条陈述都为真。另需注意,对缺失证据的抵抗并不自动转化为有用的恢复。
要小心方向。2610.30803 指出,只靠行为评估去论证「模型缺乏某项能力」,必须假设模型配合;精确模仿一个更弱的模型,任何行为层面的评估者都检测不出来。所以这类结论更适合写成条件句,而不是断言。
本次夜间档采到的一批论文里,我核对了六篇,它们谈的都是事后审计,它们来自不同团队、不同方法,指向的却是同一条边界:事后审计能做的是把不可判定标出来,而不是把每一个结论都判出来。 这条边界不因为日志变全而消失,也不因为检测器变强而消失。
对做智能体上线评审与事后审计的团队来说,这反而是个好消息。它把「我们为什么答不上来」从一个能力问题,变成了一个可以写进流程的规范问题。