同一句话让 Hermes 搜了四遍?20 分钟结果缓存让重复搜索不再重复扣费

你派 Hermes 去调研一个话题,它开了一个“搜索小分队”——好几个子代理同时开工。结果它们不约而同搜了同一个关键词:一次、两次、四次……你用的是付费搜索供应商的话,这几笔钱就这么重复扣了。又或者,它十分钟前刚抓过一个网页,转头又在同一页上重新抓了一遍。8 月 25 日合并的 PR #94618 给这类场景上了个缓存:web_search 和 web_extract 的结果 20 分钟内重复调用,不再重复向供应商收费。
缓存了什么:搜索去重 + 页面抓取去重
这次改动落在两个工具上:
web_search(网页搜索):同一个查询词在 20 分钟内重复出现,直接命中缓存,不再调用供应商的搜索 API。多个子代理并发搜同一个词时还会“合并请求”(single-flight)——第一个付费,其余共享结果。web_extract(网页抓取):同一个 URL 在 20 分钟内再次抓取,直接读磁盘缓存,不重新爬页面。抓取缓存是跨进程的:CLI、网关、定时任务、子代理共用同一份。
验证数据也很直观:官方测试里,同一个查询搜两次从 2 次供应商调用变成 1 次;4 个并发相同搜索从 4 次变成 1 次;同一 URL 抓两次从 2 次变成 1 次。
配置:两个键,默认就开着
web:
cache_enabled: true # 默认开启
cache_ttl_minutes: 20 # 缓存时长,范围 1–1440 分钟
也可以用命令改:
hermes config set web.cache_ttl_minutes 60 # 缓存拉长到 1 小时
hermes config set web.cache_enabled false # 彻底关掉缓存
安全设计:缓存永远不绕过检查
缓存听上去简单,但实现里有几个容易踩坑的点,官方特意做对了:
- 缓存放在所有安全检查之后:密钥藏在 URL 里、SSRF(服务端请求伪造)风险、策略过滤、供应商解析——这些检查全部通过后,缓存才参与。命中缓存只是跳过网络请求,不会跳过任何一道安全关卡;
- 只缓存成功的响应:失败的搜索不会留下缓存;无密钥的救援通道(keyless rescue)的结果也绝不缓存——一次性救援就是一次性;
- 缓存按调用方需要切片:搜索结果按 10/20/50/100 档位归组,
limit=5和limit=8的请求共享同一条缓存,各自按需要的条数切出来; - 超大页面不索引:超过 2MB(磁盘上限)的页面不进入缓存索引,避免缓存撑爆磁盘。
什么时候省得多、什么时候无所谓
省得最明显的场景:子代理并行调研(同一个查询被多个代理重复搜索);短时间内的重复抓取(比如多轮对话反复引用同一页面);定时任务和手动操作混用(它们共享同一份抓取缓存)。
基本无感的场景:每个查询都是新词、每个 URL 都只访问一次的工作流——缓存不会带来收益,但也几乎不增加负担(只多了一次本地查表)。
小结
20 分钟的结果缓存,把“重复搜索、重复抓取、重复扣费”变成“一次付费、大家共享”。默认开启、可配置时长、安全检查先行——这是那种“平时感觉不到,账单下来才发现省了”的改动。想知道 Hermes 还有哪些省钱的机制,我们写过 免费搜索五通道指南 和 四个隐藏技巧合集;web 搜索工具的完整用法见 hermes 命令参考。