多角色AI代码审查实战:三份提示词让大模型精准揪出漏洞
我最近让 AI 帮我 review 一段登录模块的 Python 代码它回我一句“整体逻辑清晰部分地方建议优化”然后列了几条不痛不痒的“变量命名可以更清晰”之类的废话。那一刻我明白了不是大模型不能审代码是我的问法太懒了。后来我把提示词改成“让 AI 扮演三位专家轮流审”——一个挑刺、一个找漏洞、一个补测试效果完全不一样真的翻出了两个潜在的安全问题和一个边界条件 bug。这篇文章就聊聊这套多角色代码审查的方法三份可以直接抄的专家提示词、完整的实操流程、以及我踩过的坑。适合想让大模型真正帮自己检查代码、又不想被“正确的废话”糊弄的开发者和安全测试人员。文章里没有藏着掖着的理论全是能直接用的东西。1. 为什么让 AI 换三个专家身份审代码而不是一次性问它“帮我看看”很多人的第一反应是AI 那么强直接问它“这段代码有什么问题”不就完了吗实测下来的结论是不行。这不是模型能力问题是提问方式问题。1.1 一次普通提问得到的往往是“阳光版”回答大模型默认的输出策略是“礼貌且有帮助的”。你让它“帮我看代码”它会倾向给一个折中的、积极的反馈——因为你没说希望它挑刺它就不会主动把自己切换到“毒舌模式”。于是你拿到的基本是代码整体结构不错建议增加单元测试注意变量命名……这种话你让实习生看一眼代码也能写出来。更麻烦的是普通提问下模型会自行选择关注点。同一段代码这次它可能盯着性能下次它盯着命名再下次它突然聊起架构。审查结果不稳定没有统一标准你就没法依赖它发现深层问题。1.2 角色分离的本质把大模型的“好人”人格锁起来用角色扮演提示词本质上是把大模型的默认人格“关掉”强制它加载另一套行为模式。你告诉它“你是一个尖刻的、有 10 年经验的资深工程师你的任务是在这段代码里找出所有问题并且不许客套”它的输出风格和关注点就会随即切换。这个机制在认知科学上有个通俗的解释人收到不同的任务指令大脑会激活不同的知识网络。大模型也是类似的——给它不同角色它调用的“知识分布”就不同。挑刺专家会优先关注逻辑分支和边界条件漏洞专家会优先关注输入验证和攻击面测试专家会优先关注覆盖率和用例设计。三双眼睛看的是同一段代码但看到的完全是不同的东西。我把三个专家的分工做成了一张对照表方便理解角色定位核心关注点典型输出挑刺专家逻辑正确性、边界条件、代码风格、性能隐患带行号的问题列表 修改建议漏洞专家安全风险、攻击路径、OWASP/CWE 分类CWE 编号 风险等级 修复示例测试专家测试覆盖盲区、用例设计、CI 集成建议测试用例表格、输入输出矩阵这三个角色不是重复劳动而是互补覆盖。逻辑审查查的是“这代码在正常情况下跑得对不对”漏洞审查查的是“这代码在恶意输入下会不会崩”测试审查查的是“哪些场景根本没人验证过”——三者交集之处才是真正的代码质量盲区。1.3 到底怎么定“人设”才能让 AI 不客套、不跑偏这里有个小技巧值得单独说。给角色的描述不能太短比如只说“你是代码审查专家”是不够的。模型会认为这句话只是一个角色标签行为上不会产生质的改变。要给它一个“任务边界、行为规范、输出格式”三合一的完整设定。任务边界告诉模型这次审什么行为规范告诉模型不许说什么、必须说什么输出格式决定它是给列表、表格还是带行号的报告。三者齐全模型的输出才会真正有用。后文我会给出三份完整的提示词模板直接复制改成你的项目就行。2. 三位专家的提示词设计三份可直接复制的模板这套方法的核心资产就是提示词。我用过很多版本下面这三份是目前效果最稳定的。2.1 挑刺专家先把“逻辑怪怪的”变成具体问题挑刺专家的提示词我这样写现在你是一位有 10 年一线开发经验的资深软件工程师性格直率讲究逻辑讨厌废话。下面我会给你一段代码请你以代码审查Code Review的方式审查它。 审查维度 1. 逻辑错误与边界条件空值、越界、数值溢出、并发竞争、资源未释放等 2. 可维护性命名是否表意、函数是否过长、职责是否混乱、是否存在重复代码 3. 性能隐患不必要的循环、重复计算、N1 查询、缓存使用不当 4. 异常处理是否吞掉了异常、错误分类是否合理、是否有恢复机制 输出要求 - 每条问题按严重程度分级使用“严重 / 中等 / 轻微”三级 - 每条问题给出所在位置函数名或具体行号、问题描述、修改建议 - 某一方面确实没有问题就直接跳过不要写“这方面表现良好”这类客套话 - 严禁输出“仅供参考”“建议优化”等无意义表述所有建议必须具体可执行这里的关键是“严禁输出无意义表述”这一条。不加上这句话模型还是会忍不住写一些正确的废话。加上之后输出会明显变得更尖锐、更具体。我试过把同一段带空指针隐患的代码分别用普通提问和这个提示词去测。普通提问下模型甚至没有提到那段可能空指针的代码用挑刺专家提示词后它不仅指出了空指针还补充了“当列表为空时会直接报 IndexError而调用方并没有捕获它”——这是靠代码逻辑推演才看得出来的。2.2 漏洞专家让 AI 戴上安全审计的眼镜安全审查比逻辑审查更依赖“专业视角”因为有些漏洞在正常逻辑下完全看不出来只有在特定攻击场景下才会触发。漏洞专家的提示词现在你是一位资深应用安全工程师精通 OWASP Top 10、CWE 漏洞分类和渗透测试。我将给你一段代码请以安全审计的方式检查它。 重点排查方向 - 注入类SQL 注入、命令注入、代码注入重点看用户输入是否被直接拼接进敏感操作 - XSS 与输出编码前端输出是否转义、是否使用了 innerHTML 等危险方法 - SSRF外部 URL 是否可控、是否缺少协议和域名限制 - 路径穿越文件路径拼接是否规范化、是否使用 os.path.realpath 校验 - 反序列化是否反序列化了不可信数据、是否缺少类型校验 - 越权访问接口是否校验用户身份与资源归属 - 敏感信息泄露硬编码密钥、Token 泄露、日志中打印敏感数据 输出要求 - 每条安全问题标注 CWE 编号与风险等级高/中/低 - 用一句话描述攻击者如何利用该问题例如构造什么样的 payload - 给出修复建议并附上修复后的关键代码示例 - 如果没有发现某个方向的问题直接跳过该方向不要写“未发现安全隐患”“用一句话描述攻击者如何利用”是整份提示词里最出效果的一条。因为大模型被要求“讲一个攻击故事”它就必须把代码执行流程推演一遍推演过程中容易发现逻辑断点。我遇到过一次很典型的场景一段下载文件的接口普通检查完全看不出问题但漏洞专家提示词直接推演出“文件名来自 URL 参数攻击者传 ../../etc/passwd 就能读到服务器任意文件”判断依据是 CWE-22 路径穿越——这就是角色设定对输出质量的提升。2.3 测试专家问“有没有测试”太基础要问“盲区在哪”最后一个专家是测试专家。很多开发者自己写代码不写测试让 AI 补测试的价值就在这。但要让它真正帮上忙问题不能只停留在“请帮我写测试”。现在你是一位测试架构师擅长单元测试、集成测试和测试用例设计。请为以下代码设计一套完整的测试补充方案。 任务步骤 1. 分析被测代码的输入域与输出域 2. 找出当前测试覆盖的盲区happy path 之外的分支、异常输入、边界值、空值 3. 设计测试用例覆盖正常流程、异常流程、边界条件、并发场景、安全场景 4. 给出最小必要测试集标注每个用例应当放到单元测试层还是集成测试层 输出要求 - 用 Markdown 表格输出测试用例包含字段用例名称、测试数据、预期结果、对应检查点 - 对每个用例补充一句说明解释“为什么测这个” - 如果被测代码没有现有测试直接给出最小测试集即可不要先批评代码没有测试注意最后一条“不要先批评代码没有测试”——这是防止模型跑偏的关键约束。我最初版本没有这句话结果模型花了三分之一篇幅在讲“这段代码测试覆盖率为零非常危险建议立即补充”正事没干多少。加上约束后它就老实输出用例表格了。2.4 三份提示词的共同点可量化、可定位、禁止空话回头看这三份提示词它们的骨架是相同的可以提取成一套通用公式角色加载明确资历与性格审查维度清单告诉模型看哪几类问题输出格式要求分级、定位、给出建议禁止事项不许客套、不许空谈、不许跑题这套公式适用于任何代码审查场景。你可以把维度清单换成大数据性能、前端兼容性、算法复杂度甚至换成去审查一段 SQL 脚本模板都不会失效。这也是我觉得这套方法比单个“代码审查”提示词更值得分享的原因——它不是死板的一招而是一种可迁移的思维框架。3. 实操全流程从贴代码到输出一份能用的审查报告提示词有了接下来是操作流程。我自己迭代过好几轮下面的流程是效率最高、结果最稳定的一版。3.1 喂代码前的关键一步用一段话交代背景很多人直接把代码扔给 AI然后问“有问题吗”。这种做法的误差很大。大模型不了解你的代码是干什么的、目标是什么环境、哪个部分是核心逻辑它就只能在通用层面提建议。我会在贴代码之前先给一段 Context例如这是一个 Flask 写的文件下载接口Python 3.10运行在 Linux 服务器上。 核心逻辑是 verify_token - read_file - send_file其中 verify_token 校验用户身份 read_file 按文件名读取服务器本地文件。 重点关注登录绕过和文件读取的安全性另外函数 read_file 的边界条件请重点检查。给大模型交代的项目背景其实和给新入职同事交代的背景是一样的它的职责边界、核心流程、你最担心的风险点。模型带上这些信息后再审代码就不会出现“这段代码应该加数据库索引”这种八竿子打不着的建议。3.2 跑了三轮分别拿到三份报告实操时我会开三个独立的对话窗口或者在一个对话里分三段进行。推荐用三个独立窗口因为独立上下文可以避免角色之间互相干扰。第一轮贴代码 挑刺专家提示词等它输出问题清单。第二轮贴同样的代码 漏洞专家提示词。这里要说个经验第二轮我会把第一轮的输出“藏起来”不提前让漏洞专家看到。否则它会顺着挑刺专家的思路走丧失了独立视角。三个角色独立审查再合并结果效果最好。第三轮贴代码 测试专家提示词。测试专家的输出是一张用例表格这时候我通常会让它结合代码的实际情况给出测试数据示例而不是只写“测试数据空字符串”这种干巴巴的描述。实际跑下来一轮的时间大概是挑刺专家 3060 秒漏洞专家 6090 秒测试专家 60 秒左右。整个流程 5 分钟内可以完成而人工 review 同样的代码至少要 20 分钟以上而且不一定想得这么全。3.3 第四步让 AI 当主持人把三份报告汇总排序三份报告拿在手里信息量很大但比较零散。挑刺专家列了 12 条漏洞专家列了 5 条测试专家列了 20 个用例。哪几个是马上要处理的哪几个是随手改了就行这时候我会再开一个对话把三份报告一起贴进去用一段汇总提示词你是项目经理。这是三位工程师分别 review 同一段代码后的输出 [贴三份输出] 请合并去重按以下优先级给出一份总报告 一、必须立即修复存在安全风险或会导致功能崩溃 二、建议本轮修复明显的逻辑 bug 三、可以后续优化风格、结构、测试补充 对每一个问题标注来源来自挑刺/漏洞/测试并在表格最后列出“当前已有的测试用例清单”。这一步很像让三个专家坐在一起开会AI 当主持人。它做的工作主要是去重和排序模型对这两类任务完成度很高基本不需要人工再整理格式。最终拿到手的就是一份可以直接照着改代码的问题清单。我自己跑完整个流程后有个很直观的感受单独用任意一个专家都会有漏检三个专家加汇总所有类型的问题都能被覆盖到。有一次在同一个接口里挑刺专家发现了“sess 查询可能返回 None”漏洞专家发现了“用户传入的 product_id 直接拼进 SQL”测试专家发现了“价格字段没有测过负数”。这三类问题如果只问一次 AI最多被问出来一条还大概率是最不痛不痒的那条。4. 避坑实录AI 审查常见的五个坑方法好用归好用坑也不少。这部分是我实际踩过的整理成了五个高频问题。4.1 最大的坑AI 会一本正经地胡说八道大模型存在幻觉问题在代码审查场景里表现得尤其隐蔽。它会引用一个根本不存在的 CVE 编号可能会说“这里存在 CVE-2024-38819 漏洞”但细看代码根本没有对应风险它还可能编造行号说第 45 行有问题但你的代码总共才 30 行。遇到 AI 输出的安全问题必须人工验证。我的验证方法是先看它说的位置是否存在再按它描述的攻击路径在本地写一个最小复现脚本能打穿才算数。有一次它信誓旦旦说“这里的 SQL 拼接可被注入”我跟踪下去发现参数被框架的 ORM 参数化了根本不存在注入风险。所以记住这句话AI 审查是放大器不是裁决者。它的输出必须经过一次人工复核才配叫结论。4.2 单轮审查覆盖面太窄要用“多轮追问”逼出细节第一次跑出来的报告往往只能覆盖 60% 的问题。剩下 40% 藏在细节里需要追问逼出来。我常用的追问句式- “针对上面第 3 条攻击者还有哪些变体 payload 能绕过建议的过滤器” - “这个函数在并发调用下会怎样请推演 10 个线程同时访问的场景。” - “如果上游依赖升级到 2.0 版本这段代码会出什么问题”这种追问本质上是在逼模型做“思维链推演”。它被迫把执行路径一步步展开很多平时收敛在概率分布里的问题会被显式地暴露出来。4.3 代码太长喂不进去怎么办按函数维度拆而不是按行数拆上下文窗口有上限一次塞整个项目不现实。我的做法是只挑核心文件的关键函数喂而不是把整个文件复制进去。比如审查一个 Web API我会抽四个部分路由入口函数、数据库查询函数、文件处理函数、鉴权函数。每个函数单独跑一轮三个专家耗时翻倍但效果值得。还有一个替代方案先用普通提问让 AI 输出“这份文件的函数清单”再按清单批量投喂效率更高。对于超过上下文窗口的较大项目也可以用“分层审查”先审路由层再审服务层最后审数据层。每一层单独出报告汇总时按模块归档。这个方式比一次性硬塞更贴合实际代码审查的粒度。4.4 新版代码和旧版代码混着喂模型会彻底混乱有一次我把两个版本的同一文件同时贴给了 AI想让它对比差异结果它输出了一份逻辑上完全矛盾的审查报告——一会说“第 40 行调用了 validate_params”一会说“该函数不存在”。原因就是我贴进去的两个版本接口签名不一样模型不知道以哪个版本为准。解决方法是保持单一版本审查如果要对比版本差异让模型分离成两次审查最后人工对比。这个坑很容易被忽略因为模型不会告诉你它混乱了它只会自信地给出一个混乱的答案。4.5 别把 AI 的结论直接刷进工单或者 commit 信息里最后一点也是团队协作中最容易出问题的点。我见过有人拿 AI 的审查报告直接贴到代码评审系统里当评论结果被同事指出来“第 3 条说得不对”。我自己的处理方式是把 AI 输出当草稿经人工确认后用自己的语言重新组织一遍再提给别人。这不仅是面子问题更是责任问题——AI 的分析作为参考有价值但它不是权威也不会为你的代码负责。这里我整理了一张常见问题速查表方便对照排查现象可能原因解决方式输出全是客套话提示词缺少“禁止空话”约束加上“严禁输出毫无意义的表述”指出的问题对不上代码上下文里混入了旧版本只保留单一版本代码再喂漏洞描述模糊没有攻击路径没要求攻击场景描述提示词中增加“用一句话描述攻击者如何利用”覆盖率低、漏了很多问题单轮提问、没有追问用多轮追问逼出细节三个专家的报告互相矛盾各专家关注维度不同正常现象用汇总步骤去合并排序5. 实测效果与扩展玩法用这套方法跑了小半年覆盖了登录接口、文件上传、订单支付逻辑、后台数据导出这几个常见场景全部都有真实收获。最夸张的一次是漏洞专家在一段文件上传代码里发现了一个没有限制文件类型的接口攻击者可以直接传一个 .html 文件上去变成存储型 XSS——这个要是真上线后果够喝一壶的。挑刺专家还顺手发现上传的文件名没有随机化处理会覆盖同名文件这俩问题加一起基本把一个高危漏洞讲透了。当然也不是没遇到过失手。有一次测试专家设计了一堆用例结果我看完发现它针对的函数根本不是代码里的函数——它根据函数名自己脑补了一个逻辑。所以测试专家的输出我一般只看用例设计思路具体测试数据是否匹配代码还是得人工确认。5.1 扩展玩法一让 AI 模拟“攻击者”来反驳自己审完一轮后我会追加一个刁钻问题现在你是攻击者这段代码是你的目标。请针对上述安全修复方案 思考至少 3 种绕过方式然后评估现有修复是否站得住。这个提问相当于做了一次“红队复盘”。模型会主动寻找修复方案的盲点补上第一轮审查的缺失。我多次用这招发现修复方案本身不完整比如只过滤了单引号没过滤双引号、只限制 URL 协议没限制内网地址之类。5.2 扩展玩法二把三专家流程做成一个自动化脚本这套流程其实可以脚本化。用 Python 调大模型 API把“代码 三段提示词”拼成固定模板跑完合并出 Markdown 报告。我试过用 LangChain 的链式调用来做每一步一个 Prompt最后汇总效果很稳定。考虑到现成工具很多即便不写代码市面上主流的大模型客户端也都支持多轮对话和自定义提示词手动操作完全够用。5.3 扩展玩法三适配不同语言和框架提示词里的审查维度可以根据语言特性做微调。审查 Go 代码时我会加“goroutine 泄漏”和“channel 误用”审查前端 JavaScript 时会加“闭包变量泄漏”和“事件监听未销毁”审查 Solidity 合约时会加“重入攻击”和“整数溢出”并配合实际案例中的典型问题类型去验证。三个角色框架不变只换维度清单十几秒就能生成一套适合新语言的新提示词。最后再分享一个小技巧审查完成后我会把“问题清单 修复方案”喂回模型让它“给自己两周后的自己留一句话”总结这些代码最容易在未来上线后爆雷的地方。这句话我会写进代码仓库的 README 备注里提醒以后的维护同事。这个用法有点取巧但实际效果比写一大段抽象文档有用得多——因为它帮你把这次审查浓缩成了一段“未来预警”。