欢迎光临
我们一直在努力

OpenClaw 2026-10-10 三档缓存(L1 Runtime Fact / L2 SQLite Admission / L3 Prompt KV)真实合并栈:把 Gateway 的「读」成本沿调用栈由内到外拆开

2026 年 10 月 10 日这天,OpenClaw 主仓在 24 小时内连续合入三张看起来主题不同、但工程语义高度耦合的 PR:#168655 improve: reduce repeated runtime fact queries on unchanged turns、#168647 perf(sqlite): reuse admission snapshots across worker requests 和 #168392 fix(agents): guard prompt-cache reuse across replay and releases。如果只看 PR 标题,你会以为是 runtime、SQLite、prompt cache 三个分散的工程话题;但把三张 PR 的 production delta、cache 失效规则与 CI 验证链条并排摆开,你会发现它们其实在做同一件事——把 OpenClaw Gateway 的「读」成本,沿着调用栈由内到外拆成了三层缓存。

这不是事后总结,这是 2026-10-10 当天 GitHub main 分支真实发生的事。本文按 L1/L2/L3 三档顺序展开,每档都给出对应 PR 的代码改动、失效边界与验证证据;最后给出 5 条「为什么这件事对企业 IT 值得认真读」的非工程结论。所有引用的 PR 编号、行数、测试结果均来自当天 GitHub API 拉取,时间戳 2026-10-11 06:04 Asia/Shanghai。

L1 缓存:RPC 前的 Runtime Fact 复用(#168655)

OpenClaw 的 agent 在一次 turn 中往往要查六类「runtime 准备事实」:workspace state、conversation bindings、skill-library selection、workshop history、device catalogs、GitHub attribution,以及 approval preparation。改动前,这六类事实每个 turn 都会从 SQLite worker 重读一次。#168655 的设计是把它们挂在 gateway owner 持有的 snapshot 上,owner 收到 publication 就 invalidate,数据库 retirement 就清空,callers 拿到的是独立值——而不是共享 mutable。

具体改动落在 25 个 production 文件、5 类 owner:src/agents/workspace-state-cache.ts(+84)新建一个独立 cache owner,src/agents/workspace-state-store.ts(+23/-3)把 store 改成「先看 cache 再看 worker」,src/infra/device-pairing-publication.ts(+21/-1)+store(+5/-1)+identity(+5/-3)+readonly(+7/-2)把设备配对的四类声明一起接入;src/infra/exec-approvals-store.ts(+87/-9)是改动最大的一个 owner,execution-approval 的 guard 仍然直接查表,但其它字段走 cache;src/infra/outbound/current-conversation-bindings.ts(+56/-7)+publication(+5/-3)+kernel(+1/-1)+worker.test(+44/-0)覆盖会话绑定的全套发布路径;src/skills/library/store-authority.ts(+48/-4)+store-access(+13/-5)+selection-authority.test(+40/-0)锁定 skill 选型的 authority;src/skills/workshop/changes.ts(+84/-0)+library.ts(+4/-22)+library.test(+23/-1)把 workshop history 压到 500 行 bounded snapshot 再本地 filter;src/state/user-profile-github-identity.ts(+27/-14)+user-profiles-multi-account.test(+34/-5)处理多账号的 GitHub identity。

关键的设计约束是「不引入 foreign-writer polling、不引入新 fencing、不引入新跨线程握手」。Workspace 准备路径甚至加了一个更细的判断:当输入未变时,snapshotAndRegister 直接跳过,这一步把很多 warmed-turn 的 database traffic 直接削掉。同时 cold database creation 会丢弃 path-identity snapshot(因为 owner 变成 physical file 了),auth-profile reads 暂时不动——因为缩窄那个 owner 需要更广的 writer 覆盖,留给后续 PR。

Evidence 部分,作者跑了一组 M1/C1/M2/C2/M3/C3 的三对交替基线对照,在同一个 16 vCPU idle Testbox 上,base e40606fdea9613,候选 e4f6829ce017b,workload 和 native counter 不变,只复制任务加 attribution。对照结果并未在 PR body 里完整给出数字,但 evidence 的设计本身传达了一个信号:这条 L1 缓存是被测量过的,不是被推论出来的。

L2 缓存:SQLite Admission Snapshot 复用(#168647)

L1 解决了「agent turn 重读 6 类事实」的问题,但 Gateway worker 端每个 RPC dispatch 还要做一件事:遍历所有 retained SQLite admission、复制每张 fact map、检查共享 validity cell、为没变的事实重建 string fingerprint——然后才发现 nothing has changed。#168647 把这套动作直接收掉:admission registry 在 publication 阶段就 prepare snapshot,transfer 只走 changed records,unchanged reply installation 变成 no-op。

具体改动聚焦在 src/infra/sqlite-database-admission-record.ts(+114/-35)+admission.ts(+25/-64)+admission.worker.test-support.ts(+6/-0)+admission.worker.test.ts(+24/-0)+schema-facts.native.test.ts(+55/-0)+docs/reference/database-schemas.md(+6/-0)+docs/reference/database-schemas/worker-access.md(+12/-0)。production 净增量 +40 行(139 added,99 deleted)。其中 admission.ts 砍掉的 39 行恰好就是旧的 capture/fingerprint 实现——这条 L2 缓存不是叠加,而是替换。

值得专门指出的是「弱 cursor」设计:不再保留 old snapshots,只留最新一份。Shared cells invalidate transferred facts 立即生效——这意味着 transfer 和 install 现在共用同一个 owner,在 admission-record 模块里;而 native identity/lifetime 处理仍留在 admission 模块,后者净减 39 行。Publication 和 explicit full captures 会 reclaim remotely retired records,但有一个例外——不删除「同 file 的新 admitted generation」,这是用来避免 race 把已经更新到 v2 的 admission 又被 v1 reclaim 写回去。

User Impact 的表述很克制:No schema, stored-data, permission, configuration, or upgrade/downgrade changes。这意味着这是一条「不改字节」的性能优化——你升级到包含这张 PR 的 build,数据库文件不用动,迁移脚本不用跑,但 Gateway 在长寿命场景下的主线程 CPU 会持续走低。First-use validation、shared revocation、writer custody、host-only completeness、generation-aware retirement 五条边界全部保留。

PR #168647 SQLite admission snapshot reuse 详情页截图,2026-10-10 Chrome headless 实拍
PR #168647 SQLite admission snapshot reuse 详情页截图,2026-10-10 06:05 Asia/Shanghai Chrome headless 实拍。

L3 缓存:Prompt-Prefix 与 KV-Cache 守护(#168392)

L1 和 L2 解决的都是「OpenClaw 自己读什么」;L3 是「对外发出去的内容里,哪些能被模型供应商的 prompt cache / KV cache 复用」。这是一个看起来很工程、但实际上直接决定企业 IT 账单的场景——Anthropic、OpenAI Responses、Chat Completions、Claude in-history system route 都有自己的 cache,OpenClaw 要让这些 cache 真的能命中,前提是发出去的字节是稳定的。#168392 干的就是这件事,而且它不是「新建」,是「守护」——一个 end-to-end 的 guard,装在 Full Release Validation(FRV)里,正常 CI 也跑。

这张 PR 在 nightly merge window(参 2026-10-10 那篇「夜间合入窗口」一文)是被特别提到的「带可审计工程证据」的一张:production 净增量极大(+789/-410 量级,跨 30+ 文件),覆盖 .github/workflows/full-release-validation.yml(+1/-1)+openclaw-live-and-e2e-checks-reusable.yml(+15/-1)+config/assertion-safety-baseline.txt(+1/-1)+docs/ci.md(+4/-0)+docs/help/testing/suites.md(+113/-0)+docs/reference/RELEASING.md(+16/-0)+docs/reference/full-release-validation/profiles.md(+14/-1)+docs/reference/prompt-caching.md(+28/-0)这一长串 CI / docs 变更;以及 extensions/openai/openai-provider.responses.test.ts(+52/-0)+openai-provider.test.ts(+0/-50)+replay-policy.ts(+1/-0)+packages/ai/src/anthropic-cache-carrier-parity.test.ts(+7/-2)+anthropic-cache-transport-parity.test.ts(+2/-2)+anthropic-payload-policy.ts(+2/-7)+scripts/e2e/anthropic-cache-live-docker.sh(+1/-1)+anthropic-cache-live.mts(+202/-125)+lib/anthropic-cache/mock-provider.mts(+126/-6)+prefix-stability.mts(+224/-0)这一长串真实 cache live e2e。

src/agents 侧的改动覆盖:embedded-agent-runner.cache.live.test.ts(+85/-90)+cache.test-support.ts(+216/-1)+prompt-cache.test.ts(+629/-0,新增)+attempt-history-prepare.ts(+5/-1)+session-boundary-prompt-cache-key.ts(+21/-0,新增)+tool-result-projection-key.ts(+114/-0,新增)+tool-result-truncation.ts(+19/-94)+command/attempt-auth-selection.ts(+19/-0)+command/attempt-execution.ts(+18/-19)+session-tool-result-guard-wrapper.ts(+18/-11)+session-tool-result-guard.payload.ts(+1/-8)。其中 prompt-cache.test.ts 是 629 行的新测试矩阵,offline 跑 10 个真实 admitted turns × 4 个 transport,exercise 大 tool results / image cleanup / pruning / instruction refresh / MCP disconnect-reconnect / prompt hooks / steering / reopen 全场景。

这张 PR 实际 fix 的是三个 regression:replayed tool-result bytes、internal browser-session cache affinity、Anthropic cache marker 覆盖了 transient runtime context(后者在 reopen 时会被移除)。最终的「cache 能命中」语义是:已发布的 tool results 在 replay / reopen 时保持 bounded、redacted text;private subagent completion 保留它 browser conversation 的 opaque cache key;Anthropic history checkpoint 在 unretained runtime context 前停下,包括 steering 或 tool loop 跟在后面时。live-cache release job 可由 live_suite_filter=live-cache 显式选择,默认 stable/full profile 已经包含。

PR #168392 fix(agents) guard prompt-cache reuse across replay and releases 详情页截图,2026-10-10 Chrome headless 实拍
PR #168392 prompt-cache 守护详情页截图,2026-10-10 06:05 Asia/Shanghai Chrome headless 实拍。

三档缓存合在一起看

把这三张 PR 放进同一张图:L1(168655)是「agent turn 不重读 6 类 owner 事实」,位于 RPC 调用之前;L2(168647)是「worker RPC dispatch 不重建未变的 SQLite admission snapshot」,位于 worker 层;L3(168392)是「对外发出的字节能让模型供应商 cache 命中」,位于 transport 之上。L1+L2 处理「OpenClaw 自己读什么」,L3 处理「外面 cache 命中什么」——前者是省 CPU,后者是省 token / 省 cache rebuild 开销。

这三档的设计有一个共同点:cache 失效规则都是「publication-driven」,不是「TTL-driven」。L1 的 invalidate 来自 owner 收到 publication;L2 的 reclaim 来自 publication 或 explicit full capture;L3 的 prefix oracle 是 digest-only,由 Anthropic cache harness 持有,shared digest-only prefix oracle + live transport scenario 同时存在。这种「事件驱动失效」的设计选择,在 AI agent 这种长寿命、状态可变的进程里比 TTL 更合适——TTL 总是会在某些 corner case 里让 stale data 漏过去,而 publication-driven 的失效只要 owner 路径正确就一定 stale-free。

PR #168655 improve reduce repeated runtime fact queries on unchanged turns 详情页截图,2026-10-10 Chrome headless 实拍
PR #168655 runtime fact 复用详情页截图,2026-10-10 06:05 Asia/Shanghai Chrome headless 实拍。

为什么这件事对企业 IT 值得认真读

第一,「不引入 foreign-writer polling、不引入新 fencing、不引入新跨线程握手」是 OpenClaw 这次 cache 设计三条死线。这意味着当你在生产里打开 verbose tracing、或者接 OpenTelemetry collector 时,这些 L1/L2 的失效路径不会出现「trace collector 自己产生 publication 触发 cache 失效」这种荒谬反馈环——它对监控工具是安全的。

第二,L3 的 prompt-cache.test.ts(+629)用真实 admitted turns × 4 transports 跑 offline 矩阵,加上 anthropic-cache-live.mts(+202/-125)+prefix-stability.mts(+224/-0)两条 live e2e,意味着 Anthropic cache 在 FRV 路径上有「回放即守门」的覆盖。企业 IT 担心的「我升级后 cache 命中率掉了、账单突然涨」这种事,被这张 PR 直接消除了——replay policy、prefix stability、cache marker 三处都加了 guard。

第三,L2 的「不删除同 file 新 admitted generation」是一条特别克制的工程约定——它承认 race condition 存在但不试图用加锁解决,而是用 generation-aware retirement 让 v1 自动让位给 v2。这种设计在分布式系统里很少见,绝大多数团队会用 lock 或者 fence tokens。OpenClaw 选择保留 admission module 的 native identity/lifetime 处理在原模块、只把 cache 提取出来,正是为了让这条 generation 规则继续在原 owner 手里——这是为什么 admission.ts 净减 39 行、admission-record.ts 才 +114/-35 的原因。

第四,这三张 PR 都不是独立热点,而是栈关系。#168655 在 PR body 提到「复用 owner-held snapshots」,#168647 复用 admission snapshot 路径,#168392 守住对外 cache——三层 owner 都是「同一个事实不再被多次构建」。在 2026-10-10 之前,OpenClaw 经历过 v9.9 stable 与 v9.8 stable 的双轨收紧(详见 2026-10-09 那篇「9.9 release publication evidence chain」);9.9 → 10.1 的下一步就是这种「栈式收紧」。

第五,这次三张 PR 全部位于 10 月 10 日当天合并,在 main 分支 hash 7b125134f3860743 之后(参 #168220 body 里提到的 base)——它不是某次大版本的孤立事件,而是 v2026.10.1 stable 走向 GA 之前的密集合入期。对企业 IT 而言,这意味着 10.10 → 10.15 之间会出现一连串「performance+stability+cache 守护」类的密集合入,建议把升级窗口排到 10.15 之后,让这批 cache PR 在 nightly merge window 里先沉淀一个完整周期(详见 2026-10-10 06:00 那篇「夜间合入窗口的工程治理标准」)。

来源标注

赞(0)
未经允许不得转载:时间网 » OpenClaw 2026-10-10 三档缓存(L1 Runtime Fact / L2 SQLite Admission / L3 Prompt KV)真实合并栈:把 Gateway 的「读」成本沿调用栈由内到外拆开

更好的WordPress主题

支持快讯、专题、百度收录推送、人机验证、多级分类筛选器,适用于垂直站点、科技博客、个人站,扁平化设计、简洁白色、超多功能配置、会员中心、直达链接、文章图片弹窗、自动缩略图等...

联系我们联系我们

登录

找回密码

注册