我那条 AI 日报流水线,每天早上要在几十个源里翻一遍。10 月中旬有一天它跑到一半,卡在一个源上超时退出了。我没多想,把脚本又跑了一遍。半小时后它交出一份完整的稿子,看着挺顺——直到我对账的时候发现,检索接口的调用次数比前一天多了将近一倍。

它没有报错,没有崩溃,输出也齐全。它只是把做过的事再做了一遍,然后照常告诉我成功了。

**我的判断:断点续跑是 agent 系统里正确性最脆弱的一层,而这层最阴的地方在于——它的失败形态不是崩溃,是重复执行。**你在模型侧怎么调 prompt 都调不掉它,因为它根本不是模型的问题,是流程少了一条线:哪些动作允许被重放,哪些不允许。

三个独立样本,同指一处

这一周有三件互不相干的事,说的其实是同一个问题。

**样本一:langgraph 1.2.16,四个修复全部落在恢复路径。**10 月 16 日,图编排框架 langgraph 发了这个小版本,changelog 里四条修复分别是:resume 值非法时让其他任务照常结束;resumed 的 Command 更新只应用一次;resumed 的待写入只保存一次;以及一条写得很直白的——恢复时子图会把已经完成的任务再跑一遍。一个编排框架的一次小版本里,四个修复全部落在 resume 路径上,其中一个就是「重复执行」。这不是巧合,是那一层最难写对。

**样本二:Perplexity SPACE 把「暂停」和「可恢复」分成两个词。**10 月 15 日 Perplexity 开源了支撑其 Computer 产品全部会话的执行沙箱 SPACE(Apache 2.0,Rust)。它的生命周期有四个状态,其中 paused 和 suspended 的保证级别完全不同:paused 只把虚拟机内存留在 worker 上,不落持久快照;suspended 才把内存、运行时状态和根文件系统写进快照并释放资源;默认六小时无活动自动 suspend。一个产品特意把「停一下」和「存个档」做成两个词,等于承认它们不是一回事——而大量系统里这两个概念被混用,用户以为按了暂停就能接上,其实什么都没存。

**样本三:Claude Code v2.1.302 修了两个压缩相关的缺陷。**同周 Anthropic 的 release notes 里:一是在会话正在压缩时停止会报「提示词过长」;二是会话中途新增的工具在压缩后被重新加载,会触发提示词缓存失效。第二条例子最能说明问题——缓存命中率本来只跟提示词怎么写有关,现在还跟状态的恢复顺序有关。成本和正确性在恢复路径上咬合在了一起。

样本时间暴露的问题修复方向
langgraph 1.2.1610-16resume 时子图重跑已完成任务;更新与写入被应用两次恢复路径的幂等性
Perplexity SPACE10-15paused 与 suspended 被分为两个保证级别语义分开:留内存 ≠ 落快照
Claude Code v2.1.30210-16压缩后工具重载触发 prompt cache miss恢复顺序影响成本

检索第一次有了单价,重复执行有了价格

10 月 17 日,DeepSeek 把自家的 Search 和 Fetch 接口开放给所有开发者,两个端点各 0.75 美元一千次成功调用,失败、空结果、超时都不计费。

条目数值对架构的含义
单价$0.75 / 1000 次成功调用检索从摊在 token 里变成独立科目
计费口径只按成功计费;50 条与 1 条同价返回条数应拉满,与「少取少付」直觉相反
并发上限5 req/s / 账号fan-out 型 agent 的硬约束,需自带并发闸
计费生效10-31 16:00 UTC 起对 Harness / Claude Code / Codex 服务端调用计费此前免费,需在此之前摸清触发频次

以前检索是摊在 token 里的成本,看不清;现在它自己站出来成了一列。这带来一个直接的好处:**缓存检索结果第一次有了明确的 ROI 数字——一次命中,省 0.00075 美元。**要不要做缓存,从拍脑袋变成了算数。

但真正值得警惕的是另一头。我算成本总账的习惯公式是单价乘输出量乘重试次数,现在这一列得再乘一项:被调用的次数。这一项最阴,因为它不是模型多想了几步产生的,是流程本身重复了一圈产生的——你把模型换得再便宜,重复这一圈照跑。我的日报流水线那天多出来的调用,不是它变勤快了,是它把同一批源抓了两遍。

最贵的从来不是跑一次,是同一件事跑了两次,你还以为只跑了一次。

三件事,现在就能做

**给每个能被重跑的动作配一个幂等键。**不用改架构,在动作入口接一个「我做过这件事」的标记即可。做了这一步,重复执行会变成空操作,而不是第二笔账单。早期做分布式的时候我们就是这么做的,理由不是怕它出错,是怕它出错的时候看起来一切正常。

**把「暂停」和「可恢复」在命名上分开。**留内存的和落快照的,在系统里必须是两个词、两个保证级别。这一条不写代码也能做,先把文档和状态字段里的话说清楚。

**在检索入口前面装一道并发闸,后面垫一层缓存。**闸是为了不失控,不是为了提速;有了闸,缓存才敢按「命中就省七毛五」去算收益。

本周同一主线的其他信号

  • 10-16 NIST、NSA 与 CISA 联合发布十项实践,把 agent 越权行动正式定义为一类事故,并明确要求「恢复前先验证遏制措施仍然有效」——恢复路径第一次被写进联邦级检查清单。
  • 10-16 Claude Code v2.1.302 给读取工具加了 128MB 上限,被命名得像图片的管道和设备文件也不再被当成图片整个读进内存:工具没有资源上限,是和断点续跑同级的隐性问题。
  • 10-17 OpenCode 的 Console 遭攻破,托管在服务端的 provider 密钥外泄,波及约 1.4% 用户,从最早暴露到发出通知间隔约 22 小时——同样是一层没人日常检查的系统出了事。
  • 10-15 Perplexity 开源沙箱 SPACE,随附红队报告:虚拟机逃逸 0/108,而部分联网策略在修复前 11/54 被绕过(厂商自报,未独立复现)。

数据说明

langgraph 1.2.16 的 changelog 与 Claude Code v2.1.302 的 release notes 来自两个项目的官方 GitHub 仓库;SPACE 的红队数据(0/108 逃逸、11/54 出网绕过、10 家第三方沙箱 8 家有绕过路径)与延迟数字(中位创建 60ms、P90 89ms)均为 Perplexity 自报,未独立复现;DeepSeek Search / Fetch 的定价、计费口径与并发上限来自其 10 月 17 日官方公告与 API 文档,价格对比区间(Brave 约 $5、Exa $4–7、Perplexity $1–5、Tavily $8–16 每千次)来自单一媒体的上市日快照,仅作量级参考。事件状态:均为已落地的事实性发布,无传闻成分。

相关阅读:上一篇《开放模型的门槛从许可证换成了内存墙》讨论了部署形态分层;本文讨论的是恢复路径分层——两层加起来,是 agent 系统里最容易被「能跑就行」盖过去的地方。