最近我的终端里同时跑着 Claude Code 和 Codex。用了一段时间之后,我发现两个问题必须拿出来聊聊:这两个工具到底怎么分工?以及一个更隐蔽的坑——AI agent 在对话框里打出“任务已完成”之后,很多人顺手就把代码 push 上去了,第二天线上出问题,回头一看,AI 确实“做完”了它理解的任务,但没做完你真正需要的任务。“允许结束”和“可以提交”之间,隔着一条必须由人守住的线。
这篇文章就围绕这两件事展开:Claude Code 和 Codex 怎么合理分工,以及如何在按下 git commit 之前,对 AI 的产出做一轮像样的质检。适合天天跟 Git、SVN 打交道、正在用或者打算用这两个终端 AI 工具提效的开发者。我会结合自己的实际项目拆流程、讲坑、给命令,尽量让你看完能直接照着干。
1. 为什么说 Claude Code 和 Codex 是互补而不是竞争
1.1 两个工具的定位差异
Claude Code 是 Anthropic 出的终端专属编程 agent。它最强的能力不是“写几行代码”,而是在一个很长的上下文会话里连续工作:读整个项目的目录结构、定位问题、改多个文件、运行测试、根据报错接着调。换句话说,它更像一个能持续思考的工程师,特别适合做“先想清楚再动手”的事情:架构重构、跨模块问题排查、对一个陌生代码库做探索性分析。
Codex 是 OpenAI 出的编码 agent,命令行版本在终端里就叫 codex。它的执行模式更接近流水线:你把一个描述明确的小任务丢进去,它在一个相对独立的进程里完成文件改动,跑完就退出,给出结果。因为每个任务上下文不共享、彼此独立,它特别适合批量化执行:补单元测试、做代码格式化、处理一堆相似的小 issue、升级依赖版本等。
我总结成三句话:Claude Code 负责纵深,Codex 负责宽度;一个像带项目的资深工程师,一个像能同时派出去干杂活的作业班组;一个需要你陪着它一步步推进,一个要你把需求说清楚它自己跑。搞明白这个差异,就等于拿到了分工的总纲。
1.2 我的分工判断标准
每次接到任务,我会先问自己三个问题:
- 这个任务是否需要理解全局上下文?需要就交给 Claude Code。
- 这个任务是否边界清晰、可以独立完成?是就拆出来丢给 Codex。
- 这个任务是否会触碰大量公共文件?如果会,就尽量让它只在单个 agent 的会话里完成,不要并行。
基于这个判断,我一般把“分析”和“执行”串起来用。先用 Claude Code 把整个改动盘清楚,再把手感重复的、独立的子任务丢给 Codex 批量处理,最后回到 Claude Code 或者人工来做集成验证。这个顺序很重要,反过来容易翻车——你让 Codex 先跑了一堆零碎改动,然后 Claude Code 进场一读代码,发现方案整体就不对,前面全白干了。所以我的节奏永远是:先让 Claude Code 出地图,再让 Codex 去跑腿。
1.3 双工具协作的前置条件
双工具协作之前,项目必须已经纳入版本管理,而且工作区要干净。我见过有人把两个 agent 丢进同一个脏工作区,结果两边的自动格式化互相覆盖,来回打架,最后只能靠 git checkout 恢复原样。我的规矩是:开工前 git status 必须干净,所有 agent 的改动都在分支上进行,并且明确划分各自动的文件范围。
另一个前置条件是模型接入。Claude Code 可以通过环境变量指向兼容接口,比如把 ANTHROPIC_BASE_URL 改成一个第三方兼容服务,就能接上不同的模型后端;Codex 也有类似的可配置入口,很多人会把它的 endpoint 指向兼容 OpenAI 协议的服务,比如 DeepSeek 这类开源模型的 API。这种玩法的价值在于成本和灵活性,但要注意,不同模型的能力差异会直接影响 agent 的完成质量,一些小事上可能看不出来,一旦任务复杂度上来,差距就非常明显。因此,越是用了非官方默认模型,后面那套“提交前检查”就越要严格执行。
2. 分工策略:什么活儿交给谁
2.1 典型任务分配表
下面这张表是我在实际项目里反复用下来的分配基准,你可以直接拿去做参考:
| 任务类型 | 推荐工具 | 理由 |
|---|---|---|
| 架构重构、跨文件改动 | Claude Code | 需要全局理解,长上下文连续调整 |
| 疑难 bug 排查 | Claude Code | 需要反复猜测、验证、回溯 |
| 新代码库探索、技术方案调研 | Claude Code | 让它先读代码再给结论 |
| 单元测试补全 | Codex | 边界清晰,可批量并行 |
| 简单 issue 批量处理 | Codex | 任务解耦,可独立完成 |
| 依赖升级、代码格式化 | Codex | 机械化程度高,重复性强 |
| 双 agent 结果集成 | Claude Code | 需要看到全局再决定取舍 |
这里有个容易误解的地方:不是说 Codex 不能做重构,也不是说 Claude Code 不能补测试。而是同样的任务,交给不同工具的成本和风险不一样。让 Codex 去做一个需要跨五个模块联动的大型重构,它很容易在一个局部做出“看起来合理但整体错误”的决策;让 Claude Code 去批量补二十个文件的测试,又会浪费它的长上下文优势,而且慢。按工具的性格分配任务,是在控制风险,不是在做技术信仰。
2.2 一次真实拆分案例
上周我做了一个“用户导出报表”功能,正好是双工具协作的标准场景。项目是一个内部管理后台,需求包括:数据查询层加导出接口、补参数校验 DTO、前端表格页加导出按钮和下载逻辑、补单测、更新接口文档。我没有让一个 agent 从头做到尾,而是这样拆的:
- Claude Code 先花十几分钟读项目结构,定位到用户模块的 service、controller、前端页面文件,输出一份改动计划,包含新增哪些文件、改哪些文件、每处接口的接缝长什么样、风险点在哪。
- 我把计划里的独立子任务拆成两组:一组是后端导出接口的单元测试和 mock,另一组是前端表格页的导出按钮和下载逻辑。分别开两个 Codex 会话丢进去,prompt 里都写死“只允许改指定文件”。
- 两个 Codex 并行跑完,各自在独立分支上工作,互不干扰。
- 回到主分支,把 Claude Code 喊出来做总装:让它 review 两边的 diff,把接口签名对不上的地方、DTO 字段命名不一致的地方全部修掉,再跑一遍跟这个功能相关的全部测试。
- 我自己最后过一遍整体 diff,确认没有夹带私货,再提交。
整个流程里,Claude Code 产出的是“上下文地图”,Codex 产出的是“标准件”,最后 Claude Code 做“总装质检”。从拆解到合入大概花了一个上午,比纯手写快得多,而且每个环节都有明确的负责人,出了问题也容易追责——不是追 AI 的责,而是追我这个流程设计者的责。
2.3 避免冲突的并行规则
并行跑 agent 最容易翻车的就是文件冲突和逻辑冲突。我踩过几次以后,总结了几条铁律:
- 给每个 agent 明确指定可写文件列表,超出范围的改动一律视为无效。我在 prompt 里会直接写“你可以修改 a.py、b.py,其他文件一律不允许动”。这比你在旁边反复叮嘱一百遍都有用。
- 不同 agent 的工作目录用 git worktree 隔开,每个 agent 一个 worktree,物理隔离,互不干扰。实在不想用 worktree,就至少让它们各自开分支,集成时你是最终合并的那个人。
- 并行任务之间不要有依赖关系。如果任务 B 需要任务 A 的产物,那就等 A 完全结束、你把结果确认过之后,再让 B 开工。贪并行省下来的时间,最后都会加倍赔在协调冲突上。
- 集成时不要“照单全收”。两个 agent 各自说“完成”之后,真正该看的不是它们的话,而是 git diff --stat 输出的那一串文件列表——有没有多改了什么、有没有漏掉计划里的目标文件。
3. 核心命题:允许结束不等于可以提交
3.1 “任务完成”信号是怎么来的
先搞清楚一件事:AI agent 的“任务完成”到底是什么。以 Claude Code 为例,它的执行循环大致是“规划 -> 执行 -> 观察结果 -> 再规划”,每一个子任务都有对应的完成判定。当它自己判断所有子目标都达成时,就会输出一个“完成”的信号,可能是总结,也可能是 final answer。Codex 同理,它会在内部循环结束后返回一组文件改动和一段完成说明。
问题在于,这个“完成判定”依赖的是模型对这个任务语义的理解,而不是你对仓库的真实质量要求。它知道你让它改十个文件,但它不知道你的 CI 上有十七条 lint 规则、不知道某个测试依赖了 fixture 的运行顺序、不知道线上数据库里某个字段名和本地并不一致。AI 说“我做完了”,只意味着它对该任务的内部模型处理完毕,绝不意味着这些改动已经满足了你说的“可以进入主干分支”的标准。
一个还算贴切的类比:AI 说“我做完了”就像实习生跟你说“我写完代码了”。他确实写完了他理解的代码,但可能没跑测试、没格式化、没检查有没有污染其他模块。你作为负责人,不能在他说完的瞬间就去点提交,你得审查。对 AI agent 更要如此,因为它表达“完成”时往往带着很高的确定性,而这种确定性跟实际正确性没有任何因果关系。
3.2 提交前必须守住的四条线
我给自己定了一套“提交前检查清单”,每次合代码前都按这个走一遍:
- 编译和类型检查必须通过。很多语言,比如 TypeScript,agent 改完代码但类型错误没暴露出来,它照样会说“完成”,因为它的验证手段有限。所以 commit 之前,必须在本地手动跑一遍 tsc、build、mvn compile 这类命令,以实际输出为准。
- 测试必须全量跑过相关范围。至少要跑跟改动相关的测试目录,而不是只跑 agent 自己提到的那几个测试。真正的陷阱在这里:agent 跑了自己改的文件所关联的测试,说通过了,但它没有跑回归。万一它改了一个公共函数,把挂在旁边的十几个模块弄坏了呢?
- diff 必须经过人工语义审查。这个“人工”可以是人,也可以是你另外开一个视角的 agent,但你自己一定得至少看一遍 git diff。重点看三样东西:有没有多余的调试输出(console.log、print);有没有把原本正常的东西顺手改坏(比如无目的的大段删除);有没有引入和本次任务八竿子打不着的牵连改动。
- 提交信息必须符合规范,且提交时机要对。一次提交只干一件事,不要把一个功能代码和一个无关的 format 混在同一个 commit 里。后面我会专门说提交规范怎么写。
这四条不是洁癖,是因为我真的因为这些吃过亏。
3.3 我踩过的“AI 说完成,代码有问题”的坑
上个月我做一次参数校验优化,Claude Code 在一个长会话里改完了整条调用链,明确告诉我“所有改动已完成”,我也看到编译通过了,就提交了。结果第二天线上定时任务报了错,查了半天才发现:它在重构过程中把一个工具函数的边界条件删掉了。那个函数只有两处调用,而且都是深夜的定时任务,所有现成测试都没覆盖到。编译能过、测试能过,但业务逻辑错了。
那次之后我彻底想明白了一个道理:AI 的“完成”是它和你之间的对话事件,不是你和 Git 之间的交付事件。正确的链路永远是:AI 说完成 -> 你验证 -> 你有把握 -> 你亲自提交。最后一步只能是人,这跟工具进步到什么程度无关——出了问题,背锅的也是人,不是模型。
4. 实操:双工具协作跑一个完整功能的流程
4.1 需求描述与前置准备
用一个干净的例子演示全流程。场景:内部数据平台的用户列表页缺少“导出”能力,需求有三块:后端新增导出接口、前端加导出按钮和下载逻辑、补测试和接口文档。这是一个典型的“需要全局理解 + 可以批量并行”的混合任务。
前置准备按老规矩来:先 git status 确认工作区干净,基于 main 开出 feature 分支,把所有要动的文件边界在脑子里(或者写下来)过一遍。然后我用 git worktree 建两个工作目录,一个给 Claude Code,一个给 Codex。这样它们读写文件时都在各自的目录里,最后我一个人来合并,冲突面会小很多。
4.2 阶段一:让 Claude Code 产出改动地图
我在 Claude Code 会话里给的 prompt 大致是这样:
项目:内部数据平台。需求:用户列表页增加导出报表功能。 请先阅读项目结构,重点看: 1. 后端:用户模块的 controller / service / mapper 是哪几个文件? 2. 前端:用户列表页在哪个目录,表格和按钮怎么组织的? 3. 现有导出功能有没有可复用的公共代码? 最后输出一份改动计划,包括:需要新增哪些文件、修改哪些文件、 每个文件改什么、接口契约长什么样、风险点在哪。 只做分析,不要动手改代码。这一步的价值在于让 Claude Code 把“地图”画出来。它花的时间大概十几分钟,但之后所有并行任务都有了锚点。计划出来后,我会人工过一遍,把明显不合理的地方改掉,再把子任务拆给 Codex。注意,这里不要偷懒,让 Claude Code 直接开始改,那就违背了分工原则——我们还没拿到 Codex 的批量产出,过早动手会打乱节奏。
4.3 阶段二:把独立子任务派给 Codex
根据计划,我开两个 Codex 会话,各自给一个独立 worktree。
会话 A 的 prompt:
任务:为后端导出接口补充单元测试。 背景:controller 是 UserExportController,service 是 UserExportService, DTO 类路径见项目现有结构。 要求: - 只允许修改 src/test/java/xxx/ 下的测试文件。 - 不允许改动任何 src/main 下的代码。 - 测试要覆盖:正常导出、参数为空、权限不足三个场景。 完成后请列出你修改的文件清单。会话 B 的 prompt:
任务:在用户列表页上增加导出按钮和下载逻辑。 背景:页面文件在 src/pages/UserList/index.tsx,API 调用方式参考同项目其他页面。 要求: - 只允许修改 src/pages/UserList/ 目录下的文件。 - 不允许改动后端代码和公共组件。 - 下载成功后要有提示,失败要显示错误信息。 完成后请列出你修改的文件清单。两个 Codex 并行跑。它们互不感知对方存在,这没问题,因为文件范围不重叠。等两边都跑完,我在各自 worktree 里看一眼 diff 是否越界,然后开始集成。
4.4 阶段三:回到 Claude Code 做集成和验证
集成这一步我把两个 worktree 的改动合并回主开发分支,然后再次请 Claude Code 出场。prompt 大概是:
我合并了两个分支的改动:一个是后端测试,一个是前端导出功能。 请审查当前工作区的 diff: 1. 后端接口约定和前端调用参数是否一致。 2. 有没有命名风格不统一、明显的类型错误。 3. 跑一遍和用户模块相关的测试,确认没有破坏现有逻辑。 发现问题直接改,改完告诉我改了什么。这个环节里,Claude Code 的价值是“用第三视角重新审视整个改动”。它没有参与单个子任务的细节,反而能更客观地发现问题。实测下来,接口字段不一致、命名 style 冲突这类问题,在这个阶段被抓出来的概率很高。
4.5 阶段四:人工验收和提交
集成通过后,我自己做最后的人工验收。命令基本是这个套路:
git diff main...feature --stat git diff main...feature --check git log --oneline -3diff --stat 看文件范围,diff --check 看有没有行尾空格、空行这类低级问题,log 看提交历史的位置。然后从头到尾读一遍关键文件的 diff,确认没有调试输出、没有无关改动。都确认了,写提交信息:
git add . git commit -m "feat(user): 添加用户列表导出报表功能"提交信息我会手动写,或者让 AI 生成后我改一遍。后面专门说这个问题。
4.6 关键命令集
把高频命令整理在一起,方便复制:
# 工作区检查 git status git diff --stat git diff --check # 开分支 git checkout -b feature/user-export # worktree 隔离 git worktree add ../claude-wt -b feat/claude-explore git worktree add ../codex-wt-a -b feat/codex-api-test git worktree add ../codex-wt-b -b feat/codex-ui-export # 合并某个 worktree 的改动 git checkout feat/codex-api-test git merge feat/claude-explore --no-edit # 提交前验证 npm run typecheck npm run test -- user5. 常见问题与避坑索引
5.1 安装、配置与登录问题速查
我收集了一些经常出现的问题,整理成速查表。需要说明,下面的方案只针对正常技术配置,不涉及任何绕过访问限制的操作,这点大家务必注意。
| 问题现象 | 常见原因 | 处理思路 |
|---|---|---|
| codex 提示 auth token is unavailable | 登录态失效或环境变量没配对 | 检查环境变量里是否设置了正确的 token,重新登录认证,再确认 API endpoint 配置指向正确服务 |
| codex endpoint /responses 相关报错 | 网络连接异常或 endpoint 地址不对 | 确认本地网络可访问目标服务,检查 endpoint 配置是否写错,必要时核对当前环境变量里的地址和本地实际可用的服务是否一致 |
| Claude Code 安装后无法启动 | 全局安装不完整或 Node 版本过低 | 用 npm 重新全局安装,确认 Node 版本满足要求,检查终端 PATH 是否正确 |
| Claude Code 接入 DeepSeek | 想把默认后端换成开源模型 | 设置 ANTHROPIC_BASE_URL 指向 DeepSeek 的兼容接口,同时把 ANTHROPIC_API_KEY 换成对应的 key,重启会话生效 |
| Codex 接入 DeepSeek | 想让 codex 走第三方模型 | 在 codex 的配置里把 model 和 base URL 指向兼容服务,确认鉴权方式与目标服务一致 |
| codex 打不开、没有响应 | 配置损坏或端口冲突 | 查看配置文件是否损坏,清掉临时缓存后重试,确认没有其他进程占用 CLI 依赖的端口 |
关于安装本身,Claude Code 和 Codex 都支持 npm 全局安装。装完之后第一步不是马上干活,而是开个空白目录跑一次最小验证,确认 agent 能正常启动、能读文件结构,再进真实项目。我见过太多人一上来就把 AI 连上公司仓库,结果配置有问题,AI 读不了代码库,白折腾一上午。
5.2 Git/SVN 提交常见坑
这一节是我从各种社区问题里筛出来的典型坑,不少人都在里面栽过。
SVN 拉代码没问题但提交时提示某一层上级目录没权限。这个现象通常不是服务器权限真的变了,而是工作副本的目录锁定信息和认证缓存出了问题。处理办法是:先 svn cleanup 清理锁,再看认证缓存里的账号是否过期,最后确认你是在分支根目录提交,而不是在某个子目录里。子目录提交时,SVN 会上溯检查整个目录链的权限,最容易触发这种莫名其妙的报错。
IDEA 里修改 Git 提交账户。直接在 IDEA 的 Settings -> Version Control -> Git 里配置用户信息,或者改项目下 .git/config 文件,全局的话改 ~/.gitconfig。这里有个小教训:公司仓库配了多个账号的人,务必在项目级配置里写清 user.name 和 user.email,否则提交记录可能会用错身份,后面推上去再改非常麻烦。
Git 提交代码冲突怎么解决。没有神术:先 git status 查看冲突文件列表,再逐个打开带冲突标记的文件,处理完 <<<<<<< 和 ======= 区块,最后 git add 标记为已解决再 commit。千万别试图用强行提交绕开冲突,那不是解决问题的办法。至于“git 强行提交”这个说法,要注意:强推(git push --force)是把远程历史整个重写,非常危险。如果确实需要修正自己刚推上去的提交,优先用 --force-with-lease,它会先检查远程是否被你之外的人更新过,比裸 force 安全得多。
5.3 提交信息规范与 AI 提交信息处理
版本提交类型规范这件事,我的标准很简单:遵循 conventional commits 那套,前缀表记牢就行。
| 前缀 | 适用场景 |
|---|---|
| feat | 新功能 |
| fix | 修 bug |
| docs | 文档调整 |
| style | 格式、空格、分号这类不影响逻辑的改动 |
| refactor | 重构,行为不变 |
| test | 补测试或改测试 |
| chore | 构建、依赖升级等杂事 |
很多 AI 工具能帮你生成提交信息,这是好事,但生成出来的东西一定要人工改一遍。AI 容易犯两个毛病:一是把一次改动里所有事情都塞进一个 commit message,看起来像一篇长篇说明;二是把动词写得太宏大,“refactor everything”这种信息对以后的维护者来说等于什么都没说。我自己的习惯是,给 agent 的 prompt 里直接带一句“提交信息控制在三行以内,动词用 feat/fix/docs/refactor 前缀”,跑完后我再把 message 里那些飘的形容词删掉,只留“改了什么、为什么改”。
还有一个小细节:提交前把 git status 和 git diff --stat 最后过一眼,确保没有那个叫“网站提交入口”之类无关目录下的临时文件混进来。别问我为什么强调这个,问就是我见过把 npm 缓存目录传上去的提交。
整个双工具协作的流程走下来,我最深的体会就是:工具越强,人的把关责任越重。Claude Code 和 Codex 各有各的脾气,把它们放在合适的位置上确实能省掉大量重复劳动,但 AI 那句“任务完成”只是它对自己工作结束的信号,从来不等于代码已经到了可以提交的状态。靠谱的做法始终是那几步:AI 出计划,Codex 批量执行,Claude Code 做集成,人做最终验收。这四步走顺了,AI 编程才真正从“玩具”变成“生产力”。
最后再分享一个小技巧:每次让 AI 干完一批活,先别急着进入下一轮,花五分钟把 git diff 从头到尾读一遍,你要找的不是语法错误,是那些“AI 觉得没问题但你知道不该这样”的地方。这五分钟,能帮你省掉第二天的排障时间。