2. 人格・状況認識・記憶・応答生成

2.1 キャラクターは何で決まるか

キャラクター性はモデルの名前だけでは決まらない。主に以下を合成する。

情報 実装と内容 性質
基本人格 CharacterProfileAsset: mindPrompt、概要、価値観、口調、語尾、口癖、発話例、NG表現 運営が設定する恒常情報
世界観 背景、世界設定、知識範囲、世界観外への対応 InCharacter / TranslateToWorld / Deflect / Hybrid
視聴者との距離感 relationshipGuidelines、関係レベル、呼び方、共有体験 全体方針と個人別情報が別に存在
今の意志 CharacterExperienceConfig: goal / hesitation / decisionPrinciple 設定された目標・ためらい・判断軸をプロンプトへ
今いる場面 CharacterSceneContext キャラがいる場所・場面。実際のゲーム画面等とは別
感情とムード AffectiveState、EmotionState、HumanLikenessの気分 一時的な感情と持続状態
いまの番組 台本ノード、配信フェーズ、ASMR、コラボ、ゲーム観測 実行中の活動による制約
今回の返答方針 ResponseDirector、応答長、相手のコメント 1応答ごとの演出

CharacterPersonaComposer.ComposePersonaPrompt はmindPromptに人格ガイドと世界観を合成する。追加セクションは計4,000文字まで。設定が空ならその項目の指示も出ない。

LLMcontroller.PromptSettings.GetMindPrompt が共有の入口。ASMRの人格差し替えが有効なら、通常の人格・世界観を置き換えるモードと追記するモードがある。これはコード上で意図された別人格の切替であり、通常設定を直してもASMR発話が変わらない場合の確認点になる。

読み違えやすい点: voiceProfile はLLMに伝える「声・話し方の質感」の文章。TTSのprovider・話者ID・参照音声をそれ自体が保証する設定ではない。

2.2 通常コメントのプロンプト

主経路は LLMcontroller.MainPrompt.BuildPrompt。主要な順序は次のとおり。

  1. 人格と恒常安全ルール。
  2. キャラの意志、同じ相手との往復、話題候補の出力指示、台本意味記憶、自由会話、好みの根拠。
  3. 感情状態、複数キャラ、応答長、返答言語。
  4. 過去の返答・会話メモリ、応答例。
  5. 配信の空気、コメント欄の雰囲気、応答スタイル、任意の生活感。
  6. 感情タグの形式、多様性の指示、呼び方、ストーリーアセット、知識、予定。
  7. 台本の背景、固定したSituation、今回のコメント。
  8. 相手への呼びかけ、課金への感謝、許可された視聴者情報、禁止表現、ボイス記述。
  9. 配信フェーズ、ResponseDirectorまたは旧パターン、逆質問の文脈。
  10. 間、ASMR、コントローラー、TTSスタイル、人間らしさ、自問自答の指示。

台本がある場合も「最優先は今のコメントへの返答」と明記される。台本テーマを紹介して返事の代わりにするのを抑える実装がある。

独立した演出を無制限に足す構造でもない。ResponseDirector有効時は従来のThinkingStyle/CommentResponsePatternを抑え、短い返答では生活感を抑える。台本の寄り道・話題セッション・短文応答と衝突するときはTopicDriftを抑止する。

それでも多様性、短さ、共感、具体例、人格、台本、視聴者個別情報が同じ生成に載る。各指示をモデルがどの程度実行するかは、存在確認と別の評価対象である。

プロンプトの文字予算

LLMcontroller.Utilities.GetMaxPromptCharsBudget のコード値はGemmaLocal 12,000、OllamaLocal/Cloudflare 24,000、その他80,000文字。実際のモデルのコンテキスト容量の検証結果ではなく、アプリ側の文字数上限である。

MainPromptは人格/安全等の先頭と、出力指示/現在入力等の末尾を保護して中間を優先削減する。個々の記憶、Situation、人格追加分にも別の上限がある。情報を保存していても、プロンプト予算によってその回には見えないことがある。

2.3 ResponseDirectorが決めること

ResponseDirector は追加のLLMではなくC#の演出プランナー。主なモードはNormal / QuickQuip / Acknowledge / QuoteRiff / AskBack / DeepDive。

コード既定 読み方
履歴保持 8プラン 直近の演出の偏りを抑える
長文連続の閾値 2 長めの返答が続いたら短くする
AskBackの間隔 直近3応答 毎回問いかけることを抑える
感情アークの提案確率 0.4 毎回感情変化を義務づけない
話題セッション追加上限 3ターン 会話応答側の話題維持。自動発話の保証ではない
話題セッション開始確率 0.5 引用リフ/深掘り時などの条件付き
話題の最小コメント長 10文字 挨拶だけの入力からの展開を抑える

基礎重みは30/15/10/20/10/15。コメント複雑さ、履歴、質問受付状態等で選択が変わるため、このまま実配信での出現比率になるわけではない。

台本側が話題を所有するときは DirectResponseWithTopicOwnership(... scriptOwnsTopic) でResponseDirectorの話題継続を抑える。別の AudienceDetourState と同時に話題を主導しないための調停である。

2.4 応答の長さ

ResponseLengthPlanner が目標文字数と上限からレンジを作り、SpeechLengthLimiter が最終本文を制限する。コード既定は目標80文字、最大120文字。設定世代v2以降の maxResponseLength=0 は明示的な無制限として扱う。目標文字数の0は同じ意味ではなく、既定80文字へ補正される。

Immediate / Light / Deep / Defaultの倍率はそれぞれ目標の0.2–0.5 / 0.5–1.5 / 1.5–3.5 / 1–2。ただし上限に余裕を残す補正が入る。目標80・最大120の例ではレンジは概ね20–40 / 40–100 / 70–100 / 70–100文字になる。

したがって「DeepDiveがあるから長く掘れる」とは限らない。最大長が小さいとLightとDeepの出力上限は揃う。複数ターンで話を展開する仕組みと、1返答の文字数設定を分けて考える必要がある。

2.5 状況認識の正本

SituationModelsSituationContextServiceLLMcontroller.SituationContext が中心。

SituationFact はキー、カテゴリ、値、出典、観測時刻、期限、信頼度、優先度、公開範囲、信頼区分、事実種別を持つ。配信状態、台本位置、直近発話、質問、映像観測、ゲーム状態、コラボ、物語上の制約などを集め、生成開始時の SituationSnapshot に固定する。

Snapshotには配信epoch / broadcast run / script run / node execution / ownerを含む実行scopeがある。生成途中で配信・ノード・キャラの実行単位が変わった場合、旧生成の後着発話を抑止する。OperatorCueとGameEventはノードを意図的に動かし得るため、通常返答とはscope照合条件が異なる。

SituationPromptRenderer は以下の投影を行う。

限界: Snapshotが整っていても、外部世界の真実を証明するものではない。観測が古い/不正確な場合や、必要情報が投影から落ちる場合がある。また、すべての旧来情報がSnapshot一本に統合済みではなく、CSV、メモリ、予定、StoryAssets等は別途読み込む。

会話品質v2の現在地(未コミット変更を含む)

ConversationExperiencePolicyLLMcontroller.ConversationExperience に実装を確認した。

現時点の実装は、時系列改善計画 全体の完了を意味しない。例えば汎用の出来事台帳、全ゲームの試合ID/確定結果照合、一般返答の状況変化後の1回再生成は、ここで確認したコード範囲では完成を確認できない。

2.6 記憶は複数の仕組みに分かれている

記憶 主な実装 内容/寿命 主な用途・限界
直近会話・CSV履歴 UsercommentExtractorPreviousResponses Userresponse.csv、最近の全体会話、相手の履歴 会話の流れ。表示名ベースの旧形式も残る
視聴者別会話要約 ConversationMemoryManager 既定5往復、要約20件/人、500人、プロンプト用重要要約3件 古い会話を要約して残す。意味の完全保存ではない
個人データ LLMcontroller.UserData 好き嫌い、活動、目標等 抽出値と、今回LLMへ渡す範囲は別
長期関係 ViewerRelationshipManager 来訪、コメント、関係レベル、愛称、共有体験、関係メモ 距離感・再訪・呼び方。人間関係の総合的理解ではない
今日の参加 ViewerEngagementTracker 配信内コメント数、課金等 今日の初回/常連、感謝の重複抑制
台本の消費位置 ScriptTopicTurnPlannerScriptUtteranceContinuity topic/angle/lensの消費キー、発話継続情報 同じ計画の再利用防止。内容の意味そのものとは別
台本の意味 ScriptSemanticMemory接続partial 実可聴発話、要約。5発話やノード終了等で要約 既出の主張・具体例・結論を再利用しないための文脈
自由会話 FreeTalkConversationState 実発話6件×最大320文字、話題32件、質問状態 同一配信scope内の継続
キャラの体験 CharacterExperienceState 同一相手との直前往復、接し方の希望、次回への発言、観客由来の展開 下記参照
provider会話状態 GeminiSessionRequestScope、Responses/Assistants provider側session/chain/thread 呼び出し方式固有。ローカルの実可聴記憶と同一ではない

MemoryScope によるテナント/キャラ分離、原子的保存、削除tombstoneへの対応がある。全メモリが同じ保存先・同じ寿命・同じ更新タイミングを持つ単一DBではない。

キャラの体験の具体的な強さと限界

LLMcontroller.CharacterExperience が実可聴配送と結びつける。

「覚えているのに使わない」を説明する設定

CloudViewerPiiPromptPolicyConfigenablePromptInjection は既定false。履歴・他視聴者履歴などのカテゴリも既定falseである。

ViewerPiiPromptPolicy の予算既定はカテゴリ3件、1項目80文字、全体600文字。Situation投影・履歴・関係・tool出力等で共通の予算を消費する。

つまり「保存された記憶がある」「個別化機能がON」「今回の返答でLLMが参照できた」は同義ではない。新しい記憶システムを足す前に、この公開設定と診断の excluded / contextSurvivedBudget を見る価値がある。

2.7 知識とストーリー素材

CharacterKnowledgeManager は設定済みのinline情報やJSONを読み、キーワード索引を作って検索し、関連情報をプロンプトへ入れる。StoryAssetsSchedule は別の資料経路。

これらは、運営が与えた知識・エピソード素材・予定を使う仕組みとして評価すべきである。名前が「記憶」や「ストーリー」でも、現実に実行した出来事の証明とは限らない。埋め込み検索や外部の最新情報検索が全返答で自動実行されるとみなしてはいけない。

2.8 モデルと生成経路の差

LLMController.GenerateResponseInternal は一般HTTP経路、Assistants、Responsesに分岐する。通常経路は3回までの試行、1秒/2秒の待ち、条件付きfailoverを持つ。プロバイダーごとに本文形式・会話継続・画像対応が異なる。

LLMcontroller.Monologue.SendMonologueRequest は別の軽量生成経路。ローカル推論はローカルに残す分岐があり、Gemini系ではOpenAI軽量モデルを使う分岐、Claude単独キー向けの分岐もある。v2と対応する会話モデル等の条件を満たす場合、ホストの台本/自発発話に会話用モデルを使う。

このため、Adminで「通常会話のモデル」を変更しても、補助分類・要約・ゲスト生成まで一斉に同じモデルになるわけではない。一般経路のHumanLikeness後処理も専用経路の早期returnと同じ配線ではない。モデル比較では、実際に採用された経路とモデルを記録する必要がある。

2.9 自問自答演出と内部推論の区別

SelfReflectionDirector は「迷う→理由→決める」「見方を変える」「自分への軽いツッコミ」を、声または思考吹き出しに出す演出。追加LLMで内部推論を取得する機能ではない。

60秒間隔、直近8発話の予算、最大60文字、生成/配送予約を持つ。短文、混雑、挨拶、訂正、傾聴では抑える。設定された目標とためらいや、コメントの手掛かりがない回に無理に演出を足さない。

[selftalk] / [thought] は公開演出用の文章であり、conversationReasoningEffort はモデル要求パラメータ。両者を混同して「考え中吹き出しを増やせば会話推論が改善する」と評価しない。