基礎知識
ドラマ作成者向けガイド - 基礎知識¶
このガイドでは、Marionetteでドラマを作成するための基礎知識を学びます。
ドラマとは¶
ドラマ は、Marionetteの会話シナリオです。
ドラマは、様々な Item をツリーのようにつなげることで、任意のシナリオを実現します。
ドラマのツリーは、AI発話を生成する度に一回呼ばれます 。シナリオ遷移ではなく、発話生成の度に上から下へ流れるように実行されます。
クライアント側からは、以下の順序で処理が呼ばれます:
- まず、ユーザーの発話や、ユーザーの状態をドラマに設定 (
dialog.add,state.set) - AI発話生成をトリガー (
event.trigger)
ドラマ側では、このトリガを受け取り、最終的にAI発話や音声 を返すことが基本動作です (event.response)
ItemとLink¶
graph TD
A[Item1<br/>Entry] --> B[Item2<br/>DialogAdd]
style A fill:#c8e6c9,stroke:#4caf50,color:#1b5e20
style B fill:#e1bee7,stroke:#9c27b0,color:#4a148c - Itemは、箱で表されている要素。音声合成やRAGなど、特定の処理を行います
- Linkは、Item同士の処理の順序を表します。その他にもいくつか機能を持っています:
- 前のItemの処理結果の情報を次のItemに伝えます (Value)
- 前のItemの処理が完了したかどうかを、次のItemに伝えます (is_last)
Entry¶
Entry は、ドラマの開始点となるItemです。外部からのイベント(event.trigger)を受け取り、ドラマの処理を開始します。すべてのドラマは、必ずEntryから始まります。
Group¶
Group は、複数のItemを組み合わせて再利用可能なコンポーネントとして扱う機能です。よく使う処理パターンをグループ化することで、ドラマの作成効率を向上できます。
Groupは画面上「タブ」として表現されています。「+」ボタンを押すことで追加可能です。
追加後は通常通りItemを追加していきますが、Group特有の特殊な概念も存在します:
- GroupInを追加。そこが処理の開始地点となり、Groupの前の処理の流れやデータを受け取る
- Group以降に出力したいデータや処理の流れがある場合は、GroupOutを追加し、そこにLinkをつなげる
重要
Groupでは、グループ専用の環境変数を設定できます。自由式の中で ${変数名} として参照すると、その値が展開されます。
同じGroupを複数の場所で使う際に、環境変数に異なる値を設定することで、同じ処理パターンを使いながら、それぞれ異なる挙動を実現できます。
使用例 : キャラクター発話用のGroupを作成し、環境変数 ${ai_name} を設定します。このGroupを2箇所で使用する際、一方では ai_name = "Tsuyoshi"、もう一方では ai_name = "Koichi" と設定することで、同じGroupを使いながら異なるキャラクターとして振る舞わせることができます。
DialogとStates¶
クライアントとサーバー側双方から参照と書き換えができる共通データベースとして、dialogとstatesが用意されています。
dialog: 会話履歴を保持します。ユーザーとアシスタントの会話だけでなく、システムメッセージなども含みます。states: なんでも保存できる変数です。任意の変数名を使えますし、ドットによる階層化も可能です。使用例:- ユーザー情報の保存:
user.nickname,user.age - 前回会話の要約:
conversation.summary - 会話進行管理:
greeting.done,start_timestamp
- ユーザー情報の保存:
これらは、内容が変化すると、サーバー・クライアント側にすぐに通知されます。
重要
Statesとは別に、そのツリーの中で前のItemから伝わってくる一時的な情報を扱うValueという概念存在します。Valueはクライアント側には伝わらない内部変数です。
Marionetteの中では、このDialog, States, Valueの3つを組み合わせながら、あらゆる処理を行います。
自由式¶
Marionetteでは、柔軟な処理を実現するために、自由に式を記入できる箇所が多く存在しています。
Jinja2¶
テキスト入力を柔軟に行うための書き方です。
Lambda式(短い処理向け)¶
Async関数(複雑な処理向け)¶
async def process(input_msg, output_msg):
history = await input_msg.dialog.get_recent(limit=10)
result = process_history(history)
await output_msg.update("result", result, is_last=True)
重要
詳細は、式の書き方ガイドを参照してください。
また、これらはいずれも一般的なプログラミング言語のため、ネット検索やChatGPT等で自分で記述することも可能です。