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

如何在不丢失上下文的情况下从 Codex 迁移到 OpenHands (2026)

这次迁移看起来只需要十分钟。Codex 读取 AGENTS.md。OpenHands 读取 AGENTS.md。复制仓库,将新智能体指向它,搞定。

然后,智能体开始忽略以前有效的指导,或者更糟糕的是,在只有三分之一内容适用的情况下,一次性执行所有指导。两边的文件名完全相同,但背后的加载策略却截然不同,而这正是整个迁移的核心所在。

在开始之前,先明确一个界限:本文讨论的是将指令层从 Codex 迁移到另一个智能体运行时。如果您是要将 Codex 迁移到终端原生智能体,从 Codex 迁移到 Warp 介绍了不同的目的地。如果您当前的问题是 Codex 没有采用您已经编写的规则,那么 为什么 Codex 会跳过您的 AGENTS.md 规则 是正确的起点,而不是进行迁移——如果丢失发生在会话中期而不是加载时,为什么 Codex 会忘记项目上下文 也是如此。

实际迁移了什么

这两款工具都精确地记录了它们的发现机制,并排阅读时很容易看出差异。

Codex 在开始工作前会将所有内容组装成一个单一的有序链:

"Codex 在启动时构建指令链(每次运行一次;在 TUI 中,这通常意味着每个启动的会话一次)。"

发现过程从全局开始,在 Codex 主目录中,它“如果存在则读取 AGENTS.override.md。否则,Codex 读取 AGENTS.md”并“仅使用该层级的第一个非空文件”。然后它遍历项目:

"从项目根目录(通常是 Git 根目录)开始,Codex 向下遍历到您当前的工作目录。"

在沿途的每个目录中,它会检查 AGENTS.override.md,然后是 AGENTS.md,接着是 project_doc_fallback_filenames 中配置的任何备用名称,并且“每个目录最多包含一个文件”。合并是拼接式的:“Codex 从根目录向下拼接文件,用空行连接它们。靠近您当前目录的文件会覆盖先前的指导,因为它们出现在组合提示词的较后位置。”

并且有一个硬性上限:一旦组合大小达到 project_doc_max_bytes 定义的限制(默认 32 KiB),Codex “就会停止添加文件”。

OpenHands 的出发点则完全相反。它的根目录 AGENTS.md 是常驻(always-on)的,但其他所有内容都会刻意保留,直到相关时才加载。官方文档在一个表格中列出了这些机制:仓库根目录下的 AGENTS.md 意味着“完整内容包含在初始系统提示词中”,而 .agents/skills/<skill-name>/SKILL.md 处的智能体技能(Agent Skill)意味着“首先宣传名称和描述;智能体在相关时调用完整技能”。

接下来的指导对于任何从 Codex 迁移过来的人来说都是最重要的一句话:

"使用 AGENTS.md 记录简短的、仓库范围的约定。使用 SKILL.md 记录仅在某些任务中需要的专注知识。"

以及随之而来的警告:

"常驻内容从一开始就占用对话上下文。保持 AGENTS.md 简洁,并将冗长或专业的指令移至按需加载的技能和参考中。"

所以:您的规则内容可以原样迁移。但您的规则结构不行。在 Codex 中,嵌套目录就是条件机制——您将文件放置在靠近专业工作的地方,它就会落在拼接提示词的较后位置。而在 OpenHands 中,嵌套根本不是这种机制;其机制是技能的描述、声明的触发器或声明的路径模式。

将 Codex 链扁平化为一个 OpenHands AGENTS.md 并不是捷径。这恰恰是目标工具文档明确告诉您不要做的事情。

手动迁移

步骤 1:按每个部分的实际适用频率拆分链

从根目录向下梳理您的 Codex 指令链,并将每个块分类到以下三个堆之一。

处处适用,始终正确。 测试命令、包管理器、“切勿编辑生成的文件”规则、贯穿整个仓库的命名规范。这就是您新的根目录 AGENTS.md,它应该很短。如果您当前的根目录 AGENTS.md 很长,是因为它朝着 32 KiB 的上限增长,那么现在正是找出其中有多少内容实际上是通用的时候。

仅在某一区域适用。 所有因为适用于支付服务、前端或迁移文件夹而存在于嵌套 AGENTS.md 中的内容。这些将变成带有 paths 声明的技能。OpenHands 将其记录为确定性规则而非建议:paths “将文件转换为路径触发的规则。该规则不会向模型宣传,并在读取、编辑或创建匹配文件时在每次对话中注入一次。”

这一堆是迁移带来收益的地方。在 Codex 中,嵌套文件之所以适用,是因为您在该目录或其子目录下启动了会话——作用域是您所处位置的副产品。而 paths 模式在智能体实际接触匹配文件时就会应用,无论会话从哪里开始。这比您之前试图表达的方式更精确。

仅适用于某些任务。 发布清单、事件运行手册、关于数据管道如何连接的冗长解释。这些将变成具有名称和描述的普通技能。在被调用之前,它们几乎不消耗任何成本,这就是为什么它们可以根据需要尽可能长——这与您在拼接链和字节上限约束下工作的情况正好相反。在将内容移入技能时,值得记住一个注意事项:智能体技能不是记忆。技能是智能体可以调用的程序,而不是团队决策的记录。

还有第四堆值得提及:由短语而非文件触发的指导。OpenHands 也支持这一点——triggers “当用户消息中出现关键字或命令时注入技能”,并且该技能同样可供模型调用。如果一个文件同时声明了两者,文档明确指出“paths 具有优先权”。

步骤 2:修复方向相反的文件名假设

有两个细节会给您带来麻烦,而且它们指向相反的方向。

Codex 要求您注册任何非标准的指令文件名。其文档指出,不在 project_doc_fallback_filenames 列表中的文件名“在指令发现中会被忽略”。如果您的仓库最终包含一个 Codex 读取的 CLAUDE.md,那是因为有人把它放到了该列表中。

OpenHands 默认情况下正好相反:“OpenHands 还将 CLAUDE.mdGEMINI.md 识别为特定于模型的仓库上下文。”无需注册。这意味着您一直忽略的——或者故意排除在 Codex 备用列表之外的——CLAUDE.md 在导入时就会生效。在第一次运行前检查一下是否存在此类文件。

另一个细节是 AGENTS.override.md。Codex 在两个地方使用它:全局(完全胜过 AGENTS.md)和每个目录(首先检查)。它是临时本地行为的有用逃生通道。OpenHands 的技能文档没有描述此类覆盖文件名,因此您目录树中的任何 AGENTS.override.md 在另一端都是一个没有记录的读取器的文件。针对每个文件决定其内容是属于根目录 AGENTS.md、属于限定范围的技能,还是哪里都不属于。

关于遗留文件的另一点说明:OpenHands 文档指出“没有触发器的遗留 .md 技能总是会被完整加载”,并建议在这种情况下优先选择 AGENTS.md,以便意图清晰。如果您正在移植一堆松散的 Markdown,这就是需要围绕其进行规划的句子——一个裸 .md 技能的行为将类似于常驻内容,这会让您重新回到要迁出的境地。如果您的指令文件最初是 CLAUDE.md将 CLAUDE.md 转换为 AGENTS.md 更详细地介绍了命名和内容差异。

更好的方法:不属于任何运行时的决策层

上面的一切都是重构工作,每当底层的加载模型发生变化时,您都会进行某种版本的重构。Codex 使用受字节限制的拼接。OpenHands 使用渐进式披露。下一个工具将使用其他方式。

在这一切中幸存下来的是推理:为什么存在该约定、您拒绝了什么,以及最初是什么事件将该规则放在那里的。这在指令文件中永远无法舒适地容纳,因为指令文件是命令列表,在两个平台上都应该保持简短。

MemoryLake 将该层保留在两个运行时之外,并通过 MCP 或 API 将其提供给任何发出请求的智能体。Codex 保留其自己的本地记忆,OpenHands 保持其技能目录原样不变。

步骤 1:创建 API 密钥

在开始拆分文件之前,生成一个密钥并在大约三十秒内发出您的第一次请求。

创建 MemoryLake API 密钥,使项目事实存在于 Codex 指令链和 OpenHands 技能集之外
创建 MemoryLake API 密钥,使项目事实存在于 Codex 指令链和 OpenHands 技能集之外

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

在步骤 1 中对每个块进行分类时,您会不断询问“为什么这会在这里”。边做边写下答案——决策、您拒绝的替代方案、背后的约束。文档和其他文件也放在同一个地方。

将原本会被挤压在 Codex 32 KiB 指令链限制下的项目决策上传到 MemoryLake
将原本会被挤压在 Codex 32 KiB 指令链限制下的项目决策上传到 MemoryLake

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

通过 MCP 或 API 授予 Claude、Codex、OpenClaw 和 OpenHands 访问权限。能够查询决策层的智能体不再需要将基本原理内联到常驻文件中,这使得根目录 AGENTS.md 能够保持两家厂商推荐的简短程度。

通过 MCP 和 API 将 OpenHands、Codex 和其他智能体连接到 MemoryLake
通过 MCP 和 API 将 OpenHands、Codex 和其他智能体连接到 MemoryLake

这在实践中改变了什么

第一个变化是 32 KiB 的对话结束了。达到 Codex 上限的团队有两个记录在案的选择——提高限制或跨嵌套目录拆分——这两者都是管理预算的方法。在 OpenHands 方面,预算问题发生了转移:根文件应该很短,不是因为字节上限,而是因为常驻内容从第一条消息开始就竞争上下文。按需查询的决策层是让简短文件保持简短而不丢失推理的方法。

第二个变化是作用域变得更清晰。paths 模式是比“此文件位于 payments 目录中”更强有力的声明,它在智能体实际接触的文件上触发,而不是在会话开始的地方触发。

第三个变化出现在重叠期。大多数团队会同时运行两者几周。具有两个加载模型的两个指令树会以无人注意的方式发生分歧,直到一个智能体做出了另一个智能体不会做的事情。一个共享的决策层意味着即使文件布局不同,原因也保持一致。

从 Codex 迁移到 OpenHands 的最佳实践

在复制根文件之前对其进行评估。 如果您的 Codex 链逼近字节上限,坦率的问题是其中有多少内容曾经是通用的。大部分答案是“比你想象的要少”。

将目录嵌套转换为声明的模式。 不要试图在 OpenHands 中重现您的 Codex 目录布局并期望获得相同的行为。嵌套是一侧的作用域机制;而 paths 声明是另一侧的作用域机制。

在第一次运行前审计 CLAUDE.mdGEMINI.md 它们从需要注册变成了自动识别。这通常是受欢迎的,但偶尔也会带来意外。

为每个技能提供一个说明其适用时机的描述。 发现机制仅宣传名称和描述。如果描述只说明了技能的作用而没有说明何时使用,它就不会在正确的时间被调用。

不要将推理放在常驻文件中。 两家厂商都告诉您要保持简洁。基本原理属于智能体查询的存储库,而不是加载到每条消息中的块。

对长会话中的摘要做好准备。 OpenHands 记录了一个上下文冷凝器(context condenser),它在历史记录超过配置的大小时,保持最近的消息完整并总结较旧的内容。这是管理长对话的明智方式,也是不将对话视为任何内容记录的充分理由。

结论

Codex 和 OpenHands 读取同名文件,但处理方式几乎完全相反。Codex 从项目根目录向下到您的工作目录拼接一个有序链,每个目录一个文件,直到达到字节上限。OpenHands 完整加载根文件,并将其他所有内容保留在描述、关键字触发器或路径模式之后。

这种差异就是迁移的本质。内容可以原样移植;但结构必须围绕一个加载模型进行重建,该模型鼓励简短的常驻文件和无限的按需细节。在此过程中,您会遇到两个指向相反方向的文件名意外,以及一个没有记录在案的等效项的逃生通道——AGENTS.override.md

按每个部分的适用频率拆分链,将嵌套转换为声明的模式,并将推理保存在不属于任何运行时的某个地方。这样,下一个加载模型就只是一项重构工作,而不是一项考古工程。

常见问题

我可以把整个 AGENTS.md 链直接复制到一个 OpenHands AGENTS.md 中吗?

您可以这样做,它也会起作用,但这正是目标文档警告的情况:常驻内容从一开始就占用对话上下文,OpenHands 明确建议保持 AGENTS.md 简洁,并将冗长或专业的指令移至按需加载的技能中。扁平化的链还会丢失 Codex 中目录放置所提供的所有作用域划分。

OpenHands 对 AGENTS.md 有像 Codex 的 32 KiB 那样的限制吗?

其技能文档没有指定 AGENTS.md 的字节限制。它指定的是成本模型——常驻内容从第一条消息开始就存在于上下文中——以及保持文件简洁的建议。因此,约束是真实存在的,但表现为关于上下文占用的指导,而不是可配置的字节上限。

我嵌套的 AGENTS.md 文件会怎么样?

它们的内容会迁移,但它们的作用域机制不会。在 Codex 中,嵌套文件之所以适用,是因为您的工作目录位于该子树内。在 OpenHands 中,将每个文件转换为带有 paths 声明的技能,以便在智能体接触匹配文件时注入。文档指出,该规则不会向模型宣传,并在首次匹配时在每次对话中注入一次。

在迁移之前,我应该关闭 Codex 的本地记忆吗?

没有必要关闭,而且它们值得去理解而不是丢弃——开启 Codex 的本地记忆 介绍了该界面包含的内容以及如何控制它。OpenAI 自己的指导是,将所需的团队指导保留在 AGENTS.md 或签入的文档中,而不是依靠记忆来获取必须始终适用的规则。这一建议在迁移后保持不变。

如何处理只有在我说某个特定词时才触发的规则?

这就是 triggers 的作用——用户消息中的关键字或命令会注入技能,并且该技能同样可供模型调用。如果您在同一个文件上同时声明了 triggerspaths,文档指出 paths 具有优先权。

上下文冷凝器会在会话中期丢弃我的项目规则吗?

冷凝器作用于对话历史记录——它在历史记录超过配置的大小时,保持最近的消息完整,保留关键信息,并总结较旧的内容,同时保留最早的事件。您的常驻 AGENTS.md 内容和您的技能是指令源,而不是对话轮次。实际的教训与适用于任何地方的教训相同:长对话不是持久的记录,因此请将您需要保留的内容保存在文件和可查询的存储库中。