前回、Databricksがオープンソース化したメタハーネス Omnigent の概要を紹介しました(前回の記事)。ハーネス/メタハーネスという考え方、合成・制御・協働という3つの価値、インストールとUIツアーまでを扱いましたが、目玉であるPollyのクロスレビューについては「環境によっては最後まで通らないことがある」と書いて止めていました。
今回はその続きとして、Pollyを小さなスモークテストで実際に最後まで動かし、別ベンダーによるクロスレビューが回るところまでを記録します。あわせて、動かして初めて分かった詰まりどころも残しておきます。検証環境は macOS、Omnigent v0.2.0 です。
Pollyのおさらいと今回のゴール
Pollyは、自分ではコードを書かないコーディングのオーケストレーターです。テックリードのように振る舞い、タスクを分割して、claude_code / codex / pi のサブエージェントにそれぞれ別のgit worktreeで実装させ、各diffを「書いたのとは別ベンダー」のレビュアーに回します。マージは人間が行います。
前回はこの仕組みを概念として説明しただけだったので、今回のゴールはシンプルです。小さなタスクで、実装からクロスレビューまでを実際に最後まで通し、その様子と詰まりどころを記録することです。大きなリポジトリではなく、あえて使い捨ての小さなリポジトリを使います。仕組みを雑音なく観察するには、その方が向いているからです。
セットアップ
前提
Omnigentには Python 3.12以上、Node.js 22 LTS、tmux が必要です。macOS / Linux が前提で、Windowsの場合はWSL2を使ってLinux手順に従います。
インストール
公式のインストーラを実行します。
curl -fsSL https://omnigent.ai/install.sh | sh
CLIは omnigent と omni の2つの名前で入ります。どちらも同じものです。すでに入れている場合は omni upgrade で最新(今回は v0.2.0)に更新できます。
クロスレビューには2ベンダーをそろえる
ここが今回の肝です。Pollyのクロスレビューは「実装したのとは別ベンダーがレビューする」ことが本質なので、最低2系統のコーディングCLIが要ります。今回使うのは claude_code(Claude Code CLI)と codex(Codex CLI)です。
サブエージェントはそれぞれ専用のCLIがPATHにある場合だけ起動できます。Pollyが起動時に行うのと同じ確認を、先に手元でやっておきます。
command -v claude codex pi
今回の環境では claude と codex は見つかり、pi は出ませんでした。
/Users/xxxx/.local/bin/claude
/Users/xxxx/.npm-global/bin/codex
pi は入っていませんが、クロスレビューに必要な2ベンダー(claude / codex)がそろっているので問題ありません。レビューは「claude_codeのPRをcodexが」「codexのPRをclaude_codeが」という形で双方向に成立します。
omni setup を実行すると、検出済みのハーネスが一覧で確認できます。ClaudeとCodexが Subscription として認識されていれば準備完了です。
各CLIがログイン済みであることも確認しておきます。これが通っていないと、Polly起動後にサブエージェントがboot時に失敗します。
claude --version
codex --version
スモーク用リポジトリを用意してPollyを起動する
いきなり実リポジトリを触らせず、使い捨ての小さなgitリポジトリを作ります。
mkdir -p ~/work/polly-smoke && cd ~/work/polly-smoke
git init
cat > calc.py <<'EOF'
def add(a, b):
return a + b
EOF
git add -A && git commit -m "init"
このリポジトリの中でPollyを起動します。Pollyはカレントディレクトリを基点にworktreeを作るので、対象リポジトリの中で起動するのが大事です。
omni run ~/agents/polly-dbx/
起動直後に、UIのテーマ(dark / light)を選ぶ画面が出ます。好みで選んで進めます。
選択を終えると、http://localhost:6767 にWeb UIが開きます。ターミナルとブラウザは同じセッションをリアルタイムに映します。右パネルは Files / Agents / Shells のタブで、画面下に「Polly (Claude SDK)」と表示され、Pollyの脳が claude-sdk ハーネスで動いていることが分かります。
Pollyにタスクを投げる
チャット欄に、2スライスに割れてクロスレビューが効くタスクを日本語で投げます。
calc.py に subtract と multiply 関数を追加してください。
それぞれ別のサブエージェントに実装させ、テストも付けてください。
実装したのとは別ベンダーにクロスレビューさせてください。
送信すると、Pollyは概ね次の順で動きます。最初のターンでワーカーの存在を確認し(claude と codex を検出、pi は無いと報告)、タスクを subtract と multiply の2つに分割し、claude_code と codex にそれぞれ別worktreeで並列実装させ、各PRを書いた側とは別ベンダーにレビューさせます。これらをこちらが逐一指示する必要はありません。
クロスレビューが回る
完了すると、Pollyが結果をまとめてくれます。今回の結果はこうなりました。
| 関数 | 実装ベンダー | クロスレビュー(別ベンダー) | テスト | 結果 |
|---|---|---|---|---|
| subtract | claude_code | codex | 4 passed | PASS |
| multiply | codex | claude_code | 4 passed | PASS |
狙いどおり、書き手とレビュー役が別ベンダーになっています。subtractはClaudeが書いてCodexがレビュー、multiplyはCodexが書いてClaudeがレビュー、という双方向のクロスレビューが成立しました。
右の Agents パネルには、polly(親)の下に実装とレビューのサブエージェントが並びます。実装側(add-subtract / add-multiply)とレビュー側(review-subtract / review-multiply)が、それぞれ別worktreeで動いた記録が残ります。
成果物は2本のローカルブランチです。
git log --oneline --all
4b42326 (polly/multiply) Add multiply function and tests
4373fef (polly/subtract) Add subtract function to calc with tests
b4351ee (HEAD -> main) init
中身もシンプルかつ正しく、それぞれ既存の add() は維持したまま自分の関数とテストだけを追加しています。
git diff main polly/subtract
def add(a, b):
return a + b
def subtract(a, b):
return a - b
テストの観点に、書き手の違い(別ベンダー)が薄く出ているのも面白いところです。subtractは正/負/ゼロをカバーし、multiplyはそれに加えて恒等(identity)のテストまで書かれていました。各worktreeは確認用に .worktrees/subtract と .worktrees/multiply に残っています。
動かして分かった詰まりどころ
スモークは最後まで通りましたが、途中でいくつか実際に詰まりました。ここが概念紹介だけでは見えない部分です。
codexの認証切れ(401)で即停止する
最初の実行中に、codexが401で動けなくなりました。claude_code と codex は実物のベンダーCLIをそのまま起動するネイティブハーネスなので、CLIの認証が切れていると、その瞬間にそのワーカーが停止します。今回は codex が止まったことで、multiplyの実装と、もう一方をレビューする役の両方が同時に詰まりました(pi が無いため、codexが唯一の別ベンダーだったからです)。
対処は単純で、ターミナルで再ログインするだけです。
codex login
そのうえで、Pollyに続きから再開を指示します。最初からやり直す必要はなく、完成済みの subtract はそのまま活かせます。
codex に再ログインしました。multiply を codex に実装し直して、
claude_code の subtract を codex でクロスレビューしてください。
PRは不要で、ローカルのブランチとdiffで構いません。
ネイティブCLIのハーネスは便利な反面、各ベンダーの認証状態にそのまま依存します。動かす前に各CLIのログインを確認しておくのが安全です。
git remoteが無いとPRが作れない
Pollyは本来、各実装を独立したPRとして開く設計です。ところが今回のスモーク用リポジトリにはremoteが設定されていないため、PRは作れませんでした。成果物はローカルブランチ(polly/subtract と polly/multiply)とそのdiffに留まります。
スモークとしてはこれで十分ですが、PRまで作りたい場合はremoteを設定してから実行する必要があります。
git remote add origin <url>
並列ブランチが同名ファイルを作り、マージで衝突する
地味ですが重要な落とし穴です。subtractとmultiplyは別worktreeで独立に動いたため、両方とも test_calc.py を新規ファイルとして作成しました。その結果、片方をmainにマージした後にもう片方をマージすると、test_calc.py で必ず衝突します。
git checkout main
git merge polly/subtract # まず片方
git merge polly/multiply # ここで test_calc.py が衝突する
並列worktree + 独立ブランチという構造上、同じファイルに触れるタスクを分割すると起きやすい衝突です。そしてPollyはマージをしない設計なので、この統合は人間の仕事になります。タスクをどう分割するか(同じファイルを複数スライスが触らないようにできるか)が、後始末の量を左右します。
まとめ
小さなスモークテストでしたが、Pollyの本質である「タスクを分割し、別worktreeで並列実装し、別ベンダーがクロスレビューする」という流れが、実際に最後まで回ることを確認できました。claude_code と codex の2ベンダーがあれば、双方向のクロスレビューが成立します。
一方で、動かして初めて見える運用上のポイントもありました。ネイティブCLIハーネスは各ベンダーの認証切れで即止まること、remoteが無いとPRにならずローカルdiffに留まること、並列ブランチが同名ファイルを作るとマージ衝突を人間が片付ける必要があること。これらは概念紹介では出てこない、実際に手を動かさないと分からない部分です。
次に大きなリポジトリの実タスクに当てるなら、ここで見えた「タスク分割とファイルの重なり」「各CLIの認証」「remoteの有無」を先に整えておくと、よりスムーズに通せるはずです。



