0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

非エンジニアのAI業務自動化(ディベートとJev)/3人のAIに反対の立場でディベートさせる仕組みをclaude -pで組んだ

0
Posted at

みなさんは仕事をするときにToDoリストなどを作ることも多いかと思います。

私の作業の一覧(ToDoリスト)には、未完了の作業が24項目あります。
どれを先にやるかをAIに1回聞くと、もっともらしい答えが1つ返ります。
聞き直すと、別の答えが返ることがあります。どちらも理由は通っていて、どちらを信じるか決められませんでした。

ToDoの完了が膨れ上がるとAIが読むテキスト量も増えるので、間違いもさらに増えます。

どうしたもんかと困って、ちょっと考えました(もちろんAIに壁打ちしながらw)

そこで、3人のAIに反対の立場で戦わせ、それを何回もくり返して、どの案が多く勝つかを数えることにしました。決めるのは私で、AIが作るのは材料です。

この記事では、ディベートの仕組みを作った順に書きます。審判に使ったJevとClaudeの審判の一致は、前の記事で書きました。50回回した結果と費用は、次の記事に書きます。

D1.png

図の下段の「50回」は、最後に回した本番の回数です。結果は、次の記事に書きます。

動画から持ち帰ったこと

進め方の元にしたのは、海外Yパパさんの動画(2026年7月16日公開)です。

動画は、交渉やプレゼンのように、本番が一発勝負になる場面の話です。AIで並行世界を作り、裏で何百回もやり直して、一番筋のいい一手だけを持ち帰ります。この記事では、1回の討論を「世界」と呼びます。要点は次の4つでした。

  • 3人に立場を割り当てる(肩入れ・反論・中間)。議論に加わらない審判が、一番説得力のある論を選ぶ
  • 100〜200回くり返して、何度やっても強い勝ち方を拾う。最後に、ある回の強い論と別の回の効いた反論を組み合わせる
  • ぶれがエンジンになる。ぶれがなければ、100回とも同じ結果になる
  • トークンを大量に使う力技なので、費用がかかる。負けられない説得の場面だけに使う

私が持ち帰ったのは、「くり返して分布を見る」と「最後に組み合わせる」の2点です。動画は説得の作戦づくりの話で、私の用途(どの案を選ぶか)とは向きが少し違います。

設計で決めた6つ

2026年10月3日に、次の6つを決めました。

  • 候補から1つを選ぶ形にする
  • 3人の役は、肩入れ・反論・中間にする(動画どおり)
  • 議論は2回にする。1回目は自分の論を出し、2回目は相手の論を読んで、反論と最後の主張を出す
  • 審判は議論に加えない。論を見せる順番は、回ごとに入れ替える
  • 審判が見るのは、根拠、反論への強さ、実行できるかの3点にする
  • 決めるのは私にする

動画から足したのは、何回も回して勝った回数を数えることと、最後に勝った論を組み合わせてまとめを書くことです。最初は、論者をClaude Haiku、回数を20回にしました。

軽い呼び出しにした

ディベートは、1回の討論で論者を6回呼びます(3人が2ラウンド)。Orca(複数のAIエージェントに長い作業を任せる環境。使い分けは次の記事に書きます)の子として動かすには、往復が多すぎて重くなります。そこで、論者も審判もclaude -pで呼ぶことにしました。

claude -pをそのまま使うと、1回ごとに約10万トークンの前置きが付きます(設定、フック、道具の説明などが毎回読み込まれるためです)。これを次のように切りました。

run_debate.py
cmd = ["claude", "-p", "--setting-sources", "", "--tools", "", "--strict-mcp-config",
       "--mcp-config", EMPTY_MCP, "--system-prompt", SYSTEM, "--no-session-persistence",
       "--model", model, "--output-format", "json", prompt]
env = dict(os.environ, **({} if think else {"MAX_THINKING_TOKENS": "0"}))

設定ファイルと道具を空にし、MCPは空の設定を一時ファイルで渡して強制的に切ります。会話は保存しません。実行する場所はOSの一時フォルダにして、プロジェクトのCLAUDE.mdを拾わせません。

論者には考える過程も使わせません。MAX_THINKING_TOKENS=0で、出力が約20分の1になりました。失敗したときは3回まで、3秒、6秒、9秒と待って呼び直します。

役の指示とsystem promptも、短くしました。system promptは1行です。

run_debate.py
ROLES = {
    "肩入れ": "あなたは「肩入れ役」です。割り当てられた案を、最も強く、迷いなく推してください。",
    "反論": "あなたは「反論役」です。割り当てられた案を推しつつ、ほかの案の弱点を具体的に突いてください。",
    "中間": "あなたは「中間役」です。割り当てられた案を、条件や進め方の工夫を添えて、現実的な落としどころとして推してください。",
}
SYSTEM = "あなたはディベートの参加者または審判です。日本語で、指示された JSON だけを返します。前置きや説明文、コードフェンスは付けません。"
RULE = "選ぶ基準:根拠の確かさ、反論への強さ、この人の条件で実行できるか。"

RULEは審判に渡す基準で、設計で決めた3点をそのまま1行にしたものです。

試作して、5つの議題で回した

2026年10月3日の16時7分に、最初の議題で1回だけ試しました。

議題は、
QiitaとNoteの次に、私が力を入れる発信先をどれにするか? です。

16時13分に同じ議題を20回回すと、3.1分で終わりました。審判の票は、LinkedInが12、ブログが8でした。

LinkedInにはすでに書いているので、この調査回答は一旦スルーw

続けて、16時46分から56分にかけて順に始めて、残りの4議題を20回ずつ回しました。

議題は、
すでに構築している個人ナレッジwikiをどう運用するか?、学びの計画をどう立てるか?、読書の内容を想起させて記憶に定着させる仕組みをどう作るか?、構想メモのフォルダをどう構成するか、など です。

この5議題で、審判の比べ方を試しました。その結果は前の記事に書いたとおりで、99回分の記録が残りました。

3人が同じ案に寄っていた

99回を見直すと、3人の最後の主張が同じ案に揃っている回が目立ちました。最後の主張で3人とも同じ案を推していた回数は、次のとおりです。

  • 構想メモのフォルダ:20回中20回
  • 学びの計画:20回中19回
  • 想起カード:20回中15回
  • 個人ナレッジwiki:19回中12回
  • 発信先:20回中4回

合計すると、99回中70回です。動画の「ぶれがエンジン」が、効いていませんでした。3人が最初から同じ案を推すと、反対の立場の論が出ないからだと考えています。

このときは、推す案を3人が自由に選んでいました。

くじで割り当てた

直したのは、推す案、役、モデルを、世界ごとにくじで割り当てる形です。モデルはHaiku 2席とSonnet 1席にしました。

案の割り当ては、候補の数で分けています。候補が3〜6個のときは、3つの組み合わせをすべて作ってシャッフルし、順に回します。

run_debate.py
if len(opts) >= 3:
    combos = list(itertools.combinations(opts, 3))
rng.shuffle(combos)
...
trio = list(combos[n % len(combos)])

抜粋は、3〜6個のときの分岐です。5案なら組み合わせは10通りで、20回なら各組が2回ずつ当たります。7個以上のときは別の分岐で、毎回全部を混ぜて3つずつ取り出します。乱数のシードは、議題の名前と出力フォルダの名前です。同じ条件で回せば、同じ割り当てを再現できます。

推す案は、最後まで変えさせません。プロンプトに「変えてはいけません」と書きます。2ラウンド目は、自分の1回目の論と、ほかの2人の論を渡して、反論させます。

run_debate.py
j = claude_json(f"{base}\n\nあなたが推す案は「{d['option']}」です(変えてはいけません)。{inst}\nあなたの1回目の論:\n{r1[d['id']]}\n\n"
                f"ほかの2人の論:\n{others}\n\nほかの論に反論し、最後の主張を書いてください。"
                '形式:{"final": "<反論を含む最後の主張。300字以内>"}', d["model"], False, a.budget_usd, calls, "debater",
                need={"final": ()})

審判に見せるのは、最後の主張だけです。論者の並びは世界ごとにシャッフルして、P・Q・Rの名前を付けます。役とモデルは伏せます。1回の討論の流れは、次の図のとおりです。

D6.png

直したあとに、個人ナレッジwikiの入口を決める議題を回しました。

19回で、5案が11〜12回ずつ戦っています。
入口を1つにまとめる案が11回中9回(82%)勝ち、ほかの案は12回中4回(33%)以下でした。

図の左は構想メモのフォルダの議題(自由に選ばせた回)、右は個人ナレッジwikiの議題(くじで割り当てた回)の数字です。別の議題なので、同じ議題の前後比較ではありません。

D3.png

19回の中で、勝率がどう動いたかも見ました。

入口を1つにまとめる案は、最初の4回は100%で、6回目に80%まで下がり、その後は揺れながら19回目に82%に落ち着いています。
ほかの案は、最後は33%以下でした。

J2.png

回数が少ないうちは勝率が大きく揺れ、回数を重ねるほど差が見えてきます。

外のレビューで直した

仕組みができたところで、読み取り専用のCodexに、スクリプトと手順書をレビューさせました。承認画面は0回で、56秒で終わり、重大な指摘が7件、軽微な指摘が4件ありました。直したのは次の4点です。

  • 費用の上限が緩い。呼び出しの前に累計を見て、失敗した呼び出しの費用も足すようにした
  • 一時ファイルを取り合う。作成をロックの中に入れた
  • 必要な項目の確認が漏れる。JSONに期待する項目がないときも呼び直すようにした
  • 結果のフォルダが衝突する。同じ名前のフォルダがあれば止まるようにした

これで、本番の50回を回せる状態になりました。

10月3日は、この順で進みました。16時7分の1回の試しから、17時14分〜35分に始めたくじの版の小さな試し、外のレビューでの修正を経て、17時52分に本番の50回を始めています。

D5.png

次の記事

50回回した結果、モデルの差、費用、つまずいた所は、次の記事に書きます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?