AI代码审查
本章要点
在前面几章,我们已经学会了让 AI 生成代码、解释代码,以及在代码出问题时借助 AI 调试。这一章,我们来聊另一种同样重要、却更容易被忽视的技能:代码审查。
代码审查,英文叫 Code Review。在专业团队里,这是一个正式的流程——你写完代码之后,要给同事看,让他们检查是否有问题,确认没问题后才能合并到主代码库。它的意义在于,一个人写代码,难免有盲点。多一双眼睛,就多一层保障。
但现实是,很多独立开发者、初学者,甚至小团队,并没有这个条件。你可能是一个人在做一个项目,没有同事可以帮你看代码。或者,即使有同事,他们也未必有时间或精力仔细审查每一段代码。
这就是 AI 能够发挥作用的地方。AI 就像一位随时待命的代码审查员——耐心、细致,而且从不嫌你烦。
读完这一章,你会获得:
- 理解代码审查的价值:为什么代码审查是写好代码的关键一环
- 掌握让 AI 进行代码审查的方法:怎么问、问什么,才能得到有价值的反馈
- 学会辨别 AI 反馈的优先级:哪些问题必须改,哪些可以暂时搁置
- 建立一套可持续的代码审查习惯:把 AI 审查融入你的日常开发流程
为什么代码审查如此重要
在学习如何让 AI 审查代码之前,我想先说清楚一件事:为什么要做代码审查?
很多初学者会觉得,代码能跑就行。但随着你写的代码越来越多,你会渐渐发现:能跑的代码,和好的代码,是两件完全不同的事情。
代码是写给人看的
有一句话在程序员圈子里广为流传:代码是写给人看的,只是顺便让机器执行而已。
这话听起来有点夸张,但背后的道理是真实的。你写的代码,不只是今天的你要看,还有:
- 未来的你:三个月后,当你回来修改这段代码时,还能看懂吗?
- 合作的同事:如果有人要接手你的项目,他们能理解吗?
- 调试时的你:出了问题,你能快速定位到问题所在吗?
一段好的代码,即使没有注释,也应该像一篇流畅的文章一样,让读者轻松理解它的意图。而糟糕的代码,就算"能跑",也会像一团缠绕的毛线,一旦需要修改,就会让人头疼不已。
代码质量决定项目寿命
在软件工程里,有个概念叫"技术债"(Technical Debt)。它的意思是:为了追求短期效率,写了质量不高的代码,虽然当时解决了问题,但欠下了"债"——未来你需要花更多时间偿还这些债,比如重构、修复 bug、理解遗留代码。
技术债积累到一定程度,会让项目举步维艰。这时候,哪怕只是加一个小功能,也可能需要改动大量代码,稍不注意就引发新的 bug。很多项目最终被推倒重来,很大程度上就是因为技术债太重。
代码审查,是控制技术债最有效的手段之一。它能在问题还小的时候就发现并解决,而不是等到积重难返。
审查的层次:从表面到深层
代码审查可以发现很多类型的问题,从简单到复杂,大致分为几个层次:
第一层:风格与规范。 变量命名是否清晰?缩进是否一致?代码格式是否统一?这些看起来是小事,但统一的风格能大幅提高代码可读性。
第二层:逻辑与正确性。 代码的逻辑是否正确?是否有遗漏的边界情况?比如,函数处理了空列表吗?当用户输入负数时会怎样?
第三层:性能与效率。 代码是否有不必要的重复计算?数据结构的选择是否合适?在小数据量下看不出差距,但当数据量大时,一个低效的算法可能让程序慢上百倍。
第四层:安全性。 是否有 SQL 注入的风险?用户输入是否经过了验证?密码是否以明文存储?安全问题往往是最难被发现的,因为它们不影响正常运行,只有在被攻击时才会暴露。
第五层:可维护性与设计。 代码结构是否合理?是否有重复的逻辑应该被抽象?函数是否承担了太多职责?
传统上,这些层次的检查都依赖有经验的开发者。而 AI 的强大之处在于,它能同时扫描所有层次,就像一位拥有全面知识的资深工程师。
让 AI 进行代码审查的正确方式
明白了代码审查的价值之后,我们来谈最重要的问题:如何让 AI 给出有价值的代码审查反馈?
这里有一个关键认识:你的提问方式,决定了 AI 审查的深度和质量。
如果你只是把代码扔给 AI,说"帮我审查一下",你可能得到一份泛泛的反馈,没什么实际价值。但如果你提供了足够的上下文,明确了审查的重点,AI 就能给出针对性强、可操作的建议。
提供足够的上下文
AI 不了解你的项目背景。一段代码,脱离上下文,可能有很多种解读方式。你需要告诉 AI:
- 这段代码的用途是什么? 它实现了什么功能?在整个项目中扮演什么角色?
- 谁会使用这段代码? 是内部工具还是面向用户?是个人项目还是生产环境?
- 有什么特殊要求吗? 比如,性能要求特别高、安全性特别重要,或者需要考虑国际化?
有了这些背景,AI 才能做出有针对性的判断。比如,一个只在本地运行的脚本,和一个处理用户数据的 Web API,对安全性的要求完全不同。AI 需要知道这些区别,才能给出适合你场景的建议。
明确审查的重点
你可以根据需要,让 AI 重点审查某个方面:
请帮我审查这段代码,重点关注以下几点:
1. 代码是否有安全漏洞(比如 SQL 注入、XSS 等)
2. 错误处理是否完善
3. 是否有明显的性能问题
代码背景:这是一个处理用户登录的 API 端点,会直接暴露在公网上。
代码如下:
[代码]
这种结构化的请求,能让 AI 知道你最关心什么,而不是泛泛地扫描一遍。
一次审查一个焦点
很多人习惯一次性把所有代码扔给 AI,让它全面审查。这样做固然可以,但效果往往不如集中火力更好。
更好的做法是:把代码审查分成几个专项。比如,一次专门审查安全性,一次专门审查性能,一次专门审查代码结构。每次的目标都非常明确,AI 给出的反馈也会更加深入。
就像体检一样,你可以做一个全面体检,也可以针对某个症状做专项检查。专项检查往往更精准。
全面审查:让 AI 扫描所有问题
首先,我们来看如何让 AI 进行一次全面的代码审查。这适合在你完成了一个功能之后,想对代码做一次整体检查的场景。
标准的全面审查请求
下面是一个效果比较好的全面审查请求模板:
请帮我对以下代码进行全面的代码审查。
**代码背景:**
[说明这段代码的功能、使用场景、技术栈]
**请从以下维度进行审查:**
1. 正确性:逻辑是否正确?是否有遗漏的边界情况?
2. 可读性:变量命名、代码结构是否清晰?
3. 安全性:是否有安全漏洞?
4. 性能:是否有明显的性能问题?
5. 可维护性:是否有可以改进的代码结构?
**请对每个问题:**
- 说明问题所在(引用具体的行或代码片段)
- 解释为什么这是个问题
- 给出改进建议
代码如下:
[代码]
一个完整的示例
让我用一个真实的例子来说明。假设你写了以下 Python 函数,用于从数据库查询用户信息:
def get_user(username):
conn = mysql.connector.connect(
host="localhost",
user="root",
password="123456",
database="myapp"
)
cursor = conn.cursor()
query = "SELECT * FROM users WHERE username = '" + username + "'"
cursor.execute(query)
result = cursor.fetchone()
return result
你把这段代码交给 AI,加上背景说明:"这是一个 Web 应用的用户查询函数,通过用户名从数据库获取用户信息,用户名来自前端输入。"
AI 可能会给出这样的审查反馈:
发现了 4 个重要问题:
🔴 严重:SQL 注入漏洞 第 6 行:
"SELECT * FROM users WHERE username = '" + username + "'"你直接把用户输入拼接进 SQL 语句,攻击者可以输入' OR '1'='1绕过验证,甚至用'; DROP TABLE users; --删除整张表。 修复: 使用参数化查询:cursor.execute("SELECT * FROM users WHERE username = %s", (username,))🔴 严重:数据库密码硬编码 第 3-4 行:数据库用户名和密码直接写在代码里。一旦代码被分享(比如传到 GitHub),所有人都能看到你的数据库密码。 修复: 使用环境变量存储敏感信息:
password=os.environ.get("DB_PASSWORD")🟡 中等:数据库连接没有关闭 函数执行完毕后,
conn和cursor没有被关闭。长期运行会导致连接泄漏,最终耗尽数据库的连接数。 修复: 使用try...finally或with语句确保连接被关闭。🟡 中等:返回了全部字段
SELECT *会返回用户的所有字段,包括密码哈希等敏感信息。这不仅浪费资源,还增加了数据泄露的风险。 修复: 只查询需要的字段:SELECT id, username, email, created_at
这个例子展示了 AI 能做什么:它不只是发现了 bug,还解释了为什么这是个问题,以及具体怎么修复。这正是一个优秀代码审查员的价值所在。
专项审查:深挖特定维度
全面审查好比体检,而专项审查则是针对某个器官做精密检查。当你对某个方面有特别关注时,专项审查能给出更深入的分析。
安全性审查
对于涉及用户数据、网络请求、文件操作的代码,安全性审查尤为重要。
请对以下代码进行安全性专项审查。
代码用于处理用户文件上传,部署在公网服务器上。请检查:
- 是否有路径遍历漏洞(Path Traversal)
- 文件类型验证是否安全
- 是否有文件大小限制
- 上传的文件是否可能被当作代码执行
- 其他潜在的安全问题
[代码]
性能审查
当你的代码需要处理大量数据,或者响应时间有要求时,性能审查很有价值。
这个函数需要处理几万条记录,目前运行非常慢(处理 1 万条需要约 30 秒)。
请帮我分析:
- 当前代码的时间复杂度是多少?
- 哪里是性能瓶颈?
- 有哪些具体的优化方案?
- 优化后大概能提升多少性能?
[代码]
可读性与可维护性审查
当你想提高代码质量、减少未来的维护成本时,这类审查很有帮助。
这段代码是我六个月前写的,现在回来修改时发现很难读懂。
请帮我分析:
- 哪些命名不够清晰,如何改进?
- 哪些函数承担了太多职责,应该如何拆分?
- 哪些重复代码可以被抽象?
- 整体结构是否有改进空间?
[代码]
错误处理审查
健壮的错误处理,是区分"学习项目"和"生产级代码"的重要标志之一。
请帮我审查这段代码的错误处理机制。
这是一个用户数据处理流程,需要保证数据不丢失,即使中间某一步失败也要有记录。
请检查:
- 所有可能抛出异常的地方是否都有处理?
- 错误信息是否足够详细,方便调试?
- 是否有数据一致性的风险(比如,某步失败后数据处于半更新状态)?
- 是否需要重试机制?
[代码]
理解和辨别 AI 的审查反馈
AI 给出反馈之后,你需要知道如何看待这些反馈。不是所有的建议都应该立刻执行,也不是所有的建议都是正确的。
按优先级处理反馈
我建议你把 AI 的审查反馈分为三个级别来对待:
必须立即修复(P0): 这类问题直接影响程序的正确性或安全性。比如 SQL 注入漏洞、密码明文存储、数据类型错误等。这些问题如果上了生产环境,可能导致数据泄露、系统崩溃或安全事故。发现之后,必须立刻处理,不能拖延。
应该尽快处理(P1): 这类问题不会立即造成危害,但会影响代码质量和长期维护。比如缺少错误处理、命名不清晰、明显的性能问题。这些问题应该在下一个开发周期内处理。
可以酌情改进(P2): 这类问题是风格或设计层面的建议,改了会更好,但不改也不会有立即的负面影响。比如,"这个函数可以用函数式风格改写"、"可以用更简洁的语法"。对于这类建议,你可以根据项目的实际情况决定是否采纳。
质疑不合理的建议
AI 的建议不一定总是正确的,也不一定适合你的场景。你需要有自己的判断。
有时候,AI 会给出一些技术上"更优"但脱离实际的建议。比如:
- 你写了一个简单的个人脚本,AI 建议你加上完整的日志系统、异常监控、单元测试——这些建议本身没错,但对于一个小脚本来说,投入产出比太低了
- 你的代码依赖某个特定的框架或环境,AI 给出的建议却假设你用的是另一种技术栈
- AI 建议重构整个模块,但你现在的任务只是修一个小 bug,不适合大动干戈
遇到这些情况,你可以进一步追问 AI:
你建议我 [AI 的建议]。但我的场景是 [你的实际情况]。
在这种情况下,这个建议还有必要吗?有没有更轻量的方案?
或者:
你说这里有性能问题,但这段代码只会在初始化时运行一次,不会重复执行。
在这种情况下,这个性能问题还值得优化吗?
好的 AI 会根据你的补充信息调整建议,而不是固执地坚持原来的方向。
验证 AI 的审查结论
对于 AI 提到的安全漏洞,特别是你不太熟悉的那类,最好自己查证一下。你可以:
- 让 AI 进一步解释这个漏洞的原理,以及如何被攻击者利用
- 搜索这个漏洞类型的相关资料
- 写一段测试代码,验证漏洞是否真实存在
不要盲目信任 AI 指出的每一个"漏洞"——有时候 AI 会误报,把正常的代码判断为有问题。但也不要因为看不懂就忽略——如果 AI 说某个地方有 SQL 注入风险,你不理解为什么,就应该深入去学习,而不是直接略过。
把代码审查融入开发流程
知道了如何让 AI 进行代码审查,下一步是把这个习惯真正融入你的日常开发流程。
什么时候审查
代码审查不是只在"觉得有必要"的时候才做,而应该成为开发流程的固定环节。
完成功能后,提交前: 这是最重要的时机。每次你完成了一个功能,在提交代码之前,花十分钟让 AI 扫描一遍。这个习惯能拦截大部分低级错误和安全问题,防止它们进入代码库。
接手他人代码时: 如果你需要修改或扩展别人写的代码,先让 AI 帮你做一次快速审查。这既是理解代码的手段,也是在修改之前摸清"地雷"的机会——知道哪里有隐患,才能修改时小心绕开,不把问题放大。
重构之前: 在开始重构一段代码之前,先让 AI 审查现有代码,找出它存在的问题。这样,你的重构就有了清晰的目标,而不是盲目地"感觉写得更好"。
出了生产 bug 之后: 当生产环境出现 bug,修复之后,用 AI 对修复的代码再做一次审查,确保修复本身没有引入新的问题,也顺便检查相关代码是否有类似的隐患。
建立你的审查清单
根据你的项目特点,可以建立一个个性化的审查清单,每次都让 AI 按这个清单检查:
请按以下清单审查代码:
**基础项(每次必查):**
- [ ] 是否有硬编码的密码、密钥或敏感配置?
- [ ] 用户输入是否经过了验证?
- [ ] 是否有潜在的空指针/空值错误?
- [ ] 函数和变量命名是否清晰?
**安全项(Web 功能必查):**
- [ ] 是否有 SQL 注入风险?
- [ ] 是否有 XSS 风险?
- [ ] 是否有不当的权限控制?
**性能项(数据处理必查):**
- [ ] 是否有不必要的重复计算或数据库查询?
- [ ] 循环中是否有不必要的 I/O 操作?
这个清单可以根据你的项目类型调整。一个数据分析脚本和一个 Web API 的关注点会很不一样。
让 AI 帮你写审查报告
如果你在团队中工作,有时候需要向他人说明代码的问题所在。你可以让 AI 帮你生成一份格式化的审查报告:
请对以下代码进行代码审查,并以正式的报告格式输出结果。
报告应包含:问题摘要、详细问题列表(每个问题包含位置、描述、严重程度、建议修复方案)、总体建议。
[代码]
AI 生成的报告,你可以在自己审阅后,直接分享给同事或写进提交记录,既省时间,又能保持专业。
一个完整的审查流程示例
让我们用一个完整的例子,把前面的知识串起来。
假设你开发了一个简单的用户注册 API,代码如下:
from flask import Flask, request, jsonify
import sqlite3
app = Flask(__name__)
@app.route('/register', methods=['POST'])
def register():
data = request.json
username = data['username']
password = data['password']
email = data['email']
conn = sqlite3.connect('users.db')
cursor = conn.cursor()
cursor.execute(f"INSERT INTO users VALUES ('{username}', '{password}', '{email}')")
conn.commit()
return jsonify({'message': '注册成功'})
if __name__ == '__main__':
app.run(debug=True)
第一步:全面审查
你先让 AI 做一次全面审查,提供背景信息:"这是一个 Flask 实现的用户注册接口,数据存储在 SQLite 数据库,会部署在公网服务器。"
AI 给出反馈,发现了几个严重问题:SQL 注入、密码明文存储、缺少输入验证、异常处理缺失、debug 模式不应在生产环境开启。
第二步:优先处理严重问题
你首先处理最严重的安全问题——SQL 注入和密码明文存储。修改完之后,你把新代码再发给 AI:
我已经按你的建议修复了 SQL 注入问题(改用参数化查询)和密码明文问题(改用 bcrypt 哈希)。
请检查这两处修改是否正确,同时看看还有什么遗漏:
[修改后的代码]
第三步:专项审查
处理完安全问题后,你发现代码对异常处理很薄弱。你做一次专项审查:
请专门审查这段代码的错误处理。我担心:
1. 如果请求体缺少字段,代码会直接崩溃
2. 如果数据库操作失败,没有给用户有意义的反馈
3. 如果用户名已存在,应该返回什么?
[代码]
第四步:验证修复
每次修改之后,你都把修改后的代码再发给 AI 确认,确保改动本身没有引入新问题。
第五步:最终审查
所有问题都处理完之后,做一次最终的全面审查,确认没有遗漏。
这个流程可能听起来有点繁琐,但实际上,对于一段简短的代码,整个过程可能只需要 15-30 分钟。而你收获的,是一段质量远高于原版的代码,以及对代码的更深理解。
小结
这一章,我们深入探讨了如何把 AI 变成你的代码审查伙伴。
代码审查的价值,不只是找 bug,更是在问题还小的时候就解决它,而不是等到积累成技术债。好的代码,不只是能运行,还要能被读懂、能被维护、能经得起安全考验。
让 AI 做好代码审查,关键在于提供充分的上下文和明确的审查重点。一个带有背景说明和具体问题指向的审查请求,能得到远比"帮我看看代码"更有价值的反馈。
面对 AI 给出的审查意见,要按优先级处理——安全漏洞和逻辑错误优先解决,风格与设计建议酌情采纳,不合理的建议要敢于质疑。AI 是助手,不是权威,最终的判断权在你手里。
把代码审查变成一个习惯——每次提交前审查,接手代码时审查,重构之前审查。这个习惯短期内会增加一点时间成本,但从长期来看,它会让你的代码质量越来越高,维护成本越来越低。
记住,你现在拥有的,是一个随时待命、从不疲倦、覆盖全面的代码审查员。用好它,是每一个现代开发者都值得培养的能力。
练习
基础题 1:定向审查请求
找一段你最近写的代码(至少 20 行),参考本章的模板,写一个带有背景说明和明确重点的审查请求。提交给 AI 之后,看看你得到的反馈与之前不做说明直接提交有什么不同。
基础题 2:审查别人的代码
下面这段 Python 代码有几个典型问题,试着在看答案之前,先靠自己找出问题,然后再交给 AI 进行审查,对比你的判断和 AI 的判断有什么差异:
def login(user, pwd):
db = pymysql.connect(host='localhost', user='root', password='root123', db='app')
c = db.cursor()
c.execute("SELECT * FROM users WHERE user='" + user + "' AND pwd='" + pwd + "'")
r = c.fetchone()
if r:
return True
return False
实践题 3:建立个人审查清单
根据你最常写的代码类型(Web 接口、数据处理脚本、自动化工具等),和 AI 一起设计一个属于你的代码审查清单。问 AI:"我主要写 [类型] 代码,有哪些最常见的容易被忽视的质量问题?"把这些整理成一个清单,保存下来备用。
进阶题 4:完整审查流程
选择一个你认为"写得还不错"的代码文件,按照本章介绍的流程做一次完整的代码审查:先全面审查、再专项审查、修复问题后再确认。完成后,反思:
- 你自己有没有发现这些问题?
- AI 的哪些反馈让你感到意外?
- 经过审查后,你对这段代码的信心有什么变化?
挑战题 5:评估 AI 的审查质量
找两段代码,一段故意写得有安全漏洞(比如 SQL 注入),一段故意写得性能低下(比如在循环里做不必要的数据库查询)。把它们交给 AI 审查,评估:AI 发现了所有问题吗?有没有遗漏?有没有误报?这个练习能帮你建立对 AI 审查能力的准确认知——知道它在哪方面强,在哪方面可能不够可靠。