1. 新会话开局该带哪几条
一个用了一年的项目记忆会有几百条:用户的协作偏好、若干次发布踩过的坑、几个外部系统的位置、几次失败的调试路径。新会话开始时,全都带上会挤占窗口,只带索引又可能漏掉关键条。
这个问题有两个维度,通常只被讨论了第一个:取哪几条,以及什么时候付成本。第二个维度往往更影响结果——同样取五条,全放在请求开头每轮发送,与只在命中时展开,Token 花费差一个数量级。
2. 注入成本的结构
先把成本算清楚,后面讨论策略才有依据。
设库中有 \(n\) 条记忆,索引每行 \(\ell\) 字节,单条正文 \(m\) 字节,摘要体积 \(\sigma\) 字节,每轮取回 \(k\) 条,任务共 \(t\) 轮。三种常驻方式的注入总量 \(c\) 为:
第四种是引用快照,它的大小由被引用会话的体积决定,没有稳定估算方式,后面单独讨论。
代入一组具体数值:\(n = 400\),\(\ell = 60\) 字节,\(m = 3\) KB,\(k = 3\),\(t = 20\),\(\sigma = 10\) KB。
| 方式 | 计算 | 总量 | 说明 |
|---|---|---|---|
| 索引常驻 | \(20 \times 400 \times 60\) | 480 KB | 与库大小成正比 |
| 摘要常驻 | \(20 \times 10\) | 200 KB | 与库大小无关 |
| 按需挑选 | \(480 + 20 \times 3 \times 3\) | 660 KB | 索引加命中项 |
| 引用快照 | 视引用内容 | 不可估 | 由用户行为决定 |
这组数字给出几个反直觉的结论。
第一,在 \(n = 400\) 这个规模上,按需挑选的总量高于索引常驻。原因是索引仍然要注入(否则无从挑选),而命中项额外增加 180 KB。只有 \(m\) 很小或 \(k\) 很大时,按需才明显更省。
第二,按需挑选的真正收益不在总量,在每轮的增量。索引常驻每轮固定 24 KB,按需在未命中的轮次只付 9 KB(命中三条时)。对缓存友好的系统,稳定的 24 KB 比波动的 9 到 18 KB 更省——因为稳定前缀能命中缓存。
第三,摘要常驻的成本与库大小无关,这是它最大的优势。库从 400 条涨到 4000 条,摘要在 10 KB 上限内仍然是 10 KB,索引会涨十倍。
这三条合起来解释了一个现象:为什么 Codex 选摘要常驻而 Claude Code 选索引常驻。Claude Code 的场景是单项目长期使用,\(n\) 有上限(200 行);Codex 的场景是跨项目通用,\(n\) 可能很大,必须有与规模无关的常驻成本。
2.1 缓存对成本的重构
上面的算式忽略了缓存。设每轮不变的部分为 \(f\),变化的部分为 \(v\),缓存命中价格为正常价格的 \(\alpha\),则实际成本变为:
这个式子改变了选型逻辑。索引常驻的 480 KB 里,绝大部分是每轮不变的 \(f\),按 \(\alpha = 0.1\) 算,实际成本降到 48 KB 加变化部分。按需挑选的索引部分同样享受这个折扣,但命中项是变化的,计在 \(v\) 里,不打折。
所以真实成本排序与表面排序不同:
| 方式 | 表面成本 | 缓存后成本(\(\alpha = 0.1\)) |
|---|---|---|
| 索引常驻 | 480 KB | 48 KB |
| 摘要常驻 | 200 KB | 20 KB |
| 按需挑选 | 660 KB | 48 KB + 180 KB = 228 KB |
| 引用快照 | 不可估 | 不可估 |
按需挑选在缓存上吃了亏:它的命中项每轮都变,破坏了前缀稳定性。这解释了一个实现细节——Claude Code 把按需选中的记忆作为附件注入,附件位于消息列表的特定位置,不插进系统提示;这样至少不会破坏最前面的稳定前缀。
3. 取回链路
一次记忆取回通常经过六步。
- 生成查询。查询不完全等于用户的话,通常要带上任务类型与当前工作目录。
- 按作用域过滤。用户、项目、类型、权限。这一步必须在召回之前做,先召回再过滤会把越权内容读进内存。
- 多路召回。语义相似度找"意思接近",全文索引找"精确词命中"。
- 重排。综合相似度、置信度、时效、来源可信度。
- 去重与冲突检测。同一事实的多条记忆合并,互相矛盾的不进入上下文。
- 压缩成片段。带上类型标签与来源标记,长度受预算限制。
第三步与第四步的分工常被忽视。召回负责"不漏",重排负责"排序准"。只做召回不做重排时,一条三年前的相似条目和一条昨天的相似条目会并列返回,模型无法判断哪条更该信。
取回还要带类型。同样是"用户偏好中文",作为偏好注入可以改变输出语言,作为事实注入则可能被当作约束误用。片段前面标注类型,模型才有依据决定如何使用。
3.1 重排的打分
重排要综合四个信号:相似度、置信度、时效、来源可信度。四个信号不能简单加权求和,因为它们的量纲与含义不同。
相似度是连续值,通常落在零到一之间。置信度是写入时给出的估计,也在零到一之间,但含义完全不同——它表示"这条记忆当时是否被确认",不表示"现在是否适用"。时效是时间差,需要先转成分数。来源可信度取决于来源类型:用户显式陈述高于模型推断,带文件与命令的观察高于印象式归纳。
一个可用的两段式设计:先用硬条件过滤,再对剩余项排序。
过滤:
作用域匹配(用户、项目、权限)
未过期,或过期但最近验证时间在阈值内
无未解决的冲突状态
置信度高于下限
排序:
score = sim × 0.5 + fresh × 0.3 + src × 0.2
最终权重 = score × confidence置信度取乘数,理由是它表示"这条能不能用",与"这条有多相关"是两件事。加数会让一条高相似但低置信的记忆排到前面,乘数会让它自然沉底。
时效分可以写成指数衰减:
其中 \(d\) 是距上次验证的天数,\(\tau\) 是时间常数。取 \(\tau = 90\) 天时,一周前的记忆得 0.92,一个月的得 0.72,三个月的得 0.37,半年的得 0.13。这个曲线在"一个月内"区间内的差异不大,在"超过三个月"之后迅速衰减——符合"事实可能变化"的直觉判断。
3.2 并列与互斥的判定
重排之后还有一步:判断取回的多条记忆之间是并列还是互斥。
以"这个项目的部署命令是什么"为例。库里有一条三年前的"部署用 npm run deploy",一条三个月前的"部署改到 bash deploy.sh",一条上周的"部署前必须先跑迁移"。三条都含"部署",都会被召回。
前两条是互斥:同一个属性(部署命令)上有两个不同取值。第三条是并列:它说的是另一个属性(前置条件),与前两条可以同时成立。
两类关系的处理方式相反:
- 并列:全部保留,按相关度排序;
- 互斥:只能保留一条,或全部标为待确认。
判定依据是记忆内容的 subject 与 attribute,文本相似度在这里不够用——前两条相似度极高但必须二选一,第三条相似度也高但必须保留。同一个主体上的不同属性是并列,同一个属性上的不同取值是互斥。
这条判定对写入有反要求:写入时必须带上主体与属性字段。没有这两个字段,取回阶段只能靠模型猜,而猜测在多条并存时不稳定。
3.3 注入位置的差别
同样一段记忆,放在不同位置,效果不同。
放在系统提示里时,它表现得像规则,模型更倾向于无条件遵守;放在用户消息里时,它表现得像背景信息,模型会结合当前对话判断。这两者的差别在偏好类记忆上最明显:一条"用户偏好中文"放在系统提示里,模型会全程中文;放在用户消息里,模型可能只在那一轮用中文。
Codex 把记忆作为开发者角色的指令注入,单片段 8,900 字节截断。DeepSeek Harness 把指令链渲染成一条持久用户消息。Claude Code 把索引放进系统提示读取的项目文件清单,把按需选中的记忆作为附件注入。
三种位置对应三种强度:开发者指令介于系统提示与用户消息之间,既有规则意味又允许对话覆盖;持久用户消息更弱,模型会把它当作背景;系统提示最强,但会占用最稳定的前缀,改动会破坏缓存。
选择位置时要考虑两件事:这条记忆需不需要被覆盖?如果它是硬性约定(不许提交密钥、必须跑测试),放得越强越好;如果它是偏好(喜欢表格、偏好简洁),放太强会让模型在该变通时不知变通。
4. 四种注入方式
| 方式 | 常驻成本 | 触发时机 | 失误表现 |
|---|---|---|---|
| 索引常驻 | 索引全文,约 25 KB | 每轮 | 索引膨胀后挤占窗口,条数上限被撑破 |
| 摘要常驻 | 摘要全文,约 10 KB | 每轮 | 摘要为了塞进预算而过度压缩,细节全丢 |
| 按需挑选 | 索引 + 被选中的几份 | 请求前由模型或规则选择 | 选错条目,或漏选关键条 |
| 引用快照 | 被引用会话的体积 | 用户显式引用 | 快照冻结后不再更新,与当前事实脱节 |
三种主流实现最后都落在"轻量常驻 + 按需展开",但细节不同。
Claude Code 默认把 MEMORY.md 索引整段注入,索引上限 200 行、25,000 字节。索引每条只有一行,格式是标题加一句话钩子,指向一个主题文件。当索引接近上限时,提示词要求智能体合并细节或把内容移回主题文件。较新的实现加了一条按需路径:用一次模型调用从文件清单里选出最多 5 份相关记忆,作为附件注入,索引本身不再常驻。
Codex 常驻的是摘要,索引按需检索。memory_summary.md 分四段——用户画像、用户偏好、通用技巧、记忆索引——整体控制在 10,000 字节以内,首行固定为版本标记。更详细的内容放在 MEMORY.md 这份可 grep 的手册里,摘要中只给路由提示。读取侧以开发者指令的形式注入,单个片段超过 8,900 字节就截断,并提示模型去看文件。
DeepSeek Harness 没有记忆库,常驻的是工作区指令链。它按"用户全局 → 共享 agents 根 → 项目根到工作目录"的顺序渲染,预算 65,536 字节。超出预算时先整份丢弃最宽泛的文件,再截断最具体的文件,并生成一条可见通知,指名哪些文件被省略或截断。
三种做法对应三种判断:索引是"每条都值得知道位置",摘要是"少量结论值得每轮看到",指令链是"约定每轮都要遵守"。判断标准只有一条——这条信息是不是每一轮都要用。
4.1 按需挑选的召回质量
按需路径的核心是一次模型调用,它的质量直接决定注入质量。Claude Code 的选择提示词有几条约束值得看:
- 最多选 5 份;
- 只在"确定有用"时选,不确定就不选,可以返回空列表;
- 排除索引本身(已在上下文里);
- 排除本轮之前已经展示过的;
- 如果提供了最近使用的工具列表,不要选那些工具的用法文档——模型正在用它们,已经知道怎么用;但要选那些工具的注意事项与已知问题,因为正在使用正是这些问题最相关的时候。
最后一条是一个精细的判断:它区分了"参考文档"与"警告"两类内容。前者在模型正在使用该工具时是冗余的,后者恰好相反。
这条约束的代价是选择器需要知道本轮用过哪些工具。这要求选择调用拿到额外的运行时状态,而不能只给一个查询字符串。
按需路径的失效模式有两种:漏选和错选。漏选的代价通常更大,因为模型不知道有这个东西存在;错选的代价是浪费 Token 与注意力。所以提示词倾向于"宁可少选"——这与直觉相反,但对记忆场景是对的:模型至少还能通过文件工具自己去翻,而错误信息会主动误导。
5. 渐进披露
"常驻轻量、按需展开"这件事,在多个系统里以不同名字出现,本质是同一个结构。
第一层是索引或摘要,每轮可见,只放"有什么"和"在哪里"。第二层是主题文件,命中后才读,放"具体是什么"。第三层是原始轨迹,只在核对与追溯时读,放"当时到底发生了什么"。
这三个层次与技能系统的加载方式、与知识库的分层摘要(一句话摘要、概览、全文)是同构的。原因也相同:模型能吸收的上下文有限,把预算花在"先判断相关性"上,比花在"携带全部内容"上收益高。
5.1 三层之间的传递损耗
每一层展开都有信息损耗,理解损耗发生在哪里才能设计好索引。
索引层的损耗最严重:一条记忆被压缩成一行 60 到 150 字节的描述。这个描述如果只写"发布流程",后来者无法判断它是否包含自己要找的内容;如果写成"发布前必须跑迁移、发布后要验证健康检查",信息量就足够,但每条都这么写会撑破索引上限。
主题文件层的损耗小得多,但仍有取舍:完整正文可能几 KB,而注入预算有限,所以要截断。截断的位置很关键——截在结论之前,模型只看到背景;截在来源之后,模型拿到了结论但无法核对。
原始轨迹层几乎没有损耗,但有访问成本:读一次转录要几千到几万 Token,而且多数内容与当前问题无关。
这三层损耗的分布决定了索引写作的原则:索引要写到"能判断相关性"的粒度,主题文件要保证"结论与来源完整",轨迹只在需要核对时读。
5.2 索引与主题的一致性
三层结构有一个容易忽略的维护要求:索引与主题文件必须保持同步。索引指向一个已被删除的文件、或一个已被改名但索引未更新的文件,比没有索引更糟——模型会认为自己查过了。
这类不一致的产生有几种典型路径:
- 整理时删除了主题文件,忘了删索引行;
- 主题文件被改名,索引未更新;
- 索引行的描述与主题文件内容脱节(内容改了,描述没改)。
第三种最隐蔽。索引说"这条讲测试流程",主题文件里已经改成"发布流程",模型按索引读到后会发现内容不符,但通常不会回头质疑索引。
防范办法是把检索引成一致性检查:每次整理时验证每个索引行指向的文件存在、且描述与内容关键词有重叠。这个检查很便宜,但很少有实现做。
6. 新鲜度
记忆是某个时点的观察,不是当前状态。这句话需要写进注入的内容里,否则模型会把它当作当前事实。
Claude Code 的做法是给每条记忆附年龄。年龄用相对时间表示("今天""昨天""47 天前"),因为相对时间比时间戳更容易触发核对行为。超过一天的记忆附一句说明:
这条记忆是 47 天前的。记忆是某个时点的观察,不是当前状态——关于代码行为或文件位置的描述可能已经过时。在作为事实陈述前,请核对当前代码。
这段文字同时做了三件事:给出年龄、说明性质、要求核对。三件事里最容易漏的是第二件。只说"这条记忆很旧",模型可能理解为"仍然有效但陈旧";明确说"不是当前状态",模型才会去核对。
Codex 用了另一种表达:它要求模型对有漂移风险的事实做判断——漂移风险高且核对成本低时先核对;漂移风险高但核对成本高时,可以基于记忆回答,但必须说明这是记忆来源、可能过时,并提示可以刷新。这个分层比"一律核对"更实用,因为有些核对本身会打断用户。
6.1 为什么相对时间更有效
这背后有一个具体机制:模型对绝对时间戳的处理依赖日期计算,而对相对时间短语的处理接近模式匹配。
一个 ISO 时间戳 "2027-01-15T10:20:00+08:00" 要被理解为"很久以前",模型需要先取当前时间、做减法、再判断差值是否显著。这三步都有出错空间,而且当前时间往往不在上下文里。
"47 天前"这个短语不需要计算——它直接给出了差值,模型只需判断 47 是否显著。同理,许多实现会在上下文里注入"今天是某年某月某日",目的是给相对时间一个参照点,让模型不必自己算差值。
这个观察有一个推广:任何需要模型做算术判断的信息,最好由程序算好再给。这与状态栏的设计原则一致——把归纳工作从模型侧移到程序侧。
6.2 陈旧提醒的副作用
陈旧提醒不是没有代价的。一条每天都附"请核对"的记忆,会让模型频繁中断去核对,即使内容确实有效。
权衡的依据是核对成本与出错代价之比:
| 情况 | 核对成本 | 出错代价 | 建议 |
|---|---|---|---|
| 涉及具体文件与函数 | 低(读一次文件) | 高(改错文件) | 一律核对 |
| 涉及命令与配置 | 低(读一次配置) | 中 | 核对 |
| 涉及用户偏好 | 无法核对 | 低(用户会纠正) | 不核对,直接使用 |
| 涉及外部系统状态 | 高(可能无法访问) | 中 | 提示可能过时,由用户判断 |
第一行解释了 Claude Code 为什么专门写一条"记忆提到某个函数或开关,那是它写这条记忆时存在的证据"——涉及代码位置的断言是最典型的"低核对成本、高出错代价"。
7. 记忆与指令的区分
注入时的另一个判断是"这算记忆还是算指令"。两者的处理方式不同:
| 维度 | 记忆 | 指令 |
|---|---|---|
| 谁写 | 智能体或后台管线 | 人 |
| 能否自动整理 | 能 | 不能 |
| 版本控制 | 通常不在仓库内 | 随仓库走 |
| 冲突裁决 | 用户或来源核对 | 评审 |
| 生效范围 | 通常单个用户 | 所有贡献者 |
把项目约定写进记忆,会让约定变成某个智能体的个人理解,且随时可能被"整理"掉;把用户偏好写成指令,会让每次改偏好都要动仓库。两种错位都会在几周后变成"这个系统怎么突然不听话了"。
一个具体的判据是:这条内容如果明天被删掉,谁会不高兴?只有当前用户不高兴的,是记忆;整个团队会不高兴的,是指令。
7.1 混合内容的处理
实际内容常常是混合的。一条"这个项目用 pnpm,我习惯用 pnpm 的 workspace 功能"里,"项目用 pnpm"是指令级的事实,"我习惯 workspace"是个人偏好。
处理办法是拆开写入:前者进团队指令(或团队记忆),后者进私人记忆。拆开的判据是"是否对所有贡献者成立"。
不拆的后果是两边都错:写进指令会让一个偏好变成强制约定;写进记忆会让项目事实只对一个人生效,其他人仍然用错包管理器。
8. 取回失败的五种表现
| 表现 | 直接原因 | 该在哪一层修 |
|---|---|---|
| 召回无关内容 | 索引描述模糊,或查询没带任务上下文 | 索引质量与查询构造 |
| 同一条重复出现 | 写入时未做近似去重 | 写入判据 |
| 取回两条互相矛盾的记忆 | 冲突未在存储层标记 | 整理与冲突处理 |
| 读到其他用户的记忆 | 作用域过滤在召回之后 | 取回链路顺序 |
| 引用了已失效的事实 | 缺少有效期或最近验证时间 | 存储字段与检索过滤 |
五种里有四种应该在写入与存储阶段修,只有第一种属于检索阶段。这说明记忆系统的质量问题大多在上游产生,在下游暴露。出现"怎么老是取回错的东西"时,先检查写入的索引描述是否足够区分,比调检索参数更有效。
下面把四种上游问题的具体成因说清,因为它们对应四种不同的修补动作。
同一条重复出现。 成因通常是两次任务都发现了同一事实,而第二次写入时没有检查已有条目。检查方式不能只靠文本完全相同。可靠的办法是按主体加属性做键:主体是项目、属性是包管理器,写入前先按这个键查一遍。
两条记忆互相矛盾。 成因是事实变了而旧条目没有标记。修补动作在存储层:每条记忆带替代字段,新条目声明替代哪些旧条目;整理时按这个字段把旧条目降权,取回时默认只取未被替代的。如果两条都没有声明,取回阶段就只能靠模型判断,而模型判断的结果不稳定。
读到其他用户的记忆。 成因是过滤顺序错了。这个错误特别隐蔽,因为正常的测试数据里只有一份用户,测不出来。修补动作是把它做成结构性约束:取回函数的签名里强制要求用户与项目参数,没有这两个参数就构造不出查询。
引用了已失效的事实。 成因是缺少有效期字段,或有效期没被检索使用。修补动作分两步:写入时给每条带验证时间,整理时更新;检索时把超过阈值且久未验证的条目标记为"需要核对",不直接过滤掉——直接过滤会让模型完全看不到相关线索,标记则保留了线索同时提示了风险。
9. 预算怎么算
注入内容的大小决定它能带多少条。三类记忆的典型体积差别很大:
| 内容 | 典型体积 | 说明 |
|---|---|---|
| 索引一行 | 40–80 字节 | 标题加一句话钩子 |
| 摘要一段 | 300–800 字节 | 用户画像或偏好列表中的一段 |
| 主题文件一份 | 2–8 KB | 一条记忆的完整正文与来源 |
| 原始轨迹一段 | 5–50 KB | 需要核实时才读 |
按这个量级算,一份 25 KB 的索引大约能放 300 到 600 条指针;10 KB 的摘要只能放十几段,所以摘要必须只写最高频的结论。
按需挑选的预算算法不同。它按"选几份、每份多大"分配,不按"总量除以单条"分配。Claude Code 的按需路径限死最多 5 份,同时每份有字符上限,所以最坏情况是 5 乘单份上限。这个设计把不确定性压到了可预测的范围:无论索引膨胀到多大,注入的增量都有上界。
引用快照的预算最麻烦,因为被引用的会话体积不可控。DeepSeek Harness 的做法是先丢较早的非检查点消息,再缩短保留的文本;仍然不够就用外置存储保存全文并给出定位。这个顺序值得注意:先减内容再降精度,最后才动用外部存储,因为外部存储意味着模型要多一次读取。
9.1 预算与命中率的权衡
取回条数 \(k\) 不是越大越好。设单条记忆对当前任务的边际价值随 \(k\) 递减,单条注入成本固定,则存在一个最优点。
一个简化的模型:第 \(i\) 条被取回的条目被实际使用的概率是 \(p_i\),单条消耗 \(c\) 成本,任务失败的总代价是 \(L\)。那么取回 \(k\) 条的净收益是:
这个式子的实用含义是:当 \(L\) 很大(任务失败代价高,例如生产事故排查)时,\(k\) 应该更大;当 \(L\) 很小(一次格式调整)时,\(k\) 应该更小。所以固定的 \(k\) 值在不同任务类型下都不是最优,按任务类型调 \(k\) 才有意义。
实践中这个结论表现为:调试类任务倾向多取几条(宁滥勿缺),格式类任务倾向少取(宁缺勿滥)。
10. 与技能加载的对照
渐进披露不是记忆独有的做法,技能系统用的是同一套结构。把两者放在一起看,能看清哪些是通用原则、哪些是记忆特有的。
| 维度 | 技能加载 | 记忆注入 |
|---|---|---|
| 第一层 | 技能名与一句话说明 | 索引行或摘要 |
| 第二层 | 技能的完整说明文件 | 主题文件 |
| 第三层 | 附带脚本、模板、示例 | 原始轨迹与来源 |
| 谁决定展开 | 模型判断任务是否匹配 | 模型调用或规则筛选 |
| 展开失败的后果 | 用了错误的技能,任务方向偏 | 用错了记忆,结论基于过时事实 |
| 过期机制 | 版本随仓库更新 | 需要显式的时间与验证字段 |
差别在最后一行的两处。技能的过期由仓库更新自然解决——文件改了就是新版;记忆没有这种自然机制,必须显式记录时间并主动核对。这也是为什么记忆必须带年龄提示而技能不需要。
另一个差别是展开的判断依据。技能的匹配靠描述与任务语义的相似度,判断相对可靠;记忆的匹配还要考虑时效与冲突,判断更容易出错。这解释了为什么 Claude Code 的按需选择提示词反复强调"不确定就不要选,可以返回空列表"——在记忆场景里,漏选一条的代价通常小于错选一条。
11. 衡量取回质量
取回环节的指标与写入环节不同:
| 指标 | 含义 |
|---|---|
| 命中率 | 需要记忆的任务中成功取回相关条目的比例 |
| 无效 Token 占比 | 注入内容中未被模型使用的比例 |
| 重复说明次数 | 用户被迫重新陈述同一件事的次数 |
| 注入延迟 | 从开始取回到内容进入上下文的时间 |
| 陈旧引用率 | 取回条目在核对时被证伪的比例 |
重要性排序上,重复说明次数排第一,因为它是用户能直接感知到的。命中率与陈旧引用率是诊断用的中间指标——命中率低要知道是没取回还是取回了没用,陈旧引用率高要回头看写入时的来源与验证时间。
采集这几个指标有一处实操困难:无法直接观测"模型是否用到了某条记忆"。可行的替代是看引用——如果系统要求模型在回答里标注依据的记忆,那么被引用的条目就是被使用的。这需要把引用做成机制,不能靠模型自觉。
Codex 就是这么做的:当一次回答用到某份轨迹摘要,模型要在回复末尾附一个引用块,列出文件路径、行号与一句用途说明。摘要本身不参与引用,因为它是路由层,不承担证据职责。这个设计让"无效占比"变得可测:注入的条数与被引用的条数之比。
有一点需要注意:不要把注入量当作优化目标。多注入一些"可能有用"的内容,短期看不会出错,长期会让模型的注意力被稀释,也会让用户在看到上下文占用时产生疑虑。
用缓存后的成本衡量,这一点更明显。常驻内容按 \(\alpha\) 折扣计价,变化的命中项按全价计价,所以"多带一点"的真实开销取决于它落在 \(f\) 还是 \(v\) 里。稳定地多带 4 KB 索引,实际只多付 0.4 KB;每轮浮动地多带 4 KB 命中项,就是每轮多付 4 KB。