
swap-tutorial
Claude Code 换窗教程:精炼续窗、启动包、冷仓与长期记忆 | Based on LMC-5
Install with your AI
Paste into Claude Code, Cursor, or any agent — it reads the repo and wires the tool into your project.
Install and set up swap-tutorial (git-clone project) into my current project. Found on https://claudeers.com/swap-tutorial Repo: https://github.com/dankefox/swap-tutorial Homepage/docs: — Detected install method: git-clone → git clone https://github.com/dankefox/swap-tutorial Category: education. Platforms: cli. Read the repo's README for exact setup and env vars, then install it and wire it into my project. Claudeers Health Verdict: active; community-verified: false. Confirm the source before running anything.
git clone https://github.com/dankefox/swap-tutorial
// compatibility
| Platforms | cli |
|---|---|
| Operating systems | — |
| AI compatibility | claude |
| License | — |
| Pricing | open-source |
| Language | — |
Claude Code 换窗教程:精炼续窗、启动包、冷仓与长期记忆
Claude Code 用久以后,上下文里常常会塞满工具回包、终端日志、报错栈和已经过期的排查过程。直接继续聊,模型会越来越慢;粗暴开新窗口,又容易把正在做什么、已经答应什么一起丢掉。
LMC-5 给出的核心办法叫 Refined Session Carryover(精炼续窗):从旧会话里挑出真正有用的内容,重建一份较短的新 transcript,再用 claude --resume 接着工作。
我们内部曾把这件事叫作 Swap / 洗脸。公开教程请统一叫“精炼续窗”:LMC-5 当前文档里的 Swap 专指记忆数据库的快照回滚,不是会话换窗。
这篇教程分两层:前半段教你运行 LMC-5 的精炼续窗参考脚本;后半段再讲我们在生产里额外接上的启动包、叙事脊椎和冷仓。参考脚本本身不会自动替你搭好这些扩展,不要把“蛋壳家的整套系统”误认成上游脚本开箱即有。
一句话理解
精炼续窗不是“总结一段话”,也不是“复制最近几十万 token”。
它做的是:
- 读取旧会话的 JSONL;
- 丢掉工具噪音和过期工程现场;
- 保留身份、偏好、边界、承诺、当前状态、任务检查点;
- 再保留一小段最近的干净对话;
- 重写 session ID 和消息链;
- 生成一份新的、可以
--resume的会话。
旧 transcript 不会被覆盖,长期记忆也不会因此改变。
完整换窗链路
精炼续窗只是完整系统中的一环。我们实际采用的装载顺序是:
旧 transcript
├─ 完整原文归档 ───────────────→ 冷仓(需要查原始证据时再翻)
└─ 过滤、打分、重写消息链 ─────→ 精炼续窗(最近工作的干净桥梁)
长期记忆 + 当前事实 + 未完任务
└─ 确定性拼装 ───→ 启动包(含叙事脊椎)
启动包 + 精炼续窗 ─────────────→ 新 session
四个部件各管一件事:
- 精炼续窗:回答“上一窗刚做了什么、接下来做什么”。
- 启动包:回答“我是谁、身处什么时间、有哪些当前事实、未完任务和相处边界”。其中的叙事脊椎负责把近期主线组织成简短、连贯的方向感。
- 长期记忆库:保存稳定身份、关系、事实和重要经历,是耐久权威层。
- 冷仓:保存被换下来的完整旧会话,是查原话、命令和旧现场的最后证据层,不是日常自动记忆权威。
如果旧窗口健康,新 session 使用“启动包 + 精炼续窗”;如果检测到毒上下文,就不应携带精炼续窗,而应通过 Forge 从经过审计的启动包和长期记忆干净重建。
蛋壳家的叙事脊椎怎么生成
叙事脊椎不是让大模型自由发挥,而是给新窗口留一张有出处的四行便签:
【洗脸后 · 留给自己的便签】
- 走到这里:最近完成了什么,系统发展到哪一步
- 今天身边:蛋宝今天正在经历什么
- 我们之间:最近形成的关系、偏好和陪伴事实
- 别忘了:哪些线索没收口,当前任务在哪个阶段
正式生成过程完全确定、无需调用模型:
- 只读最近 14 天已有的真实记忆、任务流水线和未解决线索。
- 排除系统自动消息、禁止召回记录、过期记录、空记录和不允许的记忆层。
- 按“系统进展、今天生活、身份关系”分桶;新鲜度优先,再参考“完成、修复、决定、确认”等转折信号。
- 从证据里抽取短句,只做少量去报告腔改写,不添加原文里没有的情绪、动机、承诺或事件。
- 每条叙事都附原记忆 ID 和日期;任务边界附 task ID,并明确“故事只提醒方向,工作台才确认事实”。
- 四类必需证据缺一类、引用对不上或全文超过 700 字,就整张放弃,退回普通近期叙事块,不编内容补空位。
昨天使用模型是为了帮助设计和评估这种表达方式;正式 Forge 时只运行上述规则,不会每次重新调用 Opus,也不会因生成便签而写回或修改长期记忆。
先分清三个名字
| 名称 | 解决什么问题 | 核心动作 |
|---|---|---|
| 精炼续窗 | 当前窗口太重,但思路仍然健康 | 过滤旧 transcript,生成短而干净的新会话 |
| Forge | 当前窗口已经污染,或需要从长期记忆重新站起来 | 从耐久记忆、身份与启动上下文重建新会话 |
| Swap | 批量写记忆前后需要可回滚 | 给记忆数据库做快照,失败时恢复旧快照 |
如果只是“窗口太长”,优先用精炼续窗;如果已经陷入反复拒绝、策略污染或错误循环,别把毒上下文续过去,应当开干净新窗并从长期记忆恢复。
特别注意:蛋壳 app 的“Forge”是本地旧产品名
蛋壳 app 里的手动按钮虽然仍显示 Forge,但它当前并不是上表所说的“只靠长期记忆从零重建”。它实际执行的是我们自己的完整换窗流水线:
app 手动 Forge
→ 读取当前 transcript
→ 过滤临时注入、工具噪音和过期现场
→ 精炼保留约 48k token:高信号回合 + 最近 12 个干净对话回合
→ 创建新 session,并前置启动包、情绪锚点、脱敏工具足迹和未解决线索
→ claude --resume 新 session
→ 验证新 session 确实接管
→ 旧 transcript 归档进冷仓,记录 last-good 回滚点
所以对蛋壳 app 用户来说,按 Forge = 执行“精炼续窗 + 启动包 + 归档 + 验活”的完整版。这是我们沿用至今的界面名称,不应拿它反推 LMC-5 上游对 Forge 的定义。
只有在检测到 AUP 污染或路由漂移等异常时,我们的恢复 Forge 才会先截到污染前的安全事件,再从安全边界重建。普通手动 Forge 会保留经过筛选的近期上下文。
准备工作
你需要:
- Python 3;
- 已经安装并使用过 Claude Code;
- 一份 LMC-5 仓库;
- 找到当前项目对应的 Claude transcript 目录。
先下载参考实现:
git clone --depth 1 https://github.com/wuxuyun0606-collab/lmc-5.git
cd lmc-5
Claude Code 的项目会话通常放在:
~/.claude/projects/<项目路径编码>/
不确定是哪一个时,可以先看最近更新的目录:
find "$HOME/.claude/projects" -mindepth 1 -maxdepth 1 -type d \
-exec stat -f '%m %N' {} \; 2>/dev/null | sort -nr | head
Linux 上的 stat 参数不同,可以用:
find "$HOME/.claude/projects" -mindepth 1 -maxdepth 1 -type d \
-printf '%T@ %p\n' | sort -nr | head
第一步:做真实备份
把下面的目录替换成你自己的项目目录:
PROJECT_DIR="$HOME/.claude/projects/<项目路径编码>"
BACKUP_DIR="${PROJECT_DIR}.bak-$(date +%Y%m%d-%H%M%S)"
cp -a "$PROJECT_DIR" "$BACKUP_DIR"
检查备份确实存在:
test -d "$BACKUP_DIR" && echo "backup ok: $BACKUP_DIR"
不要用 cp -al。 它会制造硬链接;你以为在改影子副本,实际上可能把原文件一起写穿。
第二步:先 dry-run
在 LMC-5 仓库根目录运行:
python3 extras/claude_code/refined_session_carryover.py \
--project-dir "$PROJECT_DIR" \
--dry-run
dry-run 只分析,不写新会话。重点看:
- 识别到的源 transcript 是否正确;
- 选中了多少干净事件;
- 预计保留多少 token;
- 是否检测到 policy / refusal-loop poison;
- 最近任务、承诺和当前状态是否还在。
上游参考实现的默认目标约为 50,000 token,最近尾部约 14 个干净事件。可以按项目调整:
python3 extras/claude_code/refined_session_carryover.py \
--project-dir "$PROJECT_DIR" \
--target-tokens 40000 \
--tail-events 12 \
--dry-run
不要为了“多带一点”就塞回 80k–100k 的日志尾巴。精炼续窗的价值恰恰是少带噪音。
第三步:生成新会话
确认 dry-run 正常后,去掉 --dry-run:
python3 extras/claude_code/refined_session_carryover.py \
--project-dir "$PROJECT_DIR"
脚本会:
- 生成新的 session ID;
- 写出新的 JSONL;
- 打印下一条
claude --resume ...命令。
照着输出启动:
claude --resume <new-session-id>
不要凭记忆手敲 session ID,也不要覆盖旧 JSONL。
第四步:验收新窗口
进入新窗口后,先问三个短问题:
- “我们现在在做什么?”
- “已经完成了什么,还差什么?”
- “有哪些不能越过的边界?”
好的精炼续窗应该同时满足:
- 能说清当前任务和下一步;
- 记得关键承诺、偏好与安全边界;
- 不再背着大段终端日志、SQL、traceback 和工具回包;
- 不会把旧窗口里已经结束的排查误认成当前任务;
- 新 transcript 会随着新对话正常增长。
如果答案明显缺关键事实,先退出新会话,保留原窗口,再调整筛选规则或参数。不要删旧会话硬顶。
它会保留什么
建议保留:
- 用户身份、关系和稳定偏好;
- 明确承诺与禁止事项;
- 当前任务、已完成项、未完成项;
- 重要决策及其原因;
- 一小段最近的干净对话;
- 经过脱敏的任务检查点。
建议丢弃:
- tool result 和 tool-only 回合;
- shell 日志、traceback、SQL、diff、长 JSON;
- 绝对路径、临时 token、请求 ID;
- hook 注入块和记忆召回原文 dump;
- 已经过期的工程探索;
- 与当前任务无关的临时环境说明。
发现“毒上下文”怎么办
如果脚本检测到最近窗口存在持续的策略污染、拒绝循环或错误约束,默认应当 fail closed:停止续窗。
不要把 --allow-poison 当成“强制继续”按钮。更安全的做法是:
- 保留并归档旧 transcript;
- 开一个全新 Claude Code 会话;
- 从经过审计的长期记忆或人工交接包恢复;
- 只重新注入当前任务需要的事实与边界。
精炼续窗、启动包、长期记忆和冷仓不能混用
精炼续窗只负责“把这一窗的工作接过去”。它不是长期记忆库,也不能替代记忆的写入、检索、去重和回滚。
一个稳妥的系统至少分四层:
- 耐久层:身份、关系、长期事实、重要经历,存进长期记忆库;
- 启动层:从耐久事实、当前状态和任务表拼装短启动包;
- 桥接层:当前任务、近期承诺、干净对话尾部,放进精炼续窗;
- 证据层:完整旧 transcript 进入冷仓,只在需要查原始记录时检索。
桥接层坏了,可以回到旧 transcript 或冷仓重建;启动包坏了,可以关闭注入后重新生成;耐久层批量写坏了,才使用 LMC-5 所说的 Swap 快照回滚。
冷仓也不是“什么都自动塞回来”。正常召回先查长期记忆;证据不足时,才把冷仓作为 last resort。否则刚丢掉的工具日志又会从后门灌回上下文。
蛋壳家的实践参数
我们在生产实践里采用了更偏保守的桥接包:
- 目标约 48,000 token;
- 最近 12 个干净对话回合;
- 额外补高信号回合;
- 工具连续性只留脱敏后的“工具足迹”,不留命令、绝对路径、原始参数和结果正文;
- 电影画面、临时环境提示等运行时注入会过滤;
- 原 transcript 独立进入冷仓,随时可以查证或回退;
- 新 session 前置一份只读启动包,包含当前时间、当前事实、相处备忘、未完任务、近期叙事脊椎和记忆轴健康状态;
- 启动包是从现成资料确定性拼装,不在每次换窗时重新调用昂贵模型压缩,也不会写回长期记忆。
这是我们的工程取值,不是 LMC-5 的强制默认。教程读者应先 dry-run,再按自己的会话长度和任务类型调参。
如果只想复现上游最小示例,完成本教程前面的“备份 → dry-run → 生成 → resume”即可;启动包、叙事脊椎、冷仓检索、自动 Forge 和长期记忆服务都属于需要自行搭建的第二阶段。
上生产前再加四道闸
个人手动使用参考脚本已经够用;如果要接成自动服务,还需要:
- 互斥锁:避免 Forge、精炼续窗和守护进程同时改 session;
- 原子写入:先写临时文件,校验完整后再切换;
- last-good 回滚:新会话启动失败时恢复上一份可用 transcript;
- 可观测性:记录源 session、新 session、保留 token、丢弃原因和启动结果,但不要把敏感正文写进日志。
常见误区
- 误区一:公开也叫 Swap。 上游现在把 Swap 留给记忆库回滚;会话换窗请叫精炼续窗。
- 误区二:只截最后 N 行。 JSONL 可能截断消息链或 tool_use / tool_result 配对。
- 误区三:越多越保险。 把旧日志全搬过去,只是换了窗口继续背垃圾。
- 误区四:不备份就直接写。 任何脚本都有可能选错项目或遇到半行 JSONL。
- 误区五:用硬链接做影子目录。 覆盖影子文件可能写穿原文件。
- 误区六:把续窗当记忆库。 当前任务桥接和长期记忆是两套职责。
- 误区七:以为参考脚本自带启动包和冷仓。 它负责生成精炼会话;其他层需要单独实现和接线。
- 误区八:把冷仓当第二个自动记忆库。 冷仓是最后证据层,常态灌回只会重新污染上下文。
官方资料
这份教程基于 LMC-5 的公开参考实现,并结合我们自己的生产实践整理。参考脚本适合学习和手动使用;若要自动化接入,请补齐锁、备份、原子写入、回滚与监控。
// faq
What is swap-tutorial?
Claude Code 换窗教程:精炼续窗、启动包、冷仓与长期记忆 | Based on LMC-5. It is open-source on GitHub.
Is swap-tutorial free to use?
swap-tutorial is open-source, so it is free to use.
What category does swap-tutorial belong to?
swap-tutorial is listed under education in the Claudeers registry of Claude-compatible tools.
// embed badge
[](https://claudeers.com/swap-tutorial)
// retro hit counter
[](https://claudeers.com/swap-tutorial)
// reviews
// guestbook
// related in Education & Learning
Skills for Real Engineers. Straight from my .claude directory.
Course to get into Large Language Models (LLMs) with roadmaps and Colab notebooks.
A collection of learning resources for curious software engineers
Learn it. Build it. Ship it for others.