【Dialogflow】1つのIntentでどんな質問にも答えられるスーパーエージェントを作った話


はじめに

簡単な質疑応答システムを作るためにDialogflowを使うことはよくあると思います。
通常は各質問ごとに各Intentを定義してあげるのですが、今回はそれを1つのIntentで対応してしまおう!(以下、スーパーエージェント)
という話になります。

通常の方法のデメリット

質疑応答システムは膨大な質問数を扱う事がある、つまり膨大なIntentを扱うことになるため、メンテナンスが大変です。

Q1Intent
Q2Intent
...
QXIntent

スーパーエージェントのメリット

質問数が増えてもIntentは増えることがないため、Entityの管理だけになります。

QIntent

具体的な実装方法

方針としては 会話を分解する ことになります。
例えば、「チョコレートはいくらですか」「チョコレートは何個ですか」という2つの質問があるとします。
両者共にチョコレートを題材として扱っていますが、前者は値段を問う質問で、後者は個数を問う質問なので、当然答えは変わってきます。これを通常の方法でIntent定義すると、
「{sweet}はいくらですか」と「{sweet}は何個ですか」(sweetはEntity)という学習フレーズを持った二つのIntentになると思います。スーパーエージェントでは「何個ありますか」「いくらですか」という部分もEntity管理してしまおう!というのが本質になります。なので次の様に分解してみます。
「チョコレート」を noun Entity
「いくらですか」「何個ありますか」を verb Entity
として名詞動詞に分解します。
そうすると先ほどのIntentの学習フレーズは次の様にあらわせると思います。

{noun}は{verb}

Intentが1つになりましたね。あとは名詞だけや動詞だけ、名詞と動詞が繋がったり、逆になったり、名詞だけが含まれる文章、動詞だけが含まれる文章パターンを考えます。
最終的には次の様な学習フレーズになると思います。

{noun}
{verb}
{noun}{verb}
{noun}は{verb}
{verb}{noun}
{verb}は{noun}
{noun}をしたい ※verbにパターンが存在しない、名詞だけ含まれる文章パターン
ものを{verb} ※nounにパターンが存在しない、動詞だけ含まれる文章パターン

最後にnounとverb(場合によってはID)でデータベースから質問に対する答えを検索するだけです。

まとめ

分解して考えることで、やたらとIntentを増やさなくても様々なケースに対応できます。
文章が長く、名詞や動詞が複数含まれる場合でも、塊として名詞か動詞に寄せてしまえばそれっぽく動きました。
私のケースですと、今回のスーパーエージェントを作っておく事で、要件を満たす事ができました。