PHPで自然対話(知識検索・雑談対話)

(1/1)
今回は、PHP で「docomo Developer support」を利用し、知識検索や雑談対話を行うプログラムを作ってみることにする。
PHP で自然文で質問して回答を得る」「PHP で自然対話」で使った API が 2018 年(平成 30 年)6 月末に廃止予定とのアナウンスがあったことから、これらを統合するプログラムを目指す。

サンプル・プログラム:実行例

PHPで雑談対話
最下段のテキストボックスにメッセージをし、送信ボタンを押すると docomo Developer support から応答が返ってくる。過去の雑談の流れを一覧表示できるようにしてある。

サンプル・プログラム

docomo Developer support クラス

docomo Developer support を利用する関数群はクラス pahooDoCoMoAPI として別ファイル "pahooDoCoMoAPI.php" に定義してある。このファイルを  require_once  できるパスに配置すること。

https通信を使うため、PHP から OpenSSL を利用できるようにしておく必要がある。その手順は「PHP の https 対応」を参照のこと。

0022:     //認証用パラメータ:申請はhttps://dev.smt.docomo.ne.jp/?p=login
0023:     var $DOCOMO_API_KEY        = '***************';
0024:     var $DOCOMO_CLIENT_SECRET  = '***************';
0025:     var $DOCOMO_CLIENT_CLIENT  = '***************';

docomo Developer support を利用するには、事前にアカウント登録(無料)とアプリケーションを登録し、API キーなどを取得しておく必要がある。新規登録画面から登録しよう。

docomo Developer support:知識検索

知識検索は、システム内の知識データベースやインターネット上のページを調べて、質問の答えを提供する docomo Developer support である。
知識検索を呼び出すには、事前にアプリケーション ID を取得する必要がある。
知識検索(ユーザー登録) (POST)
URL
https://api.apigw.smt.docomo.ne.jp/naturalKnowledge/v1/registration

入力パラメータ
項目名 フィールド名 内  容
APIキー APIKEY string 【必須】APIにアクセスするアプリの認証に利用する。
以下,JSON形式にすること
対話の種類 botId string 【必須】Knowledge
アプリ種別 appKind string 【必須】サービス毎に定義するアプリ種別(アプリ固定値)
応答データ(json) appId アプリケーションID
知識検索 (POST)
URL
https://api.apigw.smt.docomo.ne.jp/naturalKnowledge/v1/dialogue

入力パラメータ
項目名 フィールド名 内  容
APIキー APIKEY string 【必須】APIにアクセスするアプリの認証に利用する。
以下,JSON形式にすること
言語 language string 【必須】ja-JP
対話の種類 botId string 【必須】Knowledge
アプリケーションID appId string 【必須】ユーザ登録で取得したappId
ユーザの発話 voiceText string 【必須】200文字以下
※[角括弧] <山括弧> の入力はできない
受信日時 appRecvTime string 【必須】アプリが最後に取得パラメータを受信した時刻
YYYY-MM-DD hh:mm:ss
送信日時 appSendTime string 【必須】アプリが送信パラメータを送信した時刻
YYYY-MM-DD hh:mm:ss
応答データ(json) systemText expression システム発話 utterance 音声合成用テキスト dialogStatus commandId 対話状態ID task taskId タスクID taskName タスク名 requiredSlot slotId スロットID slotName スロット名 exValue 外部入力値 loopCount ループ回数 slotStatus slotName スロット名 slotValue スロット値 valueType スロット値のタイプ updateFlag 更新フラグ watchFlag 監視フラグ serverSendTime サーバが取得パラメータを送信した時刻

docomo Developer support:雑談対話

雑談対話は、ユーザの発話テキストを受け付け、その入力に対して自然な会話となる雑談を提供する docomo Developer support である。
雑談対話を呼び出すには、事前にアプリケーション ID を取得する必要がある。
雑談対話(ユーザー登録) (POST)
URL
https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration

入力パラメータ
項目名 フィールド名 内  容
APIキー APIKEY string 【必須】APIにアクセスするアプリの認証に利用する。
以下,JSON形式にすること
対話の種類 botId string 【必須】Chatting
アプリ種別 appKind string 【必須】サービス毎に定義するアプリ種別(アプリ固定値)
応答データ(json) appId アプリケーションID
雑談対話 (POST)
URL
https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue

入力パラメータ
項目名 フィールド名 内  容
APIキー APIKEY string 【必須】APIにアクセスするアプリの認証に利用する。
以下,JSON形式にすること
言語 language string 【必須】ja-JP
対話の種類 botId string 【必須】Chatting
アプリケーションID appId string 【必須】ユーザ登録で取得したappId
ユーザの発話 voiceText string 【必須】200文字以下
※[角括弧] <山括弧> の入力はできない
受信日時 appRecvTime string 【必須】アプリが最後に取得パラメータを受信した時刻
YYYY-MM-DD hh:mm:ss
送信日時 appSendTime string 【必須】アプリが送信パラメータを送信した時刻
YYYY-MM-DD hh:mm:ss
応答データ(json) systemText expression システム発話 utterance 音声合成用テキスト dialogStatus commandId 対話状態ID task taskId タスクID taskName タスク名 requiredSlot slotId スロットID slotName スロット名 exValue 外部入力値 loopCount ループ回数 slotStatus slotName スロット名 slotValue スロット値 valueType スロット値のタイプ updateFlag 更新フラグ watchFlag 監視フラグ serverSendTime サーバが取得パラメータを送信した時刻

解説:自然対話

0157: /**
0158:  * 自然対話
0159:  * @param string $query ユーザーの発話(UTF-8限定)
0160:  * @param string $botID 対話の種類(省略時は Chatting)
0161:  * @param string $appID アプリケーションID(省略時は新規取得)
0162:  * @param string $appRecvTime アプリが最後に取得パラメータを受信した時刻(省略時は現在時刻)
0163:  * @return string ユーザー登録ID/NULL:失敗
0164: */
0165: function naturalDialog($query$botID='Chatting', $appID='', $appRecvTime='') {
0166:     $url = array(
0167: 'Chatting' => array(
0168: 'reg' => 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/registration',
0169: 'app' => 'https://api.apigw.smt.docomo.ne.jp/naturalChatting/v1/dialogue'),
0170: 'Knowledge' => array(
0171: 'reg' => 'https://api.apigw.smt.docomo.ne.jp/naturalKnowledge/v1/registration',
0172: 'app' => 'https://api.apigw.smt.docomo.ne.jp/naturalKnowledge/v1/dialogue'),
0173: 'FAQ_Mobile' => array(
0174: 'reg' => 'https://api.apigw.smt.docomo.ne.jp/naturalFaqMobile/v1/registration',
0175: 'app' => 'https://api.apigw.smt.docomo.ne.jp/naturalFaqMobile/v1/dialogue'),
0176: 'TaskRecog' => array(
0177: 'reg' => 'https://api.apigw.smt.docomo.ne.jp/naturalTaskRecog/v1/registration',
0178: 'app' => 'https://api.apigw.smt.docomo.ne.jp/naturalTaskRecog/v1/dialogue')
0179: );
0180:     if (! isset($url[$botID]))       return NULL;
0181: 
0182:     $method = 'POST';
0183: 
0184:     //アプリケーションID取得
0185:     if ($appID == '') {
0186:         $opt0   = array(
0187:             'botId'   => $botID,
0188:             'appKind' => 'pahooDemo'
0189:         );
0190:         $option = json_encode($opt0);
0191:         if ($this->docomoAPI($url[$botID]['reg'], $method$option) == FALSE)   return NULL;
0192:         $appID = $this->responses->appId;
0193:     }
0194: 
0195:     //アプリが最後に取得パラメータを受信した時刻
0196:     if ($appRecvTime == '')    $appRecvTime = date('Y-m-d H:i:s');
0197: 
0198:     //送信パラメータ
0199:     $opt1   = array(
0200:         'language' => 'ja-JP',
0201:         'botId' => $botID,
0202:         'appId' => $appID,
0203:         'voiceText' => $query,
0204:         'appRecvTime' => $appRecvTime,
0205:         'appSendTime' => date('Y-m-d H:i:s')
0206:     );
0207:     $option = json_encode($opt1);
0208: 
0209:     return ($this->docomoAPI($url[$botID]['app'], $method$option) == FALSE) ? NULL : $appID;
0210: }

「知識検索」「雑談対話」は自然対話APIにグルーピングされている。
そこで、引数として対話の種類を渡してやることで、内部で、知識検索と雑談対話を切り替えて呼び出すメソッド naturalDialog を用意した。

前回のアプリケーション ID や受信日時を引数で指定できるようにしてあるが、もしこれらが無かったら、アプリケーション ID は新規に取得し、日時は現在日時を設定するようにした。

解説:対話の種類を返す

0151: /**
0152:  * 対話の種類を判定する
0153:  * @param string $query  メッセージ
0154:  * @return string 対話の種類
0155: */
0156: function getBotID($query) {
0157:     if (preg_match('/[\??].$/ui', $query) > 0)    $botID = 'Knowledge';
0158:     else                                            $botID = 'Chatting';
0159: 
0160:     return $botID;
0161: }

入力テキストの末尾がクエスチョンマークだったら知識検索 Knowledge を、それ以外なら雑談対話 Chatting を返すユーザー関数が getBotID である。

解説:自然対話を呼び出す

0163: /**
0164:  * docomo Developer support の自然対話を利用する
0165:  * @param string $query  メッセージ
0166:  * @param string $answer 応答を格納する変数
0167:  * @param   string $api    利用したWebAPIのURLを格納する変数
0168:  * @param string $appID  アプリケーションIDを格納する変数
0169:  * @param string $appRecvTime アプリが最後に取得パラメータを受信した時刻を格納する変数
0170:  * @return string エラーメッセージ/''
0171: */
0172: function send_dialogue($query, &$answer, &$api, &$appID, &$appRecvTime) {
0173:     $pda = new pahooDoCoMoAPI(); //docomo Developer supportクラス
0174: 
0175:     $query = preg_replace('/[\[\][]\<\><>]./ui', '', $query);
0176:     if ($query == '')              return 'メッセージがありません';
0177:     if (mb_strlen($query > 200))    return 'メッセージが長すぎます';
0178: 
0179:     $botID = getBotID($query);       //対話の種類
0180: 
0181:     //docomo Developer support 自然対話
0182:     $appID = $pda->naturalDialog($query$botID$appID$appRecvTime);
0183: 
0184:     if ($appID == NULL) {
0185:         $answer = $api = '';
0186:         return $query . ' の応答を取得できません';
0187:     } else {
0188:         $answer = $pda->responses->systemText->expression;
0189:         $appRecvTime = $pda->responses->serverSendTime;
0190:         $api = $pda->webapi;
0191:     }
0192: 
0193:     $pda = NULL;
0194: 
0195:     return '';
0196: }

まず、pahooDoCoMoAPI クラスを呼び出す。
ユーザー発話 $query に使えない文字は、関数  preg_replace  によって、あらかじめ消去しておく。
また、$query が空だったり 200 文字を超えたらエラーを返す。

続いて、前述のメソッド naturalDialog を呼び出す。
回答は、systemText->expression に入っているメッセージをそのまま利用する。

解説:対話履歴

0286: //リセット
0287: if (isButton('reset'))  $query = $dialogue = '';
0288: 
0289: //対話履歴を配列へ
0290: if ($dialogue != '') {
0291:     parse_str($dialogue$arr);
0292:     foreach ($arr as $key=>$val) {

対話履歴は配列に入れてから表示しているが、応答の度に次のページに渡す必要がある。
そこで、組み込み関数  http_build_query  を使って文字列に変換する。これを配列に復元するには  parse_str  を使った。

参考サイト

(この項おわり)
header