コロンビア大学の博士課程でAI・セキュリティの研究をしている Koukyosyumei です。
本連載では、Claude CodeやCodexを使い、さまざまなマルチエージェント研究のワークフローをh5i-python SDKで再実装します。役割分担、レビュー、投票、合議といった設計パターンを、実際に動くコードから理解することを目的としています。
本記事では、プログラムの実装を担当するエージェントと、テスト設計を担当するエージェントを分離する手法を提案している AgentCoder(Huang et al., 2024) を紹介します。
論文概要
このAgentCoderでは、「コードを書く」というプロセスを3つの役割に分割します。
- Programmer: 実際の実装を担当
- Test Designer: テストコードを担当
- Test Executor: テストコードの実行を担当
さらに、この論文では**「Test Designerが実装を直接見ないこと」**を重視しています。なぜなら、テスターが先にコードを見てしまうと、人間が与えたタスクそのものではなく、Programmerが実装したコードがやっていることをテストしようとしてしまうからです。そのため、Test Designerは人間が与えたタスクのみに基づき、Programmerとは独立してテストコードを書きます。また、Test Executorはエージェントではなく、単にテストコードを実行するオラクルです。
h5i-python を用いた実装
h5i-pythonは、Claude CodeやCodexを組み合わせ、様々なマルチエージェント・オーケストラレーションをPythonコードとして実装できるライブラリです。
このh5i-pythonは、監査可能なAI エージェント向けワークスペースを提供するh5iを内部で用いており、h5iが提供する安全なサンドボックスやエージェント間通信を簡単に使うことができます
まずは、ClaudeをProgrammer・CodexをTest Designerとして登録しましょう。
from h5i.orchestra import Conductor, Review, Verification
async with Conductor(".", "agentcoder-demo", launcher="resident", isolation="supervised") as c:
programmer = await c.hire("programmer", runtime="claude", model="claude-haiku-4-5")
test_designer = await c.hire(
"test-designer", runtime="codex", model="gpt-5.4-mini", effort="medium"
)
この二つのエージェントは、同じベースコミットから分岐した二つの異なるサンドボックス化されたWorktreeに隔離され、お互いの実装・変更を直接観測することはできません。
次に、それぞれに行わせたいタスクを送信します。
implementation, tests = await asyncio.gather(
programmer.work(task, expect_independent=True),
test_designer.work(
f"Design the test suite ONLY for: {task}\nWrite thorough "
"tests (basic, edge, and large-scale cases). Do NOT write "
"the implementation itself.",
expect_independent=True,
),
)
await c.freeze()
expect_independent=True により、それぞれの実装・変更が他者に依存しないようになります。
次に、実装されたテストをProgrammerに渡します。
candidate = await programmer.work(
"Apply the granted teammate artifact — an independently designed "
"test suite for your task — into your worktree alongside your "
"implementation. Do not weaken or delete tests; adjust your "
"implementation until it honestly satisfies them.",
materials=[tests],
)
最後に、テストの実行および、改善ループを実装します。テスト自体は新しいサンドボックス内で中立的に実行され、Programmerはテストが全て通るまで改善を繰り返します。
for iteration in range(1, MAX_ITERATIONS + 1):
verification = await c.verify(candidate, ["pytest", "-q"])
if verification.applies_cleanly and verification.tests_passed:
break
if iteration == MAX_ITERATIONS:
break
candidate = await programmer.revise(
candidate,
Review(
reviewer="test-executor",
target=programmer.id,
round=candidate.round,
body=(
"Verdict: REVISE\n\nThe independently designed test "
f"suite failed in a neutral worktree:\n{describe(verification)}\n\n"
"Fix the implementation; do not touch the tests."
),
referenced_artifacts=(candidate.id,),
),
)
最後に、最終成果物を確定させます。
verdict = await c.judge()
print("verdict:", verdict.selected_submission or "none", *verdict.reasons)
全体のコードは、agentcoder.pyに置いてあり、以下のように簡単に実行することができます。
pip install h5i-orchestra
python examples/papers/agentcoder.py "implement quicksort with pytest"
このPythonプログラムを実行すると、tmuxを用いてClaude CodeやCodexのセッションが自動で立ち上がり、実装・通信を始めます。

