代码生成与校验规范
生成、校验、合并的流程约束
规则:AI 代码生成必须遵循”准备 → 生成 → 自检”三阶段流程,每阶段有明确的准入和准出条件。
[Requirement] 生成前必须明确:目标文件、修改范围、验收标准;三者缺一不得开始生成。
[Requirement] 生成后必须执行本地自检(编译/lint/测试),未通过不得提交。
[Standard] 单次生成的变更范围不超过 400 行(新增+修改),超过必须拆分任务。
┌─────────────┐ ┌─────────────┐ ┌─────────────┐│ 准备阶段 │ ──→ │ 生成阶段 │ ──→ │ 自检阶段 ││ (Prepare) │ │ (Generate) │ │ (Verify) │└─────────────┘ └─────────────┘ └─────────────┘ │ │ │ 明确目标文件 按规范生成代码 编译/lint/测试 加载相关上下文 注释+测试同步生成 未通过则回到生成 确认验收标准 控制单次变更范围 生成自检报告| 检查项 | 说明 | 未满足时处理 |
|---|---|---|
| 目标文件明确 | 知道要改哪个/哪些文件 | 先定位文件 |
| 修改范围明确 | 知道改什么、不改什么 | 先澄清需求 |
| 验收标准明确 | 知道怎样算完成 | 先编写验收标准 |
| 上下文已加载 | 相关代码/规范已读取 | 先检索上下文 |
示例:
# 生成前的准备输出(必须先完成)
目标文件:src/services/user.py修改范围:新增 register_user 函数,不修改现有函数验收标准: 1. 邮箱重复返回 409 2. 密码 bcrypt 哈希 3. 单元测试覆盖 3 种场景上下文:已读取 user.py、User 模型、email 服务反模式:
- 不做准备,直接让 AI”写个注册功能”
- 一次性生成整个模块上千行代码
- 生成后不运行,直接提交 PR
规则:AI 生成代码的校验分为”自动校验”和”人工校验”两层,自动校验通过后方可进入人工校验。
[Requirement] 自动校验必须包含:编译/语法检查、lint/format 检查、单元测试、安全扫描,四项全部通过。
[Requirement] 人工校验必须覆盖:业务逻辑正确性、边界条件、异常处理、可读性、安全风险。
[Standard] 自动校验在本地和 CI 各执行一次,本地通过才能提交,CI 通过才能合并。
[Suggestion] 对 AI 生成的复杂逻辑,增加”变异测试”验证测试用例的有效性。
| 阶段 | 检查项 | 工具示例 | 通过标准 |
|---|---|---|---|
| 语法 | 编译/类型检查 | python -m py_compile、mypy | 0 error |
| 规范 | lint / format | ruff、eslint、gofmt | 0 error |
| 测试 | 单元测试 | pytest、jest、go test | 全部通过 |
| 安全 | 漏洞扫描 | bandit、semgrep、npm audit | 无高危 |
| 质量 | 复杂度/重复率 | radon、sonar | 圈复杂度 ≤ 10 |
| 维度 | 检查问题 |
|---|---|
| 业务正确 | 逻辑是否符合需求?有没有遗漏场景? |
| 边界处理 | 空值、零值、最大值、并发是否处理? |
| 异常处理 | 异常是否捕获?是否向上传播?是否有兜底? |
| 可读性 | 命名是否清晰?注释是否充分?结构是否合理? |
| 安全 | 是否有注入风险?是否泄露敏感数据?权限是否校验? |
| 性能 | 是否有 N+1?是否有不必要的循环?缓存是否合理? |
示例:
# 本地自动校验脚本(Python 项目)
#!/bin/bash
set -e
echo "1. 语法检查..."
python -m compileall src/
echo "2. Lint 检查..."
ruff check src/ tests/
echo "3. 类型检查..."
mypy src/
echo "4. 单元测试..."
pytest tests/ -v --cov=src
echo "5. 安全扫描..."
bandit -r src/ -ll
echo "✅ 全部校验通过"反模式:
- 只跑编译通过就认为校验完成
- 人工校验只看代码能不能跑,不看逻辑对不对
- 安全扫描出警告直接忽略
规则:AI 生成代码的合并必须经过 PR 流程,满足”双校验 + 双审批”条件方可合入主干。
[Requirement] 必须通过 Pull Request 合并,禁止直接 push 到 main/master。
[Requirement] PR 必须通过全部 CI 检查,且至少 1 名人类 Reviewer 审批通过。
[Requirement] AI 生成的核心业务代码(涉及支付、权限、数据一致性),必须 2 人审批。
[Standard] PR 标题必须包含 [AI] 前缀,描述中必须标注 AI 使用信息。
[Default] 单个 PR 的 AI 生成代码不超过 400 行,超过必须拆分。
| 代码类型 | CI 通过 | 人工审批 | 额外要求 |
|---|---|---|---|
| 普通功能代码 | ✅ | 1 人 | 单元测试覆盖率达标 |
| 核心业务代码 | ✅ | 2 人 | 架构师 Review + 集成测试 |
| 安全相关代码 | ✅ | 2 人(含安全) | 安全扫描无任何警告 |
| 配置/文档变更 | ✅ | 1 人 | 无 |
示例:
# PR 标题[AI] feat(user): 新增用户注册接口
# PR 描述## AI 使用信息- 工具:GitHub Copilot- 生成范围:src/services/user.py (register_user) + tests/test_register.py- 上下文:User 模型、email 服务、注册需求文档
## 自检结果- ✅ ruff: 0 errors- ✅ mypy: 0 errors- ✅ pytest: 3 passed, coverage 92%- ✅ bandit: no issues
## Reviewer 重点- 邮箱唯一性的并发安全- 欢迎邮件失败时的事务边界反模式:
- AI 生成代码后直接
git push origin main - PR 只有 AI 自己的”审批”,没有人类 Reviewer
- 一个 PR 包含 10 个功能点,AI 生成了 2000 行代码
规则:所有 AI 生成的代码变更必须可回滚,回滚操作必须简单、快速、可验证。
[Requirement] 每次 AI 生成代码变更前,必须确保当前分支可回退到上一个稳定版本(有 tag 或明确的 commit)。
[Requirement] 数据库迁移(DDL)变更必须包含回滚脚本,且回滚脚本经过验证。
[Standard] 发布后 30 分钟内为观察期,发现异常立即回滚,不得”先修一下再说”。
[Default] 回滚优先使用 git revert,保留变更历史;仅在紧急情况下使用 git reset --hard。
| 级别 | 触发条件 | 响应时间 | 回滚方式 |
|---|---|---|---|
| P0 | 生产宕机、数据错误、安全漏洞 | 立即 | 回滚到上一版本 |
| P1 | 核心功能不可用、大面积报错 | 5 分钟内 | 回滚或热修复 |
| P2 | 非核心功能异常、可绕过 | 30 分钟内 | 评估后决定 |
发现异常 │ ▼1. 确认影响范围 → 判断 P0/P1/P2 │ ▼2. P0/P1:立即执行回滚 - 应用回滚:git revert + 重新部署 - 数据回滚:执行回滚迁移脚本 │ ▼3. 验证回滚成功 - 核心功能恢复 - 无新的错误日志 │ ▼4. 记录复盘 → 修复问题 → 重新发布示例:
# 代码回滚
git revert <ai-generated-commit-hash>
git push origin main
# CI 自动重新部署
# 数据库回滚(如使用 Alembic)
alembic downgrade -1反模式:
- 没有回滚方案就上线 AI 生成的代码
- 出问题后不回滚,而是在线上直接改代码”修一下”
- DDL 变更只有升级脚本,没有降级脚本
以下展示一个完整的 AI 代码生成、校验、合并、回滚的端到端示例。
目标:src/services/user.py 新增 register_user验收标准: - 邮箱唯一,重复返回 409 - 密码 bcrypt 哈希 - 注册成功发送欢迎邮件 - 单元测试覆盖 ≥ 3 场景上下文:User 模型、email 服务、注册需求# src/services/user.py
from sqlalchemy.orm import Session
from passlib.context import CryptContext
from src.models.user import User
from src.schemas.user import UserCreate
from src.services.email import send_welcome_email
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
def register_user(db: Session, data: UserCreate) -> User:
"""注册新用户。
Args:
db: 数据库会话。
data: 用户注册信息。
Returns:
创建的 User 对象。
Raises:
EmailAlreadyExists: 邮箱已存在时抛出。
"""
existing = db.query(User).filter(User.email == data.email).first()
if existing:
raise EmailAlreadyExists(f"邮箱 {data.email} 已注册")
user = User(
email=data.email,
password_hash=pwd_context.hash(data.password),
)
db.add(user)
db.commit()
db.refresh(user)
send_welcome_email(user.email)
return user# 自动校验
$ ruff check src/services/user.py
All checks passed!
$ mypy src/services/user.py
Success: no issues found
$ pytest tests/test_register.py -v
test_register_success PASSED
test_register_duplicate_email PASSED
test_register_invalid_email PASSED
$ bandit -r src/services/user.py
No issues identified.人工校验(Reviewer 批注):✅ 业务逻辑正确✅ 边界处理:重复邮箱已处理⚠️ 建议:send_welcome_email 失败时是否需要回滚用户创建? → 补充:邮件失败不影响注册,记录日志即可✅ 安全:密码已哈希,SQL 参数化PR: [AI] feat(user): 新增用户注册接口CI: ✅ 全部通过Reviewer: 1 人审批通过合并方式:Squash Merge回滚 commit: <merge-commit-hash>回滚命令: git revert <merge-commit-hash>数据回滚: 本变更无 DDL,无需数据回滚验证标准: 注册接口返回 404(接口不存在)即回滚成功