
1. 任务开始前的那五分钟决定了你后面两小时的效率用 Codex 这类 AI 编程助手的人大概都经历过两种截然不同的状态。一种是丢进去一个需求它噼里啪啦改三四个文件跑通测试你 review 一下合并全程顺畅。另一种是同样丢进去一个需求它开始反复读文件、反复猜你的意图、改了一版又推翻重来上下文越滚越大额度肉眼可见地往下掉最后你等得心烦它做得也稀碎。大多数人遇到第二种情况第一反应是模型不行或者今天状态不好。但我用下来最深的体会是问题往往不在任务执行阶段而在任务开始之前。你给它的起点信息质量直接决定了它后面要走多少弯路。这就像你让一个刚入职的同事去改一个 bug如果你只说登录有问题你修一下他大概率要花半天时间到处翻代码但如果你说登录接口在 token 过期后没有正确返回 401导致前端一直重试相关代码在 auth 模块的 middleware 里他可能二十分钟就搞定了。Codex 也是一样的道理。它不会读心术它只能基于你给的上下文去推理。你给的信息越模糊它需要猜的空间就越大而每一次猜测都意味着额外的文件读取、额外的推理轮次、额外的 token 消耗。额度越用越快本质上是你把大量的 token 花在了帮它建立上下文上而不是花在真正的任务执行上。这篇内容我想聊的就是这件事为什么有些人用 Codex 越用越慢、额度越用越快以及怎么在任务开始之前就把这个问题解决掉。核心思路围绕Context Engineering上下文工程展开会涉及 Markdown 组织、Git 工作流配合、以及一些我踩过坑之后总结出来的实操习惯。不管你是刚装好 Codex 的新手还是已经用了一段时间但总觉得不太顺手的老用户应该都能从里面找到能直接用的东西。2. 为什么任务开始之前才是真正的分水岭2.1 Codex 的工作方式决定了它对起点信息极度敏感要理解为什么起点这么重要得先搞清楚 Codex 这类工具到底是怎么工作的。它不是一个你说话它执行的简单映射而是一个基于上下文做推理和决策的 agent。你给它一个任务它内部会经历这样的过程理解你的意图、定位相关文件、阅读代码、制定修改方案、执行修改、验证结果。这里面每一步都需要消耗 token而每一步的质量都依赖于前一步的输入。关键点在于它定位相关文件的方式是靠语义搜索和推理不是靠你脑子里的那张代码地图。你心里清楚这个功能在 user service 里但它不知道。它只能根据你给的描述去猜猜对了就快猜错了就要多读好几个不相关的文件然后从里面排除掉错误的再重新找。这个过程在上下文里会留下大量的探索痕迹这些痕迹会一直占着 context window让后续的推理越来越慢、越来越贵。我做过一个粗略的对比。同一个需求给订单列表接口加上分页参数校验如果我只说订单列表接口加个分页校验Codex 平均要读 8 到 12 个文件才能定位到正确的位置中间还会问我两三次澄清问题。但如果我一开始就说清楚订单列表接口在 order 模块的 controller 层分页参数目前没有校验需要加 page 和 pageSize 的范围检查参考 user 模块里已有的校验写法它基本两三个文件就能搞定中间几乎不需要来回确认。这个差距在单次任务里可能只是几分钟和几十个 token 的区别但如果你一天要跑十几个任务一周下来就是巨大的效率差异和额度消耗差异。2.2 上下文膨胀的雪球效应更麻烦的是上下文膨胀是有雪球效应的。第一次猜错方向它读了一堆无关文件这些内容进入 context 之后会干扰后续的判断。它可能会把无关文件里的某些模式误认为是相关的从而做出错误的修改建议。然后你发现不对让它改回来这一来一回又增加了新的上下文。等到任务结束的时候context 里已经堆满了各种试错痕迹下一次任务如果还在同一个会话里继续这些垃圾信息会继续拖累它。这就是为什么很多人觉得越用越慢——不是模型变慢了是你的会话上下文被污染了。每一次模糊的任务描述都在往 context 里倒垃圾。倒得多了它自然就跑不动了。2.3 额度消耗的真实去向很多人以为额度是花在生成代码上的其实不是。生成代码那部分消耗相对固定真正的大头是上下文读取和推理。你给的任务越模糊它需要读取的文件越多、推理的轮次越多、澄清的来回越多这些全都是 token。换句话说你省下的那点描述任务的时间最后都变成了它帮你猜意图的时间而且这个转换比例极其不划算——你花三十秒说清楚的事它可能要花三分钟和几千个 token 去猜。所以额度越用越快这个现象本质上是一个投入产出比的问题。你在任务开始前投入的注意力越少任务执行阶段的消耗就越大。这是一个非常典型的磨刀不误砍柴工场景。3. 把任务说清楚一份能直接抄的上下文模板3.1 为什么大多数人说不清楚不是大家不想说清楚而是默认对方知道自己知道的东西。你脑子里有一张完整的代码地图你知道模块怎么分、接口怎么调、历史包袱在哪里所以你觉得订单列表加个校验这句话已经足够清楚了。但 Codex 没有这张地图它看到的只是一句抽象的描述。这其实是沟通里的经典问题知识的诅咒。你知道得越多越难想象不知道的人需要什么信息。解决的办法不是努力说得更清楚而是用一个固定的模板来强制自己补全关键信息。模板的好处是它把该说什么这件事从依赖灵感变成了依赖流程你只要照着填就行。3.2 我常用的五段式任务描述模板下面这个模板是我用了大半年之后固定下来的基本上覆盖了 Codex 定位任务所需的所有关键信息。你可以直接拿去用也可以根据自己的项目特点调整。## 任务目标 一句话说清楚要做什么不要超过两行。 ## 涉及范围 - 模块/目录明确告诉它去哪个目录找 - 关键文件如果你知道具体文件直接列出来 - 相关接口/函数如果有明确的入口写出来 ## 现状与期望 - 现状现在是什么行为 - 期望改完之后应该是什么行为 - 边界条件哪些情况需要特殊处理 ## 参考实现 如果项目里有类似的写法指给它看让它照着抄。 ## 验证方式 怎么确认改对了跑哪个测试、看哪个接口、检查什么输出。这个模板看起来有点啰嗦但实际填起来很快熟练之后一两分钟就能写完。关键是它把 Codex 最需要的几类信息都覆盖了去哪找、改什么、改成什么样、怎么验证。有了这四样它基本不需要猜。3.3 一个真实的对比案例我拿一个实际任务来演示一下差别。需求是用户修改密码后需要让所有已登录的 session 失效。模糊版本用户改密码之后把其他地方的登录都踢掉。Codex 拿到这句话之后会开始搜索密码登录session相关的代码可能找到 auth 模块、user 模块、session 管理模块然后逐个阅读试图理解你们的 session 机制是怎么实现的。这个过程可能要读十几个文件中间还可能问你你们的 session 是存在 Redis 还是数据库之类的问题。清晰版本## 任务目标 用户修改密码成功后使其所有已登录 session 失效。 ## 涉及范围 - 模块auth 模块 - 关键文件auth/service/password.go改密码逻辑、auth/service/session.gosession 管理 - 入口函数ChangePassword ## 现状与期望 - 现状改密码只更新了密码字段旧 session 仍然有效 - 期望改密码成功后调用 session 清理逻辑删除该用户所有 session - 边界条件当前正在操作的 session 是否保留需要确认产品逻辑 ## 参考实现 auth/service/logout.go 里有 ClearUserSessions 函数可以直接复用。 ## 验证方式 改密码后用旧 token 调任意需要登录的接口应该返回 401。第二个版本Codex 基本可以直接动手不需要额外探索。两个版本的 token 消耗差距实测下来大概在三到五倍。任务越复杂这个差距越大。3.4 模板不是死的按任务类型调整这个五段式模板不是每个任务都要完整填。简单的任务可能只需要目标 涉及范围 验证方式三段复杂的重构任务才需要全部填满。核心原则是你填的每一段都是为了减少它的一次猜测。如果某个信息它自己能很容易找到你就不用写如果某个信息它很难找到或者容易找错你就一定要写。比如涉及范围这一段如果你不确定具体在哪个文件可以只写模块名让它自己去模块里找。但如果你知道具体文件写出来能省它很多时间。这是一个投入产出的权衡你花十秒写一个文件路径可能省它读五个无关文件的时间。4. 用 Markdown 和 Git 给 Codex 搭一个信息高速公路4.1 为什么 Markdown 是给 AI 写上下文的最佳格式Codex 读代码和读文档的方式不太一样。代码它有语法结构可以解析但文档它主要靠语义理解。Markdown 的结构化标记标题、列表、代码块、表格能帮它快速抓住重点比一大段纯文本的效率高很多。我自己的习惯是所有给 Codex 的任务描述都用 Markdown 写而且刻意用标题分层。比如任务目标用二级标题涉及范围用列表参考实现用代码块。这样它读的时候能很快定位到每一类信息不需要在一大段文字里自己找。还有一个细节Markdown 的换行规则。很多人写 Markdown 的时候习惯一行写很长但 Codex 读的时候过长的行会增加它的解析负担。我的做法是每行控制在合理长度重要的信息单独成行或者单独成列表项。这样它一眼就能扫到关键点。4.2 把项目约定写成 Markdown 文档让 Codex 自己读比每次写任务描述更省事的办法是把项目的通用约定写成一份 Markdown 文档放在仓库里让 Codex 每次任务开始前先读它。这份文档可以包含项目的目录结构说明各模块的职责划分常用的工具函数和它们的用途代码风格约定测试怎么跑、怎么验证我一般把这份文档命名为AGENTS.md或者CONTRIBUTING.md放在仓库根目录。然后在任务描述里加一句先读一下 AGENTS.md 了解项目约定Codex 就会自己去读。这样你就不用每次都在任务描述里重复项目背景信息了。这份文档的维护成本很低一开始花半小时写个初版后面遇到新的约定就补一句。但它带来的收益是持续的每一次任务Codex 都能站在一个统一的项目认知上开始工作而不是每次都从零开始猜。4.3 Git 工作流怎么配合干净的分支和清晰的提交Git 在 Codex 工作流里的作用很多人只想到版本控制其实它还有一个更重要的用途给 Codex 一个干净的起点。我踩过的一个坑是在一个已经改得乱七八糟的分支上让 Codex 干活。结果它读代码的时候读到的是一堆未提交的临时修改这些修改和任务本身无关但会干扰它的判断。它可能会把某个临时改动的写法当成项目约定然后照着那个错误的方向去改。后来我固定了一个习惯每次让 Codex 执行任务之前先确保工作区是干净的。要么把当前改动提交了要么 stash 起来要么切到一个新的分支。这样 Codex 读到的代码就是仓库里的真实状态不会受到临时改动的干扰。具体操作上我一般是这样# 检查当前状态 git status # 如果有未提交的改动先 stash git stash # 从主分支切一个新分支给 Codex 干活 git checkout -b feature/xxx # 任务完成后再把 stash 恢复回来 git stash pop这个流程看起来多了一步但它能避免很多Codex 改出来的东西和预期不符的问题。因为它的起点是干净的它的推理就不会被污染。4.4 提交信息也是上下文的一部分还有一个容易被忽略的点Git 的提交历史也是 Codex 的上下文来源。当它需要理解某个功能是怎么演变的它会去看 git log。如果你的提交信息写得很随意比如fixupdate改了一下它就很难从历史里获得有用信息。我的做法是提交信息尽量写清楚做了什么、为什么这么做。比如不写fix login而是写fix: 登录 token 过期后返回 401 而不是 500避免前端无限重试。这样 Codex 在看历史的时候能快速理解这个改动的意图在后续任务里也能参考这个思路。5. 那些让 Codex 变慢的隐形习惯5.1 在一个会话里塞太多不相关的任务这是最常见的隐形杀手。很多人图省事一个会话里连续跑好几个不相关的任务先改个 bug再写个新功能再重构一段代码。每个任务的上下文都留在会话里越堆越多。等到第三个任务的时候Codex 的 context 里已经塞满了前两个任务的探索痕迹和试错记录它的推理速度会明显下降而且容易被前面的内容带偏。我的做法是一个任务一个会话任务完成就开新的。如果任务之间确实有关联比如重构 A 之后要改依赖 A 的 B那可以在同一个会话里做但要在任务描述里明确说清楚这是接着上一个任务的。不相关的任务坚决分开。5.2 让 Codex 自己去探索项目结构有些人喜欢给一个很模糊的任务然后让 Codex 自己去探索项目结构。偶尔这样做没问题但如果每次都这样你就是在用 token 换它帮你画代码地图。而这个地图你其实自己心里有只是懒得写出来。更划算的做法是把项目结构的关键信息沉淀到 AGENTS.md 里让 Codex 读一次就记住而不是每次任务都重新探索一遍。这是一次性投入、长期收益的事情。5.3 忽略澄清问题的价值Codex 在任务不清晰的时候会问你澄清问题。很多人觉得这是它不够聪明的表现急着让它别问了直接干。但其实澄清问题是它在帮你补全上下文是好事。你认真回答一个问题可能省它读十个文件。我的习惯是它问什么我就认真答什么而且答得比它问的更详细一点。比如它问这个接口的鉴权是怎么做的我不只回答鉴权方式还会把相关的中间件文件路径一起给它。这样它拿到答案之后可以直接去读那个文件不需要再自己找。5.4 不清理会话里的失败尝试如果 Codex 在某个方向上试错了比如它改了一版发现不对你让它回滚。这个试错过程会留在 context 里。如果后面还要继续在这个会话里做相关任务这些失败尝试会干扰它。我的做法是如果试错比较严重直接开新会话把当前状态和正确方向重新描述一遍。虽然要重新说一遍但比在一个被污染的 context 里继续挣扎要快得多。6. 从能用到好用几个进阶的上下文管理技巧6.1 用文件引用代替大段粘贴有时候你需要给 Codex 看一段代码作为参考。很多人的做法是把代码复制粘贴到任务描述里。这样做的问题是粘贴的代码是静态的它不会随着代码变化而更新而且会占用任务描述的篇幅。更好的做法是直接给它文件路径和行号范围让它自己去读。比如参考 auth/service/session.go 第 45 到 80 行的 ClearUserSessions 函数。这样它读到的是最新的代码而且不占用你任务描述的空间。6.2 分层描述先给全局再给局部复杂的任务我习惯分两层描述。第一层是全局背景这个任务在整个项目里处于什么位置为什么要做。第二层是局部细节具体改哪个文件、哪个函数、改成什么样。全局背景帮它建立正确的推理方向局部细节帮它快速定位。两层结合比只给局部细节效果好很多因为它能理解为什么要这么改从而在遇到边界情况时做出更合理的判断。6.3 把验证方式写进任务描述这一点很多人会忽略。你不告诉它怎么验证它就只能自己猜一个验证方式或者干脆不验证。而验证方式其实是你最清楚的东西你知道跑哪个测试、看哪个接口、检查什么输出。把验证方式写清楚能省掉它大量试错的时间。我一般会在任务描述的最后加一段验证方式写清楚改完之后怎么确认。比如跑go test ./auth/...然后手动调一次改密码接口再用旧 token 调一个需要登录的接口确认返回 401。这样它改完之后会自己按这个方式验证不需要你再来回确认。6.4 定期回顾和优化你的任务描述模板任务描述模板不是一成不变的。用一段时间之后你会发现某些信息你总是要重复写那就把它沉淀到 AGENTS.md 里某些信息其实 Codex 自己能找到那就可以从模板里去掉。定期回顾你的任务描述看看哪些是真正有用的哪些是冗余的这样模板会越来越精炼填写速度也会越来越快。7. 我踩过的几个典型坑7.1 以为说得越少越显得我懂刚开始用 Codex 的时候我有一种奇怪的心理觉得说得太详细显得自己不够高级好像高手都是一句话就能让 AI 干活。结果就是任务反复来回效率极低。后来想明白了跟 AI 协作说清楚是本事不是丢人的事。你花在描述上的每一分钟都会在执行阶段加倍省回来。7.2 在错误的会话里继续任务有一次我在一个会话里做了任务 A然后接着做任务 B任务 B 做到一半发现方向不对想回到任务 A 的状态。但这时候 context 里已经混了任务 B 的内容Codex 对任务 A 的理解已经被污染了。最后只能开新会话重来。这个坑让我养成了任务隔离的习惯现在基本不会在一个会话里混做不相关的任务。7.3 忽略了 Git 状态的影响前面提过在脏工作区里让 Codex 干活是个坑。我遇到过一次更隐蔽的工作区是干净的但当前分支是一个很旧的分支代码和主分支差了很多。Codex 基于旧代码做修改改出来的东西和主分支的现状对不上。后来我固定了任务前先确认分支状态的习惯避免这类问题。7.4 把澄清问题当成干扰早期我总觉得 Codex 问澄清问题是它不够智能急着让它别问了。后来发现它问的问题往往正是我描述里缺失的关键信息。认真回答这些问题其实是在帮我补全上下文。现在我会主动在任务描述里预判它可能问的问题提前把答案写进去这样它连问都不用问。8. 把上下文工程变成肌肉记忆说了这么多核心其实就一句话Codex 的效率很大程度上取决于你在任务开始前投入的注意力。你给它的起点越清晰它走的弯路越少消耗的额度越少你等待的时间越短。这不是什么高深的技巧而是一个需要刻意练习的习惯。我自己的做法是把前面说的那套流程固定下来任务前先确认 Git 状态干净然后用五段式模板写任务描述涉及项目约定的部分引用 AGENTS.md验证方式写清楚一个任务一个会话。这套流程跑熟之后写任务描述的时间大概一两分钟但它带来的效率提升是实打实的。如果你现在正觉得 Codex 越用越慢、额度越用越快不妨先别急着换工具或者换模型回头看看自己的任务描述。大概率问题不在工具而在你给它的起点。把起点这件事做好你会发现同一个工具用起来完全是两种体验。最后分享一个我最近在用的一个小技巧我会把每次任务描述存成一个 Markdown 文件放在项目的tasks/目录下。这样一方面方便回顾另一方面如果后面有类似的任务可以直接参考之前的描述改一改比从零写快很多。而且这些任务描述积累下来本身就是一份很好的项目文档新人看了也能快速理解各个功能是怎么演变的。