1. 换工具这件事真正让人头疼的不是配置把主力编码助手从 Claude Code 切到 Codex很多人第一反应是去翻配置文件、改环境变量、重新装依赖。这些确实要做但真正让人抓狂的场景往往发生在切换之后的第二天你打开新工具面对一个做到一半的项目脑子里清楚还有三件事没做完可新工具完全不知道你昨天干到哪、为什么那么干、下一步该动哪个文件。我见过太多人在这时候选择凭记忆硬接结果就是重复劳动、改错分支、把已经验证过的方案又推翻重来。更糟的是有些决策是当时权衡了半小时才定下来的比如为什么这个模块不用现成的库而手写过一夜你自己都忘了理由新工具更不可能猜出来。所以这篇要聊的核心不是怎么装 Codex而是怎么用一份 Backlog.md 把项目进度、决策上下文、待办优先级完整交接过去。这套方法我自己在多个项目里反复用过从个人小工具到多人协作的中型系统都验证过适合任何需要在不同编码助手之间迁移工作流的开发者。哪怕你只是临时换工具试两天这份交接文档也能帮你省下大量重新对齐的时间。先说结论交接的本质是把隐性上下文变成显性文本。Claude Code 和 Codex 都是读代码、改代码的工具它们缺的从来不是能力而是你脑子里那些没写进代码的信息。Backlog.md 就是把这些信息落地的载体。2. 为什么是 Backlog.md而不是聊天记录或注释2.1 聊天记录为什么靠不住很多人第一反应是我把之前的对话记录导出来给新工具看不就行了。理论上可行实操上问题一堆。聊天记录是线性且冗余的。你和上一个工具来回几十轮里面夹杂着大量试错、废弃方案、重复确认。新工具读进去很难分辨哪句是最终决策、哪句是中途被否掉的想法。我实测过把一段两千行的对话丢给新工具它确实读了但抓重点的准确率明显下降经常把已经废弃的方案又提出来。而且聊天记录的格式各家不统一导出后结构混乱工具解析起来效率低。相比之下一份结构化的 Markdown 文档信息密度高、层级清晰工具能快速定位到当前状态待办事项关键决策这几个核心区块。2.2 代码注释解决不了进度问题那有人会说我把进度写进代码注释里不就行了。这也不对。代码注释适合解释这段代码在干什么不适合承载项目整体走到哪了。注释是局部的、贴着具体文件的而进度是全局的、跨文件的。你不可能在某个文件的注释里写清楚整个项目还剩三个模块没做其中模块 B 依赖模块 A 的接口先冻结这种全局信息。更重要的是注释会随着代码重构被删掉或错位而 Backlog.md 作为独立文档生命周期和代码解耦不会因为某次重构就丢失上下文。2.3 Backlog.md 的定位项目的外置大脑我给 Backlog.md 的定位是项目的外置大脑。它不追求记录所有细节而是记录那些不看就会走弯路的关键信息。具体来说它要回答四个问题这个项目现在处于什么状态已经做了哪些关键决策为什么这么决策接下来要做的事优先级怎么排有哪些坑已经踩过别再踩第二次这四个问题答清楚了任何编码助手接手都能快速进入状态。下面这张表是我总结的 Backlog.md 核心区块和它们各自解决的问题区块回答的问题缺失后的后果项目概览这是什么、目标是什么工具理解偏差改错方向当前状态做到哪了、什么能跑重复劳动或破坏已完成部分关键决策为什么这么设计推翻已验证方案返工待办清单下一步做什么、优先级抓不住重点做次要的事已知坑哪些路走不通重蹈覆辙浪费时间3. 一份能直接抄的 Backlog.md 结构拆解3.1 项目概览区块三句话讲清楚项目概览不需要长篇大论三句话足够这是什么、给谁用、当前阶段目标。我通常这么写## 项目概览 - 项目名某数据处理工具内部代号 - 一句话描述把多来源的日志数据清洗后汇总成统一报表 - 当前阶段目标完成数据清洗模块跑通端到端流程 - 技术栈Python 3.11 Pandas 本地 SQLite这里的关键是技术栈要写清楚版本。我踩过一次坑交接时只写了用 Python新工具默认按最新语法写结果项目环境是 3.9好几个新特性用不了又得回头改。版本号这种细节写一行省半小时。3.2 当前状态区块用能跑/不能跑说话状态描述最忌讳模糊。别说基本完成要说哪个文件能跑、哪个函数还没实现。我的写法是分三档## 当前状态 ### 已完成且验证通过 - data_loader.py能从 CSV 和 JSON 读取数据已用样本数据测试 - cleaner.py 的 dedupe 函数去重逻辑已验证边界情况覆盖 ### 已完成但未验证 - cleaner.py 的 normalize 函数写完了但没跑过真实数据 ### 未开始 - report.py报表生成完全没动 - 端到端集成测试这种分档的好处是新工具一眼就知道哪些代码可以放心依赖、哪些需要先验证再用。特别是已完成但未验证这一档很多人会漏掉结果新工具直接拿未验证的代码当基础往上搭最后发现底层有问题全盘返工。3.3 关键决策区块记录为什么不只是是什么这是整个 Backlog.md 里最有价值、也最容易被忽略的部分。代码能告诉你用了什么方案但告诉不了你为什么不用另一个方案。而后者恰恰是新工具最容易踩雷的地方。我举个例子。之前有个项目我选择手写一个简单的解析器而没用现成的库。如果只交接代码新工具很可能觉得这写得不够优雅换个库吧然后引入新依赖、改一堆代码最后发现那个库处理不了我们的特殊格式。但如果我在 Backlog.md 里写了决策理由它就不会动这块## 关键决策 ### 决策1手写解析器而非用现成库 - 背景数据格式有非标准的分隔符主流库都不支持 - 尝试过的方案试了两个流行库都在特殊分隔符上失败 - 最终选择手写约 80 行的解析器 - 影响解析逻辑集中在 parser.py改动需谨慎每条决策我都建议按背景-尝试-选择-影响四段写。这样新工具不仅知道结论还知道边界在哪不会轻易去动已经验证过的部分。3.4 待办清单区块优先级比清单本身重要待办清单不是把所有没做的事列出来就完事关键是排优先级和标依赖。我习惯用 P0/P1/P2 三档并且明确标出依赖关系## 待办清单 ### P0必须做阻塞后续 - [ ] 完成 normalize 函数的真实数据验证 - [ ] 冻结 data_loader 的输出接口report 模块依赖它 ### P1重要但不阻塞 - [ ] 实现 report.py 的基础报表 - [ ] 补充单元测试 ### P2有空再做 - [ ] 性能优化 - [ ] 日志美化依赖关系一定要写。我遇到过新工具同时开工两个有依赖关系的任务结果接口对不上白干半天。明确写X 依赖 Y工具就会先做 Y 再做 X。3.5 已知坑区块把踩过的雷标出来这个区块是纯经验输出但价值极高。每个项目都有那么几个看起来能走、实际走不通的路写下来能帮新工具省下大量试错时间## 已知坑 - 不要用 pandas 的默认 read_csv 读我们的数据分隔符会错乱必须指定 sep - SQLite 并发写入会锁单线程处理即可别想着多线程加速 - 时间字段有时区问题统一转 UTC 再处理这些坑往往来自实际调试文档里查不到只有踩过的人知道。交接时写下来等于把经验直接传递过去。4. 从 Claude Code 迁移到 Codex 的实操步骤4.1 迁移前的准备先冻结当前状态在切换工具之前第一件事是冻结当前状态。什么意思就是确保你交接的那一刻项目处于一个明确、可复现的状态。具体操作先把当前所有改动提交或暂存跑一遍现有测试确认基线是绿的然后记录下当前分支和 commit 号。这一步的目的是给交接一个明确的锚点万一新工具接手后出了问题你能快速回退到这个点。我踩过的坑是有次没冻结状态就直接交接结果 Claude Code 那边还有未保存的改动Codex 接手后基于旧代码工作两边对不上排查了半天才发现是状态没同步。4.2 生成 Backlog.md 的实操流程生成这份文档不需要什么工具手写就行但有几个提效技巧。第一从最近的对话记录里提取决策。翻一遍你和上一个工具的对话把那些最终确定用 X 方案的节点挑出来每条整理成决策区块。这个过程本身也是对自己思路的梳理。第二用代码结构反推待办。打开项目目录看哪些文件是空的、哪些函数是 TODO这些就是待办清单的素材。比凭记忆列要全得多。第三把调试时的临时笔记整理进已知坑。很多人调试时会随手记点东西比如这里不能用 X这些零散笔记整理一下就是高质量的坑位记录。整个流程熟练后大概 15 到 20 分钟比起接手后重新对齐动辄一两个小时的浪费非常划算。4.3 在 Codex 中加载 Backlog.md 的正确姿势文档写好了怎么让 Codex 用起来也有讲究。我的做法是在第一次交互时就把 Backlog.md 作为上下文传入并且明确告诉它这是项目交接文档。不要指望工具自动去读项目根目录的某个文件主动传入更可靠。传入后我通常会加一句引导这是项目交接文档请先通读然后告诉我你理解的当前状态和下一步该做什么。这一步很关键。让工具复述一遍它理解的状态你能立刻发现它有没有读偏。如果它复述的和你写的不一致说明文档某处表述有歧义当场修正比后面做错了再改成本低得多。4.4 迁移后的第一次验证小步快跑新工具接手后别急着让它做大任务。先给它一个 P0 里的小任务比如验证 normalize 函数看它的处理方式是否符合你的预期。我一般会观察三点它有没有先读相关代码再动手、它有没有遵守已知坑里的约束、它完成后有没有更新状态。这三点都对了说明交接成功可以放心让它做更大的任务。如果哪点不对回到 Backlog.md 补充说明再试一次。这个小步验证的环节很多人会跳过直接让新工具干大活结果方向偏了才发现返工成本高。花十分钟验证省几小时返工这笔账很好算。5. 让交接文档真正被用起来的几个细节5.1 文档要短到能被读完Backlog.md 最大的敌人是写太长没人读。工具虽然有耐心读完但信息太多反而稀释了重点。我的经验是控制在 200 行以内超过就说明你在记录细节而不是上下文细节应该留在代码里。判断标准很简单如果某条信息删掉后新工具会走弯路那就留着如果删掉也不影响它做对事那就是冗余删掉。用这个标准筛一遍文档自然就精简了。5.2 状态要实时更新别攒着Backlog.md 不是写完就扔的一次性文档。项目推进过程中状态会变、待办会增减、新坑会出现。我习惯每完成一个 P0 任务就更新一次保持文档和实际状态同步。这样做的额外好处是下次再换工具你手上已经有一份最新的交接文档不用临时抱佛脚。相当于把交接成本平摊到了日常而不是集中在切换那一刻。5.3 决策区块要写反面不只写正面大多数人写决策只写我选了什么但真正有价值的是我为什么不选另一个。因为新工具最容易犯的错就是重新提出那个你早就否掉的方案。所以每条决策我都强制自己写一句尝试过但放弃的方案。哪怕只是试过 X太慢放弃这么简单也能有效阻止工具走回头路。这个习惯我坚持了挺久实测能减少不少无效讨论。5.4 用统一的标记符号方便工具解析虽然是给人看的文档但既然要给工具读用一些统一的标记能提升解析效率。我常用的几个[ ]和[x]标记待办完成状态P0/P1/P2标记优先级依赖前缀标记依赖关系坑前缀标记已知问题这些符号不复杂但能让工具快速抓取结构化信息。比起纯自然语言描述解析准确率高不少。6. 几个我踩过的真实坑和应对6.1 坑一交接文档写成了代码说明书刚开始用这套方法时我把 Backlog.md 写成了代码说明书逐文件解释每个函数干什么。结果工具读完还是不知道项目整体走到哪因为说明书里全是局部信息没有全局视角。后来我调整了思路代码能说清楚的文档里不写代码说不清楚的文档里重点写。函数干什么工具读代码就知道但为什么这个函数要这么设计它和另一个模块的依赖关系代码里看不出来这才是文档该承载的。6.2 坑二待办清单没有优先级工具乱做有次我列了十几条待办但没排优先级结果新工具从第一条开始做而第一条恰好是个 P2 的优化项做完对项目推进毫无帮助。P0 的关键任务反而被晾在一边。从那以后我强制自己排优先级而且P0 最多三条。超过三条说明你没想清楚什么最重要得再砍。优先级的意义就是逼你做取舍列一堆 P0 等于没排。6.3 坑三已知坑写得太笼统工具照样踩注意数据格式问题这种坑位记录等于没写工具看了也不知道具体注意什么。有效的坑位记录必须具体到可操作哪个函数、什么输入、会出什么错、怎么规避。比如注意数据格式应该写成read_csv 必须指定 sep|否则默认逗号分隔会错乱。后者工具一看就知道怎么做前者看了还是懵。6.4 坑四忘了同步环境信息这个坑比较隐蔽。有次交接时项目依赖了几个特定版本的库但我没写进文档新工具按最新版本写代码跑起来各种不兼容。后来我在项目概览里固定加一行环境依赖把关键库的版本列清楚这类问题就再没出现过。环境信息包括语言版本、关键依赖版本、有没有特殊的环境变量、数据库类型和版本。这些看似琐碎但任何一个不对都可能导致代码跑不起来。7. 把这套方法固化成习惯用了几次之后我发现这套方法的价值远不止换工具这一个场景。它其实是一种项目上下文管理的通用做法。比如团队里来了新成员一份 Backlog.md 能让他快速上手比如你自己隔了一周回来继续做文档能帮你快速回忆比如项目要暂停一段时间再重启文档就是最好的记忆载体。所以我现在养成了一个习惯任何超过一天工作量的项目开工时就建一个 Backlog.md边做边更新。这样无论什么时候需要交接文档都是现成的不用临时整理。具体到日常维护我的节奏是这样的每天收工前花两分钟更新状态和待办每做一个关键决策就补一条决策记录每踩一个坑就加一条坑位。这些动作加起来每天不超过五分钟但积累下来的上下文价值极高。回到最初的问题从 Claude Code 换到 Codex进度怎么接答案不是某个神奇的工具或命令而是一份写清楚状态、决策、待办和坑位的 Backlog.md。它把散落在你脑子里的隐性信息变成显性文本让任何工具都能快速接手。我个人的体会是交接做得好不好直接决定了换工具这件事是提效还是添乱。花二十分钟写文档换来的是新工具第一天就能干对活而不是花半天重新对齐。这笔投入产出比在编码这件事上算是相当高的了。最后分享一个小技巧如果你不确定 Backlog.md 写得够不够清楚可以拿给一个不熟悉项目的同事看让他复述一遍项目状态。如果他能说个八九不离十说明文档合格如果他说得含糊那就是文档还有歧义回去补。这个人肉验证比任何工具测试都直接。