Skip to content

fix(recall): split stable persona before CACHE_BOUNDARY for prefix caching (#120)#449

Open
muzimu217 wants to merge 1 commit into
TencentCloud:mainfrom
muzimu217:fix/split-system-minimal
Open

fix(recall): split stable persona before CACHE_BOUNDARY for prefix caching (#120)#449
muzimu217 wants to merge 1 commit into
TencentCloud:mainfrom
muzimu217:fix/split-system-minimal

Conversation

@muzimu217

@muzimu217 muzimu217 commented Jul 9, 2026

Copy link
Copy Markdown

⚠️ CRITICAL WARNING: Unverified Host Contract

This PR relies on an UNVERIFIED assumption: OpenClaw host consumes prependSystemContext to place content before CACHE_BOUNDARY.

Evidence Status: MISSING

Risk: Silent Failure

If the host doesn't recognize prependSystemContext:

  • Persona will NOT be placed before CACHE_BOUNDARY
  • The claimed ~40-60 tokens/turn cache gain will NOT occur
  • No error message will appear (silent failure)

摘要

实验性功能 - 把稳定 persona 移到 CACHE_BOUNDARY 之前参与缓存。

⚠️ 定位声明:这是一个 边际优化(marginal optimization),不是核心修复。

  • 优化对象:Persona(~15 tokens/turn)
  • 真实问题:动态 L1(500-1700 tokens/turn)
  • 优化比例:~1.5% 的收益(舍入误差级别)
  • 类比:"摆正甲板上的躺椅,而船正在沉"

量化收益分析

对比数据

内容类型 Token 量 变化频率 缓存影响
动态 L1(真凶) 500-1700/turn 每轮变化 炸穿缓存
Persona(本PR) ~15/turn 稳定不变 舍入误差
收益比例 15 / 1000 - ~1.5%

理论收益(如果宿主支持)

  • Persona:~40 chars ≈ 10-15 tokens
  • 缓存收益:+15 tokens/turn(理论值)
  • 前提:宿主必须识别 prependSystemContext

#375 的关系

重叠警告

PR 优化对象 收益 优先级
#375(Canonical) 动态 L1 位置 避免 500-1700 tokens 炸缓存 ⭐⭐⭐ 核心
本 PR(实验性) Persona 位置 +15 tokens/turn(理论) ⭐ 边际

关键发现

建议合并顺序

  1. 先合并 fix(recall): stabilize prompt-cache memory injection #375(核心修复)
  2. 再评估本 PR 是否必要(边际价值)

已修复的漏洞

基于代码审查反馈,已修复以下问题:

✅ 漏洞#1:添加宿主契约警告

  • 明确标注 prependSystemContext 是未验证的假设
  • 详细文档化证据缺失状态
  • 说明静默失败风险

✅ 漏洞#3:删除 dedup 死代码

  • 完全移除 dedupeRecallLines 函数
  • 移除 dedup 参数(从未被传递)
  • 清理误导性的测试覆盖

✅ 漏洞#7:移除 showInjected 超scope逻辑

  • 已完全清理(之前完成)

✅ 漏洞#9:修正错误注释

  • 删除 "Pure, host-neutral" 错误声称
  • 明确标注 OpenClaw-specific

✅ 漏洞#10:添加验证测试

  • 添加宿主行为模拟测试
  • 文档化未验证假设
  • 明确测试局限性

配置

{
  "recall": {
    "cacheOptimization": "split_system"  // ⚠️ 实验性功能
  }
}

默认值"none"(向后兼容,opt-in)

建议

  • 保持默认 "none" 直到宿主契约被验证
  • 如果启用,需理解这可能无实际效果(静默失败)

改进建议

在考虑合并本 PR 前,建议:

  1. 验证宿主契约

    • 查找 OpenClaw 文档
    • 咨询 OpenClaw 维护者
    • 确认正确的字段名
  2. 评估必要性

  3. 量化真实收益

    • 如果宿主支持,测量实际缓存收益
    • 对比 L1 问题规模,评估边际价值

关键限制

本 PR 不能解决的问题

推荐替代方案

测试

  • ✅ 13 个新测试(包含宿主行为模拟)
  • ✅ 明确文档化未验证假设
  • ⚠️ 不验证实际缓存效果(需要宿主契约)

Change Type

  • Experimental feature | 实验性功能
  • Code cleanup | 代码清理
  • Documentation improvement | 文档改进

Supersedes #321 (kept open for history tracking)

建议:在验证宿主契约前,保持 "none" 默认值。

…ching (TencentCloud#120)

Move the truly stable persona content into prependSystemAddition (placed
BEFORE the host CACHE_BOUNDARY) when cacheOptimization='split_system',
so prefix-matching providers (DeepSeek/MiMo) can cache it across turns.

Dynamic L1 memories are intentionally NOT moved — they change every turn
and would bust the cache for everything downstream. Leave them in
prependContext (after the boundary), exactly as today.

Default 'none' = zero behavior change. This is orthogonal to and
composable with TencentCloud#375's injectionMode (which controls L1 position).

Dropped the earlier stable_wrapper approach: a fixed opening tag does NOT
help prefix caching because the dynamic content inside still diverges and
invalidates the cached prefix. Only genuinely stable content (persona)
belongs before the boundary.
@muzimu217 muzimu217 force-pushed the fix/split-system-minimal branch from 8f428c3 to efa2bdf Compare July 9, 2026 10:47
@muzimu217 muzimu217 changed the title refactor(recall): split_system — 稳定 persona 前置缓存边界(re-scope of #321) fix(recall): split stable persona before CACHE_BOUNDARY for prefix caching (#120) Jul 9, 2026
@muzimu217

Copy link
Copy Markdown
Author

@YOMXXX 你好,想麻烦你帮忙 review 一下这个 re-scope 后的小 PR。

背景:原 #321 想一次性覆盖 #120 的缓存问题,体量偏大(2464 行),早期方案里 stable_wrapper 的核心假设经 feedback 后发现站不住——前缀匹配缓存是对完整前缀 token 序列做哈希,wrapper 内部动态记忆每轮变化就会让其后缓存整体失效,固定开标签对真实命中率几乎没有贡献。所以我们把 #321 拆小、并放弃了 stable_wrapper。

本 PR 只做一件事:把稳定的 persona 移到 CACHE_BOUNDARY 之前参与缓存。#375 已被定为 canonical runtime fix(解决动态 L1 的位置),两者正交、不冲突,本 PR 可作为其补充而非替代。默认 none 零行为变更。

想请确认的点

  1. prependSystemAddition 这个字段的放置方式是否符合宿主约定;
  2. 这个最小方向是否值得合入,还是更希望我们直接在 fix(recall): stabilize prompt-cache memory injection #375 之上提 follow-up。

关于量化数据#433 用的是真实 provider 实测(2 provider × 2 variant × 2 repeat × 3 turn),我们早期的自建基准是仿真、不够严谨,已不纳入本 PR;如需量化佐证,我们会参考 #433 的方法补真实测量,而不是用仿真数字。

谢谢,听你的建议。

@muzimu217

Copy link
Copy Markdown
Author

补一个独立的缓存记账基准测试作为佐证:#450

说明:那是确定性仿真(不调 API、不测真实 cache_read),只验证 split_system 确实把稳定 persona 移进了缓存边界前的可缓存前缀、且动态 L1 不进前缀。真实命中率数字以 #433 的 provider 实测为准,本测试不自称测得真实提升。

@Maxwell-Code07

Copy link
Copy Markdown
Collaborator

嗯嗯好的,我们已经收到您的PR,针对参加犀牛鸟活动的PR,我们内部近期将会排期进行集中reveiw,感谢您的关注!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants