LLMにFactorioを遊ばせてみた - オープンワールド編
前回の記事 ではFactorio Learning Environment を実際に動かして、LLMが一人で電子回路の生産を自動化してしまうことを確認しました。
生成された生産ラインの様子
ただし、これはあくまで「ラボ」環境でのプレイでした。ラボ環境では、最初から全ての技術ツリーがアンロックされ、手元に潤沢なアイテムがある状態からのスタートでした。
やはりFactorioの醍醐味は、何もないところから自分で資源を採掘してアイテムを作り、サイエンスパックの物量に苦しみながら研究を進めて新しい技術を手に入れていくところですよね。そこで今回は、この「オープンワールド」環境でのプレイを試してみました。
やってみた
先日4/1はエイプリルフールということで、ネタ企画としてこのFactorio AIプレイの様子を配信していました。その様子がこちらです。
配信時間を12時間として全く何もない状態からのスタートでどこまで行けるのかを検証しました。モデルは現環境最強と言われるClaude3.7 Sonnet Thinkingを使いました。
今回はHuman-in-the-loop的な設定を試したかったため、完全なフリープレイではなく、人間から
一定ステップごとに指示を与えて、その指示をどれくらい達成できるかをみています。指示はスプレッドシートと連携するようにして、筆者がゲームのプレイ状況を見ながら必要に応じて指示を変更するようにしました。
動かすのに使用したソースコードは以下に公開していますので、気になった方はぜひ手元で試してみてください。
なお、今回の実験のトークン代は$120程度かかりました。お試しの際は使いすぎにご注意ください><^1
プレイ詳細
ゲーム内で与えた具体的な指示は以下の通りです。
- 水汲みポンプ、ボイラー、蒸気機関からなる発電所を建設する
- 電気ドリル・石炉・インサータを組み合わせて、鉄板・銅板の生産を自動化する
- 研究所を設置し、「物流サイエンスパック」の研究を完了する
- 「太陽光発電」の研究を完了する
- 太陽光パネルを設置する
- 自動化サイエンスパックの生産を自動化する
- 物流サイエンスパックの生産を自動化する
どのような順番で指示を与えるかで難易度も変わるため、指示側にもゲーム要素があるのが面白いところです。まずはやはり石炭燃料だと石炭補給に追われて他のタスクが進められなくなるため、最優先で電気を開通させてボイラー・炉以外のエネルギーを電子化することを目指します。そこから電気ドリル・インサータを使って鉄板と銅板の生産を自動化し、それらを使って研究を進めていきます。
引き続きボイラーの石炭補給がネックになるため、太陽光発電を目指して研究を進めていき、太陽光パネルで安定した電力供給の実現を目指します。最後にそこから各種オートサイエンスパックの生産の自動化がどこまでできるかを試しました。
なお、石炭供給については後述するようにベルトコンベアの扱いが非常に苦手で複雑なベルトラインを構築するのが現実的でないと判断したため、自動化にはチャレンジしていません。
結果としては次のようになりました。
-
発電所の建設:40分経過時点で完了
-
鉄板・銅板の自動化:2時間経過時点で完了
-
物流サイエンスパック研究:2時間半経過時点で完了
工場っぽいものはできていますが、全てアイテムを手動で入れており、自動化には至っていません -
太陽光発電研究:9時間40分経過時点で完了
-
太陽光パネル設置:10時間経過時点で完了
-
自動化サイエンスパックの生産自動化:失敗
-
物流サイエンスパックの生産自動化:失敗
サイエンスパックをベルトに乗せるところまではできていますが、研究所に入れるインサータがありません
太陽光発電の研究に膨大な時間がかかっていることがわかります。これはそもそも必要な資源数がとても多いというのもあるのですが、後述するように発電所を誤って2回破壊してしまい、その復旧や発電所の移設にかかった時間が大きいです。
最終的な全体像は次のようになりました。
右側にあるのが蒸気発電所+太陽光発電、左側に鉄板・銅板の製造所と散発的な工場、研究所とそこにつながるベルトコンベアがあります。
工場とサイエンスパックのベルトコンベアはそれっぽいですがうまく接続されておらず、手動の介入が必要です。
北の方には元々あった発電所の名残とそれに続く長い送電線があります。苦労の跡が感じられますね。。。
以下では、プレイを見ていて気付いた点について、特にFactorio以外での活用についての真面目な話も絡めながら書いていきます。
動いている施設を破壊してしまう
上に書いたように、太陽光発電の研究中に発電所を誤って破壊してしまう(ポンプとボイラーの間のパイプを切断してしまう)という事故が2回発生しました。
鉄板と銅板の自動化は完了していたので、ひたすら板を作って手作りでサイエンスパックを作っていけばそこまで研究に時間はかからなかったはずなのですが、この事故の復旧に大きく時間を取られた形となりました。
事故現場の様子
Factorio Learning Environmentではエンティティの状態に関する情報をエージェントに与えることで適切な行動を促すようになっています。例えばボイラーで石炭がなくなると "no fuel" というwarningが出るので、エージェントはこれを見て石炭を補給しにいくという流れになっています。ボイラーが "no fuel" となっているタイミングでは蒸気が生成されなくなるため、蒸気機関に関しても連鎖的に "no steam input" というエラーが発生してしまいます。今回の事故はおそらく、この "no steam input" の原因を "no fuel" だと理解できず、パイプの接続に問題があると判断して切断を行なったものと考えられます。
今回は起こらなかったですが、テストプレイで試していた際には 「システムの復旧に繰り返し失敗した結果、全ての施設を破壊して1から作り直す」 といったような冷や汗をかくような挙動も見られました。
笑い話のようですが、このように問題の原因を見誤って正常なシステムを壊してしまうといったリスクは今後LLMの実用化を進めていく上で同様に発生しうるなと感じました。例えばエージェントにシステムのリアルタイムなメンテナンスを任せることを考えた場合には、ネットワークの一時的な障害なのに設定に問題があると判断して無駄に変更を加え、さらに状況を悪化させてしまうといったことが起こり得ます。もっと極端な例を挙げれば「地球温暖化の解決をお願いしたらその原因である人間を排除しようとし始めた」のようなシナリオも、この挙動を見ていると考えられない話ではないなと確かに思いました。
LLMの安全性を担保していく上では人間による適切な承認プロセスと権限付与の設計が必要不可欠であると、この例を見ても改めて思います。
自律エージェントの性能を決めるのはエラーからの復帰能力・アプローチの多角性
エージェントの性能の差を一番感じたのは、一度に書けるコード量とエラーに陥った時にそこから自力で脱出できるかどうかでした。特に後者については弱いモデルだと同じ方法を何回も試して無限ループにハマっているケースでは手の打ちようがなかったのに対し、ClaudeやGeminiなどの優秀なモデルでは自分で複数のアプローチを試したり一度施設を撤去してもう一度別の場所に設置して試したりと、自力で脱出できているパターンがみられました。
今回の実験では、過去の行動履歴を要約して全て保持するようになっていたオリジナル版の実装に対し、イテレーション(10ステップ、開始時点で人間からの指示を受けとる)ごとに履歴をリセットして新しい状態から行動してもらうよう実装を変更したのですが、これは履歴をずっと持ち回すと上のようにハマった場合に抜け出せなくなったり、間違ったパターンを学習してどんどん正しい方向からずれていくような挙動が見られたためです。文章の続きを予測することで「思考」を行うLLMではこのような間違いの増幅や沼にハマりがちであり、一定のランダム性やリセット機構を持たせることがエージェントの実用化に当たっては重要になるのではないかと思いました。
適切なフィードバックの重要性
上2つに関連する話ではありますが、今回エージェントの性能を改良する上で一番重要だったのが「エラー時に適切なメッセージを提供すること」でした。
例えば別の場所に移動するmove_toアクションでは移動先が遠すぎたり経路が見つからなかったりする場合にエラーになることがあるのですが、オリジナルの実装だと "Cannot move." というメッセージだけで、これになると多くのエージェントはスタックしてしまっていました。これを "Cannot move, destination is too far or unreachable. Please try another destination." という風に変えると、別のより近いポイントを指定することでエラーから回復してくれるような挙動が見られました。
このように、エラーからの復帰能力および原因の推測をガイドしてあげる上で、エラーメッセージや実行のフィードバックはクリティカルな役割を果たすことになりそうです。現在コーディングにおいてエージェントが目覚ましい成果を挙げているのは、言うまでもなくコンパイラやリンターといった先人が築き上げてきたツール群によるところが大きいでしょう。より広い領域にエージェントの活用を広げていく上で、アクションに対してどれだけ明確なフィードバックを提供できるか(例:エラーメッセージを明確にする、POSTリクエストに対して作成されたレコードを返す等)が重要で、これらはMCPサーバーの設計などにおいても留意すべきポイントになってくるのではないでしょうか。
さいごに
オープンワールドの設定でもLLMである程度プレイできるのがわかったのは一つの成果ですが、Factorioの一番の面白さとも言えるベルトコンベアを使った工場建築というところには全く太刀打ちできない結果となり、やや消化不良感のある結果となってしまいました。
悔しいので今後ももう少しこのFactorio Learning Environmentで遊んでみたいなと思っています。画像入力(マルチモーダルモデルの活用)、ツール群の細かい改善をはじめ、リプレイデータを使った性能評価・オープンモデルの学習にもチャレンジしてみたいです。
Discussion