これは、STMB の仕組みを高いレベルで説明する文書です。コードの説明をするものではありません。代わりに、この文書では STMB がどんな情報を組み立て、どの順番で送り、モデルに何を返してほしいのかを説明します。
この文書は、STMB 用のプロンプトを書いたり編集したりするときの助けとして使ってください。
STMB には、主に 3 つのワークフローがあります。
- メモリ生成
- サイドプロンプト
- 統合
これらは互いに関係していますが、期待される出力の種類は同じではありません。
- メモリ生成は厳密な JSON を期待します。
- サイドプロンプトは通常、整ったプレーンテキストを期待します(Markdown やその他のロアブックエントリ形式は使えますが、サイドプロンプトでは JSON を使わないでください)。
- 統合も厳密な JSON を期待しますが、メモリとは異なるスキーマです。
メモリを作成するとき、STMB は通常、次の部品をこの順番で含む 1 つの組み立て済みプロンプトを送ります。
-
選択したメモリプロンプトまたはプリセット文
- これはサマリープロンプトマネージャー内の指示ブロックです。
- どんな種類の要約を書くか、どんな JSON 形状で返すかをモデルに伝えます。
{{user}}や{{char}}のようなマクロは送信前に解決されます。
-
任意の前メモリのコンテキスト
- 実行時に前のメモリを含める設定なら、それらが読み取り専用コンテキストとして挿入されます。
- これはコンテキストであり、もう一度要約する対象ではないことが明確に示されます。
-
現在のシーンの会話記録
- 選択したチャット範囲が
Speaker: messageの形で 1 行ずつ整形されます。 - これが、モデルがメモリ化するべき実際のシーンです。
- 選択したチャット範囲が
かなり大まかな形:
[memory prompt / preset instructions]
=== PREVIOUS SCENE CONTEXT (DO NOT PROCESS) ===
[zero or more earlier memories]
=== END PREVIOUS SCENE CONTEXT - PROCESS ONLY THE SCENE BELOW ===
=== SCENE TRANSCRIPT ===
Alice: ...
Bob: ...
=== END SCENE ===
期待されるのは 1 つの JSON オブジェクトです。
{
"title": "Short scene title",
"content": "The actual memory text",
"keywords": ["keyword1", "keyword2", "keyword3"]
}ベストプラクティス:
- JSON オブジェクトだけを返す。
- キーは必ず
title、content、keywordsをそのまま使う。 keywordsは文字列の配列として正しい JSON 配列にする。- タイトルは短く、読みやすくする。
- キーワードは具体的で検索しやすいものにする: 場所、物、固有名詞、特徴的な行動、識別子。
STMB 側で多少乱れた出力を救済できることはありますが、プロンプトはそれに頼るべきではありません。
良いメモリプロンプトは、次の 4 つを明確に行います。
-
どんな種類のメモリを書くのかをモデルに伝える
- 詳細なシーンログ
- コンパクトなあらすじ
- 最小限の振り返り
- 文学的な語り口のメモリ
-
何が重要かを伝える
- ストーリービート
- 決定
- キャラクターの変化
- 明かされたこと
- 結果
- 継続性に関わる詳細
-
何を無視するかを伝える
- 通常は OOC
- つなぎの内容
- より引き締まったメモリにしたいなら、雰囲気だけの雑談
-
どんな JSON を返すべきかを正確に伝える
弱いプロンプトは、たいてい次のどれかで失敗します。
- 文体だけを説明していて、JSON の形を説明していない。
- 最終的なメモリオブジェクトではなく、「役に立つ分析」や「感想」を求めている。
- 具体的な検索語ではなく、抽象的なキーワードを勧めてしまっている。
- 以前のコンテキストと現在のシーンを区別していない。
- 出力形式を一度にたくさん要求しすぎている。
- 要約を網羅的にしたいのか、トークン効率重視にしたいのかを明示してください。
contentの中で Markdown を使いたいなら、その旨をはっきり書いてください。- 短いメモリがほしいなら、JSON スキーマではなく本文の長さを制約してください。
- 検索性を強くしたいなら、要約の文体だけでなくキーワードの質にプロンプトの余地を割いてください。
- 前のメモリは、書き直す元原稿ではなく継続性のためのコンテキストとして扱ってください。
サイドプロンプトはメモリではありません。これは、別のロアブックエントリを書いたり上書きしたりするためのトラッカー/更新プロンプトです。メモリとは考え方がかなり違います。ここはとても重要です。
サイドプロンプトが実行されると、STMB は通常、次の部品をこの順番で組み立てます。
-
サイドプロンプト本体の指示文
- そのトラッカーに対する実際のタスクプロンプトです。
{{user}}や{{char}}などの ST 標準マクロは解決されます。- 手動実行ではカスタムの実行時マクロも挿入できます。
-
任意の前回エントリ
- そのサイドプロンプトに保存済みの内容があれば、STMB は最初に現在の版を含めることがあります。
- これにより、毎回ゼロから書くのではなく既存トラッカーを更新できます。
-
任意の前メモリのコンテキスト
- テンプレートが前のメモリを求めているなら、STMB はそれらを読み取り専用コンテキストとして挿入します。
-
コンパイル済みのシーンテキスト
- これは、そのトラッカーが反応するべき現在のシーン素材です。
-
任意の応答形式ガイダンス
- これはパーサー用のスキーマではありません。
- ほしい出力形式についての追加指示にすぎません。
かなり大まかな形:
[side prompt instructions]
=== PRIOR ENTRY ===
[existing tracker text, if any]
=== PREVIOUS SCENE CONTEXT (DO NOT PROCESS) ===
[optional previous memories]
=== END PREVIOUS SCENE CONTEXT ===
=== SCENE TEXT ===
[compiled scene text]
=== RESPONSE FORMAT ===
[optional format guidance]
STMB が期待しているのは、そのまま保存できるプレーンテキストです。
ここがメモリとの重要な違いです。
- サイドプロンプトは JSON を求めていません。
- STMB は通常、返ってきたテキストをそのまま保存します。
- サイドプロンプトで JSON を求めたとしても、その JSON はあなたのワークフローで必要なだけの「テキスト」です。
つまり、サイドプロンプト用のプロンプトは、パーサー向けのメモリ JSON ではなく、そのまま使える最終出力を目指すべきです。
良いサイドプロンプトは、狭く、安定していて、更新しやすいものです。
例:
- 重要度順の登場人物リストを維持する。
- 現在の関係状態を追跡する。
- 未解決のプロット上の糸口を追跡する。
{{char}}が現在{{user}}について何を信じているかを追跡する。
最も良いサイドプロンプトの書き方は、たいてい次のことをします。
-
仕事を明確に定義する
- 「登場人物トラッカーを維持する」
- 「現在の関係シートを更新する」
- 「未解決の糸口レポートを維持する」
-
更新・置換・追記のどれかを明示する
- 前回エントリの本文が含まれることがあるので、これは重要です。
-
出力レイアウトを定義する
- 見出し
- 箇条書き構造
- セクション
- 並び順のルール
-
含めないものを明示する
- 推測
- 重複項目
- 古い情報
- タスクそのものについての説明文
- 「全部を追跡して」のように広すぎる。
- 古いエントリを改訂するのか、書き直すのかを一度も言っていない。
- 最終的なトラッカーテキストではなく、思考過程や説明を求めている。
- 書式指定が曖昧で、時間とともにトラッカーが崩れていく。
- サイドプロンプトは要約プロンプトではなく、保守手順のように書いてください。
- モデルは最初に現在のトラッカーを見て、その後に新しいシーンを見るかもしれないと考えてください。
- 各トラッカーは 1 つの仕事に集中させてください。
- 応答形式フィールドを使って、レイアウト、セクション名、並び順を制御してください。
統合は、下位レベルの項目を上位レベルの要約にまとめる処理です。
例:
- メモリをアーク要約にまとめる
- アーク要約をチャプター要約にまとめる
- チャプター要約をブック要約にまとめる
統合が実行されると、STMB は通常、次の部品をこの順番で組み立てます。
-
選択した統合プロンプトまたはプリセット文
- これは、元の項目をどう圧縮するかをモデルに説明します。
- 返すべき JSON スキーマもここで定義します。
-
任意の前回の上位ティア要約
- そのティアの前回要約を引き継ぐ設定なら、まず正史コンテキストとして含められます。
- プロンプトは、それを書き直さないようにモデルへ指示します。
-
時系列順に並んだ選択済みの下位ティア項目
- 各ソース項目は識別子、タイトル、内容つきで含まれます。
- モデルはこの素材をグループ化し、圧縮し、上位ティア要約へ変換することを求められます。
かなり大まかな形:
[consolidation prompt / preset instructions]
=== PREVIOUS ARC/CHAPTER/BOOK (CANON - DO NOT REWRITE) ===
[optional previous higher-tier summary]
=== END PREVIOUS ... ===
=== MEMORIES / ARCS / CHAPTERS ===
=== memory 001 ===
Title: ...
Contents: ...
=== end memory 001 ===
=== memory 002 ===
Title: ...
Contents: ...
=== end memory 002 ===
...
=== END ... ===
STMB は、次の形をした JSON オブジェクトを期待します。
{
"summaries": [
{
"title": "Short higher-tier title",
"summary": "The consolidated recap text",
"keywords": ["keyword1", "keyword2"],
"member_ids": ["001", "002"]
}
],
"unassigned_items": [
{
"id": "003",
"reason": "Why this item was left out"
}
]
}重要な考え方:
- 統合は 1 つだけの要約を返すこともあれば、複数返すこともあります。
member_idsは、返された各要約にどのソース項目が属するかを STMB に伝えます。unassigned_itemsは、「この項目は今作った要約には入らない」とモデルが伝える方法です。
良い統合プロンプトは、次の 3 つをうまくやります。
-
圧縮先を定義する
- 1 つのアーク
- 1 つ以上のアーク
- コンパクトだが完全な振り返り
- 強く圧縮した振り返り
-
選別ロジックを定義する
- 時系列を保つ
- 継続性を保つ
- 関連項目をまとめる
- 無関係な項目は未割り当てのままにする
-
JSON 構造をとても明確に定義する
最も良い統合プロンプトは、何を保存すべきかもモデルに伝えます。
- 大きなビート
- 転換点
- 約束
- 結果
- 未解決の糸口
- 関係の変化
- 継続性にとって重要な引用や識別子
- 振り返りを求めているのに、ソース項目をどう束ねるかを一度も説明していない。
- はみ出し項目をどう扱うかをモデルに伝えていない。
member_idsを必須にしていない。- 統合 JSON オブジェクトではなく、自由形式の散文を求めている。
- 文体ばかり気にして、選別やグループ化の条件が薄い。
- 一貫した 1 つの振り返りがほしいのか、最小限の一貫した複数振り返りがほしいのかをモデルに伝えてください。
- 時系列を必須にしてください。
- 余り物を明示的に扱うよう要求してください。
- ここでもキーワードは具体的にしてください。上位ティア要約でも検索価値は必要です。
STMB 用に書くときは、ただ「AI に何を言ってほしいか」だけを考えないでください。
こう考えてください。
- STMB はシーンの前にどんなコンテキストを置くのか。
- 実際に分析される素材の単位は何か。
- この経路が期待しているのは厳密な JSON か、それとも最終的なプレーンテキストか。
- 後の検索に残るべき情報は何か。
- モデルは何を無視し、何を圧縮し、何を保存し、何を引き継ぐべきか。
この 5 つの問いにあなたのプロンプトが明確に答えていれば、STMB ではたいていうまく機能します。
-
「実際に AI に何が送られたのか見られますか?」 はい。組み立て済みプロンプトを確認したいなら、ターミナルやログ出力を見てください。
-
「プロンプトが弱くても、STMB が良い出力を強制してくれますか?」 あまりそうではありません。STMB が不正な JSON を多少救済できることはありますが、そもそも違うものを要求している曖昧なプロンプトまでは直せません。
-
「プロンプトを書き直すとき、最初に何を最適化すべきですか?」 まず返却形式を最適化してください。次に、どの詳細を残すべきかを最適化します。文体はその後です。