Tsukutta

Claude CodeとCodexを1台で協業させる

― 設計はClaude・実装はCodexに渡す

Claude Codeの記憶を4層に分けた話から続く「Claude Code環境」シリーズです。今回は、1台のMacの中でClaude CodeとCodex CLIを役割分担させる話を書きます。

きっかけは単純で、メインセッションを軽量モデルで回しているとき、実装の長いタイピングでトークンを溶かすのがもったいないと感じたからです。設計やレビューはモデルの賢さが効くけれど、決まった実装をひたすら書く工程は別プロセスに逃がしたい。そこで実装をCodexに委譲し、設計・リサーチ・レビューはClaude側に残す形に落ち着きました。

役割分担:頭脳と手を分ける

分担はCLAUDE.mdに明文化しています。要点はこうです。

工程担当理由設計・コードベースのリサーチ・計画Claude(メイン)文脈の理解とトレードオフ判断が要る実装・リファクタ・テスト生成Codex定型・大規模・反復はタイピング側に逃がすコードレビュー両方別エンジンの目を入れて品質を上げる

ポイントは「全部委譲しない」ことです。実装難易度が高い、あるいは重い設計判断を伴う実装は、文脈を持っているメインセッションが直接書いた方が速くて正確です。委譲はあくまで「決まったものを量産する」工程に限定します。

モデルの賢さが要る工程(設計・レビュー)と、賢さより量が要る工程(定型実装)を分けるのが軸です。「AIが2ついるから並列で速くなる」ではなく、「高い席に座らせる作業を選ぶ」発想です。

呼び出し方:非対話で安全に投げる

CodexはCLI(codex-cli 0.135.0)として入っています。委譲は非対話のヘッドレス実行で投げます。

text
# 実装・タスク委譲(@file でファイル参照可)
timeout 600 codex exec --skip-git-repo-check "<依頼内容>" </dev/null

# コードレビュー(現在のリポに対して実行)
codex exec review </dev/null

細かいけれど効くポイントが3つあります。

  • </dev/null で stdin を閉じる。閉じないとCodexが対話入力を待ってフリーズし、timeout まで無駄に張り付きます。
  • timeout で囲う。ヘッドレスのAIプロセスは、たまに終わらない。OS側で刈れるようにしておくと、張り付いたプロセスが溜まりません。
  • --skip-git-repo-check。gitリポ外のディレクトリで実行するときに必要。これが無いとリポ判定で弾かれます。

PATHの罠

Codexは nvm 配下にインストールされています。対話中のClaudeのBashは nvm default をロード済みなので codex がそのまま通りますが、素のzshやcron経由だと command not found になることがあります。そのときはフルパスで叩きます。

text
/Users/<you>/.nvm/versions/node/v24.13.0/bin/codex exec ...

launchdやcronから無人で回す場合、最小PATHにnvmは入っていないので、ここで必ず躓きます。フルパス指定が確実です。

委譲のフロー

実際の運用フローはこうなっています。

  1. メイン(Claude):要件を受けてコードベースをリサーチし、設計と計画を立てる
  2. 規模の判断:定型・大規模・反復的なら委譲、難所はメインで直接実装
  3. 委譲(Codex)codex exec に具体的なタスクを投げて実装させる
  4. レビュー(Codex):実装完了後、codex exec review でコードレビュー
  5. メインが詰まったら:Codexに引き継ぐ

3と4を別エンジンに分けるのが地味に効きます。同じモデルが「書いた本人」としてレビューすると甘くなりがちですが、Codexに書かせてCodexにレビューさせる/あるいはClaudeがレビューする、と書き手とレビュアーを分離できます。

引き継ぎを壊さない:ファイル受け渡し

長い委譲では、タスク・引き継ぎ・状態をファイルで渡すようにしています。会話の文脈は揮発するので、状態をディスクに落とすと再開や検証が楽になります。worktreeで隔離して走らせるときは、ステータスファイルにブランチとworktreeパスを書き出します。

text
# Status
- State: running
- Updated: 2026-06-17T...
- Branch: feat/...
- Worktree: `/path/to/worktree`

これは記憶を4層に分けた話と同じ思想です。揮発する会話の外に、状態の正本を置く。協業でも長期記憶でも、効く原則は同じでした。

踏んだ落とし穴

  • </dev/null 忘れでCodexが対話待ちフリーズ → stdinは必ず閉じる
  • cron/launchdで codex: command not found → nvm配下なのでフルパス必須
  • gitリポ外で実行が弾かれる--skip-git-repo-check
  • 全部委譲して文脈ロス → 難所はメインで直接書く。委譲は定型に限定
  • 書き手=レビュアーで甘いレビュー → 実装と review を別エンジンに分ける

まとめ

  • 1台の中で設計・レビューはClaude、定型実装はCodexに分ける
  • 委譲は codex exec --skip-git-repo-check "..." </dev/nulltimeout で囲う非対話実行
  • 全部委譲しない。難所はメインで直接書く
  • 実装とレビューを別エンジンに分けて品質を上げる
  • 状態はファイルに落とす。揮発する会話の外に正本を置く

次回は、その push の直前で秘密情報の流出を機械的に止めるフックの話 ―― pre-pushガードでAPIキーと誤pushを止めるを書きます。

この記事が良かったら

「チップをリクエスト」で著者にチップの受け取り設定をお願いできます

シェア