INHERITANCE VILLAGE / SYSTEM DESIGN
LLMに世界を任せすぎると壊れるので、Pythonを「神」にした
LLMは何をしたいかを決める。でも、世界で本当に何が起きたかを決めるのはPython。この境界を作るまでに、かなり失敗しました。
LLMで動く村人たちのシミュレーションを作るとき、最初に考えなければならなかったことがあります。
LLMを、どこまで信用するか。
例えば村人に「今何をしますか?」と聞くと、「食料を村へ納品します」「ダンジョンの武器庫へ向かいます」「魔物と戦います」と答えます。
ここまでは問題ありません。でも、その村人がまだ森の中にいたら? 武器庫に武器がもう残っていなかったら? そもそも魔物のいる場所に到着していなかったら?
LLMが「できました」と言ったからといって、本当にできたことにしてしまうと、シミュレーションの世界そのものがLLMの文章に引っ張られて壊れてしまいます。
そこで「継承する村」では、LLMは何をしたいかを決める。世界で実際に何が起きたかはPythonが決める。という分離をかなり強く入れました。
LLMは住民であって、世界そのものではない
このシミュレーションでは、4人の村人をそれぞれLLMで動かしています。毎step、村人には現在地、時刻、所持品、HP、現在の目的、近くのAgentなどを見せます。
- 現在地
- deep_forest
- 時刻
- Day 2 / 昼
- 所持食料
- 6
- HP
- 12
- 現在の目的
- 食料確保
そしてLLMは、今の目的、次に何をするか、誰を対象にするか、仲間に何を話すか、なぜそう考えたか、個人記憶に何を残すかを返します。
しかし、座標やHP、食料数までLLM自身に決めさせることはしません。そこはPython側が管理します。
- 長期目的と当面の目的
- 候補からの行動・対象選択
- 戦う・待つ・撤退する方針
- 会話、判断理由、個人記憶
- 感情を含む日記と次世代戦略
- 座標、場所、時刻、昼夜
- 移動結果、所持量、鍋の量
- HP、攻撃、戦闘ラウンド、死亡
- 武器庫在庫、装備、素材
- 世代境界と最終判定
つまりLLMは「私はこうしたい」とは言える。でも、「だから世界はこうなった」とは決められない。この役割分担にしました。
「食料を納品する」と言われても、まずPythonが確認する
村人が deposit_food を選んだとしても、その瞬間に納品を成立させません。
deposit_food を選ぶ
本当に村にいる?
食料を持っている?
可能なら状態を更新
森の中にいるのに deposit_food を選んでも納品は成立しません。LLMがどれだけ自信満々に「村へ無事に食料を届けた」と話していても、Pythonのログ上で納品されていなければ、納品していません。
これを入れないと、実験結果を信用できなくなる
世代間継承を調べたいとします。第1世代が失敗し、第2世代がその日記を読んだ結果、「素材納品に成功した」とLLMが話した。
これだけでは、継承が効いた証拠にはなりません。確認したいのは、Agentが成功したと言ったかではなく、Python上で素材を持って村へ到着し、deposit_material が実行され、素材在庫が実際に増えたかです。
LLMが生成した自己申告
Pythonが確定した状態遷移
G18で初めて素材課題が完遂したことも、固定版G2がDay 3に素材を納品したことも、最終的にはLLMの文章ではなくPythonイベントを基準に判定しています。
「誰が事実を決めるのか」を固定しておかないと、LLMの物語生成能力を、タスク達成能力と勘違いする可能性があります。
では全部Pythonで決めればいいのでは?
ここで逆の疑問が出てきます。それなら、食料を持ったら自動で村へ帰す、村に着いたら自動で納品する、素材が足りなければAgent 0をダンジョンへ送る、とすればかなり安定します。
実際、その方がゲームとしては簡単に作れます。でも今回は、それをなるべくやらないことにしました。見たいのは、LLM自身がどんな判断をするのかだからです。
能力不足に見える物理的に不可能だけ除外Pythonが
正解を教えてしまう
Pythonは「正しい行動」を教えない
研究用設定では、戦略的な行動ガードレールを基本的にOFFにしています。食料を持っているから帰れ、夜が近いから村へ戻れ、素材が必要だからAgent 3がダンジョン担当、といった上書きはしません。
これらを全部Python側でやってしまうと、LLMが賢かったのか、Pythonのルールが賢かったのか分からなくなるからです。
物理的に不可能な選択肢は除く。戦略的に悪い選択肢は残す。
今のところ、この境界を基本にしています。「その行動はできない」はPythonが言う。でも「その行動はやめた方がいい」まではPythonは言わない。
ただし「不可能なこと」は許さない
自由だからといって、壁の向こうへの瞬間移動、隣接していない部屋への移動、空の武器庫から武器を取る、武器を持っていないのに「武器を持って帰る」を選ぶ、といった行動まで許すわけではありません。
LLMが選ぶ
Pythonが検証
Pythonが確定
再びLLMへ
ダンジョンでは「戦略の失敗」と「APIの失敗」が混ざった
この境界が特に難しかったのがダンジョンでした。最初はLLMに「次にどこへ移動しますか?」と比較的自由に指定させていました。
すると、存在しない部屋を指定する、隣接していない部屋へ移動しようとする、targetが空になる、といった問題が出ました。
target が None になった
これでは、LLMが探索戦略に失敗しているのか、単にインターフェースの使い方に失敗しているのか分かりません。
そこでPythonが、現在地と隣接ノードから実行可能な候補だけを生成し、LLMにはその中から選ばせるようにしました。
entrancepassage_1「passage_1へ行け」と教えているのではなく、存在しない移動だけを候補から除いている。
このとき気付いたのが、戦略の自由と、API操作の自由は別だということでした。
戦闘も全部LLMにはやらせなかった
魔物との戦闘も同じです。LLMには戦う、仲間を待つ、撤退するといった判断をさせます。一方、攻撃力6ならHPを6減らす、といった反復計算はPythonが処理します。
LLM
Python
LLM
4人・5日では最大約1,100回の行動判断があります。創造性が不要なダメージ計算までLLMへ問い合わせると、実験時間もさらに伸びます。
Pythonを「神」にした、という感覚
開発中、このPython側の役割は「世界の神」に近いなと思うようになりました。ただし、「こう生きなさい」と命令する神ではありません。
つまりPythonは、世界の法則だけを維持する存在です。村人が危険だから家にいるのも自由。他人に任せて食料へ行くのも自由。その結果、前の記事のように責任分散が起きてもPythonは助けません。
この設計のおかげで、失敗を「考え」と「事実」に分けて追える
Pythonが権威的な状態を持っていることで、ログも役割別に分離して残せるようになりました。
world_frames.jsonl位置、HP、所持品、目的
events.jsonl移動、採取、納品、死亡
messages.jsonlAgent同士の会話
memory_reasoning.jsonl目的、理由、記憶
diary.jsonl感情を含む主観日記
failure_reports.jsonlPythonの客観的失敗報告
そのため、本人は何を考えていたか、何を選んだか、実際には何が起きたか、次の日記でどう解釈したか、を後から別々に追えます。
前の記事で書いた「全員が誰かがやると思った結果、誰もやらなかった」という協調失敗も、この複数ログを同時に残していたから特定できました。
もちろん、Python側の情報が間違っていたこともある
「Pythonが神だから絶対に正しい」わけでもありません。開発中には、PythonからLLMへ渡す情報にもバグがありました。
例えば食料の携行容量です。深い森では一時的に6個まで運べる設計だったのですが、日記用の記録には基本容量3だけが残っていました。
27Bの村人は、この矛盾を日記の中で指摘しました。これはLLMの推論ミスではありません。LLMへ見せていた世界の説明の方が間違っていました。
「AIが変なことをした」で終わらせない
LLMエージェントが奇妙な行動をすると、つい「AIが馬鹿な判断をした」と思いたくなります。でも実際には、モデル能力だけでなく、プロンプト、Schema、候補生成、世界状態、記憶、表示情報、実際の物理ルールのどこかに原因があるかもしれません。
「武器庫へ行かない」という現象ひとつでも、本当に武器を必要だと思っていない、担当を他人へ任せた、ダンジョンが遠すぎる、夜が怖い、地図が分かりにくい、target Schemaが壊れている、と原因はかなり違います。
AIの失敗を観察したいなら、AI以外の部分をなるべく監査可能にする。
LLMに自由を与えるために、自由に変更できない世界を作った
今回、LLMシミュレーションを作っていて意外だったのは、モデルそのものより、世界のルールとインターフェースを作る時間がかなり長かったことです。
どこまで住民に知らせるか。どこから先を住民自身に考えさせるか。何を物理法則として固定するか。どんな失敗なら観察対象として残し、どんな失敗は単なるAPIエラーとして除外するか。
最終的には、LLMに自由を与えるために、LLMが自由に変更できない世界を先に作る必要がありました。少し矛盾しているようですが、今回の2週間でかなり重要だった発見です。
TATTO LAB / INHERITANCE VILLAGE
前の記事では、4人が「他の誰かがやる」と考えた結果、担当者が0人になった協調失敗を掘り下げています。