MemoryLake
返回全部文章
Tutorial2026 年 9 月 21 日·11 分钟阅读

如何导出 Claude Code 会话以便在另一台机器上继续(2026 指南)

你在工作笔记本电脑上的 Claude Code 中花了三个小时进行迁移。明天你将在另一台机器上工作。显而易见的做法是找到会话文件,将其复制过去,然后恢复。

但这一步会失败,而且是以最令人沮丧的方式失败:Claude Code 会报告没有与该 ID 匹配的对话。没有警告,没有部分加载 —— 直接提示未找到。文档解释了原因,而且这个设计是刻意为之的。

本指南将介绍 /export 实际生成的内容、转录文件的用途和非用途、为什么手动复制的转录文件会被故意拒绝,以及应该携带什么来代替它,以便下一台机器可以从你中断的地方继续。

为什么复制会话文件不起作用

Claude Code 会话是与项目目录绑定的已保存对话。默认情况下,转录内容以 JSONL 格式保存在 ~/.claude/projects/<project>/<session-id>.jsonl,其中项目段是你的工作目录路径,非字母数字字符已被替换为连字符。

所以文件就在那里,复制它看起来就是答案。以下是当你这样做时,文档中记录的行为:

"跨项目搜索仅在恰好有另一个项目持有包含该 ID 消息的转录时才会解析该 ID,因此手动复制的副本会导致 Claude Code 报告未找到,而不是恢复任意一个副本。"

仔细读两遍。查找并不是找不到你的副本。而是它找到了两个候选对象,并拒绝进行猜测。复制文件这一行为恰恰破坏了恢复过程,而且你越是小心翼翼 —— 复制而不是移动,妥善保存原件 —— 你就越必然会遇到这种失败。

不应该基于该文件进行开发的第二个原因也同样显而易见:

"条目格式是 Claude Code 内部格式,且在不同版本之间会发生变化,因此直接解析这些文件的脚本可能会在任何版本发布时损坏。要基于会话数据进行开发,请使用 /export 或脚本接口。"

在围绕该文件制定计划之前,还有第三件值得了解的事情:转录文件会过期。保留清理默认运行周期为 30 天,可通过设置键进行调整。转录文件是一个工作产物,而不是存档。

这与将会话倒回到更早的时间点是不同的问题(那是在单台机器和单个会话内进行的),也与从 Claude 应用分叉远程会话不同(那是通过工具创建副本并正确注册的)。这里的问题是,如何让对话的实质内容到达一台从未拥有过它的机器。

人们尝试的其他方法

复制 JSONL 并通过 ID 恢复。 如上所述。副本正是导致未找到的原因。

复制 ~/.claude/projects 下的整个项目目录。 同样的机制,影响范围更大。你现在有两个目录持有包含相同 ID 消息的转录。

编写脚本将 JSONL 解析为摘要。 这在下一个版本发布前有效。该格式明确是内部格式,且文档中已说明它在版本之间会发生变化。

恢复并希望启动配置也随之恢复。 它不会,需要再次传递的内容列表非常具体:"如果会话依赖于 --mcp-config--settings--plugin-dir--fallback-model 或使用 --add-dir 添加的目录,请在恢复时再次传递它们。" 在会话中期使用 add-directory 命令添加的目录也不会恢复。设置文件在启动时会重新读取,因此其中存在的内容确实会恢复。

假设对话中的所有内容都能保留。 大部分内容确实可以。恢复的会话会恢复完整的历史记录,包括工具调用和结果。但是,在前一个进程结束时仍在运行的工具"在恢复时不会完成或再次运行;Claude 会在没有其输出的情况下继续。" 如果你的最后一个操作是一个耗时很长的构建,其结果将不会出现在恢复的对话中。

依赖你未请求的摘要。 在 Pro 或 Max 计划中,恢复一个已闲置超过约一小时且超过 100,000 个 token 的会话时,会首先打开一个对话框。其中一个选项会立即运行压缩,并"用摘要、你最近的交流以及最多五个最近读取的文件替换历史记录。" 这是一个合理的默认设置,但却是一个糟糕的存档,原因与选择在压缩中保留什么是一项刻意行为相同。

解决方案:导出可读记录,然后单独携带决策

两个产物承担两个不同的工作。导出为你提供作为文档的对话。而其中的决策需要作为事实来传递,而不是作为转录。

步骤 1:在会话仍处于打开状态时导出对话

在会话中运行导出命令。它会打开一个菜单,允许你将对话复制到剪贴板或将其保存为纯文本文件,其中消息和工具输出将呈现为可读文本。传递文件名即可跳过菜单并直接写入该文件。

你得到的内容被精确地描述为:"/export 生成供人阅读的渲染转录。" 这正是正确的预期。它是一个你或同事可以在任何机器、任何编辑器中阅读的文档,不依赖于任何 Claude Code 版本。

在结束一天的工作之前执行此操作,而不是在之后。导出是针对实时对话运行的,一旦保留清理或压缩对话框发挥作用,这一步就会变得更加困难。

步骤 2:将决策从导出内容中提取为独立的事实

打开导出的文件,阅读它以获取结论,而不是叙述。你正在寻找少数几行会改变某人明天工作方式的内容。

有三种内容值得提取。经过争论并解决的决策 —— 迁移在回填之前运行,以及原因。历经艰难才发现的约束 —— 在任务运行时无法修改此表。下一个会话否则会搞错的词汇 —— 你的团队所说的“租户”是指什么。

将每条内容写成一个独立的句子,不引用对话。"我们决定先运行迁移" 是不可移植的。"迁移必须在回填之前运行,因为回填会读取新列" 则是可移植的。测试标准是,对于从未看过该会话的人来说,这句话是否仍然有意义,这与区分已发生事件的索引日志与可用记忆的测试标准相同。

步骤 3:在原机器上通过 ID 恢复,在新机器上重新开始

在运行该会话的机器上,从任何目录通过 ID 恢复。查找会首先搜索当前项目及其工作树,然后是机器上的每个其他项目,因此在其他地方启动或移动的会话仍然可以解析 —— 前提是恰好有一个转录持有它的消息。传递会话所依赖的启动标志。

在新机器上,不要尝试恢复。启动一个会话并向其提供步骤 2 中的事实。这就是整个交接过程,它比听起来要快,因为这些事实在构建上就很简短。

如果你希望导出文件本身在两台机器上都可用,请将其保存在你保存工作文档的任何地方。只需将其保持在 ~/.claude/projects 之外,因为在第二个项目目录中复制转录文件正是导致未找到的重复项。

在 MemoryLake 中进行设置

步骤 2 生成了一组单句事实,这些事实需要能够从你接下来使用的任何机器上读取。MemoryLake 是一个存放它们的地方,这样交接就不再依赖于你是否记得同步文件。

You write the entries yourself, in your own words. Nothing is read out of, written to, or deleted from Claude Code's transcript files, ~/.claude, or any vendor's store.

步骤 1:创建 API 密钥

登录并从控制面板生成一个密钥。该密钥允许任何机器上的智能体读取这些条目,这是复制文件无法提供给你的部分。

MemoryLake 控制台显示 API 密钥屏幕,在此处创建并复制新密钥以供智能体使用
MemoryLake 控制台显示 API 密钥屏幕,在此处创建并复制新密钥以供智能体使用

步骤 2:上传你的第一批记忆

添加上面步骤 2 中的决策、约束和词汇,每个条目包含一个事实。将导出的转录内容保留为长格式记录;这些条目是需要在下一个会话开始时读取的部分。

已上传首批文档的 MemoryLake 工作区,列出了每个文件,因为它们已成为可搜索的记忆
已上传首批文档的 MemoryLake 工作区,列出了每个文件,因为它们已成为可搜索的记忆

步骤 3:连接你的 AI 和智能体

将两台机器上的智能体指向同一个工作区。这样,新会话在启动时就已经可以使用已确定的决策,而不是从一个无法打开的对话开始。

MemoryLake 集成屏幕,列出了可以连接到记忆层的 AI 客户端和智能体框架
MemoryLake 集成屏幕,列出了可以连接到记忆层的 AI 客户端和智能体框架

这在实践中改变了什么

第一个变化是交接不再是文件操作。你不再试图让一台机器的本地状态出现在另一台机器上,而这正是该工具刻意拒绝为你解决的问题。

第二个变化是这两个产物不再相互竞争。导出是关于你如何到达某个阶段的可读记录 —— 在拉取请求(PR)描述、交接说明或事件报告中非常有用。而事实则是下一个会话需要加载的内容。试图让一个产物承担这两个工作,正是导致产生没人阅读的庞大转录以及一无所知的新会话的原因。

第三个变化是版本更迭不再重要。渲染后的导出内容永远是纯文本。而 JSONL 转录是一种内部格式,文档中已说明它在版本之间会发生变化,因此你基于它构建的任何内容都是你无意中承担的维护承诺。

还有一个值得提及的隐私维度,因为它改变了你根本应该导出什么。转录写入可以通过环境变量完全抑制,并且可以告诉单个非交互式运行不要持久化其会话。如果你在对话不应留在磁盘上的环境中工作,这些开关是存在的 —— 这意味着导出步骤成为唯一的记录,因此请刻意执行此操作。这与你向 Claude 请求的账户级数据导出是不同的产物,后者涵盖的是消费者应用,而不是 CLI 的本地转录。

在笔记本电脑和台式机之间交替工作的团队往往最快遇到这个问题,而解决方法与防止更换机器时上下文丢失的方法相同:持久的部分必须存在于两台机器都不拥有的地方。

在机器之间迁移工作的最佳实践

在工作会话结束时导出,而不是在下一个会话开始时。 导出是针对当前对话的实时操作。保留清理、压缩对话框以及简单的遗忘都会阻碍你获取昨天的会话。

切勿将转录副本放在第二个项目目录中。 这是最有可能导致恢复失败的单一操作。请将导出内容与你的文档放在一起。

在导出内容旁写下启动标志。 恢复的会话不会恢复其启动时使用的配置标志。写下一行说明会话需要哪些标志的笔记,可以省去你花 20 分钟去弄清楚为什么工具丢失的麻烦。

将 30 天的保留期视为真正的截止日期。 默认的清理周期是 30 天,这是一个设置键,而不是一个承诺。任何你希望在六个月后还能保留的内容都需要是导出内容或事实,而不是转录。

为你的会话命名。 命名会话可以在整个仓库及其工作树中通过名称进行解析,这使得在原机器上恢复变得非常简单,并使你的笔记清晰易读。未命名的会话是一个你无法识别的 ID。

区分“我们决定了什么”和“我们讨论了什么”。 前者很短,属于交接内容。后者很长,属于导出内容。失去线索的会话通常是因为项目的决策从未在对话之外的任何地方记录下来

使用摘要请求而不是解析器。 如果你希望从旧会话中获取结构化输出,请通过 ID 向其发送后续提示并捕获结构化响应。这是一个受支持的接口。而解析 JSONL 则不受支持。

结论

Claude Code 将你的对话存储在一个你可以看到的文件中,这使得复制它看起来是迁移工作的显而易见的方法。然而,这正是该工具专门设计来拒绝的方法,它通过报告未找到来拒绝,而不是恢复一个它无法验证的副本。

受支持的路径更轻量、更持久。在会话打开时将对话导出为可读文档。从中提取少数决策、约束和术语作为独立的句子。在拥有转录文件的机器上通过 ID 恢复,并在没有转录文件的机器上重新开始,同时已加载这些事实。

这种拆分也恰好是让多个人能够接手工作的原因,这也是为什么在会话之间共享上下文首先是一个写作问题,然后才是一个工具问题的相同原因。

常见问题

我可以将 Claude Code 会话文件复制到另一台电脑并恢复它吗?

无法可靠地做到,而且这种失败是设计使然。文档指出,跨项目搜索仅在"恰好有另一个项目持有包含该 ID 消息的转录时"才会解析会话 ID,"因此手动复制的副本会导致 Claude Code 报告未找到,而不是恢复任意一个副本。"

/export 实际生成什么?

供人阅读的渲染转录。它会打开一个菜单,将对话复制到剪贴板或将其保存为纯文本文件,其中消息和工具输出显示为可读文本,传递文件名则会直接写入该文件。

Claude Code 转录文件存储在哪里?

默认情况下,以 JSONL 格式保存在 ~/.claude/projects/<project>/<session-id>.jsonl,其中项目段是工作目录路径,非字母数字字符已被替换为连字符。超过 200 个字符的转换后名称会被截断,并赋予完整路径的哈希值。

我可以自己解析 JSONL 转录文件吗?

可以,但文档建议不要基于它进行开发:条目格式"是 Claude Code 内部格式,且在不同版本之间会发生变化,因此直接解析这些文件的脚本可能会在任何版本发布时损坏。"

恢复会话会恢复所有内容吗?

对话历史记录会完整恢复,包括工具调用和结果,以及会话的智能体、大多数情况下的权限模式和活动目标。启动标志(如 MCP 配置、设置、插件目录、备用模型和添加的目录)必须再次传递。

转录文件在磁盘上保留多长时间?

保留清理默认使用 30 天,可通过设置键进行调整。使用 remove 命令删除后台会话会将其转录保留在磁盘上,并且仍然可以通过 ID 恢复。