让AI帮你写代码的安全准则
用AI写代码最好的方式,是让它在“猜测很危险”的那些环节慢下来。AI可以解释你不熟悉的代码、把报错变成可验证的假设、起草测试、审查改动、提出重构建议。它同样可能编造出不存在的接口、忽略隐藏的依赖、过度贴合你粘进去的那一小段代码,或者给出一个看着干净、却悄悄改变了你本想保留的行为的补丁。
用这条准则:AI负责提议,你的代码仓库说了算。真相来源是代码本身、能复现的失败用例、测试套件、运行日志、产品需求,以及人工审查。一个好的AI结对搭档应该帮你从这些材料出发去推理,而不是取代它们。
| 准则 | 为什么重要 | 该让模型做什么 |
|---|---|---|
| 先复现 | 避免瞎打补丁 | “先复述失败的行为和证据,再谈代码。” |
| 范围压到最小 | 降低回归风险 | “给出最小的安全改动,并列出涉及的文件。” |
| 保持行为不变 | 保护用户和接口契约 | “说出这次改动绝不能破坏的不变量。” |
| 必须有测试 | 让答案可验证 | “写出修复前失败、修复后通过的测试。” |
| 合并前审查 | 抓住那些很自信的错误 | “就正确性、安全性和遗漏的边界情况审查这份改动。” |
这在各家模型上都成立。OpenAI、Anthropic和其他服务商都会公布模型文档,说明各自的能力、上下文长度和工具调用方式。这些能力有用,但它们替代不了一套有纪律的流程。做工程时,用你评价同事的同一套标准评价模型:它会不会主动索要缺失的背景?会不会减少不确定性?会不会尊重约束条件?有没有留下你能核实的过程?
调试流程
一套可靠的AI调试流程有五个阶段:复现、定位、提出假设、打补丁、验证。不要一上来就说“帮我修一下”。从证据开始。把失败的命令、准确的报错、期望行为、实际行为、相关代码、环境信息,以及任何可能引发问题的近期改动,都交给模型。
阶段一:抓住复现过程。后端代码要带上请求、响应、状态码、日志和失败的测试。前端代码要带上路由、用户操作、浏览器控制台报错、网络响应、组件状态,必要时再加一句截图的文字描述。构建问题要带上命令、包管理器、Node版本,以及第一处失败前后的完整报错。
阶段二:先要假设,再要代码。一个谨慎的模型应该把可能的原因排个序,并说明每一条各有什么证据支撑。如果它分辨不出是哪个原因,就让它给出最小的诊断动作。可能是加一条日志、跑一个聚焦的测试、做一次类型检查,或者再读一个文件。
阶段三:要最小的补丁。明确告诉模型:不要重命名变量、不要顺手重写周边代码、不要引入新依赖、不要改变对外行为,除非它能说清理由。让它返回根因、补丁思路、涉及的文件、测试,以及风险。
阶段四:在本地跑测试。AI的输出不是验证环节。验证环节是那条能证明行为正确的命令或用户路径。如果没有现成的自动化测试,就先让模型写一个回归测试,再实现修复。
调试提示词:
请扮演一个谨慎的调试搭档。先不要写代码。首先复述复现步骤、期望行为、实际行为,以及三个最可能的根因。按证据强弱给每个原因排序。然后给出最小的诊断动作。缺陷:[描述]。命令或用户操作:[粘贴]。报错/日志:[粘贴]。相关代码:[粘贴]。约束:[技术栈、不要动的文件、必须保持的行为]。
修复提示词:
基于已确认的根因,给出最小的安全修复方案。请返回:根因、需要改动的文件与函数、补丁思路、修复前失败且修复后通过的测试、边界情况,以及回滚风险。不要重构无关代码。上下文:[粘贴]。
代码审查流程
AI当审查者,往往比当第一作者更好用。你让它审一份改动时,它能找出被漏掉的边界情况、安全问题、已经过时的假设、测试缺口和行为变化。关键是把审查要求写具体。你问“这样看着行吗”,得到的是客气的批准。你问正确性风险,才更可能得到有价值的反对意见。
把改动内容、预期行为、相关测试和各种约束都给模型。让它忽略无关紧要的代码风格,除非那会影响可维护性。你要的是优先揪出缺陷的审查,而不是做样子的鸡蛋里挑骨头。
| 审查维度 | AI应该回答的问题 |
|---|---|
| 正确性 | 这份改动真的满足需求了吗? |
| 回归风险 | 哪些既有行为可能被意外改变? |
| 安全性 | 输入、鉴权、密钥、权限和注入风险处理好了吗? |
| 错误处理 | 遇到空值、超时、重试、异常响应或中间状态会怎样? |
| 测试 | 哪些行为主张还没有被覆盖? |
| 可维护性 | 是否遵循了本项目的既有写法,改动是否易懂? |
代码审查提示词:
请像一位严格但务实的维护者那样审查这份改动。重点看正确性、回归风险、安全性、边界情况和缺失的测试。除非会带来真正的维护风险,否则忽略细枝末节的风格问题。返回一张表:问题、优先级、改动中的证据、建议的修复、需要补的测试。预期行为:[粘贴]。改动内容:[粘贴]。现有测试:[粘贴]。
对于高风险改动,可以在Whizi里用“对比多个模型的修复方案”这套做法。把同一条审查提示词分别跑在两三个模型上。如果某个模型指出了一个可能的问题,别盲目接受,回到代码里确认这个问题是否真实存在。目的不是收集更多意见,而是在合并之前把审查覆盖面铺得更宽。
重构与测试流程
用AI重构有风险,因为很多重构的好坏是由“什么没有变”来评判的。模型可能把代码变得更漂亮,同时悄悄改动了行为、错误处理、时序或对外契约。更安全的重构流程,是在动实现之前先把不变量定义清楚。
第一步:说清重构目标。比如:减少重复、拆分过大的组件、隔离数据访问、简化分支逻辑、迁移一层API封装,或者提升可测试性。然后明确哪些必须保持不变:对外函数签名、路由行为、事件名称、响应结构、数据埋点、权限、无障碍行为,以及性能预期。
第二步:要一份分阶段的计划。好用的AI重构计划应该是可回退的。每个阶段只动一小片区域,都带测试,并且都能产出一个可运行的中间状态。除非代码很小且测试覆盖良好,否则别一口气整体重写。
第三步:先写行为固化测试。改代码之前,先让AI梳理当前行为,并起草一批测试把重要情形锁定下来。这类测试对意图不明的历史代码尤其有用。它们应该覆盖常规输入、边界输入、失败路径,以及一个与本次重构起因直接相关的回归用例。
第四步:一次只落地一个阶段。每个阶段完成后跑测试,并要求一次聚焦的审查。如果模型提出了一个大而全的抽象,让它先证明这个抽象确实消除了真实的重复或风险。否则就让代码保持朴素、保持局部。
重构规划提示词:
请给出一份分阶段的重构计划。目标:[目标]。当前代码:[粘贴]。约束:保持对外行为不变、尽量少改动、遵循既有写法、不引入新依赖、每个阶段都可测试。返回:不变量、依赖关系图、阶段划分、涉及的文件、每个阶段的测试、回滚风险,以及审查清单。
单元测试提示词:
在修改实现之前先写测试。请沿用这里展示的现有测试写法:[粘贴]。必须保持的行为:[粘贴]。被测代码:[粘贴]。返回测试名称、准备工作、输入、期望结果,以及每个测试为什么重要。包含正常路径、边界情况、错误情况和回归用例。
提示词模板
好的编程提示词写得长,不是因为花哨,而是因为要长到足以消除歧义。模型需要角色、任务、上下文、约束、输出格式和验收标准。把管用的提示词存下来,AI才会变成一套可复用的工程流程,而不是一次性的闲聊。
解释代码的提示词:
请为一位刚加入这个项目的开发者解释这段代码。涵盖用途、输入、输出、数据流向、依赖、失败模式,以及哪些测试能提升信心。把代码里能直接看到的事实和你的推测分开写。代码:[粘贴]。
安全审查提示词:
请审查这段代码的安全风险。重点关注鉴权、权限、注入、密钥、校验、不安全的跳转、文件处理、依赖风险和敏感数据泄露。只返回有证据支撑的问题,并附上影响、建议的修复,以及对应的测试或人工检查方式。代码/改动:[粘贴]。
对比模型修复方案的提示词:
我在为一个编程任务对比不同的AI模型。只使用我提供的上下文。返回根因、最小的安全修复、测试、风险、你所做的假设,以及你的疑问。用1到5给你的把握程度打分,并列出哪些证据会让你改变答案。任务:[粘贴]。上下文:[粘贴]。
接受AI生成的代码之前的质量检查清单:
- 模型正确复述了任务。
- 补丁比问题小,而不是更大。
- 明确点出了对外行为和契约。
- 测试直接覆盖了这个缺陷或重构目标。
- 列出了边界情况和失败路径。
- 涉及安全的输入已被审查。
- 改动遵循了项目既有的写法。
- 你确实跑过相关的测试、检查、构建或手工复现。
- 最终改动经过了人工审查。
当你想在不改变任务的前提下对比修复方案时,Whizi很好用。把同一条调试或审查提示词粘到多个模型里,再按证据、改动范围、测试和风险给结果打分。如果你想先挑模型,可以从适合写代码的ChatGPT替代品看起,在价格页对比各个方案,或者注册一个账号,把这套流程跑在你自己的代码上。
- 从一个真实的复现开始,而不是一句含糊的缺陷描述。
- 先要假设和证据,再要代码。
- 要求给出最小的安全修复,并列出涉及的文件。
- 重构之前,先定义哪些行为绝不能变。
- 在信任这个补丁之前,先写好或更新测试。
- 就正确性、安全性和边界情况审查AI生成的改动。
- 把同一条高风险提示词跑在多个模型上,在Whizi里对比修复方案。
- AI辅助写出的代码,合并前要经过人工审查。
常见问题
怎样安全地用AI写代码?
把AI当成一个提供方案、测试和审查意见的结对搭档。从复现开始,要求最小的补丁,跑测试,合并前审查改动。不要默认生成的代码就是对的。
AI能帮忙调试代码吗?
能。AI很擅长把报错、日志和代码转化成可能的根因。最安全的调试顺序是:先要假设,再要一个诊断动作,然后才是最小修复和回归测试。
AI能写单元测试吗?
AI可以起草单元测试,但你要明确要求它覆盖清楚的行为。让它给出正常路径、边界、错误和回归四类用例,然后确认这些测试在修复前会失败、修复后会通过。
写代码最好的AI模型是哪个?
最合适的模型取决于任务和代码库。把同一条提示词用在调试、审查和重构上跑遍几个模型,然后选那个证据最清楚、改动范围最小、测试最扎实的答案。