聊天讨论 同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了

193577746(kyriewen) · June 20, 2026 · 20 hits

先说结论:用 GitHub Actions + Claude API 实现全自动 PR review,配置一次,以后每个 PR 推上去,AI 10 秒内给出详细评审意见,覆盖代码质量、潜在 bug、安全风险三个维度。这篇文章把完整配置都给你,拿走直接用。

背景:CR 慢是前端团队的通病

我们团队有个不成文的规定:PR 提上去,要在 1 个工作日内完成 review。

听起来很合理,但实际情况是这样的:

  • 早上刚到公司,打开 GitHub,待 review 的 PR 已经排了 6 个
  • 每个 PR 少则 200 行,多则 800 行
  • 还有自己的需求要写
  • 还有各种会

于是每天我的 review 质量是这样的:

  • 上午的 PR:认真看,写评论
  • 下午的 PR:大概扫一下
  • 晚上的 PR:approve,👍

然后有一天,同事 A 在群里 @ 了我:

"我那个 PR 提了两天了,能帮我看一下吗?"

我翻出来一看——800 行,涉及三个模块。

我当时脑子里只有一个念头:要是有人能替我先过一遍就好了。


解决思路:AI 做初审,人做终审

理想的工作流是这样的:

开发者 push PR
    ↓
AI 自动分析 diff
    ↓
AI 在 PR 里发评论(10秒内)
    ↓
人工看 AI 的意见 + 做最终判断
    ↓
approve 或 request changes

好处显而易见:

  • AI 处理掉 80% 的机械检查(代码风格、潜在空指针、未处理的 Promise reject)
  • 人只需要关注 AI 标注出的问题点 + 业务逻辑
  • 平均 review 时间从 30 分钟压缩到 8 分钟

坏处也要说清楚:

  • AI 不理解你的业务逻辑,会漏掉业务层面的 bug
  • AI 有时候会给"误报",需要人来过滤
  • 不能完全替代人工 review

所以定位是:AI 初审 + 人工终审,不是 AI 替代人工。


实现方案:GitHub Actions + Claude API

第一步:申请 Claude API Key

console.anthropic.com 注册,免费额度足够测试用。

把 Key 存到 GitHub 仓库的 Secrets:

  • 仓库 → Settings → Secrets and variables → Actions
  • 新建 ANTHROPIC_API_KEY

第二步:创建 workflow 文件

在你的仓库里创建 .github/workflows/ai-review.yml

name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: read
  pull-requests: write

jobs:
  ai-review:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm install @anthropic-ai/sdk @octokit/rest

      - name: Run AI Review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          PR_NUMBER: ${{ github.event.pull_request.number }}
          REPO_OWNER: ${{ github.repository_owner }}
          REPO_NAME: ${{ github.event.repository.name }}
          BASE_SHA: ${{ github.event.pull_request.base.sha }}
          HEAD_SHA: ${{ github.event.pull_request.head.sha }}
        run: node .github/scripts/ai-review.js

第三步:创建核心脚本

创建 .github/scripts/ai-review.js

const Anthropic = require('@anthropic-ai/sdk');
const { Octokit } = require('@octokit/rest');
const { execSync } = require('child_process');

const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

async function getDiff() {
  const diff = execSync(
    `git diff ${process.env.BASE_SHA}..${process.env.HEAD_SHA} -- '*.js' '*.ts' '*.tsx' '*.jsx' '*.vue'`
  ).toString();

  // 超过 8000 字符截断,避免超出 token 限制
  return diff.length > 8000 ? diff.slice(0, 8000) + '\n... [diff truncated]' : diff;
}

async function reviewWithClaude(diff) {
  const message = await anthropic.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 2048,
    messages: [{
      role: 'user',
      content: `你是一个资深前端代码审查工程师,请对以下 PR diff 进行代码审查。

**审查重点:**
1. 潜在 Bug(空值引用、异步竞态、边界条件未处理)
2. 安全风险(XSS、敏感信息泄露、输入未校验)
3. 性能问题(不必要的重渲染、大对象序列化、内存泄漏)
4. 可维护性(函数过长、命名不清晰、重复代码)

**输出格式:**
用 Markdown 输出,包含以下几个部分:
- 🔴 严重问题(必须修复)
- 🟡 建议优化(可以改进)
- 🟢 代码亮点(做得好的地方)
- 📊 总体评分(1-10分,附简短理由)

如果没有问题,直接说"代码质量良好,无明显问题"。
用中文回复,简洁直接,不废话。

**PR Diff:**
\`\`\`
${diff}
\`\`\``
    }]
  });

  return message.content[0].text;
}

async function postComment(review) {
  const { REPO_OWNER, REPO_NAME, PR_NUMBER } = process.env;

  await octokit.issues.createComment({
    owner: REPO_OWNER,
    repo: REPO_NAME,
    issue_number: parseInt(PR_NUMBER),
    body: `## 🤖 AI Code Review\n\n${review}\n\n---\n*由 Claude AI 自动生成,仅供参考,请以人工审查为准*`
  });
}

async function main() {
  try {
    console.log('Getting diff...');
    const diff = await getDiff();

    if (!diff.trim()) {
      console.log('No JS/TS changes detected, skipping review.');
      return;
    }

    console.log('Sending to Claude for review...');
    const review = await reviewWithClaude(diff);

    console.log('Posting comment...');
    await postComment(review);

    console.log('Done!');
  } catch (error) {
    console.error('Error:', error);
    process.exit(1);
  }
}

main();

第四步:推一个 PR 测试

随便改一个文件,提个 PR,大约 15-20 秒后,你会看到 AI 自动在 PR 下面发了一条评论。


真实效果展示

我们团队用了两周后,AI 的评论长这样:


🔴 严重问题(必须修复)

第 47 行 userData.profile.avatar:未做空值检查,当 profilenull 时会抛出 TypeError。建议改为 userData.profile?.avatar

第 83 行:useEffect 的依赖数组缺少 userId,可能导致使用过期的 userId 发请求,产生数据不一致。

🟡 建议优化

第 92-115 行:formatUserData 函数做了 3 件不同的事(格式化、过滤、排序),建议拆成 3 个函数,便于测试和复用。

🟢 代码亮点

错误处理写得很规范,catch 块没有直接吞掉错误,而是通过 errorReporter.capture 上报,赞。

📊 总体评分:7/10

整体结构清晰,主要问题集中在空值防护上,修复后可以直接合并。


看到这个,review 的人只需要:

  1. 确认 AI 找出的问题是否真实存在(通常是)
  2. 判断业务逻辑是否正确(这才是人工的价值所在)
  3. approve 或 request changes

平均节省 70% 的初审时间。


进阶:按文件类型差异化 review

不是所有文件都需要一样的审查策略。可以在 prompt 里加文件类型判断:

function buildPrompt(diff, fileTypes) {
  const focusMap = {
    'api': '重点关注:参数校验、错误处理、幂等性、接口安全',
    'component': '重点关注:props 类型、副作用清理、渲染性能、无障碍属性',
    'util': '重点关注:边界条件、纯函数、测试覆盖',
    'store': '重点关注:状态更新的不可变性、selector 性能、副作用隔离'
  };

  const focus = fileTypes.map(t => focusMap[t]).filter(Boolean).join('\n');

  return `你是资深前端工程师,请审查以下代码:

${focus ? `**本次特别关注:**\n${focus}\n` : ''}

${diff}`;
}

踩坑记录

坑 1:diff 太大超出 token 限制

解决方案:只 review 修改行数 < 500 的文件,超过的给一个提示"文件变更过大,请人工重点审查"。

坑 2:AI 给出"误报",降低信任度

解决方案:在 prompt 里加一句 "如果你不确定是否是问题,不要写出来"。比 "尽可能找出所有问题" 效果好很多。


现状

现在我们团队的 CR 流程是这样的:

  1. 开发提 PR
  2. AI 10 秒内完成初审,发评论
  3. reviewer 看 AI 评论 + diff,平均 8 分钟完成终审
  4. merge

那个之前每天催我 review 的同事 A,现在每次 AI 评论发出来,他比我更认真地研究 AI 说了什么。

上周他跟我说:

"AI 给我找出了一个我自己写代码时没注意的空指针,这玩意儿比我认真。"


完整代码

完整的配置文件我放在下面,可以直接 copy 到你的项目里:

.github/workflows/ai-review.yml(上文已贴完整版)

.github/scripts/ai-review.js(上文已贴完整版)

需要的环境变量:

  • ANTHROPIC_API_KEY:从 Anthropic 控制台获取
  • GITHUB_TOKEN:GitHub Actions 自带,不用手动配置

配置完之后,去提一个测试 PR,看着 AI 自动开始 review,还挺有成就感的。


写在最后

这套方案不是为了让人偷懒的——而是让人的精力花在刀刃上

机械的检查(空值、类型、格式)让 AI 做,业务逻辑、架构判断、团队规范这些需要上下文的判断,留给人。

如果你的团队也有 CR 堆积的问题,可以直接拿这套配置用。有什么问题评论区说,我看到了会回。

点赞收藏一下,下次出团队提效工具合集时方便你找回来。

No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.