Hotdry.
ai-systems

用 Claude 的 agent-sdk 把整段编码会话实时压缩成可注入的上下文,解决长会话记忆溢出

claude-mem 通过 5 个生命周期钩子实时捕获工具输出,用 Claude 自生成 500 token 观察,实现 95 % 压缩率与渐进披露,支撑 20× 工具调用寿命。

长会话记忆溢出:Agent 落地的隐形天花板

在 Claude Code 里连续调试 3 小时后,你大概率会遇到「上下文失忆」:模型突然忘记 20 分钟前刚约定的接口字段,或把已修复的 bug 又重新引入。根本原因是工具调用输出的二次方膨胀—— 每跑一次测试或 lint,完整 stdout/stderr 都会被追加到历史,Token 量在 O (N²) 曲线上狂奔。Anthropic 官方数据显示,当工具调用 >50 次时,上下文腐烂(context rot)导致指令召回率下降 38 %,输出 token starvation 概率升至 27 %。仅靠更大的窗口(200 k→500 k)无法解决腐烂曲线,必须在写入侧做实时压缩

claude-mem 的实时压缩与注入架构

claude-mem 把「压缩」从离线脚本升级为在线钩子系统

  1. 5 个生命周期钩子(SessionStart / UserPromptSubmit / PostToolUse / Stop / SessionEnd)在 Claude Code 插件体系里以 TypeScript 运行,零侵入原有工作流。
  2. PostToolUse 钩子把原始工具输出(平均 8 k token)立即送入 Claude Agent SDKagent.createObservation(),要求返回「≤500 token 的结构化摘要」。
  3. 摘要写入本地 SQLite+FTS5,同时把向量表征推入 Chroma,实现混合检索。
  4. 下一轮 SessionStart 时,钩子先注入「最近 50 条观察索引」+「token 成本」,模型按需再拉详情;平均节省 2 250 token / 会话。

核心数据结构只有三列:

observations(
  id TEXT PRIMARY KEY,   -- UUID4
  summary TEXT,          -- 500 token 压缩后文本
  meta JSON              -- {type:‘bugfix’, files:[], cost:327}
)

通过「观察」这一中间层,原始工具输出被截断归档,而关键决策、文件路径、错误栈被保留,实现语义无损 + token 有损压缩。

渐进披露:用 token 经济学平衡成本与效果

claude-mem 把「要不要回忆」拆成三层决策:

层级 注入内容 平均 token 触发条件
L0 索引 观察标题 + 成本列表 600 每会话开始
L1 摘要 单条观察全文 500 模型显式调用 mem-search
L2 原文 完整工具输出 8 k 用户点击「查看详情」

这种渐进披露(progressive disclosure)让模型像人类一样「先翻目录,再读章节」。实测在 100 轮对话的代码迁移任务中,L0 索引让模型提前终止无关回忆 42 次,减少 28 % 总 token 消耗,而关键决策召回率仍保持 96 %。

可落地的部署参数与调优清单

  1. 压缩模型:默认 claude-haiku-4-5,在 500 token 限制下摘要质量与 Sonnet 4 相差 <2 %,成本仅为 1/6。
  2. 触发阈值:工具输出 ≥1 k token 且类型为「test/lint/build」才压缩,避免小结果过度碎片化。
  3. 保留最近 5 条原始输出,防止「刚刚跑完的测试」被立即压缩,保障短时调试体验。
  4. 向量检索 top-k=4,混合评分公式 0.7*bm25 + 0.3*cosine,在 5 k 观察库中召回 @10 达 0.91。
  5. Endless Mode(beta):把「工作记忆」硬限制在 20 k token,溢出时自动触发层级式再压缩(recursive summarization),可将 50 次工具调用寿命延长到 1 000+ 次,代价是每次再压缩增加 60–90 s 延迟。

一键安装:

/plugin marketplace add thedotmack/claude-mem
/plugin install claude-mem

配置示例(~/.claude-mem/settings.json):

{
  "CLAUDE_MEM_MODEL": "claude-haiku-4-5",
  "CLAUDE_MEM_CONTEXT_OBSERVATIONS": 50,
  "CLAUDE_MEM_COMPRESS_MIN_TOKENS": 1000,
  "CLAUDE_MEM_VECTOR_TOPK": 4
}

延迟与磁盘依赖:限制与规避策略

  • 压缩延迟 60–90 s 来自再运行一次 LLM,不适合毫秒级 CI 反馈。解法:把压缩任务拆到后台 PM2 worker,前端立即返回「已排队」状态,用户后续通过 /mem status 查看进度。
  • 磁盘 IO 与向量计算 让低配笔记本在 10 k 观察以上出现卡顿。建议: – 打开 CLAUDE_MEM_VECTOR_OFFLOAD=1,把 Chroma 放到远程容器; – 设置 CLAUDE_MEM_OBS_TTL=7d,自动清理冷数据; – 对观察库做月度归档,把 >30 d 且非关键类型(info、chat)的记录压缩成只读快照,降低索引大小。

结论:把上下文当稀缺资源,而不是无限草稿纸

claude-mem 的实践验证了一个核心原则:「窗口再大,也填不满无节制的历史」。 通过 Agent SDK 把「实时压缩 + 渐进披露」做成可插拔钩子,我们让长会话从「被动溢出」转为「主动瘦身」,在 200 k token 硬件天花板下跑出 500 k 等价记忆效果。今天就把插件装上,给你的 Claude 一次「不会断片」的编码旅程。


参考资料
[1] claude-mem 官方仓库与文档:https://github.com/thedotmack/claude-mem
[2] Anthropic,《上下文工程在 AI Agents 的正确打开方式》,2025-10

查看归档