用 Codex/Claude Code 写代码,为什么一定要配合 Git 分支和 PR?
Codex、Claude Code 这类 coding agent 已经不是“帮你写一段代码”的聊天工具。它们可以进入本地仓库,读文件、改文件、执行命令、跑测试、看 diff,然后继续修。
这也是它们危险的地方:它们改的是你的真实项目。
如果没有 Git 分支和 PR 流程,agent 写代码的速度越快,越容易把风险放大。它可能顺手改了无关文件,可能把本地配置、生成文件、别人正在改的代码一起带进来,也可能在你没看懂的情况下执行了破坏性命令。
所以结论先说清楚:用 Codex/Claude Code 做真实项目开发时,分支和 PR 不是团队仪式,而是最低工程护栏。
为什么不能直接在主分支上让 agent 改?
主分支应该代表一个相对稳定、可部署、可回滚的状态。即使是个人项目,也最好把主分支当成“当前可信版本”,而不是实验场。
coding agent 的工作方式和人不一样。人改代码时通常会在脑子里保留边界:这次只修这个接口,只动这个组件,只加这几个测试。agent 虽然也能遵守指令,但它会根据上下文主动探索,可能读到相邻文件后认为“顺手修一下”更合理。
这类主动性很有价值,但不能直接落在主分支上。
分支隔离解决的是三个问题:
- 隔离未完成工作:agent 可以多轮尝试、失败、修正,不影响主分支。
- 隔离别人改动:多人仓库里,当前工作区可能已经有别人的未提交文件,分支和 diff 能帮助你看清边界。
- 隔离回滚成本:如果方向错了,丢弃一个分支比清理主分支上的混乱改动容易得多。
真正稳的流程是:先确认工作区状态,再从正确基线拉一个新分支,再让 agent 做一个明确任务。不要让它在一个已经堆满无关改动的目录里自由发挥。
Diff review 是你真正的控制权
很多人用 agent 最大的问题,不是 agent 写错代码,而是自己不看 diff。
AI 的解释可能很顺,但最终事实在 diff 里。它到底改了哪些文件,删了哪些逻辑,新增了哪些依赖,改了哪些配置,只有 diff 能说清楚。
review diff 时至少要看四件事:
- 改动范围是否符合需求。
- 有没有混入无关格式化、生成文件、本地配置或临时调试代码。
- 是否破坏了现有架构边界,比如把后端调用塞进不该放的位置。
- 是否真的处理了错误路径、权限、缓存、并发、空值和回滚场景。
如果 diff 太大,大到你不愿意读,就说明任务拆得太粗。不要把“看不完”当成小问题。看不完的 diff,本质上就不该被合并。
测试不是形式,是给 agent 的反馈回路
Codex/Claude Code 的优势不只是会写代码,而是能进入“改完、运行、看失败、再修”的循环。
所以你不应该只让它“帮我实现一下”,还应该让它运行项目里真实的验证命令。例如:
npm test
pnpm build
mvn test
cargo test
go test ./...
具体跑什么,要看项目规范。关键是不要只相信静态解释。很多 agent 写出的代码能通过肉眼阅读,但会在类型检查、单元测试、集成测试或构建阶段暴露问题。
测试结果还可以反过来约束 agent。一个好的任务描述不是“修一下直到你觉得好了”,而是“修复这个行为,并运行这个测试命令验证”。如果测试失败,让它基于失败输出继续修,而不是重新猜。
当然,也不是所有任务都必须全量测试。改一行文案不需要跑完整集成测试。但只要涉及业务逻辑、权限、数据库、缓存、支付、认证、部署配置,就应该有对应验证。
PR 描述不是写给老板看的
很多开发者把 PR 描述当成礼貌性总结。对 agent 代码来说,PR 描述更像一份交接记录。
它至少应该说明:
- 这次解决了什么问题。
- 主要改了哪些模块。
- 行为上有什么变化。
- 跑了哪些测试或构建。
- 还有哪些风险没有完全覆盖。
这件事很适合让 agent 帮忙做,但不能让它凭空编。最好的方式是让它根据实际 diff 和命令输出写 PR 描述。比如:
根据当前 git diff 和刚才的测试结果,写一段简短 PR 描述。
包含 scope、implementation、validation 和 remaining risk。
不要声称跑过没有跑的测试。
这能减少 review 成本,也能防止几天后你自己忘了当时为什么这么改。
哪些命令不能随便授权?
coding agent 能执行命令,是效率来源,也是主要风险来源。
通常比较安全的是读取状态和运行验证的命令,例如 git status、git diff、rg、npm test、pnpm build。这些命令也要看,但它们主要是观察或验证。
需要停下来确认的是会删除、覆盖、改历史、改持久化系统的命令,例如:
rm -rfgit reset --hardgit checkout -- .git push --force- 删除 Docker volume
- 直接操作生产数据库
- 安装来源不明的脚本
- 上传包含密钥或用户数据的日志
判断标准很简单:如果这个命令执行错了,是否会让你丢数据、丢提交、影响别人、影响生产环境? 如果答案是会,就不要让 agent 自动通过。
尤其要注意 git reset --hard 和 git checkout -- .。它们看起来像“恢复干净”,但会直接丢弃未提交改动。如果工作区里有别人或你自己还没保存的改动,这就是灾难。
适合 agent 的任务粒度
agent 不是不能做大任务,但大任务必须拆成可审查的片段。
不好的任务:
- “帮我重构整个项目。”
- “把前端优化一下。”
- “检查所有 bug 并修掉。”
- “把权限系统重新设计一下。”
更好的任务:
- “检查这个接口为什么没有按角色过滤数据,并补测试。”
- “把这个页面的 API 请求移到 services 层,保持 UI 行为不变。”
- “修复这个表单重复提交问题,并抽一个可复用的提交锁。”
- “根据这条 review comment 修改,不要碰其他文件。”
好的粒度有几个特征:目标明确、文件范围可估计、验证方式存在、diff 能在一次 review 里看完。
如果一个任务需要 agent 连续改几十个文件,最好先让它做计划,再拆成多个分支或多个 PR。不要把所有不确定性压进一个巨大的 diff。
分支和 PR 不会降低速度,反而会减少返工
有人会觉得:我只是用 AI 快速改一下,为什么还要开分支、看 diff、写 PR?
真实情况是,省掉流程通常不是变快,而是把风险推迟。你当时少花了十分钟,后面可能要花几个小时清理无关改动、找回被覆盖的代码、解释为什么构建坏了。
分支和 PR 的作用不是让你慢下来,而是让每次 AI 参与的改动都有清晰边界:
- 哪些是本次需求。
- 哪些文件被改了。
- 哪些测试跑过了。
- 哪些风险还在。
- 谁负责最终合并。
这套边界越清楚,agent 越像工程工具;边界越模糊,它越像一台会快速制造不确定性的机器。
一个实际可用的工作流
个人项目和团队项目都可以从这个流程开始:
git status看当前工作区,确认没有不该混入的改动。- 从最新主分支或目标分支创建新分支。
- 给 agent 一个明确任务,说明允许修改的范围。
- 让 agent 先读代码、说明判断,再开始改。
- 改完运行项目里合适的测试、构建或 lint。
- 查看
git diff,确认没有无关改动。 - 让 agent 根据真实 diff 和验证结果整理 PR 描述。
- 开 PR,让人 review,再合并。
如果是高风险仓库,还可以加两条规则:agent 不能自动执行破坏性命令;agent 不能自动提交、推送或合并,除非你明确要求。
结论
Codex 和 Claude Code 能明显提高开发效率,但它们不应该绕过工程流程。它们越能改真实仓库,你越需要分支、diff、测试和 PR。
分支负责隔离风险,diff 负责暴露事实,测试负责验证行为,PR 负责让变更被审查和记录。
把这四件事做好,coding agent 就是一个高效协作者。跳过这些护栏,它就可能变成一个很快、很自信、但难以追责的改代码入口。