现在很多开发者已经不满足于让 GPT 写一个函数、解释一段报错了。
更常见的场景是:
- 让 GPT 看一段旧代码;
- 让 GPT 根据需求生成 patch;
- 让 GPT 补测试;
- 让 GPT 写 PR 描述;
- 让 GPT 根据 diff 总结变更影响;
- 让 GPT 帮忙提醒 Review 重点。
这确实比以前高效。
但也带来一个新问题:
AI 生成的代码,最后还是要进入 PR、Review、测试和合并流程。**
如果只停留在“GPT 帮我写了代码”,那还不算真正进入工程流。真正关键的是:
这段代码改了哪些文件?
有没有测试?
有没有改到配置?
有没有涉及鉴权、支付、订单、删除数据?
有没有对应文档?
Review 人应该重点看哪里?
这些问题不解决,AI 写得再快,也可能只是把风险更快地推到 PR 里。
这篇文章不讨论“怎么让 GPT 写更多代码”,而是写一个轻量级 Python 工具:
输入 git diff,输出 PR Review Checklist。**
目标是把 AI 生成代码后的检查动作标准化,避免开发者只看代码能不能跑,而忽略 Review 边界。
一、为什么需要从 diff 生成 Review Checklist?
很多团队使用 AI 编程工具时,会出现一个很典型的流程:
这个流程看起来没问题,但实际有几个风险。
第一,AI 生成代码经常只关注“完成需求”,不一定关注影响范围。
比如一个需求是“修复登录态丢失问题”,GPT 可能会修改 session、cookie、middleware、auth helper 等多个位置。代码能跑,不代表影响范围清楚。
第二,AI 可能漏测试。
它给你 patch,但没有提醒你应该补哪些单元测试、集成测试或回归测试。
第三,AI 可能动到高风险区域。
比如 payment、auth、admin、migration、delete、permission 这些关键词,一旦出现在 diff 里,Review 重点就完全不一样。
第四,PR 描述容易写得很漂亮,但 Review Checklist 很空。
PR 描述说“优化登录逻辑”,但 Reviewer 真正需要知道的是:
- 是否影响已有登录态;
- 是否影响 refresh token;
- 是否需要回归移动端;
- 是否涉及权限边界;
- 是否有兼容老数据。
所以,与其让 GPT 只写 PR 描述,不如先让脚本从 diff 里提取结构化信息,再生成 Review Checklist。
二、我们要实现什么?
这个脚本先做一个最小可用版本。
输入:一段 git diff 文本。
输出:一个 Review Checklist,包含:
- changed_files:变更文件列表;
- risk_keywords:命中的风险关键词;
- has_tests:是否包含测试文件;
- has_docs:是否包含文档变更;
- suggested_review_points:建议 Review 关注点;
- suggested_test_points:建议测试关注点;
- risk_level:整体风险等级。
这个工具不是替代 Reviewer,而是帮助 Reviewer 更快定位重点。
尤其在 AI 生成代码越来越多的情况下,Review 不应该只靠“看一遍感觉还行”。
三、输入示例:一段 git diff
假设我们有这样一段 diff:
diff –git a/src/auth/session.py b/src/auth/session.py
index 9f1a2aa..e31bc98 100644
— a/src/auth/session.py
+++ b/src/auth/session.py
@@ -12,7 +12,10 @@ def refresh_session(user_id, token):
– session = get_session(user_id)
– session.token = token
+ session = get_session(user_id)
+ if not session:
+ session = create_session(user_id)
+ session.token = token
session.save()
return session
diff –git a/src/payment/order.py b/src/payment/order.py
index 4d11aac..a91f0bc 100644
— a/src/payment/order.py
+++ b/src/payment/order.py
@@ -45,6 +45,9 @@ def update_order_status(order_id, status):
order = get_order(order_id)
+ if status == "PAID":
+ order.paid_at = now()
order.status = status
order.save()
return order
这段 diff 看起来不长,但已经涉及两个高风险点:
- auth;
- payment。
而且没有看到测试文件变化。
如果这个 PR 是 AI 生成的,就更应该让 Reviewer 重点关注:
- 登录态创建是否安全;
- session 是否会重复创建;
- 支付状态是否幂等;
- PAID 状态是否可能被重复写入;
- 是否需要补测试。
四、先定义数据结构
用 dataclass 定义 ReviewResult。
from dataclasses import dataclass, asdict
from typing import List, Dict
@dataclass
class ReviewResult:
changed_files: List[str]
risk_keywords: List[str]
has_tests: bool
has_docs: bool
risk_level: str
suggested_review_points: List[str]
suggested_test_points: List[str]
def to_dict(self) –> Dict:
return asdict(self)
字段设计尽量简单,方便后续导出 JSON,或者接入 CI、PR Bot、内部工具。
五、实现 diff 解析器
下面写一个基础版本。
import re
from dataclasses import dataclass, asdict
from typing import List, Dict, Set
@dataclass
class ReviewResult:
changed_files: List[str]
risk_keywords: List[str]
has_tests: bool
has_docs: bool
risk_level: str
suggested_review_points: List[str]
suggested_test_points: List[str]
def to_dict(self) –> Dict:
return asdict(self)
class DiffReviewChecklistGenerator:
def __init__(self):
self.risk_keyword_map = {
"auth": ["auth", "login", "session", "token", "permission", "role"],
"payment": ["payment", "order", "paid", "refund", "transaction"],
"database": ["migration", "schema", "delete", "drop", "truncate"],
"config": ["config", "env", "secret", "key"],
"admin": ["admin", "root", "superuser"],
}
self.test_patterns = [
"test_", "_test", "/tests/", "spec.", ".spec", ".test"
]
self.doc_patterns = [
".md", "docs/", "README"
]
def generate(self, diff_text: str) –> ReviewResult:
changed_files = self._extract_changed_files(diff_text)
risk_keywords = self._detect_risk_keywords(diff_text, changed_files)
has_tests = self._has_tests(changed_files)
has_docs = self._has_docs(changed_files)
risk_level = self._calculate_risk_level(
risk_keywords=risk_keywords,
has_tests=has_tests,
changed_files=changed_files,
)
suggested_review_points = self._suggest_review_points(
risk_keywords=risk_keywords,
has_tests=has_tests,
has_docs=has_docs,
)
suggested_test_points = self._suggest_test_points(
risk_keywords=risk_keywords,
has_tests=has_tests,
)
return ReviewResult(
changed_files=changed_files,
risk_keywords=sorted(risk_keywords),
has_tests=has_tests,
has_docs=has_docs,
risk_level=risk_level,
suggested_review_points=suggested_review_points,
suggested_test_points=suggested_test_points,
)
def _extract_changed_files(self, diff_text: str) –> List[str]:
files = re.findall(r"diff –git a/(.*?) b/(.*?)\\n", diff_text)
return sorted({target for _, target in files})
def _detect_risk_keywords(self, diff_text: str, changed_files: List[str]) –> Set[str]:
text = " ".join(changed_files) + "\\n" + diff_text
text = text.lower()
detected = set()
for category, keywords in self.risk_keyword_map.items():
for keyword in keywords:
if keyword.lower() in text:
detected.add(category)
break
return detected
def _has_tests(self, changed_files: List[str]) –> bool:
joined = "\\n".join(changed_files).lower()
return any(pattern.lower() in joined for pattern in self.test_patterns)
def _has_docs(self, changed_files: List[str]) –> bool:
joined = "\\n".join(changed_files)
return any(pattern in joined for pattern in self.doc_patterns)
def _calculate_risk_level(
self,
risk_keywords: Set[str],
has_tests: bool,
changed_files: List[str],
) –> str:
score = 0
if "payment" in risk_keywords:
score += 4
if "auth" in risk_keywords:
score += 3
if "database" in risk_keywords:
score += 4
if "config" in risk_keywords:
score += 2
if "admin" in risk_keywords:
score += 3
if len(changed_files) >= 5:
score += 2
if risk_keywords and not has_tests:
score += 2
if score >= 7:
return "high"
if score >= 4:
return "medium"
return "low"
def _suggest_review_points(
self,
risk_keywords: Set[str],
has_tests: bool,
has_docs: bool,
) –> List[str]:
points = []
if "auth" in risk_keywords:
points.append("重点检查登录态、权限边界、token 生命周期和异常分支。")
if "payment" in risk_keywords:
points.append("重点检查订单状态流转、支付幂等性、重复回调和异常回滚。")
if "database" in risk_keywords:
points.append("重点检查数据库迁移、删除操作、兼容性和回滚方案。")
if "config" in risk_keywords:
points.append("重点检查配置变更是否影响不同环境,避免泄露密钥。")
if "admin" in risk_keywords:
points.append("重点检查管理员权限、角色边界和越权风险。")
if not has_tests:
points.append("当前 diff 未检测到测试文件变更,建议 Reviewer 重点确认测试覆盖。")
if not has_docs:
points.append("当前 diff 未检测到文档变更,如接口或行为变化明显,建议补充说明。")
if not points:
points.append("未检测到明显高风险关键词,仍需按常规流程进行代码审查。")
return points
def _suggest_test_points(
self,
risk_keywords: Set[str],
has_tests: bool,
) –> List[str]:
points = []
if "auth" in risk_keywords:
points.extend([
"补充登录态不存在时的测试。",
"补充 token 刷新失败时的测试。",
"补充并发刷新 session 的测试。",
])
if "payment" in risk_keywords:
points.extend([
"补充重复支付回调测试。",
"补充订单状态从未支付到已支付的测试。",
"补充支付状态重复写入的幂等性测试。",
])
if "database" in risk_keywords:
points.extend([
"补充迁移前后数据兼容测试。",
"补充回滚路径测试。",
])
if not has_tests:
points.append("至少补充一组与本次变更直接相关的单元测试或回归测试。")
if not points:
points.append("根据业务影响范围补充必要的回归测试。")
return points
这个脚本做的事情比较明确:
- 从 diff 中提取变更文件;
- 根据文件名和 diff 内容识别风险类别;
- 判断是否有测试文件;
- 判断是否有文档变更;
- 根据风险类别生成 Review 建议;
- 根据风险类别生成测试建议。
它不追求完全智能,但足够做一层基础过滤。

六、运行示例
把前面的 diff 输入进去:
diff_text = """
diff –git a/src/auth/session.py b/src/auth/session.py
index 9f1a2aa..e31bc98 100644
— a/src/auth/session.py
+++ b/src/auth/session.py
@@ -12,7 +12,10 @@ def refresh_session(user_id, token):
– session = get_session(user_id)
– session.token = token
+ session = get_session(user_id)
+ if not session:
+ session = create_session(user_id)
+ session.token = token
session.save()
return session
diff –git a/src/payment/order.py b/src/payment/order.py
index 4d11aac..a91f0bc 100644
— a/src/payment/order.py
+++ b/src/payment/order.py
@@ -45,6 +45,9 @@ def update_order_status(order_id, status):
order = get_order(order_id)
+ if status == "PAID":
+ order.paid_at = now()
order.status = status
order.save()
return order
"""
generator = DiffReviewChecklistGenerator()
result = generator.generate(diff_text)
print(result.to_dict())
输出示例:
{
'changed_files': [
'src/auth/session.py',
'src/payment/order.py'
],
'risk_keywords': [
'auth',
'payment'
],
'has_tests': False,
'has_docs': False,
'risk_level': 'high',
'suggested_review_points': [
'重点检查登录态、权限边界、token 生命周期和异常分支。',
'重点检查订单状态流转、支付幂等性、重复回调和异常回滚。',
'当前 diff 未检测到测试文件变更,建议 Reviewer 重点确认测试覆盖。',
'当前 diff 未检测到文档变更,如接口或行为变化明显,建议补充说明。'
],
'suggested_test_points': [
'补充登录态不存在时的测试。',
'补充 token 刷新失败时的测试。',
'补充并发刷新 session 的测试。',
'补充重复支付回调测试。',
'补充订单状态从未支付到已支付的测试。',
'补充支付状态重复写入的幂等性测试。',
'至少补充一组与本次变更直接相关的单元测试或回归测试。'
]
}
这个输出比“请帮我写一个 PR 描述”更有价值。
因为它直接告诉 Reviewer:
- 这次变更涉及 auth 和 payment;
- 风险等级是 high;
- 没有测试文件;
- 没有文档变更;
- Review 应重点看登录态和支付状态;
- 测试至少要补哪些场景。
这才是 AI 生成代码进入工程流程时应该补上的一环。
七、生成 PR Review Prompt
有了结构化结果之后,还可以把它转成 Prompt,让 GPT 帮忙写 PR Review Checklist。
def build_review_prompt(result: ReviewResult) –> str:
review_points = "\\n".join(
f"- {point}" for point in result.suggested_review_points
)
test_points = "\\n".join(
f"- {point}" for point in result.suggested_test_points
)
files = "\\n".join(f"- {file}" for file in result.changed_files)
return f"""
你是一个代码审查助手。
请根据下面的 diff 分析结果,生成 PR Review Checklist。
要求:
1. 不要直接判断代码可以合并。
2. 必须区分 Review 重点和测试重点。
3. 如果 risk_level 是 high,必须提醒需要人工重点复核。
4. 不要使用“保证没问题”“可以直接上线”等表达。
5. 输出格式使用 Markdown Checklist。
变更文件:
{files}
风险类别:
{", ".join(result.risk_keywords) or "无明显风险类别"}
风险等级:
{result.risk_level}
Review 关注点:
{review_points}
测试关注点:
{test_points}
"""
调用:
prompt = build_review_prompt(result)
print(prompt)
输出的 Prompt 可以直接交给 GPT,让它生成更规范的 PR Review 文本。
注意这里的分工:
- Python 负责结构化 diff;
- GPT 负责把结构化信息变成可读 Checklist;
- Reviewer 负责最终判断。
这样比直接把 diff 丢给 GPT 更稳。
八、Prompt 输出示例
GPT 最终可以生成类似这样的 Checklist:
## PR Review Checklist
### 变更范围
– [ ] 确认 `src/auth/session.py` 中 session 不存在时自动创建的逻辑符合预期。
– [ ] 确认 `src/payment/order.py` 中 `paid_at` 写入不会破坏原有订单状态流转。
### 权限与登录态
– [ ] 检查 session 重复创建或并发刷新时是否会产生脏数据。
– [ ] 检查 token 生命周期是否受到影响。
– [ ] 检查异常分支是否有明确处理。
### 支付与订单
– [ ] 检查支付回调重复触发时是否具备幂等性。
– [ ] 检查订单状态重复写入是否会影响后续流程。
– [ ] 检查异常回滚路径是否明确。
### 测试要求
– [ ] 补充登录态不存在时的测试。
– [ ] 补充 token 刷新失败时的测试。
– [ ] 补充重复支付回调测试。
– [ ] 补充订单状态幂等性测试。
### 人工复核
– [ ] 当前变更风险等级为 high,需要人工重点复核后再考虑合并。
这就是比较理想的 AI 辅助方式。
不是让 GPT 直接告诉你“能不能合并”,而是让它帮你把 Review 注意事项列清楚。
九、传统 Review vs GPT 辅助 Review

这张表的核心不是“让 GPT 替代 Review”。
而是:
让 GPT 帮忙整理 Review 材料,让 Reviewer 更快看重点。
十、进一步扩展:接入 Git 命令
实际使用时,可以直接从 git diff 获取输入。
import subprocess
def get_git_diff(base_branch: str = "main") –> str:
result = subprocess.run(
["git", "diff", f"{base_branch}…HEAD"],
capture_output=True,
text=True,
check=True,
)
return result.stdout
if __name__ == "__main__":
diff_text = get_git_diff("main")
generator = DiffReviewChecklistGenerator()
result = generator.generate(diff_text)
prompt = build_review_prompt(result)
with open("pr_review_prompt.md", "w", encoding="utf-8") as f:
f.write(prompt)
print("PR Review Prompt 已生成:pr_review_prompt.md")
这样就可以把它作为一个本地小工具使用。
后续还可以做成:
- pre-push 检查;
- CI Job;
- GitHub Action;
- PR Bot;
- 内部代码审查插件。
十一、技术边界提醒

⚠️ 第一,关键词识别会误报。
比如文件里出现 order,不一定真的涉及支付风险。
所以脚本输出只是提醒,不是最终结论。
⚠️ 第二,关键词识别也会漏报。
如果高风险逻辑没有明显命名,脚本可能检测不到。
所以不能只靠脚本。
⚠️ 第三,GPT 不应该直接判断能不能合并。
它可以生成 Review Checklist,但最终是否合并必须由 Reviewer 和团队流程决定。
⚠️ 第四,测试建议不等于测试覆盖。
脚本可以提示补哪些测试,但测试是否真的覆盖风险,还要人工确认。
⚠️ 第五,不要把敏感 diff 随便丢给外部工具。
涉及密钥、内部配置、客户数据、未公开业务逻辑时,要先脱敏,并遵守团队安全规范。
十二、最后:新手程序员不要先追工具,先看自己有没有真实代码流程
如果只是偶尔问 GPT 一个语法、解释一段报错、写一个小函数,普通问答已经能覆盖不少轻量场景。
但如果你已经经常把 GPT 放进开发流程,比如读 diff、补测试、写 PR 描述、整理 Review Checklist、分析日志、理解旧项目,那就说明它正在进入真实工作流。
这时再考虑更稳定的能力,才比较合理。
如果你正在判断自己是否已经进入这种阶段,可以把 gpt43.com 当作一个新手买前判断参考入口,重点对照 ChatGPT Plus 和 编程场景常用 这两类场景,看自己是轻量问答,还是已经开始把 AI 放进真实代码流程。它更适合放在最后做边界核对,而不是一开始替你做决定。
十三、总结
AI 生成代码越来越快,但代码进入工程流程,不能只看“能不能生成”。
更稳的做法是:
先用 git diff 提取变更范围;
再识别风险类别;
再检查有没有测试和文档;
再生成 Review Checklist;
最后由 Reviewer 判断能不能合并。
GPT 可以帮你写代码,也可以帮你整理 Review 材料。
但它不应该替你做最终合并决定。
📌 对开发者来说,真正可靠的 AI 编程工作流,不是“让 GPT 多写点代码”,而是“让 GPT 生成的东西能被检查、能被测试、能被 Review、能被追踪”。

![pip install安装markitdown时出现ERROR: ‘packages/markitdown[all]‘ is not a valid editable requirement解决方案-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260823004656-6a8a430045592-220x150.png)
![pip install安装markitdown时出现ERROR: ‘packages/markitdown[all]‘ is not a valid editable requirement解决方案-171主机测评](https://www.171host.com/wp-content/uploads/2026/08/20260823004339-6a8a423bd3e97-220x150.png)

