最近、設計とかPRレビューをAIに相談することが増えました。
Claude CodeやCopilotに、
「この設計どう思う?」
と聞くと普通にかなり良いことを言ってくれます。
ただ、使っているうちに一つ気になることがありました。
結局、一つのAIの判断に乗っかってるだけでは?
もちろん、
「セキュリティ担当、アーキテクト、プロダクト担当の3人になって議論して」
みたいなプロンプトを書くことはできます。
自分も最初はそれでいいと思っていました。
でも、よく考えるとちょっと変です。
同じ会話の中で3人格を演じても、2人目は1人目の回答を知っています。
3人目は1人目と2人目の回答を知っています。
しかも最後に、
「では総合的に判断すると〜」
と結論を出すのも同じAIです。
それって本当に多数決なんだろうか。
そんな疑問から作り始めたのが、これです。
最初は本当に「3人に聞くだけ」だった
名前の通り、エヴァのMAGIが元ネタです。
最初に考えていたのはかなり単純で、
- MELCHIOR
- BALTHASAR
- CASPER
の3つのAgentを動かして、2票以上取った意見を採用する。
それだけでした。
ただ、作っていくと問題がどんどん出てきました。
例えば、
MELCHIOR: approve
BALTHASAR: reject
CASPER: approve
だったとして。
この3票を最後にLLMへ渡して、
「結果をまとめて」
とお願いしたら、LLM側が
「安全上の懸念があるため今回は見送るべきです」
と解釈することもできます。
それなら、何のために投票させたのか分かりません。
なので、採決はAIにやらせるのをやめました。
今はRustで書いたCLIが票を数えます。
2 approve -> approved
2 reject -> rejected
otherwise -> undecided
かなり普通です。
でも、この普通の処理をLLMの外に出すことが自分の中では結構大事でした。
そもそも他のAgentの回答を見せたくない
もう一つ気になったのが、他人の意見に引っ張られることです。
例えば最初のAgentが、
「この変更は危険です」
と強めに言ったあとで、残り2つのAgentを動かす。
これだと、後のAgentがその意見を前提に考えてしまう可能性があります。
なのでMAGI Councilでは、対応しているHost上では3つを別々のSubagent Contextで動かします。
さらに、投票内容そのものを親Agentへ返さず、Hook側で保存します。
親Agentに返るのは、
VOTE_SEALED
だけです。
つまり3票揃うまでは、誰が何に投票したのか分かりません。
ここまでやって、ようやく自分の中で
「3人に聞いた」
と言ってもいいかな、と思えるようになりました。
もちろん、同じモデルを3つ使っているなら完全に独立しているわけではありません。
3人とも同じ勘違いをすることは普通にあり得ます。
ここはこの仕組みで解決できる問題ではないです。
でも完全に隔離すると、それはそれで微妙だった
ここは作ってから気づきました。
他のAgentの意見を一切見せないようにすると、独立性は上がります。
ただ、人間の議論にある
「その指摘を聞いたら確かにそうかも」
がなくなります。
独立した3人にアンケートを取っているだけになってしまう。
それで後から追加したのがTHOMASです。
THOMASは4票目を持つAgentではなく、反論役です。
最初の3票を集めたあと、必要であれば各意見に対する反証を作ります。
その反証だけを本人へ返して、もう一度考えてもらいます。
他のPersonaが何票入れたかは見せません。
例えば、
初回:
MELCHIOR -> approve
だったものが、反証を読んで
最終:
MELCHIOR -> reject
になることもあります。
最初からAgent同士で会話させるのではなく、
一度自分で考えさせてから反論だけ渡す
形にしました。
この辺から、当初思っていたよりだいぶ面倒なプロジェクトになりました。
多数決だけでは危ないケースもある
もう一つ悩んだのがCritical Riskです。
例えば2対1でapproveだったとしても、1人だけが
「認証を回避できる」
みたいな問題を見つけていたら、そのまま通したくありません。
そのため、設定によってはCritical RiskにVetoを持たせています。
なので、
approve
approve
reject + critical risk
でもrejectになるケースがあります。
多数決を作っておいて多数決をひっくり返すのはどうなんだ、と自分でも思いました。
ただ、実際の開発判断でも、
「3人中2人がOKって言ったから脆弱性あるけどリリースします」
とはならないので、ここは必要だと判断しました。
何でも3Agentで考えれば良いとは思っていない
作っておいてなんですが、MAGI Councilを常用したら普通に重いです。
Agentを3つ動かすので、当然トークンも使います。
さらにTHOMASまで動かしたらもっと増えます。
なので現在は、
- 票が割れた
- Critical Riskの根拠が怪しい
- 少数派だけ別のEvidenceを持っている
- 同じEvidenceについて評価が割れている
みたいな時だけ、追加レビューを走らせるようにしています。
逆に3人とも同じ結論で、特に怪しいところがなければ、そのまま採決します。
変数名を決めるためにMAGIを呼ぶ必要はないです。
自分が想定しているのは、
- このPRをマージするか
- この設計で進めるか
- Breaking Changeを許容するか
- 今日リリースするか
- 技術的には正しいけど運用がしんどい変更を採用するか
みたいな、ちょっと判断に迷う場面です。
作っていて一番面白かったところ
最初はマルチエージェントを作ってみたかっただけでした。
でも途中から、考えていることが変わってきました。
「Agentを何人動かすか」より、
LLMにどこまで任せるか
の方が面白くなりました。
例えばMAGI Councilでは、
AIに任せているのは、
- Evidenceを読む
- リスクを考える
- approve / reject / abstainを選ぶ
ところです。
一方で、
- 投票形式の検証
- 投票の保存
- 票数計算
- Veto判定
- 状態管理
- Hash検証
みたいなものは普通のプログラムでやっています。
LLMに全部やらせた方が実装は簡単です。
でも、決まったルールで動いてほしいところまでLLMに任せる必要はないと思いました。
この線引きは、作っていてかなり面白かったです。
まだ普通に課題はある
もちろん、これでAIの判断が正しくなるわけではありません。
同じモデルを使っていれば、3Agentとも似たミスをする可能性があります。
Confidenceも自己申告なので、
{
"confidence": 90
}
だから90%正しい、という意味ではありません。
また、SubagentやHookでどこまでContextを分離できるかはHost側の機能にも依存します。
MAGI Councilは「正解を出す仕組み」というより、
AIに判断させる時の手順をなるべく曖昧にしないための仕組み
くらいに考えています。
さいごに
GitHubはこちらです。
最初は、
「MAGIみたいに3つのAIで多数決したら面白そう」
くらいのノリで作り始めました。
結果的には、
「3Agentをどう動かすか」
よりも、
「AIの回答を意思決定として扱うなら、何をAIに任せて何をプログラム側で固定するべきか」
を考えるプロジェクトになりました。
まだ改善中なので、設計的に怪しいところや、
「そこまでやるならこうした方が良くない?」
みたいなのがあればIssueをもらえると嬉しいです。