Corredor

ウェブ、プログラミングの勉強メモ。

Oracle Digital Assistant を使ってチャットボットを作る

Oracle Digital Assistant というサービスを使って、簡単なチャットボットを作ってみる。

Digital Assistant について

Oracle Autonomous Digital Assistant は、チャットボットを作れるサービス。以前は Intelligent Bot Cloud Service (IBCS) と呼ばれていた。

IBCS 時代の「Chat Bot」機能が、現 Digital Assistant における「Skill」という機能になり、この「Skill」機能を複数組み合わせて、「Digital Assistant」と呼ばれる一つの大きなチャットボットを作れるようになった。

Skill 単体や、1つ以上の Skill を組み込んだ Digital Assistant は「Channel」を作ることで Web サービスや Web サイトと連携できるようになる。

具体的にどんなサービスになるかというと、ユーザに質問事項を入力してもらうと、「よくある質問」を回答してくれるようなサービスだったり、ユーザに商品や個数を入力してもらって商品の注文を受け付けたりするようなサービスが作れるようになる。

Digital Assistant 管理画面への移動方法

Oracle Cloud My Services にログイン → ダッシュボード画面のハンバーガーメニュー → 「サービス」を展開 → 「Autonomous Digital Assistant」を押下。「Autonomous Digital Assistant」画面に移動する。

インスタンスが未作成なら、ココで「インスタンスの作成」ボタンからインスタンスを作成しておく。

インスタンス作成後は「Autonomous Digital Assistant」画面にインスタンス一覧が表示されるので、当該インスタンスの右端にあるアイコンを押下し、「Digital Assistant Designer UI」項目を押下する。

「Welcome to Oracle Digital Assistant!」という画面に移動できたら OK。

Skill を作る

今回は、ユーザが「出会いの挨拶らしき発言」をしたら「Hello」と応答し、「別れの挨拶らしき発言」をしたら「Bye」と応答する、簡単なチャットボットを作ってみる。

「Digital Assistant Designer UI」画面のハンバーガーメニュー → Development → Skills と移動し、「New Skill」を押下する。

「Create Skill」ダイアログにスキル名などを入力し、「Create」ボタンを押下する。

インテントを作成する

Intent (インテント) とは、「ユーザの意図」を判定するためのキーワードのこと。複数のサンプルフレーズを登録しておき、ユーザの発言がそのサンプルフレーズに近かったら、ユーザがやりたいこと (= 意図 = Intent) が特定できる、という仕組みだ。

作成したスキルの詳細画面に移動したら、左メニューより「Intents」アイコン (人間の頭のアイコン) を押下する。「+ Intent」ボタンでインテントが作成できる。インテント名は英語で指定する。そして、「Examples」欄に、サンプルフレーズを入力していく。

今回のチャットボットの例でいくと、「出会いの挨拶を交わしたい」という意図と、「別れの挨拶を交わしたい」という意図がある、と設計できる。

そこでまずは、「出会いの挨拶を交わしたい」インテントとして、greetIntent を作成する。「Examples」欄には「hello」「hi」「こんにちは」などの文言を入れておこう。

同様に、「別れの挨拶を交わしたい」インテントとして、byeIntent を別に作成する。「Examples」欄には「bye」「goodbye」「さようなら」などの文言を入れておこう。

画面右上の「Try It Out!」リンクを押下すると、右ペインにチャット画面が表示され、ユーザの入力値がどの程度そのインテントに合致すると判定されたか、という反応度合い (Confidence) が確認できる。

Examples フレーズと反応度合い (Confidence) について

Examples フレーズに登録した英語の文字列は、大文字・小文字を区別する。

  • 例えば、「hi」というフレーズを登録した場合の、各入力値に対する反応は以下のとおり。
    • hi」 : 反応する (小文字で完全一致)
    • hi.」「hi!」「hi?」 : 反応する (Confidence は 100%。小文字で完全一致、直後の記号は無視される)
    • Hi」「HI」 : 反応しない (Confidence は 0%。大文字・小文字が一致していない)

よって、Examples フレーズには「小文字のみ」「大文字のみ」「大文字始まりの小文字表記」などのバリエーションを登録しておくと良い。

Examples フレーズと日本語について

現在の Digital Assistant は日本語対応が未熟で、Examples フレーズに日本語を使うのは困難と思われる。色々独自に検証した結果、以下のような挙動だった。

  • Examples の入力欄「Enter your example utterances here.」の挙動に癖がある。Enter キーを押下すると、日本語変換中であってもフレーズが登録されてしまう。日本語フレーズを登録したい場合はメモ帳などからテキストをコピー & ペーストして登録すると良い。
  • こんにちは」というフレーズを登録した場合、ユーザからの入力に対し、原則的には完全一致しないと反応できない (Confidence が 0% になってしまう)
    • こんにち」という入力 : 反応しない (部分一致では反応しない)
    • こんにちは」 : 反応する (完全一致)
    • こんにちは?」「こんにちは!」「こんにちは、」「こんにちは。」 : 反応する (完全一致した直後の記号1文字は無視される様子)
    • こんにちは!!」「こんにちは!?」 : 反応しない (完全一致した後、記号が2文字以上続くと反応しなくなる)
    • 注文受付処理開始」などといった、漢字が多く登場するサンプルフレーズを登録した場合、完全一致している文字列でも反応しなかった

ダイアログ・フローを作成する

greetIntentbyeIntent の2つの Intent が作れたら、次は Dialog Flow の作成に移る。左メニューより「Flows」アイコン (文章っぽいイメージのアイコン) を押下し、ダイアログ・フローの編集画面に遷移する。

ココに表示されているのは YAML で、Digital Assistant 独自の構文で会話の流れを定義していくことで、チャットボットの会話フローが作成できる。「+ Components」ボタンを押下すると、よくある処理を逆引きで指定し、雛形となるスニペットコードを挿入できたりする。

今回は、ユーザの入力値からインテントを判断し、greetIntent に近いと判断したら「Hello」と応答、byeIntent に近いと判断したら「Bye」と応答、どちらとも取れなければ「I don't know」と応答させてみる。以下のコードをコピペしてもらえれば良いかと思う。

# metadata : お決まりの書式
# --------------------------------------------------------------------------------

metadata:
  platformVersion: 1.0
main: true
name: MySkill  # スキル名

# context : 変数を定義する
# --------------------------------------------------------------------------------

context:
  variables:
    # 「変数名: "型"」と書く。string・boolean・int・float・double、list・map・resourcebundle、エンティティ名が指定できる
    # インテント・エンジンの結果を保持するには、「iResult: "nlpresult"」のように宣言する
    iResult: "nlpresult"

# states : 会話フローを定義する
# --------------------------------------------------------------------------------

states:
  
  # インテントを解析するステート
  intentState:
    component: "System.Intent"  # そのステートで使用するコンポーネント (処理) を指定する。基本はビルトインコンポーネントを使う
    properties:
      variable: "iResult"  # 解析した文字列を指定の変数に入れる
    transitions:
      actions:  # 解析した文字列がインテントに合致したら、指定のステートを実行し処理する
        greetIntent     : "greetState"       # 「インテント名: "次に実行するステート名"」と記述する
        byeIntent       : "byeState"         # この actions 内には作成した全てのインテントを列挙しておくべき (後述)
        unresolvedIntent: "unresolvedState"  # unresolvedIntent というアクション名は固定。いずれのインテントにも当てはまらない場合の処理を指定する
        # unresolvedIntent を指定しておらず、どのインテントにも合致しない文言を受け取った場合は、このステートの直後に定義されているステートに自動的に移動する
  
  # このステートに移動することは想定していない
  afterIntentState:
    component: "System.Output"
    properties:
      text: "異常 : このステートには移動しません"
    transitions:
      return: "done"
  
  # greetIntent に合致した際の応答
  greetState:
    component: "System.Output"  # ただメッセージを応答するだけのコンポーネント
    properties:
      text: "Hello!"  # 応答する文言。日本語もこの場で記述できる。
    transitions:
      return: "done"  # 「return」を指定するとセッションが終了する (後続のステートには移動せず、最初のステートの手前に戻る)。値は慣例的に「"done"」が使われる
  
  # byeIntent に合致した際の応答
  byeState:
    component: "System.Output"
    properties:
      text: "Bye!"  # 応答する文言
    transitions:
      return: "done"
  
  # 合致するインテントがなかった場合の応答
  unresolvedState:
    component: "System.Output"
    properties:
      text: "I don't know."  # 応答する文言
    transitions:
      return: "done"

このダイアログ・フローの構文を覚えるのが大変だが、中でも重要なポイントは以下のとおり。

  • context ブロックで変数宣言を行う。Oracle PL/SQL における DECLARE みたいなイメージ。
  • states ブロックに、会話フローの処理を書いていく。
    • 一つのステートにつき、一つの処理を行うのが原則。
    • ステートは基本的に、上から下に、記述された順に繋がって実行されていく。「次に実行されるステート」をハンドリングする場合は、transitions プロパティで定義する。
    • 正常系、異常系を含めた、会話フロー (= 次に実行するステート) の定義が面倒。transitions プロパティの指定によってステートを「飛び越える」感覚と、それ以外の場合に「次のステートに勝手に移動する」感覚を意識すること…。
  • インテントを判定した際の transitions プロパティには、定義した全てのインテントと「対応する次のステート」を記載した方が良い。「インテントとして定義はされているが、transitions.actions に列挙していないインテント」が存在する場合、そのインテントに合致する文言を受け取ると正常にハンドリングできなくなり、エラーになってしまうため。
  • unresolvedIntent は、「どのインテントとも合致しない文言だった」場合に反応する固定のインテント名。コレを記述しなかった場合に、どのインテントにも合致しない文言を受け取った場合は、transitions.actions に記載のどの条件にも合致しないことになるので、その次に記述されているステートの処理が行われる。

ひととおり実装できたら、画面右上の「Validate」ボタンより、Dialog Flow の YAML に構文エラーがないかが確認できる。

動作確認する

インテントを定義し、ダイアログ・フローを作成したら、動作確認してみよう。←メニュー下部にある「Skill Tester」ボタン (再生アイコンのボタン) を押下すると、チャット画面が開くので、ココから実際に会話することで動作検証ができる。

「hi」や「hello」といった文言に「Hello!」と、「bye」や「goodbye」といった文言に「Bye!」と、それ以外のデタラメな発言に対しては「I don't know.」と、ボットが答えてくれることが確認できるかと思う。右ペインの「States」部分には、どういう順番でステートが実行されているかが表示されるので、狙ったとおりに動作しているかが確認できるだろう。

以上

今回は大変シンプルだが、ユーザからの発言に対し、挨拶を返すチャットボットを構築できた。

チャットボット AIとロボットの進化が変革する未来

チャットボット AIとロボットの進化が変革する未来