kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

Autocodeでセッションを実装してカウンターを作ってみた

Autocodeでセッションを実装してカウンターを作ってみました。

// authenticates you with the API standard library
// type `await lib.` to display API autocomplete
const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});
const cookie = require('cookie');
const { randomUUID } = require('crypto');

const appName = "session_sample";

function gen_sess_id(){
  return randomUUID().split('-').join("");
}

let sess_id;
if (context.http.headers.hasOwnProperty('cookie')){
  let cookies = cookie.parse(context.http.headers.cookie);
  sess_id = cookies.ACSESSID;
} else {
  sess_id = gen_sess_id();
}

let counter = 0;

let sess_data = await lib.utils.kv['@0.1.16'].get({
  key: `${appName}_${sess_id}`
});

if(sess_data){
  counter = sess_data.counter;
}

counter++;

await lib.utils.kv['@0.1.16'].set({
  key: `${appName}_${sess_id}`,
  value: {
    counter: counter
  },
  ttl: 60
});

const body = {
  "sess_id": sess_id,
  "counter": counter
};

return {
  headers: {
    'Content-Type': 'application/json',
    'Set-Cookie': cookie.serialize('ACSESSID', sess_id)
  },
  statusCode: 200,
  body: Buffer.from(JSON.stringify(body))
};

Autocodeのkey-value storeのドキュメントによると、

Because storage is tied to your user account rather than to a specific token or app, you should be wary of conflicts around two different apps relying on the same key for storage. For more examples, check out the API documentation page.

らしいので、キーは、アプリ名とセッションIDを組み合わせています。あと、

You can store a maximum of 1024 key-value pairs at a time. Keys may be up to 1kb in size, and values may be up to 18kb.

あたりもあるので、AirtableなりPostgreSQLなりを使うほうが良さそうな気がします。

Autocodeことはじめで、カウンターを作ってみた

以下で紹介されていたローコードプラットフォーム「Autocode」、Voiceflow Dialog Management APIの実行環境として使えるんではないか?ということで、ちょっと試してみた。

目次

まずは触ってみる

上記サイトで紹介されているのをまず一通りやってみた所感としては、

  • いろいろなサービスとの連携がライブラリ化されている実行環境がセットになってるリッチなIDE、という感じ
  • サンプルにもあるDiscordとの連携を試してみた感じ、コード補完が使いやすく、パラメータもGUIで設定できたり、と各サービスのAPIドキュメントを見なくても簡単にかける

ということで、Voiceflow Dialog Management APIを、Autocodeで予め連携が用意されているものとつなげるならば、とても楽にかける気がします。

ただ、Discordも個人的にはあんまり使ってないし、まずは以下で作ったWebサイトチャットボットの普通のバックエンドAPIとして使いたい。

kun432.hatenablog.com

この場合、

  • マルチターンな会話の場合には、cookieを使ったセッション処理が必要になる
  • CORSに対応させる必要になる

というところで、Webサーバ部分の処理をある程度書かないといけないのだけど、このあたりはAutocodeではあまり気にしなくて良さそうな部分っぽくて、ドキュメント見ててもあまりピンとこない。

そこで、いろいろ調べつつまずはよくあるカウンターを書いてみました。

// authenticates you with the API standard library
// type `await lib.` to display API autocomplete
const lib = require('lib')({token: process.env.STDLIB_SECRET_TOKEN});
const cookie = require('cookie');

console.log(JSON.stringify(context.http.headers, null, 2));

let counter = 1;
if (context.http.headers.hasOwnProperty('cookie')){
  let cookies = cookie.parse(context.http.headers.cookie);
  counter = cookies.hasOwnProperty('counter') ? Number(cookies.counter) + 1 : 1;
}

const body = {
  "counter": counter
};

return {
  headers: {
    'Content-Type': 'application/json',
    'Set-Cookie': cookie.serialize('counter', counter)
  },
  statusCode: 200,
  body: Buffer.from(JSON.stringify(body))
};

expressの場合、cookieやセッション周りの処理はexpress-sessionあたりを使えば色々隠蔽されてシンプルに書けるのだけど、Autocodeだと

  • cookieを渡す場合はカスタムレスポンスを使って自分でset-cookieしないといけなさそう。
  • cookieを取り出す場合、リクエストはcontextに全て入っているので、cookieを取り出して、自分でパースしないといけなさそう。

ということで、上記のような感じに。なんていうか、expressにはだいぶ甘やかされてるんだなという気がしたw

単にクライアント側のcookie使ってやり取りしてるだけでサーバーサイドでセッション管理とか何もやってないし、CORSあたりも考えないといけないので、先は長い・・・

参考

HTTPリクエストの取り出し方

docs.autocode.com

カスタムなHTTPレスポンスを返す

docs.autocode.com

npmパッケージも使える

docs.autocode.com

今回はクライアントcookieしか使ってないけど、セッションやるなら多分このへん。アプリ単位じゃなくてアカウント単位ってところはちょっと気をつけないといけないかも。PostgreSQL/Airtable/Google Sheetsあたりを使ってもいいかもしれない。

docs.autocode.com

Voiceflowのユーザーペルソナを試してみる

ひさびさのVoiceflowの新機能のご紹介です。

会話フローのテストを行う場合、ユーザの状態にあわせてテストを行いたいことがあります。

  • 初めての利用なのか?何度も利用しているユーザなのか?
  • スキルがユーザの名前を知っているのか?知らないのか?

このように何らかの「パーソナライズ」を組み込んでいる場合はその条件に合わせてテストを行いたいですよね。そこで新しく追加されたのが「ユーザーペルソナ」です。

目次

サンプルスキル

以下のようなサンプルを用意しました。プロジェクトは「Chat Assitant」タイプです。

https://raw.githubusercontent.com/kun432/voiceflow-samples/main/user-persona/sample-user-persona.vf

※右クリックでダウンロードしてインポートしてください。

以前お伝えしたとおり、Voiceflowのテストツールは、残念ながらAlexa・Google向けプロジェクトでは使用できませんのでご注意ください。

実際には全く使えないというわけではないですが、Alexa開発者コンソールやActions on Google上のテストツールを完全にシミュレートしているわけではないので、きちんとしたテストを行うにはそれぞれのプラットフォーム上のテストツールを使う方が良いということです。)

フローはこんな感じ。

ユーザから都道府県を聞いて天気を答えるというものです。実際には天気APIなどを使って天気予報の結果を取得することになりますが、今回はサンプルなのでランダムに回答するようにしています。ポイントは、

  • 初回利用と2回目以降で、チャットボットの応答が変わる。
    • 1回目は、名前と住んでいる都道府県を聞いて、永続的に記憶した上で、天気を答える。
    • 2回目以降は、永続的に記憶された名前と都道府県を使って、そのまま天気を答える。

というところで、少しパーソナライズ的な要素を入れています。1回目の会話フローはこんな感じです。

普通にテストを行うと、変数は何もない状態、つまり1回目の利用ということになるわけです。

ユーザーペルソナを使う

で、次は当然2回目以降のパターンを試してみたいですよね。テスト画面の左側を見てください。

ここにプロジェクトで使用している変数がすべて表示されています。

これを少しいじってみましょう。

sessionsがVoiceflowが予め持っているユーザの利用回数です。nameregionが今回のプロジェクトで作っているユーザの名前と住んでいる都道府県ですね。1回目の利用時に必要な情報はユーザからすでに取得済み、という想定ですね。

これで再度テストを実行してみるとこうなります。

1回目のテストとは異なり、すでにユーザからは必要な情報を取得済みですので、名前や都道府県を取得するためのやりとりが発生せずに応答を返していることがわかりますね。このようにしていろいろ想定される条件にあわせて変数を書き換えればよいわけですが、毎回毎回変更するのは面倒です。

これを一つのセットとして記憶しておけるのが「ユーザペルソナ」機能です。早速使ってみましょう。

変数が表示されている箇所の上にある「All project variables」をクリックします。

"Add new"をクリックします。

ユーザーペルソナを設定する画面が出てきましたので、設定していきましょう。まずは「初回ユーザ」から。

"Name"にユーザペルソナ名を入力します。"Starting Block"は、会話フローのどこからスタートするか、を選択することができます。通常は"Start"にしておいて最初から行えばよいでしょう。

次に「初回ユーザ」の場合の変数を設定します。今回のフローでは、sessions / name / region が永続的に保持され、初回 or 2回目以降で異なる箇所になりますので、これらにチェックを入れます。

それぞれの変数の入力欄が追加されますので、それぞれ値を入れます。Voiceflowでは自分で作成した変数の初期値は0になりますので、nameregionを0にセットします。予め用意されているsessionについては1が初期値になりますので、1をセットします。最後にSave Stateをクリックして保存します。

これで「初回ユーザ」のユーザーペルソナが作成されました。

同様にして、2回目以降のユーザーペルソナとして「継続ユーザ」を作成しましょう。こんな感じです。

これで2つのユーザーペルソナが作成されました。

以後は、ここでユーザーペルソナを切り替えてテストを行えば、それぞれの条件がセットされたテストが行えるというわけです。また、右側のテスト開始ボタンのところからも切り替えることができます。

プロトタイプ共有でユーザーペルソナを使う

さらに、作成したユーザーペルソナをプロトタイプ共有で使うこともできます。

"Share Prototype"をクリックして、"Variable State"でユーザーペルソナを選択して"Copy Link"をクリックします。

発行されたURLにアクセスすると、ユーザーペルソナに応じた変数が設定された状態で、対話フローが動作します。

まとめ

音声アプリを長く利用してもらうためにはパーソナライズはほぼ必須といってよいと思いますが、実際にやろうと思うと実は結構面倒です。今回のユーザーペルソナ機能を使って予めパターンを用意しておけば、いつでもかんたんに切り替えてテストができるのでとても便利ですね。ぜひご活用ください。

個人的な要望としては、Alexa向けプロジェクトでもこれができるとよいなぁと思ったりしてます・・・