资讯中心

AI代码审查副驾驶:OpenCodeReview如何用大模型提升Code Review效率

📅 2026/9/26 9:18:01
AI代码审查副驾驶:OpenCodeReview如何用大模型提升Code Review效率
1. 项目背景为什么代码审查需要一颗“AI副驾驶”1.1 那些年我们被 Code Review 折磨的时刻先说一个让我下定决心做 open-code-review 的场景。那是在一家成长很快的创业公司团队从5个人扩张到30多个人PR 数量从每天几个涨到几十个。代码审查Code Review开始变得越来越痛苦我自己作为技术负责人每天要花两个小时盯在 GitHub 上一遍遍看别人改的逻辑口干舌燥地解释“这里为什么不能用全局变量”“这个异常为什么不处理”。更烦的是我辛辛苦苦写的评语经常被几个“LGTM”淹没——大家根本来不及认真看。后来我做过一个小统计随手抽查了团队最近 100 个合入的 PR其中有 27 个在合并之后的一周内出过 bug而这些 bug 里有 14 个如果仔细看代码是完全可以在 review 阶段发现的。不是大家不负责而是人的注意力本身就撑不住这种高强度的“逐行盯梢”。人看代码超过二十分钟效率就会断崖式下降这就是典型的“审查疲劳期”。这个项目 open-code-review本质上就是想给每个 PR 配一个不眠不休的“AI 副驾驶”。它会在我把 PR 推上去之后自动拉取 diff分析改动的上下文然后输出一份像模像样的 Code Review 报告哪里可能有 bug、哪里写法不够健壮、哪里性能会出问题并直接给出修改建议。它不是为了替代人而是把“有没有明显问题”这层底给兜住好让人类 reviewer 把精力集中在真正需要判断力的地方比如架构合理性、未来扩展性、业务语义对齐这些事上。1.2 现有工具链的边界到底在哪在动手写 open-code-review 之前我把团队现有的“质量防线”从头到尾捋了一遍发现每一层都有明显的边界。第一层是格式化工具比如 Prettier、Black、gofmt。它们管的是“长得齐不齐”完全不知道这段代码在干什么。第二层是 Lint 工具ESLint、Pylint、RuboCop 这些。它们基于规则做匹配能抓出未使用变量、空 catch、明显反模式但规则本身是静态的写死的它对“这个列表明明可以预分配容量却没用 append 逐步扩容”这类动态逻辑问题基本无能为力。第三层是自动化测试单测、集成测试、覆盖率它们能验证“符合预期的行为”但写测试的人自己也容易跟实现代码共用同一个盲区——你觉得没问题的地方测试通常也不会覆盖到。换句话说传统工具链擅长的是“语法表面”和“已知规则”它缺的是“语义理解”。而这一点恰恰是大语言模型的强项。让模型读一段 diff它不仅能看出变量名写错还能推断出“这个循环里为什么对同一个 map 反复做深拷贝”“这里如果 user 为 null 会直接 NPE”“两个 goroutine 并发写同一个 channel 可能 panic”。这种能力不是靠规则堆出来的而是靠海量代码训练出来的“代码直觉”。所以 open-code-review 的定位从一开始就很清楚不是替代 Lint 和测试而是在 Lint 和测试之上补上“语义审查”这一层最稀缺的价值。2. 整体设计open-code-review 到底长什么样2.1 运行模式与使用流程我见过不少团队想自己做 AI 代码审查最常见的做法是在 CI 里写一个脚本拿到 git diff 之后整段丢给 ChatGPT然后把回答贴在 PR 评论里。听起来很简单实际用下来会发现几个问题提示词没设计好回答一会像教科书一会像营销号diff 一长就超过上下文窗口模型给的建议经常和仓库里的既有风格冲突。open-code-review 从一开始就设计成两种运行模式方便不同团队接入。第一种是 CLI 模式适合本地开发时自查。我在本地跑open-code-review --base main --head feature-xxx它会自己去解析git diff生成一份 Markdown 报告我可以在提交 PR 前先看一眼把明显的低级错误提前干掉。这个模式的好处是没有网络依赖除了调用模型 API也不影响团队流程适合个人开发者。第二种是 CI 模式也是这个项目真正发挥威力的场景。我可以把它集成到 GitHub Action 或者 GitLab CI 里当有新的 PR 推上来时自动触发审查任务把结论以评论的形式发回到 PR 页面并给每个问题标注严重级别。这样整个团队不用装任何额外工具只要打开 PR 就能看到 AI 的审查结果相当于每个 PR 都有一个免费的机器人 reviewer 在盯着。一个典型的运行流程是这样的开发者推送代码到 PR - CI 被触发 - open-code-review 拉取本次变更的 diff - 解析 diff 并收集相关上下文 - 调用大模型 API 逐块分析 - 汇总结果、去重、分级 - 以评论形式发布到 PR。整个过程耗时取决于改动量一般两三百行的 PR两到三分钟就能出报告。2.2 核心模块拆解它内部做了哪些事如果只看表面open-code-review 好像就是一个“把 diff 丢给 GPT”的壳子。但实际拆开看里面有六个模块每个模块都踩过不少坑。第一个是 diff 解析器。git diff出来的 unified diff 格式里有大量噪音信息a/ b/ 前缀、一行行的 和 -直接丢给模型不是不行但会浪费大量 token而且模型容易混淆“新代码”和“旧代码”。所以我在这个模块里做了一件事把 diff 重新结构化每一处改动都变成一个带有前后文的对象并明确标识出改动前后的代码。第二个是上下文收集器。只给模型看孤立的一小块 diff经常出现“看不懂”的情况。比如一个函数改了签名但调用它的地方在另一个文件里如果模型看不到调用点就不知道这个改动会影响到哪些人。这个模块会通过 tree-sitter 解析代码结构找到被修改符号的引用位置把相关的定义和调用点一起拉进来作为额外的上下文提供给模型。第三个是审查引擎也就是和模型 API 交互的部分。它负责把 diff 片段和上下文拼装成结构化的请求设置合适的 temperature 和 max_tokens并且处理失败重试和速率限制。第四个是报告生成器。模型返回的结果往往是自由文本不能直接发需要把它解析成统一结构再套上 Markdown 模板生成易读的报告。第五个是分级过滤模块。我会把发现的问题分成 P0、P1、P2 三个等级P0 是会导致崩溃、数据丢失、严重安全漏洞的问题P1 是逻辑错误和明显的性能隐患P2 是代码风格和可维护性改进建议。这样做是避免给开发者造成“狼来了”的疲劳感——如果每次报告里都有五十条问题其中四十五条是无关紧要的风格建议过不了两周人就不看了。第六个是评论发布模块。对接 GitHub 的 Review Comment API 或 GitLab 的 Discussions API把报告推送到对应代码行上。2.3 技术选型上的三个关键决策先说说为什么调用云端大模型 API而不是在本地部署一个模型。这个决策我踌躇了很久。本地部署的好处是代码不出内网数据安全性好而且长期来看没有按量计费的问题。但现实情况是要把效果做到能用的程度本地至少得跑 7B 以上的模型对显存和算力的要求不小团队里如果没人专门维护推理服务它大概率会沦为摆设。API 方案的好处是效果稳定大厂模型的代码理解能力明显强于本地小模型而且按量付费的模式对于“每次 PR 审一次”这种低频场景来说成本非常可控。至于代码泄漏问题我会在后面的安全章节里专门展开讲这里先留个扣。第二个决策是“增量审查”而不是“全量审查”。我最早也试过把整个仓库喂给模型让它做全面体检。结果是Token 消耗巨大普通规模的项目一两百万 token 起步费用吓人而且模型会陷在海量代码里“拣了芝麻丢了西瓜”给你挑出一堆无关紧要的风格问题真正重要的逻辑缺陷反而漏掉了。后来我改成只审“本次改动涉及到的函数及其直接调用方”效果反而好了很多因为聚焦让模型更容易在有限的上下文里做深度推理。这也符合人在做 Code Review 时的直觉——先盯这次改了哪再看它会影响谁。第三个决策是输出必须用 JSON 再做结构化处理而不是直接用自然语言。第一次做这个项目的时候我让模型“自由发挥”写报告结果它写出了一篇声情并茂的小作文开头是“这段代码展示了作者良好的编程习惯”中间是“但是呢我发现了几个可以改进的地方”最后还来一句“总体而言这是一个非常优秀的 PR”。这样的东西发到 PR 评论里开发者看一眼就想关掉。后来我改成要求模型只输出 JSON字段包括 severity、line、message、suggestion再写一个解析器把 JSON 转成报告效果立刻可控了。3. 从零到一核心实现与关键步骤3.1 diff 解析把 PR 变成模型能读懂的片段这一步是整个项目的地基也是最容易被人忽略的部分。git diff的原始输出长这样diff --git a/src/user_service.py b/src/user_service.py index 3f2c1a4..9a7b3d0 100644 --- a/src/user_service.py b/src/user_service.py -21,8 21,10 def get_user(user_id): if user_id is None: raise ValueError(user_id cannot be None) - user db.query(User).filter(User.id user_id).first() - return user user db.query(User).filter(User.id user_id).first() if user is None: logger.warning(user %s not found, user_id) return None return user直接把这个文本丢给模型它能看懂但效果不够好。原因有两个一是模型会把-开头的旧代码和开头的新代码同等看待偶尔会拿旧代码来挑新代码的毛病二是当 diff 很长时模型需要记住大量行号信息token 浪费严重。我在 open-code-review 里做了一层解析把上述输出转成结构化对象dataclass class DiffHunk: file_path: str old_start: int old_lines: int new_start: int new_lines: int additions: List[str] deletions: List[str] property def is_binary(self): return False def parse_unified_diff(diff_text: str) - List[DiffHunk]: hunks [] current_file None current_hunk None for line in diff_text.splitlines(): if line.startswith( b/): current_file line[6:] continue if line.startswith(): # 解析 hunk header找出新旧代码块的行号范围 match re.search(r -(\d),?(\d*) \(\d),?(\d*) , line) if match: if current_hunk: hunks.append(current_hunk) old_start int(match.group(1)) old_len int(match.group(2)) if match.group(2) else 1 new_start int(match.group(3)) new_len int(match.group(4)) if match.group(4) else 1 current_hunk DiffHunk( file_pathcurrent_file, old_startold_start, old_linesold_len, new_startnew_start, new_linesnew_len, additions[], deletions[], ) continue if current_hunk: if line.startswith() and not line.startswith(): current_hunk.additions.append(line[1:]) elif line.startswith(-) and not line.startswith(---): current_hunk.deletions.append(line[1:]) else: # 上下文行记录到 additions 里的目的是保持顺序 current_hunk.additions.append(line[1:]) if current_hunk: hunks.append(current_hunk) return hunks解析完成后还需要做一轮“噪音过滤”。像package-lock.json、yarn.lock、dist/目录下的产物、*.min.js这类文件没有任何审查价值直接跳过能省下大量 token。我维护了一个默认的 ignore 列表也支持通过配置文件自定义。这个细节看着小实际用在大仓库时效果非常明显一次 PR 的 token 消耗能降 30% 以上。3.2 上下文增强让 AI 不只看到“孤立的一块代码”这是 open-code-review 和“直接把 diff 贴给 ChatGPT”最大区别的地方。模型只看 diff 片段经常会得出片面的结论。举个具体例子一个改动是把user_service.get_user(user_id)的返回值从“抛异常”改成了“返回 None”单看这段 diff模型只会说“哦你改了返回值类型”。但如果它能看到所有调用方就可能发现某个调用方没有处理 None 就直接user.name了这正好是一个真实的 NPE 隐患。我实现上下文增强时没有一开始就上很重的方案。第一版只做了“把被修改函数所在的整个函数体提取出来”够用但不够好。后来加上了基于 tree-sitter 的符号解析先用 tree-sitter 把每个文件解析成 AST找到被修改的符号定义再在整个仓库的 AST 索引里搜索该符号的引用位置把引用代码片段一起交给模型。from tree_sitter import Language, Parser import tree_sitter_python as tspython LANGUAGE Language(tspython.language()) parser Parser(LANGUAGE) def get_function_bounds(source, line_number): tree parser.parse(source.encode(utf-8)) root tree.root_node def walk(node): if node.type in (function_definition, class_definition, decorated_definition): if node.start_point[0] line_number node.end_point[0]: return node for child in node.children: result walk(child) if result: return result return None node walk(root) if node: return node.start_point[0], node.end_point[0], node.type return None, None, None拿到函数边界后再回到源码里把这一段抽出来作为“改动所在的完整函数上下文”。对于跨文件的引用需要配合一个简单的全仓索引。我早期用ripgrep做字符串匹配虽然糙但够用后来遇到的问题多了比如同名函数、方法重载导致误匹配才换成 tree-sitter 的 AST 索引。至今为止这个方案在 Python、JavaScript、TypeScript、Go、Java 等主流语言上都工作得不错。这里有一个非常关键的工程细节上下文不是越多越好。我一开始把相关函数全文都塞进提示词结果模型“看的东西太多”给出的建议开始发散甚至出现幻觉——它会把 A 函数的问题安到 B 函数上。后来我加了一个 max_context_lines 参数每个相关文件的上下文最多取被修改位置前后各 40 行超出部分截断。控制上下文长度本质上是控制模型的“注意力焦点”这一点在模型能力还没有强到可以随意处理超长文本之前非常重要。3.3 提示词设计一次好的审查一半靠提示词提示词是这个项目的灵魂也是我改得最多、最不满意的地方。第一版提示词我写了整整两页把大佬的 10 条代码审查标准、团队的代码规范全塞进去结果模型输出越来越像“八股文”什么“建议提取公共方法”“提高代码的可读性”这类正确的废话反复出现。后来我把提示词砍成三段式角色设定、审查清单、输出格式。你是一名有 15 年经验的高级软件工程师正在进行严格的代码审查。 请根据以下输入找出真实存在的问题。只报告你确信的问题 不要为了凑数量而挑刺。 审查优先级 1. 正确性是否存在逻辑错误、空指针、条件判断错误、资源泄漏 2. 并发安全是否有共享状态竞争、死锁、原子性缺失 3. 错误处理异常是否被吞掉、错误路径是否缺失清理操作 4. 性能是否有不必要的循环、重复查询、明显的时间复杂度退化 5. 可维护性命名、函数长度、重复代码 不要报告 - 代码风格问题如引号、缩进、换行 - 非本次改动引入的历史问题 - 没有证据支撑的猜测 输入JSON { file_path: src/user_service.py, change_summary: 用户不存在时返回 None 而不是抛出异常, diff_hunk: ..., related_symbols: [ {name: get_user, signature: def get_user(user_id: int) - Optional[User]}, {name: get_user_caller, code: user get_user(user_id); return user.name} ] } 输出必须为合法 JSON格式如下 { comments: [ { severity: P0/P1/P2, line: 24, message: 问题的具体描述, suggestion: 建议的修改方案 } ] }这个提示词有四个关键点值得展开。第一明确告诉模型“不要报告什么”比告诉它“要报告什么”更管用。如果不加这个约束模型会习惯性地把无关紧要的风格建议和无关历史问题带进来产生大量噪音。第二要求模型“只报告你确信的问题”。模型天然有讨好用户的倾向你要是写“请找出所有可以改进的地方”它一定会给你列出一堆错误的废话。用“确信”两个字能让它在生成时更保守一些。第三输出格式严格规定为 JSON并且我要求模型“不要输出任何其他文字”。这一步大大简化了解析逻辑也避免了“开始前寒暄”这类破坏体验的输出。第四模型参数上temperature 设置为 0.2max_tokens 设置为 1500。temperature 低是为了减少随机性代码审查不是创意写作需要的是稳定和准确max_tokens 限制在 1500 是为了防止模型在回答里写小作文超过长度会被截断这样反而倒逼它言简意赅。3.4 审查主流程与报告生成有了 diff、上下文和提示词剩下的就是把整个流程串起来。先看一个简化的审查主流程代码import json import asyncio from concurrent.futures import ThreadPoolExecutor async def review_pull_request(repo, pr_number, config): # 1. 获取 diff diff_text await get_github_diff(repo, pr_number) # 2. 解析 diff 成结构化的 hunks hunks parse_unified_diff(diff_text) # 3. 过滤噪音文件 hunks [h for h in hunks if should_review(h.file_path, config)] # 4. 为每个 hunk 补充上下文 context_map {} for hunk in hunks: context_map[hunk.file_path] await build_context(hunk) # 5. 并发调用模型进行审查 tasks [review_hunk(hunk, context_map[hunk.file_path], config) for hunk in hunks] results await asyncio.gather(*tasks) # 6. 收集所有问题 all_comments [] for result in results: if result.get(comments): all_comments.extend(result[comments]) # 7. 按严重程度排序、去重 all_comments deduplicate_and_sort(all_comments) # 8. 生成报告并在 PR 上发评论 report build_markdown_report(all_comments) await post_github_comment(repo, pr_number, report) return report这里我把“逐个 hunk 调用模型”设计成了并发任务。实际的并发数不是越高越好因为模型 API 有速率限制并发太高会 429。我一般在配置里允许设置max_concurrency默认是 3每次请求间隔 200ms。实测下来一个 300 行改动的 PR大概会切成 20 个左右的 hunk并发 3 个请求跑完总耗时约 90 秒。报告生成这一层要做的核心工作是“去重”。模型在审查多个 hunk 时经常会针对同一个问题重复提意见。比如一个变量名在三个地方改错了模型会在三处各给出一条 comment。我会用“文件路径 变量名 问题类型”做一个 hash把相似的评论聚合成一条只保留最具体的那条。这个逻辑看着简单却大幅提升了报告的可读性。报告模板我按照严重级别做了分区用 Markdown 渲染## AI Code Review 报告 ### P0 严重问题 (2) - **File: src/user_service.py:24** - get_user 返回 None 但调用方未做空判断 建议在调用方增加 if user is None 判断或改为抛出自定义异常。 ### P1 逻辑问题 (5) - ... ### P2 改进建议 (8) - ...最后通过 GitHub REST API 的POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews接口把报告发布到 PR 上。有一个小细节值得注意尽量不要用issue comments接口直接贴一篇完整的长文而是用review threads的形式把每条评论挂到对应的代码行上。开发者点开 PR 的 Files changed 页面就能在具体位置看到 AI 的评论体验好很多。3.5 模型选型与成本控制open-code-review 在模型上做得比较灵活通过配置文件可以随时切换。核心接口只要求“输入是文本、输出是 JSON”的模型都能接入我在本地开发时常用 gpt-4o-mini因为它速度快、价格低在代码审查场景下性价比很高。如果项目特别复杂、改动逻辑深的我会切成更强的模型比如 gpt-4o 或 Claude 的 Sonnet 系列效果会好一些但成本也会高几倍。成本这块很多团队会担心。我算过一笔账一个典型的 PR200 行改动拆成 15 个 hunk每个 hunk 带上 1000 多字的上下文加起来大概消耗 15000~20000 个 token。按 gpt-4o-mini 的定价计算输入百万 token 十几块钱一次审查的模型成本基本就在几毛钱到一块钱之间。一天审 50 个 PR成本不超过 50 块比一个初级工程师的人力成本便宜太多了。不过要提醒的是如果直接接入企业级大模型 API价格就不止这个数了。我见过一个团队做同样的工具选了最贵的旗舰模型每个 PR 成本高达十几块团队一天 200 个 PR一个月光 AI 审查的成本就过万后来不得不做了两个优化一是只审查新增代码量超过 50 行的“大 PR”小的改动直接跳过二是把模型降级小改动用便宜模型只有大改动才用旗舰模型。这套分级策略省下来的钱非常可观。4. 实战效果与常见问题排查4.1 在真实项目上的效果到底能审出什么做工具最怕自嗨。open-code-review 做完第一版之后我没急着写 README 到处宣传而是先拿自己维护的两个开源项目和一个朋友的商业项目试跑了两个星期收集了两百多个 PR 的审查结果。从我自己的 Python 项目来看AI 审查发现的问题分布大概是这样的问题类型占比典型例子空值与异常处理32%函数返回值可能为 None 但没有处理资源管理18%打开文件没用 with、数据库连接未关闭并发安全12%使用了可变默认参数、共享变量未加锁逻辑正确性15%条件判断写反、边界条件漏处理性能隐患10%循环里重复查询数据库、列表查找用了 O(n)可维护性13%函数过长、重复代码、命名不当最让我惊讶的是 P0 级别的问题还真不少。两个星期里抓到了 3 个会导致线上事故的 bug一个是没有对用户输入做校验就直接拼进 SQL一个是文件上传后没有关闭句柄导致 Linux 系统文件描述符耗尽还有一个是在多线程环境下对共享 dict 做了非原子的“检查再写入”操作。这三个问题如果在人工 review 阶段大概率也能被发现但问题是当时团队里没人想到去看那段代码——这才是 AI 审查真正的价值它不会累不会漏只要 diff 里存在问题它就会盯着看。当然AI 审查也有明显的短板。它对“业务语义”理解很弱。一个改动是把优惠券的有效期从“领取后 30 天”改成“领取后 30 个自然日”单从代码 diff 上完全看不出问题只有懂业务的人才知道原来需求和实现之间有细微差别。所以我的定位一直是AI 先筛一遍“通用问题”人再集中精力看“业务问题”两者互补。4.2 高频问题与排查技巧实录在实际使用过程中有几个问题反复被使用者问到我系统地梳理一下排查思路。问题一误报率太高怎么办这是反馈最多的。AI 审出来的 20 条评论里可能有一半是“正确的废话”或者“不符合本仓库实际情况”的建议。解决办法有三个。第一在 prompt 里增加“仓库上下文”把项目的语言版本、框架、既有约定写进去比如“本项目使用 Django ORM请使用 Q 对象进行复杂查询”。第二把 P2 级别的建议默认关掉只保留 P0 和 P1 在 PR 评论里展示P2 级别的生成一个 JSON 文件供开发者本地查看减少评论轰炸。第三使用“相似问题聚合”和“白名单机制”如果某个文件或某类问题被标记为“不相关”次数超过 3 次就把对应规则自动加入项目的 ignore 列表。问题二响应速度太慢CI 被拖慢。PR 合并通常希望越快越好如果 AI 审查要跑三分钟很容易成为发布流程瓶颈。我的做法是默认只审查“新增代码量大于 100 行且小于 800 行”的 PR太小的直接跳过人工几分钟就看完太大的拆成多个包分别审查防止超时。同时审查结果以“机器人评论”的形式异步返回不设置成 GitHub 的 required check这样即使模型 API 挂了也不会阻塞正常的 CI 流程。这个设计让我避免了很多次“模型超时导致整个 CI 红掉”的尴尬。问题三模型漏掉问题或者给的建议不对。说实话这个问题到目前为止还没有完美的解法。大模型不是形式化验证工具不可能保证百分百的召回率。我的经验是不要单独依赖一个模型。open-code-review 支持配置多个模型同时审查同一个 diff比如让模型 A 审正确性模型 B 审并发安全模型 C 审性能然后再把三个结果合并。缺点是成本翻三倍优点是发现问题数量显著提升尤其是一些隐蔽的并发问题模型之间能互为补充。有钱的团队可以这么玩小团队就用默认的单模型方案即可。问题四代码安全与隐私怎么办很多公司对把代码发送到第三方 API 有顾虑这是一个很现实的问题。open-code-review 从设计上做了一些缓解措施默认只发送“本次改动涉及的代码片段”不会发送整个仓库支持配置敏感文件过滤规则比如以_test.py结尾的文件可以选择直接不发给模型如果公司内网有私有化部署的模型服务如 vLLM 或 TGI也可以直接替换 API 地址。不过要坦率说如果公司有最严格的数据合规要求比方说代码完全不能出内网那这个方案就不合适了只能考虑本地部署模型。这是取舍问题我不回避。问题五多语言支持不到位。tree-sitter 的语言解析器是独立安装的不同语言的支持成熟度差异很大。Python、JavaScript、TypeScript、Go 这些生态完善的语言体验最好Rust、Java 也不错但 PHP、Ruby、Swift 这些相对小众的语言偶尔会解析失败。我的应急方案是解析失败的文件退化为“整文件作为上下文”模式不再做细粒度的符号增强。效果还是有只是不如大树语言那么精准。4.3 与人工审查的配合方式最后聊聊我实际用的最多的工作流也是我现在认为最正确的一种用法。PR 提交后AI 先跑把 P0 和 P1 的问题以评论形式挂在代码行上。作为 reviewer我先看 AI 的评论尤其是有没有 P0 级别的问题需要立刻阻止合并。确认没有 P0 之后我再快速浏览一遍 diff重点看那些 AI 不擅长的部分业务语义、架构演进、接口设计。这两步加起来一个几百行的 PR从以前要花半小时现在大概十分钟就能审完效率提升非常明显。AI 评论里如果有明显错误的建议我会直接点“dismiss”顺手在配置文件里加一条过滤规则让下次不再犯同样的错误。这样经过两到三周的磨合AI 的准确率会越来越高因为过滤规则已经把本地项目的“隐性约定”沉淀下来了。经过这几个月各种规模的团队试用我最深刻的体会是AI 代码审查工具最大的敌人不是模型能力不够而是信任没建立起来。开发者如果觉得这个工具总是说废话他就不会再看了。所以设计这类工具时克制比炫技重要——宁可少报 10 个问题也不要乱报 10 个问题。我现在每次迭代 open-code-review第一件事是拿上周的误报率数据来回调 prompt而不是急着加新功能。这个经验应该也适用于所有准备做类似 AI 生产力的同学。目前 open-code-review 还在继续迭代下一步我想加入“基于 git blame 的改动归属感知”也就是在审查时知道每一行是谁写的、大概什么意图这样能更好地结合上下文另外一个方向是自动生成修复补丁让开发者一键应用进一步缩短修复周期。工具会越来越像“自动驾驶”但方向始终是那一个让代码审查更轻松让 bug 更少溜进线上。

看完文章,想为自己的企业也做一次专业网站诊断?

尧图顾问免费为您评估现有网站,并给出建站/改版建议与报价方案。

免费获取方案