GitHub Copilot 代码审查实战:在 Pull Request 中用好自动审查与自定义指令

2026-06-03 17 预计阅读时间:1 分钟
来源:realpython.com AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:11 分钟

GitHub Copilot 的代码审查功能已经从"实验性标签"走向正式可用。它能在 PR 提交时自动生成审查意见,也支持你通过自定义指令(custom instructions)引导审查方向,而不是被动接受通用建议。这篇文章把关键配置和实操要点梳理清楚,帮你把 Copilot Review 从"偶尔看看"变成日常流程的一部分。

自动审查:让每一条 PR 都有第一轮反馈

Copilot Code Review 的自动审查(automatic review)是核心入口。开启后,每当 PR 创建或更新时,Copilot 会自动扫描变更并给出意见,不需要手动触发。

开启方式

在仓库的 Settings → Code review → Copilot 中勾选自动审查即可。但更可控的做法是通过仓库的 YAML 配置文件来管理,这样配置变更也有版本记录:

# .github/copilot-review.yml
# 启用 Copilot 自动代码审查
auto_review:
  enabled: true
  # 触发事件:PR 创建时自动审查
  on_create: true
  # PR 更新(新 commit 推入)时也自动审查
  on_update: true

把这个文件提交到仓库默认分支,Copilot 就会按配置行动。如果只想在特定分支上启用,可以结合 GitHub 的分支保护规则做过滤——在 Settings → Branches → Branch protection rules 中,对目标分支勾选 "Require pull request reviews before merging",Copilot 的自动审查意见会出现在这条 PR 的 review 列表中。

需要注意:Copilot 的审查意见不会计入 GitHub 要求的人工 review 数量。它提供的是"第一轮快速扫描",真正合并仍需人工审批。

自定义指令:告诉 Copilot 你关心什么

默认情况下,Copilot 会从通用角度审查代码——变量命名、潜在 bug、性能问题等。但每个团队有自己的关注点:你可能要求所有 API 返回统一错误格式,或者禁止直接使用 datetime.now() 而必须走项目封装的时钟工具。

自定义指令(custom instructions)就是用来注入这些团队规则的。

在仓库中添加指令文件

创建 .github/copilot-instructions.md,用自然语言描述你希望 Copilot 遵循的审查重点:

# .github/copilot-instructions.md

## 代码审查重点

- 所有对外 API 必须返回统一 JSON 结构:`{"code": int, "message": str, "data": any}`,缺少此结构的代码应被标记。
- 禁止直接调用 `datetime.datetime.now()`,必须使用 `app.utils.clock.now()` 以便测试时 mock。
- 数据库查询禁止在循环中逐条执行,必须批量操作。
- 新增的 public 函数必须有 docstring,格式遵循 Google Style。
- 所有 HTTP 请求必须设置超时,不允许无 timeout 的 `requests.get` 调用。

这段指令会被 Copilot 在审查 PR 时读取并作为额外上下文。效果是明显的:当 PR 中出现裸调用 datetime.now(),Copilot 会直接指出应替换为 app.utils.clock.now(),而不是只泛泛地说"考虑可测试性"。

指令编写要点

几条实践建议:

  1. 具体优于抽象——"注意性能"是废话,"禁止循环内逐条 DB 查询"是可执行的规则。
  2. 给出正面示例——与其只说"不要用 X",不如写"用 Y 替代 X,示例:from app.utils.clock import now"。
  3. 控制在 10 条以内——指令过长会被截断或稀释权重,聚焦最关键的规则。
  4. 和团队 lint 规则对齐——如果 Ruff/Pylint 已经检查了某条规则,不必在 Copilot 指令中重复,让 Copilot 补充静态分析覆盖不到的部分(如架构约定、业务约束)。

实操:一条 PR 的完整审查流程

下面用一个具体场景走一遍流程。假设你提交了一条修改用户查询接口的 PR。

提交前:本地快速自查

虽然 Copilot 审查发生在 PR 端,但本地可以先跑一遍规则检查,减少来回往返:

# 用 ruff 检查 lint 规则(和 copilot-instructions.md 中对齐的部分)
ruff check app/api/user_query.py

# 用 pytest 跑相关测试
pytest tests/api/test_user_query.py -v

本地通过后提交 PR:

git checkout -b feat/user-query-batch
git add app/api/user_query.py
git commit -m "refactor: batch user query to avoid N+1 DB calls"
git push origin feat/user-query-batch

# 通过 GitHub CLI 创建 PR(可选,也可在网页端操作)
gh pr create \
  --title "refactor: batch user query to avoid N+1 DB calls" \
  --body "将逐条查询改为批量查询,减少数据库往返次数。"

PR 端:Copilot 自动审查结果

PR 创建后,Copilot 会在几分钟内提交审查意见。假设你的改动中有一处遗漏:

# app/api/user_query.py — PR 中的代码片段

import datetime  # ← 问题:直接 import datetime

from app.db import get_session

def query_users(user_ids: list[str]):
    """批量查询用户信息"""
    results = []
    for uid in user_ids:  # ← 问题:仍是逐条查询
        user = get_session().execute(
            f"SELECT * FROM users WHERE id = '{uid}'"
        )
        results.append(user)
    return {
        "results": results  # ← 问题:不符合统一 API 返回格式
    }

Copilot 结合你的自定义指令,会给出三条针对性意见:

  • datetime import:根据指令,应使用 app.utils.clock.now() 替代 datetime.datetime.now()。当前虽未直接调用 now(),但引入了 datetime 模块,后续容易违规,建议移除。
  • 循环逐条查询:违反"禁止循环内逐条 DB 查询"规则,应改为批量 WHERE id IN (...) 查询。
  • 返回格式:缺少统一 {"code", "message", "data"} 结构。

修复后重新提交

# app/api/user_query.py — 修复后

from app.utils.clock import now  # 使用项目封装的时钟
from app.db import get_session

def query_users(user_ids: list[str]) -> dict:
    """批量查询用户信息,返回统一 API 格式。

    Args:
        user_ids: 用户 ID 列表。

    Returns:
        包含 code/message/data 的统一响应字典。
    """
    session = get_session()
    placeholders = ",".join(["?"] * len(user_ids))
    rows = session.execute(
        f"SELECT * FROM users WHERE id IN ({placeholders})",
        user_ids
    )
    return {
        "code": 0,
        "message": "success",
        "data": list(rows)
    }

推送新 commit 后,Copilot 会根据 on_update: true 配置再次自动审查,确认问题已修复。

手动触发审查:针对特定文件的深度检查

自动审查覆盖整个 PR diff,有时你只想让 Copilot 重点看某几个文件。GitHub 支持在 PR 界面手动请求 Copilot 审查:

  1. 在 PR 页面右侧 "Reviewers" 区域,点击 "Request review"。
  2. 选择 @github-copilot 作为审查者。
  3. 可在评论框中附加具体指令,例如:@github-copilot 请重点审查 app/api/user_query.py 的 SQL 注入风险

这种手动触发适合两种场景:

  • 大 PR 的聚焦审查——改动 50 个文件时,自动审查可能分散注意力,手动指定关键文件更有效。
  • 补充审查——自动审查已通过,但你对自己不太确定的部分想再要一轮意见。

采纳建议与边界认知

Copilot Code Review 是加速器,不是决策者。实际使用中有几条边界需要认清:

场景 Copilot 能做的 Copilot 做不到的
代码风格与约定 根据自定义指令精准标记违规 理解团队未写成文档的隐性习惯
逻辑 bug 检测 发现明显的空指针、未处理异常 理解复杂业务逻辑的语义正确性
安全漏洞 标记 SQL 拼接、硬编码密钥 判断权限模型是否符合业务需求
性能问题 标记 N+1 查询、无 timeout 请求 评估真实负载下的瓶颈

建议的采纳流程

  1. Copilot 意见到达后,快速分类:明确违规 → 立刻修;有争议 → 留评论讨论;误报 → 标记并忽略。
  2. 对误报类型做记录,定期更新 copilot-instructions.md 来减少同类误报。
  3. 人工审查者把精力集中在 Copilot 覆盖不到的区域:业务语义、架构影响、跨模块联动。

配置清单

上线 Copilot Code Review 前后,跑一遍这个清单:

  • [ ] 仓库 Settings 中已启用 Copilot Code Review
  • [ ] .github/copilot-review.yml 已提交,auto_review.enabled: true
  • [ ] .github/copilot-instructions.md 已提交,包含 ≤10 条具体规则
  • [ ] 指令内容与现有 lint/CI 规则无重复
  • [ ] 分支保护规则中人工 review 要求未被取消(Copilot 不替代人工审批)
  • [ ] 团队已约定 Copilot 意见的处理流程(修/讨论/忽略)
  • [ ] 首周运行后复盘:统计误报率,调整指令措辞

Copilot Code Review 的价值不在于它多聪明,而在于它把团队已有的规则以低成本、高频率的方式持续执行。把指令写具体、把流程定清楚,它就能从"偶尔给点建议"变成"每条 PR 的第一道关卡"。


相关推荐