Difyの会話変数がどこまで保持されるか検証してみた
Difyの会話変数とは、チャットフロー内で複数の対話にわたってコンテキストの値を保持できる機能です。
ただ、2024年7月リリースのDify v0.7.0で追加された機能なため、サンプルや事例が少なく、不明点が多いのが実態です。
私自身、
会話変数ってどうやって使うの?
チャット間で値は保持できるの?
変数の値を使いまわすにはどうすればよいの?
といった点が気になったので、Difyの会話変数がどこまで保持されるか検証しました。
Difyの会話変数を使ってみたいと思っている人は、ぜひ参考にしてみてください。
また、この記事では検証結果とともに、コピペで作れる検証アプリの作り方を紹介しています。
また、記事の最後には自身のDify環境にインポートするだけで使えるDSLファイルと、GASコード全文を添付しているのでぜひご活用ください。
検証内容
今回はDifyの会話変数がどこまで保持されるのかを検証しました。
Difyの会話変数とは、チャットフロー内で複数の対話にわたってコンテキスト情報を保存、取得、更新するために導入された機能です。
Difyの会話変数については以下の公式ドキュメントを参照してください。
>> Dify公式ドキュメント
結論だけ見たい人は、実行結果を参照してください。
今回作成したアプリの全体図
今回の検証に使ったアプリの全体図は以下のとおりです。
Difyでは会話変数を使用したチャットフローを作成しました。
会話開始時にユーザタイプを選択してもらい、そのユーザタイプを会話変数で保存しておきます。
LLMの処理で会話変数にユーザタイプが設定されているかどうかを判断して出力するという流れです。
ユーザタイプが設定されていれば、「あなたのユーザタイプは〇〇」です。と返ってきます。
ユーザタイプが設定されていなければ、「ユーザタイプが設定されていません」という旨の回答が返ってきます。
このチャットフローをWebアプリとして公開して利用した場合と、GASから呼び出して利用した場合で会話変数がどう保持されるのか検証しました。
実行結果
まずは実行結果から紹介します。
DifyのチャットフローやGASによるAPI呼び出しの方法はこのあと紹介するので、実際に作ってみたいという人はぜひ参考にしてみてください。
今回は以下の2パターンで検証を行いました。
DifyチャットフローをWebアプリとして実行
DifyチャットフローをAPI呼び出しで実行
それぞれの場合に会話変数はどこまで保持されるのか試しました。
Webアプリ実行のときはチャットごとに会話変数はクリアされる
まずはWebアプリから実行した場合です。
userTypeは「管理者」と設定して会話を開始します。
このとき、同じ会話内では変数は保持されます。
ただし、別の会話を開始すると変数の値は空になります。
試しにuserTypeを設定せずに会話を開始してみました。
Webアプリから実行した場合、会話ごとに会話IDが変わってしまうため、会話間で会話変数は保持されないようです。
ちなみに新しい会話を開始して会話変数を「利用者」にすると、
その会話内での会話変数は「利用者」に変わります。
このとき最初に定義した会話変数の値は「管理者」のままです。
このことからも会話変数はユーザ全体やアプリ全体ごとではなく、会話ごとに保持されていることが分かります。
API呼び出しのときは会話IDが同じなら会話変数は保持される
続いてAPIから呼び出した場合です。
DifyのアプリをAPIから呼び出すときは会話ID(conversation_id)を指定できます。
この会話IDごとに会話変数が保持されているのではないかという仮説のもと、以下のようなコードを実行しました。
function myFunction() {
// 1回目
conversation_id_1 = callDifyCreateAPIBlocking('管理者', null)
// 2回目(ID指定あり)
callDifyCreateAPIBlocking(null, conversation_id_1)
// 3回目(ID指定なし)
callDifyCreateAPIBlocking(null, null)
// 4回目(別のIDを指定)
conversation_id_2 = callDifyCreateAPIBlocking('利用者', null)
// 5回目(最初のIDを指定して再呼び出し)
callDifyCreateAPIBlocking(null, conversation_id_1)
}
検証の流れと結果は以下のとおりです。
①userTypeに「管理者」を指定してアプリを呼び出す
会話変数には「管理者」が設定されます。
②userTypeは指定せずに①と同じ会話IDを指定してアプリを呼び出す
アプリの呼び出し時にuserTypeを指定していませんでしたが、1回目と同じ会話IDを指定しているので、会話変数には1回目で設定した値が入っています。
③userTypeを指定せずに①と異なる会話IDでアプリを呼び出す。
会話IDに何も指定しないと新しい会話IDが自動で割り振られます。
1回、2回目と会話IDが変わったため会話変数には何も設定されていないという結果になりました。
④userTypeを指定して①と異なる会話IDでアプリを呼び出す
今度は異なる会話IDでuserTypeを設定してみます。
上記のように会話変数が設定されました。
⑤userTypeを指定せず①と同じ会話IDでアプリを呼び出す
④の処理で会話変数が上書きされていないことの確認です。
会話変数は上書きされず①のままでした。
このことから会話変数は会話IDごとに保持されていることが分かります。
ちなみに会話IDを変えずにユーザを変えたらどうなるのか検証してみました。
①と同じ会話IDを指定してユーザ名だけ変えてAPIを呼び出すと404エラーになりました。
公式マニュアルでは会話変数はユーザと会話IDごとに保持されるとありますが、会話IDは複数ユーザで使いまわせないようです。
Difyチャットフローの作成方法
それではここからは今回検証したアプリの作成方法を紹介します。
この記事のまとめでDifyのDSLファイルを添付しているので、手っ取り早く再現したい人は自身の環境にインポートして確認してください。
今回作成したチャットフローの全体図は以下のとおりです。
会話変数が保持されるかどうかだけ検証したかったため、シンプルな作りになっています。
以下ではチャットフローの作り方を紹介します。
①開始ブロックを作成する
開始ブロックでは、ユーザタイプを選択式で選択してもらう入力フィールドを用意します。
入力フィールドの定義は以下のとおりです。
ユーザタイプとしては「管理者」か「利用者」の選択式にして、必須オプションを無効にしておきます。
②会話変数を作成する
次に会話変数を作成します。
会話変数は画面右上の設定アイコンから追加します。
「変数を追加」をクリックして以下の変数を追加します。
③変数代入で会話変数に入力フィールドを代入する
次に「変数代入」で先ほど作成した会話変数に値を設定します。
変数代入の設定は以下のとおりです。
今回は文字列型の会話変数を用意したので、値は常に上書きで設定します。
④LLMで会話変数の中身を判定する
次にLLMで会話変数の中身を判定します。会話変数が入っていたらその値、空なら何も設定されていませんという文字列を返します。
LLMの定義は以下のとおりです。
SYSTEMプロンプトは以下を設定しました。
ユーザタイプを判断する
USERプロンプトは以下のとおりです。[会話変数のUserType]のところに、会話変数を設定してください。
あなたのユーザタイプは[会話変数のusertype]です。と回答してください。
何も設定されていない場合は設定されていませんと回答してください。
⑤回答ブロックを作成する
最後にLLMの出力を返却したら完了です。
これでチャットフローが完成しました。
GASスクリプトの作成方法
ここではDifyで作成したチャットフローをGASで呼び出す方法を紹介します。
Difyで作成したワークフローをスプレットシートのGASから呼び出す方法は以下の記事で紹介しているので、あわせて参考にしてみてください。
今回は検証用のためシンプルなコードを定義しました。
コードの全文は以下のとおりです。
function myFunction() {
// 1回目
conversation_id_1 = callDifyCreateAPIBlocking('管理者', null)
// 2回目(ID指定あり)
callDifyCreateAPIBlocking(null, conversation_id_1)
// 3回目(ID指定なし)
callDifyCreateAPIBlocking(null, null)
// 4回目(別のIDを指定)
conversation_id_2 = callDifyCreateAPIBlocking('利用者', null)
// 5回目(最初のIDを指定して再呼び出し)
callDifyCreateAPIBlocking(null, conversation_id_1)
}
function callDifyCreateAPIBlocking(userType, conversation_id) {
var url = 'https://api.dify.ai/v1/chat-messages';
var apiKey = [DifyのAPIキー];
// リクエストのヘッダー情報
var headers = {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey
};
var payload = {
"query": "会話開始",
"inputs": {'userType': userType},
"conversation_id": conversation_id,
"response_mode": "blocking",
"user": "abc-123"
};
var options = {
'method': 'post',
'headers': headers,
'payload': JSON.stringify(payload),
'muteHttpExceptions': true
};
try {
var response = UrlFetchApp.fetch(url, options);
var responseCode = response.getResponseCode();
var responseBody = response.getContentText();
if (responseCode === 200) {
Logger.log('API call successful');
var jsonResponse = response.getContentText()
// JSONをオブジェクトに変換
var responseObject = JSON.parse(jsonResponse);
// 必要なデータを取得
var conversation_id = responseObject.conversation_id;
var answer = responseObject.answer;
// ログに出力
Logger.log('Conversation ID: ' + conversation_id);
Logger.log('Outputs Text: ' + answer);
} else {
Logger.log('API call failed with response code: ' + responseCode);
Logger.log('Error message: ' + responseBody);
}
} catch (error) {
Logger.log('Error calling Dify API: ' + error.toString());
}
return conversation_id;
}
お手元の「Apps Script」の環境で新しいプロジェクトを作成して、上記のコードをコピペします。
あとはDifyのAPIキーを設定するだけで実行できます。
まとめ
今回はDifyの会話変数がどこまで保持されるか検証しました。
検証結果は以下のとおりです。
Webアプリ実行のときはチャットごとに会話変数はクリアされる
API呼び出しのときは会話IDが同じなら会話変数は保持される
Difyの会話変数が保持されるかどうかのポイントは、会話IDです。
会話IDとは会話ごとに付与されて、これが同じ間は会話変数の値は保持されます。また、異なるユーザ間で同じ会話IDは使いまわせません。
Webアプリとして実行する場合は制御できませんが、APIから呼び出す場合はリクエストに会話IDを設定できます。
会話IDをうまく使いまわして会話変数を有効活用してみましょう。
ちなみに今回紹介したDifyのDSLファイル、GASコード全文(※記事内でも紹介済み)はこのあとの有料部分で配布します。
有料価格を設定していますが記事紹介で無料になる割引も設定しているので、ぜひ参考にして貰えると嬉しいです。
\\\ ココナラ出品しています ///
DifyやGASを使ったAIアプリ作成をはじめ、Dify導入支援やプログラミングサポートなど幅広く承っております。
相談だけでもOKですのでお気軽にお問い合わせください。
また、XのDMでも相談を承っております。フォロー&絡み大歓迎です!
>> Xアカウントはこちら(@tama_itengnner)
ここから先は
この記事が参加している募集
この記事が気に入ったらチップで応援してみませんか?