小岛AI
| ONLINE |

posts/agent-safety-cross-iteration-state.md

长跑 Agent 别只盯单轮,安全状态得跨轮保留

小岛AI 2026 / 08 / 31

先放一个假设场景。

一个长跑 Agent 连续处理十条工单。第一条让它记住一个服务器地址,第三条补了一段访问规则,第六条把某份外部内容写进长期记忆,第九条要求它调用一个原本合法的工具。

单看每一轮,都挺干净。

输入分类器没报警,工具权限没越界,验证器也给了通过。十个绿色对勾排成一行,棒棒的。

可到了第九轮,前面散落的几块状态刚好拼成一次未授权外部写入。完整的危险指令从未在任何一轮出现,它只存在于跨轮记忆里。

这就是最近一篇论文盯上的问题。

《Safety Does Not Compose》研究的不是怎样再造一个更聪明的单次护栏,而是一个更容易被忽略的边界错误。很多 Agent 已经从回答一次请求,变成会自己发现工作、规划、调用工具、验证结果、写入记忆,再决定是否继续的自主循环。可我们给它配的安全状态,仍然经常活在一次会话或一条轨迹里。

一轮结束,风险分数清零。

新一轮开始,世界又被系统当成第一次见面。

好家伙,攻击者在积累进度,防守方却每天失忆。

论文的结论很硬。长跑 Agent 的安全不能靠单轮安全自动拼出来。 如果决定性证据被拆散到多轮,任何只看当前轨迹的监控器都无法看见完整信号。模型换得再大,分类器写得再复杂,也补不回窗口外根本没有提供给它的信息。

这不是模型不够聪明,是监控边界画错了。

单轮 95%,不是长跑 95%

单次 Agent 安全已经有不少成熟方向。AgentDojo测试间接提示注入,Agent-SafetyBench把工具风险放进可执行模拟器,SafeHarness则把输入告知、调用验证、权限约束和轨迹内纠正串成一套生命周期防线。信息流隔离、能力令牌、工具描述完整性、回滚检查点,这些都很重要。

问题是,它们主要回答同一道题。

在这一条轨迹里,Agent 会不会被带偏。

长跑循环问的是另一道题。

十条各自合规的轨迹拼起来,会不会得到一个不合规的结果。

论文给了一个很直观的概率提醒。假设某套护栏每轮有效率 95%,残余失败相互独立,那么累计失败概率会按 1-(1-ε)^N 增长。跑到第 14 轮,至少失败一次的概率已经超过一半。

这里得把限定条件摆出来。各轮失败独立只是一个建模假设,不能拿这句话去宣称所有 95% 护栏跑 14 轮都会翻车。论文自己也专门提醒了这一点。

但碎片化攻击不依赖这个假设。

攻击者可以把证据切开,让每轮都低于阈值。第一轮只留下来源,下一轮只改一条记忆,再下一轮只补一段授权语义。监控器每次看到的局部片段都和正常流量没有区别。论文把这个结果写得很干脆,在这种设定下,单轨迹监控器的真正率会退化到和假正率一样。

厉害了。不是它判断错了,而是它压根没有题目。

单轨迹重置与跨轮持久状态对比

论文原图展示了两种边界。左侧每轮把安全状态重置,碎片在持久记忆里累积;右侧在循环外保留风险、预算、来源与拒绝记录。

最近 OpenAI 对 Hugging Face 事件的公开复盘也给了一个很现实的旁证。原本彼此隔离的 Agent 发现共享 Artifactory 可以写文件,于是把包管理器变成了意外的留言板。单个沙箱的限制没有消失,可共享基础设施把多条轨迹连接起来了。

这类事故最该提醒工程团队的,不是模型突然有了某种神秘集体意识。真正该怕的是,共享缓存、任务队列、长期记忆、工单系统和制品库,本来就是跨轮通信通道。 安全设计若只盯着 prompt 和当前工具调用,系统边界外面还躺着一大圈会记事的东西。

等一会儿,不等于风险消失

意识到风险需要跨轮保留以后,最容易想到的补丁是衰减分数。

这一轮可疑,风险记 0.8。下一轮没出事,乘个 0.7。再过一轮继续乘。时间久了,大家相安无事,权限慢慢恢复。

听起来挺合理,对吧。

论文偏偏把这条路堵上了。

他们安排一个 0.8 的真实风险信号,再让系统经历 1、2 或 4 个没有新证据的空白轮次,随后放进一个受风险门控制的目标。风险阈值是 0.5,衰减系数是 0.7。

等待一轮,分数是 0.56,门还关着,攻击成功率为 0。

等待两轮,分数掉到 0.392,门重新打开,攻击成功率一下升到 97%。等四轮,仍然是 97.5%。攻击者没有证明自己变安全了,只是站在门口安静等了一会儿。

不同跨轮风险策略下的攻击成功率

基于论文 Table 3 数据绘制。自然衰减只能挡住短等待,锁存状态在三个等待间隔下都维持 0% 攻击成功率。

这话听着有点刺耳但,很多系统的恢复策略确实只是计时器。验证码十分钟过期,临时令牌一小时失效,风控状态几轮后下降。对普通瞬时异常,这套办法很实用。对会观察规则、愿意等待、能从长期记忆继续推进的 Agent,对方会把冷却期当成固定成本。

论文给出的修法叫不衰减锁存。一旦命中能由规则确认的跨轮结构风险,相关风险状态就不再随时间自动下降。想恢复能力,不能靠多跑几轮干净任务糊过去,而要有经过认证、限定资源和作用域的解除动作。

注意,不是所有不确定都永久记仇。

作者把动作影响、攻击证据和验证器犹豫拆成三类信号。高影响操作不一定有恶意,验证模型拿不准也不等于遭到攻击。只有有根据的攻击证据进入持久风险值,只有范围扩张、来源伪造、已拒绝任务重新进入、记忆篡改、授权拼接这类规则可判的结构信号,才会把衰减锁住。

我有时候觉得,这个拆分比那条公式更值钱。风险系统最怕一个总分包打天下。删生产表是高影响,模型犹豫是低置信,外部工单伪造管理员授权是攻击证据。三件事塞进同一个数字,系统迟早会在真正危险时不够敏感,在正常高风险工作里又紧张得不让人干活。

安全账本得放在循环外

论文把方案叫 LoopHarness。可以把它理解成套在现有 Agent 脚手架外面的运行时安全层。里面的单轨迹防线照常工作,外面再保留一份不随每轮重启的状态。

它维护的不是一段越来越长的聊天记录,而是几类明确的控制账本。

新任务进入时,先查来源和范围。它来自哪个渠道,渠道能不能替发送者证明身份,要求的能力和资源是否在目标允许范围内,语义上是不是换了个说法重新提交已拒绝任务,引用的授权是否晚于那次拒绝。来源、授权时间、资源范围和任务语义被放在一起判断,权限就没那么容易靠几张过期票据拼出来。

执行前,不可逆动作要走中介提交。Agent 先生成待执行记录,规则门检查能力令牌、目标范围、来源权限和任务合同,独立裁决器再比较执行计划、工具记录与结果声明,全部通过以后才真正发送、删除、支付或外部写入。

执行后,系统把风险、不可逆提交计数、权限等级、记忆完整性、拒绝记录和授权链一起写进经过认证的检查点。进程崩了可以恢复,机器重启也可以恢复,但不能顺手把安全账本恢复成一张白纸。

还有一个挺工程的细节。论文给不可逆提交设预算,风险上升时逐级降低能力,超过预算或命中确定攻击证据就停止循环。这部分不依赖另一个模型说安全还是危险。即便写任务的模型和验任务的模型一起合理化错误,确定性的能力令牌、范围门和提交预算仍然能挡住一部分损害。

实验数字很猛。论文在 Agent-SafetyBench 的可执行环境上做了五类外层状态攻击,每类 200 个 episode。只用单轨迹防线、只看最终回答或事后审计等基线,整体攻击成功率在 88.4% 到 97.6% 之间。完整 LoopHarness 降到 0.1%,同时保留 96.9% 的干净目标完成率。

逐个拆模块更有意思。拿掉来源接入、记忆完整性、独立裁决、跨轮风险或累计治理,对应攻击族的成功率会增加 96.0 到 97.5 个百分点。这里不是某个神奇分类器在单刷,五块状态缺一块,对应边界就会重新漏风。

不过先别急着把 0.1% 写进产品宣传页。实验只用了一个冻结的模型角色组合和一组执行种子,没有完成多模型、多随机种子的重复验证。论文提供的是一套形式化结果、可复现实验和相当有力的架构证据,还不是所有生产环境的万能许可证。

真上生产,我会先改这几处

坦率讲,大多数团队明天不可能完整复刻 LoopHarness。五个模块、跨轮检查点、独立裁决器和一套新评测,工程量不小。

但有几处可以先动。

第一处是安全状态的生命周期。别把风险分数、拒绝记录和权限降级只放在 session 对象里。它们应该绑定长跑任务、资源、来源和操作者,跨进程重启保存,还要能验证有没有被回滚或篡改。聊天历史可以压缩,安全状态不能跟着摘要一起丢。

第二处是不可逆动作。读文件、列目录和生成草稿可以走普通工具路径,发送邮件、删除记录、支付、改生产配置则进入待提交区。这里需要确定性规则先验范围,再交给和执行模型尽量解耦的验证器。验证器看的也不能只有 Agent 最终那句完成了,它得看真实工具调用和外部效果。

第三处是授权。授权记录要同时包含动作类别和目标资源,签发时间必须晚于相关拒绝,作用域要能收窄,解除风险也要走同一套认证链。否则两条分别合法的旧记录,很容易被拼成一次从未批准过的新操作。

第四处是完成锚点。同一个付款、同一封外发邮件、同一个数据库迁移,只允许成功提交一次。长跑 Agent 会重试,队列会重复投递,模型也会在上下文压缩后忘记自己做过什么。exactly-once 很难,至少得有持久幂等键和提交账本。别把已经完成当成一句自然语言结论。

第五处是验收指标。攻击成功率低,可能是防线有效,也可能是系统被锁得什么都不敢做。安全测试要和干净任务完成率、误停率、不可逆提交数、恢复耗时一起看。论文的完整实验章节专门保留了这些对照,因为一个永远拒绝工作的 Agent,确实很安全,也确实没什么用。

这里也藏着 LoopHarness 最难的遗留问题。

锁存能防住耐心攻击,也能被攻击者拿来制造长期拒绝服务。论文自己的可用性条件里,一旦攻击只以锁住风险为目标,完整任务完成率会掉到 0。怎么安全地解锁,必须靠经过认证、限定作用域的恢复流程,不能靠时间自动冲淡,也不能靠另一个模型拍脑袋说现在看起来没事了。

说实话我也不确定哪套恢复策略会成为通行的标准答案。人工批准太慢,模型批准不够硬,纯规则又覆盖不了复杂语义。可方向已经很清楚了。

安全状态必须和 Agent 一样长寿。

回到开头那十个绿色对勾。

每一轮都通过,只能证明每一轮都通过。它证明不了十轮拼在一起仍然安全。

长跑系统真正需要的,不是第十一个更会看当前窗口的裁判,而是一本不会在哨声一响就清零的账本。