恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Codex高效提问指南:七张急救卡搞定重构、测试与代码评审
首页
资讯中心
/
Codex高效提问指南:七张急救卡搞定重构、测试与代码评审
Codex高效提问指南:七张急救卡搞定重构、测试与代码评审
发布时间:2026/10/15 12:01:04
1. 为什么明明把任务丢给了 Codex它却总是答非所问先说一个我观察到的普遍现象很多人对 Codex 这类编程助手的第一印象是“它好像很聪明又好像不太聪明”。让它写段排序算法、生成个接口文档表现还不错可一旦涉及具体的业务代码比如“帮我看看这个模块为什么内存涨得这么快”“给这个函数补测试”它就容易东扯西扯给出一些看起来能用、实际上跟你的项目半毛钱关系都没有的答案。问题出在哪大部分时候不是模型不行而是提问的方式太随意了。你想想我们平时在代码里写注释都嫌麻烦更别说给 Codex 完整交代一段代码的背景、约束、输入输出和期望了。但模型并不知道你真实的工程上下文它只能靠你这句话里的信息量来做推断。你说“帮我把这段代码优化一下”它会默认你是想让它把变量名改短一点、把 if 换成 switch你说“这个函数有问题”它会默认你只是想知道语法错误而不是想让它帮忙查并发竞态。我觉得程序员向 Codex 要产出跟向一个刚入职、有一定基础但完全不了解你项目的实习生布置任务是类似的。你不告诉他边界条件、不告诉他验收标准、不告诉他项目里哪些约定不能破坏他交上来的东西大概率得返工。所以我才把常用的提问方式整理成几张“急救卡”核心思路就一条先诊断后开方再复诊。也就是先让 Codex 理解现状再让它给出方案最后根据实际运行结果继续追问。这套思路并不复杂但把它固定成模板以后每天能省下的沟通成本非常可观尤其是那种一天要问十几轮、二十几轮的高强度开发日。这篇文章想做的事很简单给你七张可以直接抄的提问卡片每张都带一个真实场景下的完整提问示例再讲一讲怎么把这些卡片组合起来应对那种“既要改 A、又要测 B、还要不破坏 C”的复杂需求。如果你是刚开始用 Codex或者用了一段时间但总觉得产出不稳定这篇内容应该能帮你找到问题所在。需要说明的是下文涉及的代码场景都做了脱敏处理但提问结构和思维方式是可以直接迁移到你自己项目里的。2. 七张“急救卡”逐张拆解每张都有可直接套用的完整案例这七张卡片分别对应七类高频开发任务重构优化、故障定位、文档注释、测试补齐、代码评审、跨语言迁移、陌生代码库速览。每一张我都会给出典型场景、完整提问示例以及提问时最容易踩的坑。2.1 重构卡让 Codex 只动结构、不动行为重构是所有卡片里最容易翻车的一类原因很简单模型往往分不清“重构”和“顺手改逻辑”的边界。我见过最典型的一个事故是这样的某开发者让 Codex 把一个 Python 函数改成更容易理解的写法模型不仅压缩了代码量还顺手改变了两个边界条件下的返回行为。单测跑不过去这位同事花了大半天时间才意识到问题出在模型“好心帮忙”改了一个分支判断。后来我把重构类提问固定在这样一个结构里用起来稳定很多角色和目标先交代清楚比如“你是一名熟悉该业务的老同事”然后是位置给出具体函数名和文件路径接着是动机说清楚是为了可读性、性能还是消除重复最关键的最后一句一定是“只允许调整结构和命名不允许改变任何输入输出行为和异常抛出逻辑”。比如这种写法有一个函数 calculate_discount定义在 src/pricing.py 里。 当前问题是它的嵌套 if 太深读起来很费劲整个函数有七八层缩进。 我需要你帮我重构它目标是降低圈复杂度。 要求 1. 保持函数签名不变 2. 保持所有输入输出映射关系不变 3. 每一步重构都要写一句理由说明为什么这样拆。 请先输出重构后的完整代码再输出每一处改动的动机说明。这里有个关键点一定要点名“输入输出映射关系”它相当于给 Codex 划了一条数学上可检验的底线。如果它输出的代码里出现了一个原函数根本不会出现的异常类型或者某个边界条件从“返回 None”变成了“抛异常”你一眼就能发现。另外我自己会额外加一句“不要引入第三方库”。模型有时候图省事直接给你推荐装一个什么库来简化逻辑这在生产项目里往往是不想接受的尤其是在依赖管理严格的团队里。2.2 定位卡不急着让 Codex 修先让它列出最可能的原因遇到线上问题或者测试挂掉的时候很多人第一反应是直接把报错信息丢给 Codex问它“怎么修”。我的建议是反过来——先问它“可能是哪几个原因”让它按概率排出前三名。这不是绕弯子。Codex 给出的“修法”通常是基于报错文本的浅层推断它没有执行过你的服务看不到真实的调用链和栈帧。但如果让它基于报错文本和经验知识列出假设本质上就是在帮我们缩小排查范围这是它最擅长也最不容易出错的部分。我常用的排错提问长这样我的程序在调用 send_message 时抛了 TypeError: unsupported operand type(s) for : NoneType and str发生在 message_queue.py 的第 44 行。 我已经确认过第 44 行确实是字符串拼接操作。 请列出可能导致这个 None 出现在这里的三个最可能原因按可能性从高到低排列。 每个原因需要说明可能发生的业务场景、如何用日志或调试器快速验证、以及相应的修复思路。 先不要直接给我改代码。注意最后那半句“先不要直接给我改代码”非常关键。一旦你允许它边分析边改它写出来的修复代码往往是针对最表面的那个假设万一假设错了反而浪费更多时间。等它列完假设你再根据自己的业务知识挑一个最可疑的方向深入这时候再让它输出小范围的修复补丁准确率会高很多。这其实就是医生看病的逻辑——先鉴别诊断再开处方。还有一个经验在排错类提问中文件路径和行号一定要写准行号可以不确定但路径和函数名最好不要含糊。Codex 对位置信息的理解方式跟人脑不太一样你不给位置它就按“最常见的使用方式”猜而你项目里的使用方式往往不是最常见的。2.3 注释卡让注释服务新人而不是服务 Codex写注释这件事争议一直很大。有人认为代码即文档注释越少越好有人觉得没有注释的新人接手就是灾难。我的态度是折中代码应该自解释但涉及业务意图、边界约定和非显然处理的地方必须有注释。Codex 有个很大的优势——耐性。让它把一个一百行的函数逐段解释清楚它不会烦。但它的默认注释风格有两个问题第一废话太多喜欢解释那些代码本身已经很清楚的东西比如“这里将 x 加一”第二中文注释里偶尔混入英文术语或者在注释里编造业务背景。所以我的注释卡长这样给下面的函数 generate_report 写中文注释。 函数路径在 src/reporter.py。 要求 1. 给函数整体写一段说明包括它服务于什么业务流程、前置条件和副作用 2. 给核心代码块写行内注释只解释“为什么这样做”和“这里的边界约定”不解释“做了什么” 3. 不允许出现“这里将值赋值给变量”之类的废话 4. 若某处代码本身含义模糊请明确指出“此处理解为...如果实际意图不同请纠正我”。你可能会问最后一条会不会有点多余其实很有用。模型对代码的理解偶尔会跑偏比如把一个重试逻辑理解成业务判断。如果它敢于把理解说出来你就能在合并注释之前发现这种偏差而不是看着一个看起来很合理的注释被提交进去。至于“前置条件和副作用”这两个词是我从工程文档里借鉴来的效果奇佳。让 Codex 明确写出“这个函数假设 config 里一定包含 api_key”“这个函数会修改 session 状态”往往能暴露出很多平时没人注意的隐性依赖。2.4 测试卡把正常路径、边界值、异常路径写进同一个请求让 Codex 补测试是性价比极高的一件事但默认生成的测试往往只覆盖正常路径个别时候连正常路径都覆盖得很敷衍。我的做法是在提问时主动规定测试结构要求它按三层来写。三层指的是正常路径、边界值、异常场景。这个框架不是给模型定的是我们写测试本来就应该遵守的基本逻辑只不过用提问的方式把它表达出来。示例提问为以下函数编写 Jest 测试用例文件路径是 src/validator.ts。 函数签名 validateUsername(username: string): { ok: boolean; reason?: string } 已知规则长度 3 到 16 个字符只能包含字母、数字、下划线不能以下划线开头。 请按以下结构输出 1. 正常路径用例两个覆盖长度中间值和含数字/下划线的组合 2. 边界值用例三个覆盖长度等于 3、长度等于 16、以下划线开头 3. 异常场景用例三个覆盖长度越界、包含非法字符、传入空字符串。 每个用例请写明断言的内容和为什么这样断言。这里有个容易被忽略的点在提问里给出具体的输入值范围。如果你只写“请给 validateUsername 写测试”模型可能拿外部输入、类型异常、undefined 等情况来充数反而把你真正关心的业务边界给漏了。你喂给它的规则越具体它产出的测试就越贴合你的验收标准。我还习惯在得到测试代码后追加一轮“把这些用例当作黑盒测试反推一下如果被测函数是这样实现的哪些用例会失败”这一步本质上是在做变异测试的思路。Codex 会帮你挑出那些即使代码写错也能通过的“弱断言”然后你再针对性修正。2.5 评审卡以某位资深同事的口吻挑剔代码代码评审这事在 GitHub/GitLab 上做是一套流程但你也可以先在本地用 Codex 过一遍减少给同事添麻烦的次数。我的经验是让 Codex 以特定角色来评审比不带角色的评审效果翻倍。不带角色的评审模型输出的大多是比较泛的赞美和“建议增加注释”“建议拆分函数”这种万金油。带上角色之后它会真的去挑刺而且挑刺的方向更接近一个资深工程师的视角。你看这个例子假设你是一位注重可维护性和并发安全的高级工程师请评审下面这段代码的 diff。 代码逻辑一个购物车接口收到请求后更新 Redis 中的库存数据。 评审要求 1. 重点关注并发问题、资源泄漏、异常处理遗漏、可扩展性风险 2. 每条意见标注严重级别严重/一般/建议 3. 每条意见给出针对性的修改建议并说明为什么 4. 如果某处写法你认为是合理的直接忽略不用客气。我特别强调“如果某处写法合理直接忽略”因为模型的默认输出太长为了“显得认真”它会强行凑几条不痛不痒的意见。这一句能帮你把噪音砍掉一大半。从实际效果看Codex 在这类任务里最突出的能力是发现并发问题。比如“这个 Redis 操作不是原子的存在超卖风险”或者“这个连接没放进 finally 里异常时会泄漏”。这些点恰恰是人肉评审时最容易疲劳忽略的。2.6 迁移卡从 Python 到 JavaScript重点是要“本地化风格”跨语言迁移也是我很常用 Codex 的场景之一。但很多人的提问方式就是简单一句“把这段 Python 转成 JavaScript”。结果呢生成的东西看起来像“Python 语法换皮”处处带着非惯用的痕迹。原因在于模型默认会保守地保留原语言的语法结构比如把 Python 的列表推导式翻译成 JavaScript 的 for 循环把字典推导式翻译成连续的对象赋值。它需要明确指令才会使用目标语言的惯用表达。我常用的迁移卡片长这样请把下面这段 Python 代码迁移成 TypeScript。 代码功能从配置文件读取一组规则按优先级排序后返回。 迁移要求 1. 不逐行直译请按照 TypeScript 的惯用法重写比如充分利用类型、接口、可选链 2. 不要为了对齐源结构而引入多余的类或装饰器 3. 对原代码中的动态类型行为请显式定义联合类型并给出注释 4. 迁移后请指出两处你认为目标语言做得更好的地方。“指出两处你认为目标语言做得更好的地方”这句话是我后来加上的。它有两个作用一是强迫模型认真思考两门语言的差异而不是机械替换二是让你在审查迁移结果时能同步学习到一些目标语言的最佳实践。再补一点关于迁移的通用原则数据格式和业务语义优先于语法。你在提问里最好能明确说一句“这两段代码必须保持相同的输入输出结构尤其是日期格式、数值精度、异常类型”。迁移脚本最容易踩的坑就是精度和时区问题提前打了预防针后面省一堆事。2.7 速览卡把陌生代码库变成一次有向导的参观接手别人留下的项目最怕的就是不知道从哪里看起。这时候我用于“速览”的提问模板是这样的先让 Codex 给出代码库的整体结构地图再让它挑出最核心的一条主链路来精讲。我之前完全没有接触过这个项目请帮我快速了解它。 项目根目录是 /workspace/order-service主要语言是 Java。 请先完成以下三件事 1. 用 200 字以内概括这个服务的职责和入口点 2. 列出一个新订单从接口进入、经过哪些核心类、最终落库的完整调用链 3. 指出三个你认为要改这个项目最先需要理解的文件并分别说明原因。这个模板最值钱的地方在第三问——“如果只让你读三个文件你会选哪三个”。模型给出的答案往往是一个合格的程序员真正理解项目时才会关注的枢纽文件比如启动类、配置类、核心领域模型。而不是泛泛地列几个 Controller 让你挨个读。拿到速览结果后我的习惯流程是打开它提到的几个文件人工快速过一遍然后回来继续追问细节。这比自己从 readme 开始读、再到目录里摸索至少快一个下午。3. 模板的组合写法两个甚至三个急救卡变成一条工作流单张卡片本身解决的是孤立问题。但在真实项目中很少有“只重构”“只补测试”“只看代码库”这种单一动作的任务。大多数开发工作是一个链条先理解再动手再验证。所以模板之间的组合能力才是这套急救卡的真正价值所在。3.1 最值得练的三个组合场景我日常使用频率最高的是下面这三种组合分别对应接手旧代码、线上紧急处理和开发新功能。场景一是“接手历史遗留模块”第一步用速览卡2.7让 Codex 概括这个模块的职责和数据流第二步用测试卡2.4给关键函数先补上基线测试第三步用重构卡2.1在测试的保护下开始改结构。这三步的逻辑很像修老房子先画图纸再打地基最后才动土木。没有测试基线就重构和摸着黑拆承重墙没什么两样。场景二是“线上紧急故障”第一步用定位卡2.2让 Codex 列出可能原因第二步从日志系统把真实堆栈贴回去追问“如果是这个原因修复方案是什么”第三步用评审卡2.5让 Codex 检查修复补丁本身会不会带来新问题。线上问题最重要的约束是不扩大影响范围。定位卡帮你把猜测范围框住评审卡帮你在发布前拦住一刀切式的修复。场景三是“开发新功能”先用速览卡2.7确认新功能应该挂在现有架构的哪个位置然后用一个不是模板中的自由提问让 Codex 给出实现方案框架最后把方案框架当作约束再进去用重构卡2.1优化细节。这本质上是“先问架构再问实现”的两种粒度切换。很多人一上来就让 Codex 直接生成一个完整的 ControllerServiceRepository结果模型把项目里并不存在的中间层也幻想出来了。分两步走就是为了避免这种过度生成。3.2 组合时的三条上下文控制铁律模板组合最怕遇到的问题不是模型不懂而是它“记混了”——把上一轮你展示的代码文件当成这一轮需要修改的对象。为了避免这种情况我给自己定了几条必守的原则。第一每轮对话都明确点出当前目标是哪三个文件。如果你在上一轮贴了 a.ts、b.ts、c.ts 三个文件这一轮实际只想改 a.ts那就开口先写“本轮只考虑 a.tsb.ts 和 c.ts 只作为调用方背景”。模型没有人类的短时记忆边界你不强调它就可能把三个文件都改了。第二对模型的输出别直接相信“验证通过”这句话。Codex 有时候会在代码注释里写“// 以上代码已通过测试”实际上它根本没跑过。这个时候我会用一条追问模板“你刚才的修改涉及 b.ts 的 import 变更请确认这个变更不会破坏 xxx 场景下的类型推导。”说白了把模型当作一个诚实但偶尔迷糊的同事需要反复确认它说的验证到底靠不靠谱。第三每完成一轮任务主动发起一次上下文压缩。比如“前面讨论的定位过程已经结束了现在只保留最终结论”。这能防止 Codex 在后续对话里被前面很长一串排错细节干扰重新回到正确轨道上来。很多长会话跑到后面质量下降就是因为没有做这种显式的上下文切换。组合写法还有一个小技巧把上一轮 Codex 的代码输出连同你的修改意见一起作为新问题的一部分贴回去。比如“我改了你输出的第 12 行去掉了可选链因为业务上这个字段一定存在请基于新的代码重新审查”。看起来只是单纯复述实际上这是用“增量反馈”的方式让模型逐步逼近你真正想要的结果。4. 从急救卡到日常习惯排除不稳定输出和沉淀个人提问库模板能解决“不知道该怎么说”的问题但不能解决所有问题。在我用 Codex 大半年之后剩下的工作主要是两件事一是处理它偶尔的不稳定表现二是把每次有效的提问沉淀成自己的“提问弹药库”。4.1 面对 Codex 的不稳定输出我的处理节奏不稳定主要出现在三类情况输出过长导致后半部分质量下降多次生成结果不一致以及对某些小众语言的支持明显比对 Python、JavaScript 弱。输出过长的问题典型的场景是让它生成一个完整模块结果写到后面它忘了前面的约定比如变量名不一致、函数签名漂移。我的应对很简单在一开始就给输出加长度约束“请先输出第一个核心文件的完整代码其他文件用接口占位分两轮完成。”把大任务拆短正好避开了模型长文本容易走神的问题。多次生成结果不一致的常见于“设计类”提问因为没有唯一正确答案模型每次给出的方案侧重不同。我不会跟它在同一轮里死磕而是多开几轮让它各给一版方案然后人工横向对比挑出最符合当前项目约束的那一版再把挑中的版本作为唯一基准继续往下聊。至于小众语言说实话目前没有特别好的办法。我的经验是退一步先用 Codex 写出基于逻辑的伪代码然后挂一个“请标注哪些语法需要到官方文档确认”的指令把自己从容易出错的部分中解放出来。4.2 怎么构建属于自己的十六张、二十张提问卡最开始的我也是从别人分享的模板开始抄的但抄完总觉得不完全贴合自己的项目。后来我改了一个策略不再背模板本身而是背“模板里的变量名”。什么意思就是每个模板里真正有用的其实不只是句式而是那几个需要你手动填的槽位。比如重构卡里必须填的四个槽位是文件路径、函数名、重构动机、不可破坏的约束定位卡里必须填的是报错信息、代码位置、已排查方向、处理顺序测试卡里必须填的是被测对象、规则列表、用例结构。把这些变量抽象出来之后我就给自己建了一个纯文本的 prompt 片段库按用途分类存放。合在一起是一个大的“急救手册”但实际上每个条目都可以单独取用也可以跟别的条目拼装。平时写代码时我不需要复制整段模板只需要按场景召唤对应的几行。这里有一点想提醒你别追求完美提示词先追求稳定产出。我见过有的开发者为了一个提问反复措辞十几分钟这种求完美的心态反而背离了模板的意义。模板的价值是让你三十秒内发出请求而不是三十秒内写出完美请求。就算第一次给的产出方向不对后面加一轮修正也能拉回来比你一开始陷入分析瘫痪要强得多。还有一个更进阶的用法是把这些提示词片段沉淀到团队的文档里。比如团队内部的“快捷命令手册”“Codex 使用约定”一类的地方。新人接手项目时直接看到“重构前先贴测试卡”“未知文件先走势图卡”比一遍遍口头讲解靠谱多了。团队里每个人都在用同一套语言跟 Codex 沟通代码审查、交接成本也会低不少。说到底急救卡不是让你变成提问大师而是让 Codex 在你手里从“偶尔好用”变成“大部分时候都算得上顺手”。如果你下次打开编辑器第一反应不是敲一行普通的话而是顺手抽出对应场景那张卡那你已经读完这篇文章最大的收获了。