👓

LLMを使って兵士育成シミュレーションを開発してみた。

に公開

はじめに

こんにちは。ナウキャストでデータエンジニアをしているTakumiです。

2025年6月25日にCitySim: Modeling Urban Behaviors and City Dynamics with Large-Scale LLM-Driven Agent Simulation という論文がWoven by TOYOTAから発表されました。
この論文では、LLMを用いて都市計画のシミュレーションを行う手法を紹介しています。

論文を読んで、

  • AI Agentの自由度
  • シミュレーションを行うための環境制約

を美しく融合させており、とても面白いと思いました!
解説とそれを利用して実装したシステム(soldier_sim)を紹介します!

この記事でわかること

この記事では、LLM(大規模言語モデル)を使ったシミュレーション手法であるCitySimの解説 と、その手法を用いて実装した兵士育成システム(soldier_sim)の紹介 を行います。

この記事で紹介する兵士育成ゲームのコードは以下のリポジトリで公開しています。
https://github.com/TakumiMukaiyama/soldier_sim

理論編(論文紹介)

CitySim全体のコンセプト

CitySim論文は、従来の都市シミュレーションが抱える根本的な限界を解決するために、LLMを活用したアプローチを提案しています。

従来手法の課題

従来のAgent-Based Model(ABM)の限界としては、以下のような課題がありました。

  • 硬直的なルールベース: 手作りのルールによる制約で、人間の微妙な意図や計画、適応的行動を再現できない
  • 予測精度の限界: 解釈可能性は高いが、現実の複雑な人間行動を正確に予測できない
  • 環境変化への適応不足: 変化する環境に対する認知的柔軟性が不足

深層学習ベースでもシミュレーションは可能で、ある程度の精度は達成できますが、こちらでも以下のような課題があります。

  • ブラックボックス性: 予測性能は高いが、内部メカニズムが解釈困難
  • 大量データ依存: 広範囲な訓練データが必要
  • 動的環境対応: 変化する環境条件への適応が困難

解決アプローチ

そこで、LLMを使ってより柔軟かつ高精度なシミュレーションを実現するために開発されたのがCitySimという手法です。
CitySimには、以下のような特徴があります。

  • LLM駆動エージェント: 人間レベルの知能を持つLLMによる柔軟な意思決定
  • 再帰的価値駆動アプローチ: 義務的活動、個人的習慣、状況的要因をバランスよく統合
  • マルチモーダル都市コンテキスト: 視覚的、社会的、文化的手がかりを統合的に処理

再帰的価値駆動アプローチ(Recursive Value-Driven Approach)

理論的基盤

CitySim の核心となる理論は、再帰的価値駆動アプローチです。これは人間の意思決定プロセスを以下の3つの要素の動的バランスとして整理しています。

  1. 義務的活動(Mandatory Activities): 仕事、学校など社会的に必要な活動
  2. 個人的習慣(Personal Habits): 個人の好み、過去の経験に基づく行動パターン
  3. 状況的要因(Situational Factors): 現在の状況、突発的な出来事への対応

この整理を行うことで、人間の複雑な意思決定フローの記録と、各意思決定が次の意思決定に及ぼす影響を定量的に表すことができています。

価値関数の定式化

エージェントの行動選択は、以下の統合価値関数により決定します。

V(a_t) = \alpha \cdot V_{\text{mandatory}}(a_t) + \beta \cdot V_{\text{habit}}(a_t) + \gamma \cdot V_{\text{situation}}(a_t) + \delta \cdot V_{\text{belief}}(a_t)

where

  • V(a_t): 時刻 t における行動 a の総合価値
  • V_{\text{mandatory}}(a_t): 義務的価値(社会的・職業的責任)
  • V_{\text{habit}}(a_t): 習慣的価値(過去の行動パターンとの一致度)
  • V_{\text{situation}}(a_t): 状況的価値(現在の状況への適合度)
  • V_{\text{belief}}(a_t): 信念価値(POI(Point of Interest)に対する主観的評価)
  • \alpha, \beta, \gamma, \delta: 重み係数(個人特性により調整)

各価値要素の詳細計算方法

1. 義務的価値 V_{\text{mandatory}}(a_t)

概念: 社会的役割や職業的責任に基づく行動の必要性を表す価値です。

計算式:

V_{\text{mandatory}}(a_t) = \sum_{r \in R} w_r \cdot \text{urgency}(r, t) \cdot \text{relevance}(a_t, r)

where:

  • R: エージェントが持つ役割・責任の集合
  • w_r: 役割 r の重要度重み
  • \text{urgency}(r, t): 時刻 t における役割 r の緊急度
  • \text{relevance}(a_t, r): 行動 a_t の役割 r への関連度

具体例(兵士エージェントの場合):

# 兵士の義務的価値計算例
roles = {
    "combat_training": {"weight": 0.4, "urgency": high_during_training_hours},
    "equipment_maintenance": {"weight": 0.3, "urgency": depends_on_equipment_state},
    "administrative_duty": {"weight": 0.2, "urgency": depends_on_schedule},
    "team_coordination": {"weight": 0.1, "urgency": high_during_operations}
}

# 訓練場への移動を評価する場合
def calculate_mandatory_value(action="go_to_training_ground", current_time="09:00"):
    if action == "go_to_training_ground" and "09:00" <= current_time <= "17:00":
        return 0.4 * 0.9 * 1.0  # 高い義務的価値
    else:
        return 0.4 * 0.2 * 0.3  # 低い義務的価値
2. 習慣的価値 V_{\text{habit}}(a_t)

概念: 過去の行動パターンとの一致度に基づく価値です。人間の行動の予測可能性と安定性を表現します。

計算式:

V_{\text{habit}}(a_t) = \sum_{h \in H} \text{freq}(h) \cdot \text{similarity}(a_t, h) \cdot \text{recency}(h)

where:

  • H: 過去の行動履歴
  • \text{freq}(h): 行動 h の過去の実行頻度
  • \text{similarity}(a_t, h): 候補行動 a_t と過去行動 h の類似度
  • \text{recency}(h): 行動 h の最近性(時間的近さ)

具体例:

# 習慣的価値の計算例
def calculate_habit_value(candidate_action, action_history):
    total_value = 0.0
    
    for past_action in action_history:
        # 頻度計算(過去30日間での実行回数)
        frequency = count_action_in_period(past_action, days=30) / 30
        
        # 類似度計算(同じPOI, 同じ時間帯など)
        similarity = calculate_action_similarity(candidate_action, past_action)
        
        # 最近性計算(指数減衰)
        days_ago = (current_time - past_action.timestamp).days
        recency = exp(-0.1 * days_ago)
        
        total_value += frequency * similarity * recency
    
    return total_value

# 例:毎朝8時に食堂に行く習慣がある兵士
# 現在時刻8:05で食堂への行動を評価
habit_value = calculate_habit_value(
    candidate_action="go_to_mess_hall",
    action_history=past_morning_routines
)  # → 高い値(0.8-0.9)を返す
3. 状況的価値 V_{\text{situation}}(a_t)

概念: 現在の内部状態と環境状況に対する行動の適合度を表す価値です。

計算式:

V_{\text{situation}}(a_t) = \sum_{s \in S} w_s \cdot \text{need}(s) \cdot \text{satisfaction}(a_t, s)

where:

  • S: 内部状態の集合(エネルギー、空腹、社会的欲求など)
  • w_s: 状態 s の重要度重み
  • \text{need}(s): 状態 s の現在の需要レベル
  • \text{satisfaction}(a_t, s): 行動 a_t による状態 s の満足度

具体例:

# 状況的価値の計算例
def calculate_situational_value(action, agent_state):
    states = {
        "energy": {"weight": 0.4, "need": 1.0 - agent_state.energy},
        "hunger": {"weight": 0.3, "need": agent_state.hunger},
        "social": {"weight": 0.2, "need": abs(0.5 - agent_state.social)},
        "safety": {"weight": 0.1, "need": 1.0 - agent_state.safety}
    }
    
    total_value = 0.0
    for state_name, state_info in states.items():
        # 行動による状態改善度を計算
        improvement = calculate_state_improvement(action, state_name)
        
        # 需要と改善度の積
        value_contribution = (
            state_info["weight"] * 
            state_info["need"] * 
            improvement
        )
        total_value += value_contribution
    
    return total_value

# 例:エネルギーが低い(0.2)兵士が宿舎に行く場合
situational_value = calculate_situational_value(
    action="go_to_barracks",
    agent_state=AgentState(energy=0.2, hunger=0.1, social=0.5)
)  # → 高い値(エネルギー回復のため)
4. 信念価値 V_{\text{belief}}(a_t)

概念: 各POIに対するエージェント個人の主観的評価に基づく価値です。カルマンフィルタで更新される多次元信念を使用します。

計算式:

V_{\text{belief}}(a_t) = \sum_{d \in D} w_d \cdot \mu_d(POI) \cdot \text{relevance}(d, \text{context})

where:

  • D: 信念次元の集合(満足度、利便性、雰囲気、効果性)
  • w_d: 次元 d の重要度重み
  • \mu_d(POI): POIに対する次元 d の信念平均値
  • \text{relevance}(d, \text{context}): 現在の文脈における次元 d の関連度

具体例:

# 信念価値の計算例
def calculate_belief_value(action, poi, agent_beliefs, context):
    if action.target_poi != poi:
        return 0.0
    
    belief_dimensions = {
        "satisfaction": {"weight": 0.3},
        "convenience": {"weight": 0.2}, 
        "atmosphere": {"weight": 0.2},
        "effectiveness": {"weight": 0.3}
    }
    
    total_value = 0.0
    for dimension, info in belief_dimensions.items():
        # POIに対する信念値を取得(カルマンフィルタで管理)
        belief_mean = agent_beliefs[poi][dimension]["mean"]
        belief_variance = agent_beliefs[poi][dimension]["variance"]
        
        # 文脈関連度(疲労時は雰囲気重視、緊急時は効果性重視など)
        context_relevance = calculate_context_relevance(dimension, context)
        
        # 不確実性を考慮した価値計算
        uncertainty_penalty = sqrt(belief_variance) * 0.1
        
        dimension_value = (
            info["weight"] * 
            belief_mean * 
            context_relevance * 
            (1.0 - uncertainty_penalty)
        )
        
        total_value += dimension_value
    
    return total_value

# 例:訓練場に対して高い効果性信念を持つ兵士
belief_value = calculate_belief_value(
    action="go_to_training_ground",
    poi="training_ground",
    agent_beliefs={
        "training_ground": {
            "satisfaction": {"mean": 0.7, "variance": 0.1},
            "convenience": {"mean": 0.5, "variance": 0.2},
            "atmosphere": {"mean": 0.6, "variance": 0.15},
            "effectiveness": {"mean": 0.9, "variance": 0.05}  # 高い効果性信念
        }
    },
    context="skill_improvement_needed"
)  # → 高い値を返す

重み係数の個人差設定

重み係数 \alpha, \beta, \gamma, \delta は、エージェントの個性を表現する重要なパラメータです。

性格タイプ別の係数例:

personality_weights = {
    "disciplined_soldier": {
        "alpha": 0.5,  # 義務重視
        "beta": 0.3,   # 習慣重視
        "gamma": 0.1,  # 状況対応は低め
        "delta": 0.1   # 主観は抑制
    },
    "adaptive_soldier": {
        "alpha": 0.2,  # 義務は最低限
        "beta": 0.1,   # 習慣に縛られない
        "gamma": 0.5,  # 状況対応重視
        "delta": 0.2   # 経験活用
    },
    "experienced_veteran": {
        "alpha": 0.3,  # 義務は理解
        "beta": 0.2,   # 適度な習慣
        "gamma": 0.2,  # バランス取り
        "delta": 0.3   # 経験信頼
    }
}

この詳細な価値関数設計により、CitySim は人間らしい複雑で個性的な意思決定プロセスを LLM エージェントに適用することができています。

再帰的最適化プロセス

行動選択は以下の再帰的プロセスで実行します。

1. 現在状態の評価
   → 多次元需要パラメータの更新
   → 個人特性係数(α, β, γ, δ)の適用
   → 時間・環境要因の考慮
   
2. 候補行動の生成
   → 利用可能なPOI(Point of Interest)の列挙
   → アクセス可能性制約の適用
   
3. 価値計算
   → 各候補行動に対する統合価値V(a_t)の算出
   → 義務的・習慣的・状況的・信念価値の統合
   
4. 最適行動選択
   → 最高価値を持つ行動の決定
   → 不確実性を考慮した確率的選択
   
5. 実行と学習
   → 行動実行後の結果観測
   → カルマンフィルタによる信念更新
   → 経験の多層メモリシステムへの格納

カルマンフィルタによる信念更新メカニズム

理論的背景

エージェントがPOI(Point of Interest)に対して形成する主観的信念は、ベイズ推定の特殊ケースであるカルマンフィルタを用いて更新します。これにより、エージェント毎に性格や能力に幅を持たせることができます。

カルマンフィルタの数学的定義

基本更新式

エージェントがPOIを利用した際の信念更新は以下の式によって行います。

K = \frac{\sigma_b^2}{\sigma_b^2 + \sigma_o^2}

where:

  • K: カルマンゲイン(新しい観測への信頼度)
  • \sigma_b^2: 事前信念の不確実性(事前分散)
  • \sigma_o^2: 観測ノイズ(観測分散、デフォルト: 0.2)

信念と不確実性の更新

\begin{align} \mu_{\text{updated}} &= K \cdot z_t + (1 - K) \cdot \mu_{\text{prior}} \\ \sigma_{\text{updated}}^2 &= (1 - K) \cdot \sigma_b^2 \end{align}

where:

  • \mu_{\text{updated}}: 更新後の信念(平均)
  • z_t: 時刻 t での観測値
  • \mu_{\text{prior}}: 事前信念(平均)

ベイズ推定との関係

カルマンフィルタは、ガウス分布を仮定したベイズ推定の解析解として理解できます。

P(\theta|D) \propto P(D|\theta) \cdot P(\theta)

事前分布: P(\theta) = \mathcal{N}(\mu_b, \sigma_b^2)
尤度: P(D|\theta) = \mathcal{N}(\theta, \sigma_o^2)
事後分布: P(\theta|D) = \mathcal{N}(\mu_{\text{updated}}, \sigma_{\text{updated}}^2)

信念次元の多次元管理

各POIに対して、エージェントは4次元の信念ベクトルを管理します。

belief_dimensions = {
    "satisfaction": "満足度(総合的な満足感)",
    "convenience": "利便性(アクセスしやすさ)", 
    "atmosphere": "雰囲気(環境の快適さ)",
    "effectiveness": "効果性(目的達成度)"
}

各次元で独立してカルマンフィルタを適用し、エージェント固有の経験を反映した多面的な信念を形成します。

学習の収束特性

カルマンフィルタの重要な特性は以下の通りです。

  1. 不確実性の単調減少: \sigma_{\text{updated}}^2 \leq \sigma_b^2 が常に成立
  2. 一貫性: 観測データが増加するほど真の値に収束
  3. 最適性: 最小二乗誤差の意味で最適な推定

多層メモリシステム(3層メモリアーキテクチャ)

アーキテクチャ概要

CitySim では、人間の記憶システムを模倣した3層メモリアーキテクチャを採用しています。

Temporal Memory ←→ Reflective Memory ←→ Spatial Memory
     ↑                    ↑                    ↑
 詳細な行動記録        日次行動パターン     POI信念ベクトル

Temporal Memory(時系列メモリ)

機能: エージェントのすべての行動を詳細に時系列で記録

記録内容:

  • 行動の時刻・場所・種類・継続時間
  • 行動時のエージェント内部状態
  • 行動選択の理由・判断根拠

活用方法:

  • 時間範囲による行動履歴の検索
  • エージェント別の行動パターン分析
  • POI利用頻度・傾向の把握

Reflective Memory(内省メモリ)

機能: 日次でTemporal Memoryを要約し、エージェントの行動パターンを抽出

生成プロセス:

  • 日次でTemporal Memoryの生データを分析
  • 行動頻度パターンの統計的要約
  • エージェントの状態変化傾向の抽出
  • スキル成長パターンの識別
  • 社会的相互作用の記録
  • 意思決定ロジックの特徴抽出

抽象化レベル

  • Level 1: 個別行動の統計的要約
  • Level 2: 行動パターンの識別
  • Level 3: 長期的傾向の抽出

Spatial Memory(空間メモリ)

機能: 各POIに対する多次元信念ベクトルの管理

信念ベクトル構造:

  • 多次元評価: 満足度、利便性、雰囲気、効果性の4次元
  • 確率的表現: 各次元をガウス分布(平均・分散)で表現
  • 不確実性管理: 経験不足時は高い分散、経験蓄積で分散減少
  • 履歴追跡: 過去の観測値履歴を保持
  • 利用統計: 訪問回数・最終更新日時の記録

更新メカニズム

  1. POI利用後に観測値生成
  2. 各次元でカルマンフィルタ適用
  3. 信念と不確実性の同時更新
  4. 履歴データの蓄積

実装編

CitySimの理論を応用して、兵士を育てるほったらかしゲームのようなシステム(soldier_sim)を作成しました。

システム概要

soldier_sim は、CitySim論文の理論をベースに、軍事環境における兵士の育成をシミュレーションするLLM駆動マルチエージェントシステムです。

基本仕様

  • 規模: 最大100名のエージェント(兵士)を同時にシミュレーション
  • 期間: 100日間の連続シミュレーション(2400時間ステップ)
  • 環境: 訓練場、食堂、宿舎、指揮本部、武器庫の5つのPOI
  • スキル: 武器技能、組織マネジメント能力、社会性の3つの専門能力
  • 個性システム: カルマンフィルタによる施設への主観的評価の更新

エージェント(兵士)の実装

兵士エージェントを定義することで、軍事組織における多様な個性と能力を持つ人員をシミュレーションします。育成ゲーム要素を重視し、長期的な成長を楽しめる設計となっています。

エージェント属性設計

class SoldierAgent:
    def __init__(self, agent_id: str, personality: Dict):
        # 基本情報
        self.id = agent_id
        self.name = personality["name"]
        self.rank = personality["rank"]  # Private, Corporal, Sergeant, Lieutenant, Captain
        
        # 基本状態パラメータ(消耗/回復型)
        self.energy = 1.0           # エネルギー(体力・精神力)
        self.hunger = 0.0           # 空腹度
        self.social = 0.5           # 社会的欲求
        
        # スキルパラメータ(成長型)- 育成ゲーム要素
        self.weapon_strength = 0.3   # 武器技能(戦闘・武器操作)
        self.management_skill = 0.2  # 管理技能(指導力・リーダーシップ)
        self.sociability = 0.5       # 社会性(コミュニケーション能力)
        
        # 個性パラメータ(Big Five準拠)
        self.personality_traits = {
            "openness": personality["traits"]["openness"],         # 開放性
            "conscientiousness": personality["traits"]["conscientiousness"], # 誠実性
            "extroversion": personality["traits"]["extroversion"], # 外向性
            "agreeableness": personality["traits"]["agreeableness"], # 協調性
            "neuroticism": personality["traits"]["neuroticism"]    # 神経症傾向
        }
        
        # 多層メモリシステム
        self.spatial_memory = {}     # POI信念ベクトル
        self.location = [0.0, 0.0]   # 現在位置

育成ゲーム設計方針

スキル成長の設計思想

本システムは育成ゲームとして設計し、プレイヤーが長期間にわたってエージェントの成長を楽しめるよう、以下の方針を採用しています。

1. 初期スキルレベルの制限

# 階級別初期スキル設定例
rank_initial_skills = {
    "Private": {
        "management_skill": (0.0, 0.05),    # 新人レベル
        "weapon_strength": (0.4, 0.6),      # 基礎訓練済み
        "sociability": (0.3, 0.7)           # 個人差大
    },
    "Corporal": {
        "management_skill": (0.08, 0.12),   # 初級リーダー
        "weapon_strength": (0.5, 0.7),      # 中級技能
        "sociability": (0.4, 0.8)
    },
    "Captain": {
        "management_skill": (0.28, 0.30),   # 最高初期レベル
        "weapon_strength": (0.6, 0.8),      # 高技能
        "sociability": (0.6, 0.9)
    }
}

2. 成長上限の設定

  • Management Skill: 最大成長幅 0.7(Private)〜 1.0(Captain)
  • Weapon Strength: 技能特化により1.0まで到達可能
  • Sociability: 性格特性により個人上限を決定

需要パラメータの詳細

基本状態パラメータ

Energy(エネルギー)

  • 機能: 体力・精神力を表現
  • 変化: 時間経過で減少、休憩・食事で回復
  • 更新式: \text{energy}_{\text{new}} = \max(0.0, \text{energy} - 0.05 \times \Delta t \times \mathcal{U}(0.8, 1.2))

Hunger(空腹度)

  • 機能: 生理的欲求レベル
  • 変化: 時間経過で増加、食事で大幅減少
  • 更新式: \text{hunger}_{\text{new}} = \min(1.0, \text{hunger} + 0.08 \times \Delta t \times \mathcal{U}(0.8, 1.2))

Social(社会的欲求)

  • 機能: 他者との交流への欲求
  • 変化: 性格(外向性)に応じて減少、交流で回復
  • 更新式: \text{social}_{\text{new}} = \max(0.0, \text{social} - 0.03 \times \Delta t \times \text{personality}_{\text{factor}})
スキルパラメータ

Weapon Strength(武器技能)

  • 機能: 戦闘・武器操作能力
  • 成長: 訓練場・武器庫での活動により向上
  • 減衰: 長期間の非実施で緩やかに減少

Management Skill(管理技能)

  • 機能: 指導力・リーダーシップ能力
  • 成長: 指揮本部での業務により向上
  • 育成要素: 初期値を低く設定し、長期的成長を促進

Sociability(社会性)

  • 機能: コミュニケーション能力・人間性
  • 成長: 社会的交流により向上(食堂、宿舎での活動)
  • 個人差: 性格特性(協調性・外向性)により上限値を決定
  • 軍事的意義: チームワーク、情報伝達効率、部隊士気に影響
# Sociability上限値計算
def calculate_sociability_cap(agreeableness: float, extroversion: float) -> float:
    personality_modifier = ((agreeableness + extroversion) / 2 - 0.5) * 0.3
    base_cap = 0.8  # 基本上限
    return min(1.0, base_cap * (1 + personality_modifier))

収穫逓減効果の実装

現実的な学習曲線を再現するため、スキル向上に収穫逓減効果を適用しています。

def apply_effect_with_diminishing_returns(self, attribute: str, effect: float, cap: float = 1.0) -> None:
    current = getattr(self, attribute)
    
    if effect > 0:
        # 上限に近づくほど効果が減少
        distance_to_cap = cap - current
        diminish_factor = distance_to_cap / cap
        random_factor = random.uniform(0.8, 1.2)  # 個人差
        new_value = current + (effect * diminish_factor * random_factor)
    else:
        # 負の効果は現在値に比例
        diminish_factor = current / cap
        random_factor = random.uniform(0.8, 1.2)
        new_value = current + (effect * diminish_factor * random_factor)
    
    setattr(self, attribute, max(0.0, min(cap, new_value)))

この設計により、エージェント毎に異なる成長パターンが現れ、長期的な育成要素を楽しめるシミュレーションを実現しています。

POI(Point of Interest)システム

軍事基地の5つの施設を実装しました。各施設の役割と効果は以下の通りです。

各施設の詳細

1. 訓練場(Training Ground)

  • 目的: 兵士の武器技能向上と戦闘訓練
  • 効果: 武器技能向上、体力消耗、軽度の空腹増加
  • 活動: 射撃練習、格闘訓練、戦術演習

2. 食堂(Mess Hall)

  • 目的: 食事摂取による基本的生理欲求の満足
  • 効果: 空腹度大幅減少、エネルギー回復、社会的交流
  • 活動: 食事、同僚との会話、栄養補給

3. 宿舎(Barracks)

  • 目的: 休息と睡眠による体力回復
  • 効果: エネルギー大幅回復、社会的交流
  • 活動: 睡眠、休憩、同僚との懇親

4. 指揮本部(Command Center)

  • 目的: 管理業務と戦略立案による指揮能力向上
  • 効果: 管理技能向上、軽度の体力消耗、社会的交流
  • 活動: 作戦計画、部隊管理、報告書作成

5. 武器庫(Armory)

  • 目的: 武器整備と装備管理による技能向上
  • 効果: 武器技能向上、軽度の体力消耗
  • 活動: 武器点検、装備整備、メンテナンス作業
MILITARY_POIS = {
    "training_ground": {
        "name": "Training Ground",
        "location": [100, 200],
        "effects": {
            "weapon_strength": +0.15,
            "energy": -0.10,
            "hunger": +0.05
        },
        "activity_type": "train"
    },
    "mess_hall": {
        "name": "Mess Hall", 
        "location": [50, 150],
        "effects": {
            "hunger": -0.8,
            "energy": +0.1,
            "social": +0.05
        },
        "activity_type": "eat"
    },
    "barracks": {
        "name": "Barracks",
        "location": [0, 100],
        "effects": {
            "energy": +0.6,
            "social": +0.1
        },
        "activity_type": "rest"
    },
    "command_center": {
        "name": "Command Center",
        "location": [150, 100],
        "effects": {
            "management_skill": +0.12,
            "energy": -0.05,
            "social": +0.08
        },
        "activity_type": "manage"
    },
    "armory": {
        "name": "Armory",
        "location": [200, 50],
        "effects": {
            "weapon_strength": +0.08,
            "energy": -0.03
        },
        "activity_type": "arm"
    }
}

実装上の設計考慮点

各施設は異なる需要充足パターンを持つよう設計しています。

  • エネルギー回復: 宿舎(+0.6)> 食堂(+0.1)> 指揮本部(-0.05)> 武器庫(-0.03)> 訓練場(-0.10)
  • 空腹度対応: 食堂(-0.8)が圧倒的に効果的、訓練場(+0.05)は空腹を増進
  • 技能成長: 訓練場(武器+0.15)、指揮本部(管理+0.12)、武器庫(武器+0.08)の3つで専門性分化
  • 社会的交流: 指揮本部(+0.08)> 食堂・宿舎(+0.05, +0.1)で自然な交流機会を提供

この設計により、兵士エージェントは生理的需要(エネルギー・空腹)、成長欲求(技能向上)、社会的需要のバランスを取りながら行動選択を行います。

処理フロー

システム全体の処理フロー

以下のMermaid図は、soldier_simの全体的な処理フローを示しています。日次ループとエージェント処理の主要な流れを分かりやすく表現しています。

メイン処理ループ

システムの核心となる処理ループは以下のように実装しています。

def run_simulation():
    for day in range(simulation_days):
        # 1. 日次反射メモリ更新
        update_reflective_memory(day)
        
        for step in range(time_steps_per_day):
            # 2. 全エージェントの需要更新
            for agent in agents:
                agent.update_needs(time_delta=1.0)
            
            # 3. 行動計画と実行
            for agent in agents:
                # LLMまたはルールベースでの行動計画
                action = planner.plan_action(
                    agent_state=agent.to_dict(),
                    reflective_memory=memory.get_reflective_memory(agent.id),
                    poi_list=[poi.to_dict() for poi in pois]
                )
                
                # 行動実行とPOI効果適用
                execute_action(agent, action)
                apply_poi_effects(agent, action)
                
                # カルマンフィルタによる信念更新
                update_poi_beliefs(agent, action)
                
                # メモリ記録(高性能バッファリング)
                memory.record_action(agent, current_time, poi, action)
            
            # 4. 時間進行
            advance_time()
        
        # 5. 日次サマリー生成
        generate_daily_summaries(day)
    
    # 6. 最終データ出力
    save_simulation_results()

シミュレーション

今回は比較のために同じ条件でルールベースでのシミュレーションと、LLM Agentベースでのシミュレーションを比較します。

前提条件

  • エージェント数:10

  • 期間:7日(POIの選択は3時間毎に行う。1日に8回選択。)

  • POIの個数:20個

  • POIの種類:16種類
    具体的には、以下の16個が含まれる。

    • training
    • food
    • rest
    • sleep
    • office
    • armory
    • recreation
    • medical
    • fitness
    • library
    • workshop
    • communications
    • maintenance
    • outdoor
    • spiritual
    • logistics
  • エージェントの性格種類(Persona): 6種類
    シミュレーション内のエージェントに対して、固有の性格特性を持たせました。それぞれの性格特性をエージェント構築時に持たせるようにしています。具体的な性格種類と、シミュレーションにおける存在割合は以下の通りです。

    1. 武器専門家 (Weapon Specialist)(全体の25%)

      • 訓練場や武器庫を好む
      • 武器技能が1.5倍のスピードで成長
      • 管理能力は0.8倍に低下
      • 訓練場や武器庫に対する選好度が2.0~2.5倍と高い
      • 事務所などの管理施設には興味が薄い
    2. 天然リーダー (Natural Leader)(全体の15%)

      • 管理能力が1.6倍で成長
      • 社交性が1.3倍で成長
      • 事務所・兵站・通信センターを優先的に選択
      • 指導力と管理スキルが急速に向上
      • チーム運営や戦略策定に長けている
    3. 社交的 (Social Butterfly)(全体の15%)

      • 社交性が1.7倍で成長
      • 武器技能は0.9倍に低下
      • 娯楽施設・通信センター・食堂を好む
      • 人との交流を重視
      • チーム内のコミュニケーション促進に貢献
    4. 学者 (Scholar)(全体の15%)

      • 管理能力が1.4倍で成長
      • 武器技能は0.8倍、体力は0.7倍と低め
      • 図書館や事務所を非常に好む
      • 屋外活動には消極的
      • 知識獲得と分析に長けている
    5. フィットネス愛好家 (Fitness Enthusiast)(全体の20%)

      • 武器技能が1.3倍、体力が1.6倍で成長
      • 体力トレーニング施設・屋外活動・訓練場を好む
      • 常に活動的で休息を嫌う
      • 管理業務には興味が薄い
    6. 内向的 (Introvert)(全体の10%)

      • 武器技能が1.1倍
      • 社交性は0.7倍と低い
      • 休憩所・図書館・睡眠施設を優先的に選択
      • 人との交流を避ける
      • 静かな環境での個人作業を好む

ルールベースの詳細

今回比較するルールベースで使用した行動選択ルールは以下の通りです。

  1. アクティブイベント最優先
    怪我・病気・特別任務などのイベントが発生している場合は、そのイベントに強制的に従う行動(例:医務室へ行く)が最優先されます。

  2. 時間ベースのルール
    夜間(22:00-05:00)は睡眠を最優先
    食事時間(12:00, 18:00)は食事を優先
    早朝(06:00-08:00)は訓練を優先

  3. 需要ベースのルール
    空腹度が高い場合(>70%)は強制的に食事
    エネルギーが低い場合(<30%)は強制的に休憩や睡眠

  4. 性格(アーキタイプ)ベースの選好
    上記に該当しない場合、各エージェントの性格タイプごとに定義された「施設(POI)への好み」に基づき、時間帯ごとのボーナスやペナルティを加味して最適な行動を選択します。

結果と分析

logから見るルールベースとLLMベースのシミュレーション結果の違い

ルールベース

{
    "agent_id": "agent_8",
    "action": {
        "poi_id": "barracks_1",
        "activity": "rest",
        "expected_duration": 1,
        "reason": "Critical energy level"
    }
}

LLMベース

{
    "agent_id": "agent_20",
    "action": {
        "poi_id": "training_ground_1",
        "activity": "train",
        "expected_duration": 2,
        "reason": "As a fitness enthusiast with high energy in the early morning, training at the Main Training Field fits his profile by modestly boosting weapon_strength and power with a manageable energy cost."
    }
},

これを見ると、LLMベースの方が

  • 自分の性格
  • 現在の状態

を踏まえて、POIを選択していることがわかります。

スキル分布

  • ルールベース:スキルの分散が広く、個体差が大きい。
  • LLMベース:特定スキル(例:Weapon Strength, Power)に極端なピークが見られ、最適化傾向が強い。

Skill Distribution

POIの使用回数(Heatmap)

  • ルールベース:睡眠・食事に集中し、他のPOIにもバランスよく分散。
  • LLMベース:training POIの訪問が突出して多く、スキル向上に強く集中。
    Heatmap for the number of using POI

スキルの伸び方

  • LLMベース:特にPowerの成長が急激。全体的に成長速度が高い。
  • ルールベース:比較的なだらかで自然な成長曲線。
    Skill Progress

1日あたりのPOI利用回数

  • ルールベース:library・office・recreationなど多様なカテゴリを活用。
  • LLMベース:training・foodなど目的達成に直結するPOIに集中。
    Average Visits per Agent per Day

エージェント10体のスキルを見て、比較

  • ルールベース:エージェント間のスキルにばらつきが見られ、万能型が多い。
  • LLMベース:特定スキルが極端に高く、役割特化型の傾向が見える。
    All Skills

考察

  1. スキル分布と成長トレンドから見える違い
    ルールベースを使うと、緩やかかつ多様性のある成長、LLMベースを使うと、目的に沿った最適化が進みやすく、効率的かつ偏りのある成長をする。
    総合的価値計算を行った後に最適行動を選択するため、エージェントの重み係数(Persona)次第で学習の最適化方向がガッツリ変わっちゃう。従来手法が潤沢にあって、既存手法に対してLLMの自由度や柔軟性を持ち込むのであれば良さそう?

  2. POIの訪問分布から見られる違い
    ルールベースを使うと、訪問先が分散していて、「人間の活動のリアルさ」という意味ではこちらの方が近いかも。LLMベースを使うと、training POIが最も多い。これは「スキルを伸ばす」という目的に対して、同じ行動を継続しているように見える。
    POI使用分布をみたときに、LLMベースよりもルールベースの方が人間っぽいと思ってしまったので、人間は価値基準や目的意識を持って行動しているのではなく、ルーティン的な動きをすることが多いのかも。

まとめ

LLMを使うことで目的に対して最適化できるシミュレーションを作成することができました。
多様性という観点ではルールベースの方が優れていたので、一定の割合でルールベース行動させることで、より柔軟なシミュレーションをできる可能性があると感じました。

他にどんなゲームを作れそうか

CitySimの考え方を応用することで、以下のゲームの開発もできる考えています。

  1. 学園経営シミュレーション

    • エージェント(生徒)が人格・記憶・目標を持ち、スキル成長。
    • POI:教室、部活動、図書館、食堂
  2. 企業内人材開発ゲーム

    • エージェントが配属・異動・評価を通じてスキル獲得。
    • POI:部署、プロジェクト
  3. 異星移住コロニー運営

    • 限られた資源・環境下でエージェントが自己最適化しながら役割分担。
    • POI:発電施設、居住区、装備庫
  4. 災害対応シミュレーション

    • 役割(救助・医療・情報)に応じたスキル発展と協働。
    • POI:避難所、医療テント、被災現場
Finatext Tech Blog

Discussion