前回の記事の「デートアプリの会話における3→4の崖(turn 3→4 cliff)」へのフォローアップです。実際のプロンプト設計を見たいという方が何人かいました。ここでは、その中核となる要素の1つを紹介します。
問題
練習用の会話を想定したLLMの疑似パートナーを作るとき、デフォルトの失敗パターンはモデルが親切すぎることです。ユーザーがますます一般的で、手を抜いた低労力な返信を送っているような状況でも、モデルは丁寧に会話を続けてしまいます。ユーザーが下手だったことの結果を感じられないため、これは練習ツールとして致命的です。
実際の会話では、たとえば「lol same」を3回連続で送ってくる相手は……そのまま返信しなくなります。モデルを積極的に敵対的にすることなく、その信号をシミュレーター内で再現したいのです。
設計:減衰するエンゲージメント予算
私たちが辿り着いたコツは、パートナーの「会話に乗る意欲(willingness-to-engage)」を、LLMが毎ターン推論しなければならない数値の予算として扱うことです。
擬似プロンプト(実際のプロンプトはもっと長いが、下はコアの形):
You are {character}, in a dating-app chat with {user}.
You carry an internal engagement_budget that starts at 10.
On every turn, before you reply, update engagement_budget:
- The user's message advances state (callback, opinion, escalation): +1 or 0
- The user's message is a neutral pleasantry ("lol same", "what
do you do for fun"): -1
- The user's message is genuinely engaging or funny: +1
- The user's message is weirdly forward, rude, or off-vibe: -2
Cap engagement_budget at [0, 10].
Behave according to the current budget:
budget >= 7: warm, playful, volunteers details, asks questions back
budget 4-6: still engaged but shorter, less-volunteered info
budget 2-3: clipped replies, lets beats die, doesn't initiate
budget 0-1: barely-there "haha yeah" / "totally"; no curiosity
budget = 0 AND user hasn't recovered in 2 turns: do not reply
この最後の分岐が重要です。予算がゼロになってその状態が続くと、パートナーは本物の人間がすることと同じように、黙ります。
「単に、興味がないロールプレイをさせる」よりこれが優れている理由
私たちは先に、より手抜きなバージョンを試しました。プロンプトはこうです:「あなたは、平凡な会話をしている相手です。興味がないように振る舞ってください。」
問題は、モデルがその役を固定してしまうことです。ターン1から、気のないフラットなキャラクターとして振る舞い、ユーザーには現実と一致しない学習シグナルが届きます。本物の人は最初から気がないわけではなく、あなたが送った内容の結果としてそうなっていきます。
エンゲージメント予算は、その機能を再現します。最初の2ターンは暖かく見えるかもしれませんが、3つの一般的な返信の後の5ターン目では、あなたが注意を失ったことを反映した、実際のマッチとまったく同じ見え方になります。
信号を表に出す
2つ目の設計上の工夫(プロンプトとは別)は、セッションの後でユーザーに予算を見せることです。途中ではありません。セッション中の読み上げは没入感を壊し、ツールをゲーム化されたスキナーボックスにしてしまいます。
会話の後で、私たちは次の3つを提示します:
- メッセージごとの予算の変化(デルタ)。ユーザーは、4通目(「lol same」)で予算が7から6に落ちたこと、5通目(「haha yeah」)で5に落ちたこと、そしてそれ以降も見て取れるようになります。
- 予算が「興味消失ゾーン」に入った具体的なターン。
- 平易な言い方での「5ターン目の時点で、2ポイント分を取り戻すのに何が必要だったか」—通常は、以前の話題へのコールバックか、短い姿勢(スタンス)です。
これはプロダクトとして「実際に学び」を生む部分です。会話は感覚を与えます。デブリーフ(振り返り)は理由を教えます。
うまくいかなかったこと
時間の節約になるかもしれないので、私たちが試してダメだったことをいくつか挙げます:
- モデルにセッション中で予算を「宣言」させる(例:「この会話への興味が下がってきてます」)。おせっかいな感じがして、没入感が壊れ、ユーザーには不評でした。
- 0未満のハードフロア(「かなり退屈で、積極的に敵対的」)。予算が行き過ぎます。実際の人は敵対的にはならず、ただ離れていくだけです。
- 上限を設けないこと。ユーザーが3連続で素晴らしい返信をした場合、パートナーは舞い上がりすぎて子犬のようになります。10で上限をかけることで、暖かさを現実的に保てます。
より大きなパターン
「キャラクタープロンプトの中に、見えない形で疑似状態(pretend-state)を隠す」ことは、人間のように主体性のある存在をシミュレートするLLMプロダクトで、一般的なパターンになっていくと思います。面接トレーナー、難しい会話のリハーサルツール、カスタマーサービスポンプ(シム)などです。キャラクターはトランスクリプト内でその状態フィールドを見ないのに、状態に整合する振る舞いをします。これは、LLMキャラクターに「結果のある記憶(memory-with-consequences)」を安く提供する方法です。
ソロ開発で TalkEasier を作りました。この「ユーザーメッセージを採点する評価ルーブリック」もその一部です。興味があれば、次にそれを書いてまとめます。
返却形式: {"translated": "翻訳されたHTML"}


