# AI 辅助代码审查与团队协作

> 代码审查是软件质量的最后一道防线,但传统 Code Review 有两个痛点:**速度慢**(等待审查者排期)和**不一致**(不同审查者标准不同)。AI 辅助代码审查不是替代人类审查,而是把机械性的检查(安全漏洞、编码规范、常见 Bug 模式)交给 AI,让人类审查者专注于架构合理性和业务逻辑。本章构建一套 AI + 人类协作的代码审查体系。

## 1. AI 代码审查的定位

### 1.1 AI 擅长审查什么

| 审查维度 | AI 能力 | 人类优势 |
|---------|---------|---------|
| **安全漏洞** | ★★★★★ 模式匹配极强 | 业务级权限逻辑 |
| **编码规范** | ★★★★★ 一致性完美 | 风格的"味道"判断 |
| **常见 Bug** | ★★★★ 已知模式检测 | 隐含的业务 Bug |
| **性能问题** | ★★★★ N+1、缺少索引 | 架构级性能瓶颈 |
| **类型安全** | ★★★★ 类型推断准确 | 泛型设计合理性 |
| **架构合理性** | ★★ 模式建议 | ★★★★★ 全局判断 |
| **业务正确性** | ★ 缺少领域知识 | ★★★★★ 业务经验 |
| **代码可读性** | ★★★ 命名建议 | ★★★★ 整体叙事 |

**结论**:AI 做第一轮审查(安全、规范、常见问题),人类做第二轮审查(架构、业务、可读性)。

### 1.2 审查流程设计

```
开发者提交 PR
    │
    ▼
┌─────────────────┐
│ AI 自动审查      │ ← 立即触发,几分钟内完成
│ - 安全扫描       │
│ - 规范检查       │
│ - Bug 模式检测   │
│ - 性能警告       │
└───────┬─────────┘
        │
    AI 审查通过?
    ├── 否 → 开发者修复 → 重新触发 AI 审查
    │
    ▼
┌─────────────────┐
│ 人类审查         │ ← AI 已过滤掉低级问题
│ - 架构合理性     │
│ - 业务正确性     │
│ - 代码可读性     │
│ - 测试充分性     │
└───────┬─────────┘
        │
    人类审查通过?
    ├── 否 → 开发者修改 → 重新审查
    │
    ▼
  合并到 main
```

## 2. 本地 AI 代码审查

### 2.1 Claude Code 审查

在提交 PR 前用 Claude Code 做本地审查:

```bash
# 审查当前分支相对 main 的所有改动
$ claude
> 审查我当前分支(feat/notifications)相对于 main 的所有改动。

  审查维度和优先级:
  
  P0 - 安全(必须修复):
  - SQL 注入(拼接 SQL 字符串)
  - XSS(未转义用户输入到 HTML)
  - 权限绕过(缺少 requirePermission 或 tenantId 过滤)
  - 敏感数据泄露(API 返回密码、Token 等)
  
  P1 - Bug 风险(建议修复):
  - 未处理的 null/undefined
  - 缺少错误处理
  - 竞态条件
  - 类型不安全(as any, @ts-ignore)
  
  P2 - 性能(建议优化):
  - N+1 查询
  - 缺少数据库索引
  - 不必要的重渲染
  - 大数据量未分页
  
  P3 - 规范(可选改进):
  - 不符合 CLAUDE.md 编码规范
  - 命名不清晰
  - 缺少类型定义
  
  输出格式:按优先级分组,每条包含文件名、行号、问题描述、修复建议。
```

### 2.2 Cursor 审查

在 Cursor 中审查特定文件:

```
// Chat Panel (Cmd+L)

审查 @lib/actions/notification.ts,重点检查:

1. 每个 Server Action 是否有权限检查
2. 输入是否都用 zod 验证了
3. 数据库查询是否都过滤了 tenantId
4. 错误处理是否返回 { error: string } 格式
5. 是否有未 await 的异步操作

参考项目规范:@.cursorrules
```

### 2.3 预提交审查脚本

把 AI 审查集成到 Git hooks:

```ts
// scripts/ai-review.ts
import { execSync } from 'child_process'

const diff = execSync('git diff main...HEAD --name-only').toString()
const changedFiles = diff.trim().split('\n')

// 只审查业务代码,跳过配置文件和测试
const filesToReview = changedFiles.filter(f =>
  (f.startsWith('lib/') || f.startsWith('app/') || f.startsWith('components/')) &&
  !f.includes('__tests__') &&
  !f.includes('.config.')
)

if (filesToReview.length === 0) {
  console.log('No business files to review.')
  process.exit(0)
}

const prompt = `
Review these changed files for security issues only (P0):
- SQL injection
- XSS
- Missing auth/permission checks
- Sensitive data exposure

Files: ${filesToReview.join(', ')}

Output: JSON array of issues, or empty array if no issues found.
Format: [{ "file": "...", "line": N, "severity": "P0", "issue": "...", "fix": "..." }]
`

// 调用 Claude Code 或其他 AI API
const result = execSync(`claude -p "${prompt}" --output-format json`).toString()
const issues = JSON.parse(result)

if (issues.length > 0) {
  console.error('⚠️  Security issues found:')
  issues.forEach((i: any) => console.error(`  ${i.file}:${i.line} - ${i.issue}`))
  process.exit(1)
}

console.log('✅ No security issues found.')
```

## 3. CI/CD 集成自动审查

### 3.1 GitHub Actions + AI 审查

```yaml
# .github/workflows/ai-review.yml
name: AI Code Review

on:
  pull_request:
    types: [opened, synchronize]

permissions:
  pull-requests: write
  contents: read

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

      - name: Get changed files
        id: changed
        run: |
          FILES=$(git diff --name-only origin/main...HEAD | grep -E '^(lib|app|components)/' | grep -v '__tests__' | tr '\n' ' ')
          echo "files=$FILES" >> $GITHUB_OUTPUT

      - name: AI Security Review
        if: steps.changed.outputs.files != ''
        uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            Review these files for security vulnerabilities:
            ${{ steps.changed.outputs.files }}
            
            Check for:
            - SQL injection
            - XSS vulnerabilities
            - Missing authentication/authorization
            - Sensitive data exposure
            - Input validation issues
            
            Post findings as PR review comments.

      - name: AI Convention Review
        if: steps.changed.outputs.files != ''
        uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          prompt: |
            Review these files against project conventions:
            ${{ steps.changed.outputs.files }}
            
            Conventions:
            - Server Components by default
            - Server Actions for mutations (not API routes)
            - All DB queries must include tenantId
            - Zod validation for all inputs
            - Error format: { error: string }
            
            Only report violations, not suggestions.
```

### 3.2 审查结果格式化

AI 审查的结果应该直接以 PR Comment 的形式呈现:

```markdown
## 🤖 AI Code Review

### 🔴 P0 - Security Issues (1)

**lib/actions/user.ts:42** - Missing tenantId filter
```ts
// Current (UNSAFE):
const user = await db.select().from(users).where(eq(users.id, userId))

// Should be:
const user = await db.select().from(users).where(
  and(eq(users.id, userId), eq(users.tenantId, tenantId))
)
```

### 🟡 P1 - Bug Risks (2)

**lib/actions/notification.ts:78** - Unhandled null case
> `notification` could be null if it was deleted between the check and the update. Add a null guard.

**components/notification-bell.tsx:23** - Missing cleanup
> `setInterval` in `useEffect` without cleanup will cause memory leaks. Add `clearInterval` in the return function.

### 🟢 P2 - Performance (1)

**app/(dashboard)/projects/page.tsx:15** - Consider parallel data fetching
> `getProjects()` and `getStats()` are independent queries. Use `Promise.all()` to fetch them in parallel.

### Summary
- **Files reviewed**: 8
- **Issues found**: 4 (1 P0, 2 P1, 1 P2)
- **Recommendation**: Fix P0 before merging
```

## 4. 质量评估体系

### 4.1 代码质量评分

让 AI 对每次 PR 给出量化评分:

```
审查完成后,请给出代码质量评分(0-100):

评分维度(各 20 分):
1. 安全性:无漏洞=20,有 P1=10,有 P0=0
2. 正确性:错误处理完善=20,部分缺失=10,大量缺失=0
3. 规范性:完全符合规范=20,轻微偏差=15,不符合=0
4. 可维护性:类型完善+命名清晰=20,部分模糊=10
5. 测试覆盖:有充分测试=20,部分测试=10,无测试=0

总分 = 各维度之和
- 90+: 可直接合并
- 70-89: 建议修改后合并
- <70: 需要重写部分代码
```

### 4.2 审查清单模板

```markdown
## Next.js SaaS PR 审查清单

### 安全
- [ ] Server Actions 有 requirePermission() 检查
- [ ] 数据库查询包含 tenantId 过滤
- [ ] 用户输入经过 zod 验证
- [ ] 敏感数据不出现在 Client Component props
- [ ] API Routes 验证了认证 token
- [ ] 没有硬编码的密钥或密码

### 数据
- [ ] 新表有 id, tenantId, createdAt, updatedAt
- [ ] 外键有对应索引
- [ ] Schema 变更有迁移文件
- [ ] 大量数据查询有分页

### 前端
- [ ] 默认使用 Server Component
- [ ] 'use client' 只在必要时使用
- [ ] 表单有 loading 和 error 状态
- [ ] 使用 Suspense 和 Skeleton fallback

### 测试
- [ ] 新功能有对应单元测试
- [ ] 关键路径有 E2E 测试
- [ ] 测试覆盖正常和异常场景
```

## 5. 团队规范落地

### 5.1 用 AI 检测规范偏差

团队编码规范写在文档里,但执行往往靠自觉。AI 可以自动化检测:

```bash
# Claude Code 规范检测命令
> 扫描 lib/actions/ 目录,检查以下规范是否被遵守:

  规则 1:每个 Server Action 必须以 'use server' 开头
  规则 2:每个 Action 必须调用 requirePermission()
  规则 3:所有输入必须用 zod schema 验证
  规则 4:返回类型必须是 { data?: T, error?: string }
  规则 5:mutation 后必须调用 revalidatePath()
  
  输出违规列表:文件名 + 行号 + 违反的规则 + 修复建议
```

### 5.2 自动修复规范问题

```bash
> 修复 lib/actions/ 目录下所有不符合规范的代码:

  1. 缺少 requirePermission → 在函数开头添加
  2. 缺少 zod 验证 → 根据参数类型生成 schema
  3. throw new Error → 改为 return { error: message }
  4. 缺少 revalidatePath → 在 mutation 成功后添加
  
  修改前后运行 pnpm test 确保功能不受影响。
```

### 5.3 新人引导

AI 审查对新加入团队的成员特别有价值:

```bash
# 新人的第一个 PR
> 这是新同事提交的第一个 PR。请用教学的语气审查:
  - 指出不符合项目规范的地方,并解释为什么这么规定
  - 给出修改示例
  - 表扬做得好的地方
  
  参考项目规范:CLAUDE.md
```

## 6. 协作模式

### 6.1 AI + 人类双审模式

```
PR 创建
  ↓
[AI 审查] 自动触发(2-3 分钟)
  ↓
[开发者] 修复 AI 发现的问题
  ↓
[AI 重新审查] 确认问题已修复
  ↓
[人类审查者] 重点看:
  - 架构是否合理?
  - 业务逻辑是否正确?
  - 是否有更好的实现方式?
  - 这个改动会影响其他模块吗?
  ↓
[合并]
```

### 6.2 分级审查

不是所有 PR 都需要同等级别的审查:

| PR 类型 | AI 审查 | 人类审查 | 说明 |
|---------|--------|---------|------|
| **文档/配置** | 跳过 | 快速浏览 | 风险低 |
| **UI 调整** | 规范检查 | 视觉验证 | 截图对比 |
| **普通功能** | 全面审查 | 1 人审查 | 标准流程 |
| **核心模块** | 全面审查 | 2 人审查 | 支付、认证等 |
| **数据库变更** | 安全审查 | 2 人审查 + DBA | 不可逆操作 |

### 6.3 审查效率数据

引入 AI 审查后的典型改善:

| 指标 | 纯人类审查 | AI + 人类 | 改善 |
|------|-----------|----------|------|
| **首次审查时间** | 4-8 小时 | 5 分钟(AI)+ 2 小时(人类) | -60% |
| **审查轮次** | 2.8 轮 | 1.5 轮 | -46% |
| **生产 Bug 率** | 基线 | -35% | 安全问题大幅减少 |
| **审查者负担** | 100% | ~50% | 低级问题 AI 处理 |

## 7. 安全审查专项

### 7.1 OWASP Top 10 检测

```
审查以下文件,按 OWASP Top 10 逐项检查:

@app/api/
@lib/actions/

检查项:
A01 - Broken Access Control(缺少权限检查)
A02 - Cryptographic Failures(明文存储敏感数据)
A03 - Injection(SQL 注入、XSS、命令注入)
A04 - Insecure Design(缺少速率限制、缺少验证)
A05 - Security Misconfiguration(暴露调试信息)
A07 - Authentication Failures(会话管理缺陷)

输出格式:
| OWASP 编号 | 文件 | 行号 | 风险等级 | 描述 | 修复建议 |
```

### 7.2 敏感数据审查

```
扫描整个项目,查找以下敏感数据泄露风险:

1. 硬编码的密钥或 Token(grep: API_KEY, SECRET, TOKEN, PASSWORD)
2. .env 文件是否在 .gitignore 中
3. 客户端代码中是否引用了 process.env(不含 NEXT_PUBLIC_ 前缀)
4. API 响应中是否包含密码哈希、内部 ID、或调试信息
5. 日志中是否打印了敏感数据

只报告确认的问题,不报告误报。
```

## 本章小结

- **AI + 人类双审**:AI 处理安全/规范/常见 Bug,人类关注架构/业务/可读性
- **本地审查**:提交前用 Claude Code 或 Cursor 做自审,减少 PR 返工
- **CI/CD 集成**:GitHub Actions 自动触发 AI 审查,结果以 PR Comment 呈现
- **质量评分**:五维度量化评分(安全/正确/规范/可维护/测试),90+ 可直接合并
- **规范自动化**:用 AI 检测并修复编码规范偏差,比人工检查更一致
- **分级审查**:文档跳过、UI 快速、普通 1 人、核心 2 人,效率最大化
- **安全专项**:OWASP Top 10 逐项检查 + 敏感数据扫描
- **效率提升**:首次审查时间 -60%,审查轮次 -46%,生产 Bug -35%