代码审查与微重构:用Prompt构建可控的AI代码优化流程 每次提完代码的自审需求团队成员都会丢来一句“帮我看看这段代码顺便优化一下”。起初我都是在IDE里逐行读后来直接把代码丢给大模型但问题马上来了——没有约束的“顺便优化”经常把同事的代码改得面目全非遇到业务逻辑复杂的模块还容易出现“改一帧崩全局”的尴尬。直到我把“代码审查”和“微重构”拆成分阶段的prompt并把边界条件、风险清单、输出格式全部写清楚整个流程才真正稳下来。这个“代码审查微重构prompt”的核心价值就是把两件事合并成一条可控的流水线先让模型做严格审查并输出问题清单和风险等级再在这个基础上进行最小粒度的重构最后给出完整的变更说明。它适合两类人一类是每天要review别人代码、又被各种风格差异折磨的开发者另一类是习惯先让AI看一眼自己代码再提PR的个人开发者。1. 整体设计思路为什么要“先审查、再微重构”1.1 审查和重构天然是配套动作分开做只会浪费时间我以前发起过的prompt需求经常是“请帮我审查这段代码然后顺便优化一下”听起来很自然但实际执行结果几乎不可用。大模型在同一个回复里既要判断问题又要动手改往往会因为注意力分配不均导致某一边做得很差。最常见的情况是它只罗列了两三个表面的格式问题然后大刀阔斧地重写了一遍代码——变量重命名了、循环改成了列表推导式、嵌套if换成了guard clause逻辑上好像也说得通但一跑测试发现原有的异常处理分支被悄悄删掉了。后来我把流程拆开先让它只做审查并输出结构化的发现清单等清单确认后再进入重构阶段。这个改变带来的效果立竿见影第一模型在审查时会老实很多不再想着“反正最后要改审查随便说两句就行”第二我可以先看清单里的问题等级决定哪些值得改、哪些不值得动避免不必要的代码变动第三一旦确定了问题清单重构成了一个“照着方案执行”的动作模型的输出稳定性明显提升。1.2 微重构的粒度边界需要靠prompt框架来划定“微重构”这个词听起来简单但执行起来最大的坑是范围蔓延。一次重构动辄把几十行代码推倒重来这在大型业务代码中是致命的。我必须让模型明确“最小变更”“行为保持”“单一目标”这几个硬性约束并且告诉它什么情况属于“越界”。在设计prompt时我把微重构的目标定义为以下四点优化可读性、消除重复代码、拆分过长的函数、提升局部逻辑的清晰度同时规定所有改动必须以“不改变函数的输入输出行为和异常路径”为前提。如果模型发现要实现某个优化需要动到函数签名、改数据结构或者调整模块间的协作方式它必须停下来在“风险提示”里说明而不是自作主张去改。这个“提出但不执行”的机制是我反复调出来最有效的。1.3 为什么不用“直接让模型重写整个文件”的方案有人会问既然大模型能力强直接让它输出优化后的完整代码不就好了吗答案是不行至少在真实工程场景里不行。完整重写意味着模型要依靠自己的理解在高层面上重建代码结构而它对这个项目的业务背景、历史包袱、隐性约束都一无所知重写往往会引入很隐蔽的逻辑偏差。而微重构是在原代码基础上做局部手术每一处改动都像在已有的骨架上加固而不是拆了重搭出错时也更容易定位和回滚。另外从审查到重构的这个split设计还有一个额外好处它有效缓解了“模型尽力讨好用户”的倾向。当你直接说“优化代码”时模型默认你想看到改动于是即便代码已经不错它也会硬挤一些修改出来而审查阶段的目标是找问题、提风险、做评判模型不需要为了“显得有用”而强行改码输出的真实性高很多。2. 核心细节解析prompt中必须包含的关键模块2.1 角色与目标设定好的prompt不是上来就把代码贴给大模型而是先创立一个清晰的执行框架。我的prompt第一段是角色设定“你是一名有十年经验的代码审查专家关注代码正确性、可维护性和性能风险同时具备节制的重构能力。”这比你直接说“帮我看看代码”更能引导模型进入专业状态。目标设定也很关键我会明确说出这次任务的范围“先完整审查我提供的代码片段按严重程度输出问题清单审查完成后再根据确认的问题清单进行微重构。”这个顺序和输出预期是prompt的骨架必须写在最前面因为大模型对“先做什么、再做什么”的指令比“同时做好几件事”要听话得多。2.2 审查维度与输出清单审查维度决定了模型会关注哪些角度。如果只说“看看这段代码有什么问题”模型大概率只给你找语法瑕疵、命名问题这些表象。我自己整理过一份维度清单直接写进prompt里正确性是否存在边界条件未处理、空指针/空值风险、并发安全性问题、逻辑分支遗漏可读性命名清晰度、函数是否过长、代码注释是否必要且准确、结构是否易于理解性能是否有明显的多余计算、循环内重复调用、可缓存而未缓存的热点安全是否存在注入风险、敏感数据泄露、不可信输入处理不当健壮性异常处理是否合理、依赖外部资源是否有超时/降级机制针对每个维度都要求模型用列表形式输出“文件位置行号级别描述有的话或函数名具体问题严重程度修改建议”这样我能直接对照源码做判断。严重程度我常用P0/P1/P2三级P0是会导致错误或事故的P1是明显不合理的实现或重要改进点P2是建议性的风格优化。2.3 微重构执行规范与边界控制重构阶段的prompt是整套框架里最需要精细化控制的部分。我给了四个硬性规范第一改动必须是局部的、最小化的。模型要尽量复用已有变量名和函数名除非原命名严重误导或与规范冲突否则不展开重命名。第二不允许改变对外接口。函数签名、类名、模块导出、返回值的结构和语义都保持不变。这个约束能避免模型顺手把调用方全改了的连锁反应。第三每次重构必须带清晰的diff式说明。在输出的代码块前后标注“改动点-原因”让我一眼看出哪里动了、为什么动。第四如果发现审查清单里有某些问题无法在不触及外部接口的前提下解决比如需要改变数据模型才能修好模型要输出“超范围提示”把问题留给开发者决策而不是自己绕路硬改。这四条规范缺一不可。我吃过亏的是第三条没写清楚时模型重构完代码连个注释都不留我根本分不清它改了哪些地方code review时无从查起。后来把“diff说明”作为强制的输出格式放在prompt中这个问题就解决了。2.4 输出格式模板与交互流程为了让模型输出更可靠我在prompt里写死了输出格式模板包括审查结果按P0/P1/P2分级的问题清单每项包含位置、问题、理由、建议修法重构计划基于审查清单列出你想改哪些点用什么方式改计划耗时或难度预估可选重构后代码只贴被修改过的函数/代码块不要展示整个文件变更说明逐条列出实际改动标注对应的问题编号以及每处改动的目的和风险超范围记录任何超出原审查模块边界的潜在问题统一在此记录这种模板化输出让后续人工review的效率大大提升。我可以在问题清单阶段直接回复模型“P2级别的先不改P1里面的第2条我不同意你的修改建议用另一种方式改”然后让它带着新的指令进入重构阶段。多轮对话的稳定性也因此高了很多因为每轮都有固定的输出框架可以比对。3. 实操过程与核心环节实现3.1 完整prompt模板示例下面是我目前一直在用的prompt模板。要注意的是这段prompt不是一次成型而是经过多轮试错才稳定下来的。使用时可以直接复制替换掉“待审查代码”部分的代码即可你是一名拥有十年经验的代码审查专家擅长从正确性、可读性、性能、安全和健壮性五个维度审查代码同时具备克制而精准的微重构能力。 任务流程分两个阶段 第一阶段代码审查。严格按以下维度审查我提供的代码不要急于修改先输出结构化问题清单。 第二阶段微重构。根据我批准的问题清单做最小范围的重构修改并输出完整变更说明。 审查维度 1. 正确性边界条件、空值/空引用、并发、逻辑分支遗漏、异常路径。 2. 可读性命名、函数长度、注释质量、结构清晰度。 3. 性能不必要的计算、重复调用、可缓存的逻辑、热点路径。 4. 安全注入风险、敏感信息、不可信输入、加密或访问控制。 5. 健壮性异常处理、外部依赖、超时与降级机制。 输出格式要求 审查阶段请严格输出 ### 审查结果 按严重程度分类的问题清单 - [P0] 位置问题描述风险理由修改建议 - [P1] 位置问题描述风险理由修改建议 - [P2] 位置问题描述风险理由修改建议 重构阶段请严格输出 ### 重构计划 列出你计划修改的点以及修改方式。 ### 重构后代码 只展示修改过后的函数或代码块保持其他部分不变。 ### 变更说明 逐条列出实际改动引用问题编号并说明每处改动的目的与潜在风险。 ### 超范围提示 如果某些问题涉及改动函数签名、数据模型、模块接口或调用方无法在局部重构中解决请在这里说明不要直接修改。 微重构硬性规范 1. 最小变更原则保持对外接口不变尽量复用原有命名不做风格性重写。 2. 行为不变原则不得改变输入输出行为、异常路径、边界处理语义。 3. 谨慎改动原则如果不确定某处改动是否会引入风险保留原样并把风险列入“超范围提示”。 4. 禁止扩大范围不得顺带修改无关代码不得重构与你确认清单无关的部分。 待审查代码 [在这里粘贴你的代码片段]3.2 实操示例一个真实的审查与重构过程拿一个典型的反馈型代码片段来演示这个prompt的实际效果。假设我有下面这段Python代码是一个简单的用户登录尝试控制逻辑def login_attempt_check(user, max_attempts, lock_minutes): attempts get_attempts(user.id) if attempts max_attempts: lock_user(user.id, lock_minutes) return False else: increment_attempts(user.id) return True用上面的prompt跑一遍后审查阶段输出的问题清单大致会是P0attempts用判断但从业务上看“第N次失败后是否允许继续尝试”的边界定义不清如果max_attempts传0就会直接锁用户缺少入参校验。P1函数没有区分“本次登录失败”和“之前已经超过阈值”两种场景返回值True/False的语义在调用方容易混淆。P1每次调用都无条件increment_attempts但登录成功后的清空操作没有放在这个函数里次数会越攒越多。P2else分支在提前return后其实可以省略减少嵌套层级。基于这份清单我可以决定是否批准重构。如果这张清单里有些问题我不想处理比如业务需求本来就是“永远不清空次数”就可以在第二轮回复时告诉模型“P0第2条不用改P1两条都改P2改”。模型会重新调整计划再执行。进入重构阶段后的输出大致是def login_attempt_check(user, max_attempts, lock_minutes): if max_attempts 0: raise ValueError(max_attempts must be positive) current_attempts get_attempts(user.id) if current_attempts max_attempts: lock_user(user.id, lock_minutes) return False increment_attempts(user.id) return True变更说明里会标注改动点1为新增入参校验对应P0问题改动点2为移除else分支对应P2优化改动点3为局部变量名调整便于语义明确同时“超范围提示”里会建议把登录成功后的attempts清空逻辑纳入调用方处理因为本函数无法独立完成。整个过程从审查到重构完全可控。3.3 如何把prompt接入日常代码评审工作流实际使用时我不会每一段代码都走完整流程。目前我沉淀了一套接入方式效率比纯手工review高不少第一步从版本控制工具里导出需要review的diff只选改动过的函数级别片段不要整个文件丢给模型。为什么因为大模型在长上下文中容易被无关代码带偏而且上下文窗口有限放太多文件会导致关键信息被稀释。第二步在prompt模板里贴上必要的前置上下文。比如这个函数所在的模块是做什么的、有没有特定的代码规范、是否有历史背景需要注意。没有这些上下文时模型可能会按通用的最佳实践来审查结果跟项目实际风格差很多。第三步先跑一轮审查拿到P0和P1问题清单后再决定是否进入重构。如果代码本身质量已经不错可能直接结束流程如果问题多再针对问题做多轮重构。不要一上来就要求模型“审查后直接重构”这样你等于放弃了中途干预的机会。我自己还会把输出中的问题清单复制回代码评论系统作为review意见草稿。模型语言通常比人工写的更结构化我再稍微改一下措辞就能发给同事省掉了打字的功夫。当然每条意见我都会再确认一遍毕竟模型会看走眼有时候会把本来就合理的写法当成问题。4. 常见问题与排查技巧实录4.1 模型审查不全面漏掉关键逻辑问题这是使用审查类prompt时最先遇到的头疼问题。模型经常把注意力放在浅层命名和格式上对深层逻辑漏洞视而不见。我的排查思路是先检查是不是prompt里的审查维度列表太笼统。如果只写了“请全面审查”模型大概率会默认“全面”等于“看看语法和命名”。解决方法是把每个维度下面再拆出几个具体子问题比如在安全维度下写“是否存在SQL注入、路径遍历、不安全的反序列化、敏感硬编码”在正确性维度下写“是否处理了None、空列表、超大数字、并发修改”。这个“子问题列表”是在几轮实测里慢慢补全的补完以后审查命中率明显提升。另外如果模型给的清单全都是P2级别的风格建议而没有任何P0/P1大概率是因为它没理解代码逻辑。此时我会在prompt里补充一句“如果代码逻辑自己能跑通请明确指出你的判断依据并在不确定的地方提问不要假设上下文。”这个约束能逼着模型把注意点放在逻辑推理而不是表面修饰上。4.2 重构后“看着很干净跑起来就报错”这是重构阶段最容易翻车的情况。模型改后的代码格式漂亮、结构优雅但一执行就异常。最常见的原因有三个一是模型对原代码的隐含副作用理解不到位比如某个局部变量原本在下面还被用到结果被它优化没了二是异常处理路径被压缩原本某个分支会捕获特定异常重构后用统一的兜底处理吞掉了细节三是模型使用了它自己“想象”的API比如把标准库的某个行为记错了导致运行时错误。针对这个问题我在prompt中加入了三个防御机制第一要求模型在“变更说明”中列出每处改动的测试影响面提示我该跑哪些case第二要求“重构后代码”必须是完整可运行的函数片段而不只是局部几行第三也是最关键的——我会在prompt末尾追加一句“如果对原行为的某个细节不确定请保留原写法并在超范围提示中说明”。这一句能有效减少模型自作主张“优化”造成的隐性破坏。4.3 上下文窗口不够长文件被截断代码review时经常遇到一个函数几百行甚至一个文件上千行的情况直接粘进prompt很容易突破上下文限制或者让模型因为信息过载而输出质量下降。我常用的处理办法是“按函数拆分审查”让模型每次只review一个函数或一个独立模块而不是整个文件。如果函数之间有关联我会在prompt里用文字简单描述关联关系而不是把所有代码都塞进去。如果文件确实需要整体审查我就会采用“先整体扫一遍再聚焦关键函数”的两段式流程第一轮让模型输出“该文件的功能概览、模块间依赖、可疑风险点”第二轮再逐个函数深入审查。这样即使上下文窗口有限也能覆盖核心逻辑而不是因为塞不下而漏掉关键点。4.4 多轮对话后模型开始“自由发挥”prompt用很多轮之后模型有时会越来越“放飞”。比如在第二轮重构时它会无视第一轮确认的问题清单自己又追加了很多额外的改动。这是典型的多轮对话漂移问题。我的应对策略是在每轮新指令之前先重新粘贴一遍“微重构硬性规范”部分而不是默认模型记得上一轮的要求。虽然这会多占用一点token但稳定性提升非常明显。另一种做法是开一个新的对话窗口把上一轮的问题清单复制过去作为新对话的输入上下文。这比在同一条对话里不断追加指令要稳得多。4.5 输出结构不稳定清单一会儿是表格一会儿是列表模型输出格式不统一是prompt工程中最常见的问题之一。有时候它会跳出我定义的“### 审查结果”标题自己用小标题组织内容甚至直接讲一段话然后给代码完全不按模板来。我的处理办法是强化模板的引导不仅写清楚输出格式还在prompt里附一段“输出示例”给模型看一个短小的样例。比如### 审查结果 - [P1] login_attempt_check 函数中 uses comparison, check the boundary at max_attempts0 …模型看到具体示例后会非常忠实地模仿这种格式。我试过很多次加上输出示例之后结构稳定性大幅提升几乎不会再出现模板偏移。另外一个技巧是把“不要输出与模板无关的内容”写进prompt虽然这是一个比较弱的指令但在配合输出示例时会起正作用。5. 进阶调优与场景扩展5.1 根据项目语言微调审查维度同一个prompt模板在不同语言上使用时需要调整审查子项。比如审查Python代码时我会额外关注GIL影响下的多线程行为、是否用了可变默认参数、上下文管理器是否正确关闭资源审查JavaScript/TypeScript时则关注异步流里有没有未处理的Promise rejection、闭包有没有意外捕获循环变量、可选链和空值合并的使用是否合理审查Go时关注error有没有被吞掉、goroutine有没有泄漏、并发访问有没有加锁。这个“语言微调”做起来很简单只需要你在prompt的审查维度列表里增加对应语言的专项检查项。我习惯保留基础五维度在其下挂一个“本语言专项”小节跟随项目语言变化替换内容。这样不会丢失通用审查能力又能兼顾语言特性。5.2 结合单元测试让重构更有底气微重构最怕的就是“行为不变”这个承诺无法验证。要让这个机制更可靠一个很好的进阶做法是把prompt和测试结合起来。我现在的流程是在重构之前先让模型基于原代码的公共行为写几个最小化的测试用例只验证输入输出和异常路径然后在重构完成后手动运行这些测试确认结果完全一致。如果你用的是支持测试的仓库结构也可以把相关测试函数作为上下文贴给模型让它清楚哪些边界行为必须保持。实测下来测试先行能把重构后的“隐性回归”概率明显降低尤其是对那种长函数拆分的场景效果更好。没有测试时改动上线前一定要人工过一遍核心逻辑不要盲目信任模型的“行为不变”。这不是模型能力不行而是它对你业务语义的理解天然有盲区。5.3 从“单次审查”扩展为“团队规范落地工具”这个体验让我逐步扩展了prompt的使用场景不仅是帮自己审查代码还能把它当成团队代码规范的落地工具。你可以在prompt里附上团队自有的编码规范摘要比如禁止在循环里查询数据库、所有外部接口必须做超时控制、DTO不允许直接暴露内部字段等模型审查时会按照这些规则执行而不是通用的“建议性最佳实践”。这种方式尤其适合新成员接入团队的场景。新人写完代码后先用这套prompt自审一遍很多低级问题在提交人工review之前就被拦住了团队老师的压力也会小很多。我甚至见过一些团队把“用AI做前置自审”写进了PR合入检查清单的前置步骤不过不管怎么用核心还是那个原则模型给出的是“疑似问题”最终拍板和负责的仍然是开发者自己。6. 我的实际体会与踩坑记录6.1 prompt不是越长越好但关键约束绝不能再精简设计代码审查重构prompt时我最初的想法是把所有规则都写进一句话里以为这样够简洁。结果模型的输出随意得让我崩溃——它一会儿只审查不重构一会儿把整个函数重写一遍。后来我把硬性规范和输出格式从描述性文字改成了可操作的条目和模板效果立刻改善。但我也发现一个悖论我最早写的prompt有大量冗余段比如“你是一位资深的代码审查专家请通过你的专业能力帮助用户识别潜在风险”这类话除了占token之外基本没用。真正有作用的是明确的任务阶段、可解释的审查维度、强制的输出模板和边界约束。所以现在我的prompt文字不算多但每个元素都能对输出产生实际约束只有那些真正影响模型行为的规则才值得被保留。6.2 越关键的改动越要带着“怀疑式提问”去看模型输出用这个prompt工作了大半年之后我最大的心得是不要因为prompt写得好就相信模型的输出尤其是代码审查领域模型最大的风险是“一本正经地胡说八道”。它可能会在审查中给出一个看起来很专业的建议但落地后反而破坏了原有设计。我的习惯是对于标为P0或P1的建议一律打开源码重读一遍确认模型的判断依据是否成立。对于重构后的代码聚焦diff部分逐行检查重点关注异常路径和边界条件。省下来的时间主要花在“不用从零构思审查角度”和“快速生成标准化review意见”上而不是盲目全盘接受AI的结论。这个心态如果不摆正再好的prompt工具也挡不住线上事故。