ここ数ヶ月、私の開発ワークフローはこんな感じでした。Claude CodeとCodexを横に並べて起動し、同じプロンプト、同じゴールで、それぞれ独立にコードベースを調査させます。計画を立てるときはClaudeにプランを書かせ、それをCodexにコピーしてレビューしてもらいます。Claudeが見落としたこと――エッジケース、誤った前提、見逃したファイル――をCodexが指摘してくれるので、その結果をClaudeに戻して修正させ、修正版をまたCodexにコピーして、両者が合意するまで繰り返します。前のラウンドの変更をステージングしてCodexが差分を見やすいようにすることもありました。最後に自分の目でも確認します。
とてもうまくいっていました。2つのモデルはそれぞれ違うところに気づきます。Claudeは統合とコミュニケーションが得意です。Codexはより丁寧にコードを読み、コードパスをたどり、エッジケースを確認し、早まって「完了」と宣言しません。それぞれが独立して調査するからこそ、結果がよくなるのです。
ただ、その中継作業が最悪でした。
リンクが消えたり、書式が崩れたりしましたが、それは本当の問題ではありません。本当の問題は、すべてのやり取りが私に依存していたことです。出力をコピーして、もう一方のセッションに貼り付けて、待って、コピーして、また貼り付ける。もっと有意義なことに使えるはずの注意力が、このループに縛られていました。人間がメッセージバスになっているワークフロー――それが本当の苦痛でした。
ワークフロー自体を変えたいわけではありませんでした。ただ、人間がメッセージバスをやめられればよかったのです。
すべてを裏付けたHarnessの記事
その後、YouTubeの動画で言及されていたAnthropicのHarness design for long-running application developmentという記事に出会いました。全文を読んで、2つのことが同時にはっきりしました。
まず、自分がすでに体験していたことの裏付けです。作ったコードを「自分が書いた」というアンカリングバイアスなしに、別のセッションで独立して検証させると、より良い結果が出る。それはまさにClaudeとCodexで体感していたことでした。
次に、その体験をより明確なシステムとして整理してくれました。私はそれまで「異なるモデル」という部分に注目していましたが、この記事は「独立した評価者」という側面をはっきりと示していました。別のClaudeセッションでも、十分に独立していれば効果があるのです。分離そのものが重要な要素なのです。
考えてみれば当然です。もしオリジナルのセッションがコードに問題があると思っていたなら、そもそもそう書かなかったはずです。これはペアプログラミングがずっと持っていた利点と同じです。2つ目の目が、書いた本人の脳がフィルタリングしてしまうものをキャッチする。LLMもその点では私たちとそれほど変わりません。
体験で裏付けられ、研究で明確になった。その組み合わせで確信しました。これは個人的な癖ではなく、一般的に有用なワークフローだと。そこで、このワークフローを正式なプラグインにしてTandemKitと名付けました。

本当に解決すべきだった連携の問題
最初の設計では、4つのトップレベルセッションを用意しました。Planner、Generator、そして2つのEvaluator(1つはClaude、もう1つはCodex)です。プレーンテキストファイルで連携させていました。あるセッションが完了するとシンクファイルを書き出し、もう一方がバックグラウンドでそのファイルの変更を待つ仕組みです。Claudeでは完璧に動きました。しかしCodexはどうしても待機を確実にやってくれません。ファイル監視の方法を変えてもシグナリングの仕組みを変えても、Codexは自分の番であることに気づかなかったり、待機をスキップしてしまったりしました。
5回目か6回目の回避策を試していたとき、OpenAIがClaude Code向けの公式Codexプラグインcodex-plugin-ccをリリースしたことを知りました。ClaudeがCodexを内部から呼び出し、そのレスポンスを確認し、同じCodexセッションを後から再開できるようになったのです。まさに必要としていたものでした。
これによってClaude-Codex間のやり取りが見えなくなったわけではありません。すべてのやり取りはTandemKit/配下のMarkdownファイルに書き出され、1ラウンドにつき1ファイルです。調査、収束のやり取り、評価の判定――ミッション全体の履歴がディスクに残ります。
このアーカイブは後々も役に立ちます。数週間後に不思議な挙動が見つかったとき、gitの履歴にはコミットメッセージだけでなく、そのコミットの背後にあった会話全体が残っているので、なぜその決定がなされたのかを実際に掘り下げることができます。ワークフロー自体の改善にも最適です。過去のミッションを読み返すと、あるルールがAGENTS.mdやローカルスキルに追加すべきだったことに気づく、というのがよくあります。
変わったのは配管の部分です。不安定な4つ目のターミナルを操る代わりに、TandemKitはcodex-plugin-ccを通じて1つの永続的なCodexサブエージェントをオンデマンドで呼び出し、独立したパスが必要なときはいつでもそれを再開するようになりました。
ミッションとは何か
AIエージェントをほぼ毎日1年近く使ってきた中で、ミッションは私がたどり着いた作業の単位です。計画、実装、評価をそれぞれ独立して行う価値があるほど大きく、かつ1セットのセッション内で実装と完全な検証の両方ができるほど小さい、そのちょうどいいサイズです。
それより小さい作業――1ファイルの修正、ちょっとしたリファクタリング、単純なリネーム――ならClaude Codeを直接使います。TandemKitのマルチセッションループは、そういった変更には不釣り合いなトークンと手順を消費してしまいます。
それより大きい作業なら、始める前に分割します。そこでPlanKitが自然にフィットします。PlanKitはアイデアをIdeas → Roadmap → Features → Missionsというフローで整理します。「ミッション」の段階まで来れば、曖昧な機能のかたまりではなく、セッションサイズに整形された作業単位になっています。
最近のミッションの実例
TranslateKit(AI搭載のアプリローカライゼーションツール)にApp Store Connectのローカライゼーション対応を追加したいと思っていました。アイデアはシンプルでした。App Store Connectで手動でアプリのメタデータを管理する代わりに、開発者がTranslateKit上でアプリ名、サブタイトル、説明文、キーワードをすべてのローカライゼーションについて直接編集できるようにする――AppleのAPIで同期する仕組みです。
1つのミッションには大きすぎたので、2つに分けました。1つ目はApp Store Connect APIの接続(JWT認証、認証情報の管理、メタデータの取得と更新)、2つ目はそれをアプリ上で表示するためのUI変更です。データレイヤーが先、UXレイヤーが後です。
計画段階で、ClaudeとCodexが私が考慮していなかったエッジケースを洗い出してくれました。例えば、ユーザーが新しい言語を追加したいけれど、まだ新しいApp Store Connectのバージョンがない場合はどうなるのか。リリース済みのバージョンは編集できないので、変更をローカルにキャッシュするか、先にバージョンを作成するようユーザーに促すか、プラットフォーム全体で自動作成を提案するか、システムが判断する必要があります。
そしてTandemKitが新しいバージョンを作成する場合、バージョン番号はどうするのか。履歴を見て推測するのか。ユーザーに入力させるのか。よくある次バージョンの選択肢を提示するのか。これらはプロダクトの意思決定であり、実装の詳細ではありません。コードを書く前にSpecに入れるべき内容です。
APIミッションの評価段階で、Claudeは最初、ハッピーパスが通り既存バージョンのテストがグリーンだったため合格と判定しました。しかしCodexは目立たないブランチをたどり、本当のギャップを見つけました。編集可能なApp Store Connectのバージョンがまだ存在しない場合、コードは新しいバージョンレコードを作成するものの、同じフロー内でローカライゼーションの書き込みをリトライしていなかったのです。そのため「新しい言語」のパスは成功したように見えて、ユーザーが再度同期を実行するまで何もしていない状態でした。まさに2つ目のモデルが見つける類のコードパスバグです。
修正は小さなもので、バージョン作成後に書き込みをリトライし、そのブランチのテストを追加するだけでした。しかし2回目のパスがなければ、見逃されていたでしょう。
3つのセッション、自律ループ
あなた -- 計画
|
`--> [1] Planner Session
Claude ---------> Codex(バックグラウンド)
| <- 発見事項 - |
`---- 収束 -------┘
|
Spec.md <-- 続行前にあなたが承認
あなた -- 両方のセッションを開始して、離席
|
|--> [2] Generator Session
| Spec.mdに基づいて実装
| マイルストーンごとにコミット
|
`--> [3] Evaluator Session
Claude ---------> Codex(バックグラウンド)
| <- 発見事項 - |
`---- 収束 -------┘
|
FAIL -> Generatorが修正 -> ループ
PASS -> レビューブリーフィング -> あなたPlannerだけが対話的なステップです。Spec.mdを承認したら、GeneratorとEvaluatorはFAILによる修正依頼かPASSによるレビューブリーフィングが届くまで、自律的に動き続けます。
ClaudeとCodexはどうやって合意するのか
まず思いつくのはスコアリングでしょう。両方のモデルが作業を採点し、平均を出して、閾値を超えたら合格とする。しかしスコアは失敗を隠します。8/10でも、2つの重要な基準が完全に不合格で、残りがすべて問題なしということがあり得ます。
そこでTandemKitは基準ごとに評価します。各所見には2つの軸が付与されます:
合意レベル:agreed(合意)、partially agreed(部分的に合意)、disputed(不一致)
重要度レベル:HIGH、MEDIUM、LOW
ClaudeとCodexは独立して調査し、所見をファイルに書き出します。次にClaudeがCodexの所見を読み、統合された評価を作成します。合意する部分はそのまま、異なる部分は理由を説明します。Codexがその統合をレビューします。意見が分かれた場合は、記憶から議論するのではなく、実際のソースファイルを再読することになります。
収束ルールはシンプルです。partially agreedまたはdisputedのバケットにHIGHまたはMEDIUMの所見が残っていない状態になるまでループが続きます。同じ不一致が3ラウンド生き残った場合、TandemKitは反復を停止し、両方の立場をユーザーに提示します。
通常は2〜4ラウンドで収束します。
Agent Teamsではダメなのか
Claude Codeにはまさにこの用途のためのAgent Teamsがあるのでは?と思うかもしれません。確かにありますが、Agent TeamsにはAPIの課金が必要で、Claude Maxには含まれていません。またCodexとの統合もできません。
Claude Maxにすでに月額100ドル以上払っているなら、ChatGPT Plusに月額20ドルを追加するのは合理的な選択です。独立した2つ目のモデルに加えて、UIモックアップやアイコンなどClaudeが生成できないビジュアルの画像生成も使えます。
すべてがプレーンテキスト
すべての調査、すべての収束のやり取り、すべての評価ラウンドが、プロジェクト内の読みやすいファイルとして保存されます:
TandemKit/001-ConnectAPIClient/
├── Spec.md
├── Planner-Discussion/
│ ├── Claude-01.md ← Claudeの調査
│ ├── Codex-01.md ← Codexの独立した発見事項
│ └── Claude-02.md ← 収束した計画
├── Generator/
│ └── Round-01.md
└── Evaluator/
├── Round-01.md ← FAIL: バージョン作成済み、ローカライズ書き込み未リトライ
└── Round-02.md ← PASSファイルを開けば、推論の全過程をたどることができます。
はじめ方
GitHubのREADMEにセットアップの全手順と、セッション間の受け渡しの仕組みが書かれています。もしここまで読んで「これ、手作業でつなぎ合わせてやっていたワークフローだ」と思ったなら、まさにそこから始めてみてください:
GitHubFlineDev/TandemKitPair programming for AI agents — a Claude Code plugin that coordinates Claude and Codex across planning, generation, and evaluation.
