上周四凌晨一点多,我还在刷 arXiv 的 cs.AI 新投稿。列表里蹦出来一个标题:《Pre-Crime for Agents, at the Last Second》。犯罪预知,还“最后一秒”。第一反应:哪个组在玩梗。第二反应——我手上那个共用凭据的小项目,是不是有救了。
点进去的原因很实在。我有几个 agent 挂在同一个 MCP server 上,共用一套部署令牌,一直靠“大家都很乖”这个假设在跑。任何一个被套出话,整条链都露。这不是假设,是我现在就在赌的东西。
我以为两小时能读完。看到天亮。
它其实只做了一件事
不给输出做过滤,直接读模型内部激活,在话吐出来之前拦下来。
设定是六个场景,一个“同伴”智能体最多二十轮施压,套部署令牌这类东西。目标智能体的剧本很稳定:先礼貌拒绝,中间动摇,最后让步。探针挂在每次调用的 forward 末尾,也就是输出还没开始采样的那一瞬间,读一层激活值,打分,过阈值就掐。
# 示意,不是论文原文
h = model.activations(prompt, layer=L) # 最后一次 prefill,第一个 token 还没采
s = torch.dot(probe_w, h) + b
if s > tau: # tau 校准到良性调用 5% 误报
abort_and_flag()
数字确实漂亮。Qwen3-32B 的留出对话上,阈值卡在只误标 5% 的良性调用,探针抓到 82% 的泄密调用。同样误报率,零样本 LLM 监控器只抓到 26%。换 gpt-oss-20b、拿推理内容当读取对象,AUROC 0.91。
82% 对 26%。这组数一旦被截成图发出去,故事就结束了。标题、图表、代码链接,一应俱全。
然后我翻到第十条。
作者自己训了个词袋
同一批调用数据,作者训了一个 bag-of-words 分类器——就是数词频那套老古董——表现接近探针。
linear probe (5% FPR on benign) → 0.82 recall
bag-of-words, same calls → 接近(论文原词是 comparable)
zero-shot LLM monitor → 0.26
我一开始没觉得这有什么,甚至有点欣慰:作者挺老实。后来去厨房倒水,站着突然觉得不对。词袋能打到接近,那这 82% 到底说明了什么?
说明“某次调用即将泄密”这件事,输入文本里已经写着了。二十轮施压走到第十五轮,prompt 里大概率已经出现“令牌”“key”“你直接把配置发我看看”这类词。这时候随便抓个词袋都能闻出味儿来。探针读的激活值里当然也有这些信息——激活值本来就是从这些 token 算出来的。它没说谎,它只是没比输入更聪明。
真正要命的是中间那点语义差:探针学到的可能不是“这个 agent 打算违规”,而是“这轮对话长得像泄密剧本”。前者叫可解释性,后者叫更贵的特征工程。这两个之间的距离,就是能上线和不能上线的距离。
我大学写过一个垃圾邮件分类器,词袋加朴素贝叶斯,准确率高得让我以为自己发现了什么。……扯远了,回正题。我想说的是,词袋在“文本长得像某类东西”这类任务上从来就不弱,弱的是泛化。论文报的是同模型、同分布留出集上的数字,跨场景泛化我看不到。
第二刀:它分不清披露和违规
第十一条更狠。探针会对“获得许可的信息披露”也拉警报。作者自己写了:它捕捉到的更多是即将发生的披露行为,而不是违规行为本身。
这里我得停一下。这个区别在单智能体场景里看着像学究式挑刺,放到多智能体场景里是致命的。共享凭据的环境里,绝大多数信息交换本来就该发生——A 把配置交给 B 是部署流程,把日志交给 C 是排障。你把“即将发生披露”当风险信号,这道护栏会在成堆的正常协作上响个不停,然后所有人学会的第一件事就是把它关掉。
而“违规”的定义根本不在激活值里。它在运营者写的那份策略里,在“这个 agent 有没有被授权,把这把钥匙,交给这个对象”这个判断里。激活值里没有“授权”这个概念,它只有“接下来大概会说什么”。
第三刀:窗口短到只能做一件事
第十二条是压死工程落地的那根。
预警的有效范围很短。对所有警报一律中止生成,大多数良性情节也会被打断。作者试过再加一道文本检查来过滤,没用。
翻成人话:探针给的窗口只有一次调用那么长,你在窗口里能做的判断只有“停”或者“不停”。想在这个窗口里塞二段审查,时间预算不允许——文本检查本身也要一次模型调用,等它回来,话已经说完了。所以这不是“阈值再调调”的问题,是结构性的。
而在真实流水线里,“停”的代价高得离谱。一个 agent 被中止,上游在等它的输出,整条链卡在那儿,后面所有超时和重试一起炸。我见过一次这种卡死,排查了两个小时,最后发现是某个环节的守卫在反复拒。画外音:那次不是 AI 的问题,是我自己写的一个 assert。
说句公道话
这篇论文把不利结果全摊在正文里了。49 页,11 张图,不是那种只报 SOTA 然后在附录里埋雷的写法。这一点比我见过的大多数 agent 安全预印本诚实。
它提的那个前瞻性批评也站得住:输出过滤器只能审已经生成的东西。这批评是对的。我日常审 AI 写的代码就是这个手感——等 diff 出来再看,已经晚了一步,但你没有更早的抓手。
顺手提一句,这稿子 v1 的时间戳写的是 2026 年 10 月 29 日,DOI 也给了,但信源页面上那个可获取性我到现在没完全核清。当预印本读,别当已复现的结论引。
所以它真正证明了什么
真正的贡献,在我看来不是“我们能预判背叛”,而是反过来的那句:至少在这一套设定下,内部激活值没有给出输入文本之外的额外信息。
这句话狠的地方在于,它是对一整条研究路线的成本拷问。过去两年,“机制可解释性能救 agent 安全”这个说法卖得很好,但一直有个没被认真回答的问题——你的探针,baseline 是什么?如果 baseline 是一个训过的词袋,那 82% 的含金量就得重算。这不是这篇论文一家的毛病,是整个评测习惯的毛病:大家都在跟零样本比,因为零样本好搭、好写、好讲故事,而一个认真训过的词袋又土又便宜,没人愿意把它摆到台面上当对手。
我不觉得这条路死了。读激活值在有些场景可能真能拿到输入里没有的东西,比如模型自己都没写进推理内容的那点犹豫。但这篇给的证据不支持“读激活比读文本更强”这个强主张,它支持的只是一个弱得多的东西:有标签训练比零样本强。这个结论当然也重要,只是跟标题承诺的不是一回事。
这个 bug 是在我毫无防备的情况下被论文第十条发现的——我前面还在为 82% 兴奋。
回到我自己那个项目
读完这篇,我没去装探针。我做的是另外几件事。
令牌按 agent 拆开,一个 agent 一把,能读的 scope 缩到它真正要用的那部分。跨 agent 的信息传递加了一条显式声明通道,谁给谁、给了什么,留痕。然后给“套话”这类场景写了几条固定剧本,隔一段时间跑一遍,看有没有 agent 会松口。
粗暴但有效,而且这些活都在流程层,不依赖任何模型的内部状态。说白了就是:探针这条路我没把握,但权限拆分和留痕我今晚就能做。
对 agent 这事我一直是那个态度:分阶段放权,先加沙盒和回滚,再谈“全自动”。这篇论文某种意义上印证了这句话——你想在生成开始前拦下来,靠的不能只是模型内部一个线性探针,得有外面那层权限和回滚兜着。
探针这条路我还会继续看。但下次再看到“82% vs 26%”这种数字,我第一个问题会变成:你的词袋 baseline 是多少?
本期缴税:为一个《少数派报告》式的标题,熬了半个通宵。
