ごった煮

色々な事を書いてます

複雑な受け答えをするBotを実装する

Botを使って注文を取るといった複雑な受け答えを実装する場合に便利な機構がBot Frameworkには提供されているのでそれの使い方についてです。

初めに

今回は、公式が出しているサンドウィッチの注文を受けるBotをベースに進めます。

FormFlow

以前は、Dialog Modelを使って簡単な受け答えをするBotを実装しましたが、今回は新しい概念としてFormFlowというものを使用します。

FormFlowを使用すると会話の状況でのヘルプや、以前の会話に戻る、会話の進行状況などの情報を簡単にユーザに提供可能になります。

FormFlowは、Dialog Modelと比べると会話の柔軟性は低くなりますが、その分注文や定型的なオペレーション用の会話を簡単に提供できるようになるのでうまく使いどころを分けるとよりそれっぽいBotが作れます。

実装してみる

FormFlowで実際に簡単な注文を聞くBotを実装してみます。

まず質問生成に使用するクラスです。

    public enum Burger
    {
        ハンバーガー, チーズバーガー, テリヤキバーガー, チキンバーガー
    };

public enum SideMenu
{
    ポテト, ナゲット, パイ
};

public enum Drink
{
    シェイク, コーヒー, ミルク
}

[Serializable]
public class SandwitchOrder
{
    public Burger? ハンバーガー;
    public List<sidemenu> サイドメニュー;
    public List<drink> ドリンク;

    public static IForm<sandwitchorder> BuildForm()
    {
        return new FormBuilder<sandwitchorder>().Message("ご注文をお願いします。").Build();
    }
}

質問の選択肢は、Enumの要素、質問されるものの名前(例えばhogeを選んでくださいのhoge)は、Enumの変数名になります。

C#は、日本語が扱えるので今回はわかりやすくするために日本語を使用します。

次にBotの本体にあたるコントローラクラスです。

    [BotAuthentication]
    public class MessagesController : ApiController
    {
        internal static IDialog MakeRootDialog()
        {
            return Chain.From(() => FormDialog.FromForm(SandwitchOrder.BuildForm));
        }

        public async Task Post([FromBody]Message message)
        {
            return await Conversation.SendAsync(message, MakeRootDialog);
        }
    }

実行結果

Bot Emulatorで実行してみます。

まず初めに適当に何かメッセージを投げると質問開始です。

image

image

Enumの変数をList形式で宣言しておくと、複数の要素をカンマ区切りで選択できます。

Backと入力すると、前の質問に戻ります。

image

statusと入力すると現在選択されているものが表示されます。

image

helpでどのような入力が受け付けられるかなどが見れます。(manコマンド的なやつ)

image

resetで最初に戻ります。

image

quitで終了です

image

まとめ

このライブラリですが、選択肢をList型で宣言すると一番目の要素が無視される動きをしています。

恐らくライブラリのバグっぽいのでそこだけ注意しましょう。最悪このライブラリはGithubで管理されているのでプルリク投げましょう。

これだけの実装で、すごく簡単に注文受付用のシンプルなBotが完成しました。

注文以外にも簡単な選択肢のアンケートなら、これでもうあとは入力結果をDBなりに飛ばす仕組みと使いやすいようにGUIでラップしてやれば完成です。

表示するテキストなどは、ある程度カスタムできるみたいなのでそれはまた今度