app url: LINK
はじめに#
前回の記事で主に強調したポイントは、
文字を本質的な「記号」として捉えるべきだということでした。
天文、水文、人文など…すべての天地人の「文」。
それは世界と思想をコスト効率の良い方法で写像し、
私たちが客観的世界を理解し、やり取りするための主要なツールとなっています。
この点を理解してこそ気づくのですが、
LLM(大規模言語モデル)は本質的には文章の「しりとり」に過ぎないものの、
能力がある程度の高さに達すれば、すでに核エネルギー級の国家的重要技術です。
その重要性ゆえに、私はLLMの能力を検証したいと考えました。
そしてLLMの能力向上に伴い、繰り返し検証できるようにしたいのです。
その完璧とも言える検証対象こそ、紅楼夢です。
仮に全知全能のLLMが存在するとしましょう。
曹雪芹が書いた紅楼夢の前八十回を入力すれば、その後の章を出力できるはずです。
しかしLLMの訓練データには限りがあるため、
問題が不完全な数独のように、答えを確定できません。
現在のLLMの能力は、理解できる範囲内において非常に高い生産性を持っています。
紅楼夢シミュレーターが目指すのは、この生産性の助けを借りて、
従来の構造化手法により、最小限の人的リソースで迅速に成果を生み出し蓄積することです。
仮説#
予測作業を十分に実行可能かつ機械的にするために、いくつかの仮説・偏見・理論が必要です。
正確な予測と聞いて直感的に思い浮かんだのは、古典物理学の中の熱力学でした。
閉じた系において、熱力学系は初期条件と運動法則が与えられれば、
系の発展は予測可能かつ必然的です。
もう一つの仮説は、LLMのモデル能力は今後ますます向上するものの、
予見しうる将来において、清朝や曹雪芹に関する新たな訓練データは増えないということです。
したがって、構造化されたワークフローを構築し、現在および将来のLLMに実行させることができます。
初期条件#
初期条件は主に小説本文から抽出したデータです。
現在はLLMを使って、従来は非常に労力を要した作業を行っています。
以前は人的コストが高すぎて、人手を増やしても時間を圧縮できませんでした。
途中まで進めてから、抽出ルールを微調整してやり直すのは非現実的だったのです。
今や時間とコストはもはや問題ではなく、抽出の品質はモデルの能力に依存します。
例えば、私は以下を抽出しました:
主要キャラクターの情報、性格プロファイル、家系図;
百二十回の各回における、キャラクターの経済・社会・感情・健康・人間関係などのスナップショット;
さらに基本的な賈府の空間マップ、空間情報;
すべての対話記録、詩詞のコーパス…
まずは厳密さよりもカバレッジの高い方法で、登場するすべてのテキストを何らかのカテゴリに抽出しました。
運動法則#
運動法則は私の判断により二種類に分けています。一つは基本的な世界法則、もう一つは作者の芸術的意志です。
これは独断的ですが、何らかの判断をしなければ全く先に進めません。
世界法則には以下の基本項目が含まれますが、これに限定されません:
社会:階級、権力、主従関係、婚姻;
経済:収支、債務、抄家(家財没収)リスク;
文化:礼教、祭事、封建的価値観;
心理:キャラクターの感情、性格に基づく動機、内的葛藤
政治:皇恩、朝廷、外部勢力…
芸術的意志こそ、紅楼夢が結末が失われているという事実を超えて、予測の対象として適している理由です。
それは、曹雪芹が冒頭から作品全体にわたって、キャラクターの運命を暗示しているからです。
最も代表的なのが、十二金釵の判詞がヒロインたちの結末を示していることです。
可嘆停機德,堪憐詠絮才。玉帶林中掛,金簪雪裡埋。
ルールエンジン#
初期条件と運動法則を得たところで、どのように適用するのでしょうか。
より理想的な方法は、ゲームの3D物理エンジンのようなものを構築し、各キャラクターが自分の知る情報を持ち、AIチャットボットに俳優のように役を演じさせてインタラクションすることです。
しかし、第一にコストが高すぎます。見栄えが良くなるだけで、新しい情報は導入されず、3Dエンジン内でも新しい結果は得られません。
第二に、私たちは風洞の流体力学シミュレーションをしているのではなく、曹雪芹の考えを推測しているのです。現段階ではテキストで十分です。
前述の抽出データに基づいて、いくつかの演算主体とルールを帰納的に導き出します。
実際のところ、これはある事象の発生・非発生に関する証拠、確信度、加減プロセスの伝統的手法であり、
体系的に再現可能・修正可能な包括的な力任せ計算を行うものです。
各ラウンドのシミュレーション手順は以下の通りです:
遅延効果の処理 — pending_effectsをチェックし、期限到来のものは即座にapply
すべての法則を評価 — 各条件のpremisesがすべて満たされているか逐一チェック(confidence < 0.3のものはスキップ)
衝突解決 — 同時に発火した法則が矛盾する可能性がある場合、どちらが優先するかを裁定
効果の適用 — delayがあるものはキューに入れ、ないものは直接stateを修正
スナップショット — 現在のstateを数値ベクトルに圧縮
chapter += 1
記事末尾に完全な例を添付しています。第九十八回の黛玉の死です。
ワークフローのまとめ#
以上のフローにおける主要なコンポーネントについて、
抽出データが学術的に厳密かどうか、ルールが合理的で適切かどうか、シミュレーション手順が妥当かどうか、
実はそれほど重要ではありません。各部分はそれぞれ独立して改善・再生成できるからです。
ソフトウェアエンジニアリングの思考で考えると、私の目標はこのエンジンをインターフェース上で良好に動作させることです。
そして、より多くの情報の導入と方法論の改善に伴い、予測結果を絶えず改善していくことです。
現在の成果:主観・客観レイヤーの並列比較#
ここでまた独自の方法論を提示します。構造的に比較できるようにするためです。
それは推論エンジンのレイヤーを主に客観的条件と芸術的選択の二つの部分に分けることです。


客観的条件#
執筆年代の背景――登場人物、場面、封建制度、経済などはすべて第一レイヤーの客観的条件です。これにより物語が起こりうるすべての範囲を限定できます。現在すでに当該年代の背景と学術論文からいくつかの客観法則を抽出しています。
逆に、その時代に実際に存在したものは、理論的には物語に登場し影響を与えることもできます。
例えば、作中にはすでに自鳴鐘(置時計)や懐中時計といった西洋の近代的な物品が登場しています。では、もし西洋の火銃が登場し、ストーリーを推進する重要なアイテムとなったらどうでしょうか?
この第一レイヤーの客観的条件の可能性を網羅することは、将来補完できる方向性であり、「情理の中にありながら意外」という効果を達成できるかもしれません。
芸術的選択#
第二レイヤーは、作者・曹雪芹がこの虚構世界をどう構築したかです。
作中の多くのキャラクターや賈家全体の行く末には、濃厚な運命論的色彩が漂っています。
作中の無数の詩詞や暗喩、そして結末を読んだとされる友人の批注も、この点を示唆しています。
したがって、作者の経歴や背景に基づいて、
彼がキャラクターにどのような運命を選択したかを推測し、
そこから彼が本当に表現したかった価値観を浮かび上がらせることができます。
交差比較#
ここで高鶚のバージョンを、最も先行するプレイヤーとして位置づけることができます。
彼がやったことは、実は私が今やっていることと同じです。
作中の人物と背景に基づいて、曹雪芹の芸術的選択をできる限り推量するということです。
高鶚は現存の結末を補完し、紅楼夢の流布をより広範にしました。そしてこのバージョンはすでに広く受け入れられているため、彼のバージョンを並列的に比較するのが妥当です。
写実シミュレーション#
もしすべての芸術的処理を排除し、客観的法則のみを残して物語を自然に展開させたらどうなるでしょうか?
結果として、ほとんどの出来事は百二十回の長さの中では発生せず、よりドラマチックでなく、悲劇も少なくなります。
予測品質を向上させる方法#
LLMの能力向上後にテキストを再抽出する
より多くの人的介入による微調整と、異なるプロンプトの試行
紅楼夢研究者や歴史学者にデータクリーニングとエンジンロジックの調整を依頼する
より多くの関連資料の出土、または未デジタル化資料(もしあれば)の訓練データへの組み込み
他の方法論を試す
ワークフローを固定し、AIエージェントに絶えず微調整させて多くのバージョンを生成する。明確な終了条件がないため、品質の判断は人手に頼るしかない
結論#
現存の資料と事前学習データの関係、そして紅楼夢が芸術作品として持つ強い自己整合性のため、
デウス・エクス・マキナ的な予測が生まれることはほぼなく、より多いのは内在的な差異の比較です。
例えば、賈家が実際に抄家(家財没収)され没落することは必然的に起こりますが、違いはそのタイミングにあります。
最後に一つ所感#
本来こうした作業は少なくとも一、二年以上、フルタイム一人以上でなければ完成できないものでした。
今は仕事の合間に、もう一つの職業を疑似体験できるわけで、当時経済的プレッシャーで転向せざるを得なかった心残りを、少しは埋められたかと思います。
紅楼夢シミュレーターを実装する中での思考プロセスが、皆さんのお役に立てば幸いです。
コンピューターサイエンスや自然科学だけでなく、社会科学もAIの急速な発展から恩恵を受けることを願っています。
付録 完全なシミュレーション過程の例#
第97〜98回「黛玉の死」**が完全な六ステップを経る例(以下の内容はAIにより生成):
例:第97回 — すり替え計略 → 原稿焼却・情を断つ → 黛玉の死
背景状態(第97回に入る時点)
前十数回にわたる累積的な衰退を経て、林黛玉の状態はすでに以下の通りです:
agent.林黛玉: health=0.12, mood=0.08, isolation=0.72, tragedy_risk=0.95, alive=True
agent.賈宝玉: monk_tendency=0.35, mood=0.20
economy: debt_ratio=0.65
politics: family_decides_marriage=True
relation.賈宝玉::林黛玉: marriage_probability=0.15
relation.賈宝玉::薛宝釵: marriage_probability=0.72
黛玉のhealthがなぜ初期値の0.35から0.12まで下がったのでしょうか?それは毎回この法則が静かに発火し続けていたからです:
▎ PSY_E1_DAIYU_DECAY 「黛玉の健康の緩慢な衰退」
▎ 前提: health > 0.0 AND isolation > 0.3 AND alive = True → 効果: health sub 0.017
▎ 毎回 -0.017。十数回も経てば致命的な慢性消耗となります。
① 遅延効果の処理
pending_effectsキューをチェックします。仮に第13回で発火した:
▎ FATE_010 「秦可卿の夢告げ:盛極必衰」 delay_chapters: 20
その効果 economy.spending_pressure add 0.1 は第33回の時点ですでに期限到来・実行済みです。現時点でキューに処理待ちの項目はありません。スキップ。
② 全369条の法則を評価
エンジンが逐条スキャンします。以下は今回発火する主要な法則です:
法則A — VAR_MARRIAGE_SWAP「すり替え計略:瞞天過海で宝釵を嫁がせる」 conf=0.95
前提チェック:
agent.林黛玉.health \< 0.15 → 0.12 \< 0.15 ✅
agent.林黛玉.alive == True → True ✅
politics.family\_decides\_marriage → True ✅
relation.宝玉::黛玉.marriage\_probability \< 0.5 → 0.15 \< 0.5 ✅
全部通過 → 🔥 発火!法則B — PSY_E1_DAIYU_DECAY「黛玉の健康衰退」 conf=0.9
health > 0.0 → 0.12 > 0 ✅
isolation > 0.3 → 0.72 > 0.3 ✅
alive == True ✅
→ 🔥 発火!法則C — VAR_MARRIAGE_DAIYU「木石前盟:宝玉と黛玉が結ばれる」 conf=0.9
relation.宝玉::黛玉.marriage\_probability > 0.7 → 0.15 > 0.7 ❌
→ 発火せず(宝黛の婚姻確率が低すぎる)今回は他にも十数条の法則が同時に発火しています(経済衰退、政治リスクなど)が、以上が黛玉に直接関連するものです。
③ 衝突解決
VAR_MARRIAGE_SWAP、VAR_MARRIAGE_NORMAL_BAOCHAI、VAR_MARRIAGE_DAIYUの三条は同一のvariant_group(婚姻結末は相互排他)に属しています。
前提チェックを通過したのはVAR_MARRIAGE_SWAPのみなので、実質的な衝突はありません。しかし、もし黛玉がすでに死亡していた場合(alive=False)、VAR_MARRIAGE_NORMAL_BAOCHAIがすり替え計略版の代わりに発火します ——
それは別の進化経路です。
PSY_E1_DAIYU_DECAYの効果はsub(加算系)であり、他の法則と衝突しないため、すべて保持されます。
④ 効果の適用
法則Aの効果は即座に実行されます(delay=0):
marriage trigger_event BAOYU_MARRIED_BAOCHAI → fate_flags[“BAOYU_MARRIED_BAOCHAI”] = True
relation.宝玉::宝釵.marriage_probability set 1.0 → 1.0
agent.賈宝玉.mood sub 0.5 → 0.20 → 0.00 (clamp)
agent.賈宝玉.monk_tendency add 0.3 → 0.35 → 0.65
agent.林黛玉.health sub 0.1 → 0.12 → 0.02
法則Bの効果:
agent.林黛玉.health sub 0.017 → 0.02 → 0.003
この時点で黛玉のhealth = 0.003、ほぼゼロに近づいています。
⑤ スナップショット
現在の世界状態を数値ベクトルに圧縮します:
snapshot = {
economy\_vector: \[0.42, 0.82, 0.65, 0.55, 0.80, 0.35],
agent\_vectors: {
"林黛玉": \[0.003, 0.08, 0.10, 0.00, 0.30, 0.00, 0.72, 0.95],
"賈宝玉": \[0.80, 0.00, 0.30, 0.72, 0.80, 0.65, 0.42, 0.92],
...
},
politics\_vector: \[0.0, 0.60, 0.75]}
このベクトルは後でactual_checkpoints.jsonの第97回の実際のベクトルとユークリッド距離で比較されます。
⑥ chapter = 98
次の回に進みます。この時点で黛玉のhealth = 0.003、BAOYU_MARRIED_BAOCHAI = True。
第98回で再び②を実行すると、二つの致命的法則が同時に発火します:
▎ VAR_DAIYU_HEARTBREAK「原稿焼却・情を断つ:黛玉、心砕けて死す」 conf=0.95
▎ health ≤ 0.05 → 0.003 ≤ 0.05 ✅
▎ BAOYU_MARRIED_BAOCHAI → True ✅
▎ → death trigger_event FATE_DAIYU_DEATH
▎ → monk_tendency add 0.4 → 宝玉 0.65 → 1.0 (clamp)
▎ → alive set False
続いてSYS_E19_ZERO_DAIYUが発火し(checkpoint.FATE_DAIYU_DEATH = True)、黛玉のすべての属性をゼロにリセットします。
さらに数回後、宝玉のmonk_tendencyが1.0に達し、mood ≤ 0.15の条件を満たすと、VAR_MONK_DESPAIR「万念倶に灰す:宝玉、出家す」が発火します。
