代码 Review 机器人与规范自动化检测

封面信息图

在很多技术团队的代码审查(Code Review)流程中,高级工程师往往把大量高价值的时间浪费在低价值的琐碎检查上:某个函数的错误分支漏了记录、异步调用没做 catch、新加的变量名拼写错误或者存在明显的越界隐患。

传统的 ESLint、SonarQube 等静态扫描工具虽然能检测 AST 规则,但它们对代码语义、业务逻辑一致性以及上下文重构建议毫无感知能力。而直接把几十个文件打包扔给大模型做 Review,不仅 Token 成本高昂,还会因为漫无边际的幻觉建议导致开发者直接关闭这个流程。

本文分享我们在 CI/CD 与 Git Hook 链路中落地的一套轻量级 AI Code Review 机器人,探讨如何通过 Git Diff 修剪、结构化规则约束与阻断阈值,实现代码质量的低成本自动化初筛。

架构设计:两层过滤与精简 Diff

为了兼顾执行速度与准确率,整个 Review 机器人遵循“先静态过滤,再语义初筛”的流水线设计:

[Git Commit / Push] 
       │
       ▼
[文件过滤器] ──── 过滤 .lock / dist / 静态资源 / 超过 500 行的超大文件
       │
       ▼
[Diff 块提取器] ── 仅保留改动行及上下 3 行上下文(unified diff)
       │
       ▼
[AI 结构化审查引擎] ── 提示词严格约束输出 JSON,分为 BLOCKER / WARNING / SUGGESTION
       │
       ▼
[CI 门禁决策] ── 存在 BLOCKER 则阻断合并,输出精准行号高亮与修改建议

核心实现:自动化审查脚本

以下是集成在 Git Hook 或 CI 步骤中的审查脚本核心实现(TypeScript):

import { execSync } from 'node:child_process';
import { GoogleGenAI } from '@google/genai'; // 或使用 OpenAI 兼容 SDK

interface ReviewIssue {
  file: string;
  line: number;
  level: 'BLOCKER' | 'WARNING' | 'SUGGESTION';
  rule: string;
  description: string;
  suggestedFix?: string;
}

const IGNORE_PATTERNS = [
  /package-lock\.json$/,
  /pnpm-lock\.yaml$/,
  /\.min\.(js|css)$/,
  /\.d\.ts$/,
  /^dist\//,
  /^build\//
];

// 提取当前分支相对于 target 分支的有效变更
function getTargetDiff(targetBranch = 'main'): { file: string; diff: string }[] {
  const diffOutput = execSync(`git diff ${targetBranch}...HEAD --unified=3`, { encoding: 'utf8' });
  const fileDiffs = diffOutput.split(/^diff --git /m).filter(Boolean);

  const results: { file: string; diff: string }[] = [];

  for (const block of fileDiffs) {
    const match = block.match(/^a\/(.*?)\s+b\/(.*?)$/m);
    if (!match) continue;
    const filePath = match[2];

    // 过滤忽略文件
    if (IGNORE_PATTERNS.some((pat) => pat.test(filePath))) {
      continue;
    }

    // 限制单文件 diff 大小,防止超长 token 消耗
    if (block.length > 10000) {
      console.warn(`[Review] 文件 ${filePath} 改动过大 (>10KB),跳过 AI 细粒度审查`);
      continue;
    }

    results.push({ file: filePath, diff: block });
  }

  return results;
}

// 调用大模型进行严格审查
async function reviewDiffBlock(file: string, diff: string): Promise<ReviewIssue[]> {
  const prompt = `你是一个资深全栈工程师,正在审查 Git Diff 代码改动。
请仅针对代码质量、潜在 Bug、资源泄漏、未处理的边界异常和明显的规范违规进行审查。
如果包含 "// @ai-ignore" 注释,请跳过对应行的提示。
请严格输出 JSON 数组,格式如下:
[
  {
    "file": "${file}",
    "line": 42,
    "level": "BLOCKER | WARNING | SUGGESTION",
    "rule": "错误命名 | 空指针风险 | 缺失错误处理 | 资源泄漏",
    "description": "简明扼要说明问题所在",
    "suggestedFix": "修复后的代码片段"
  }
]
若代码无明显问题,请直接输出空数组 []。绝对不要包含任何额外 Markdown 说明。

Diff 内容如下:
${diff}
`;

  // 此处调用配置好的模型接口
  const response = await callLLM(prompt);
  try {
    const cleanJson = response.replace(/^```json/m, '').replace(/```$/m, '').trim();
    return JSON.parse(cleanJson) as ReviewIssue[];
  } catch (err) {
    console.error(`解析 Review 响应失败: ${file}`, err);
    return [];
  }
}

规则收敛与误报抑制实践

在真实团队落地 AI Review 机器人时,最容易引发开发者抵触的是“假阳性误报”(AI 瞎提无意义的风格建议)。为了让这个工具真正成为开发者的助手而非阻碍,我们落实了以下三条准则:

  1. 白名单忽略注解(@ai-ignore:允许开发者在特定的业务妥协代码旁加上 // @ai-ignore: 解释原因,机器人遇到该标记立即跳过,避免因业务特殊需求导致的反复误报。
  2. 严格区分阻断级别
    • BLOCKER:仅限于 SQL 注入、密钥硬编码、未捕获 Promise rejection 导致进程崩溃、死循环等致命 Bug。只有出现此类问题时才会退出状态码 1 并阻断 CI。
    • WARNING:性能可能下降、未清理的定时器或监听器、未对齐的国际化文本。只在 PR 评论中标记,不阻断发布。
    • SUGGESTION:可读性与命名建议,仅供参考。
  3. 单次审查 Token 预算控制:在每次 PR 触发时,限制总 Diff 处理行数。对于大型重构 PR(如超过 30 个文件),只对核心业务目录(如 src/services/src/api/)做 AI 扫描,脚手架和配置文件走轻量规则。

总结

AI 赋能研发效能的核心,不在于“用 AI 替代资深工程师做决策”,而在于“用 AI 构筑第一道语义防线”。通过 Git Hook 与轻量 LLM 审查机器人的结合,我们把 80% 的低级规范疏漏和边界死角拦截在提交阶段,不仅提升了主干分支的代码健康度,也让团队内的人工 Code Review 重新聚焦在系统架构设计与业务合理性等深层次议题上。

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐