在大屏或电脑上体验更佳——动画和操作区域更宽敞。
输入

上下文与记忆

上下文窗口是模型本次可读取的有限 token 空间,用户消息、模型回复、工具结果等都要共享它。长会话接近上限时,harness 可用摘要替换旧消息;需要跨会话保留的事实,则写入记忆存储,再按规则加载。

可以把窗口看成桌面、记忆文件看成档案柜。桌面放当前材料,压缩把旧材料换成摘要,保留重点但丢掉部分原文。档案柜要显式存入。本课下一会话只恢复记忆文件;真实产品还可能保存完整会话或摘要,不能把这个接口当成通则。

上下文压缩如何工作

本例的大块输入来自工具。read("src/parser.ts") 返回 19,000 token,测试输出再增加 22,100。画面按 token 数绘制块高(小消息有最小高度),旁边显示精确账目。用户文字、模型输出也能占满窗口,只是本课工具结果占主导。

harness 在每次模型调用前检查:tokens(ctx) > 0.92 × LIMIT 则先压缩。把固定头部与最近两条消息之间的旧内容交给摘要器,保留目标、决定、未完成工作,再重建为 [system prompt, memory file, summary, recent tail]。最近消息保留原文,旧内容只剩摘要表示。

阈值留在 92% 是为了预留空间;达到上限的请求不能指望目标模型在被拒后自行整理。真实实现还要计入输出预算,并检查工具大输出或保留尾部是否已超限,必要时先截断或分批处理。

记忆与压缩分开。本例把用户的 Always pnpm, never npm 写入记忆文件,但当前上下文中的记忆块是会话开始时的快照,不会随写入更新。下一会话重新加载才出现新行。摘要仍属于当前会话,本例会话结束时丢弃,只有文件通道跨界。

默认同时启用两者。No compaction 关闭压缩,让同一会话撞到上限;No memory 仍压缩,但不保存跨会话事实。

上下文与记忆逐步演示

本课窗口为 50,000 token,92% 阈值为 46,000。以下计数来自预设轨迹,不是实时分词测量。

  1. 会话 1 启动。 system 3.0k,加注入的 MEMORY.md 快照 1.0k,已用 4.0k。
  2. 收到任务。 “修复失败的解析器测试,始终用 pnpm,不用 npm”占 0.5k;模型表示记下规则并读取解析器,占 0.8k。
  3. 写记忆。 MEMORY.md += "Always pnpm, never npm" 写入独立存储,表计不变。它没有刷新当前注入块;真实记忆工具的请求与结果仍可能占 token,不能泛化为写记忆零成本。
  4. 窗口增长。 读取请求占 0.3k,文件占 19.0k,含第 247 行循环边界错误、MAX_DEPTH 递归保护、Unicode 代理对的 TODO。诊断与修复描述占 0.9k,bash("apply patch && pnpm test") 占 0.3k,测试日志占 22.1k。合计 47.9k/50k。
  5. 触发检查。 47.9k > 46k,下一次模型调用先等待压缩。
  6. 选择片段。 括号圈住固定头部与最近尾部之间的五条消息。system、记忆快照、最后两条消息不压缩。
  7. 生成摘要。 本课使用真实模型 claude-opus-5-5 的录制摘要,保留 src/parser.ts 第 247 行、i <= n 应为 i < n、用户要求用 pnpm,以及下一步打补丁并用 pnpm 跑测试,显示预算 0.8k。原文件中的 MAX_DEPTH 与 Unicode TODO 没有进入这份摘要。
  8. 替换。 五块收成一块,末尾两条原样保留,计数 47.9k → 27.2k。现在是 [system, memory, summary, test command, test log]。
  9. 检查信息损失。 用户问文件中是否有 Unicode TODO,摘要找不到,展示回答表示需要重读文件。该细节刚才可见,现在已不在活动上下文:按设计工作的压缩也可能丢掉没有提炼的内容。
  10. 会话结束。 当前列连同摘要消失,独立记忆记录保留。
  11. 会话 2 启动。 system 加重新读取的 MEMORY.md,记忆已有 pnpm 行,占 1.1k,总计 4.1k,没有前次会话历史。
  12. 检查跨会话保留。 用户要求为新仓库安装 date-fns,扫描在记忆块找到规则,展示命令 pnpm add date-fns。

No compaction 继续增长到 47.9k、48.5k、49.0k;再加入读取操作与 4.2k changelog 后为 53.5k,下次 API 请求因 context_length_exceeded 被拒。不是模型质量逐渐下降,而是本例请求没有进入生成。

No memory 的摘要仍写着偏好 pnpm,所以本会话的安装探测正确;会话结束后,第二会话只有 system,预设回答又用 npm install lodash。这是未把纠正跨会话传入的示例,不是对模型必然行为的预测。

信息能保留多久

本例的原消息在被选中压缩前保留,摘要到会话结束(除非之后的压缩再次摘要它),记忆行到被修改或删除。信息若没有显式升级到更长寿命的存储,可能在默认边界消失。

压缩不一定先丢行号与数值。每张摘要卡录制五次,凡涵盖诊断的摘要都保留 parser.ts 第 247 行、i < n 修复与 pnpm 规则,因为它们是当前任务的结论。同一文件里未被问及的旁支证据则不同:92% 的单次摘要五次中四次丢掉 Unicode TODO,50% 的摘要再摘要五次中只丢两次。同一模型、同一消息,结果不同。摘要在结论之外保留什么,无论哪个方向都不能依赖。

压缩后仍需原样使用的资料,应保留可重新读取的来源,或在合适的记录中保存。尤其不要把“曾经看见”当作“摘要一定记住”。

阈值也有取舍。92% 在本任务压缩一次,之前离上限只剩几千 token;50% 在载入 MEMORY.md 时会压缩两次,第二次把第一次摘要也纳入,有再次遗漏或歪曲的机会。早压缩增加摘要调用、提早移除原文;晚压缩可能被单次大工具输出顶过上限。关掉压缩,本例在 50k 边界报错。摘要再摘要不保证每次都更差,但会引入新的压缩风险。

更大窗口能容纳更多内容,不能消除资料管理需求。上下文增大会占空间,并可能增加处理成本与延迟;前缀缓存和计费方式会改变实际关系。应区分当前工作材料与需要长期保留的事实。

边界情况

  • 检查在模型调用前。 本例的压缩运行都能落在上限内,但生产实现必须在压缩后复查,并预留输出。大尾部仍可能使摘要后的请求超限。
  • 尾部可能最重。 最后两条里有 22.1k 测试日志,所以压缩后仍为 27.2k,而不是 4k。若需更多空间,要调整工具结果保留策略。
  • 摘要继承模型错误。 若把决定写错,后续请求会继续接收该错误;摘要存在不代表已核实。
  • 记忆会过期。 团队换工具后,旧 pnpm 规则可能不适用。跨会话保留也需要更新和删除。
  • 二次压缩涉及旧摘要。 50% 阈值(载入 MEMORY.md)先在诊断后、再在测试日志后触发,第二个片段包含第一份摘要。本课展示的录制运行中,这次摘要保留了 Unicode TODO,所以 50% 的探测能找到,92% 的找不到。

常见错误

  • 假定模型自行记住过去会话。 本课每次调用靠显式输入,会话 2 只恢复记忆文件。其他产品可恢复历史,但仍需系统把它提供给模型。
  • 期待所有原证据保留。 修复结论会保留;无关 TODO 是否保留取决于这次运行,录制的五次摘要中四次丢掉。后续需要的原文要记录来源或重新读取。
  • 把记忆当全量日志。 下一会话注入仍占窗口,把所有材料写入只会在另一层重建拥挤问题。记忆应经过筛选。
  • 混淆文件与注入快照。 本例 remember() 改文件,不改当前块;新行在下一会话注入时进入。
  • 只靠本会话摘要保留偏好。 No memory 的摘要虽有规则,仍随该会话结束而消失。
  • 只提高窗口上限。 容量增加不替你选择资料寿命,大文件输出仍会继续占用空间。

模型的简化

50k 是教学窗口,不代表任何实际型号。所谓记忆文件由独立内存状态模拟,本课不写你的 MEMORY.md。token 大小是预设账目;真实 harness 应用分词器估计,并按提供者限制保留空间。

压缩摘要来自 claude-opus-5-5 对本例消息的逐字录制,既非手写,也不是播放时实时生成。录制显示 bug 位置每次都保留,Unicode TODO 只是有时保留。其他展示行为与计数服务于教学,不能作为模型表现基准。

真实系统常先截断旧工具输出,再做摘要;缓存固定前缀,支持手动压缩(如 Claude Code 的 /compact),并使用不同阈值。会话与摘要也可能持久保存。本课展示的是有损工作上下文、阈值摘要、跨会话重新注入记忆三项机制。