COTOBA agent AIML reference

COTOBA AIMLについて

COTOBA AIMLとは、COTOBA DESIGN, Inc.の対話プラットフォームであるCOTOBA Agentで、対話シナリオを記載する為に利用する対話言語です。 AIML(Artificial Intelligence Markup Language)をベースにCOTOBA DESIGN, Inc.が独自拡張を行なっており、JSONの取り扱いやAPIからのメタデータの処理、REST APIの呼び出しおよび戻り値の参照による対話制御等、COTOBA Agent以外の情報を用いた対話制御ができるような拡張を行なっています。

COTOBA AIML記述方法

対話シナリオの記述方法について説明します。 ここでは利用者の発話内容に対する、対話プラットフォームの応答を記載するという、基本的な対話シナリオの例を説明します。

変数の保持、JSONの利用方法、REST APIの呼び出し方法等はCOTOBA AIMLリファレンスの内容を組み合わせることで、様々な対話シナリオを作成することができます。

基本対話シナリオ

利用者の発話の内容に応じ、対話プラットフォームからの応答を定義し、対話シナリオを記述します。

category要素は、AIMLの対話ルールの基本単位です。 category要素内に、 pattern と template といった1つの対話ルールを記載します。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">

    <category>
        <pattern>おはよう</pattern>
        <template>おはようございます、今日も1日頑張りましょう。</template>
    </category>

</aiml>
Input: おはよう
Output: おはようございます、今日も1日頑張りましょう

応答の分岐

対話シナリオを作成する場合、利用者の1つ前の発話に応じて応答文を変更する必要が多々あります。

例えば、対話プラットフォームからの問い合わせに対し、”はい/いいえ”で応答を返すシーンがあります。”はい/いいえ”をpatternに記載しますが”はい/いいえ”といった、一般的な言い回しは他の対話でも利用され区別をつける必要があります。

この場合の応答分岐の例としては、thatを利用します。

以下例では、”はい”、”いいえ”の結果により応答を変えています。ただし、”はい”、”いいえ”のユーザ発話はこの例以外でも発生しますが、 この応答はBotの応答が、”コーヒーに砂糖とミルクを入れますか?”の時だけにマッチするように、thatでBotの前発話をマッチ条件にしています。

<category>
    <pattern>私はコーヒーが好きです</pattern>
    <template>コーヒーに砂糖とミルクを入れますか</template>
</category>

<category>
    <pattern>はい</pattern>
    <that>コーヒーに砂糖とミルクを入れますか</that>
    <template>わかりました</template>
</category>

<category>
    <pattern>いいえ</pattern>
    <that>コーヒーに砂糖とミルクを入れますか</that>
    <template>ブラックですね</template>
</category>
Input: 私はコーヒーが好きです
Output: コーヒーに砂糖とミルクを入れますか
Input: はい
Output: わかりました

対話内容の抽出、変数利用

利用者の発話の内容を抽出するには”*”とstarを利用します。また、利用者の発話した内容を保持する為、getとsetを利用します。

1つ目の発話でペットの種類を保持します。その際利用者の発話patternのペットの種類に相当する部分をワイルドカード”*”で指定します。ワイルドカードの部分をtemplateで利用する場合<star/>を用います。starにはpatternで定義したワイルドカード指定した範囲の文字列が抽出されます。

変数の利用はset/getを使用します。setの属性で指定した名称petcategoryにsetの内容を保持します。

次の発話では、利用者のペットの名前を保持します。同様にsetを用い保持しますが、別の変数名petnameを利用します。

次の発話では、保持した内容を利用し対話プラットフォームからの応答の選択および返答内容に変数の内容を含めます。

変数の内容による分岐は、conditionを利用します。conditionは対象となる変数との文字列比較を行う要素で、switch-caseのような処理を記載することができます。

以下の例では、ペットの種類petcategoryが”犬”か”猫”かをswitch-case文のcaseに当たるliで分岐します。どちらでもなかった場合未評価結果を返します。

また、返答の内容にpetnameで保持した内容を返しています。

<category>
    <pattern>私のペットは*です</pattern>
    <template>
        <think><set name="petcategory"><star /></set></think>
        <star/>が好きなんですね
    </template>
</category>

<category>
    <pattern>ペットの名前は*です</pattern>
    <template>
        <think><set name="petname"><star /></set></think>
        いい名前ですね。
    </template>
</category>

<category>
    <pattern>私のペット覚えてる?</pattern>
    <template>
        <condition name="petcategory">
            <li value="犬">あなたのペットは犬の<get name="petname" />ですよね</li>
            <li value="猫">あなたのペットは猫の<get name="petname" />ですよね</li>
            <li>ペットは飼っていなかったよね</li>
        </condition>
    </template>
</category>
Input: 私のペットは犬です。
Output: 犬が好きなんですね。
Input: ペットの名前はマロンです。
Output: いい名前ですね。
Input: 私のペット覚えてる?
Output: あなたのペットは犬のマロンですよね。

BOT連携

複数BOTを作成し各々の結果を連携し動作させることができます。REST通信での連携にはsraix要素の 汎用RESTインタフェース を利用します。 以下のように、既に作成したボットIDをホスト名の呼び出し先に指定し、bodyに必要な情報を設定します。

BOTからの戻り値は、var:__SUBAGENT_BODY__に含まれており、json要素で取り出しを行うことができます。

<?xml version="1.0" encoding="UTF-8"?>

<aiml version="2.0">
    <category>
        <pattern>サブエージェント*</pattern>
        <template>
            <think>
                <json var="body.utterance"><star /></json>
                <json var="body.userId"><get var="__USER_USERID__" /></json>
                <sraix>
                    <host>https://HOSTNAME/bots/BOT_ID/ask</host>
                    <method>POST</method>
                    <header>"Content-Type":"application/json;charset=UTF-8"</header>
                    <body><json var="body" /></body>
                </sraix>
            </think>
            <json var="__SUBAGENT_BODY__.response" />
        </template>
    </category>
</aiml>
sraix要素の属性 botName を指定することで、BOTのエイリアス定義を利用して対BOT専用の通信処理が行えます。
詳細については、対話プラットフォームで、公開されているbot呼び出し を参照してください。

エイリアス定義を利用して同じ処理を行う場合、まず、エイリアスの登録ファイル(botnames.yaml)に以下の内容を記述します。

bot:
  ALIAS_NAME:
    url: https://HOSTNAME/bots/BOT_ID/ask

シナリオの記述は以下の様に簡略化されます。

<?xml version="1.0" encoding="UTF-8"?>

<aiml version="2.0">
    <category>
        <pattern>サブエージェント*</pattern>
        <template>
            <sraix botName="ALIAS_NAME">
                <star />
            </sraix>
        </template>
    </category>
</aiml>

意図解釈エンジン連携

意図解釈エンジンで作成したモデルを用いる場合、推論エンドポイントをボット作成時に設定します。

NLU要素を利用し意図解釈エンジンのインテントによるpattern分岐シナリオを作成します。その際の意図解釈エンジン利用時のインテント、スロットは、nluintent,nluslot要素で取得することができます。

また、対話プラットフォームはシナリオの記述に従いルールベースの意図解釈を行って、patternマッチングで評価した結果に応じて応答を返しますが、マッチするpatternがなかった場合、高度意図解釈のインテントの結果を用いた対話制御を行います。これは意図解釈の結果より、シナリオ作成者が記述する内容を優先させるためです。例外として、patternとしてワイルドカードのみが記述されたcategoryが存在する場合、シナリオ記述のマッチングと、意図解釈のマッチングとの両方でマッチしなかった後に、マッチ処理を行います。子要素のnluを定義した場合でも、pattern要素の内容を記載すると通常のパターン評価が行われます。nlu要素の属性は、nlu を参照してください。

以下の例では、意図解釈エンジンの処理結果が”レストラン検索”だった場合、patternにマッチし、意図解釈エンジンのインテントリスト、スロットリストを返すサンプルです。

<aiml version="2.0">
    <category>
        <pattern>
            <nlu intent="レストラン検索" />
        </pattern>
        <template>
            <think>
                <set var="count">0</set>
                <set var="slotCount"><nluslot name="*" item="count" /></set>
            </think>
            <condition>
                <li var="count"><value><get var="slotCount" /></value></li>
                <li>
                    slot:<nluslot name="*" item="slot"><index><get var="count" /></index></nluslot>
                    entity:<nluslot name="*" item="entity"><index><get var="count" /></index></nluslot>
                    <!-- score:<nluslot name="*" item="score"><index><get var="count" /></index></nluslot> -->
                    <think>
                        <set var="count"><map name="upcount"><get var="count" /></map></set>
                    </think>
                    <loop />
                </li>
            </condition>
        </template>
    </category>
</aiml>
尚、sraix要素の属性 nlu を指定することで、特定のNLUサーバと直接通信を行って、意図解釈エンジンの処理結果を取得することもできます。
詳細については、SubAgentの NLU通信インタフェース を参照してください。

用語集

本章ではドキュメント中で用いる用語を定義します。

対話処理にまつわる用語

本セクションでは、ドキュメント中で用いる対話処理にまつわる用語を定義します。

用語 定義
対話シナリオ 対話処理の実行に関わる処理プログラムやデータを記述したファイル群。対話処理のプログラムは AIML (Artificial Inteligence Markup Language) で記述する。
開発者 対話処理のプログラムやデータを記述し対話アプリケーションを開発する者。
対話エンジン 対話シナリオを登録して対話処理を実行する実行環境。
ボット 対話エンジンに対話シナリオが登録されて対話処理を実行可能な状態にある対話処理プロセス。
ユーザ ボットに対して対話処理を要求する者。
システム ボットの別称。ユーザと対比する文脈で用いることがある。
リクエスト ユーザがボットに対して行う対話処理要求、あるいは、その内容。
レスポンス ボットが対話処理を行ってユーザに返す対話処理応答、あるいは、その内容。
発話文 リクエストに含まれ、ユーザがボットに送信する文字列。
応答文 レスポンスに含まれ、ボットがユーザに返信する文字列。
高度意図解釈 機械学習モデルにより発話文の意図(インテント)を推論し、意図に付随するキーワード(スロット)を発話文から抽出する機能、あるいは、その機能を実行するモジュール。
対話ログ 対話エンジン(ボット)が実行した対話処理の動作過程を記録したログ。
サブエージェント あるボットが、特定の対話処理やその他の情報処理を、他のボット、あるいは、情報サービスに行わせるために呼び出す先のボットや情報サービスをさす。SA (SubAgent) とも記す。
メインエージェント サブエージェントを呼び出す側のボット。MA (MainAgent) とも記す。

cAIML

本セクションでは、ドキュメント中で用いる cAIML (COTOBA AIML) にまつわる用語を定義します。

用語 定義
AIML Artificial Inteligence Markup Language の略称。対話処理プログラムの記述言語の1つ。AIML は XML 形式で記述する。
cAIML COTOBA AIML の略称。COTOBA DESIGN による独自仕様拡張を含む AIML。
タグ XML の基本構造を規定するタグ(開始タグ ‘<…>’、終了タグ ‘</…>’)のうち cAIML で定義されたもの。
要素 タグを構成する主構成要素。開始タグ ‘<要素>’、終了タグ ‘</要素>’ の記法で記述される。
属性 タグを構成するサブ構成要素。開始タグ ‘<要素 属性=”値”>’ の記法で記述される。属性は複数あっても良いが、同じ属性は複数指定できない。どの属性が使えるかは要素毎に規定される。要素を関数だと考えると、属性は引数と解釈出来る。
内容 開始タグと終了タグの間に記述される文字列。’<要素 属性=”値”>内容</要素>’ の記法で記述される。内容には文字列や他の要素を複数記述することが出来る。これにより cAIML は XML 同様、入れ子構造の記述形式となる。
要素名 特定の要素を指定するための名称。
属性名 特定の属性を指定するための名称。
属性値 属性に設定する値。cAIML で属性値として記述する場合ダブルクオーテーションでくくる決まりである。
ブロック 内容を含んだある要素全体(対応する開始タグから終了タグの間の記述内容)を指す。
ノード cAIML の XML 形式のデータ構造を木構造と見た時の要素に相当する木構造の構成要素。
NLU cAIML から呼び出す高度意図解釈機能を指す。

COTOBA Agent dialog engine API

対話API

対話エンジンをREST APIクラス(programy.clients.restful.yadlan.sanic.client)を用いて立ち上げた場合に利用されるAPIです。 ユーザの発話文を含むリクエストをボットに送信し、ボットからの応答文を含むレスポンスを取得します。

項目 内容
プロトコル HTTP
メソッド POST

リクエスト

対話APIリクエストに設定する内容です。

  • リクエストヘッダ
フィールド名 説明
Content-Type application/json;charset=UTF-8 コンテントタイプでJSON、文字コードはUTF8を指定します。
  • リクエストボディ
項目名   キー 必須 説明
ロケール   locale string No 言語指定。ISO-639 言語コードとISO-3166 国コードをハイフン繋いだ組み合わせを指定します。例:ja-JP, en-US, zh-CN。 未指定の場合、ボット側で規定した言語で動作します。
時間情報   time string No リクエスト側時刻。ISO8601(RFC3339)形式で指定します。例:2018-07-01T12:18:45+09:00。 未設定の場合サーバ時刻で動作します。
ユーザID   userId string Yes ユーザ毎のユニークなIDを指定します。
トピックID   topic string No 対話シナリオで記載したシナリオIDを指定します。未指定の場合、対話エンジンが持っているtopicのまま動作します。
ユーザ発話   utterance string Yes ユーザの発話文。
タスク変数削除   deleteVariable boolean No trueを設定するとAIML記述のset/getの属性 data で設定した変数を一括で削除します。name、varで設定した変数は削除されません。
メタデータ   metadata string No JSON形式のメタデータ、もしくは文字列を設定できます。設定したデータを対話シナリオ内で利用する場合、対話シナリオ側で、このメタデータを使用するための記述が必要です。詳細は 対話APIデータの変数利用 を参照してください。
コンフィグ   config   No 対話エンジン動作状態に関する設定。
  ログレベル logLevel string No 対話エンジンの対話ログの出力レベルを設定します。設定値は次のとおりです。none:対話ログを出力しない、error:エラーレベル以上の対話ログを出力する、warning:ワーニングレベル以上の対話ログを出力する、info:動作状態以上の対話ログを出力する、debug:デバッグ以上の対話ログを出力する。対話ログの出力量の大小関係は、none<error<warning<info<debugになります。未指定の場合、対話ログの出力レベルは変更されません。
  • リクエスト例
POST /v1.0/ask HTTP/1.1
Host: www.***.com
Accept: */*
Content-Type: application/json;charset=UTF-8

{
    "locale": "ja-JP",
    "time": "2018-07-01T12:18:45+09:00",
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308E03A71",
    "topic": "greeting",
    "utterance": "こんにちは",
    "deleteVariable": false,
    "metadata": {"arg1":"value1","arg2":"value2"},
    "config": {"logLevel":"debug"}
}

レスポンス

対話APIリクエストに対するレスポンスボディはJSON形式です。 対話APIリクエストに対するレスポンスコードの一覧は以下のとおりです。 対話エンジン内の処理以外に起因するレスポンスコード(以下一覧以外のHTTPステータスコード)が返されることもあります。 その場合のレスポンスボディの内容は不定です。

  • レスポンスコード
コード 説明
200 リクエスト正常終了。
400 パラメータエラー。リクエストの内容の見直しが必要です。
  • レスポンスヘッダ
フィールド名 説明
Content-Type application/json;charset=UTF-8 コンテントタイプでJSON、文字コードはUTF8を指定します。
  • レスポンスボディ
項目名 キー 必須 説明
ユーザ発話 utterance string Yes 対話エンジン内部で処理を行ったユーザ発話文。英数の半角化、半角カナの全角化等の内部処理を行った結果を返します。
ユーザID userId string Yes ユーザ毎のユニークなIDを指定します。リクエストのuserIdと同じ。
応答文 response string Yes 対話エンジンから応答文。UTF8の文字列を返します。
トピック名 topic string Yes 現在のトピック名。
レイテンシ latency number Yes エンジン内処理時間。リクエストを受けてからレスポンスを返すまでの処理時間で単位は秒。シナリオに登録されているパターンマッチ処理、意図解釈処理、SubAgentの処理を含んだ処理時間になります。
メタデータ metadata string No JSON形式のメタデータ、もしくは文字列が設定されます。メタデータの内容は対話シナリオ内の記述により指定されます。
  • レスポンス例
HTTP/1.1 200 Ok
Content-Type: application/json;charset=UTF-8

{
    "response": "こんにちは、今日もいい天気ですね",
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308E03A71",
    "topic": "greeting",
    "latency":0.0317230224609375,
    "utterance": "こんにちは"
}

音楽再生に対応した対話シナリオで”次の曲を再生”と発話し、metadataに再生指示の情報を設定するように対話シナリオで記述した場合の例。

HTTP/1.1 200 Ok
Content-Type: application/json;charset=UTF-8

{
    "response": "次の曲を再生しますね",
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308E03A71",
    "topic": "music_play",
    "latency":0.0317230224609375,
    "utterance": "こんにちは",
    "metadata": {"play":"next"}
}

デバッグAPI

デバッグAPIは、アップロードされたzipアーカイブの対話シナリオファイルを対話エンジンに登録する際に発生したエラー情報や、対話の履歴情報を取得するためのAPIです。 過去の対話を含めた対話状態を取得することができます。また、対話中に使用するグローバル変数の値を設定(変更)することもできます。

項目 内容
プロトコル HTTP
メソッド POST

リクエスト

デバッグAPIリクエストに設定する内容です。 デバッグAPIエンドポイントには事前に登録したユーザのみがアクセスできます。

  • リクエストヘッダ
フィールド名 説明
x-dev-key yyyyyyyyyyyyyyyyy user-information のx-dev-keyで取得したAPIキーを指定します。
Content-Type application/json;charset=UTF-8 コンテントタイプでJSON、文字コードはUTF8を指定します。
  • リクエストボディ
項目名   キー 必須 説明
ユーザID   userId string No ユーザ毎のユニークなIDを指定します。未指定や存在しないユーザの場合、conversation,current_conversations,logs情報は取得されません。
変数リスト   variables   No 値を設定する変数の情報をリスト形式で指定します。ユーザIDが未指定の場合、変数リストの指定は無効になります。存在しないユーザの場合、更新した変数情報を含むconversation情報は取得できますが、対話履歴の無い状態になります。
  変数タイプ type string No 変数タイプを指定します。指定できるタイプは ‘name’もしくは ‘data’ になります。(key,valueとともに指定します。)
  変数名 key string No 値を設定する変数名を指定します。(type,valueとともに指定します。)
  value string No 変更する値を記載します。(type、keyとともに指定します。)
  • リクエスト例
POST / HTTP/1.1
Host: www.***.com
Accept: */*
x-dev-key: yyyyyyyyyyyyyyyyy

Content-Type: application/json;charset=UTF-8

{
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308000000",
    "variables": [
        {
            "type": "name",
            "key": "name_variable",
            "value": "0"
        },
        {
            "type": "data",
            "key": "data_variable",
            "value": "1"
        },
        :
        }
    ]
}

レスポンス

デバッグAPIリクエストに対するボディはJSON形式です。 デバッグAPIリクエストに対するレスポンスコードの一覧は以下のとおりです。 対話エンジン内の処理以外に起因するレスポンスコード(以下一覧以外のHTTPステータスコード)が返されることもあります。 その場合のレスポンスボディの内容は不定です。

なお、送信時に、変数リスト:variablesを指定した場合、受信データには変数設定が反映された情報が返ります。

  • レスポンスコード
コード 説明
200 リクエスト正常終了。
400 パラメータエラー。リクエストの内容の見直しが必要です。
  • レスポンスヘッダ
フィールド名 説明
Content-Type application/json;charset=UTF-8 コンテントタイプでJSON、文字コードはUTF8を指定します。
  • レスポンスボディ
項目名 キー 必須 説明
対話履歴情報 conversations json Yes 指定したユーザの対話履歴を取得します。
直近対話情報 current_conversations json Yes 直近の対話処理での変数内容の変更状況を取得します。
シナリオエラー情報 errors json Yes 対話シナリオ登録時のエラー内容を取得します。
シナリオ重複情報 duplicates json Yes 対話シナリオ登録時のpatternの重複を取得します。
設定ファイルエラー情報 errors_collection json Yes 各種設定ファイルの登録時のエラー内容を取得します。
ログ情報 logs json Yes 直近の対話処理の中で、templateタグ内のlogタグで出力した対話ログ内容を取得します。
  • レスポンス例
HTTP/1.1 200 Ok
Content-Type: application/json;charset=UTF-8

{
    "conversations": {
        "categories": 1251,                      /* 登録されているCategory数 */
        "user_categories": 0,                    /* learnfで登録されたユーザ固有のCategory数 */
        "exception": null,                       /* 例外発生時のメッセージ */
        "client_context": {                      /* クライアント・ユーザ情報 */
            "botid": "bot",
            "brainid": "brain",
            "clientid": "yadlan",
            "depth": 0,
            "userid": "E8BDF659B007ADA2C4841EA364E8A70308E03A71"
        },
        "properties": {                          /* 現在のグローバル変数(name)値リスト */
            "topic": "daytime",
            "name_variable": "0"
        },
        "data_properties": {                     /* 現在のグローバル変数(data)値リスト */
            "data_variable": "1"
        },
        "max_histories": 100,                    /* 最大対話履歴管理数) */
        "questions": [                           /* 対話履歴(古いものから順に、max_histories分を格納) */
            {
                "exception": null,
                "name_properties": {                 /* 処理完了時のグローバル変数(name)値リスト */
                    "topic": "daytime"
                },
                "data_properties": {},               /* 処理完了時のグローバル変数(data)値リスト */
                "var_properties": {                  /* 処理完了時のローカル変数(var)値リスト */
                    "__USER_LOCALE__": "None",
                    "__USER_METADATA__": "None"
                    :
                },
               "sentences": [                        /* 発話文毎の処理情報 */
                    {
                        "question": "test",              /* 発話文 */
                        "matched_node": {                /* マッチしたシナリオ情報 */
                            "file_name": "../storage/categories/basic.aiml",
                            "start_line": "78",
                            "end_line": "92"
                        },
                        "response": "response OK"        /* 応答文 */
                    }
                :
            :
        ]
    },
    "current_conversation": [
        {
            "before_variables": {                /* 変更があった変数の処理開始時の値リスト */
                "name_properties": {
                    "topic": "*",
                    "name_variable": null
                },
                "data_properties": {
                    "data_variable": null
                }
            },
            "after_variables": {                 /* 変更があった変数の処理完了時の値リスト */
                "name_properties": {
                    "topic": "daytime",
                    "name_variable": "0"
                },
                "data_properties": {
                    "data_variable": "1"
                }
            },
            "question": "test",                  /* 発話文 */
            "that": "*",                         /* マッチ対象となる直近の応答文(初期値:"*") */
            "topic": "*"                         /* マッチ対象となる現在のTopic値 */
            "matched_node": {                    /* マッチしたシナリオ情報 */
                "file_name": "../storage/categories/basic.aiml",
                "start_line": "78",
                "end_line": "92"
            },
            "processing_result": "response OK",  /* brainの通常処理で生成された応答文(denied_srai実施時には空文字) */
            "response": "response OK"            /* 応答文 */
            "srai_histories": [                  /* srai処理の実施履歴 */
                {
                    "before_variables": {            /* 変更があった変数のsrai処理開始時の値リスト */
                        "name_properties": {
                            "topic": "*"
                        },
                        "var_properties": {
                            "var_variable": null
                        }
                    },
                    "after_variables": {            /* 変更があった変数のsrai処理完了時のリスト */
                        "name_properties": {
                            "topic": "daytime"
                        },
                        "var_properties": {
                            "var_variable": "srai_var"
                        }
                    },
                    "question": "test srai",         /* srai対象の発話文 */
                    "that": "*",
                    "topic": "*",
                    "matched_node": {
                        "file_name": "../storage/categories/basic.aiml",
                        "start_line": "4",
                        "end_line": "11"
                    },
                    "processing_result": "srai OK",
                    "response": "srai OK"
                }
            ]
        }
    ],
    "errors": [
        {                                        /* シナリオ内の不正情報をファイル・Category単位で出力 */
            "category": {
                "end": "None",
                "start": "None"
            },
            "description": "Failed to load contents of AIML file : XML-Parser Exception [mismatched tag: line 238, column 25]",
            "file": "../storage/categories/ng.aiml",
            "node": {
                "column": "0",
                "raw": "0"
            },
            "node_name": null
        }
    ],
    "duplicates": [
        {                                        /* シナリオ内での重複Categoryの情報を出力 */
            "category": {
                "end": "35",
                "start": "21"
            },
            "description": "Dupicate grammar tree found [おはよう]",
            "file": "../storage/categories/basic.aiml",
            "node": {
                "column": "9",
                "raw": "22"
            }
        }
    ],
    "errors_collection": {
        "denormals": [                           /* denormal.txtの不正情報を出力 */
            {
                "description": "illegal format [\"word\"]",
                "file": "../storage/lookups/denormal.txt",
                "line": 1
            }
        ],
        "normals": [],                           /* normal.txtの不正情報を出力 */
        "genders": [],                           /* gender.txtの不正情報を出力 */
        :
    },
    "logs": [
        {
            "info": "(templete log-node) log message"
        }
    ]
}

errors/duplicates/errors_collectionの内容を参照することで、シナリオや各種設定ファイルで登録に失敗した項目を確認することができます。

conversations/current_conversation/logsの内容からは対話処理の状況が確認できます。(例外発生時の要因は、conversationsのexceptionで提示されます。)
conversationsでは、使用されている全変数の情報が出力されますが、current_conversationでは、開始時と終了時の間で変更があった変数のみを出力します。
レスポンス例のcurrent_conversationからは、発話文 “test” に対して、”test srai” に対するsrai処理が実施され、srai処理の中でtopic変数が変更されたことが確認できます。

ユーザ固有情報のクリア指定

デバッグAPIのリクエストには、ユーザ毎に保持する固有情報をクリアする専用の指定もあります。
本指定を行った場合には、他の指定よりも優先される為、レスポンスボディにデバッグ情報は格納されません。
クリア処理を行う対象は、以下の2種類です。
  • 対話履歴(conversation 指定): ユーザ毎の対話履歴情報をクリアします。履歴情報と共にユーザ毎に保持する変数情報も初期化されます。
  • learn登録情報(learn 指定): Templateの learnf ノードで登録された、ユーザ固有のCategory情報をクリアします。
  • リクエストボディ
項目名 キー 必須 説明
ユーザID userId string Yes ユーザ毎のユニークなIDを指定します。存在しないユーザの場合、処理は失敗します。
クリア対象 reset string Yes ‘conversation’、’learn’ のいずれか、または、両方を意味する ‘all’ を指定します。
  • リクエスト例
POST / HTTP/1.1
Host: www.***.com
Accept: */*
x-dev-key: yyyyyyyyyyyyyyyyy

Content-Type: application/json;charset=UTF-8

{
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308000000",
    "reset": "all"
}
  • レスポンスボディ

以下のどちらかのJSON形式が設定されます。

  • 成功時: {“reset”: “Succeeded”}
  • 失敗時: {“reset”: “Failed”}
  • レスポンス例
HTTP/1.1 200 Ok
Content-Type: application/json;charset=UTF-8

{
    "reset": "Succeeded"
}

COTOBA AIML: 基本要素

この章では、COTOBA AIML (cAIML) でサポートしているAIMLの基本となる要素について説明します。
セクション冒頭の[…]は、その要素が最初に定義されたAIMLのバージョンを示しています。
[custom]は、cAIML 独自仕様拡張の要素です。

cAIMLのパターンマッチング優先順位ルールの詳細については「パターンマッチング」を参照してください。

aiml

[1.0]

aiml要素は、cAIMLのルート要素です。他の全てのcAIMLの要素はaiml要素の内容として記述する必要があります。
  • 属性
パタメータ タイプ 必須 説明
version string Yes 記述されているAIMLのバージョンを指定します。
  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <!-- cAIML element should be described here -->
</aiml>

category

[1.0]

category要素は、cAIMLの対話ルールの基本単位に相当します。
category要素の内容として、ユーザの発話文とのマッチングパターンを指定する pattern 要素とシステムの応答文を指定する template 要素を記述して1つの対話ルールを構成します。
aiml要素の内容に、複数のcategory要素のブロックを含んだ形で記述することができます。
aiml 要素と topic 要素を除く、すべてのcAIMLの要素は、category要素のブロック内に含まれている必要があります。

尚、登録可能なcategory数は、コンフィグレーション定義の 制限値定義max_categories までとなります。

  • 属性

なし

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは</pattern>
        <template>今日もいい天気ですね</template>
    </category>
        <category>
            <pattern>さようなら</pattern>
            <template>明日また会いましょう</template>
        </category>
</aiml>
Input: こんにちは
Output: 今日もいい天気ですね
Input: さようなら
Output: 明日また会いましょう

関連項目: aiml, topic , pattern, template

pattern

[1.0]

pattern要素は、category要素の内容として記述し、pattern要素の内容としてユーザの発話文とのパターンマッチングを行うパターンを記述します。
pattern要素内に記述された文字列とユーザ発話文の文字列が一致した場合、当該のpattern要素を含む対話ルール(category要素のブロック内の処理)が実行されます。
  • 属性

なし

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは</pattern>
        <template>今日もいい天気ですね。</template>
    </category>
</aiml>
pattern要素の内容には文字列以外のcAIML要素を含む記述を行うこともできます。
それにより、複雑なパターンマッチ処理を行うことができます。
pattern要素の内容として記述可能なcAIML要素の詳細については、pattern要素 を御覧ください。

template

[1.0]

template要素は、category要素の内容として記述し、template要素の内容としてシステムの応答文を記述します。
対話ルール(category要素のブロック)が実行された場合、当該category要素のブロック内のtemplate要素の内容に記述された文字列が、システムの応答文として返されます。
  • 属性

なし

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは</pattern>
        <template>今日もいい天気ですね。</template>
    </category>
</aiml>
template要素の内容には文字列以外のcAIMLタグを含む記述を行うことができます。
それにより、複雑な応答文生成処理を行うことができます。
template要素の内容に記述可能なcAIML要素の詳細については、template要素 を御覧ください。

topic

[1.0]

topic要素のブロック内に、複数の対話ルール category 要素を記述することで対話ルールをコンテキスト化することができます。
対話ルールがコンテキスト化されると、対話エンジンが保持する変数 topic の値が、topic要素のname属性で指定した属性値と一致する時だけ、対話ルールが評価されます。
topic要素のブロック内に含まれない対話ルール(コンテキスト化されない対話ルール) category 要素は、name属性の属性値がワイルドカード”*”と指定されているのと同じ扱いになり、対話エンジンが保持する変数 topic の値に関係なくその対話ルールは評価されます。
ただし、topic要素でコンテキスト化された対話ルールが優先して評価され、そのコンテキスト化された対話ルールが実行されなかった場合にのみ、コンテキスト化されない対話ルールが評価されます。

“topic”は予約語となるためユーザが定義する変数名としては利用できません。

  • 属性
パラメータ タイプ 必須 説明
name string Yes topic名を指定します。
topic要素を利用すると、以下の使用例のように同じ pattern のマッチング動作をコンテキスト(topicの値)に応じて使い分けることができます。
この使用例では、ユーザの「私は何も入れません」という発話に対して、その発話より前に設定されたtopicの値に応じて、評価される対話ルールを切り替えることで応答を変えています。
  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>*について話しましょう</pattern>
        <template>
            私も<set name="topic"><star /></set>が好きです。
        </template>
    </category>

    <topic name="コーヒー">
        <category>
            <pattern>私は何も入れません</pattern>
            <template>私はクリームと砂糖を入れます</template>
        </category>
    </topic>

    <topic name="紅茶">
        <category>
            <pattern>私は何も入れません</pattern>
            <template>私はレモンティーが好きです</template>
        </category>
    </topic>
</aiml>
Input: コーヒーについて話しましょう
Output: 私もコーヒーが好きです
Input: 私は何も入れません
Output: 私はクリームと砂糖を入れます
Input: 紅茶について話しましょう
Output: 私も紅茶が好きです
Input: 私は何も入れません
Output: 私はレモンティーが好きです

関連項目: that, set, think

pattern要素内の子要素

本章ではpattern要素の内容として記述可能な子要素について説明します。
子要素の使用可否については、カスタマイズが可能です。詳細は カスタムpattern要素 を参照してください。
cAIMLでサポートしているパターンマッチング要素の一覧は以下のとおりです。
公式の AIML 2.x仕様に対し、独自の要素セットを追加しています。
  • bot: マッチさせるボットの情報を指定
  • iset: マッチさせる単語の集合を指定
  • nlu: マッチさせる高度意図解釈結果を指定
  • oneormore: 1個以上の任意の単語とマッチするワイルドカード
  • priority: ワイルドカードよりも優先してマッチする単語を指定
  • regex: マッチさせる正規表現を指定
  • set: マッチさせる単語の集合を記述したファイルを指定
  • topic: マッチの条件に追加するtopic変数の値を指定
  • that: 1つ前のシステムの応答文を指定
  • word: マッチさせる単語(文字列)を指定
  • zeroormore: 0個以上の任意の単語とマッチするワイルドカード
ここで説明する要素の大半は、属性の指定と、内容としての子要素の記述により対話エンジンがアクセス可能な各種のデータを利用できます。
pattern要素の記述によるパターンマッチ方法の詳細については パターンマッチング を参照してください。
各要素の先頭の[…]は、対象の要素が最初に定義されたAIMLのバージョンを示しています。

尚、マッチングは、英数記号は半角文字、カタカナは全角文字の統一コードで行います。

bot

[1.0]

bot要素は、カスタムボットプロパティを呼び出すために使用されます。 これらの変数には、ボットにアクセスするすべてのユーザがアクセスできます。
カスタムボットプロパティは、propertiesファイル で設定します。patternのbotで設定する値は単語で、間に空白を指した複数単語は使用できません。
指定するプロパティ名は、大文字・小文字、全角・半角を区別しますが、値のマッチングは、統一コードで行います。
  • 属性
パラメータ タイプ 必須 説明
name string Yes ボットプロパティ名を指定します。

propertiesファイルで定義していないプロパティ名をnameで指定した場合、シナリオ不正、または、常にアンマッチになります。

  • 使用例

以下の使用例ではボットの名称を返します。(propertiesファイル で ‘name:ボット’ と設定している前提)

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>あなたは<bot name="name" />ですか?</pattern>
        <template>私の名前は<bot name="name" />です。</template>
    </category>
</aiml>
Input: あなたはボットですか?
Output: 私の名前はボットです。

関連項目: ファイル管理:properties

iset

[1.0]

iset要素は、単語リストファイル(sets) を使用せず、少数のマッチ対象単語を記述する場合に使用します。マッチングは、統一コードで行います。
要素として、複数英単語からなる文字列も指定が可能ですが、その場合、単語数が多いものが優先してマッチします。
尚、英単語列と日本語文字列が混在する指定の場合の動作は保証できません。(日本語文字列の場合、間の空白は除外してマッチングを行います。)
  • 属性
パラメータ タイプ 必須 説明
words string Yes カンマ区切りでマッチ対象文字列(単語列)を記載します。
  • 使用例

以下の使用例では、「東京」「神奈川」「千葉」「群馬」「埼玉」「栃木」のいずれかの単語とマッチするiset要素の記述例です。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>私は<iset words="東京, 神奈川, 千葉, 群馬, 埼玉, 栃木" />に住んでいます。</pattern>
        <template>
            私も関東に住んでいます。
        </template>
    </category>
</aiml>
Input: 私は東京に住んでいます。
Output: 私も関東に住んでいます。

関連項目: set

nlu

[custom]

nlu要素は、高度意図解釈エンジンによるユーザ発話文の意図解釈結果を用いて対話処理を行う場合に使用します。
属性、子要素の設定方法、高度意図解釈エンジンの利用方法などの詳細は、NLU を参照してください。
  • 属性
パラメータ タイプ 必須 説明
intent string Yes マッチさせるインテント名を指定します。大文字・小文字、全角・半角を区別します。
scoreGt string No マッチさせる信頼度を指定します。対象インテントの信頼度が指定した値より大きい場合にマッチします。
scoreGe string No マッチさせる信頼度を指定します。対象インテントの信頼度が指定した値以上の場合にマッチします。
score string No マッチさせる信頼度を指定します。対象インテントの信頼度が指定した値の時にマッチします。
scoreLe string No マッチさせる信頼度を指定します。対象インテントの信頼度が指定した値以下の場合にマッチします。
scoreLt string No マッチさせる信頼度を指定します。対象インテントの信頼度が指定した値より小さい場合にマッチします。
maxLikelihood string No truefalse を指定します。対象インテントの信頼度が最大尤度かどうかを指定します。 true の場合、対象インテントが最尤時のみマッチします。 false 場合、対象インテントがの信頼度が最尤候補でなくてもマッチします。未指定時は true として処理します。
指定可能なインテント名は、高度意図解釈エンジンが使用している意図解釈モデルを作成する学習データ内に記述したインテント名の範囲内に限定されます。
scoreXxは1つしか指定できません。複数記載した場合、scoreGt、scoreGe、score、scoreLe、scoreLtの順で採用します。(scoreGtとscoreが記載されていると、scoreGtが採用されます。)
  • 使用例

意図解釈モデルで周辺検索のインテント名が ‘aroundsearch’ と設定されている場合の例

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>
            <nlu intent="aroundsearch" />
        </pattern>
        <template>
            周辺検索を行います。
        </template>
    </category>
</aiml>
Input: この周辺を探して。
Output: 周辺検索を行います。

関連項目: NLU

oneormore

[1.0]

oneormore要素 “_”, “*”は、ワイルドカードの1つで、少なくとも1個の任意の単語とマッチします。 このワイルドカードが pattern要素内の記述の最後にある場合は、ユーザの発話文の終端までマッチ処理を行います。 また、このワイルドカードが pattern要素内の記述の他のAIMLパターンマッチング要素の間にある場合は、ワイルドカードの次のパターンマッチング要素のマッチ処理が行われるまでマッチ処理を行います。

このワイルドカードによるマッチ処理と他のAIMLパターンマッチング要素のマッチ処理の間にはマッチ処理が適用される優先順位があります。
ワイルドカード “_”は、 AIMLパターンマッチング要素 setisetregexbot よりも先にマッチ処理が行われます。ワイルドカード “*”は、これらのAIMLパターンマッチング要素よりも後にマッチ処理が行われます。
パターンマッチング処理の詳細は、 パターンマッチング を参照してください。

次の2つの使用例では、「こんにちは」1単語とその後に続く1個以上の単語とのマッチを評価します。

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは _</pattern>
        <template>
            こんにちは
        </template>
   </category>
</aiml>
Input: こんにちは いい天気ですね
Output: こんにちは
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
   <category>
       <pattern>こんにちは *</pattern>
       <template>
           ご機嫌いかがですか?
       </template>
   </category>
</aiml>
Input: こんにちは いい天気ですね
Output: ご機嫌いかがですか?

関連項目: zeroormoreパターンマッチング

priority

[1.0]

priority要素は、pattern要素内のマッチ対象単語の先頭に “$” を記述したもので、他のパターンのマッチ処理よりも、当該単語のマッチ処理を優先します。
以下の使用例では、”こんにちは * “、”こんにちは * ありがとう”等のワイルドカードを含む pattern要素が記述されている対話ルールがあっても、”$” を記述した単語 “今日” を優先してマッチします。
  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは $今日もいい天気ですね</pattern>
        <template>
            そうですね
        </template>
    </category>

    <category>
        <pattern>こんにちは *</pattern>
            <template>
                こんにちは
            </template>
        </category>

        <category>
            <pattern>こんにちは * ありがとう</pattern>
            <template>
                どういたしまして
            </template>
        </category>
</aiml>
Input: こんにちは 今日もいい天気ですね
Output: そうですね
Input: こんにちは 今日の天気はいまいちですね
Output: こんにちは
Input: こんにちは 今日は ありがとう
Output: どういたしまして

関連項目: wordパターンマッチング

regex

[custom]

regex要素の使用によりユーザ発話文に対する正規表現によるパターンマッチングができます。(統一コードではなく、大文字・小文字のみ同一視します。) 単語単位の正規表現への対応、文字列に関する正規表現にも対応します。

  • 属性
パラメータ タイプ 必須 説明
pattern string No 正規表現で単語を記述
template string No regex.txtファイルで定義した単語単位の正規表現を利用
form string No 複数の単語を含めた文字列を対象とした正規表現を記述
regex要素を記述する際には、pattern,template,formのいずれかの属性を指定することが必須になります。
正規表現として不正な値が指定された場合、シナリオ不正になります。
正規表現で省略可能指定(例:’(a)?’)のみを指定した場合、該当する場合でもアンマッチになることがあります。
  • 使用例

regex要素の属性は、3つの方法で正規表現を指定します。

1つ目は、patternに直接正規表現を記述する方法(単語単位)です。
「こんにちは」「こんにちわ」はいずれも分かち書き処理によって1単語として扱われる文字列なので、次の使用例でマッチします。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern><regex pattern="こんにち[は|わ]" /></pattern>
        <template>
            こんにちは
        </template>
    </category>
</aiml>
2つ目は、templateを利用する方法です。template属性に 正規表現リストファイル に記載したテンプレート名を指定します。
templateの記述内容は、patternと同じく単語単位です。
正規表現リストファイルで定義していないテンプレート名をtemplateで指定した場合、シナリオ不正になります。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern><regex template="konnichiwa" /></pattern>
        <template>
            こんにちは
        </template>
    </category>
</aiml>
3つ目は、formを利用する方法です。文字列を対象とした正規表現を指定します。
マッチ対象のユーザ発話文を文字列として扱うため、発話文が分かち書き処理によって1単語として扱われることはありません。
日本語文字列が分かち書き処理によりどのような単語に分割されるかに左右されずに正規表現でマッチするための機能です。
formに指定する正規表現は、以下の組み合わせになります。
表記 意味
‘[…]’ ‘[…]’内のいずれかの文字にマッチすればOK。
‘A|B’ ‘|’の左右の文字列のいずれかにマッチすればOK。
‘(X)’ 正規表現Xのサブパターン化。XにマッチすればOK。
‘()?’ ‘?’の直前のサブパターンにマッチしてもしなくてもOK。
‘(?!X)’ 最後尾がXにマッチしなければOK。(他の指定との併用は不可)

次の使用例では、以下の文のいずれにもマッチします。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>
            <regex form="今[はわ]何時(ですか|です)?" />
        </pattern>
        <template>
            <date format="%H時%M分%S秒" />
        </template>
    </category>
</aiml>

「今は何時」「今は何時ですか」「今は何時です」 「今わ何時」「今わ何時ですか」「今わ何時です」

関連項目: ファイル管理:regex_templates

set

[1.0]

set要素では、外部ファイルで指定した複数の単語列のいずれかとのマッチ処理を指定します。マッチングは、統一コードで行います。
マッチ対象の単語は、、単語リストファイル(sets) にリスト形式で列記します。
要素として、複数英単語からなる文字列も指定が可能ですが、その場合、単語数が多いものが優先してマッチします。
尚、英単語列と日本語文字列が混在する指定の場合の動作は保証できません。(日本語文字列の場合、間の空白は除外してマッチングを行います。)
  • 属性
パラメータ タイプ 必須 説明
name string Yes setsファイル名から拡張子を除いた文字列。
無効なファイルの名称をnameで指定した場合、シナリオ不正になります。
また、コンフィグレーションの dynamic で定義されている名称については、dynamic が優先されるため無効になります。
  • 使用例

以下の例では、prefecture.txtに日本の都道府県名が記載されていることを想定しています。

 <?xml version="1.0" encoding="UTF-8"?>
 <aiml version="2.0">
     <category>
         <pattern>私は<set name="prefecture" />に住んでいます。</pattern>
         <template>
             私は東京に住んでいます。
         </template>
     </category>
</aiml>
Input: 私は千葉に住んでいます。
Output: 私は東京に住んでいます。

関連項目: isetファイル管理:sets

topic

[1.0]

topic要素を使用すると、システムの予約変数topicの値がnameに指定した値と一致することを条件に追加することができます。マッチングは、統一コードで行います。
topicは、次のようにtemplate要素のsetを用いて値を設定することができます。
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern><!-- pattern description goes here --></pattern>
        <template>
            <think><set name="topic">FISHING</set></think>
            <!-- response sentence goes here-->
        </template>
    </category>
</aiml>
topic要素の条件は、patternのマッチ処理後に評価されます(AIML処理の基本ルール)。同一のpattern定義でtopic指定がないものがあると、どちらにマッチするかは規定できません。
同一のpattern定義でtopic指定がないものが必要な場合は、現在設定されているtopicの値による条件分岐(condition)で、応答文を変化させる方式を推奨します。

以下の使用例では、”なぜそれを知っていますか?”というユーザ発話に対して、それより前の対話でtopicの値が”FISHING”か”COOKING”のどちらに設定されているかで、応答文が変ります。

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>なぜそれを知っていますか?</pattern>
        <topic>FISHING</topic>
        <template>
            子供の頃、父が教えてくれました。
        </template>
    </category>

    <category>
        <pattern>なぜそれを知っていますか?</pattern>
        <topic>COOKING</topic>
        <template>
            子供の頃、母が教えてくれました。
        </template>
    </category>
</aiml>

関連項目: that, set(template要素), think

that

[1.0]

that要素を用いることで、1つ前の対話におけるシステムの応答文が指定した文字列とマッチすることを条件に追加することができます。マッチングは、統一コードで行います。
that要素のこの働きにより、対話内容の流れを考慮した対話ルール記述が可能になります。
例えば、”はい”、”いいえ” といった、汎用的なユーザ発話文に対するシステム応答文を、直前の対話内容によって場合分けすることができます。
that要素の条件は、patternのマッチ処理後に評価されます(AIML処理の基本ルール)。同一のpattern定義でthat指定がないものがあると、どちらにマッチするかは規定できません。
同一のpattern定義でthat指定がないものが必要な場合は、templateのthat要素で取得した値による条件分岐(condition)で、応答文を変化させる方式を推奨します。
  • 使用例

以下の使用例では、直前の対話のシステム応答文が「コーヒーに砂糖とミルクを入れますか」か「紅茶にレモンを入れますか」かで、ユーザ発話文の「はい」、「いいえ」にマッチする対話ルールを場合分けして、直前の対話内容に整合するシステム応答文が返されるようにしています。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>私はコーヒーが好きです</pattern>
        <template>コーヒーに砂糖とミルクを入れますか</template>
    </category>

        <category>
        <pattern>私は紅茶が好きです</pattern>
        <template>紅茶にレモンを入れますか</template>
    </category>

    <category>
        <pattern>はい</pattern>
        <that>コーヒーに砂糖とミルクを入れますか</that>
        <template>わかりました</template>
    </category>

    <category>
        <pattern>いいえ</pattern>
        <that>コーヒーに砂糖とミルクを入れますか</that>
        <template>ブラックですね</template>
    </category>

    <category>
        <pattern>はい</pattern>
        <that>紅茶にレモンを入れますか</that>
        <template>わかりました</template>
    </category>

    <category>
        <pattern>いいえ</pattern>
        <that>紅茶にレモンを入れますか</that>
        <template>ストレートティーですね</template>
    </category>
</aiml>

関連項目: topic

word

[1.0]

AIMLの最も基本的なパターンマッチング要素です。 word要素は、単語(分かち書きされた各文字列の単位)を表しており、対話エンジン内部で利用する要素でシナリオでの記述はできません。 英単語においては大文字と小文字を区別せずマッチ処理を行います。 また、全角文字・半角文字については、英数字は半角、カナ文字は全角でマッチ処理を行います。

以下の使用例ではHELLO, hello, Hello, HeLlOのどれでもマッチします。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>HELLO</pattern>
        <template>
            こんにちは
        </template>
    </category>
</aiml>

関連項目: priority

zeroormore

[1.0]

zeroormore要素 “^”, “#” は、ワイルドカードの1つで、少なくとも0個の任意の単語とマッチします。 このワイルドカードが pattern要素内の記述の最後にある場合は、ユーザの発話文の終端までマッチ処理を行います。 また、このワイルドカードが pattern要素内の記述の他のAIMLパターンマッチング要素の間にある場合は、ワイルドカードの次のパターンマッチング要素のマッチ処理が行われるまでマッチ処理を行います。

このワイルドカードによるマッチ処理と他のAIMLパターンマッチング要素のマッチ処理の間にはマッチ処理が適用される優先順位があります。
ワイルドカード “^”は、 AIMLパターンマッチング要素 setisetregexbot よりも先にマッチ処理が行われます。ワイルドカード “#”は、これらのAIMLパターンマッチング要素よりも後にマッチ処理が行われます。

ワイルドカードを連続して記述したpattern要素を指定する場合には、oneormore との混合は避けてください。入力文の該当する範囲の単語数により、star要素での対象単語取得時に誤動作が発生する場合があります。

次の使用例では、「こんにちは」のみ、あるいは、「こんにちは」で始まり1つ以上の単語が続く文にマッチします。

詳細は、パターンマッチング を参照してください。

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>こんにちは ^</pattern>
        <template>
            こんにちは
        </template>
    </category>

    <category>
        <pattern>こんにちは #</pattern>
        <template>
            ご機嫌いかがですか?
        </template>
    </category>
</aiml>

関連項目: oneormoreパターンマッチング

template要素内の子要素

本章ではtemplate要素内で記述可能な子要素について説明します。
子要素の使用可否については、カスタマイズが可能です。詳細は カスタムtemplate要素 を参照してください。
対話プラットフォームでサポートしているtemplateの要素内に記述可能な子要素のリストは以下のとおりです。
公式の AIML 2.x仕様に対し、独自の要素セットを追加しています。
  • addtriple: RDFナレッジベースへのエレメント追加要素
  • authorise: ユーザロールによりAIML要素の実行権の切り替え要素
  • bot: bot固有のプロパティの取得要素
  • button: ボタン押下を促す要素
  • card: 画像、ボタン、タイトル、サブタイトルを1つにまとめる要素
  • carousel: カード要素をまとめる要素
  • condition: 条件分岐して処理を行う要素
  • date: 日付、時刻取得要素
  • delay: 遅延要求設定要素
  • deletetriple: RDFナレッジベースからのエレメント削除要素
  • denormalize: 単語から文字列への変換要素
  • eval: 変数値の文字列化要素(learn/learnfで利用)
  • explode: 文字分割要素
  • first: 先頭単語取得要素
  • extension:拡張機能要素
  • formal: 先頭文字大文字化要素
  • gender: 三人称代名詞の性別変換要素
  • get: 変数内容取得要素
  • id: クライアント名取得要素
  • image: 画像情報指定要素
  • implode: 文字列結合要素
  • input: pattern文取得要素
  • interval: 時刻差分計算要素
  • json: JSON要素
  • learn: ユーザ固有category登録要素
  • learnf: ユーザ固有category登録要素
  • li: 分岐条件記述要素
  • link: URL情報指定要素
  • list: リスト形式情報指定要素
  • log: ログ出力要素
  • lowercase: 英文字小文字化要素
  • map: 辞書利用の変換要素
  • nluintent: NLUインテント取得要素
  • nluslot: NLUスロット取得要素
  • normalize: 文字列から単語への変換要素
  • oob: Out of Band要素
  • olist: オーダーリスト形式指定要素
  • person: 一・二人称代名詞変換要素
  • person2: 一・二人称代名詞と三人称代名詞の変換要素
  • program: プログラムバージョン取得要素
  • random: ランダム分岐指定要素
  • reply: ユーザへの提示内容指定要素
  • request: 入力履歴取得要素
  • resetlearn: learn情報リセット要素
  • resetlearnf: learnf情報リセット要素
  • response: 出力履歴取得要素
  • rest: 先頭単語以外の取得要素
  • set: 変数設定要素
  • select: RDFナレッジベースの検索要素
  • sentence: 英文整形要素
  • size: カテゴリ数取得要素
  • space: 半角スペース挿入要素
  • split: 文章分割要素
  • sr: sraiとstarの省略要素
  • srai: パターンマッチ再実行要素
  • sraix: REST API呼び出し要素
  • star: ワイルドカード取得要素
  • system: システムコール実行要素
  • that: 過去応答文取得要素
  • thatstar: 過去応答文内ワイルドカード取得要素
  • think: 内部処理記述要素
  • topicstar: topic内ワイルドカード取得要素
  • uniq: RDFナレッジベースの検索要素
  • uppercase: 英文字大文字化要素
  • video: ビデオ情報指定要素
  • vocabulary: シナリオ単語数取得要素
  • word: 単語ノードを示す定義
  • xml: 未定義XMLノードの定義
尚、templateの子要素は、配下に上記の子要素を記述することで複合的に各種の処理を行うことができます。(一部、配下に子要素を指定できないものもあります。)
本章の各子要素の説明で記述する指定可能な子要素の項目は、親となる子要素の配下で特有の処理を行うもののみを記述しています。

以下の要素は処理結果が空文字の為、単体で使用した場合にはアンマッチと同じ結果になります。他の要素や任意の文字列と併せて使用することを推奨します。

  • addtriple
  • deletetriple
  • json (取得の場合を除く)
  • learn
  • learnf
  • resetlearn
  • resetlearnf
  • think

詳細

このセクションでは、AIMLのtemplate要素内に記述する要素の説明を行います。
ほとんどの要素はXMLの属性または子要素を追加して、データを利用します。
各要素の先頭の[…]は、対象の要素が最初に定義されたAIMLのバージョンを示しています。

addtriple

[2.0]

addtriple要素は、RDFナレッジベースにエレメント(知識)を追加します。 エレメントの構成要素には、subject (主語)、predicate (述語)、object (目的語)の3つのアイテムがあります。

addtriple要素の結果文字列は、常に空文字になります。
addtriple要素の詳細については、RDFサポート を参照してください。
  • 子要素
パラメータ タイプ 必須 説明
subj string Yes subject (主語)の値
pred string Yes predicate (述語)の値
obj string Yes object (目的語)の値
指定された値は検索を効率的に行う為、統一コード(英数記号:半角、カタカナ:全角)に変換して格納されます。
値に空文字(空白のみを含む)を指定した場合、実行時に例外が発生します。(シナリオ展開時に検出した場合、該当シナリオは無効になります。)

以下の使用例では、ユーザの発話文「私はカレーが好きだ」に対して、subject=’私’、pred=’好き’, object=’カレー’ のアイテムで構成されるエレメント(知識)をRDFナレッジベースに登録します。

  • 使用例
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>* は * が 好き #</pattern>
        <template>
            <addtriple>
                <subj><star /></subj>
                <pred>好き</pred>
                <obj><star index="2"/></obj>
            </addtriple>
            好みを登録しました
        </template>
    </category>
</aiml>
Input: 私 は カレー が好きだ
Output: 好みを登録しました

登録を行った結果の確認方法は、uniq, select を参照してください。

関連項目: deletetriple, select, uniq, RDFサポート

authorise

[1.0]

authorise要素を使うことにより、template要素内に記述されるAIML要素を実行するかどうかを、ユーザの権限によって切り替えることができます。
ユーザとしてauthorise要素のrole属性で指定された権限が無い場合、authorise要素内に記述したAIML要素は実行されません。
詳細は Securityの 承認 を参照してください。
  • 属性
パラメータ タイプ 必須 説明
role string Yes ロール名。ユーザグループファイル で規定
denied_srai string No 認証失敗時のsrai用発話文

ユーザグループファイル で規定されていない”ロール名”を指定した場合、全ユーザが権限なしとして扱われます。

  • 使用例

この使用例では、ユーザの権限に”root”がある場合のみ、vocabularyの内容を返せます。 ユーザに権限がない場合、コンフィグレーションで定義された、denied_srai(又は、denied_text)が実行されます。

<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>ボキャブラリリスト数</pattern>
        <template>
            <authorise role="root">
                <vocabulary />
            </authorise>
        </template>
    </category>
</aiml>
また、denied_srai属性を指定することで、ユーザに権限が無い場合のデフォルト動作を決めることができます。
(denied_sraiの値をpattern要素に定義したシナリオが必要になります。)
<?xml version="1.0" encoding="UTF-8"?>
<aiml version="2.0">
    <category>
        <pattern>ボキャブラリリスト数</pattern>
            <template>
                <authorise role="root" denied_srai="ACCESS_DENIED">
                    <vocabulary />
                </authorise>
            </template>
    </category>
</aiml>

関連項目: 承認

bot

[1.0]

bot要素は、bot固有のプロパティを取得します。この要素は読み込み専用です。 プロパティは、propertiesファイル で規定することで、任意の情報を固定値として登録することができます。

  • 属性 (子要素での指定も可能)
パラメータ タイプ 必須 説明
name string Yes propertiesファイルで規定した、プロパティ名を指定
プロパティ名は変数名と同じ位置づけになる為、大文字・小文字、全角・半角を区別します。
プロパティには、任意の固有値以外に、コンフィグレーション定義を置換するパラメータとしても使用します。
  • 使用例

プロパティとして、name、birthdate、app_version、grammar_versionが登録されている前提です。

 <category>
    <pattern>あなたは誰?</pattern>
    <template>
        私の名前は<bot name="name" />です。
        <bot name="birthdate" />生まれです。
        アプリケーションバージョンは<bot name="app_version" />です。
        グラマーバージョンは<bot name="grammar_version" />です。
    </template>
</category>

name属性に、登録されてないプロパティ名を指定した場合、シナリオ展開時に異常を検出し、該当シナリオは無効になります。

botの子要素としてnameを利用することで、name属性と同じ内容を記載することができます。

<category>
    <pattern>あなたは誰ですか?</pattern>
    <template>
        私の名前は<bot><name>name</name></bot>です。
        <bot><name>birthdate</name></bot>生まれです。
        アプリケーションバージョンは<bot><name>app_version</name></bot>です。
        グラマーバージョンは<bot><name>grammar_version</name></bot>です。
    </template>
</category>

子要素のnameに、登録されてないプロパティ名を指定した場合、実行時に取得失敗となり、コンフィグレーション定義の default-property の定義値が返ります。 (default-propertyが定義されていない場合、default-getの定義値が返ります。)

尚、properties_jsonエンティティ を利用して、プロパティの値にJSON形式を指定した場合、取得されるデータはファイルの内容そのものではなく、JSONデータとして変換された文字列が設定されます。
properties_jsonエンティティ に、以下のJSONファイルを ‘test_json.json’ として配置した場合、
{
  "key1": "value1",
  "key2":
    {
      "key2_1": "value2_1"
    }
}

<bot name="test_json" /> で取得される値は、以下に様に編集された文字列になります。

{"key1": "value1", "key2": {"key2_1": "value2_1"}}

関連項目: ファイル管理:properties

button

[2.1]

button要素は、会話中にユーザにタップを促す用途で利用されるリッチメディア要素です。 子要素として、buttonの表記に使用するテキスト、Botに対するpostback、ボタン押下時のURLを記載できます。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素 (属性での指定も可能)
パラメータ タイプ 必須 説明
text string Yes ボタンに表示するテキストを記載します。(空文字を許容します。)
postback string No ボタン押下時の動作を記載します。ユーザにはこのメッセージは見せず、Botに対するレスポンスやアプリケーションで処理を行う場合に利用します。
url string No ボタン押下時のURLを記載します。
  • 使用例
<category>
    <pattern>乗り換え</pattern>
    <template>
         <button>
             <text>乗り換え検索しますか?</text>
             <postback>乗り換え案内</postback>
         </button>
    </template>
 </category>

<category>
    <pattern>検索</pattern>
    <template>
         <button>
             <text>検索しますか?</text>
             <url>https://searchsite.com</url>
         </button>
    </template>
 </category>

card

[2.1]

card要素はリッチメディア要素で、画像、ボタン、タイトル、サブタイトルなど、いくつかの他の要素を使用し1つのカードとします。 これらのリッチメディア要素すべてを含むメニューが表示されます。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素 (属性での指定も可能)
パラメータ タイプ 必須 説明
title string Yes カードのタイトルを記載します。(空文字を許容します。)
subtitle string No カードに対する追加情報を記載します。
image string Yes カード用の画像URL等を記載します。(空文字を許容します。)
button string Yes カード用のボタン情報を記載します。
  • 使用例
<category>
    <pattern>検索</pattern>
    <template>
        <card>
            <title>カードメニュー</title>
            <subtitle>カードメニュー詳細情報</subtitle>
            <image>https://searchsite.com/image.png</image>
            <button>
                <text>検索しますか?</text>
                <url>https://searchsite.com</url>
            </button>
        </card>
    </template>
</category>

関連項目: button, image

condition

[1.0]

condition要素は、template内での条件判断を行う際に使用し、switch-caseのような処理を記載できます。
conditionの属性・子要素で指定した変数と判定値の組み合わせで条件判定を行い、li 子要素を使用することで複数の条件を列記することができます。
対象変数には、get/setで定義したグローバル変数、ローカル変数とともに、Bot固有情報(プロパティ)も指定できます。
  • 属性
パラメータ タイプ 必須 説明
name 変数名 No 分岐条件とするグローバル変数(name)名を指定します。
var 変数名 No 分岐条件とするローカル変数(var)名を指定します。
data 変数名 No 分岐条件とするグローバル変数(data)名を指定します。
bot プロパティ名 No 分岐条件とするBot固有情報(プロパティ)名を指定します。
value 判定値 No 分岐条件となる値を指定します。(大文字・小文字、全角・半角を区別します)
regex 判定値 No 分岐条件となる値を正規表現で指定します。判定は完全一致(大文字・小文字は同一視)で行います。
  • 子要素
パラメータ タイプ 必須 説明
li string No 指定した変数に対する分岐条件を記載します。

 属性の各パラメータも子要素として指定できます。

condition要素には、変数と判定値の記載方法により、次の3つの処理方式があります。

  • 単一判定: li 子要素を使用せずに、1つの変数と判定値の組み合わせを指定します。
  • 条件分岐: condition として対象とする1つの変数を規定し、li 子要素毎に判定値を指定することで、複数の条件に対応します。
  • 複数条件での分岐: li 子要素毎に変数と判定値の組み合わせを指定することで、複数の条件に対応します。
この3つの処理方式とは異なる記載方法の場合には、シナリオ展開時に異常となり、該当シナリオは無効になります。
(不正例:変数と判定値の組み合わせが成立しない場合や、’condition’要素に変数を指定した状態で、’li’要素にも変数を指定した場合等。)

以下に、各方式でのconditionの記載方法を説明します。

単一判定
condition要素として、1つの変数と判定値の組み合わせを指定する方式です。
この記載方法は、変数値の判定結果がtrueの場合に要素の文字列を返し、falseの場合は何も実行しません。
以下の使用例の様に4種類の記載方法があり、いずれも同じ動作を示しています。
  • 使用例
<condition name="ペット" value="犬">私も犬派です</condition>
<condition name="ペット"><value></value>私も犬派です</condition>
<condition value="犬"><name>ペット</name>私も犬派です</condition>
<condition><name>ペット</name><value></value>私も犬派です</condition>

name変数:”ペット”の値が”犬”であった場合、”私も犬派です”を返します。

条件分岐
condition の属性・子要素で1つの変数を設定し、 li 子要素で対象となる値に対する分岐を記述します。分岐方法はswitch-caseに似ています。
condition の変数の内容を li 子要素の判定値と比較し、trueになった条件の内容を返します。
分岐条件に合致しない場合、判定値が指定されていない li 子要素の内容を返します。判定値が指定されていない li 子要素がない場合は、何も返しません。

以下の使用例では、name変数:”ペット”の値を評価します。評価の優先順序は記載順になります。

  • 使用例
<condition name="ペット">
    <li value="犬">私も犬派です</li>
    <li value="猫">猫が一番好きです</li>
    <li>ペットは飼ってないです</li>
</condition>

<condition>
    <name>ペット</name>
    <li value="犬">私も犬派です</li>
    <li value="猫">猫が一番好きです</li>
    <li>ペットは飼ってないです</li>
</condition>
複数条件での分岐
li 子要素毎に条件分岐を指定する場合の記載方法で、分岐方法はif文の集合体に似ています。
li 子要素で定義された各条件が順次チェックされます。各``li`` 子要素では異なる変数、判定値を持つことができます。
条件がtrueになるとその時点で評価が完了し、該当する li 子要素の内容を返します。

以下の使用例では、name変数:”ペット”と、name変数:”飲み物”の値を評価します。評価の優先順序は記載順になります。

  • 使用例
<condition>
    <li name="ペット" value="犬">私も犬派です</li>
    <li value="猫"><name>ペット</name>猫が一番好きです</li>
    <li name="飲み物"><value>コーヒー</value>マンデリンがいいです</li>
    <li><name>飲み物</name><value>紅茶</value>アールグレイが好きです</li>
    <li>好きなものはありますか</li>
</condition>
ループ処理
条件によりcondition処理を繰り返す場合、<loop />li の子要素として記載します。
通常<li>で分岐した場合、処理内容を<template>として返しますが、’<loop />’がある場合、対象となる<li>に分岐し、<li>の処理を終えた後、<condition>の内容を再評価します。
尚、1つのcondition要素内で実施できるループ処理の回数は、コンフィグレーション定義の 制限値定義max_search_condition までとなります。
制限数を超えてループ処理を行った場合、処理例外が発生します。

以下の使用例では、変数”話題”を評価して返す内容を決定しますが、分岐条件に一致しなかった場合、”話題”に”雑談”を設定して<condition>の再評価を行い、”雑談”としてループを抜けます。

  • 使用例
<condition var="話題">
    <li value="花">花は何が好きですか</li>
    <li value="飲み物">コーヒーはどうですか</li>
    <li value="雑談">何かいいことありました?</li>
    <li><think><set var="話題">雑談</set></think><loop /></li>
</condition>

関連項目: li, get, set, bot

date

[1.0]

date要素は、日付と時刻の文字列を取得します。基準値はシステムの現在日時ですが、対話API で、locale/timeが指定されている場合、返す内容は次の様に変化します。

  • localeを指定: 国コードを元に、該当する地域の日時への換算を行います。(国コードに対して地域が確定できない場合は変換を行いません。)
  • timeを指定: 指定された日時を基準値として処理します。

日付・時刻の出力形式の指定には、Pythonの日時文字列の書式を使用します。 詳細は Pythonのマニュアル(datetime)を参照してください。

  • 属性 (子要素での指定も可能)
パラメータ タイプ 必須 説明
format string No 出力形式指定。未指定時は ‘%c’

formatの指定が不正な場合には、結果にはformatで指定された文字列がそのまま返ります。

  • 使用例
<category>
    <pattern>今日は何日ですか</pattern>
    <template>
        今日は<date format="%Y/%m/%d" />です。
    </template>
</category>

<category>
    <pattern>今日は何日ですか</pattern>
    <template>
        今日は<date><format>%Y/%m/%d</format></date>です。
    </template>
</category>

関連項目: interval

delay

[2.1]

delay要素はリッチメディア要素で、遅延を行う要素です。 音声合成の再生中などの待ち時間の定義を行ったり、ユーザに対するBotの返答遅延を指定したりするために利用します。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素 (属性での指定も可能)
パラメータ タイプ 必須 説明
seconds string(数値) Yes 遅延秒数を指定。

secondsに数値以外を指定した場合、属性指定では該当シナリオが無効になり、子要素指定の場合は “0” が設定されます。

  • 使用例
<category>
    <pattern>* 秒待って</pattern>
    <template>
         <delay>
             <seconds><star/></seconds>
         </delay>
     </template>
 </category>

deletetriple

[2.0]

deletetriple要素は、RDFナレッジベースからエレメントを削除します。
指定できるエレメントは起動時にRDFファイルから読み込まれたエレメント、もしくは addtriple で追加されたエレメントです。
deletetriple要素の結果文字列は、常に空文字になります。
詳細は、RDFサポート を参照してください。
  • 子要素
パラメータ タイプ 必須 説明
subj string Yes 削除対象のsubject (主語)の値
pred string No 削除対象のpredicate (述語)の値
obj string No 削除対象のobject (目的語)の値
指定された値は統一コード(英数記号:半角、カタカナ:全角)に変換して、削除処理に使用します。
obj指定を省略した場合、subjとpredが一致するものが削除され、pred/objの指定を省略した場合、subj以下の全てが削除されます。
  • 使用例
<category>
    <pattern>*  * を削除</pattern>
    <template>
        <deletetriple>
            <subj><star /></subj>
            <pred></pred>
            <obj><star index="2"/></obj>
        </deletetriple>
        削除しました
    </template>
</category>

関連項目: addtriple, select, uniq, RDFサポート

denormalize

[1.0]

normalize要素が対象文字列に含まれる記号や短縮形の文字列を単語に変換するのに対して、denormalize要素は逆の動作を行います。
変換内容は、denormalファイル で指定し、大文字・小文字、全角・半角を区別して変換を行います。
例えば、’www.***.com’に対して、normalizeで’.’を’dot’、’*’を’_’に変換した場合、’www dot _ _ _ dot com ‘になりますが、
denormalizeで’dot’を’.’、’_’を’*’に変換するように指定した場合、normalize/denormalizeで、’www.***.com’に復元されます。
英文の場合、normalizeの変換結果には必ず前後に空白が挿入されている為、denormalizeの指定では、前後に空白を挿入するか否かを含めて指定する必要があります。
  • 使用例
<category>
    <pattern>URLは * です。</pattern>
    <template>
        <think>
            <set var="url"><normalize><star /></normalize></set>
        </think>
        <denormalize><get var="url" /></denormalize>を復元します。
    </template>
</category>
Input: URLはwww.***.comです。
Output: www.***.comを復元します。

<denormalize />は<denormalize><star /></denormalize>と同義です。

  • 使用例
<category>
    <pattern>URLは *です。</pattern>
    <template>
         <denormalize />に変換します。
    </template>
</category>
Input: URLは___です。
Output: ***に変換します。

関連項目: ファイル管理:denormal, normalize

eval

[1.0]

eval要素は、learnlearnf 要素の一部として利用されます。 eval要素は、内容をテキスト化した値を返します。

eval要素の内容にget要素等を記載してその値の取得に失敗した場合、default-get の値が設定されます。

次の例では、eval指定により、name型変数’name’の値:’マロン’と、name型変数’animal’の値:’犬’が文字列として設定されたcategoryが生成されます。 その後このlearnfノードに合致する、’マロンは誰ですか’という入力を行うと、’あなたのペットの犬です。’と返します。

  • 使用例
<category>
    <pattern>私のペットは * の * です。</pattern>
    <template>
        あなたのペットは、<star />の<star index="2" />ですね。
        <think>
            <set name="animal"><star /></set>
            <set name="name"><star index="2" /></set>
        </think>
        <learnf>
            <category>
                <pattern>
                    <eval>
                        <get name="name"/>
                    </eval>
                    は誰ですか。
                </pattern>
                <template>
                    あなたのペットの
                    <eval>
                        <get name="animal"/>
                    </eval>
                    です。
                </template>
            </category>
        </learnf>
    </template>
</category>
Input: 私のペットは犬のマロンです。
Output: あなたのペットは犬のマロンですね。
Input: マロンは誰ですか。
Output: あなたのペットの犬です。

関連項目: learn, learnf

explode

[1.0]

explode要素は、対象文字列を1文字単位に分割し、半角スペースで区切ります。 ’coffee’と入力した場合、explodeを有効にすると、’c o f f e e’に変換します。

  • 使用例
<category>
    <pattern>EXPLODE *</pattern>
    <template>
        <explode><star /></explode>
    </template>
</category>

<explode />は、<explode><star /></explode>と同義です。書き換えると以下の様になります。

<category>
    <pattern>EXPLODE *</pattern>
    <template>
        <explode />
    </template>
</category>
Input: EXPLODE coffee
Output: c o f f e e

関連項目: implode

image

[2.1]

image要素はリッチメディア要素で、画像の情報を返すことができます。 内容に、画像URLやファイル名を指定します。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

<category>
    <pattern>画像表示</pattern>
    <template>
        <image>https://url.for.image</image>
    </template>
</category>

first

[1.0]

first要素は、複数単語からなる文字列に対して、先頭の単語を返します。単単語の場合は、そのまま返ります。
(文字列の単語分割時には、 punctuation_chars の指定による特定文字除外の処理を行います。)
取得に失敗した場合は、コンフィグレーション定義の default-get の値が返ります。
  • 使用例
<category>
    <pattern>私の名前は * です </pattern>
    <template>
        あなたの名前は <first><star /></first> さんですね。
    </template>
</category>
Input: 私の名前は 山田 太郎 です
Output: あなたの名前は山田さんですね
RDFナレッジベースの検索結果に適用した場合、結果リスト内の先頭データを取得します。 詳細は、RDFサポート を参照してください。
JSON形式のデータには対応していません。

関連項目: rest

extension

[custom]

extension要素は、対話エンジンのカスタマイズを必要とする要素になります。
extension要素では、Pythonの処理クラスを呼び出す機能を提供し、 programy.extensions.base.Extension インタフェースを実装するPythonモジュールクラスへのフルパスを指定します。
extension要素の内容が処理クラスに対する引数(文字列)として、引き渡されます。

詳細は、 Extensions を参照してください。

  • 属性
パラメータ タイプ 必須 説明
path string Yes extension処理クラスのパス名
  • 使用例
<category>
    <pattern>
        GEOCODE *
    </pattern>
    <template>
         <extension path="programy.extensions.goecode.geocode.GeoCodeExtension">
             <star />
         </extension>
    </template>
</category>

関連項目: Extensions

formal

[1.0]

formal要素は、対象文字列内の単語の先頭文字を大文字に変換します。
JSON形式やリスト形式のデータに適用した場合、各要素毎に処理が行われます。
  • 使用例
<category>
    <pattern>私の名前は * * </pattern>
    <template>
     <formal><star /></formal> <formal><star index="2"/></formal>さん、こんにちは
    </template>
</category>

<formal />は<formal><star /></formal> と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>私の名前は * * </pattern>
    <template>
        <formal /><formal><star index="2"/></formal>さん、こんにちは
    </template>
</category>
Input: 私の名前は george washington
Output: George Washington さん、こんにちは

gender

[1.0]

gender要素は、発話文に含まれる性別を表す人称代名詞等を対象に、逆の性別の単語に変換することを目的としています。
変換内容は、genderファイル で指定します。
変換方法の指定には変換前と変換後のセットで記載し、genderのセット内に一致するものがある場合にのみ変換が行われます。複数単語に対する指定も可能です。
変換対象の判定は、英数記号:半角、カタカナ:全角に変換した上で行いますが、変換結果はgenderファイルの値になります。
  • 使用例
<category>
    <pattern>* に会いましたか?</pattern>
    <template>
        いえ、 <gender><star/></gender> に会いました。
    </template>
</category>
Input: 彼に会いましたか?
Output: いえ、彼女に会いました。

関連項目: ファイル管理:gender

get

[1.0]

get要素は、変数の値取得に用います。取得に失敗した場合、コンフィグレーション定義の default-get の値が返ります。
propertiesファイル での “default-get” 定義が優先されます。)
getで取得できる値は、set を使って、対話処理実施時に値の設定を行います。
起動時に初期値を設定する場合、defaultsファイル に記載することで、グローバル変数(name)として利用することができます。
変数種別には3種類あり、ローカル変数と保持期間が異なるグローバル変数が2種類あります。
  • ローカル変数(var)
“var”属性を指定することで、ローカル変数扱いになります。
ローカル変数は、set/getが記載されているcategoryの範囲のみ保持されます。したがって、sraiの参照先では別変数扱いになります。
  • 継続保持グローバル変数(name)
“name”属性を指定することで、グローバル変数扱いになります。グローバル変数は別categoryで設定した内容も参照することができます。
また、グローバル変数の内容は継続的に保持しており、対話処理を繰り返し実施した場合でも内容を保持しています。
  • 指定範囲保持グローバル変数(data)
“data”属性を指定することで、グローバル変数扱いになります。nameとの差異は、対話APIのdeleteVariableにtrueが設定された時点でdataで定義した変数がクリアされる点です。
  • 属性
パラメータ タイプ 必須 説明
name 変数名 No グローバル変数(name)名を指定
var 変数名 No ローカル変数(var)名を指定
data 変数名 No グローバル変数(data)名を指定
AIMLの変数を値として指定する場合に属性では指定できないため、子要素としても指定できるようにしています。動作は属性と同じになります。
また、子要素 tuple を指定することで、RDFナレッジベースのエレメントも取得できます。詳細は、RDFサポート を参照してください。
  • 子要素
パラメータ タイプ 必須 説明
name 変数名 No グローバル変数(name)名を指定
var 変数名 No ローカル変数(var)名を指定
data 変数名 No グローバル変数(data)名を指定
tuple 子要素 No RDFナレッジベースのエレメントを処理する場合に指定
get要素として、属性・子要素で、var, name, data, tuple のいずれかが設定されている必要があります。
複数の属性、子要素を指定した場合には、不正指定としてシナリオは無効になります。
尚、変数名は、大文字・小文字、全角・半角を区別して管理します。
  • 使用例
<!-- Access Global Variable -->
<category>
    <pattern>今日は * です</pattern>
    <template>
        <think><set name="weather"><star/></set></think>
         今日の天気は、<get name="weather" />です。
    </template>
</category>

<!-- Access Local Variable -->
<category>
    <pattern>明日は * です</pattern>
    <template>
        <think><set var="weather"><star/></set></think>
         今日の天気は<get name="weather" />,明日の天気は<get var="weather"/>です。
    </template>
</category>
<category>
    <pattern>天気は?</pattern>
    <template>
         今日の天気は<get name="weather" />,明日の天気は<get var="weather"/>です。
    </template>
</category>
Input: 今日は晴れです。
Output: 今日の天気は晴れです。
Input: 明日は雨です。
Output: 今日の天気は晴れ,明日の天気は雨です。
Input: 天気は?
Output: 今日の天気は晴れ,明日の天気はunknownです。

コンフィグレーションの dynamicvariables が定義されている場合、グローバル変数(name)名として dynamic の定義が優先されます。

関連項目: set, ファイル管理:properties

id

[1.0]

id要素は、クライアント名を返します。クライアント名はクライアント開発者が コンフィグファイル のclient定義で指定します。
id要素には、属性・子要素は指定できません。
  • 使用例
<category>
    <pattern>あなたの名前は?</pattern>
    <template>
        <id />
    </template>
</category>
Input: あなたの名前は?
Output: console

implode

[custom]

implode要素は、対象文字列内にある半角スペースを削除し、1単語に結合します。
‘c o f f e e’と入力した場合、implodeを実施すると、’coffee’に変換します。
  • 使用例
<category>
    <pattern>Implode *</pattern>
    <template>
        <implode><star /></implode>
    </template>
</category>

<implode />は、<implode><star /></implode>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>Implode *</pattern>
    <template>
        <implode />
    </template>
</category>
Input: Implode c o f f e e
Output: coffee

関連項目: explode

input

[1.0]

input要素は、入力された発話文に対してマッチ処理用に編集した文字列(対話処理の対象となる文章)を返します。
編集処理では、英数記号の半角化とカタカナの全角化、マッチ処理対象外文字の除去、及び、単語分解と再結合が行われ、発話文が再構成されます。
input要素は、pattern内のワイルドカード <star/> とは異なり、発話文全体の範囲を返します。
  • 使用例
<category>
    <pattern>質問はなんですか?</pattern>
    <template>
        あなたの質問は、"<input />"です。
    </template>
</category>
Input: 質問はなんですか?
Output: あなたの質問は、”質問はなんですか?”です。

interval

[1.0]

interval要素は、2つの日時の差分を計算します。(マイナスの差分にも対応します。)
日時の形式指定には、Pythonの日時文字列の書式を利用します。 詳細は Pythonのマニュアル を参照してください。
  • 属性
パラメータ タイプ 必須 説明
format string No 日時データの書式。省略値は ‘%c’
  • 子要素
パラメータ タイプ 必須 説明
format string No 日時データの書式。省略値は ‘%c’
from string Yes 計算を行う始端日時をformatの書式で指定
to string Yes 計算を行う終端開始日時をformatの書式で指定
style string No 出力する単位を指定。省略値は ‘days’

style で指定する形式には、以下の種類があります。

  • 日時の単位指定: ‘years’, ‘months’, ‘weeks’, ‘days’, ‘hours’, ‘minutes’, ‘seconds’, ‘microseconds’
  • 複合単位指定: ‘ymd’, ‘hms’, ‘ymdhms’
from, to で指定されたデータが format の書式と異なる場合や、不正な形式の場合、実行時に例外が発生します。
又、style が変数等で指定され、実行時に対象外の値が使用された場合、結果として空文字が返ります。
  • 使用例
<category>
    <pattern>あなたは何歳ですか?</pattern>
    <template>
         <interval format="%B %d, %Y">
             <style>years</style>
             <from><bot name="birthdate"/></from>
             <to><date format="%B %d, %Y" /></to>
         </interval>
         歳です。
    </template>
</category>
Input: あなたは何歳ですか?
Output: 5歳です。

関連項目: date

json

[custom]

json要素は、JSONをシナリオで利用するための機能で、データの取得と設定の両方の機能を持ちます。設定系の処理を行った場合、結果には空文字が返ります。
SubAgentmetadataNLU (高度意図解釈)などで使用するJSONデータを利用するために使用します。
詳細は、 JSON を参照してください。
属性/子要素のname/var/dataで指定する変数名には、get/setで定義した変数名を使用します。
但し、設定を行う場合には、変数名とともに、JSONとしてのキーを付加して指定する必要があります。
 指定例: “変数名.キー” (属性・子要素で”key”を指定した場合には、変数名のみでも処理されます。)
変数型 varはローカル変数、nameはグローバル変数、dataはグローバル変数です。
また、メタデータ変数や、サブエージェントの戻り値等のシステム固定変数名もvar型変数として利用できます。
  • 属性
パラメータ タイプ 指定値 必須 説明
name JSON変数名   No グローバル変数(name)名を指定します。キー名を付加することを推奨します。
var JSON変数名   No ローカル変数(var)名を指定します。キー名を付加することを推奨します。
data JSON変数名   No グローバル変数(data)名を指定します。キー名を付加することを推奨します。
function   len No 対象のJSONプロパティが配列の場合、配列長を取得します。対象がJSONオブジェクトの場合、JSONオブジェクトの要素数を取得します。
    delete No 対象プロパティを削除します。配列の場合でindexを指定していると対象となる要素を削除します。
    insert No JSON配列に対する値の追加を指定します。配列番号(index)とともに指定します。
index インデックス   No JSONデータを取得する場合のインデックスを指定します。対象が配列の場合、配列番号を指します。JSONオブジェクトではキーを先頭から順に数えたオブジェクトを指します。JSONデータを設定・変更する場合、配列のみに指定できます。
item   key No JSONデータからキーを取得する場合に使用します。この属性を指定すると値ではなくキーを取得します。
key キー指定   No JSONデータを操作するキーを指定します。
type   string No 数値・論理値・null値を文字列として処理することを指定します。

json要素として、var, name, data のいずれかが設定されている必要があります。

  • 子要素
シナリオの変数を値として指定する場合に属性では指定できないため、子要素としても指定できるようにしています。
動作は属性と同じ動作になります。同じ属性名、子要素名を指定した場合には子要素の設定が優先されます。
パラメータ タイプ 必須 説明
function 関数名 No JSONに対する処理オプションを指定します。内容については属性のfunctionを参照。
index インデックス No JSONデータを取得する場合、JSONオブジェクト、配列に対して指定でき、配列では配列番号を差し、JSONオブジェクトではキーを先頭から順に数えたオブジェクトを指します。JSONデータを設定・変更する場合、配列のみに指定できます。
item キー名取得 No JSONデータからキーを取得する場合に使用します。この属性を指定すると値ではなくキーを取得します。
key キー指定 No JSONデータを操作するキーを指定します。
  • 使用例
“transit”というSubAgentからのレスポンスが返ってきた場合のJSONのデータを取得し、対話処理の応答文として利用する場合を説明します。
以下のjsonデータがSubAgentから返却された場合、”__SUBAGENT__.transit”がSubAgentからのレスポンスデータの格納変数名になります。
JSONデータを取得する場合、属性に対象となるjson名を指定しますが、この場合”__SUBAGENT__.transit”が対象json名となります。
JSONデータの子要素の取得を行う場合、json名に、要素毎のキー名を”.”で繋げたプロパティを指定する方法と、key で指定する方法があります。
{
    "transportation":{
        "station":{
            "departure":"東京",
            "arrival":"京都"
        },
        "time":{
            "departure":"2018/11/1 11:00",
            "arrival":"2018/11/1 13:30"
        }
    }
}

上記例の様に、transportation.station.departureを返却する場合、

<category>
    <pattern>東京から京都に行きたい。</pattern>
    <template>
        <json var="__SUBAGENT__.transit.transportation.station.departure"/>出発ですね。
    </template>
</category>
Input: 東京から京都に行きたい。
Output: 東京出発ですね。

関連項目: JSON, SubAgent

learn

[2.0]

learn要素は、対話の条件によりユーザ固有の新たなcategoryを登録します。すでに登録していたcategoryの内容を置換することも可能です。
新たなcategoryはメモリ上に保持されており、contextが有効な期間、同一クライアントを利用する同一ユーザからのアクセス時のみ有効になります。
登録されたcategoryは、他のシナリオで restlearn 要素・ resetlearnf 要素が実行されるまで保持されます。
初期ロードされるcategory(categoriesエンティティ で展開)と同じPattern要素を新たに登録した場合、learn要素で指定したcategoryが優先されます。
登録可能なcategory数は、コンフィグレーション定義の 制限値定義max_categories で制限されており、learn要素での登録も制限されます。
制限数に達した状態で新規登録を行った場合には、処理例外が発生します。(同じpattern要素に対する再登録を行うことは可能です。)

learnfはファイル保持なので、bot再起動でも状態を保持しますが、learnはbot再起動時に初期化されます。

子要素には、category要素を記述し、登録時の変数の値を処理条件に含める場合には eval を利用します。
一度に複数のcategoryを登録することも可能ですが、topic要素でグループ化することはできません。topicを指定する場合には、category要素配下にtopic要素を記述する必要があります。
尚、learn要素の結果は、常に空文字になります。
  • 使用例
<category>
     <pattern>私のペットは * の * です。</pattern>
     <template>
         あなたのペットは、<star />の<star index="2" />ですね。
         <think>
             <set name="animal"><star /></set>
             <set name="name"><star index="2" /></set>
         </think>
         <learn>
             <category>
                 <pattern>
                     <eval>
                         <get name="name"/>
                     </eval>
                     は誰ですか。
                 </pattern>
                 <template>
                     あなたのペットの
                     <eval>
                         <get name="animal"/>
                     </eval>
                     です。
                 </template>
             </category>
         </learn>
     </template>
 </category>
Input: 私のペットは犬のマロンです。
Output: あなたのペットは犬のマロンですね。
Input: マロンは誰ですか。
Output: あなたのペットの犬です

関連項目; eval, learnf, restlearn, resetlearnf

learnf

[2.0]

learnf要素は、対話の条件によりユーザ固有の新たなcategoryを登録します。すでに登録していたcategoryの内容を置換することも可能です。
新たなcategoryはメモリ上とともに、ファイル上にも保持されており、他のシナリオで restlearn 要素・ resetlearnf 要素が実行されるまで保持し続けます。
登録されたcategoryは、同一クライアントを利用する同一ユーザからのアクセス時のみ有効になります。
初期ロードされるcategory(categoriesエンティティ で展開)と同じPattern要素を新たに登録した場合、learnf要素で指定したcategoryが優先されます。
登録可能なcategory数は、コンフィグレーション定義の 制限値定義max_categories で制限されており、learn要素での登録も制限されます。
制限数に達した状態で新規登録を行った場合には、処理例外が発生します。(同じpattern要素に対する再登録を行うことは可能です。)

learnfはファイル保持なので、botの再起動時に再ロードされます。

子要素には、category要素を記述し、登録時の変数の値を処理条件に含める場合には eval を利用します。
一度に複数のcategoryを登録することも可能ですが、topic要素でグループ化することはできません。topicを指定する場合には、category要素配下にtopic要素を記述する必要があります。
尚、learnf要素の結果は、常に空文字になります。
  • 使用例
<category>
     <pattern>私のペットは * の * です</pattern>
     <template>
         あなたのペットは、<star />の<star index="2" />ですね。
         <think>
             <set name="animal"><star /></set>
             <set name="name"><star index="2" /></set>
         </think>
         <learnf>
             <category>
                 <pattern>
                     <eval>
                         <get name="name"/>
                     </eval>
                     は誰ですか。
                 </pattern>
                 <template>
                         あなたのペットの
                     <eval>
                         <get name="animal"/>
                     </eval>
                     です。
                 </template>
             </category>
         </learnf>
     </template>
 </category>
Input: 私のペットは犬のマロンです。
Output: あなたのペットは犬のマロンですね。
Input: マロンは誰ですか。
Output: あなたのペットの犬です。

関連項目: eval, learn, restlearn, resetlearnf

li

[1.0]

li要素は、condition要素での分岐条件の指定と、random要素での選択要素を指定する子要素として使用します。

condition要素の子要素として使用する場合には、以下の子要素(属性)が指定できます。 詳細な利用方法は、condition を参照してください。

  • 子要素(’loop’以外は属性でも指定可能。)
パラメータ タイプ 必須 説明
name 変数名 No 分岐条件とするグローバル変数(name)名を指定します。
var 変数名 No 分岐条件とするローカル変数(var)名を指定します。
data 変数名 No 分岐条件とするグローバル変数(data)名を指定します。
bot プロパティ名 No 分岐条件とするBot固有情報(プロパティ)名を指定します。
value 判定値 No 分岐条件となる値を指定します。(大文字・小文字、全角・半角を区別します)
regex 判定値 No 分岐条件となる値を正規表現で指定します。判定は完全一致(大文字・小文字は同一視)で行います。
loop string No condition要素内でのループ処理を指定します。

random要素の子要素として使用する場合には、属性や子要素の規定はありません。 詳細な利用方法は、random を参照してください。

関連項目: condition, loop, random

list

[2.1]

list要素は、itemに記載した要素をリスト形式で返すリッチメディア要素です。 子要素のitemにリストの内容を記載することができます。また、itemにlistを記載し入れ子にすることもできます。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素
パラメータ タイプ 必須 説明
item string Yes リストの内容を記載します。

item には、テキスト以外に、button や、image 等のリッチメディア要素を配置することができます。

<category>
    <pattern>リスト</pattern>
    <template>
        <list>
            <item>
                <list>
                    <item>リストアイテム 1.1</item>
                    <item>リストアイテム 1.2</item>
                </list>
            </item>
            <item>リストアイテム 2.1</item>
            <item>リストアイテム 3.1</item>
        </list>
    </template>
</category>

関連項目: card, button, image

log

[custom]

log要素は開発者用の要素で、この要素を記載すると、botのログファイルに出力されます。
ロギングレベルは、level属性で指定します。
  • 属性
パラメータ タイプ 必須 説明
level 変数名 No ‘error’, ‘warning’, ‘debug’, ‘info’ のいずれかを指定します。省略時は’info’で出力されます。

詳細は、 ログ設定 を参照してください。

尚、コンフィグレーションのストレージ定義で logs を有効にすると、直近の対話での情報がユーザ毎のログファイルに出力されます。
ユーザ毎のログファイルの内容は、デバッグAPI でも取得できます。
  • 使用例
<category>
    <pattern>こんにちは</pattern>
    <template>
        こんにちは
        <log>挨拶</log>
    </template>
</category>

<category>
    <pattern>さよなら</pattern>
    <template>
        さよなら
        <log level="error">挨拶</log>
    </template>
</category>
Input: こんにちは
Output: こんにちは ※ログには、infoレベルで”挨拶”と出力されている
Input: さよなら
Output: さよなら ※ログには、errorレベルで”挨拶”と出力されている

関連項目: ログ設定

lowercase

[1.0]

lowercase要素は、対象となる文字列内の半角英字を小文字にします。 英字以外に、大文字・小文字が存在するギリシャ文字等にも対応します。

  • 使用例
<category>
    <pattern>こんにちは * です</pattern>
    <template>
        こんにちは <lowercase><star /></lowercase>さん
    </template>
</category>

<lowercase />は、<lowercase><star /></lowercase>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>こんにちは * です</pattern>
    <template>
        こんにちは <lowercase />さん
    </template>
</category>
Input: こんにちは GEORGE WASHINGTON です
Output: こんにちは george washingtonさん

関連項目: uppercase

map

[1.0]

map要素では、外部ファイルで指定した変換辞書により、対象文字列の変換を行います。
対象文字列の定義は、、mapsファイル でファイル毎に、’変換対象文字列: 変換後文字列’ の形式で列記します。
変換対象文字列の一致判定は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で行いますが、 変換結果には指定された変換後文字列が設定されます。
変換対象文字列、変換後文字列に、複数単語からなる文字列を指定することもできますが、空白の数を含めて一致する必要があります。

変換対象文字列のリストに一致するものが無い場合、コンフィグレーション定義の default-map の定義値が返ります。 (default-mapが定義されていない場合、空文字が返ります。)

  • 属性 (子要素での指定も可能)
パラメータ タイプ 必須 説明
name map名 Yes mapsファイル名から拡張子を除いた文字列を指定します。
属性でnameを指定した場合、登録されてないファイル名を指定すると、シナリオ展開時に異常を検出し、該当シナリオは無効になります。
子要素でnameを指定した場合、登録されてないファイル名を指定すると、実行時に例外が発生します。
  • 使用例
<category>
    <pattern>* の県庁所在地は?</pattern>
    <template>
       <map name="prefectural_office"><star/></map>です。
    </template>
</category>
Input: 神奈川県の県庁所在地は?
Output: 横浜市です。

コンフィグレーションの dynamicmaps が定義されている場合、mapsファイル名として dynamic の定義が優先されます。

関連項目: ファイル管理:maps

nluintent

[custom]

nluintent要素は、NLU結果のintent情報を取得するための機能です。
NLU結果がある場合のみ値が返ります。従って、基本的に以下の変数に対して使用します。
  • patternに nluタグ を指定したcategoryにマッチした場合に、ローカル変数(var): __SYSTEM_NLUDATA__ を対象に処理します。
  • templateの sraixタグ でNLU通信を行った場合に、ローカル変数(var): __SUBAGENT_NLU__.エイリアス名 を対象に処理します。
  • NLU結果を代入した変数を対象に処理します。

詳細は、 NLU を参照してください。

  • 属性
パラメータ タイプ 必須 説明
name インテント名 Yes 取得するインテント名を指定します。 * でワイルドカード扱いになります。ワイルドカード指定時はindexで取得対象を指定します。
item 取得アイテム名 Yes 指定したインテントの情報を取得します。intentscore および count を指定できます。 intent指定時はインテント名を取得することができます。score指定時は確信度(0.0〜1.0)を取得します。countはインテント名の数を返します。
index インデックス No 取得するインテントのインデックス番号を指定します。nameで指定したインテント名がマッチしたリスト中のインデックス番号を指定します。
target 対象変数名 No 任意の変数を対象とする場合に、その変数名を指定します(省略値は、 __SYSTEM_NLUDATA__ )。sraixでのNLU通信結果を対象とする場合には、__SUBAGENT_NLU__.エイリアス名 を指定します。
type 変数種別 No target の指定時に有効で、変数の種別:’name’, ‘data’, ‘var’ のいずれかを指定します(省略値は、’var’)。
AIMLの変数を値として指定する場合に属性では指定できないため、子要素としても指定できるようにしています。
動作は属性と同じ動作になります。同じ属性名、子要素名を指定した場合子要素の設定が優先されます。
  • 子要素
パラメータ タイプ 必須 説明
name インテント名 Yes 取得するインテント名を指定します。 内容については属性のnameを参照。
item 取得アイテム名 Yes 指定したインテントの情報を取得します。内容については属性のitemを参照。
index インデックス No 取得するインテントのインデックス番号を指定します。内容については属性のindexを参照。
  • 使用例

NLUの処理結果のインテント情報を取得します。 以下例のNLU処理結果からインテントを取得する場合を説明します。

{
    "intents": [
        {"intent": "restaurantsearch", "score": 0.9 },
        {"intent": "aroundsearch", "score": 0.4 }
    ],
    "slots": [
        {"slot": "genre", "entity": "イタリアン", "score": 0.95, "startOffset": 0, "endOffset": 5 },
        {"slot": "genre", "entity": "フレンチ", "score": 0.86, "startOffset": 7, "endOffset": 10 },
        {"slot": "genre", "entity": "中華", "score": 0.75, "startOffset": 12, "endOffset": 14 }
    ]
}

NLUで処理したインテントを取得する場合、以下のように記述します。

<category>
    <pattern>
        <nlu intent="restaurantsearch"/>
    </pattern>
    <template>
        <nluintent name="restaurantsearch" item="score" />
    </template>
</category>
Input: イタリアンかフレンチか中華を探して
Output: 0.9。
sraixタグ でNLU通信を行った結果からインテントを取得する場合、以下のように記述します。
尚、この場合の nlu_servers ファイルでは、serversのエイリアス名として、’someNlu’ が登録されているものとします。
<category>
    <pattern>
        NLU通信 *
    </pattern>
    <template>
        <think>
            <sraix nlu="sameNlu"><star /></sraix>
        <thimk>
        <nluintent name="restaurantsearch" item="score" target="__SUBAGENT_NLU__.someNlu" />
    </template>
</category>
Input: NLU通信 イタリアンかフレンチか中華を探して
Output: 0.9。

関連項目: NLUNLUインテントの取得

nluslot

[custom]

nluslot要素は、NLU結果のslot情報を取得するための機能です。
NLU結果がある場合のみ値が返ります。従って、基本的に以下の変数に対して使用します。
  • patternに nluタグ を指定したcategoryにマッチした場合に、ローカル変数(var): __SYSTEM_NLUDATA__ を対象に処理します。
  • templateの sraixタグ でNLU通信を行った場合に、ローカル変数(var): __SUBAGENT_NLU__.エイリアス名 を対象に処理します。
  • NLU結果を代入した変数を対象に処理します。

詳細は、 NLU を参照してください。

  • 属性
パラメータ タイプ 必須 説明
name スロット名 Yes 取得するスロット名を指定します。 * でワイルドカード扱いになります。ワイルドカード指定時はindexで取得対象を指定します。
item 取得アイテム名 Yes 指定したスロットの情報を取得します。slotentityscorestartOffsetendOffset および count を指定できます。 slot指定時はスロット名を取得することができます。entity指定時はスロットの抽出文字列、score指定時は確信度(0.0〜1.0)、startOffset指定時は抽出文字列の開始文字位置、endOffset指定時は抽出文字列の終端文字位置を取得します。 countは同一スロット名の数を返します。
index インデックス No 取得するスロットのインデックス番号を指定します。nameで指定したスロット名がマッチしたリスト中のインデックス番号を指定します。
target 対象変数名 No 任意の変数を対象とする場合に、その変数名を指定します(省略値は、 __SYSTEM_NLUDATA__ )。sraixでのNLU通信結果を対象とする場合には、__SUBAGENT_NLU__.エイリアス名 を指定します。
type 変数種別 No target の指定時に有効で、変数の種別:’name’, ‘data’, ‘var’ のいずれかを指定します(省略値は、’var’)。

AIMLの変数を値として指定する場合に属性では指定できないため、子要素としても指定できるようにしています。 動作は属性と同じ動作になります。同じ属性名、子要素名を指定した場合子要素の設定が優先されます。

  • 子要素
パラメータ タイプ 必須 説明
name スロット名 Yes 取得するスロット名を指定します。 内容については属性のnameを参照。
item 取得アイテム名 Yes 指定したスロットの情報を取得します。内容については属性のitemを参照。
index インデックス No 取得するスロットのインデックス番号を指定します。内容については属性のindexを参照。
  • 使用例

NLUの処理結果のスロット情報を取得します。 以下例のNLU処理結果からスロットを取得する場合を説明します。

{
    "intents": [
        {"intent": "restaurantsearch", "score": 0.9 },
        {"intent": "aroundsearch", "score": 0.4 }
    ],
    "slots": [
        {"slot": "genre", "entity": "イタリアン", "score": 0.95, "startOffset": 0, "endOffset": 5 },
        {"slot": "genre", "entity": "フレンチ", "score": 0.86, "startOffset": 7, "endOffset": 10 },
        {"slot": "genre", "entity": "中華", "score": 0.75, "startOffset": 12, "endOffset": 14 }
    ]
}

NLUで処理したスロットを取得する場合、以下のように記述します。

<category>
    <pattern>
        <nlu intent="restaurantsearch"/>
    </pattern>
    <template>
        <nluslot name="genre" item="count" />
        <nluslot name="genre" item="entity" index="0" />
        <nluslot name="genre" item="entity" index="1" />
        <nluslot name="genre" item="entity" index="2" />
    </template>
</category>
Input: イタリアンかフレンチか中華を探して
Output: 3 イタリアン フレンチ 中華。
sraixタグ でNLU通信を行った結果からスロットを取得する場合、以下のように記述します。
尚、この場合の nlu_servers ファイルでは、serversのエイリアス名として、’someNlu’ が登録されているものとします。
<category>
    <pattern>
        NLU通信 *
    </pattern>
    <template>
        <think>
            <sraix nlu="sameNlu"><star /></sraix>
        <think>
        <nluslot name="genre" item="count" target="__SUBAGENT_NLU__.someNlu" />
        <nluslot name="genre" item="entity" index="0" target="__SUBAGENT_NLU__.someNlu" />
        <nluslot name="genre" item="entity" index="1" target="__SUBAGENT_NLU__.someNlu" />
        <nluslot name="genre" item="entity" index="2" target="__SUBAGENT_NLU__.someNlu" />
    </template>
</category>
Input: NLU通信 イタリアンかフレンチか中華を探して
Output: 3 イタリアン フレンチ 中華。

関連項目: NLUNLUスロットの取得

normalize

[1.0]

normalize要素は、対象となる文字列に含まれる記号や、短縮形の文字列を、指定された単語に変換します。
変換内容は、normalファイル で指定し、大文字・小文字、全角・半角を区別して変換を行います。
英単語に対する変換の場合、文字を単位とする変換(文字変換)と、単語を単位とする変換(単語変換)を、文字変換・単語変換の順で行い、両者とも、変換後の文字列の前後には、空白が挿入されます。
(日本語の場合、単語変換のみを行います。)
例えば、’.’を’dot’、’*’を’_’に変換する場合、’www.***.com’は、’www dot _ _ _ dot com’に変換されます。
  • 使用例
<category>
    <pattern>URLは *</pattern>
    <template>
        <normalize><star /></normalize>を表示します。
    </template>
</category>

<normalize />は、<normalize><star /></normalize>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>URLは *</pattern>
    <template>
         <normalize />を表示します。
    </template>
</category>
Input: URLはwww.***.com
Output: www dot _ _ _ dot com を表示します。

関連項目: ファイル管理:normal , denormalize

olist

[2.1]

olist(ordered list)要素は、子要素の item に記載した要素をリスト形式で返すリッチメディア要素です。 子要素のitemにはリストの内容を記載することができます。また、itemにlistを記載し入れ子にすることもできます。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素
パラメータ タイプ 必須 説明
item string Yes リストの内容を記載します。
  • 使用例
<category>
    <pattern>リストを表示して</pattern>
    <template>
         <olist>
            <item>
                 <card>
                     <image>https://searchsite.com/image0.png</image>
                     <title>Image No.1</title>
                     <subtitle>Tag olist No.1</subtitle>
                     <button>
                         <text>Yes</text>
                         <url>https://searchsite.com:?q=yes</url>
                     </button>
                 </card>
             </item>
             <item>
                 <card>
                     <image>https://searchsite.com/image1.png</image>
                     <title>Image No.2</title>
                     <subtitle>Tag olist No.2</subtitle>
                     <button>
                         <text>No</text>
                         <url>https://searchsite.com:?q=no</url>
                     </button>
                 </card>
             </item>
         </olist>
    </template>
 </category>

関連項目: item , card

oob

[1.0]

OOBは “Out of Band” の略で、oob要素が評価されると対応する内部モジュールが処理を行い、処理結果をクライアントに返します。
内部モジュールでの処理はOS上での機器操作を想定しており、組み込み機器などで利用することを想定した機能です。
OOBを処理する内部モジュールは、システム開発者が設計、実装を行います。詳細は OOB を参照してください。
oob要素の子要素の名称に、利用するOOB機能の識別名を指定し、その内容として引数を指定します。引数として記述した内容はXML化されてOOBの処理モジュールに引き渡されます。
引数を複数指定する場合、要素名にはAIMLで使用する要素名と重ならない名称を使用してください。
コンフィグレーションで登録していないOOBの識別名を指定した場合には、実行時に例外が発生します。
(重要)
 OOBの処理は、他の要素とは異なり、template内に記述された他の要素の処理を全て実施した後に実行されます。
 又、実施できるOOB機能はcategory内で1つのみで、複数のOOBの指定を行っても、実施されるのは最初の1機能のみです。
  • 使用例
<category>
    <pattern>DIAL *</pattern>
    <template>
         <oob><dial><star /></dial></oob>
    </template>
</category>
Input: DIAL 0123-456-7890
Output: (DIAL) (返却内容は内部モジュールの実装次第)

関連項目: xmlOOB

person

[1.0]

person要素は、発話文に含まれる一人称の代名詞と二人称の代名詞の間の変換を行うことを目的としています。
変換内容は、personファイル で指定します。
変換方法の指定には変換前と変換後のセットで記載し、personのセット内に一致するものがある場合にのみ変換が行われます。複数単語での指定も可能です。
変換対象の判定は、英数記号:半角、カタカナ:全角に変換した上で行いますが、変換結果はpersonファイルの値になります。
  • 使用例
<category>
    <pattern>私は * を待っています。</pattern>
    <template>
        あなたは <person><star /></person> を待っているんですね。
    </template>
</category>

<person />は、<person><star /></person>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>私は * を待っています。</pattern>
    <template>
        あなたは <person /> を待っているんですね。
    </template>
</category>
Input: 私はあなたを待っています。
Output: あなたは私を待っているんですね。

関連項目: ファイル管理:person , person2

person2

[1.0]

person2要素は、発話文に含まれる一人称の代名詞と三人称の代名詞の間の変換を行うことを目的としています。
変換内容は、person2ファイル で指定します。
変換方法の指定には変換前と変換後のセットで記載し、person2のセット内に一致するものがある場合にのみ変換が行われます。複数単語での指定も可能です。
変換対象の判定は、英数記号:半角、カタカナ:全角に変換した上で行いますが、変換結果はperson2ファイルの値になります。
  • 使用例
<category>
    <pattern>* に * を教えてください。</pattern>
    <template>
        <person2><star/></person2> の <star index="2" /> はこれです。
    </template>
</category>

<person2 />は、<person2><star /></person2>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>* に * を教えてください。</pattern>
    <template>
        <person2 /> の <star index="2" /> はこれです。
    </template>
</category>
Input: 私に行き方を教えてください。
Output: あなた方の行き方はこれです。

関連項目: ファイル管理:person2 , person

program

[1.0]

program要素は、Botのバージョン情報を ‘ボット名 version バージョン名’ の形式で返します。(対話エンジンのバージョンを示すものではありません。)
ボット名は、default:’AIML bot’ で、 propertiesファイル で ‘fullname’ を指定することで変更できます。
バージョン名は、コンフィグレーションの version をdefaultとし、 propertiesファイル の ‘version’ 指定で変更できます。

propertiesファイルのversionに ‘v1,0’ を指定した場合には、以下の様になります。

  • 使用例
<category>
    <pattern>version</pattern>
    <template>
        <program />
    </template>
</category>
Input: version
Output: AIML bot version v1.0

関連項目: ファイル管理:properties

random

[1.0]

random要素は、列記された li 子要素の中からランダムに1個を選び、その結果を返します。

  • 子要素
パラメータ タイプ 必須 説明
li string Yes ランダムで出力する結果を指定します。
  • 使用例
<category>
    <pattern>こんにちは</pattern>
    <template>
        <random>
             <li>こんにちは</li>
             <li>今日の調子はどうですか?</li>
             <li>今日の予定を調べましょうか?</li>
        </random>
    </template>
</category>
Input: こんにちは
Output: 今日の予定を調べましょうか?
Input: こんにちは
Output: 今日の調子はどうですか?

関連項目: li

reply

[2.1]

reply要素は、リッチメディア要素でbutton要素に似ています。子要素として、読み上げに使用するtext、Botに対するpostbackを記載します。
replyとbuttonの違いは、GUIを利用せず音声対話などで利用することを想定しています。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 子要素 (属性での指定も可能)
パラメータ タイプ 必須 説明
text string Yes 読み上げテキストを記載します。(空文字を許容します。)
postback string No 動作を記載します。ユーザにはこのメッセージは見せずBotに対するレスポンスやアプリケーションで処理を行う場合に利用します。
  • 使用例
<category>
    <pattern>乗り換え</pattern>
    <template>
         <reply>
             <text>乗り換え検索しますか?</text>
             <postback>乗り換え案内</postback>
         </reply>
    </template>
 </category>

関連項目: button

request

[1.0]

request要素は、履歴番号を指定することで対話履歴の中から該当する入力(発話文)履歴を返します。
入力文は、英数記号の半角化とカタカナの全角化、マッチ処理対象外文字の除去、及び、単語分解と再結合が行われ、発話文が再構成されたものになります。
履歴番号は、‘0’が現在で、数値が大きくなるほど過去の履歴になります。’-1’を指定すると最古の入力文が取得できます。
該当する履歴がない履歴番号を指定した場合、取得失敗として空文字を返します。
  • 属性
パラメータ タイプ 必須 説明
index string No 履歴番号を整数値で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>なんて言ったっけ?</pattern>
    <template>
          <request index="2" />、
          <request index="1" />、
          <request index="0" />、
          と言いました。
    </template>
</category>
Input: こんにちは
Output: こんにちは
Input: もう夜だね
Output: こんばんは
Input: なんて言ったっけ?
Output: こんにちは、もう夜だね、なんて言ったっけ?、と言いました。

<request />は、<request index=”1” />と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>なんて言ったっけ?</pattern>
    <template>
          <request />、と言いました。
    </template>
</category>
Input: こんにちは
Output: こんにちは
Input: なんて言ったっけ?
Output: こんにちは、と言いました。

関連項目: response

resetlearn

[2.x]

resetlearn要素は、メモリ上の learn 要素. learnf 要素で登録されたユーザ固有のcategoryを全て削除します。
resetlearnでは、learnf要素で作成したファイルを削除しない為、再起動時にlearnf要素で登録したcategoryが復活します。
resetlearnを実行することで、使用中のcategory数は初期ロードしたcategory数に戻ります。また、Pattern要素が同じでユーザ固有定義が優先されて使用できなかった初期ロードのcategoryも使用できる様になります。
尚、resetlearn要素の結果は、常に空文字になります。
  • 使用例
<category>
    <pattern>私の言ったことを忘れて。</pattern>
    <template>
         <think><resetlearn /></think>
         わかりました。残念ですが忘れます。
    </template>
</category>

関連項目: learn, learnf, resetlearnf

resetlearnf

[2.x]

resetlearnf要素は、learn 要素. learnf 要素で登録されたユーザ固有のcategoryを全て削除します。
resetlearnとの差は、learnf要素で作成したファイルを含めて削除する点です。
resetlearnfを実行することで、使用中のcategory数は初期ロードしたcategory数に戻ります。また、Pattern要素が同じでユーザ固有定義が優先されて使用できなかった初期ロードのcategoryも使用できる様になります。
尚、resetlearnf要素の結果は、常に空文字になります。
  • 使用例
<category>
    <pattern>私の言ったことを忘れて。</pattern>
    <template>
         <think><resetlearnf /></think>
         わかりました。残念ですが忘れます。
    </template>
</category>

関連項目: learn, learnf, resetlearn

response

[1.0]

response要素は、履歴番号を指定することで対話履歴の中から該当する出力(応答文)履歴を返します。
履歴番号は、‘0’が現在(未確定の為、指定不可)で、数値が大きくなるほど過去の履歴になります。’-1’を指定すると最古の出力文が取得できます。
該当する履歴がない履歴番号を指定した場合、取得失敗として空文字を返します。
  • 属性
パラメータ タイプ 必須 説明
index string No 履歴番号を ‘0’ 以外の整数値で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>君はなんて言ったっけ?</pattern>
    <template>
          <response index="2" />、
          <response index="1" />、
          と言いました。
    </template>
</category>
Input: こんにちは
Output: こんにちは
Input: もう夜だね
Output: こんばんは
Input: 君はなんて言ったっけ?
Output: こんにちは、こんばんは、と言いました。

<response />は、<response index=”1” />と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>君はなんて言ったっけ?</pattern>
    <template>
          <response /> 、と言いました。
    </template>
</category>
Input: こんにちは
Output: こんにちは
Input: 君はなんて言ったっけ?
Output: こんにちは、と言いました。

関連項目: request

rest

[2.0]

rest要素は、複数単語からなる文字列に対して、最初以外の単語列を返します。first要素の逆の動作です。
(文字列の単語分割時には、 punctuation_chars の指定による特定文字除外の処理を行います。)
取得に失敗した場合は、コンフィグレーション定義の default-get の値が返ります。
例えば、”山田 太郎”の場合、”太郎”が返ります。
尚、結果の単語列は、日本語の場合でも空白区切りで返ります。
  • 使用例
<category>
    <pattern>私の名前は * です</pattern>
    <template>
        あなたの名前は<rest><star /></rest>さんですね
    </template>
</category>
Input: 私の名前は 山田 太郎 です
Output: あなたの名前は太郎さんですね
RDFナレッジベースの検索結果に適用した場合、結果リスト内の先頭以外のデータを取得します。 詳細は、RDFサポート を参照してください。
JSON形式のデータには対応していません。
first要素とrest要素を、condition要素内で使用することで、単語毎の処理を繰り返して実行することができます(取得失敗を意味する “unknown” の取得で終了します)。
(但し、本処理は単語分解結果に依存します。又、conditionでのloop処理には回数制限がありますので、大規模なデータに対する処理では例外が発生します。)
  • 使用例
<category>
    <pattern>単語展開 *</pattern>
    <template>
        <think>
            <set var="WORDS"><star /></set>
        </think>
        <condition var="WORDS">
            <li value="unknown" />
            <li>
                "<first><get var="WORDS" /></first>"
                <think>
                    <set var="WORDS"><rest><get var="WORDS" /></rest></set>
                </think>
                <loop />
            </li>
        </condition>
    </template>
</category>
Input: 単語展開 apple orange grape
Output: “apple” “orange” “grape”。

関連項目: first

set

[1.0]

template内のset要素では、グローバル変数とローカル変数の設定を行うことができます。変数型:name/var/dataの差異は、 get を参照してください。
JSON形式やリスト形式のデータも文字列として指定することで、set要素で設定することができます。
set要素の結果には、設定した値が返ります。応答文に反映されない様にする場合は、think を利用してください。
グローバル変数(name/data)については、利用可能な変数の総数がコンフィグレーション定義の 制限値定義max_properties で制限されます。
制限数に達した状態で新規登録を行った場合には、処理例外が発生します。(登録済みの変数は使用できます。)
defaultsファイル で初期設定するグローバル変数(name)については全て登録されますが、初期登録段階で制限値に達している場合、新たな変数は使用できません。
変数を削除するには、set要素の設定値に空文字を指定します。(グローバル変数(data)については、対話APIdeleteVariable 指定で削除することもできます。)
但し、グローバル変数(name)の ‘topic’ は削除できない変数として、空文字を指定しても ‘*’ が設定されます。
  • 属性 (子要素での指定も可能)
パラメータ タイプ 必須 説明
name 変数名 No グローバル変数(name)名を指定
var 変数名 No ローカル変数(var)名を指定
data 変数名 No グローバル変数(data)名を指定
set要素として、属性・子要素で、var, name, data のいずれかが設定されている必要があります。
複数の属性、子要素を指定した場合には、不正指定としてシナリオは無効になります。
尚、変数名・設定値とも、大文字・小文字、全角・半角を区別して管理します。
  • 使用例
<!-- グローバル変数 -->
<category>
    <pattern>MY NAME IS *</pattern>
    <template>
        <set name="myname"><star /></set>
    </template>
</category>

<!-- ローカル変数 -->
<category>
    <pattern>MY NAME IS *</pattern>
    <template>
        <set var="myname"><star /></set>
    </template>
</category>

関連項目: get

select

[2.0]

select要素はRDFの検索に使用する要素で、起動時に展開するRDFファイルの内容と、addtriple で追加されたRDFナレッジベースを対象に検索を行い、該当する情報を取得します。
select要素での検索は、肯定検索を行うクエリと否定検索を行うクエリが指定でき、条件に合わせてそれぞれを列記することで複合的な検索が行えます。但し、クエリを列記した場合、それぞれの結果に対してAND条件で合致する結果を返します。
又、検索用変数を利用することで、クエリ間で共通する値を検索対象とすることもできます。検索用変数名の先頭文字には ‘?’ を付与します。
(クエリを列記した場合で、先行するクエリの結果が後続のクエリの結果より少ない場合には、全ての検索対象が取得できない場合があります。)
詳細は RDFサポート を参照してください。
  • 子要素
パラメータ   タイプ 必須 説明
vars   変数名リスト No 利用する検索用変数名を空白区切りで列記
q     No 肯定検索をするクエリの指定
  subj string No 検索対象のsubject (主語)の値、又は、検索用変数名を指定
  pred string No 検索対象のpredicate (述語)の値、又は、検索用変数名を指定
  obj string No 検索対象のobject (目的語)の値、又は、検索用変数名を指定
notq     No 否定検索をするクエリの指定。子要素指定に対して AND条件で処理します。
  subj string No 検索対象外のsubject (主語)の値、又は、検索用変数名を指定
  pred string No 検索対象外のpredicate (述語)の値、又は、検索用変数名を指定
  obj string No 検索対象外のobject (目的語)の値、又は、検索用変数名を指定
select要素には、子要素として、q、又は、notq が1つは必要です。又、クエリ間で変数を共有する場合、vars 子要素も必須になります。
‘q’、’notq’ の子要素についても、subjpredobj のいずれか1つが最低限必要です。同一子要素が複数指定された場合、最後の指定が有効になります。
クエリ内で、’subj’、’pred’、’obj’の指定を省略した場合、省略された項目の全データが合致するものとして扱います。
以下の例では、RDFナレッジベースに対して、predicate=”legs”, object=”4” を指定した検索を行って、subject(変数名:’?name’) の一覧を取得しています。
検索結果は変数名と値のリスト形式で設定され、基本的にRDFデータ毎にまとめられます。
検索結果がなかった場合には、コンフィグレーション定義の default-get の値が返ります。
  • 使用例
<category>
    <pattern>* 本足の動物は?</pattern>
    <template>
        <select>
             <vars>?name</vars>
             <q><subj>?name</subj><pred>legs</pred><obj><star/></obj></q>
        </select>
    </template>
</category>
Input: 4 本足の動物は?
Output: [[[“?name”, “ZEBRA”]], [[“?name”, “LION”]], [[“?name”, “ELEPHANT”]]]
次の例では、RDFナレッジベースに対して、predicate=”legs” を指定した検索を行って、subject(変数名:’?name’) と object(変数名:’?number’) の一覧を取得しています。
出力結果は、RDFデータ毎に ‘subject’ と ‘object’ がまとめられた形でリストに格納されています。
<category>
    <pattern>動物の足は?</pattern>
    <template>
     <select>
         <vars>?name ?number</vars>
         <q><subj>?name</subj><pred>legs</pred><obj>?number</obj></q>
     </select>
    </template>
</category>
Input: 動物の足は?
Output: [[[“?name”, “ANT”], [“?number”, “6”]], [[“?name”, “BAT”], [“?number”, “2”]], [[“?name”, “LION”], [“?number”, “4”]], [[“?name”, “PIG”], [“?number”, “4”]], [[“?name”, “ELEPHANT”], [“?number”, “4”]], [[“?name”, “PERSON”], [“?number”, “2”]], [[“?name”, “BEE”], [“?number”, “”]], [[“?name”, “BUFFALO”], [“?number”, “4”]], [[“?name”, “ANIMAL”], [“?number”, “Legs”]], [[“?name”, “FROG”], [“?number”, “4”]], [[“?name”, “PENGUIN”], [“?number”, “2”]], [[“?name”, “DUCK”], [“?number”, “2”]], [[“?name”, “BIRD”], [“?number”, “2”]], [[“?name”, “MONKEY”], [“?number”, “4”]], [[“?name”, “GOOSE”], [“?number”, “2”]], [[“?name”, “FOX”], [“?number”, “4”]], [[“?name”, “KANGAROO”], [“?number”, “2”]], [[“?name”, “DOG”], [“?number”, “4”]], [[“?name”, “COW”], [“?number”, “4”]], [[“?name”, “SHEEP”], [“?number”, “4”]], [[“?name”, “FISH”], [“?number”, “0”]], [[“?name”, “OX”], [“?number”, “4”]], [[“?name”, “DOLPHIN”], [“?number”, “0”]], [[“?name”, “BEAR”], [“?number”, “4”]], [[“?name”, “WOLF”], [“?number”, “4”]], [[“?name”, “ZEBRA”], [“?number”, “4”]], [[“?name”, “CAT”], [“?number”, “4”]], [[“?name”, “WHALE”], [“?number”, “0”]], [[“?name”, “CHICKEN”], [“?number”, “2”]], [[“?name”, “TIGER”], [“?number”, “4”]], [[“?name”, “HORSE”], [“?number”, “4”]], [[“?name”, “OWL”], [“?number”, “2”]], [[“?name”, “GOAT”], [“?number”, “4”]], [[“?name”, “RABBIT”], [“?number”, “4”]]]

任意の変数名を利用せずに検索対象項目に ‘?’ のみを指定した場合、変数名として、”?subj”, “?pred”, “?obj” が出力されます。

関連項目: addtriple, deletetriple, uniq, RDFサポート

sentence

[1.0]

sentence要素は、英文に対する整形を目的として、文章の最初の単語を大文字にし、他のすべての単語を小文字に設定します。 英字以外に、大文字・小文字が存在するギリシャ文字等にも対応します。

  • 使用例
<category>
    <pattern>Create a sentence with the word *</pattern>
    <template>
        <sentence>HAVE you Heard ABouT <star/></sentence>
    </template>
</category>
Input: Create a sentence with the word AnImAl
Output: Have you heard about animal

<sentence />は<sentence><star /></sentence>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>CORRECT THIS *</pattern>
    <template>
        <sentence />
    </template>
</category>
Input: CORRECT THIS PleAse tEll Us The WeAthEr ToDay.
Output: Please tell us the weather today.

size

[1.0]

size要素は、利用可能なカテゴリ数を返します。 カテゴリ数には、初期登録されたcategoryに加え、learn/learnfで登録されたcategoryを含む為、ユーザ毎で数値が変わる場合があります。

  • 使用例
<category>
    <pattern>理解できるカテゴリ数は?</pattern>
    <template>
        <size />です。
    </template>
</category>
Input: 理解できるカテゴリ数は?
Output: 5000です。

space

[custom]

space要素は、要素毎の結果文字列の間に半角スペースを挿入します。
英文の場合には単語間に空白が入りますが、日本語の場合には基本的に空白が入らない為、本要素で空白を挿入します。sraix 要素でのSubAgent連携で引数を空白区切りで指定する場合などにも使用します。
尚、文字列結合の処理で重複空白は1つの空白に置換される為、英文に対して本要素を指定した場合でも空白が重複することはありません。
<category>
    <pattern>おはようございます。</pattern>
    <template>
         <think>
             <set var="french">フレンチ</set>
             <set var="italian">イタリアン</set>
             <set var="chinese">中華</set>
         </think>
         <get var="french"/><get var="italian"/><get var="chinese"/>を検索。
         <get var="french"/><space/><get var="italian"/><space/><get var="chinese"/>を検索。
    </template>
</category>
Input: おはようございます。
Output: フレンチイタリアン中華を検索。フレンチ イタリアン 中華を検索。

関連項目: sraix

split

[2.1]

split要素はリッチメディア要素で、XML内の文章を分割するために使用します。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

<category>
    <pattern>おはようございます。</pattern>
    <template>
         今日はいい天気ですね。
         <split/>
         明日も晴れるといいですね。
    </template>
</category>
Input: おはようございます。
Output: 今日はいい天気ですね。<split/>明日も晴れるといいですね。

sr

[1.0]

sr要素は、入力文に対するsrai要素処理を簡易に行うもので、<srai><star /></srai> の省略形です。
従って、srai 要素と同様に、コンフィグレーション定義の 制限値定義max_search_srai の制限対象です。
  • 使用例
<category>
    <pattern>私の質問は * です</pattern>
    <template>
        <sr />
    </template>
</category>

<sr />は、<srai><star/></srai>と同義です。

<category>
    <pattern>私の質問は * です</pattern>
    <template>
        <srai><star/></srai>
    </template>
</category>

関連項目: star, srai

srai

[1.0]

srai要素は、内容で括られた文章でパターンマッチを実行し、該当するcategoryに対する処理を実施して結果文字列を返します。該当するcategoryが無い場合には、空文字が返ります。
“srai”自体には正式な意味を持ちませんが、symbolic reduction、もしくは、symbolic recursionという意味になります。
共通的な処理を行うcategoryを登録しておき、srai要素に対応する発話文を指定することで、シナリオの記述を整理することができます。
srai処理はパターンマッチを複数回行うため負荷が高く、実施回数をコンフィグレーション定義の 制限値定義max_search_srai で制限しています。
制限回数を超えてsrai処理を行った場合、処理例外が発生します。

以下の例は、”HI”に対応したcategoryで共通する処理を定義し、その他の入力文に対応したcategoryで利用しています。

  • 使用例
<category>
    <pattern>こんにちは</pattern>
    <template><srai>HI</srai></template>
</category>

<category>
    <pattern>Hello</pattern>
    <template><srai>HI</srai></template>
</category>

<category>
    <pattern>Hola</pattern>
    <template><srai>HI</srai></template>
</category>

<category>
    <pattern>HI</pattern>
    <template>こんにちは</template>
</category>
Input: Hola
Output: こんにちは

関連項目: star, sr

sraix

[2.0]

sraix要素は、sraiの拡張機能ではなく、サブエージェント連携を行う別の機能で、外部サービスとのREST通信を行って結果を返します。
外部との通信を行うため、相手サービスとの通信内容の確認を行った上で利用する必要があります。
又、通信異常が発生した場合の考慮も必要で、異常時の文字列の指定の機能とともに、REST通信時のHTTPステータスコードを取得する機能もあります。
通信時間についても、タイムアウト時間の指定とともに、送受信の時間情報を取得することもできます。

サブエージェントが提供するサービスと連携する方法には、以下の4種類があり、それぞれで設定される結果や受信データの取得方法が異なります。

sraix要素で指定する属性・子要素は以下になります。詳細は SubAgent を参照してください。

  • 属性
パラメータ タイプ 必須 説明
service string No カスタム外部サービスのサービス名。
botName string No botサービス連携のbotエイリアス名。
nlu string No NLUサービス連携のNLUエイリアス名。
template string No 汎用RESTサービス連携用の雛形名。
default string No 通信異常発生時の結果文字列。
timeout string No 通信タイムアウト時間(秒単位)を ‘1’ 以上の整数で指定。未指定時は ‘10’。
  • 子要素
サブエージェントの連携方法によって指定する子要素が異なります。SubAgent を参照してください。
尚、子要素の内容に不正があった場合、処理例外が発生することがあります。
以下は、カスタム外部サービスを利用した例です。
尚、日本語の場合、sraix要素の内容が全て結合されて空白区切りにならない場合があるため、引数間に space を指定しています。
  • 使用例
<category>
    <pattern>*から*までの乗り換え案内</pattern>
    <template>
        <sraix service="myService">
            <star/>
            <space />
            <star index="2"/>
        </sraix>
    </template>
</category>
Input: 東京から大阪までの乗り換え案内
Output: 10:00発の、のぞみが一番早く着きます。

関連項目: star, space, SubAgent

star

[1.0]

star要素は、入力文に対して、pattern要素(ワイルドカードを含む)に該当した文字列を取得するために使用し、先頭から順に識別番号(1〜)が振られます。
ワイルドカードとは、1つ以上の文字列を指定する *, _、もしくは、0以上の文字列を指定する ^, # に該当する文字列を意味し、pattern要素の setisetregexbot 要素に該当する文字列も対象になります。
文字列取得には識別番号を指定しますが、識別番号に対応した文字列が無かった場合には空文字が返ります。

star要素で取得する結果はパターンマッチング時の値が対象となるため、以下の様になります。

  • ワイルドカードの結果: 英数記号:半角、カタカナ:全角に変換されたマッチ文字列。
  • set要素の結果: マッチした 単語リスト(sets)ファイル の定義文字列。
  • iset要素の結果: マッチした isetの のwords定義文字列。
  • regex要素の結果: 正規表現としてマッチした、英数記号:半角、カタカナ:全角に変換された文字列。
  • bot要素の結果: マッチした propertiesファイル の定義文字列。
  • 属性
パラメータ タイプ 必須 説明
index string No star識別番号を ‘1’ 以上の整数で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>私は * と * が好きです。</pattern>
    <template>
        あなたは、 <star /> と <star index="2" /> が好きなのですね。
    </template>
</category>
Input: 私は花と猫が好きです。
Output: あなたは、花と猫が好きなのですね。

関連項目: sr, srai

system

[1.0]

system要素を使用すると、システムコールを利用することができます。
ユーザがオペレーティングシステムを知っていてシェルスクリプトを注入できれば、基本システムへ自由にアクセスできるようになる為、セキュリティ対策として。デフォルト環境では使用できません。
利用が必要な場合は、コンフィグレーションの overrides定義 で、allow_system_aiml に ‘true’ を設定する必要があります。
system要素の結果はシステム環境に依存しますが、システムコールが利用できない状態での結果は空文字になります。
  • 使用例
<category>
    <pattern>LIST ALL AIML FILES</pattern>
    <template>
        <system>ls -l *.aiml</system>
    </template>
</category>

that

[1.0]

that要素は、category の子要素としても定義があり、直前の応答文との一致判定に利用されますが、templateの要素としての that は、過去の応答文を取得する要素として使用します。
履歴の指定には履歴番号を使用し、‘0’が現在(未確定の為、指定不可)で、数値が大きくなるほど過去の履歴を指定することになります。’-1’を指定すると最古の応答文が取得できます。
該当する履歴がない履歴番号を指定した場合、取得失敗として空文字を返します。
  • 属性
パラメータ タイプ 必須 説明
index string No 履歴番号を ‘0’ 以外の整数値で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>こんにちわ</pattern>
    <template>
         こんにちは
    </template>
</category>

<category>
    <pattern>すみません</pattern>
    <template>
         <that />ですね
    </template>
</category>
Input: こんにちわ
Output: こんにちは
Input: すみません
Output: こんにちはですね

関連項目: that(pattern), thatstar

thatstar

[1.0]

thatstar要素は、that で指定したワイルドカードに対応する文字列を取得します。
patternに対する star と同じ方法でアクセスされますが、patternのワイルドカードではなく、thatに指定されたワイルドカードを利用する際に使用します。
文字列取得には識別番号を指定しますが、識別番号に対応した文字列が無かった場合には空文字が返ります。
  • 属性
パラメータ タイプ 必須 説明
index string No star識別番号を ‘1’ 以上の整数で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>...</pattern>
    <template>
         コーヒーが好きですか?
    </template>
</category>

<category>
    <pattern>はい</pattern>
    <that> * が好きですか?</that>
    <template>
        私も<thatstar />が好きです。
    </template>
</category>
Input: …
Output: コーヒーが好きですか?
Input: はい
Output: 私もコーヒーが好きです。

関連項目: that(pattern), that, star, topicstar

think

[1.0]

think要素は、内容の処理結果を応答文に反映せずに、Bot内での処理を実施する要素です。結果は常に空文字になります。

  • 使用例
<category>
    <pattern>私の名前は * です</pattern>
    <template>
       <think>
           <set name="name"><star /></set>
       </think>
       あなたの名前を覚えました。
    </template>
</category>

topicstar

[1.0]

topicstar要素は、topic で指定したワイルドカードに対応する文字列を取得します。
patternに対する star と同じ方法でアクセスされますが、patternのワイルドカードではなく、topicに指定されたワイルドカードを利用する際に使用します。
文字列取得には識別番号を指定しますが、識別番号に対応した文字列が無かった場合には空文字が返ります。
  • 属性
パラメータ タイプ 必須 説明
index string No star識別番号を ‘1’ 以上の整数で指定。未指定時は ‘1’。
  • 使用例
<category>
    <pattern>私はコーヒーが好きです。</pattern>
    <template>
        <think><set name="topic">beverages コーヒー</set></think>
        わかりました。
    </template>
</category>

<topic name="beverages *">
    <category>
        <pattern>私の好きな飲み物は?</pattern>
        <template><topicstar/>です。</template>
    </category>
</topic>
Input: 私はコーヒーが好きです。
Output: わかりました。
Input: 私の好きな飲み物は?
Output: コーヒーです。

関連項目: topic(pattern), star, thatstar

uniq

[2.0]

uniq要素は select と同様に、起動時に展開するRDFファイルの内容と、addtriple で追加されたRDFナレッジベースを対象に検索を行い、該当する情報を取得します。
selectとの違いは、selectは検索結果の複数候補をリスト形式で全てを返すのに対し、uniqは重複した候補を除外した結果を空白区切りで返す点です。
詳細は RDFサポート を参照してください。
uniq要素での検索では、取得したい項目に対して ‘?’ を指定します。
検索結果がなかった場合には、コンフィグレーション定義の default-get の値が返ります。
  • 子要素
パラメータ タイプ 必須 説明
subj string No 検索対象のsubject (主語)の値、又は、’?’
pred string No 検索対象のpredicate (述語)の値、又は、’?’
obj string No 検索対象のobject (目的語)の値、又は、’?’
uniq要素には、子要素として、subjpredobj のいずれか1つが最低限必要です。同一子要素が複数指定された場合、最後の指定が有効になります。
‘subj’、’pred’、’obj’の指定を省略した場合、省略された項目の全データが合致するものとして扱います。
subjectの一覧を取得する場合、以下の様に記述します。
結果として、subjectの一覧が空白区切りで出力されますが、重複したものは除外されます。(空白区切りのため、RDFとして空白を含むデータが登録されていた場合には注意が必要です。)
<category>
    <pattern>subject list</pattern>
    <template>
        <uniq>
            <subj>?</subj>
        </uniq>
    </template>
</category>

以下の例では、結果的に、RDFナレッジベースに対して、predicate=”は”, object=”バラ科” を指定した検索を行って、’subject’の一覧を取得しています。

  • 使用例
<category>
    <pattern>*  *</pattern>
    <template>
        <addtriple>
            <subj><star /></subj>
            <pred></pred>
            <obj><star index="2"/></obj>
        </addtriple>
        登録しました
    </template>
</category>

<category>
    <pattern>探して * * *</pattern>
    <template>
        <uniq>
            <subj><star /></subj>
            <pred><star index="2"/></pred>
            <obj><star index="3"/></obj>
        </uniq>
    </template>
</category>
Input: 桜 は バラ科
Output: 登録しました
Input: 苺 は バラ科
Output: 登録しました
Input: 探して 桜 は ?
Output: バラ科
Input: 探して ? は バラ科
Output: 桜 苺

関連項目: addtriple, deletetriple, select, RDFサポート

uppercase

[1.0]

uppercase要素は、対象となる文字列内の半角英字を大文字にします。英字以外に、大文字・小文字が存在するギリシャ文字等にも対応します。

  • 使用例
<category>
    <pattern>こんにちは * です</pattern>
    <template>
        こんにちは<uppercase><star /></uppercase>さん
    </template>
</category>

<uppercase />は、<uppercase><star /></uppercase>と同義です。書き換えると以下の様になります。

  • 使用例
<category>
    <pattern>こんにちは * さん</pattern>
    <template>
        こんにちは<uppercase />さん
    </template>
</category>
Input: こんにちは george washington さん
Output: こんにちはGEORGE WASHINGTONさん

関連項目: lowercase

vocabulary

[1.0]

vocabulary要素は、Botの単語数として起動時に展開された以下の項目の合計数を返します。

日本語の場合、単語分割した上で積算します。
単語の重複は精査していないため、累計値になります。
  • 使用例
<category>
    <pattern>知っている単語数は?</pattern>
    <template>
        <vocabulary />です。
    </template>
</category>
Input: 知っている単語数は?
Output: 10000です。

関連項目: size

video

[2.1]

video要素は、リッチメディア要素で、ビデオの情報を返すことができます。 ビデオのURLやファイル名を指定することができます。

対話エンジンでは、リッチメディア要素に対して、XML形式の結果を返します。 実際の画面描画等は、コンフィグレーション定義のclientの renderer で指定した処理クラスの制御に依存します。

  • 使用例
<category>
    <pattern>ビデオ表示</pattern>
    <template>
        <video>https://url.for.video</video>
    </template>
</category>

word

[1.0]

word要素は内部処理で生成する要素で、template内に記述されているテキスト部分(子要素内を含む)が展開されます。

  • 使用例
<category>
    <pattern>HELLO</pattern>
    <template>Hi there!</template>
</category>

この使用例の場合、’Hi there!’ がword要素として展開されます。

xml

[1.0]

xmlという要素は存在しませんが、対話エンジンで使用可能な要素以外がXML形式で指定されている場合、XML形式のままで結果に反映します。 これにより、templateの応答の一部として、XML形式の要素を記載することができます。

  • 使用例
<category>
    <pattern> * をボールド表示</pattern>
    <template>
        <bold><star /></bold>
    </template>
</category>
Input: 対象範囲ををボールド表示
Output: <bold>対象範囲</bold>。

パターンマッチング

入力文とpattern要素とのマッチングは、それぞれに対してコード変換を行った上で実施します。 マッチングで使用する文字は、英数記号は半角文字、カタカナは全角文字になります。

入力文に対しては、コンフィグレーション定義によりマッチングで使用しない文字を除去する制御も行います。 コンフィグレーション定義は、tokenizer定義 のpunctuation_charsで指定します。

AIMLのパターンマッチングでは、ユーザ入力に対してワイルドカードを利用してマッチングを行うことができます。 ワイルドカードの指定には *, ^ , _, # があり、各々利用方法が異なります。

ただし、ワイルドカードを連続して記述したpattern要素を指定する場合には、oneormorezerooremore の混合は避けてください。誤動作が発生する場合があります。

* ワイルドカード

* を用いることで、ユーザ入力の単語を抽出することができ、1つ以上の合致を判定します。(oneormoreワイルドカード)

<pattern>こんにちは *</pattern>

この例では、

こんにちは!
こんにちは山田さん
こんにちは誰ですか?

にマッチします。 しかし、この例では”こんにちは”に続く単語を期待しているため、”こんにちは”という入力のみにはマッチしません。

^ ワイルドカード

^ を用いることで、0以上の単語マッチングを指定できます。(zeroormoreワイルドカード) すなわち、ワイルドカードに相当する単語が無くても、指定した単語の表記のみがマッチングした場合でも評価結果が成り立ちます。

<pattern>こんにちは ^</pattern>

この例では、* と異なり、

こんにちは
こんにちは!
こんにちは山田さん
こんにちは誰ですか?

と、”こんにちは”単体入力にもマッチします。

_# ワイルドカード

*^ は、単語のマッチングより優先順位が低い評価を行います。 すなわち、

<pattern>こんにちは いい天気ですね</pattern>
<pattern>こんにちは ^</pattern>
<pattern>こんにちは *</pattern>

という定義がされていた場合、”こんにちは いい天気ですね”という入力の場合一番上のpatternにマッチします。

これに対し、 _# は単語のマッチングより高い優先順位で評価されます。 _ は、 * 同様、1以上のマッチングで合致判定を行います。(oneormoreワイルドカード) # は、 ^ 同様、0以上のマッチングで合致判定を行います。(zeroormoreワイルドカード)

<pattern>こんにちは いい天気ですね</pattern>
<pattern>こんにちは _</pattern>
<pattern>こんにちは #</pattern>

という定義がされていた場合、”こんにちは いい天気ですね”という入力の場合 # にマッチします。

優先単語指定

$ 指定した単語は、 _ , # より優先して評価されます。

<pattern>こんにちは $いい天気ですね</pattern>
<pattern>こんにちは _</pattern>
<pattern>こんにちは #</pattern>

という定義がされていた場合、”こんにちは いい天気ですね”という入力の場合一番上のpatternにマッチします。

判定優先順位

patternでのワイルドカード指定時の優先順位は以下のようになります。

  • $(単語)
  • # ( 0以上 )
  • _ ( 1以上 )
  • (単語)
  • ^ ( 0以上 )
  • * ( 1以上 )

ファイル管理

対話プラットフォームで使用するファイルに関して説明します。
以降の説明では、主に、対話プラットフォームで利用するファイル管理方式として、ローカルファイルを指定しています。
ファイル管理方式には、ローカルファイル以外にも、データベースでの管理もありますが、構成は同じになります。
定義ファイルの拡張子は、シナリオファイルがaiml、サブエージェント連携用の定義ファイルがyaml、その他の主な設定ファイルはtxtです。
(その他、クラス定義ファイルのconfなども使用します。)

ディレクトリ構成

シナリオファイルのディレクトリ構成は以下のとおりです。
storage 各種ファイルディレクトリ
├── braintree AIML展開ファイルディレクトリ
├── categories シナリオファイルディレクトリ
│   └── *.aiml
├── conversations 対話履歴情報ディレクトリ
│   └── *.conv
├── debug デバッグ情報ディレクトリ
│   ├── duplicates.txt
│   ├── errors.txt
│   ├── errors_collection.txt
│   └── *.log
├── learnf 動的生成シナリオファイルディレクトリ
│   └── *.aiml
├── licences ライセンスファイルディレクトリ
│   └── license.keys.txt
├── lookups 置換辞書ファイルディレクトリ
│   ├── regex.txt
│   ├── denormal.txt
│   ├── gender.txt
│   ├── normal.txt
│   ├── person.txt
│   └── person2.txt
├── maps mapリストファイルディレクトリ
│   └── *.txt
├── nodes 要素処理クラス定義ファイルディレクトリ
│   ├── pattern_nodes.conf
│   └── template_nodes.conf
├── properties プロパティ定義ファイルディレクトリ
│   ├── nlu_servers.yaml
│   ├── botnames.yaml
│   ├── rest_templates.yaml
│   ├── defaults.txt
│   ├── properties.txt
│   └── json JSON形式プロパティ定義ファイルディレクトリ
│       └── *.json
├── prosessing 文編集クラス定義ファイルディレクトリ
│   ├── preprocessors.conf
│   └── postprocessors.conf
├── rdfs RDFファイルディレクトリ
│   └── *.txt
├── security セキュリティファイルディレクトリ
│   └── usergroups.yaml
├── sets setリストファイルディレクトリ
│   └── *.txt
└── spelling スペルチェックファイルディレクトリ
    └── corpus.txt

エンティティ

対話プラットフォームでは、格納するデータの種類によってエンティティを規定し、各々でファイル管理を行います。
利用するファイルの構成は、コンフィグファイル(config.yaml)で定義し、どのデータの種類を利用するかを、以下のエンティティを設定するか否かで指定します。
尚、エンティティには、共通的に使用するものと、特定要素のみで使用するものがありますが、定義や管理の方法は同じです。
以下のエンティティの中で、”自動生成”が”No”のデータは編集が可能で、起動時に展開して利用します。
“単一ファイル”が”Yes”のデータは対象ファイルを1つだけ指定でき、”No”のファイルはディレクトリ指定を行い複数のファイルを指定します。
  • 共通のエンティティ
エンティティ 格納内容 単一ファイル 自動生成 説明
binaries ツリーデータ No Yes AIMLを展開した検索用ツリーのバイナリデータを格納します。
braintree ツリーデータ No Yes AIMLを展開した検索用ツリーのXML形式データを格納します。
categories 対話用AIML No No 対話の制御に使用するAIMLファイル群を格納します。
conversations 対話履歴情報 No Yes ユーザ毎の過去を含めた対話処理内容(変数値を含む)の履歴情報ファイルを格納します。
defaults プロパティリスト Yes No 初期起動時に展開するグローバル変数(name)の定義ファイルを格納します。
duplicates 重複指定情報 Yes Yes (デバッグ用)AIMLファイル展開時のcategory重複情報ファイルを格納します。
errors エラー情報 Yes Yes (デバッグ用)AIMLファイル展開時のエラー情報ファイルを格納します。
errors_collection 登録エラー情報 Yes Yes (デバッグ用)辞書などの各種定義ファイル登録時のエラー情報ファイルを格納します。
license_keys ライセンスキー Yes No 外部接続等で必要になるライセンスキーファイルを格納します。
pattern_nodes クラス定義リスト Yes No patternの各要素の処理クラス定義ファイルを格納します。
postprocessors クラス定義リスト Yes No レスポンスの応答文に対して編集を行う場合の処理クラス定義ファイルを格納します。
preprocessors クラス定義リスト Yes No リクエストのユーザ発話に対して編集を行う場合の処理クラス定義ファイルを格納します。
properties プロパティリスト Yes No patternの bot、及び、templateの bot 要素で使用するプロパティ定義ファイルを格納します。
properties_json JSON形式プロパティ No No 主にtemplateの bot 要素で使用するJSON形式プロパティファイルを格納します。
spelling_corpus スペルチェック情報 No No スペルチェックを行う場合のもとになるコーパスファイルを格納します。
template_nodes クラス定義リスト Yes No templateの各要素の処理クラス定義ファイルを格納します。
  • Pattern要素用のエンティティ
エンティティ 格納内容 単一ファイル 自動生成 説明
regex_templates 正規表現リスト Yes No regex 要素のtemplate指定で使用する正規表現リストファイルを格納します。
sets 対象単語リスト No No set 要素で使用する単語リストファイルを格納します。
  • Template要素用のエンティティ
エンティティ 格納内容 単一ファイル 自動生成 説明
denormal 変換辞書 Yes No denormalize 要素での変換に使用する辞書ファイルを格納します。
gender 変換辞書 Yes No gender 要素での変換に使用する辞書ファイルを格納します。
learnf categoryリスト No YES learnf 要素の処理で作成されるcategories情報を、ユーザ毎に格納します。
logs ログ情報 No YES log 要素の処理で作成されたログ情報を、ユーザ毎に格納します。
maps プロパティリスト No No map 要素での変換に使用する辞書ファイルを格納します。
normal 変換辞書 Yes No normalize 要素での変換に使用する辞書ファイルを格納します。
person 変換辞書 Yes No person 要素での変換に使用する辞書ファイルを格納します。
person2 変換辞書 Yes No person2 要素での変換に使用する辞書ファイルを格納します。
rdf RDFデータリスト No No RDF 関連要素の処理対象となるRDFデータの定義ファイルを格納します。
usergroups セキュリティ情報 Yes No authorise 要素で使用するロール定義ファイルを格納します。
  • サブエージェント連携用のエンティティ
エンティティ 格納内容 単一ファイル 自動生成 説明
nlu_servers 利用NLU接続情報 Yes No NLUマッチング対象のNLUと、sraix 要素で実施するNLU通信に使用するアクセス情報の定義ファイルを格納します。
bot_names 公開Bot接続情報 Yes No sraix 要素で実施する公開Botとの通信に使用するアクセス情報の定義ファイルを格納します。
rest_templates REST通信雛形情報 Yes No sraix 要素で実施する汎用REST通信で使用する雛形の定義ファイルを格納します。

ローカルファイル利用時の定義例

エンティティ定義

以下の例は、console という名前のクライアントを使用した場合のエンティティの定義例です。
クライアントの設定では、 storage というセクションに、 entities というサブセクションがあります。
ファイルの管理方法として、各エンティティ毎に入出力の制御を行う方式(ストア)の名称を指定します。
ここでは、ストア方式名:file を指定しています。
console:
  storage:
      entities:
          binaries: file
          braintree: file
          categories: file
          conversations: file
          defaults: file
          duplicates: file
          errors: file
          errors_collection: file
          license_keys: file
          pattern_nodes: file
          postprocessors: file
          preprocessors: file
          properties: file
          properties_json: file
          spelling_corpus: file
          template_nodes: file
          regex_templates: file
          sets: file
          denormal: file
          gender: file
          learnf: file
          logs:   file
          maps: file
          normal: file
          person: file
          person2: file
          rdf: file
          nlu_servers: file
          bot_names: file
          rest_templates: file
          usergroups: file

fileストレージエンジンの定義

同じ storageセクションのサブセクションstoresで、ストア内での実処理を行うストレージエンジンを指定します。
ここでは、ストア名:fileに対して、”type: file”で、ローカルファイルの入出力を行うストレージエンジンを利用することを指定しています。
ローカルファイル入出力(file指定)の場合、実処理を行うストレージエンジンの名称は、 エンティティ名+'_storage' になります。
エンティティ毎のストレージエンジンの設定は、以下のように ‘config’サブセクションで行います。
stores:
    file:
        type: file
        config:
          binaries_storage:
            file: ./storage/braintree/braintree.bin
          braintree_storage:
            file: ./storage/braintree/braintree.xml
          categories_storage:
            dirs: ./storage/categories
            subdirs: true
            extension: aiml
          conversations_storage:
            dirs: ./storage/conversations
          defaults_storage:
            file: ./storage/properties/defaults.txt
          duplicates_storage:
            file: ./storage/debug/duplicates.txt
          errors_storage:
            file: ./storage/debug/errors.txt
          errors_collection_storage:
            file: ./storage/debug/errors_collection.txt
          license_keys_storage:
            file: ./storage/licenses/license.keys
          pattern_nodes_storage:
            file: ./storage/nodes/pattern_nodes.conf
          postprocessors_storage:
            file: ./storage/processing/postprocessors.conf
          preprocessors_storage:
            file: ./storage/processing/preprocessors.conf
          properties_storage:
            file: ./storage/properties/properties.txt
          properties_json_storage:
            dirs: ./storage/properties/json
            extension: json
          spelling_corpus_storage:
            file: ./storage/spelling/corpus.txt
          template_nodes_storage:
            file: ./storage/nodes/template_nodes.conf
          regex_templates_storage:
            file: ./storage/lookups/regex.txt
          sets_storage:
            dirs: ./storage/sets
            extension: txt
          denormal_storage:
            file: ./storage/lookups/denormal.txt
          gender_storage:
            file: ./storage/lookups/gender.txt
          learnf_storage:
            dirs: ./storage/learnf
          logs_storage:
            dirs: ./storage/debug
          maps_storage:
            dirs: ./storage/maps
            extension: txt
          normal_storage:
            file: ./storage/lookups/normal.txt
          person_storage:
            file: ./storage/lookups/person.txt
          person2_storage:
            file: ./storage/lookups/person2.txt
          rdf_storage:
            dirs: ./storage/rdfs
            subdirs: true
            extension: txt
          nlu_servers_storage:
            dirs: ./storage/properties/nlu_servers.yaml
          bot_names_storage:
            dirs: ./storage/properties/botnames.yaml
          rest_templates_storage:
            dirs: ./storage/properties/rest_templates.yaml
          usergroups_storage:
            file: ./storage/security/usergroups.yaml

‘config’サブセクションでの定義は、対象となるエンティティによって、単一ファイルや、複数ファイルの利用を示す記載方法をとります。

単一ファイルのエンティティの場合

単一ファイルを指定するエンティティの場合、’file’属性でファイルパスを指定します。

usergroups_storage:
    file: ./storage/security/usergroups.yaml

複数ファイルの利用が可能なエンティテイの場合

複数ファイルが利用可能なエンティティの場合、以下の3つの属性を指定します。 ただし、自動生成対象のエンティティの場合、ディレクトリパスのみの指定となります。

  • dirs: 対象ファイルディレクトリパスを指定。
  • subdirs: 対象ファイルディレクトリ配下のサブディレクトリをサーチするかどうかをtrue/falseで指定。
  • extension: ロードするファイルタイプの拡張子を指定。
categories_storage:
  dirs: ./storage/categories
  subdirs: true
  extension: aiml

conversations_storage:
  dirs: ./storage/conversations

尚、自動生成対象外で、複数ファイルを指定することが可能なストレージエンジンは、以下の5つになります。

  • categories_storage
  • sets_storage
  • maps_storage
  • properties_json_storage
  • rdf_storage

※sets_storage/maps_storage/properties_json_storageは、ファイル名を識別子として利用するため、同一ファイル名の重複配置を防止する意味で、 ‘subdirs: false’ を指定することを推奨します。

データベース利用時の定義例

データベースで管理する場合の例として、Redisを利用した例を以下に示します。

エンティティ定義

Redisで管理するエンティティに対して、storageのentitiesサブセクションで、ストア方式名:redis を指定しています。

console:
  storage:
      entities:
          binaries: redis
          braintree: redis
          categories: file
          :

Redisでの入出力が可能なエンティティは、以下のものになります。

  • binaries : AIMLを展開した検索用ツリーのバイナリデータを格納。
  • braintree : AIMLを展開した検索用ツリーのXML形式データを格納。
  • conversations : ユーザ毎の過去を含めた対話処理内容(変数値を含む)の履歴情報を格納。
  • duplicates : (デバッグ用)AIMLファイル展開時のcategory重複情報を格納。
  • errors : (デバッグ用)AIMLファイル展開時のエラー情報を格納。
  • errors_collection : (デバッグ用)辞書などの各種定義ファイル登録時のエラー情報ファイルを格納。
  • learnf : learnf 要素の処理で作成されるcategories情報を、ユーザ毎に格納。
  • logs : log 要素の処理で作成されたログ情報を、ユーザ毎に格納。

Redisストレージエンジンの定義例

storageセクションのstoresのサブセクションで、ストア名:redisに対して、”type: redis”で、Redisに対する入出力を行うことを指定しています。
‘config’サブセクションでは、Redisの利用に必要な共通パラメータを指定し、実際の入出力は、エンティティ毎のストレージエンジンでキー設定を含めて行います。
stores:
   redis:
       type: redis
       config:
           host: localhost
           port: 6379
           db: 0
           prefix: programy
           drop_all_first: false
           username: xxx
           password: xxx
           ssl: false
           timeout: 1

尚、username は、redis-server:V6.0以降の利用時に指定が可能です。

定義ファイルの記述方法

編集可能なファイルで、AIML以外に、使用することの多い定義ファイルについて記述方法を説明します。

各定義ファイルは、シナリオ(AIML)の解析前に展開します。この為、定義ファイルに登録されていない名称等を使用したAIML記述は無効になります。
Brain コンフィグレーション に以下の定義を行うことで、各定義ファイル展開時の異常情報をまとめて errors_collection エンティティで指定したファイルに出力することができます。
brain:
  debugfiles:
    save-errors_collection: true

プロパティリストファイル

以下のエンティティで指定するファイルは、botのプロパティや変数への値設定を目的として ’名称: 値’ の形式で記述します。

  • defaults : グローバル変数(name)の初期値を定義。
  • properties : patternの bot、及び、templateの bot 要素で使用するbotのプロパティを定義。
defaults
defaults エンティティでは、シナリオで使用するグローバル変数(name)の値設定を初期起動時に行うことができます。
ただし、ユーザ毎の対話情報履歴が存在する場合は、履歴上の最新値が反映されるため、既に存在するの変数に対する変更は行わず、存在しない変数のみを追加します。
以下の例では、initial_variable(name変数)の値として、ユーザ毎の初回対話時に”初期値”を設定します。
initial_variable: 初期値
properties
properties エンティティは、templateの bot 要素での情報取得に使用するとともに、マッチングで指定する bot 要素でも使用できます。
JSON形式の値を設定する場合には、properties_json エンティティも使用できます。
”名称” 内容 説明
name ボット名 bot 要素のname属性に’name’を指定した際に取得できる値。
birthdate ボット作成日 bot 要素のname属性に’birthdate’を指定した際に取得できる値。
grammar_version グラマーバージョン bot 要素のname属性に’grammar_version’を指定した際に取得できる値。
app_version アプリバージョン bot 要素のname属性に’app_version’を指定した際に取得できる値。
version シナリオバージョン 他の項目と同様にname指定で取得するとともに、 program 要素で取得するバージョン情報の値。
以下の定義を指定すると、コンフィグレーションで定義された制御値を変更して、独自の動作を指定することができます。
記述として、名称のみを指定することで、制御値を空文字に変更する(制御を無効化する)こともできます。
名称 内容 説明 対応config定義
default-response デフォルトレスポンス マッチするpatternがなかった場合に返す応答文。 Bot定義のdefault_response
exception-response 例外レスポンス 処理例外が発生した場合に返す応答文。 Bot定義のexception_response
default-get 取得失敗文字列 未定義変数に対し、 get 要素等でデータ取得を行なった場合に設定される文字列。 Brain定義(defaults)のdefault-get
default-property property取得失敗文字列 bot 要素で未定義の変数名を指定した場合に設定される文字列。 Brain定義(defaults)のdefault-property
default-map map変換失敗文字列 map 要素で変換対象の文字列がなかった場合に設定される文字列。 Brain定義(defaults)のdefault-map
joiner_terminator 文終端文字 応答文の語尾句等を自動的に付与する文字列を指定します。指定なしの場合何も付与しません。 Bot定義(joiner)のterminator
joiner_join_chars 文終端除外文字 joiner_terminatorの指定で文終端文字を自動付与する際に、joiner_terminator指定の文字を結合除外する文字列を指定します。 指定なしの場合、joiner_terminatorで指定した文字を付与します。 Bot定義(joiner)のjoin_chars
splitter_split_chars 文分割文字 内部的に文章分割を行う文字を指定します。指定された文字列が文中に含まれていると、複数文として扱い、responseに複数の応答文を結合した文字列を返します。ただし、metadataは最終文で設定した内容のみが返ります。指定なしの場合、 発話文を1文として扱います。 Bot定義(splitter)のsplit_chars
punctuation_chars 区切り文字 区切り文字扱いを行う文字を指定します。区切り文字はマッチング対象外として、発話文や、topic・thatの対象文から除外してマッチング処理を行います。 Brain定義(tokenizer)のpunctuation_chars
before_concatenation_rule 文字列連結時の空白挿入条件(前条件) 応答文生成等で、生成された複数の文字列を連結する時点で空白を挿入する場合の前文字列の形式を正規表現で指定します。 Brain定義(tokenizer)のbefore_concatenation_rule
after_concatenation_rule 文字列連結時の空白挿入条件(後条件) 応答文生成等で、生成された複数の文字列を連結する時点で空白を挿入する場合の後文字列の形式を正規表現で指定します。 Brain定義(tokenizer)のafter_concatenation_rule

default-get の設定値は、json や、RDFの検索 select 等の要素での取得失敗時に設定されるとともに、default-propertydefault-map が未定義の場合の値としても使用されます。

  • 設定例
name:基本応答
birthdate:March 01, 2019

version: v0.0.1
grammar_version:0.0.1
app_version: 0.0.1

default-response: すみません、意味がわかりませんでした。
exception-response: 処理例外が発生しました。
default-get: わかりません
default-property: 定義されていません
default-map: map登録されていません

joiner_terminator: 。
joiner_join_chars: .?!。?!
splitter_split_chars:  。
punctuation_chars: ;'",!()[]:’”;、。!()「」
before_concatenation_rule: .*[a-z]
after_concatenation_rule: [a-z].*

JSON形式の定義をpropertyとして設定する場合、改行を含めて記入することで視覚的な確認を容易にする方法として、properties_json エンティティを使用することができます。

properties_json エンティティは、templateの bot 要素でのJSON形式の情報取得に使用するもので、マッチングで使用することは推奨できません。
properties_json エンティティでは、その配下にJSONファイルを配置することで、ファイル名(拡張子を除く)をそのまま名称として使用することができます。(大文字/小文字・全角/半角を区別します。)
尚、propertyの値には、JSONファイルの内容そのものではなく、JSONデータとして変換された文字列が設定されます。
joiner_terminator

応答文の語尾句等を自動的に付与する文字列を指定します。 設定例に、”こんにちは”を指定した場合、

  • 設定例
joiner_terminator: 。
<category>
    <pattern>こんにちは</pattern>
    <template>今日も元気に行きましょう</template>
</category>
Input: こんにちは
Output: 今日も元気に行きましょう。

対話APIのレスポンスの応答文:responseの文末に自動的に付与される句点「。」を抑止する場合には、以下の定義を行ってください。 (”:”の後ろに何も指定しないことで、無効化することができます。)

joiner_terminator:

未指定にすると、応答文に句点が付与されません。

Input: こんにちは
Output: 今日も元気に行きましょう
joiner_join_chars
joiner_join_chars(結合除外文字)は、joiner_terminator(文終端文字)を自動付与する際に、結合除外する文字列を指定します。
joiner_join_chars未指定の場合、 応答文に”今日も元気に行きましょう。”、”いい気分ですね!”などの応答文を記載した場合に、joiner_terminator指定の文字を結合すると、
“今日も元気に行きましょう。。”、”いい気分ですね!。”のように、応答文記載の文末文字に加えjoiner_terminatorで指定した句点を結合した応答文が返ります。
joiner_join_charsを指定しておくと、”そうですね!”、”こんにちは。”と、joiner_terminatorを結合しない応答文を返します。
  • 設定例
joiner_terminator: 。
joiner_join_chars: .?!。?!
<category>
    <pattern>こんにちは</pattern>
    <template>今日も元気に行きましょう。</template>
</category>
<category>
    <pattern>今日もいい天気ですね</pattern>
    <template>いい気分ですね!</template>
</category>
Input: こんにちは
Output: 今日も元気に行きましょう。
Input: 今日もいい天気ですね
Output: いい気分ですね!

joiner_join_charsを未指定にすると、joiner_terminatorで指定した文字が必ず結合されます。

joiner_terminator: 。
joiner_join_chars:
Input: こんにちは
Output: 今日も元気に行きましょう。。
Input: 今日もいい天気ですね
Output: いい気分ですね!。
splitter_split_chars

内部的に文章分割を行う文字を指定します。 指定された文字列が文中に含まれていると、複数文として扱い、responseに複数の応答文を結合した文字列を返します。 splitter_split_charsに”。”を指定した場合、発話文が”こんにちは。今日もいい天気ですね。”のような1文が、 分割処理され “こんにちは”と”今日もいい天気ですね”の2文になります。

  • 設定例
joiner_terminator: 。
splitter_split_chars: 。
<category>
    <pattern>こんにちは</pattern>
    <template>今日も元気に行きましょう</template>
</category>
<category>
    <pattern>今日もいい天気ですね</pattern>
    <template>いい気分ですね</template>
</category>
Input: こんにちは。今日もいい天気ですね。
Output: 今日も元気に行きましょう。いい気分ですね。

splitter_split_charsを未指定にすると、発話文が分割されないため、”こんにちは。今日もいい天気ですね。”を一文としたマッチングを行い、前述のAIMLではマッチする発話がないため応答なしになります。

splitter_split_chars:
Input: こんにちは。今日もいい天気ですね。
Output: すみません、意味がわかりませんでした。
punctuation_chars

入力文の区切り文字扱いを行う文字を指定します。区切り文字はマッチング対象外とし発話文から除外した形でマッチング処理を行います。 “こんにちは。”および”こんにちは”という入力がある場合、punctuation_charsに指定された文字は、無視され同一発話扱いになります。

  • 設定例
punctuation_chars: ;'",!()[]:’”;、。!()「」
<category>
    <pattern>こんにちは</pattern>
    <template>今日も元気に行きましょう</template>
</category>
Input: こんにちは。
Output: 今日も元気に行きましょう。
Input: こんにちは
Output: 今日も元気に行きましょう。

punctuation_charsを未指定にすると、”。”もマッチ対象となるため、”こんにちは。”と”こんにちは”は別発話扱いとなります。

punctuation_chars:
Input: こんにちは
Output: 今日も元気に行きましょう。
Input: こんにちは。
Output: すみません、意味がわかりませんでした。
concatenation_rule
template要素の展開処理では、子要素毎の結果文字列を結合して応答文を生成します。
英文であれば一律に単語間に空白を挿入して結合しますが、日英混合文では、前後の文字列(単語)の関係で制御する必要があり、本設定にて、空白を挿入する対象の文字列形式を正規表現で指定します。
before_concatenation_rule: .*[ -~]  (前文字列の語尾が半角英数字または記号)
after_concatenation_rule: [ -~].*   (後文字列の先頭が半角英数字または記号)
  • 設定例 (前文字列の語尾が半角英字で、後文字列の先頭が半角英字の場合に、空白を挿入。)
before_concatenation_rule: .*[a-z]
after_concatenation_rule: [a-z].*
<category>
    <pattern>* and *</pattern>
    <template><star /><star index="2" /></template>
</category>
Input: sugar and milk
Output: sugar milk。
Input: sugar and ミルク
Output: sugarミルク。
Input: 砂糖 and milk
Output: 砂糖milk。
Input: 砂糖 and ミルク
Output: 砂糖ミルク

全角英字を含めて対応する場合の指定は、以下の様になります。(正規表現では、大文字・小文字を区別しないため、便宜上、全角を大文字で指定しています。)

before_concatenation_rule: .*[a-zA-]
after_concatenation_rule: [a-zA-].*

英数字と通貨記号の間に空白を挿入する場合には、以下の設定を行います。

before_concatenation_rule: .*[a-z0-9]
after_concatenation_rule: [a-z0-9$¥].*

サブエージェント定義ファイル

以下のエンティティで指定するファイルは、利用するサブエージェント毎の接続情報を定義するため、yaml形式で記述します。 yaml形式の場合、記号が意味を持つ場合があるため、記号を含む文字列を指定する場合には、間に空白を入れない、または、文字列全体を “’” で囲む必要があります。

  • nlu_servers : 利用するNLUサーバに関するアクセス情報を定義します。
  • bot_names : 利用する公開Botに関するアクセス情報を定義します。
  • rest_templates : 利用するRESTサーバに関するアクセス情報を定義します。
nlu_servers

nlu_servers エンティティでは、次の3つの定義を行います。

  • sraix 要素で使用するNLUサーバのアクセス先情報を定義します。
  • マッチ処理に使用するNLUサーバのアクセス先情報を定義します。
  • マッチ処理時のNLUサーバ毎の通信時間の最大値を指定します。
‘sraix’要素で使用するNLUサーバ情報には、エイリアス名毎に、アクセス先URL(エンドポイント)、APIキーを設定し、’sraix’の属性: nlu でエイリアス名を指定することで利用できます。
尚、アクセス先URLの指定は必須で、エイリアス名は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で管理します。
以下の例は、2つのエイリアス名の定義を行った例です。1つ目はURLにAPIキー設定なし、2つ目はURLとともにAPIキーを設定しています。
servers:
  エイリアス名_1:
    url: http://localhost:5200/run
  エイリアス名_2:
    url: http://localhost:3000/run
    apikey: test_key
マッチ処理に使用するNLUサーバ情報についても、アクセス先URL(エンドポイント)、APIキーを設定します。 (name指定を除き、アクセス先URLの指定は必須です。)
複数のNLUサーバを利用する場合があるため、yaml記述にはリスト(行頭記号:’-‘)指定を行い、記述順序に従って、マッチ処理時のNLUサーバ通信を行います。
(1つのNLUサーバのみを利用する場合は、行頭記号:’-‘の指定は省略が可能です。)
尚、NLUマッチングでは、同一のURLに対する重複通信を抑止するため、同じURLが指定されている場合、2つ目以降の重複指定は無視されます。
以下の例は、1つ目はURL指定のAPIキー設定なし、2つ目はURL指定とともにAPIキーを設定、3つ目にはserversで定義したアクセス情報を使用することを指定しています。
nlu:
  - url: http://localhost:5201/run
  - url: http://localhost:3000/run
    apikey: test_key
  - name: エイリアス名_1
NLUサーバ毎の通信時間の最大値の指定は秒単位で、各サーバに共通の値として以下の様に指定します。最大値の時間を超えて通信が行われた場合、該当サーバとの通信は失敗したものとして扱います。
尚、本指定はNLUを利用したマッチ処理を行う場合に有効で、省略時には、コンフィグレーション定義で指定された値(又は、初期値:10秒)が使用されます。
timeout: 1
マッチ処理に使用するNLUサーバ情報を本ファイルで指定する場合には、コンフィグレーション定義に以下の指定が必要です。
この指定がない場合や、本ファイルにマッチ処理に使用するNLUサーバ情報が指定されていない場合には、コンフィグレーション定義のNLUサーバの情報を使用します。
(コンフィグレーション定義でもNLUサーバの情報が指定されていない場合には、マッチ処理にNLUは利用されません。)
brain:
  nlu:
    use_file: true
bot_names
bot_names エンティティでは、sraix 要素で使用する公開Botのアクセス先情報として、エイリアス名毎に、主にアクセス先URL(エンドポイント)、APIキーを設定します。
sraix要素では属性: botName でエイリアス名を指定することで公開Botを利用できます。
(指定する値は、Bot生成時に確定しますので、公開Botの提供者に確認する必要があります。)
尚、アクセス先URLの指定は必須で、エイリアス名は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で管理します。
以下の例は、2つのエイリアス名の設定を行った例です。1つ目はURLにAPIキー設定なし、2つ目はURLとともにAPIキーを設定しています。
bot:
  エイリアス名_1:
    url: http://localhost:5400/bots/botId_1/ask
  エイリアス名_2:
    url: http://localhost:5401/bots/botId_1/ask
    apikey: test_key

公開Botとの通信では、各種のパラメータが指定できるため、エイリアス名毎に、雛形情報として以下の指定も可能です。(url以外は省略が可能です。) 尚、通信時に使用されるパラメータの値には、sraix 要素での子要素指定の内容が優先して設定されます。

bot:
  エイリアス名:
    url: http://localhost:5401/bots/botId_1/ask
    apikey: test_key
    metadata: Send Data
    locale: ja-JP
    time: 2018-07-01T12:18:45+09:00
    topic: test
    deleteVariable: false
    config: '("loglevel": "info"}'
rest_templates
rest_templates エンティティでは、sraix 要素で行う汎用REST通信で使用する雛形情報をテンプレート名毎に設定します。
‘sraix’要素では属性: template でテンプレート名を指定することで汎用REST通信を行います。
尚、アクセス先情報である ‘host’ の指定は必須で、テンプレート名は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で管理します。
設定項目としては、汎用REST通信で指定できる全パラメータの指定が可能ですが、通信時に使用されるパラメータの値には、sraix 要素での子要素指定の内容が優先して設定されます。
以下の例は、2つのテンプレート名の設定を行った例です。1つ目は必須定義のhost設定のみ、2つ目では全パラメータを設定しています。
rest:
  テンプレート名_1:
    host: 'http://localhost:5300/rest'
  テンプレート名_2:
    host: 'http://localhost:5300/rest'
    method: POST
    query:  '"item":"1234"'
    header: '"Content-Type": "applicaton/json"'
    body: '{"key": "Send Data"}'

単語リストファイル

以下のエンティティで指定するファイルでは、処理対象となる単語・文字列を列記します。

  • sets : set 要素で使用するマッチ処理対象の単語リストを定義。
sets エンティティでは、set要素での情報参照がファイル名(拡張子を除く)で行われるため、情報の種類毎にファイルを分けることが可能です。
識別名は、ファイル名(拡張子を除く)を、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した名称で管理します。
マッチ処理も、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で行いますが、 star 要素で取得される値はファイルに記述したものになります。
尚、日本語の場合、マッチ処理時に行う単語分割の結果によって一致しない場合が発生するため、単語ではなく文字列としてのマッチ処理を行います。
以下の例は、都道府県名を列記したprefecture.txtの例です。
東京都
東京
神奈川県
神奈川
大阪府
大阪
 :

英文の場合でも、複数単語からなる文字列を指定することが可能で、マッチ処理では単語数が多いものが優先されます。 尚、英字リストと日本語リストとでは処理方式が異なるため、1つのファイル内に両者を混合させた場合の動作は保証されません。

正規表現リストファイル

以下のエンティティで指定するファイルでは、 ’正規表現名 : 正規表現文字列’ の形式で記述します。

  • regex_templates : regex 要素のtemplate指定で使用する正規表現リストを定義。
regex_templates エンティティでは、regex要素で行うマッチ処理に使用する正規表現文字列を、正規表現名毎で指定します。
regex要素側では、template属性で正規表現名を指定します。尚、正規表現の記述は、基本的に単語ベースで指定する必要があります。
尚、正規表現名は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で管理します。
記述例は、以下の様になります。
konnichiwa : こんにち[は|わ]
tomorrow : 明日|あす|あした
today : 今日|きょう
  :

変換辞書ファイル

以下のエンティティで指定するファイルは、変換用のテーブルを作成することを目的として 変換対象文字列と変換後文字列の関係を列記します。

  • maps : map 要素用の変換テーブルのリストを定義。
  • normal : normalize 要素用の変換テーブルのリストを定義。
  • denormal : denormalize 要素用の変換テーブルのリストを定義。
  • gender : gender 要素用の変換テーブルのリストを定義。
  • person : person 要素用の変換テーブルのリストを定義。
  • person2 : person2 要素用の変換テーブルのリストを定義。
maps
maps エンティティでは、map要素の情報参照をファイル名(拡張子を除く)で行われるため、情報の種類毎にファイルを分けることが可能です。
ファイル名(拡張子を除く)は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で管理します。
ファイル毎の記述は、’変換対象文字列: 変換後文字列’ の形式で列記します。
変換対象文字列の一致判定は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で行いますが、 変換結果には指定された変換後文字列が設定されます。

以下の例は、都道府県と県庁所在地の関係を列記したprefectural_office.txtの例です。

東京都:東京
東京:東京
神奈川県:横浜市
神奈川:横浜市
大阪府:大阪市
大阪:大阪市
 :
normal
normal エンティティでは、’”変換対象文字列”,”変換後文字列”’ の形式を列記することで、文字列内の記号等を独立した単語に変換します。
英字の場合、”変換対象文字列”の1文字目が’ ‘(空白)でない場合、記号の変換を前提として、対象文字列内で一致するものすべてを変換します(文字置換)。
対して、1文字目が’ ‘(空白)の場合には、単語を単位とした変換を行います(単語置換)。
英文に対するnormalizeでの変換処理は、文字変換、単語変換の順で行い、両者とも、変換後の文字列の前後には、空白が挿入されます。
2つの変換を組み合わせた例として、”.”を”dot”、” Mr”を”mister”で指定することで、”Mr.”を”mister dot”に変換することもできます。
尚、日本語の場合、単語を単位として変換を行います。
".","dot"
"/","slash"
":","colon"
"*","_"
" Mr","mister"
" can t","can not"
denormal
normal エンティティでの変換と対をなす、denormal エンティティでも、’”変換対象文字列”,”変換後文字列”’ の形式を列記し、単語から記号等の文字列に戻します。
英字の場合、”変換対象文字列”は単語であり、”変換後文字列”には前後の文字列と連結する場合の’ ‘(空白)の要否を含めて指定します。空白が無い場合には、前後の文字列と連結されます。
normalizeの逆の例として、”mister dot”を” Mr.”に戻す場合、別の指定方法として、”dot”を”.”、”mister”を” Mr”の2つに分けて指定することもできます。
"dot","."
"slash","/"
"colon",":"
"_","*"
"mister dot"," Mr."
"can not"," can't "
gender,person,person2
genderpersonperson2 の各エンティティは、単語単位で変換を行うもので、’”変換対象文字列”,”変換後文字列”’ の形式を列記します。
変換対象文字列、変換後文字列に空白を含む複数単語の文字列を指定することも可能です。
変換対象文字列の一致判定は、英字:半角大文字、数字・記号:半角、カタカナ:全角に変換した上で行いますが、 変換結果には指定された値が設定されます。

例として、genderでは以下の様に定義します。

"he","she"
"his","her"
"him","her"
"her","him"
"she","he"
"かれ","彼女"
"かのじょ","彼"
"かれし","彼女"
"彼","彼女"
"彼女","彼"
"彼氏","彼女"

AIML要素の定義ファイル

以下のエンティティでは、対話エンジンで使用可能なAIML要素と処理クラスを関連づけるための定義ファイルを指定します。 詳細は カスタム要素 を参照してください。

  • pattern_nodes : patternの各要素の処理クラス定義ファイルを指定。
  • template_nodes : templateの各要素の処理クラス定義ファイルを指定。

その他のエンティティ

rdf エンティティで指定するファイル形式は、RDFサポート を参照してください。

usergroups エンティティで指定するファイル形式は、Securityの ユーザグループファイル を参照してください。

以下のエンティティについては、実装(クラス定義等)に依存する内容を含むため、記述方法の説明は省略します。

  • license_keys : 外部接続等で必要になるライセンスキーファイル。
  • postprocessors : レスポンスの応答文に対して編集を行う場合の処理クラス定義ファイル。
  • preprocessors : リクエストのユーザ発話に対して編集を行う場合の処理クラス定義ファイル。
  • spelling_corpus : スペルチェックを行い場合のもとになるコーパスファイル。

JSON

JSONをAIMLで利用するための機能です。 SubAgent,metadata,意図解釈結果などのJSONデータをAIMLで利用するために使用します。

name/var/dataで指定する変数名には、get/setで定義した変数名を使用します。 varはローカル変数、nameはグローバル変数、dataはグローバル変数(APIからのdeleteVariableがtrueまで保持する変数)を対象とします。 また、メタデータ、サブエージェントの戻り値等のシステム固定変数名もvar変数として利用できます。

  • 属性
パラメータ タイプ 指定値 必須 説明
name JSON変数名   No グローバル変数(name)名を指定します。キー名を付加することを推奨します。
var JSON変数名   No ローカル変数(var)名を指定します。キー名を付加することを推奨します。
data JSON変数名   No グローバル変数(data)名を指定します。キー名を付加することを推奨します。
key キー指定   No JSONデータを操作するキーを指定します。
item   key No JSONデータからキーを取得する場合に使用します。この属性を指定すると値ではなくキーを取得します。
function   len No 対象のJSONプロパティが配列の場合、配列長を取得します。対象がJSONオブジェクトの場合、JSONオブジェクトの要素数を取得します。
    delete No 対象プロパティを削除します。配列の場合でindexを指定していると対象となる要素を削除します。
    insert No JSON配列に対する値の追加を指定します。
index インデックス   No JSONデータを取得する場合のインデックスを指定します。対象が配列の場合、配列番号を指します。JSONオブジェクトではキーを先頭から順に数えたオブジェクトを指します。JSONデータを設定・変更する場合、配列のみに指定できます。
type   string No 数値・論理値・null値を文字列として処理することを指定します。

json要素として、var, name, data のいずれかが設定されている必要があります。

  • 子要素

AIMLの変数を値として指定する場合に属性では指定できないため、子要素としても指定できるようにしています。 動作は属性と同じ動作になります。同じ属性名、子要素名を指定した場合子要素の設定が優先されます。 ただし、keyを子要素で利用する場合のみ、name・data・varの区別はしており、別扱いとなります。

パラメータ タイプ 必須 説明
function 関数名 No JSONに対する処理を記述します。ここのfunctionについては属性を参照。
index インデックス No JSONデータを取得する場合のインデックスを指定します。対象が配列の場合、配列番号を指します。JSONオブジェクトではキーを先頭から順に数えたオブジェクトを指します。JSONデータを設定・変更する場合、配列のみに指定できます。
item キー名取得 No JSONデータからキーを取得する場合に使用します。この属性を指定すると値ではなくキーを取得します。
key キー指定 No JSONデータを操作するキーを指定します。

基本利用方法

JSON要素にname、data、もしくは、var属性で、対象となるJSONデータを指定します。 JSON要素に内容を設定した場合、対象となるJSONデータに値を設定、更新します。 JSON要素に内容を設定しなかった場合、削除の場合を除き、対象となるキーの値を取得します。取得に失敗した場合、 get と同様に、Config等で設定された”default-get”の値が返ります。 以下に、JSONを対象とした場合のデータの取得方法、設定方法を説明します。 サブエージェントの戻り値を利用する例で説明します。サブエージェントの戻り値は、変数 __SUBAGENT__.family に保持されている前提です。

{
    "family": {
        "名前": "一郎",
        "誕生日": "19700101",
        "年齢": 48,
        "性別": "male",
        "自宅": { "住所": "東京都港区","座標": "x,y" },
        "家族": {
            "父": "太郎",
            "母": "花子",
            "兄弟": [ "二郎", "菊子" ],
            "子": [ "三郎", "桃子" ]
        },
        "親戚": {
            "祖父": [ "士郎", "五郎" ],
            "祖母": [ "久里子", "梅子" ],
            "従姉妹": [ "史郎", "咲子" ],
            "孫": [ "紗希子" ]
        },
        "友人": [ "和宏", "京子" ],
        "趣味": [ "ゴルフ", "野球" ],
        "病歴": [ "高血圧", "花粉症" ],
        "アレルギー": [ "牛乳", "そば" ]
    }
}

JSONデータの取得時の属性/子要素指定方法

属性および子要素の指定方法を説明します。 記載方法は異なりますが、処理結果は同じ結果になります。

キー指定の値取得

“父”の値を取得する場合、以下の記述を行います。 属性の場合、 . 区切りで取得したいキーを記載します。 子要素の場合、<key> の内容に取得したいキーを記載します。

<json var="__USER_METADATA__.family.家族.父" />
<!-- <json var="__USER_METADATA__.family"><key>家族.父</key></json>  上記内容と同動作-->
配列の取得

配列になっている、”兄弟”の値を取得する場合、 値の取得同様、 . 区切りで取得したいキーを記載、もしくは子要素 <key> をに記述することで指定した配列を取得します。 実行結果として、 ["二郎", "菊子"] を取得します。

<json var="__USER_METADATA__.family.家族.兄弟" />
<!-- <json var="__USER_METADATA__.family.家族"><key>兄弟</key></json>  上記内容と同動作-->
配列長の取得

functionに”len”を指定すると配列長を取得します。 “兄弟”の場合、 2 を取得します。

<json var="__USER_METADATA__.family.家族.兄弟" function="len"/>
<!-- <json var="__USER_METADATA__.family.家族.兄弟"><function>len</function></json>   上記内容と同動作-->
配列値の取得

配列の内容を取得する場合、配列のインデックスを記載します。 “兄弟”の0番目の値、 二郎 を取得します。

<json var="__USER_METADATA__.family.家族.兄弟" index="0"/>
<!-- <json var="__USER_METADATA__.family.家族.兄弟"><index>0</index></json>  上記内容と同動作-->
JSONオブジェクトの要素数取得

JSONオブジェクトの要素数を取得する場合、functionに len を指定します。 familyを指定した場合の要素数は 11 になります。

<json var="__USER_METADATA__.family" function="len"/>
<!-- <json var="__USER_METADATA__.family"><function>len</function></json>  上記内容と同動作-->
JSONオブジェクトのキーを取得する場合

JSONオブジェクトのキーを取得する場合、itemに key を指定します。 familyの5番目を指定すると、 家族 を取得します。

<json var="__USER_METADATA__.family" item="key" index="5"/>
<!-- <json var="__USER_METADATA__.family"><item>key</item><index>5</index></json>  上記内容と同動作-->

JSONデータの更新

JSONデータに既にあるキーの値を変更する場合、JSON要素の内容に値を記載します。 内容を記載することで、”住所”を”新横浜”に更新します。 空の内容にする場合、 "" を指定してください。

<json var="__USER_METADATA__.family.自宅.住所">新横浜</json>
<json var="__USER_METADATA__.family.自宅.座標">""</json>
<!-- <json var="__USER_METADATA__.family.自宅"><key>住所</key>新横浜</json>
    <json var="__USER_METADATA__.family.自宅"><key>座標</key>""</json>  上記内容と同動作-->

更新前

"自宅": {"住所": "東京都港区", "座標": "x,y"},

更新後

"自宅": {"住所": "新横浜", "座標": ""},
JSONデータへの追加

新しいキーを追加する場合、新しいキーに値を指定することで新たなキーを追加します。

<json var="__USER_METADATA__.family.郵便番号">222-0033</json>
<!-- <json var="__USER_METADATA__.family"><key>郵便番号</key>222-0033</json>  上記内容と同動作-->

更新前

{
    "family":{
        "病歴": ["高血圧", "花粉症"],
        "アレルギー": ["牛乳", "そば"]
    }
}

更新後

{
    "family":{
        "病歴": ["高血圧", "花粉症"],
        "アレルギー": ["牛乳", "そば"],
        "郵便番号": "222-0033"
    }
}
配列の内容の変更

配列の内容を変更する場合、配列のインデックスを記載します。 “趣味”の0番目の値を変更する場合、以下のように取得します。

<json var="__USER_METADATA__.family.趣味" index="0">サッカー</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key><index>0</index>サッカー</json>  上記内容と同動作-->

更新前

{
    "family":{
        "趣味": ["ゴルフ", "野球"]
    }
}

更新後

{
    "family":{
        "趣味": ["サッカー", "野球"]
    }
}
配列の変更

配列になっている”趣味”の要素を全て変更する場合、 個々の要素をダブルクォートで囲み、カンマで区切ります。

<json var="__USER_METADATA__.family.趣味">"サッカー","釣り","映画鑑賞"</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key>"サッカー","釣り","映画鑑賞"</json>  上記内容と同動作-->

を指定すると、

更新前

"趣味": ["ゴルフ", "野球"],

更新後

"趣味": ["サッカー","釣り","映画鑑賞"],
配列への要素追加

配列への要素追加はfunctionにinsertを指定し、indexで挿入箇所を設定します。 先頭に値を追加する場合、indexに0を指定します。 マイナスインデックスは後ろからのインデックス値を表し、indexに-1を指定すると配列の最後に値を追加します。 個々の要素をダブルクォートで囲み、カンマで区切ります。

以下の例では、配列になっている”趣味”に対しindex=”0”を指定し、配列の先頭に値を追加しています。

<json var="__USER_METADATA__.family.趣味" function="insert" index="0">"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key><function>insert</function><index>0</index>"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>   上記内容と同動作-->

更新前

"趣味": ["ゴルフ", "野球"],

更新後

"趣味": ["サッカー", "釣り", "映画鑑賞", "旅行(海外,国内)", "ゴルフ", "野球"],

以下の例では、配列になっている”趣味”に対し配列要素数のindex=”2”を指定することで、配列の最後に値を追加しています。

<json var="__USER_METADATA__.family.趣味" function="insert" index="2">"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key><function>insert</function><index>2</index>"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>  上記内容と同動作-->

更新前

"趣味": ["ゴルフ", "野球"],

更新後

"趣味": ["ゴルフ", "野球", "サッカー", "釣り", "映画鑑賞", "旅行(海外,国内)"],

また、index=”-1”でも同様に、配列の最後に値を追加しています。

<json var="__USER_METADATA__.family.趣味" function="insert" index="-1">"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key><function>insert</function><index>-1</index>"サッカー","釣り","映画鑑賞","旅行(海外,国内)"</json>  上記内容と同動作-->

更新前

"趣味": ["ゴルフ", "野球"],

更新後

"趣味": ["ゴルフ", "野球", "サッカー", "釣り", "映画鑑賞", "旅行(海外,国内)"],
配列の作成

カンマ区切りの要素を設定するか、functionにinsertを指定しindexを0か-1を設定した場合に配列を作成します。(indexに0もしくは-1以外を指定した場合作成されません)

以下の例では、新たな配列要素として”学歴”を作成しています。

<json var="__USER_METADATA__.family.学歴" >"A小学校","B中学校","C高校","D大学"</json>
<!-- <json var="__USER_METADATA__.family.学歴" function="insert" index="0">"A小学校","B中学校","C高校","D大学"</json>  上記内容と同動作-->
<!-- <json var="__USER_METADATA__.family.学歴" function="insert" index="-1">"A小学校","B中学校","C高校","D大学"</json>  上記内容と同動作-->
<!-- <json var="__USER_METADATA__.family"><key>学歴</key><function>insert</function><index>0</index>"A小学校","B中学校","C高校","D大学"</json>  上記内容と同動作-->

作成後

"学歴": ["A小学校","B中学校","C高校","D大学"]

1要素の場合は、functionにinsert未指定でJSONオブジェクトを作成することができるが、insertを指定して配列に変更することはできません。 1要素でも要素が増える場合は、配列要素として作成する必要があります。

<!-- <json var="__USER_METADATA__.family.学歴" function="insert" index="0">"D大学"</json>  上記内容と同動作-->
<!-- <json var="__USER_METADATA__.family.学歴" function="insert" index="-1">"D大学"</json>  上記内容と同動作-->
<!-- <json var="__USER_METADATA__.family"><key>学歴</key><function>insert</function><index>0</index>"D大学"</json>  上記内容と同動作-->

更新後、1要素の配列が作成されます。

"学歴": ["D大学"]

functionにinsert未指定の場合、

<json var="__USER_METADATA__.family.学歴" >"D大学"</json>

更新後はJSONオブジェクトが作成されます。

"学歴": "D大学"

JSONデータの削除

配列の要素削除

配列の要素を削除するには、functionにdelete、indexに削除する要素の番号を設定します。 指定したindexの値を削除します。 マイナスインデックスは後ろからのインデックス値を表し、indexに-1を指定すると配列の最後の値を削除します。

<json var="__USER_METADATA__.family.趣味" index="0" function="delete" />
<!-- <json var="__USER_METADATA__.family.趣味"><index>0</index><function>delete</function></json>  上記内容と同動作-->
<json var="__USER_METADATA__.family.趣味" index="-1" function="delete" />
<!-- <json var="__USER_METADATA__.family.趣味"><index>-1</index><function>delete</function></json>  上記内容と同動作-->

更新前

"趣味": ["ゴルフ", "野球","読書"],

更新後

"趣味": ["野球"],
キーの削除

キーを削除する場合は、functionにdeleteを設定します。 指定されたキーおよび値が削除されます。

“function”に”delete”を指定することで”趣味”キーと値を削除します。

<json var="__USER_METADATA__.family.趣味" function="delete" />
<!-- <json var="__USER_METADATA__.family.趣味"><function>delete</function></json>   上記内容と同動作-->

更新前

"友人": ["和宏", "京子"],
"趣味": ["ゴルフ", "野球"],
"病歴": ["高血圧", "花粉症"],

更新後

"友人": ["和宏", "京子"],
"病歴": ["高血圧", "花粉症"],

JSON形式データの指定

要素として、JSON形式のデータを設定する場合、波括弧:{}で囲んだJSONの文字列形式を指定します。 配列の操作でも指定できますが、JSON文字列形式の記述をリストで指定することはできないため、1要素ずつ指定する必要があります。

JSON形式として不正がある場合、設定することはできません。

<json var="__USER_METADATA__.family.家族.父">{"名前": "太郎", "年齢": 80}</json>
<!-- <json var="__USER_METADATA__.family.家族"><key>父</key>{"名前": "太郎", "年齢": 80}</json>  上記内容と同動作-->

更新前

"父": "太郎",

更新後

"父": {
       "名前": "太郎",
       "年齢": 80
       },

尚、本機能はJSONのキーに対して内容を設定するものであり、以下の様に、変数に直接JSON形式のデータを設定することはできません。 変数にJSON形式の内容を設定する場合には、set 要素を使用してください。

<!-- 設定不可 --> <json var="__USER_METADATA__">{"family": {"家族": {"父": {"名前": "太郎", "年齢": 80}}}}</json>

<!-- 設定可能 --> <set var="__USER_METADATA__">{"family": {"家族": {"父": {"名前": "太郎", "年齢": 80}}}}</set>

リスト形式データの指定

要素として、リスト形式のデータを設定する場合、角括弧:[]で囲み、設定値をカンマ区切りで指定します。

リスト形式として不正がある場合、設定することはできません。

<json var="__USER_METADATA__.family.趣味">["サッカー","釣り","映画鑑賞"]</json>
<!-- <json var="__USER_METADATA__.family"><key>趣味</key>["サッカー","釣り","映画鑑賞"]</json>  上記内容と同動作-->

更新前

"趣味": ["ゴルフ", "野球"],

更新後

"趣味": ["サッカー", "釣り", "映画鑑賞"],

尚、本機能はJSONのキーに対して内容を設定するものであり、以下の様に、変数に直接リスト形式のデータを設定することはできません。

<!-- 設定不可 --> <json var="__USER_METADATA__">["サッカー","釣り","映画鑑賞"]</json>

数値、真偽値、nullの取り扱い

AIMLでは文字列としての扱いしかなく、JSONの数値、真偽値、nullを直接取り扱う事は出来ません。 これらの内容をJSON要素に設定および取得する場合の動作を説明します。

設定
設定時に、数値のみを指定すると内部では数値として取り扱います。
数値以外の文字列が含まれると文字列扱いになります。
真偽値を示す、”true”,”false”を設定した場合、真偽値としてJSONに登録します。
値にnullを設定した場合、JSONにはnullを設定します。
数値、true,false,nullを文字列として設定する場合、typeに string を指定します。

例:

<json var="__USER_METADATA__.family.年齢">30</json>
<json var="__USER_METADATA__.family.満年齢">31</json>
<json var="__USER_METADATA__.family.誕生日" type="string">19700101</json>
<json var="__USER_METADATA__.family.自己紹介">null</json>
<json var="__USER_METADATA__.family.電話番号認証">true</json>
<json var="__USER_METADATA__.family.メール認証" type="string">false</json>

例の設定結果は以下のJSONになります。

{
    "family": {
        "年齢": 30,
        "満年齢": "31歳",
        "誕生日": "19700101",
        "自己紹介": null,
        "電話番号認証": true,
        "メール認証": "false"
    }
}
取得

JSON要素で数値、真偽値、nullを取得する場合、これらは文字列として取得されます。 数値の場合、数値文字列、真偽値の場合”true”,”false”の文字列、nullの場合”null”の文字列として取得します。

例:

<json var="__USER_METADATA__.family.年齢"/>
<json var="__USER_METADATA__.family.満年齢"/>
<json var="__USER_METADATA__.family.誕生日"/>
<json var="__USER_METADATA__.family.電話番号認証"/>
<json var="__USER_METADATA__.family.メール認証"/>
<json var="__USER_METADATA__.family.自己紹介"/>

取得値は、以下のとおり各々が文字列で取得されるため、シナリオ設計者が取得元のデータ型を意識しておく必要があります。

30
31
19700101
true
false
null

関連項目: SubAgentmetadata意図解釈

NLU

基本として、pattern要素で、意図解釈処理を行うための定義ですが、template要素の子要素:sraixでの指定により、意図解釈結果を直接取得して利用することもできます。

patternの子要素として nlu を定義すると、高度意図解釈のインテントとのマッチングの評価を行います。
対話制御では、シナリオの記述に従いルールベースの意図解釈を行って、patternマッチングで評価した結果に応じて応答を返しますが、マッチするpatternがなかった場合、高度意図解釈のインテントの結果を用いた対話制御を行います。
これは意図解釈の結果より、シナリオ作成者が記述する内容を優先させるためです。
例外として、patternにワイルドカードのみが記述されたcategoryが存在する場合、シナリオ記述のマッチングと、意図解釈のマッチングとの両方でマッチしなかった後に、マッチ処理を行います。
子要素のnluを定義した場合でも、pattern要素の内容を記載すると通常のパターン評価が行われます。
nlu要素の属性は、nlu を参照してください。
尚、シナリオ内にnlu子要素が指定されたpatternが1つも無い場合、意図解釈結果の取得は行いません。
templateの子要素 sraix の属性として nlu を指定すると、任意の高度意図解釈エンジン(NLUサーバ)から意図解釈結果を取得できます。
NLUサーバとの通信方法については、SubAgentの NLU通信インタフェース を参照してください。

基本利用方法

高度意図解釈から以下のフォーマットで、インテント、スロットの情報が返却された例で説明します。

{
    "intents": [
        {"intent": "transportation", "score": 0.9 },
        {"intent": "aroundsearch", "score": 0.8 }
    ],
    "slots": [
        {"slot": "departure", "entity": "東京", "score": 0.85, "startOffset": 3, "endOffset": 5 },
        {"slot": "arrival", "entity": "京都", "score": 0.86, "startOffset": 8, "endOffset": 10 },
        {"slot": "departure_time", "entity": "2018/11/1 19:00", "score": 0.87, "startOffset": 12, "endOffset": 14 },
        {"slot": "arrival_time", "entity": "2018/11/1 11:00", "score": 0.88, "startOffset": 13, "endOffset": 18 }
    ]
}

インテントでのマッチング

AIMLのpatternの子要素としてnluを記載します。
以下の例では、高度意図解釈から返却されたインテントが ‘transportation’ にマッチし、応答文が返ります。
<category>
    <pattern>
        <nlu intent="transportation" />
    </pattern>
    <template>
        乗り換え案内ですね?
    </template>
</category>
Input: 東京から京都に行きたい。
Output: 乗り換え案内ですね?

インテント候補にはあるがマッチしないパターン

以下の例は、高度意図解釈のインテントが ‘aroundsearch’ の場合です。
‘aroundsearch’ はインテントの候補にありますが、最尤候補ではないためマッチしません。
(‘aroundsearch’ の尤度が、’transportation’ と同じ場合にはマッチします。)
<category>
    <pattern>
        <nlu intent="aroundsearch" />
    </pattern>
    <template>
        周辺検索ですね?
    </template>
</category>
Input: 東京から京都に行きたい。
Output: NO_MATCH

最尤候補でない場合のマッチング

インテント ‘aroundsearch’ が最尤候補でなくても含まれる場合にマッチングさせたい場合、属性 maxLikelihoodfalse を設定します。
maxLikelihood が未指定の場合、true を指定した場合と同じ動作になります。
<category>
    <pattern>
        <nlu intent="aroundsearch" maxLikelihood="false" />
    </pattern>
    <template>
        周辺検索ですね?
    </template>
</category>
Input: 東京から京都に行きたい。
Output: 周辺検索ですね?

score指定でのマッチ

インテントのscore値によるマッチング条件について説明します。
属性として、 scoreGt、scoreGe、score、scoreLe、scoreLtの5種類の指定が可能となり、設定内容は以下になります。
また、この属性を指定した場合、信頼度での比較マッチングを行うため maxLikelihoodfalse 扱いになります。
パラメータ名 意味 説明
scoreGt > 対象インテントの信頼度が指定した値より大きい場合にマッチします。
scoreGe >= 対象インテントの信頼度が指定した値以上の場合にマッチします。
score = 対象インテントの信頼度が指定した値の時にマッチします。
scoreLe <= 対象インテントの信頼度が指定した値以下の場合にマッチします。
scoreLt < 対象インテントの信頼度が指定した値より小さい場合にマッチします。

scoreXx指定時の動作は以下のマッチングになります。

<nlu intent="transportation" scoreGt="0.9"/>  transportationにマッチングしません。
<nlu intent="transportation" scoreGe="0.9"/>  transportationにマッチングします。
<nlu intent="transportation" score="0.9"/>    transportationにマッチングします。
<nlu intent="aroundsearch" scoreLe="0.8"/>  aroundsearchにマッチングします。
<nlu intent="aroundsearch" scoreLt="0.8"/>  aroundsearchにマッチングしません。
尚、以下の例のように、高度意図解釈の結果によって複数の条件が成立つ記述が可能ですが、AIMLファイル内のcategoryの記載順序が早いものから適用されます。
複数のAIMLファイルを利用する場合、AIMLの展開処理をデイレクトリ名・ファイル名の昇順で行うため、その順序を意識して配置する必要があります。
(サブディレクトリを使用する場合、上位ディレクトリ内のファイルを処理した後、サブディレクトリ配下のファイル処理に移ります。)
<category>
    <pattern><nlu intent="transportation" scoreGe="0.8"/></pattern>
    <template>乗り換え案内ですね?</template>
</category>

<category>
    <pattern><nlu intent="aroundsearch" scoreGe="0.8"/></pattern>
    <template>周辺検索ですね?</template>
</category>

インテントマッチとワイルドカード

以下は、ルールベース、意図解釈結果にマッチしなかった場合、雑談サブエージェントを呼び出す例になります。 patternとしてワイルドカードのみが記述されたcategoryが存在する場合、シナリオ記述のマッチングと、意図解釈のマッチングとの両方でマッチしなかった後に、マッチ処理を行います。

<aiml>
    <category>
        <pattern>こんにちは</pattern>
        <template>こんにちは</template>
    </category>

    <category>
        <pattern><nlu intent="aroundsearch" /></pattern>
        <template>
            周辺検索します
        </template>
    </category>

    <category>
        <pattern>
            *
        </pattern>
        <template>
            <sraix service="雑談"><get var="__USER_UTTERANCE__" /></sraix>
        </template>
    </category>
</aiml>
Input: こんにちは
Output: こんにちは
Input: この辺りのコンビニ
Output: 周辺検索します
Input: 雑談対話
Output: 雑談対話の結果です

sraiに対するNLUマッチ

マッチ結果のtemplateに ‘srai’ 要素が指定されている場合、srai対象の発話文が、現在保持している高度緯度解釈結果の取得時の発話文と同じ場合には、再取得の処理は行いません。 対象発話文が異なる場合に、srai対象の発話文に対する高度意図解釈結果の再取得を行います。

以下の場合、srai処理での高度意図解釈結果の再取得は行いません。

<aiml>
    <category>
        <pattern><nlu intent="transportation" /></pattern>
        <template>
            ご希望
            <srai><input /></srai>
        </template>
    </category>

    <category>
        <pattern>
            *
        </pattern>
        <template>
            承りました
        </template>
    </category>
</aiml>
Input: 東京から京都に行きたい。
Output: ご希望承りました。

NLUデータの取得

NLUのデータは、ローカル変数(var) __SYSTEM_NLUDATA__ に展開されますが、API変数と同様に扱うため、レスポンスを返却するまでの間は、srai処理でも引き継いで利用することができます。
ただし、srai処理時に高度意図解釈結果の再取得が行われた場合、内容は置換されます。
JSON要素を用い 意図解釈結果 のデータを取得する例を示します。
<category>
    <pattern>
        <nlu intent="transportation" />
    </pattern>
    <template>
        <think>
                <set var="slot"><json var="__SYSTEM_NLUDATA__.slots"><index>1</index></json></set>
                <set var="entity"><json var="slot.entity" /></set>
                <set var="score"><json var="slot.score" /></set>
        </think>
        <get var="entity"/>のscoreは<get var="score" />です。
    </template>
</category>
Input: 東京から京都に行きたい。
Output: 東京のscoreは0.85です。

関連項目: nluJSON要素

NLUインテントの取得

templateでインテントの内容を取得する場合、 nluintent を使用します。
NLU処理結果として、以下の結果を取得している前提でインテント情報の取得方法を説明します。
{
    "intents": [
        {"intent": "restaurantsearch", "score": 0.9 },
        {"intent": "aroundsearch", "score": 0.4 }
    ],
    "slots": [
        {"slot": "genre", "entity": "イタリアン", "score": 0.95, "startOffset": 0, "endOffset": 5 },
        {"slot": "genre", "entity": "フレンチ", "score": 0.86, "startOffset": 7, "endOffset": 10 },
        {"slot": "genre", "entity": "中華", "score": 0.75, "startOffset": 12, "endOffset": 14 }
    ]
}

NLUで処理したインテント情報を取得する例です。mapには数値をカウントアップすることを定義していることが前提です。 intentCountにインテント数を保持しconditionの条件としてintentCount数になるまで、各スロットのintent名、scoreを取得します。

<category>
    <pattern>
        <nlu intent="restaurantsearch"/>
    </pattern>
    <template>
        <think>
          <set var="count">0</set>
          <set var="intentCount"><nluintent name="*" item="count" /></set>
        </think>
        <condition>
            <li var="count"><value><get var="intentCount" /></value></li>
            <li>
                intent:<nluintent name="*" item="intent"><index><get var="count" /></index></nluintent>
                score:<nluintent name="*" item="score"><index><get var="count" /></index></nluintent>
                <think>
                    <set var="count"><map name="upcount"><get var="count" /></map></set>
                </think>
                <loop/>
            </li>
        </condition>
    </template>
</category>
Input: イタリアンかフレンチか中華を探して。
Output: intent:restaurantsearch score:0.9 intent:aroundsearch score:0.4

尚、templateの子要素sraixを利用して意図解釈結果を取得した場合、nluintentの属性で格納変数: __SUBAGENT_NLU__.エイリアス名 の指定が必要ですが、同様の操作が行えます。

関連項目: nluintent

NLUスロットの取得

templateでNLU処理結果のスロットの内容を取得する場合、 nluslot を使用します。
NLU処理結果として以下の結果を取得していることを前提としてスロット情報の取得方法を説明します。
{
    "intents": [
        {"intent": "restaurantsearch", "score": 0.9 },
        {"intent": "aroundsearch", "score": 0.4 }
    ],
    "slots": [
        {"slot": "genre", "entity": "イタリアン", "score": 0.95, "startOffset": 0, "endOffset": 5 },
        {"slot": "genre", "entity": "フレンチ", "score": 0.86, "startOffset": 7, "endOffset": 10 },
        {"slot": "genre", "entity": "中華", "score": 0.75, "startOffset": 12, "endOffset": 14 }
    ]
}

NLUで処理したスロット情報を取得する例です。mapには数値をカウントアップすることを定義していることが前提です。 slotCountにスロット数を保持しconditionの条件としてslotCount数になるまで、各スロットのslot名、entity、scoreを取得します。

<category>
    <pattern>
        <nlu intent="restaurantsearch" />
    </pattern>
    <template>
        <think>
          <set var="count">0</set>
          <set var="slotCount"><nluslot name="*" item="count" /></set>
        </think>
        <condition>
            <li var="count"><value><get var="slotCount" /></value></li>
            <li>
                slot:<nluslot name="*" item="slot"><index><get var="count" /></index></nluslot>
                entity:<nluslot name="*" item="entity"><index><get var="count" /></index></nluslot>
                score:<nluslot name="*" item="score"><index><get var="count" /></index></nluslot>
                <think>
                    <set var="count"><map name="upcount"><get var="count" /></map></set>
                </think>
                <loop/>
            </li>
        </condition>
    </template>
</category>
Input: イタリアンかフレンチか中華を探して。
Output: slot:genre entity:イタリアン score:0.95 slot:genre entity:フレンチ score:0.86 slot:genre entity:中華 score:0.75

尚、templateの子要素sraixを利用して意図解釈結果を取得した場合、nluslotの属性で格納変数: __SUBAGENT_NLU__.エイリアス名 の指定が必要ですが、同様の操作が行えます。

関連項目: nluslot

複数のNLUサーバ利用

高度意図解釈の結果取得に複数のNLUサーバを利用する場合、 nlu_serversファイル を使用します。
nlu_serversファイルで複数のNLUサーバを指定した場合、記述された順序に従ってサーバとの通信を行い、応答を受信する毎にマッチング処理を行います。マッチするものがあれば、その時点で結果を返し、マッチするものがない場合に、次のサーバとの通信を行います。
(途中のNLUサーバとの通信に失敗した場合でも、次のNLUサーバとの通信に移ります。)
patternとしてワイルドカードのみが記述されたcategoryが存在する場合、指定されたNLUサーバからの結果が全てアンマッチの場合に処理されます。

コンフィグレーション定義例

brain:
  nlu:
    classname: programy.nlu.cotobadesignNlu.CotobadesignNlu
    use_file: true

nlu_serversファイル定義例

nlu:
  - url: http://localhost:5201/run
  - url: http://localhost:3000/run
    apikey: test_key

シナリオの記述には特別な指定はありません。

尚、nlu_serversファイルの記述に有効なサーバ(URL)定義が無い場合、コンフィグレーション定義のURLが使用されます。 コンフィグレーション定義にも有効なURLが無い場合、高度意図解釈連携機能は利用できません。

NLUサーバとの通信時間管理

マッチ処理で行うNLUサーバとの通信に対して、最大の通信時間を指定できます(初期値:10秒)。最大通信時間を超えた場合、NLUデータは取得されません。
(複数サーバを利用する場合には、次のサーバへの通信に移ります。)
以下の2通りの指定が可能で、nlu_serversファイルの定義が優先されます。

コンフィグレーション定義例

brain:
  nlu:
    classname: programy.nlu.cotobadesignNlu.CotobadesignNlu
    url: http://localhost:5201/run
    timeout: 1

nlu_serversファイル定義例

nlu:
  url: http://localhost:5201/run
timeout: 1
又、各NLUサーバとの通信時間(レイテンシ)は、以下のJSON形式で、ローカル変数(var):__MATCH_NLU_LATENCY__ に格納されます。
但し、シナリオでこの変数値を取得する為には、マッチするCategoryを使用する必要があります。(アンマッチになる場合は、ワイルドカードのcategoryを利用します。)
※デバッグAPIで出力される対話履歴情報には格納されています。
{
  "latency": [
    {"サーバ名", 秒単位の小数点付き数値},
      :
  ]
}

※サーバ名には、nlu_serversファイルの定義に合わせた ‘NONAME-定義順(0~)’、又は、’servers’ で付与したエイリアス名が設定されます。

metadata

概要

対話APIリクエストボディに設定された metadata情報は、シナリオの変数データ(テキスト、または、JSON)として用いることができます。
また、対話APIレスポンスボディに設定する metadata情報も、シナリオの変数データとして設定することができます。

対話APIで設定されたmetadataの利用

対話APIリクエストでJSONの要素として指定された metadata情報を、対話シナリオで利用可能な変数に展開した状態で保持します。
APIから渡されたJSON内の metadata 要素は、変数名 __USER_METADATA__ に展開します。
metadata要素がJSON形式の場合、 json タグを用いることで、__USER_METADATA__内の要素を取得することができます。
__USER_METADATA__の内容は、対話APIのレスポンスを返却するまでの間有効です。継続して__USER_METADATA__の内容を利用する場合、別途変数に代入してください。

メタデータ変数__USER_METADATA__はローカル変数(var)として扱いますが、ユーザ毎の管理情報であるため、特別に、レスポンスを返却するまでの間は、srai処理でも引き継いで利用することができます。

metadataの変数への展開方法

対話APIからmetadataとして渡されたデータを、変数__USER_METADATA__に展開します。
metadataには、テキストデータと、JSONデータを設定することができ、各々のシナリオでの取り扱い方を説明します。
尚、以下の説明では、myServiceサブエージェントを利用して情報を取得し、以下の結果がJSONデータとして返却されることを前提として記載します。
返却されたデータは、変数 __SUBAGENT__.myService に展開されています。サブエージェント連携についての詳細は、 SubAgent を参照してください。
{
    "transportation": {
        "station": {
            "departure": "東京",
            "arrival": "京都"
        },
        "time": {
            "departure": "2018/11/1 11:00",
            "arrival": "2018/11/1 13:30"
        },
        "facility": ["鹿苑寺", "清水寺", "伏見稲荷大社"]
    }
}
テキストデータとしての取り扱い方

テキストデータの場合、変数__USER_METADATA__に対する get タグで内容を取得することができます。

対話APIコールのmetadataとして、以下のように文字列が与えられた場合を説明します。

{
    "locale": "ja-JP",
    "time": "2018-07-01T12:18:45+09:00",
    "topic": "*",
    "utterance": "subagent こんにちは",
    "metadata": "メタデータテスト"
}
シナリオには以下のように記載します。
__USER_METADATA__の内容を get タグで取得し、 sraix タグの内容として設定することで、myService サブエージェントに引き渡します。
サブエージェントの返却データは、 __SUBAGENT__.myService に保持されており( 詳細は SubAgent に記載)、要素のキーを指定することでJSON内の値を取得しています。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <think>
                <sraix service="myService">
                    <star /><space />
                    <get var="__USER_METADATA__" />
                </sraix>
                <set name="departure"><json var="__SUBAGENT__.myService.transportation.station.departure" /></set>
                <set name="arrival"><json var="__SUBAGENT__.myService.transportation.station.arrival" /></set>
            </think>
            <get name="departure"/>から<get name="arrival"/>までを検索します。
        </template>
    </category>
</aiml>

ユーザ発話が「subagent こんにちは」の場合、以下のように展開されたデータが、サブエージェントに渡ります。

引数番号 サブエージェントに渡された内容
第1引数 こんにちは
第2引数 メタデータテスト

※ 引数を空白で分離する為に、space要素を使用しています。

JSONデータとしての取り扱い方

対話APIコールのmetadataとして、以下のようにJSONデータが与えられた場合を説明します。

{
    "locale": "ja-JP",
    "time": "2018-07-01T12:18:45+09:00",
    "topic": "*",
    "utterance": "subagent こんにちは",
    "metadata": {"arg1": "value1", "arg2": "value2", "arg3": "value3"}
}
metadataがJSONの場合、 json タグを使用することで、JSON形式のデータとして取り扱うことができます。
JSONの値を取得して個々に設定する場合には、 json タグにキーを指定して対象となる値を取得し、その値を sraixタグ の内容として設定することで、サブエージェントに引き渡すことができます。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <think>
                <sraix service="myService">
                    <star /><space />
                    <json var="__USER_METADATA__.arg1" /><space />
                    <json var="__USER_METADATA__.arg2" /><space />
                    <json var="__USER_METADATA__.arg3" />
                </sraix>
                <set name="departure"><json var="__SUBAGENT__.myService.transportation.station.departure" /></set>
                <set name="arrival"><json var="__SUBAGENT__.myService.transportation.station.arrival" /></set>
            </think>
            <get name="departure"/>から<get name="arrival"/>までを検索します。
        </template>
    </category>
</aiml>

ユーザ発話が「subagent こんにちは」の場合、以下のように展開されたデータがサブエージェントに渡ります。

引数番号 サブエージェントに渡された内容
第1引数 こんにちは
第2引数 value1
第3引数 value2
第4引数 value3

※ 引数を空白で分離する為に、space要素を使用しています。

サブエージェントにmetadata全てを引き渡す方法

対話APIからmetadataとして渡されたJSONデータを、サブエージェントにそのままJSONとして渡すことができます。
json タグの属性に__USER_METADATA__を指定することで、metadataに設定されたデータ全てを取得し、サブエージェントに引き渡します。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <think>
                <sraix service="myService">
                    <star /><space />
                    <json var="__USER_METADATA__" />
                </sraix>
                <set name=departure><json var="__SUBAGENT__.myService.transportation.station.departure" /></set>
                <set name=arrival><json var="__SUBAGENT__.myService.transportation.station.arrival" /></set>
            </think>
            <get name='departure'>から<get name='arrival'>までを検索します。
        </template>
    </category>
</aiml>

ユーザ発話が「subagent こんにちは」の場合、myServiceサブエージェントに対する第2引数で指定されたJSONがそのまま渡ります。

引数番号 サブエージェントに渡された内容
第1引数 こんにちは
第2引数 {‘arg1’: ‘value1’, ‘arg2’: ‘value2’, ‘arg3’: ‘value3’}

※ 引数を空白で分離する為に、space要素を使用しています。

対話APIに返すmetadataの設定

対話APIのレスポンスに設定するmetadata要素の指定は、シナリオの返却用メタデータ変数__SYSTEM_METADATA__にデータを設定することで行います。
レスポンスのmetadata要素には、テキストデータ、または、JSONデータを設定することができ、各々のシナリオでの取り扱い方を説明します。

メタデータ変数__SYSTEM_METADATA__はローカル変数(var)として扱いますが、ユーザ毎の管理情報であるため、特別に、レスポンスを返却するまでの間は、srai処理でも引き継いで利用することができます。

テキストデータとしての取り扱い方

以下の例では、myServiceサブエージェントから取得したデータの中の”出発地”のテキストを、返却用メタデータ変数に設定しています。
サブエージェントから返却されたJSONから、出発地:”station.departure”の要素(テキスト)を取得し、__SYSTEM_METADATA__に設定します。
これによって、対話APIのレスポンスのmetadata要素として、テキストデータが返却されます。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <think>
                <sraix service="myService">
                    <star />
                </sraix>
                <set var="__SYSTEM_METADATA__"><json var="__SUBAGENT__.myService.transportation.station.departure" /></set>
            </think>
            メタデータに出発地を設定しました。
        </template>
    </category>
</aiml>
Input: subagent 東京
Output: メタデータに出発地を設定しました。
metadataの内容: “東京”

JSONデータとしての取り扱い方

以下の例では、myServiceサブエージェントから取得したJSONデータを、返却用メタデータ変数に設定しています。
json タグで、サブエージェントから返却されたJSONデータ全体を__SYSTEM_METADATA__に設定します。
これによって、対話APIのレスポンスのmetadata要素として、JSONデータが返却されます。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <think>
                <sraix service="myService">
                    <star />
                </sraix>
                <set var="__SYSTEM_METADATA__"><json var="__SUBAGENT__.myService" /></set>
            </think>
            メタデータにサブエージェントの処理結果を設定しました。
        </template>
    </category>
</aiml>
Input: subagent 東京
Output: メタデータにサブエージェントの処理結果を設定しました。
metadataの内容: {“transportation”: {“station”: {“departure”: “東京”, “arrival”: “京都”}, “time”: {“departure”: “2018/11/1 11:00”, “arrival”: “2018/11/1 13:30”}, “facility: [“鹿苑寺”, “清水寺”, “伏見稲荷大社”]}}

関連項目: 対話API対話APIデータの変数利用JSONSubAgent

対話APIデータの変数利用

概要

対話API で指定されたデータの利用方法を説明します。

対話APIデータの変数

対話APIで与えられたデータは、対話シナリオで利用可能な変数に展開した状態で保持します。 保持期間はクライアントにレスポンスを返却するまでです。継続して内容を保持する場合、別途変数に代入してください。 対話APIリクエスト時に該当変数が未設定の場合、’None’が返ります。

対話APIデータを保持する変数名は下表のとおりです。

項目名 変数名 説明
ロケール __USER_LOCALE__ string 対話API locale で指定した言語コード。
時間情報 __USER_TIME__ string 対話API time で指定した時刻情報。
ユーザID __USER_USERID__ string 対話API userId で指定したユーザID。
ユーザ発話 __USER_UTTERANCE__ string 対話API utterance で指定したユーザ発話内容。
メタデータ __USER_METADATA__ string 対話API metadata で指定したメタデータ。変数としては文字列で保持しています。 json タグで取り扱う場合はJSONデータとして利用します。
尚、各変数はローカル変数(var)として扱いますが、ユーザ毎の管理情報であるため、特別に、レスポンスを返却するまでの間は、srai処理でも引き継いで利用することができます。
(各変数値をシナリオで変更して利用することは可能ですが、一部の要素処理での省略値としても使用するため、推奨はしません。)

利用例

クライアントからの対話APIで以下のように、対話APIデータが与えられた場合、

{
    "locale": "ja-JP",
    "time": "2018-07-01T12:18:45+09:00",
    "userId": "E8BDF659B007ADA2C4841EA364E8A70308E03A71",
    "topic": "*",
    "utterance": "こんにちは",
    "metadata": {"arg1": "value1", "arg2": "value2"}
}

シナリオでの扱い方は、以下のようになります。

<aiml>
    <category>
        <pattern>こんにちは</pattern>
        <template>
            <get var="__USER_LOCALE__" /> ,
            <get var="__USER_TIME__" /> ,
            <get var="__USER_USERID__" /> ,
            <get var="__USER_UTTERANCE__" />
        </template>
    </category>
</aiml>
Input: こんにちは
Output: ja-JP,2018-07-01T12:18:45+09:00,E8BDF659B007ADA2C4841EA364E8A70308E03A71,こんにちは

metadataについては、 metadata を参照してください。

SubAgent

概要

サブエージェント(SubAgent)は、sraix要素を使用して呼び出す外部のサービスです。 sraixで指定する外部サービスの呼び出し方法を説明します。

外部サービスの呼び出しの方法には、次の4種類があります。

  • 汎用RESTインタフェース
    属性に、”template”を指定した場合、または、属性で、”botName”、”nlu”、”service”が未指定の場合、子要素のhost、header、query、body等を利用して、REST APIとして外部サービスを呼び出します。
  • 対話プラットフォームで、公開されているbot呼び出し
    属性に、”botName”を指定した場合、対話プラットフォームで公開されているbotを呼び出します。
  • NLU通信インタフェース
    属性に、”nlu”を指定した場合、意図解釈エンジン(NLUサーバ)を呼び出します。
  • カスタム外部サービス実装
    属性に、”service”を指定した場合、カスタム実装を行なった処理を利用して、外部サービスを呼び出します。
  • 属性
パラメータ タイプ 必須 説明
未指定   No 子要素による汎用REST API呼び出し。
template string No 汎用REST通信用のテンプレート名。
botName string No 公開Bot通信用のエイリアス名。
nlu string No NLU通信用のエイリアス名。
service string No カスタム外部サービスのサービス名。
default string No 外部呼び出し失敗時の応答文。
timeout string No 通信タイムアウト時間(秒単位)を ‘1’ 以上の整数で指定。未指定時は ‘10’。
SubAgentからのレスポンスボディは、シナリオ(AIML)で利用可能なローカル変数(var)に展開されます。AIMLで処理できるのはテキストのみなので、バイナリデータの戻り値はサポートしていません。
レスポンスボディの内容がJSONの場合、 json タグでJSON内部のパラメータを取得できます。
ローカル変数(var)に展開された内容は、AIMLのcategoryの範囲のみで有効なため、継続して他のcategoryで利用する場合(sraiを含む)、別途、グローバル変数(name/data)に代入してください。
また、category内で、複数回、サブエージェントの呼び出しを行った場合、サブエージェントからの戻り値が上書きされる場合があるため、必要なレスポンスの内容は個別に変数に代入してください。
“default”属性は4種類の外部サービスの呼び出し方法に共通で指定でき、呼び出しに失敗した場合に、設定された内容を戻り値として返します。
“timeout”属性も4種類の外部サービスの呼び出し方法に共通で指定でき、通信要求に対しての送受信待ち時間を制限します。

共通仕様

各外部サービス呼び出しに共通する機能として、通信失敗の検出と要因解析のための機能があります。

通信失敗時の応答文(default)

通信失敗時には、sraixの戻り値として””(空文字)が設定されますが、”default”属性を指定した場合、指定された文字列をsraixの戻り値として返します。

以下は、カスタム外部サービス実装を利用する場合の例です。

<category>
    <pattern>botステータスチェック *</pattern>
    <template>
        <star />のステータスは、<sraix service="someBot" default="通信失敗"><star /></sraix>です。
     </template>
</category>
Input: botステータスチェック 公開bot
Output: 公開botのステータスは、通信失敗です。

タイムアウト指定(timeout)

外部サービスとの通信時間を指定された時間で制限します。タイムアウトが発生した場合には、sraixの戻り値として””(空文字)が設定されます。
“default”属性を指定することで、指定された文字列をsraixの戻り値として返すこともできます。
指定は秒単位(省略値:10秒)で行いますが、動作環境によっては指定時間までに異常を検出する場合があります。30秒程度までの値を指定されること推奨します。

以下は、カスタム外部サービス実装を利用しタイムアウトが発生した場合の例です。

<category>
    <pattern>botステータスチェック *</pattern>
    <template>
        <star />のステータスは、<sraix service="someBot" timeout="10"><star /></sraix>です。
     </template>
</category>
Input: botステータスチェック 公開bot
Output: 公開botのステータスは、です。

HTTPステータスコードの取得

通信失敗の要因には、パラメータの指定異常などを含め各種ありますが、通信処理の結果として、 ローカル変数(var): __SUBAGENT_STATUS_CODE__ に、HTTPステータスコードの値が文字列として設定されます。

  • 取得失敗 : 通信処理が行われなかった。
  • 000 : 通信要求に問題があり通信が行われなかった、または、通信結果として、ステータスコードが取得できなかった。
  • 001 : 通信タイムアウトが発生した。
  • 200 : 通信が正常に行われた。
  • その他 : 通信結果として、異常を示すステータスコードが通知された。

以下は、REST通信のhostに接続できないURLを指定した場合の例です。

<category>
    <pattern>不正RESTサーバ指定</pattern>
    <template>
        <think>
            <sraix><host>https://otherhost.com:5000</host><body>data</body></sraix>
        </think>
        ステータスコードは、<get var="__SUBAGENT_STATUS_CODE__" />です
     </template>
</category>
Input: 不正RESTサーバ指定
Output: ステータスコードは、000です。

レイテンシの取得

外部サービスとの通信時間(レイテンシ)は動作環境やネットワーク状況によって変動します。
送受信に要した時間を確認できる様に、ローカル変数(var): __SUBAGENT_LATENCY__ に、送受信時間を秒単位の小数点付き数値で設定します。
通信が行われなかった場合には、変数値の取得に失敗します。

以下は、REST通信のhostに通信できないURLを指定してタイムアウトが発生した場合の例です。

<category>
    <pattern>通信タイムアウト</pattern>
    <template>
        <think>
            <sraix timeout="1"><host>https://anyhost.com</host><body>data</body></sraix>
        </think>
        通信時間は、<get var="__SUBAGENT_LATENCY__" />秒です
     </template>
</category>
Input: 通信タイムアウト
Output: 通信時間は、1.010000秒です。

汎用RESTインタフェース

sraixの属性に”template”を指定した場合、または、属性で、”botName”、”nlu”、”service”が未指定の場合、 子要素のhost, header, query, body等を利用して、REST APIとして外部サービスを呼び出します。

属性に”template”を指定した場合の値には、rest_templates ファイルで登録したテンプレート名を指定します。
(登録されていないテンプレート名を指定した場合には、AIML展開時に異常を検出し、該当のcategoryは無効になります。)
“template”指定の場合にも子要素の指定を行うことで、送信する内容を変更することができます。

送信

  • 子要素
パラメータ タイプ 必須 説明
host string No 接続先のURLを指定します。属性に’template’を指定しない場合は必須です。
method string No HTTPのメソッド。未指定時はGETで、その他、POST/PUT/DELETE/PATCHに対応します。
query string No queryとして指定するパラメータを連想配列で指定します。
header string No ヘッダに指定するキーと値を連想配列で指定します。
body string No ボディに設定する内容を指定します。
sraixの処理実行時に子要素の不正を検出した場合には、処理例外が発生します。この場合、通信処理は行われず、対話としての応答文は空文字になります。
(例外発生時の応答文は、propertiesexception-response で指定できます。)

汎用RESTインタフェースでのリクエストは、以下のように指定します。 bodyには文字列を設定します。

<category>
    <pattern>XXX</pattern>
    <template>
        <sraix>
            <host>https://www.***.com/ask</host>
            <method>POST</method>
            <query>"userid":"1234567890","q":"question"</query>
            <header>"Authorization":"yyyyyyyyyyyyyyyyy","Content-Type":"application/json;charset=UTF-8"</header>
            <body>{"question": "Ask this question"}</body>
        </sraix>
    </template>
</category>

送信内容

POST /ask?userid=1234567890&q=question HTTP/1.1
Host: www.***.com
Content-Type: application/json;charset=UTF-8
Authorization: yyyyyyyyyyyyyyyyy

{
    "question": "Ask this question"
}

対話APIで指定された metadata をボディに指定する場合は、jsonタグで __USER_METADATA__ を取得し、子要素”body”に設定します。

<category>
    <pattern>XXX</pattern>
    <template>
        <sraix>
            <host>https://otherhost.com/ask</host>
            <method>POST</method>
            <query>"userid":"1234567890","q":"question"</query>
            <header>"Authorization":"yyyyyyyyyyyyyyyyy","Content-Type":"application/json;charset=UTF-8"</header>
            <body><json var="__USER_METADATA__" /></body>
        </sraix>
    </template>
</category>

テンプレートを使用した送信

rest_templatesファイルで以下の定義を行った場合のテンプレートの使用例を示します。

rest:
  テンプレート:
    host: 'https://otherhost.com/ask'
    method: POST
    query:  '"item":"1234"'
    header: '"Content-Type": "applicaton/json"'
    body: '{"key": "Send Data"}'
sraixの記述で子要素を指定しない場合、テンプレートの定義内容で送信を行います。
テンプレートの定義を無効にする場合、sraixの該当子要素に空文字を指定します。
以下の例では、queryを無効化しています。
<category>
    <pattern>XXX</pattern>
    <template>
        <sraix template="テンプレート">
            <query></quesy>
        <sraix>
    </template>
</category>

送信内容

POST /ask HTTP/1.1
Host: otherhost.com
Content-Type: application/json

{
  "key": "Send Data"
}
sraixで子要素を指定した場合、テンプレートの定義より優先して設定されますが、query、headerは、指定された要素を結合した状態にして送信します。(同じ要素名の場合は置換します。)
テンプレートのquery、header定義がある場合に、一部のキーの情報を無効にする場合、sraixの記述で該当項目に対して {対象キー: None} を設定します。
bodyについては、テンプレート定義とsraixの子要素指定の両方がJSON形式の場合に限り、結合した形式で送信します。但し、置換を行う場合は、第一階層のキーからの指定が必要です。
テンプレート定義のbodyがJSON形式で、一部のキーを除外して送信したい場合、子要素をJSON形式で指定し、{対象キー: null} を設定します。(第一階層のキーのみが対象となります)。
尚、テンプレート定義として hostの指定は必須ですが、sraixの記述で置き換えることができます。
以下の例では、hostを置換し、methodとともに、queryの”item”要素を無効化しています。また、header・bodyには、要素を追加しています。
<category>
    <pattern>XXX</pattern>
    <template>
        <sraix template="テンプレート">
            <host>https://otherhost.com/ask</host>
            <method></method>
            <query>"item": None, "userid":"1234567890"</query>
            <header>"Authorization":"yyyyyyyyyyyyyyyyy"</header>
            <body>{"key2": "added data"}</body>
        <sraix>
    </template>
</category>

送信内容

GET /ask?userid=1234567890 HTTP/1.1
Host: otherhost.com
Content-Type: application/json
Authorization: yyyyyyyyyyyyyyyyy

{
  "key": "Send Data", "key2": "added data"
}

受信

受信結果のボディ内容を、sraixの結果として返します。
AIMLで処理できるのはテキストのみなので、バイナリのボディはサポートしていません。
受信結果は、ローカル変数(var): __SUBAGENT_BODY__ にも展開します。 getで、<get var=”__SUBAGENT_BODY__” />を指定することで、ボディの文字列を取得できます。
ローカル変数(var)の内容はcategory単位で保持されるため、継続してレスポンスの内容を利用する場合、別途グローバル変数(name/data)に代入してください。
また、category内で、複数回、汎用RESTインタフェース呼び出した場合、__SUBAGENT_BODY__ は上書きされるため、必要なレスポンス内容は他の変数に代入してください。

sraixの結果と、ローカル変数の格納値は同じ形式なので、以下の2つの記述の結果は同じになります。

<category>
    <pattern>XXX</pattern>
    <template>
        <sraix template="テンプレート" />
    </template>
</category>
<category>
    <pattern>XXX</pattern>
    <template>
        <think>
            <sraix template="テンプレート" />
        </think>
        <get var="__SUBAGENT_BODY__" />
    </template>
</category>

受信結果のボディ内容がJSONの場合、 json タグでJSON内部のパラメータを取得できます。

{
    "transportation": {
        "station": {
            "departure": "東京",
            "arrival": "京都"
        },
        "time": {
            "departure": "2018/11/1 11:00",
            "arrival": "2018/11/1 13:30"
        }
    },
    "facility": ["鹿苑寺", "清水寺", "伏見稲荷大社"]
 }

というボディ内容の場合、以下の記述で、JSONタグによりボディの内部情報を取得することができます。

<json var="__SUBAGENT_BODY__.transportation.station.departure" />   <!-- 取得結果: 東京 -->
<json var="__SUBAGENT_BODY__.facility" function="len" />            <!-- 取得結果: 3 -->
<json var="__SUBAGENT_BODY__.facility"><index>1</index></json>      <!-- 取得結果: 清水寺 -->

対話プラットフォームで、公開されているbot呼び出し

sraixの属性に、”botName”を指定した場合、対話プラットフォームで公開されているbot(公開Bot)を呼び出します。
属性”botName”の値には、bot_names ファイルで登録したエイリアス名を指定します。
sraixの内容が公開botへの入力文(発話文)として送信されますが、入力文がない(含む、空文字)場合は通信処理を行いません。
(登録されていないエイリアス名を指定した場合には、AIML展開時に異常を検出し、該当のcategoryは無効になります。)
エイリアス名の定義で各種パラメータを指定した場合にも、子要素の指定を行うことで、送信する内容を変更することができます。
公開botからの戻ってくる内容は、対話API の受信データで規定されたJSON形式であり、sraixの戻り値に、その中のresponse要素を返します。

送信

公開bot利用時のパラメータは子要素として記載します。子要素の内容は、対話API のボディの内容として送信されます。
子要素については、対話API を参照してください。
sraixで、ユーザIDが未指定の場合、対話APIで指定されたユーザIDを引き継いで使用します。
公開Botを利用する場合、sraixにはユーザ発話を設定する子要素はなく、sraixの内容が公開Botに通知するutteranceとして扱われます。
sraixの内容が無い(含む、空文字)の場合、公開Botへの通信は行われず、属性:defaultが未設定の場合のsraixの戻り値は空文字になります。
  • 子要素
パラメータ   タイプ 必須 説明
userId   string No ユーザID。未指定の場合、対話APIの指定値を引き継ぎます。
locale   string No ロケール。言語指定ISO-639 言語コードとISO-3166 国コードをハイフン繋いだ組み合わせを指定します。
time   string No 時間情報。ISO8601(RFC3339)形式で指定します。
topic   string No トピックID。topic情報を変更する場合にのみ指定します。
deleteVariable   boolean No タスク変数削除指定。’true’が指定された場合のみに送信します。
metadata   string No メタデータ。Text形式、または、JSON形式で指定します。
config     No コンフィグ指定。JSON形式で指定します。
  logLevel string No ログレベル。’none’,’error’,’warning’,’info’,’debug’のいずれかを指定します。
userId以外の子要素が未指定の場合、該当の要素は送信されません。
sraixの処理実行時に子要素の不正を検出した場合には、処理例外が発生します。この場合、通信処理は行われず、対話としての応答文は空文字になります。
(例外発生時の応答文は、propertiesexception-response で指定できます。)

以下の例は、userId, topic、deleteVariable、metadata、configをシナリオで指定し、locale、timeは、指定しない場合の例です。 尚、bot_names ファイルでは、URLとapikeyのみを指定した場合になります。

bot:
  someBot:
    url: https://somebot.com/bots/botId_1/ask
    apikey: test_apikey
<category>
    <pattern>botステータスチェック *</pattern>
    <template>
        <think>
            <json var="askSubagent.郵便番号">222-0033</json>
            <json var="config.logLevel">debug</json>
        </think>
        <sraix botName="someBot">
            <star />
            <userId>someUser</userId>
            <topic>test</topic>
            <deleteVariable>true</deleteVariable>
            <metadata><json var="askSubagent"/></metadata>
            <config><json var="config"/></config>
        </sraix>
    </template>
</category>
Input: botステータスチェック 郵便番号検索
Output: 新横浜

送信内容

POST /bots/botId_1/ask HTTP/1.1
Host: somebot.com
Content-Type: application/json;charset=UTF-8
x-api-key: test_apikey

{
    "userId": "someUser",
    "topic": "test",
    "deleteVariable": true,
    "metadata": {"郵便番号": "222-0033"},
    "config": {"logLevel": "debug"},
    "utterance": "郵便番号検索"
}

bot_namesでパラメータを設定した場合の送信

bot_namesファイルで以下の定義を行った場合の送信例を示します。

bot:
  someBot:
    url: https://somebot.com/bots/botId_1/ask
    locale: ja-JP
    time: 2018-07-01T12:18:45+09:00
    topic: test
    deleteVariable: false
    config: '("loglevel": "info"}'
    metadata: Send Data
sraixの記述で子要素を指定しない場合、bot_namesの定義内容で送信を行います。
bot_namesの定義を無効にする場合、sraixの該当子要素に空文字を指定します。
以下の例では、time、topicを無効化しています(deleteVariableは’false’のため送信されません)。
尚、userIdはbot_namesでは設定できないため、個別に指定します。(省略時には、対話APIの変数(var型)の __USER_USERID__ の値を使用します。)
<category>
    <pattern>XXX</pattern>
    <template>
        <sraix botName="someBot">
            <userId>someUser</userId>
            <time></time>
            <topic></topic>
            こんにちは
        <sraix>
    </template>
</category>

送信内容

POST /bots/botId_1/ask HTTP/1.1
Host: somebot.com
Content-Type: application/json;charset=UTF-8
x-api-key:

{
    "userId": "someUser",
    "locale": "ja-JP",
    "config": {"logLevel": "info"},
    "utterance": "こんにちは",
    "metadata": "Send Data"
}
sraixで子要素を指定した場合、bot_namesの定義より優先して設定されます。
metadataについては、bot_names定義とsraixの子要素指定の両方がJSON形式の場合に限り、結合した形式で送信します。但し、置換を行う場合は、第一階層のキーからの指定が必要です。
bot_names定義のmetadataがJSON形式で、一部のキーを除外して送信したい場合、子要素をJSON形式で指定し、該当キーの値として 直値:’null’ を設定します。(第一階層のキーのみが対象となります)。
以下の例では、topicとdeleteVariableを置換し、metadataを編集した値を送信しています。
尚、metadataに関するJSON結合処理例を示すため、前述のbot_names定義のmetadataを、次の様にJSON形式の値に変更しているものとします。
metadata: '{"key1":"value1", "key2": "value2", "key3": "value3"}'
<category>
    <pattern>XXX</pattern>
    <template>
        <sraix botName="someBot">
            <userId>someUser</userId>
            <topic>test</topic>
            <deleteVariable>true</deleteVariable>
            <metadata>{"key1": null, "key2": {"modify": "data"}, "key4": "added"}</metadata>
            こんにちは
        </sraix>
    </template>
</category>

送信内容

POST /bots/botId_1/ask HTTP/1.1
Host: somebot.com
Content-Type: application/json;charset=UTF-8
x-api-key:

{
    "userId": "someUser",
    "locale": "ja-JP",
    "time": "2018-07-01T12:18:45+09:00",
    "topic": "test",
    "deleteVariable": true,
    "config": {"logLevel": "info"},
    "utterance": "こんにちは",
    "metadata": {"key2":{"modify": "data"}, "key3": "value3", "key4": "added"}
}

受信

公開Botからの受信したボディ(JSON形式)の中の response要素が、sraixの戻り値として設定されます。
受信したボディがJSON形式でない場合や、JSON内に response要素が無い場合には公開Botとの通信として異常とし、属性:defaultが未設定の場合のsraixの戻り値は空文字になります。

以下のシナリオで、

<category>
     <pattern>*</pattern>
     <template>
        <sraix botName="someBot"><star /></sraix>
     </template>
</category>

公開Bot:someBotからの受信データが

HTTP/1.1 200 Ok
Content-Type: application/json;charset=UTF-8

{
    "response": "こんにちは、今日もいい天気ですね。",
    "topic": "greeting"
}

だった場合、結果は、

Input: こんにちは
Output: こんにちは、今日もいい天気ですね。

になります。

公開Botからの受信内容は、ローカル変数(var) __SUBAGENT_EXTBOT__.エイリアス名 にJSON形式で展開され、jsonタグで取得することができます。
尚、該当変数はcategory単位に保持されるため、継続利用の場合は、グローバル変数(name/data)への代入が必要です。
また、category内で、複数回、公開Botを呼び出した場合、__SUBAGENT_EXTBOT__ は上書きされるため、必要なレスポンス内容は他の変数に代入してください。
<category>
     <pattern>*</pattern>
     <template>
        <think>
            <sraix botName="someBot"><star /></sraix>
        </think>
        <json var="__SUBAGENT_EXTBOT__.someBot" />
     </template>
</category>
Input: こんにちは
Output: {“response”: “こんにちは、今日もいい天気ですね。”, “topic”: “greeting”}。

getタグで取得する場合には、変数名のみを指定する必要があり、第一階層のキーとしてエイリアス名が設定されたJSON全体を取得することになります。 前述のjsonタグをgetタグに変更すると、以下の様になります。

<get var="__SUBAGENT_EXTBOT__" />
Input: こんにちは
Output: {“someBot”: {“response”: “こんにちは、今日もいい天気ですね。”, “topic”: “greeting”}}。

公開Botからの受信ボディの内容はJSONのため、 json タグでJSON内部のパラメータを取得できます。 また、metadata の内容がJSONである場合、JSONタグで metadata 内のパラメータも取得できます。

公開Botからのボディの内容が、

{
    "utterance": "こんにちは",
    "response": "こんにちは、今日もいい天気ですね。",
    "topic": "greeting"
    "metadata":{"broadcaster":"OBS","title":"午後のニュース"}
}

の場合、

<json var="__SUBAGENT_EXTBOT__.someBot.response" />              <!-- 取得結果: こんにちは、今日もいい天気ですね。 -->
<json var="__SUBAGENT_EXTBOT__.someBot.utterance" />             <!-- 取得結果: こんにちは -->
<json var="__SUBAGENT_EXTBOT__.someBot.topic" />                 <!-- 取得結果: greeting -->
<json var="__SUBAGENT_EXTBOT__.someBot.metadata" />              <!-- 取得結果: {"broadcaster":"OBS","title":"午後のニュース"} -->
<json var="__SUBAGENT_EXTBOT__.someBot.metadata.broadcaster" />  <!-- 取得結果: OBS -->
<json var="__SUBAGENT_EXTBOT__.someBot.metadata.title" />        <!-- 取得結果: 午後のニュース -->

として、公開botからの戻り値、及び、metadataの情報を取得することができます。

(デバッグ情報)
 公開Botからの受信データ形式が不正な場合には通信異常として扱いますが、受信データは、__SUBAGENT_EXTBOT__.エイリアス名 に格納します。

NLU通信インタフェース

sraixの属性に、”nlu”を指定した場合、意図解釈エンジン(NLUサーバ)を呼び出します。
属性”nlu”の値には、nlu_servers ファイルで登録したエイリアス名を指定し、sraixの内容をNLUサーバへの入力文(発話文)として送信します。
(登録されていないエイリアス名を指定した場合には、AIML展開時に異常を検出し、該当のcategoryは無効になります。)
NLUサーバからの戻ってくる内容は、意図解釈エンジン仕様 で規定されたJSON形式であり、sraixの戻り値に、JSON形式のデータを返します。

以降の説明では、NLUサーバから以下のJSON形式のデータが返却された例として説明します。

{
    "intents": [
        {"intent": "transportation", "score": 0.9}
    ],
    "slots": [
        {"slot": "departure", "entity": "東京", "score": 0.85}
    ]
}

また、nlu_serversの定義は以下のもの使用するものとします。

servers:
  someNlu:
    url: https://***.com/run
    apikey: test_key

送信

NLU通信を利用する場合、sraixにはユーザ発話を設定する子要素はなく、sraixの内容がNLUに通知する発話文になります。
sraixの内容が無い(含む、空文字)の場合、NLUへの通信は行われず、属性:defaultが未設定の場合のsraixの戻り値は空文字になります。
以下は、NLU呼び出し時の動作例です。
<category>
    <pattern>nlu通信 *</pattern>
    <template>
        <sraix nlu="someNlu"><star /></sraix>
     </template>
</category>

送信内容

POST /run HTTP/1.1
Host: someNlu.com
Content-Type: application/json;charset=UTF-8
x-api-key: test_key

{
    "utterance": "お出かけは"
}
Input: nlu通信 お出かけは
Output: {“intents”: [{“intent”: “transportation”, “score”: 0.9 }], “slots”: [{“slot”: “departure”, “entity”: “東京”, “score”: 0.85}]}。

受信

送信時の例で示した通り、NLUサーバから受信したボディ(JSON形式)が、そのまま、sraixの戻り値として設定されます。
受信したボディがJSON形式でない場合はNLUとの通信として異常とし、属性:defaultが未設定の場合のsraixの戻り値は空文字になります。
NLUからの受信内容は、ローカル変数(var) __SUBAGENT_NLU__.エイリアス名 にJSON形式で展開され、jsonタグで取得することができます。
尚、該当変数はcategory単位に保持されるため、継続利用の場合は、グローバル変数(name/data)への代入が必要です。
また、category内で、複数回、公開Botを呼び出した場合、__SUBAGENT_NLU__ は上書きされるため、必要なレスポンス内容は他の変数に代入してください。
<category>
     <pattern>*</pattern>
     <template>
        <think>
            <sraix nlu="someNlu"><star /></sraix>
        </think>
        <json var="__SUBAGENT_NLU__.someNlu" />
     </template>
</category>
Input: お出かけは
Output: {“intents”: [{“intent”: “transportation”, “score”: 0.9 }], “slots”: [{“slot”: “departure”, “entity”: “東京”, “score”: 0.85}]}。

getタグで取得する場合には、変数名のみを指定する必要があり、第一階層のキーとしてエイリアス名が設定されたJSON全体を取得することになります。 前述のjsonタグをgetタグに変更すると、以下の様になります。

<get var="__SUBAGENT_NLU__" />
Input: お出かけは
Output: {“someNlu”: {“intents”: [{“intent”: “transportation”, “score”: 0.9 }], “slots”: [{“slot”: “departure”, “entity”: “東京”, “score”: 0.85}]}}。

NLUからの受信ボディの内容はJSONのため、 json タグでJSON内部のパラメータを取得できます。

<json var="__SUBAGENT_NLU__.someNlu.intents" />             <!-- 取得結果: [{"intent": "transportation", "score": 0.9}] -->
<json var="__SUBAGENT_NLU__.someNlu.intents" index="0" />   <!-- 取得結果: {"intent": "transportation", "score": 0.9} -->
<json var="__SUBAGENT_NLU__.someNlu.slots" />               <!-- 取得結果: [{"slot": "departure", "entity": "東京", "score": 0.85}] -->
<json var="__SUBAGENT_NLU__.someNlu.slots" index="0" />     <!-- 取得結果: {"slot": "departure", "entity": "東京", "score": 0.85} -->
(デバッグ情報)
 NLUからの受信データ形式が不正な場合には通信異常として扱いますが、受信データは、__SUBAGENT_NLU__.エイリアス名 に格納します。

nluintent / nluslotでのデータ取得

NLUサーバからの受信したデータを、template要素の nluintentnluslot を利用して、 マッチ処理で取得したNLUデータ: __SYSTEM_NLUDATA__ に対する処理と同様の操作を行うことができます。

以下に、NLUサーバから受信したデータに対して、nluintentで内容を取得する例を示します。

<nluintent name="*" item="count" target="__SUBAGENT_NLU__.someNlu" />                 <!-- 取得結果: 1 -->
<nluintent name="*" item="intent" index="0" target="__SUBAGENT_NLU__.someNlu" />      <!-- 取得結果: transportation -->
<nluintent name="transportation" item="score" target="__SUBAGENT_NLU__.someNlu" />    <!-- 取得結果: 0.9 -->

同様に、nluslotで内容を取得する例は以下の様になります。

<nluslot name="*" item="count" target="__SUBAGENT_NLU__.someNlu" />                 <!-- 取得結果: 1 -->
<nluslot name="*" item="slot" index="0" target="__SUBAGENT_NLU__.someNlu" />        <!-- 取得結果: departure -->
<nluslot name="departure" item="entity" target="__SUBAGENT_NLU__.someNlu" />        <!-- 取得結果: 東京 -->

尚、 nluintentnluslot で、JSON型の変数名(区切り文字:’.’ を利用)を指定できるのは、 ローカル変数(var) の __SUBAGENT_NLU__.xxx の形式の場合のみです。

カスタム外部サービス実装

属性に、”service”を指定した場合、カスタム実装を行なった処理を利用して、外部サービスを呼び出すことができます。 カスタム外部サービスは、利用するサービス(SubAgent)毎に実装が必要な呼び出し方法があるため、以下の基底クラスを継承して個別に実装します。

programy.services.service.Service

処理クラスの実装では、基底クラスを継承したクラスを作成し、ask_question()関数として、発話データに相当する”question”引数を利用して、結果の文字列を返す処理を実装します。 外部サービスとの連携を行う場合、ask_question()内に、REST通信機能を実装することになります。

from programy.services.service import Service

class StatusCheck(Service):
   __metaclass__ = ABCMeta

   def __init__(self, config: BrainServiceConfiguration):
       self._config = config

   @property
   def configuration(self):
       return self._config

   def load_additional_config(self, service_config):
       pass

   @abstractmethod
   def def ask_question(self, client_context, question: str):
       return "OK"

次に、Brainコンフィグレーションの services に、次のようにカスタム外部サービスのエントリを追加することで、sraixのサービス名として利用できるようになります。

myService:
    classname: programy.services.myService.StatusCheck
    url: https://myService.com/api/statuscheck

AIMLで利用する場合には、以下の例のように、sraixの属性”service”に、カスタム外部サービスのエントリ名を指定します。 sraixのカスタム外部サービスの処理としては、カスタム外部サービスのエントリのclassnameで定義されたクラスをロードし、関数:ask_question()が呼び出します。 関数:ask_question()の戻り値が、sraixの結果になります。

<category>
    <pattern>ステータスチェック *</pattern>
    <template>
        <star />のステータスは、<sraix service="myService"><star /></sraix>です。
    </template>
</category>
Input: ステータスチェック カスタム
Output: カスタムのステータスはOKです。

カスタム外部サービスへの引数および戻り値

引数

sraix service=”myService”がカスタム外部サービス呼び出しで、sraix要素内を引数として扱います。 引数の定義は個々のカスタム外部サービスの引数I/Fに依存しており、個々のサービスに合わせ実装を行う必要があります。

以下の例はmyServiceという外部サービスを利用する例で、引数4つを空白区切りで設定する前提で記載されています。
尚、日本語の場合、sraix要素の内容が全て結合されて空白区切りにならない場合があるため、引数間に space要素 を指定しています。
<aiml>
    <!-- sub agent execute -->
    <category>
        <pattern>subagent *</pattern>
        <template>
            <set var="text">
                <sraix service="myService">
                    <star />
                    <space />
                    <json var="__USER_METADATA__.arg1" />
                    <space />
                    <json var="__USER_METADATA__.arg2" />
                    <space />
                    <json var="__USER_METADATA__.arg3" />
                </sraix>
            </set>
            <think>
                <set name="departure"><json var="__SUBAGENT__.myService.transportation.station.departure" /></set>
                <set name="arrival"><json var="__SUBAGENT__.myService.transportation.station.arrival" /></set>
            </think>
            <get name="departure">から<get name="arrival">までを検索します。
        </template>
    </category>
</aiml>
戻り値
カスタム外部サービスの戻り値、つまり、個別実装のask_question()関数の戻り値は、ローカル変数(var) __SUBAGENT__.サービス名 に展開されます。
該当変数はcategory単位に保持されるため、継続利用の場合は、グローバル変数(name/data)への代入が必要です。
また、category内で、複数回、カスタム外部サービスを呼び出した場合、__SUBAGENT__ は上書きされるため、必要なレスポンス内容は他の変数に代入してください。

変数に格納される形式は、テキスト、または、JSON形式となり、カスタム実装でもバイナリは使用できません。

以下の例では、myServiceに対する処理の戻り値が __SUBAGENT__.myService に展開されていますが、その内容がJSON形式で、

{
    "transportation": {
        "station": {
            "departure" :"東京",
            "arrival" : "京都"
        },
        "time": {
            "departure": "2018/11/1 11:00",
            "arrival": "2018/11/1 13:30"
        },
        "facility": ["鹿苑寺", "清水寺", "伏見稲荷大社"]
    }
}

の場合、

<json var="__SUBAGENT__.myService.transportation.station.departure" />
<json var="__SUBAGENT__.myService.transportation.station.arrival" />

として、jsonタグを利用して、ボディの内部情報を取得することができます。

カスタム外部サービスの戻り値がテキストの場合、__SUBAGENT__.myService を変数名として、getタグで取得することになります。
※sraixの結果データの処理方式を統一する観点から、カスタム実装において、JSON形式で出力することを推奨します。
<get var="__SUBAGENT__.myService />

関連項目: metadata, 対話API, JSON

Extensions

概要

Extensionsとは、拡張機能を個別に実装するための機能で、templateのextension要素に、path属性としてPythonパスを記載することで追加機能を呼び出すことができる仕組みを提供します。

カスタムエクステンションの実装

カスタムエクステンションの実装クラスでは、以下の基底クラスを継承する必要があります。

programy.extensions.base.Extension
次に実装例を示します。
エクステンションの処理を実行するメソッドは execute() で、エクステンションのクラスには、contextdata を引数としたexecuteメソッドを実装します。
context には、クライアント・ユーザ毎の管理情報を格納したClientContextクラス(programy.context.ClientContext)が引き渡され、ユーザID等の情報を取得することができます。
data には、extensionタグの内容が文字列で設定されます。

以下は、数値演算を行うカスタムエクステンションの例です。

# programy/extensions/calc.py

from programy.extensions.base import Extension

class CalcExtension(Extension):

    def execute(self, context, data):
        try:
            result = str(eval(data))
            return result
        except Exception:
            return None
AIMLでカスタムエクステンションを利用する場合、以下の様にextension要素を記載します。
AIMLのextension要素の処理としては、path属性で指定されたクラスをロードし、execute() を呼び出します。
execute() の戻り値が、extension要素の結果になりますので、戻り値には文字列を設定する必要があります。(Noneの場合は、空文字扱いになります。)

なお、path属性で指定されたクラスのロード失敗や、execute() 処理に異常がある場合、対話エンジンは処理中の例外発生として扱います。 (応答文定義の exception_response が指定さている場合、指定の文字列が返ります。)

<category>
    <pattern>
        演算 *
    </pattern>
    <template>
         結果は、
         <extension path="programy.extensions.calc.CalcExtension">
             <star />
         </extension>
         です。
    </template>
</category>
Input: 演算 1 + 2 * 3 / 4 - 5
Output: 結果は、-2.5です。

この場合、execute() のdata引数には <star /> の展開文字列として、‘1 + 2 * 3 / 4 - 5’ が引き渡されます。

シナリオ変数の利用

カスタムエクステンション実行時に引数として通知されるクライアント・ユーザ毎の管理情報:ClientContextクラスを利用することで、シナリオ内で設定された変数の情報も操作できます。
各変数は対話内容により変動する為、クライアント・ユーザ毎の対話情報(conversation)で管理されています。対話情報の取得は、以下の様に行います。
def execute(self, context, data):

    conversation = context.bot.get_conversation(context)

対話情報を取得することで、変数内容の参照や、設定を行うことが可能になります。変数の種別については、template要素の get の記述を参照してください。

なお、各変数の値は文字列形式で格納されています。JSON形式のデータを利用する場合は、以下の操作で形式変換を行って使用してください。

  • 取得時: <JSON変数:辞書型> = json.loads(<シナリオ変数:文字列型>)
  • 格納時: <シナリオ変数:文字列型> = json.dumps(<JSON変数:辞書型>, ensure_ascii=False)

継続保持グローバル変数(name)の利用

name変数は、対話情報内の properties に辞書データとして格納されています。操作関数には以下を使用します。

name_list = conversation.properties                   # 変数(辞書)リストの取得
get_value = conversation.proprty('変数名')             # 任意変数値の取得
set_value = conversation.set_property('変数名', '値')  # 任意変数の追加・変更
remove = conversation.set_property('変数名', ’’)       # 任意変数の削除(値に空文字を指定)

指定範囲保持グローバル変数(data)の利用

data変数は、対話情報内の data_properties に辞書データとして格納されています。操作関数には以下を使用します。

data_list = conversation.data_properties                   # 変数(辞書)リストの取得
get_value = conversation.data_proprty('変数名')             # 任意変数値の取得
set_value = conversation.set_data_property('変数名', '値')  # 任意変数の追加・変更
remove = conversation.set_data_property('変数名', ’’)       # 任意変数の削除(値に空文字を指定)

ローカル変数(var)の利用

var変数は category単位の処理内でのみ有効な変数のため、対話情報においてcategory毎の情報を管理するquestionクラスの _properties に辞書データとして格納されています。 操作を行うためには、以下の様に、現在処理中の questionクラスを取得した上で操作関数を使用します。

question = conversation.current_question()

var_list = question._properties                   # 変数(辞書)リストの取得
get_value = question.proprty('変数名')             # 任意変数値の取得
set_value = question.set_property('変数名', '値')  # 任意変数の追加・変更
remove = question.set_property('変数名', ’’)       # 任意変数の削除(値に空文字を指定)

bot固有プロパティの取得

bot固有のプロパティ(固定値)の取得には、以下の操作関数を使用します。

bot_property = conversation.bot.brain.properties.property('プロパティ名')

OOB

OOB(Out of Band) は、動的にロードされるクラスとAIMLのoob要素で指定するOOB機能の名称の組み合わせで実現します。 使用するOOB機能毎に、Pythonクラスを実装し、コンフィグレーションの OOB設定 で、以下の様に機能名と関連付けを行う必要があります。

パラメータ名 説明  
OOBの名称   この項目に設定した名称が、AIMLで指定するOOB名になります。例では’email’がOOB名になります。
  classname 実装を行うOOBのpythonのクラスパスを定義します。OOB内を実装する子要素は実装クラスで定義しており、configで指定する必要はありません。

OOBの実装基底クラスは次のように定義されています。

# programy/oob/defaults/oob.py

import xml.etree.ElementTree as ET

class OutOfBandProcessor(object):

    def __init__(self):
        self._xml = None

    # Override this method to extract the data for your command
    # See actual implementations for details of how to do this
    def parse_oob_xml(self, oob: ET.Element):
        self._xml = oob
        return True

    # Override this method in your own class to do something
    # useful with the command data
    def execute_oob_command(self, client_context):
        raise NotImplementedError()

    def process_out_of_bounds(self, client_context, oob: ET.Element):
        if self.parse_oob_xml(oob) is True:
            return self.execute_oob_command(client_context)
        return ""

電子メールを送信するOOB機能がある場合、OOBを利用するAIMLは次のように記載します。

<oob>
    <email>
        <to>宛先</to>
        <subject>件名</subject>
        <body>本文</body>
    </email>
</oob>

この場合、OOBの処理クラスに渡される引数は以下のXMLになります。

<oob>
    <to>宛先</to>
    <subject>件名</subject>
    <body>本文</body>
</oob>

実装クラスは次のようになります。 parse_oob_xml()メソッドでAIMLのoob要素で指定された内容(XML形式)から引数値を取得し、execute_oob_command()メソッドで実際にメールを送信する処理を実装します。

# programy/oob/email/email.py

from programy.oob.defaults.oob import OutOfBandProcessor

class EmailOutOfBandProcessor(OutOfBandProcessor):

    def __init__(self):
        OutOfBandProcessor.__init__(self)
        self._to = None
        self._subject = None
        self._body = None

    def parse_oob_xml(self, oob: ET.Element):
        for child in oob:
            if child.tag == 'to':
                self._to = child.text
            elif child.tag == 'subject':
                self._subject = child.text
            elif child.tag == 'body':
                self._body = child.text
            else:
                logging.error ("Unknown child element [%s] in email oob"%(child.tag))

            if self._to is not None and \
                self._subject is not None and \
                self.body is not None:
                return True

            logging.error("Invalid email oob command")
            return False

    def execute_oob_command(self, client_context):
        logging.info("EmailOutOfBandProcessor: Emailing=%s", self._to)
        return ""

OOB機能を利用するための定義として、コンフィグレーションで以下の設定を行います。

oob:
    email:
        classname: programy.oob.email.email.EmailOutOfBandProcessor

OOBの詳細設定方法は、 OOBの設定 を参照してください。

RDFサポート

RDF(Resource Descriptor Framework)はW3Cが勧告する、XMLをベースにメタコンテンツを記述するための規格です。
RDFで基本となるデータ構造は triple と呼ばれる3つのデータの組で、主語(subject)、述語(predicate)、目的語(object)の組み合わせで表されます。
詳細は、 RDF Concepts And Abstract を参照してください。
tripleのデータは、subject、predicate、objectをコロン ‘:’で区切ったテキストで表記することができます。
以下は、飛行機に関する情報をtriple化して列記した例で、”AIRPLANE”という”subject”に対し、複数の”predicate”と、predicateに対応する”object”が定義できます。
AIRPLANE:hasPurpose:to transport us through the air
AIRPLANE:hasSize:9
AIRPLANE:hasSpeed:12
AIRPLANE:hasSyllables:1
AIRPLANE:isa:Aircraft
AIRPLANE:isa:Transportation
AIRPLANE:lifeArea:Physical
本対話エンジンのRDFサポートは、W3C勧告にある外部リソースを利用したデータ処理ではなく、内部に保持するtripleデータ群(以降、’RDFデータ’と表記)を対象として処理を行います。
また、検索機能についても、単純な検索に対応することを目的としており、検索エンジンが提供している複雑な検索処理には対応していません。

RDFデータ処理用のAIMLタグ

本対話エンジンでは、template要素でのRDFデータ処理用として以下のAIMLタグが使用できます。

  • addtriple : RDFデータの追加。
  • deletetriple : RDFデータの削除。
  • uniq : RDFデータに対する検索(単一結果出力用)。
  • select : RDFデータに対する検索(複合結果出力用)。

また、検索結果を変数に出力した場合には、以下のAIMLタグが使用できます。

  • get : 検索結果データを取得。一部のデータのみを取得する場合、子要素:tuple を利用します。
  • first : 検索結果データから、先頭の検索結果を取得します。
  • rest : 検索結果データから、2番目以降の検索結果を取得します。
  • set : 検索結果データの他変数への代入。

RDFデータ管理

対話エンジンでは、subject、predicate、objectの組み合わせを一意のデータとして管理し、エレメントと称します。 RDFデータの各エレメントは、対話エンジン起動時の初期ロードとともに、シナリオでの操作により追加・削除が行えます。

初期ロード

対話エンジンの起動時に、事前に用意したファイル群から各エレメントを登録します。

対象ファイルの指定は、ファイル管理のエンティティrdf で行い、該当する全ての定義ファイルを読み込んで、エレメントを展開します。

*特定のフォルダ配下の ‘*.txt’ から展開する場合の例(サブフォルダも利用可能)。

client_type:
    storage:
        entities:
            rdf: file

        stores:
            file:
                type: file
                config:
                    rdf_storage:
                        dirs: ../storage/rdfs
                        subdirs: true
                        extension: txt
定義ファイルは、エレメント毎に、subject、predicate、objectをコロン ‘:’で区切って列記します。subject、predicate、objectのいずれかが空文字の場合は、無効になります。
同じ組み合わせのエレメントが複数指定されている場合でも、重複登録は行いません。
なお、RDFデータに対する検索を効率的に行うため、登録されたデータは全て文字コードを変換して登録します(英字:半角大文字、数記号:半角、カタカナ:全角)。

以降では、次の記述をした定義ファイルを初期ロードしたものとして説明します。

ant:legs:6
ant:sound:scratch
bat:legs:2
bat:sound:eee
bear:legs:4
bear:sound:grrrrr
buffalo:legs:4
buffalo:sound:moo
cat:legs:4
cat:sound:meow
chicken:legs:2
chicken:sound:cluck cluck
dolphin:legs:0
dolphin:sound:meep meep
fish:legs:0
fish:sound:bubble bubble

エレメント追加

template要素の addtriple 要素を利用することで、動的に新しいエレメントを追加できます。記述形式は、以下になります。

<addtriple>
  <subj>Subject</subj><pred>Predicate</pred><obj>Object</obj>
</addtriple>

動物の特性を追加する例です。

<addtriple>
    <subj>cow</subj><pred>sound</pred><obj>moo</obj>
</addtriple>
<addtriple>
    <subj>dog</subj><pred>sound</pred><obj>woof</obj>
</addtriple>

初期ロードと同様に文字コード変換を行って登録するため、以下のRDFデータが登録されます。

COW:SOUND:MOO
DOG:SOUND:WOOF

なお、addtripleで追加したデータは永続的ではなく、対話エンジンを再起動した時点で初期状態に戻ります。

エレメント削除

template要素の deletetriple 要素を利用することで、addtriple要素で追加したエレメントだけではなく、初期ロードしたエレメントも削除できます。記述形式は、以下になります。

<deletetriple>
  <subj>Subject</subj><pred>Predicate</pred><obj>Object</obj>
</deletetriple>
3つの要素(subject、predicate、object)を指定すると、全て合致したエレメントのみが削除されます。
subjectとpredicateだけを指定した場合、objectの値に関係なく、合致するエレメントを削除します。
subjectだけを指定した場合、そのsubjectに合致する全てのエレメントを削除します。

addtripleで追加したエレメントと、初期ロードしたエレメントを削除する例です。

<deletetriple>
  <subj>cow</subj><pred>sound</pred><obj>moo</obj>
</deletetriple>
<deletetriple>
  <subj>ant</subj><pred>sound</pred><obj>scratch</obj>
</deletetriple>

なお、deletetripleも永続的ではなく、対話エンジンを再起動した時点で初期状態に戻ります。

RDFデータの検索

RDFデータの検索要素には2種類がありますが、それぞれの仕様は以下のように異なります。

  • uniq要素

    1つの検索条件を指定し、検索結果に対して重複した文字列を除外し、空白区切りの結合した文字列を返します。

  • select要素

    複数の検索条件の指定が可能で、検索結果をエレメントを単位とした複数候補をリスト化した文字列で返します。変数を使用することで関連づけた検索が可能です。

uniqによる検索

template要素の uniq 要素を用いて、RDFデータの検索を行います。
uniqでの検索では、取得したい項目に対して ‘?’ を指定します。

特定の情報を取得する場合、以下の様に記述します。

<uniq>
    <subj>ant</subj>
    <pred>sound</pred>
    <obj>?</obj>
</uniq>
結果として、subject、predicateが一致するエレメントのobjectの値が取得できます。
SCRATCH

検索時にエレメント要素の指定を省略することが可能で、subjectの一覧を取得する場合、以下の様に記述します。

<uniq>
    <subj>?</subj>
</uniq>
結果として、subjectの一覧が空白区切りで出力されます。uniqでは重複する文字列は除外される為、一覧として参照できます。
ANT BAT BEAR BUFFALO CAT CHICKEN DOLPHIN FISH

特定の条件を指定する例として、predicate=”legs”の条件で、objectの一覧を取得します。

<uniq>
    <pred>legs</pred>
    <obj>?</obj>
</uniq>
結果として、重複したものは除外される為、以下の様になります。
6 2 4 0

selectによる検索

template要素の select 要素を用いて、RDFデータの検索を行います。
selectの検索結果は、[“要素名”, “値”] を最小単位として、エレメント毎に格納される為、以下の様なリスト形式の文字列になります。
[[[“subj”, “ANT”], [“pred”, “LEGS”], [“obj”, “6”]], [[“subj”, “ANT”], [“pred”, “SOUND”], …], …]

selectで使用可能なクエリ用の子要素には <q>とともに、<notq>がありますが、<notq>は、子要素で指定された条件に合致しない全てのエレメントを対象としますので大量のデータを出力することになります。

単純検索

単純な検索の場合、<q>要素の内容として、subject、predicate、objectの3つを指定すると、合致した結果として登録されている内容をリスト型で返します。

<select>
    <q><subj>dog</subj><pred>sound</pred><obj>woof</obj></q>
</select>
初期ロード状態では結果が空文字になる為、取得失敗時の応答文が返りますが、エレメント追加 を実施すると、以下の結果が返ってきます。
[[[“subj”, “DOG”], [“pred”, “SOUND”], [“obj”, “WOOF”]]]

特定の1つの要素のみを取得する場合、以下の記述ができます。

<select>
    <q><subj>cat</subj><pred>sound</pred><obj>?</obj></q>
</select>
この場合、”?”を指定した要素の内容を示す、以下の結果が返ってきます。
[[[“?”, “MEOW”]]]
変数による検索
複数の要素を返す場合や、一致する要素のリストを受け取る場合は、変数を使用する必要があります。
変数はvarsタグの内容で定義し、変数名の接頭辞として “?” を付けます。
クエリ<q>でエレメントの要素に変数を設定することができます。
以下の場合、変数:?x はsubject、変数:?y はpredicate、変数:?z はobjectの格納対象となります。
<select>
    <vars>?x ?y ?z</vars>
    <q><subj>?x</subj><pred>?y</pred><obj>?z</obj></q>
</select>
指定したデータに一致するすべてのエレメントから、変数に該当するデータを取得することができます。
以下は、動物の足の本数(legs)を検索する例です。
<select>
    <vars>?x ?y</vars>
    <q><subj>?x</subj><pred>legs</pred><obj>?y</obj></q>
</select>
検索結果が合致した場合、以下の様に変数に該当する情報のみの結果が返ってきます。
[[[“?x”, “ANT”], [“?y”, “6”]], [[“?x”, “BAT”], [“?y”, “2”]], [[“?x”, “BEAR”], [“?y”, “4”]], [[“?x”, “BUFFALO”], [“?y”, “4”]], [[“?x”, “CAT”], [“?y”, “4”]], [[“?x”, “CHICKEN”], [“?y”, “2”]], [[“?x”, “DOLPHIN”], [“?y”, “0”]], [[“?x”, “FISH”], [“?y”, “0”]]]
複合条件検索
変数を使用した場合には、複数のクエリを使用することで条件を絞り込むことができます。
以下の例では、1つ目のクエリで取得したsubjectのリストと、2つ目のクエリで取得したsubjectのリスト中で、共通するものが変数:?xとして、出力されます。
<select>
    <vars>?x</vars>
    <q><subj>?x</subj><pred>legs</pred><obj>0</obj></q>
    <q><subj>?x</subj><pred>sound</pred></q>
</select>
結果として、predicate=”legs”でobject=”0”が定義されたsubjectの中で、predicate=”sound”が定義されているsubjectのリストが返ってきます。
[[[“?x”, “DOLPHIN”]], [[“?x”, “FISH”]]]
さらに変数を使用することで、該当するsubjectの中から特定の要素の情報を取得することができます。以下の例では、objectを変数:?yで出力します。
<select>
    <vars>?x ?y</vars>
    <q><subj>?x</subj><pred>legs</pred><obj>0</obj></q>
    <q><subj>?x</subj><pred>sound</pred><obj>?y</obj></q>
</select>
結果は次の様になります。
[[[“?x”, “DOLPHIN”], [“?y”, “MEEP MEEP”]], [[“?x”, “FISH”], [“?y”, “BUBBLE BUBBLE”]]]
データ取得
select要素は、SQLのSELECT文のようにデータセットを作成するために使用されます。
以下の例では、select要素の取得結果を’set’タグを用いて、tuplesに格納しています。
<set var="tuples">
    <select>
        <vars>?x ?y</vars>
        <q><subj>?x</subj><pred>sound</pred><obj>?y</obj></q>
    </select>
</set>
この場合に、tuplesに以下の内容が設定されています。
[[[“?x”, “BAT”], [“?y”, “EEE”]], [[“?x”, “BEAR”], [“?y”, “GRRRRR”]], [[“?x”, “BUFFALO”], [“?y”, “MOO”]], [[“?x”, “CAT”], [“?y”, “MEOW”]], [[“?x”, “CHICKEN”], [“?y”, “CLUCK CLUCK”]], [[“?x”, “DOLPHIN”], [“?y”, “MEEP MEEP”]], [[“?x”, “FISH”], [“?y”, “BUBBLE BUBBLE”]], [[“?x”, “DOG”], [“?y”, “WOOF”]]]

前述の’select’要素から生成されたデータを取得する場合、’get’タグの子要素’tuple’を利用して取得します。

<get var="?x">
    <tuple>
        <get var="tuples" />
    </tuple>
</get>
<get var="?y">
    <tuple>
        <get var="tuples" />
    </tuple>
</get>
この例の場合、getの’var’属性に、select要素で指定した変数 “?x” を指定しています。
次に、tupleタグで、select要素の結果を格納した”tuples”(リストオブジェクト)を指定することで、”tuples”の中から、変数 “?x” に該当するデータが取得できます。
結果として、変数 “?x” からは以下の内容が取得できます。
BAT BEAR BUFFALO CAT CHICKEN DOLPHIN FISH DOG
同様に、変数 “?y” からは以下の内容が取得できます。
EEE GRRRRR MOO MEOW CLUCK CLUCK MEEP MEEP BUBBLE BUBBLE WOOF

また、”tuples”に対して、firstタグ、restタグを利用することで、以下の様に部分的な結果を取得することもできます。

<get var="?x">
    <tuple>
        <first><get var="tuples" /></first>
    </tuple>
</get>
<get var="?y">
    <tuple>
        <rest><get var="tuples" /></rest>
    </tuple>
</get>
結果として、firstタグ(先頭データ取得)で、変数 “?x” から取得した値は以下になります。
BAT
同様に、restタグ(先頭以外のデータ取得)で、変数 “?y” から取得した値は以下になります。
GRRRRR MOO MEOW CLUCK CLUCK MEEP MEEP BUBBLE BUBBLE WOOF

Security

認証と承認の2段階のセキュリティ定義があります。

認証(Authentication)

認証機能は要件に応じたユーザ管理等の個別の実装が必要になる機能のため、使用していません。
また、外部サービスを利用して認証を行う、account_linker については、対話処理とは別に実施すべき機能のため使用できません。
別途、必要な認証手続きを上位のアプリケーション等で行った上、対話処理を実施される事を推奨します。
以下に、認証に関する基本的な制御構造について説明します。
認証はコアコードのbrain内で実施され、ユーザからの発話文毎に処理される ask_question() 内で呼び出されます。
コンフィグレーションで指定された認証サービスを利用して、認証されたユーザのみが対話処理を実施できる様に制御します。
class Brain(object):

    def __init__(self, bot, configuration: BrainConfiguration):
       self._security = SecurityManager(configuration.security)

    def authenticate_user(self, client_context):
        return self._security.authenticate_user(client_context)

    def ask_question(self, bot, clientid, sentence):

        authenticated = self._security.authenticate_user(client_context)
        if authenticated is not None:
            return authenticated
認証サービスは、コンフィグレーションの定義に従って、SecurityManagerによってロードされるクラスで、その基底クラスは次のように定義されています。
SecurityManagerの authenticate_user() を実施することで、認証サービス内の authenticate() が呼び出されます。
class Authenticator(object):

    def __init__(self, configuration: BrainSecurityConfiguration):
        self._configuration = configuration

    @property
    def configuration(self):
        return self._configuration

    def get_default_denied_srai(self):
        return self.configuration.denied_srai

    def authenticate(self, clientid: str):
        return False

以下の認証サービスの例では、対話処理のアプリケーションの識別名となる’clientid’と、個々のユーザの識別名’userid’で制御しています。 この実装では、clientid:’console’でアクセスされたユーザの’userid’を’authorised’リストで管理して、認証を行うシンプルなものです。

class ClientIdAuthenticationService(Authenticator):

    def __init__(self, configuration: BrainSecurityConfiguration):
        Authenticator.__init__(self, configuration)
        self.authorised = [
            "console"
        ]

    def user_auth_service(self, client_context):
        return False

    def _auth_clientid(self, client_context):
        authorised = self.user_auth_service(client_context)
        if authorised is True:
            self.authorised.append(client_context.userid)
        return authorised

    def authenticate(self, client_context):
        try:
            if client_context.userid in self.authorised:
                return True
            else:
                if self._auth_clientid(client_context) is True:
                    return True

                return False
        except Exception as excep:
            YLogger.error(client_context, str(excep))
            return False

上記機能を使用するには、Brainコンフィグレーションの security で、以下の項目を定義する必要があります。

brain:
    security:
        authentication:
            classname: programy.security.authenticate.clientidauth.ClientIdAuthenticationService

承認(Authorisation)

承認は、templateの authorise 要素において、配下にある各要素の展開を制御する為に行います。
承認も認証と同じく要件に応じた処理が必要であり、変更を可能にする為、コンフィグレーションで指定された承認サービスを利用する方式で行います。

authorise 要素での承認処理は、以下の様に行っています。

class TemplateAuthoriseNode(TemplateNode):

    def resolve_to_string(self, client_context):

        if client_context.brain.security.authorisation is not None:
            try:
                allowed = client_context.brain.security.authorisation.authorise(client_context.userid, self.role)
            except AuthorisationException:
                allowed = False

承認サービスは、コンフィグレーションの定義に従って、brain.security.authorisation にロードされるクラスで、その基底クラスは次のように定義されています。

class Authoriser(object):

    def __init__(self, configuration: BrainSecurityConfiguration):
        self._configuration = configuration

    @property
    def configuration(self):
        return self._configuration

    def get_default_denied_srai(self):
        return self.configuration.denied_srai

    def authorise(self, userid, role):
        return False

以下に、authorise要素で使用している、ユーザの識別名’userid’を元に行う承認処理を説明します。

シナリオでの承認を用いた記載は、利用制限をかけるtemplate要素を、authorise タグで囲むことで指定します。
以下のシナリオの場合、発話文で’ALLOW ACCESS’が入力された場合、指定された’userid’が ‘root’ の権限(role)を持っている場合、’Access Allowed’ の文字が変え入りますが、持っていない場合には空文字が返ります。
<category>
    <pattern>ALLOW ACCESS</pattern>
    <template>
        <authorise role="root">
            Access Allowed
        </authorise>
    </template>
</category>

承認処理を行うクラスの実装は以下になります。

class BasicUserGroupAuthorisationService(Authoriser):

    def __init__(self, config: BrainSecurityAuthorisationConfiguration):
        Authoriser.__init__(self, config)
        self._users = {}
        self._groups = {}

    @property
    def users(self):
        return self._users

    @property
    def groups(self):
        return self._groups

    def initialise(self, client):
        self.load_users_and_groups(client)

    def load_users_and_groups(self, client):
        if client.storage_factory.entity_storage_engine_available(StorageFactory.USERGROUPS) is True:
            storage_engine = client.storage_factory.entity_storage_engine(StorageFactory.USERGROUPS)
            usergroups_store = storage_engine.usergroups_store()
            usergroups_store.load_usergroups(self)
        else:
            YLogger.warning(self, "No user groups defined, authorisation tag will not work!")

    def authorise(self, userid, role):
        if userid not in self._users:
            raise AuthorisationException("User [%s] unknown to system!" % userid)

        if userid in self._users:
            user = self._users[userid]
            return user.has_role(role)
        return False

尚、本機能を使用する為、Brainコンフィグレーションの security で、以下の項目を定義する必要があります。

security:
    authorisation:
        classname: programy.security.authorise.usergroupsauthorisor.BasicUserGroupAuthorisationService
        denied_srai: AUTHORISATION_FAILED
        denied_text: Access Denied!

 ※ denied_sraidenied_text は、認証失敗時の動作に関するオプションです。

ユーザグループファイル

承認処理を制御するために、ユーザ(userId)と権限(role)の関係を定義するものが、Storageの usergroupsエンティティ で指定したファイルになります。
定義は、yaml形式で行います。基本的な記述形式は、以下の2つの形式になります。

1つ目は、ユーザ毎に権限を記載する方式です。

users:
  ユーザ名:
    roles: 権限名リスト

2つ目は、グループ名を規定し、グループ毎に権限を指定し、該当するユーザ名を列記する方式です。

groups:
  グループ名:
    roles: 権限名リスト
    users: ユーザ名リスト

以下の例では、’administrator’の権限は’rootと’user’、’others’の権限は’user’、そして、’guest1’と’guest2’の権限は’guest’になります。

設定例

users:
  administrator:
    roles: root, user
  others:
    roles: user

groups:
   general:
      users: guest1, guest2
      roles: guest
また、groupsを子タグで指定することで関係付けができるため、以下の様な指定も可能です。
この場合には、結果的に、’console’の権限は’user’に加えて、’root’、’admin’、’system’、’ask’が設定されます。

設定例

users:
  console:
    roles: user
    groups: sysadmin

groups:
  sysadmin:
    roles: root, admin, system
    groups: user
  user:
    roles: ask
尚、グループを関係付けて記述した場合、最終的にユーザに対する権限が指定されないことがあります。基本的な記法をベースとしたシンプルな記述を推奨します。
又、記述純情に関係なく``users`` 定義の展開を先に行う為、users 定義でユーザの権限を指定している場合、groups 定義で同じユーザに別の権限を指定しても、users での指定が優先されます。

Pre/Post Processors

対話エンジン内にはPre ProcessorsとPost Processorsの2種類のプロセッサがあります。
発話文に対し、対話エンジン内での対話処理前に加工する必要がある場合、対話エンジンからの応答文に対し返却前に加工が必要である場合に用います。
  • Pre Processors は、対話エンジン内部で対話処理を行う前に、文字列の前処理を行うプロセッサです。
  • Post Processors は、対話エンジン内部で対話処理を行った応答文に対し、APIで返却を行う前に文字列の後処理を行うプロセッサです。

Pre Processors

Pre Processorsは、以下の抽象基本クラスから継承します。

programy.processors.processing.PreProcessor

このクラスには単一のメソッドprocessがあり、入力されたstringに対し前処理を行い、処理された文字列を返却します。 返却された文字列を対話エンジン内で利用し対話を進行します。

class PreProcessor(Processor):

    def __init__(self):
        Processor.__init__(self)

    @abstractmethod
    def process(self, bot, clientid, string):
        pass

Post Processors

Post Processorsは、以下の抽象基本クラスから継承します。

programy.processors.processing.PostProcessor

このクラスには単一のメソッドprocessがあり、入力されたstringに対し前処理を行い、処理された文字列を返却します。 返却された文字列をエンドユーザに対する応答文として使用します。

class PostProcessor(Processor):
    def __init__(self):
        Processor.__init__(self)

    @abstractmethod
    def process(self, bot, clientid, string):
        pass

カスタム要素

対話エンジンはAIMLのpattern要素・template要素に対して、使用可能な要素の指定や、既存要素の処理の置き換えに加えて、AIMLの機能を拡張するための新しい要素が追加できる構造になっています。
新しい要素を追加する場合には、利用者のニーズやシステム要件に沿った固有機能の実装を要素として指定することで、既存要素では処理ができなかった独自の機能を追加できます。
既存要素についても、処理内容を変更した要素実装を複数用意することで、要件に応じて容易に要素の処理内容を切り替えることができます。

カスタムpattern要素

対話エンジンは pattern要素として、pattern_nodes.conf で定義されているAIMLタグをサポートします。
pattern_nodes.conf を変更することで、要素に対応する処理クラスを変更したり、独自の要素を追加することができます。
要素の実装を変更すると、パーサが動作しなくなったりパフォーマンスや他の要素の動作に重大な影響を与える可能性があるため全体の動作を理解した上でご利用ください。

要素毎に以下の記述を列記します。

AIMLタグ名 = python処理クラスのパス

*記述例

#AIML 1.0
root = programy.parser.pattern.nodes.root.PatternRootNode
word = programy.parser.pattern.nodes.word.PatternWordNode
priority = programy.parser.pattern.nodes.priority.PatternPriorityWordNode
oneormore = programy.parser.pattern.nodes.oneormore.PatternOneOrMoreWildCardNode
topic = programy.parser.pattern.nodes.topic.PatternTopicNode
that = programy.parser.pattern.nodes.that.PatternThatNode
template = programy.parser.pattern.nodes.template.PatternTemplateNode

#AIML 2.0
zeroormore = programy.parser.pattern.nodes.zeroormore.PatternZeroOrMoreWildCardNode
set = programy.parser.pattern.nodes.set.PatternSetNode
bot = programy.parser.pattern.nodes.bot.PatternBotNode

#Custom
iset = programy.parser.pattern.nodes.iset.PatternISetNode
regex = programy.parser.pattern.nodes.regex.PatternRegexNode
新たなtemplate要素を作成する場合、programy.parser.pattern.nodes.base.PatternNode を基底クラスとして継承します。
本基底クラスを継承することで、AIMLのXML要素をpatternクラスのノード属性にカプセル化します。また、patternの評価中に対象文字列を要素の型に変換させる処理も行います。

以下が、オーバーライドする主なメソッドになります。

  • __init__(self, attribs, text, userid='*', element=None, brain=None)

    xmlの要素を解析して展開します。xmlの属性記述が attribs にリストで、内容が text で引き渡されます。展開できない場合は必要に応じて適切な例外をスローします。

  • def equivalent(self, other)

    処理要素が他の評価要素と等価かどうかを判定します。

  • def equals(self, client_context, words, word_no)

    対象文字列が要素のルールにマッチするかどうかを判定します。words で単語単位の分割リスト、word_no で評価開始位置が引き渡されます。 判定結果は EqualsMatchクラス(programy.parser.pattern.matcher.EqualsMatch)で返し、EqualsMatchクラス生成の第一引数で True/False を設定します。

  • def to_string(self, verbose=True)

    デバッグやロギングの出力の為に、要素情報を文字列表現に変換します。

  • def to_xml(self, client_context, include_user=False)

    要素の内容をXML形式に変換します。XML形式の Braintree を出力する場合に利用します。

カスタムtemplate要素

対話エンジンは template要素として、template_nodes.confを含むシステムで定義された全てのAIMLタグをサポートします。
template_nodes.conf を変更することで、要素に対応する処理クラスを変更したり、独自の要素を追加することができます。
要素の実装を変更すると、パーサが動作しなくなったりパフォーマンスや他の要素の動作に重大な影響を与える可能性があるため全体の動作を理解した上でご利用ください。

要素毎に以下の記述を列記します。

AIMLタグ名 = python処理クラスのパス

*記述例

word = programy.parser.template.nodes.word.TemplateWordNode
authorise = programy.parser.template.nodes.authorise.TemplateAuthoriseNode
random = programy.parser.template.nodes.rand.TemplateRandomNode
condition = programy.parser.template.nodes.condition.TemplateConditionNode
srai = programy.parser.template.nodes.srai.TemplateSRAINode
sraix = programy.parser.template.nodes.sraix.TemplateSRAIXNode
get = programy.parser.template.nodes.get.TemplateGetNode
set = programy.parser.template.nodes.set.TemplateSetNode
map = programy.parser.template.nodes.map.TemplateMapNode
bot = programy.parser.template.nodes.bot.TemplateBotNode
think = programy.parser.template.nodes.think.TemplateThinkNode
normalize = programy.parser.template.nodes.normalise.TemplateNormalizeNode
denormalize = programy.parser.template.nodes.denormalise.TemplateDenormalizeNode
person = programy.parser.template.nodes.person.TemplatePersonNode
person2 = programy.parser.template.nodes.person2.TemplatePerson2Node
gender = programy.parser.template.nodes.gender.TemplateGenderNode
sr = programy.parser.template.nodes.sr.TemplateSrNode
id = programy.parser.template.nodes.id.TemplateIdNode
size = programy.parser.template.nodes.size.TemplateSizeNode
vocabulary = programy.parser.template.nodes.vocabulary.TemplateVocabularyNode
eval = programy.parser.template.nodes.eval.TemplateEvalNode
explode = programy.parser.template.nodes.explode.TemplateExplodeNode
implode = programy.parser.template.nodes.implode.TemplateImplodeNode
program = programy.parser.template.nodes.program.TemplateProgramNode
lowercase = programy.parser.template.nodes.lowercase.TemplateLowercaseNode
uppercase = programy.parser.template.nodes.uppercase.TemplateUppercaseNode
sentence = programy.parser.template.nodes.sentence.TemplateSentenceNode
formal = programy.parser.template.nodes.formal.TemplateFormalNode
that = programy.parser.template.nodes.that.TemplateThatNode
thatstar = programy.parser.template.nodes.thatstar.TemplateThatStarNode
topicstar = programy.parser.template.nodes.topicstar.TemplateTopicStarNode
star = programy.parser.template.nodes.star.TemplateStarNode
input = programy.parser.template.nodes.input.TemplateInputNode
request = programy.parser.template.nodes.request.TemplateRequestNode
response = programy.parser.template.nodes.response.TemplateResponseNode
date = programy.parser.template.nodes.date.TemplateDateNode
interval = programy.parser.template.nodes.interval.TemplateIntervalNode
system = programy.parser.template.nodes.system.TemplateSystemNode
extension = programy.parser.template.nodes.extension.TemplateExtensionNode
learn = programy.parser.template.nodes.learn.TemplateLearnNode
learnf = programy.parser.template.nodes.learnf.TemplateLearnfNode
first = programy.parser.template.nodes.first.TemplateFirstNode
rest = programy.parser.template.nodes.rest.TemplateRestNode
log = programy.parser.template.nodes.log.TemplateLogNode
oob = programy.parser.template.nodes.oob.TemplateOOBNode
xml = programy.parser.template.nodes.xml.TemplateXMLNode
addtriple = programy.parser.template.nodes.addtriple.TemplateAddTripleNode
deletetriple = programy.parser.template.nodes.deletetriple.TemplateDeleteTripleNode
select = programy.parser.template.nodes.select.TemplateSelectNode
uniq = programy.parser.template.nodes.uniq.TemplateUniqNode
search = programy.parser.template.nodes.search.TemplateSearchNode
新たなtemplate要素を作成する場合、programy.parser.template.nodes.base.TemplateNode を基底クラスとして継承します。
本基底クラスを継承することで、AIMLのXML要素をtemplateクラスのノード属性にカプセル化します。また、template展開中に子要素も含めた結果のテキスト化も行います。

オーバーライドする主要なメソッドには、以下のものがあります。

  • def parse_expression(self, graph, expression)

    xmlの要素を解析して展開します。AIMLパーサの環境が graph で、該当タグのxml要素が expression で引き渡されます。展開できない場合は必要に応じて適切な例外をスローします。

  • def resolve_to_string(self, client_context)

    要素の内容を文字列(応答文)に展開します。後述の resolve() によって呼び出されます。

  • def resolve(self, client_context)

    個々のtemplate要素を文字列に展開するために、brainによって呼び出されます。文字列を作成するために子要素を辿り、下位から順に resolve() を実行して結果文字列を生成(結合)します。

  • def to_string(self)

    デバッグやロギングの出力の為に、要素情報を文字列表現に変換します。

  • def to_xml(self, client_context)

    要素の内容をXML形式に変換します。これは、learnf/learnf の結果としてaimlファイルを作成する際に利用したり、XML形式の Braintree を出力する場合に利用します。

コンフィグレーション

コンフィグレーションファイル

コンフィグレーションファイルは、対話処理を行うための構成・処理方式を決めるパラメータを記述したファイルで、以下の2種類があります。

  • 対話用コンフィグレーションファイル : 対話エンジンの構成・処理方式を指定するファイル。(以降、’コンフィグファイル’と記載します。)
  • ログ出力用コンフィグレーションファイル : 対話エンジンのログ出力の方式を指定するファイル。(以降、’ログコンフィグ’と記載します。)
コンフィグファイルは、対話エンジンの起動時に、–configオプションで、コンフィグファイルのパスを指定します。
ログコンフィグは、対話エンジンの起動時に、–loggingオプションで、ログコンフィグのファイルパスを指定します。
コンフィグファイルで指定できるフォーマットは、.yaml、.json、.xmlのいずれかです。
-–cformatオプションでフォーマットを指定するか、-–configオプションで指定するコンフィグファイルの拡張子からフォーマットが決まります。

起動コマンド例

python3 ../../src/programy/clients/console.py --config ./config.yaml --cformat yaml --logging ./logging.yaml

コマンドラインオプション

起動時に指定するコマンドラインオプションには、以下のものがあります。
このコマンドラインオプションは、全てのclientで同じオプション指定を行うことができます。
  • -–config [コンフィグファイルパス] : client実行時に使用するコンフィグファイルのパスを指定します。
  • -–cformat [yaml|json|xml] : コンフィグファイルのフォーマットを指定します。指定はオプションで行い、未指定の場合、コンフィグファイルの拡張子から自動判別します。
  • -–logging [ログコンフィグパス] : ログコンフィグのファイルパスを指定します。
  • -–noloop : 対話処理ループを実行しないオプションです。コンフィグファイルの読み込み、AIMLの読み込みを行い、対話エンジンを終了します。対話エンジンの起動確認用として利用します。
  • -—subs : 代替え引数設定ファイルを指定します。コンフィグファイル内に記載された代数をsubsで指定した内容に置換します。詳細については、 コマンドラインオプションの置換 を参照してください。

通信系のclientでレスポンス内に付加情報を格納する場合のオプションとして、以下の指定もあります。

  • -—version : 対話エンジンのversion名を指定します。レスポンス内に、{“version”: “version名”} の形式で格納されます。未指定の場合には、レスポンス内への格納は行いません。

コンフィグファイル

コンフィグファイルは、複数のセクションで構成されており、大きく分けて、次の3つのセクションに分類されます。

  • client : アプリケーション層としての構成に関する定義を行うセクションです。
  • bot : 対話要求に対して、対話処理全体の制御を行う層で、発話文の分解や応答時の付加動作等に関する定義を行うセクションです。
  • brain : 発話文毎のマッチ処理やシナリオを実行する層で、要素毎の動作を制御する定義を行うセクションです。
clientのセクションでは、アプリケーション(クライアントアプリ)としての動作環境を定義します。
動作形態には、コンソール起動や、REST通信等の様々なインタフェースがある為、それぞれの動作形態毎に名称(クライアント名)を付与して定義します。
これにより、1つのコンフィグファイルに複数のクライアントアプリ用の構成を定義することができます。
(クライアントアプリ側からクライアント名を指定することで、対応した動作環境が生成されます。)

clientのセクションの共通的な定義として、以下の項目が規定されています。

  • description : clientに関する説明文を指定します。
  • renderer : 対話結果に対する編集等を行う場合の処理クラスを指定します。(対話結果がXML形式の場合の画面描画処理等で利用します。)
  • bot : clientが利用するbot定義の名称を指定しますが、内部処理として’bot’固定で、変更しても無効です。
  • bot_selector : 複数のbotが存在する場合のセレクターの処理クラスを指定しますが、内部処理として指定は無効です。

又、アプリケーションの動作環境に応じた個別の項目も必要に応じて定義します。

コンソールクライアントの個別定義例

console:
    description: Program-Y Console Client
    prompt: ">>>"

REST通信クライアントの個別定義例

yadlan:
    description: Program-Y REST Client
    host: 0.0.0.0
    port: 5100
    debug: false
    workers: 4
    config_key: false
さらに、clientセクションには、対話処理で使用するファイル環境に関する定義を行います。
詳細については、ファイル管理 を参照してください。

botのセクションには、以下のサブセクションがあります。

  • Botコンフィグレーション
    • conversations : 対話履歴に関する項目を定義します。
    • splitter : 発話文の分解に関する項目を定義します。
    • joiner : 応答文生成時の終端文字に関する項目を定義します。
    • spelling : スペルチェックに関する項目を定義します。
    • translation : 翻訳制御に関する項目を定義します。
    • sentiment : 感情判定に関する項目を定義します。

brainのセクションには、以下のサブセクションがあります。

  • Brainコンフィグレーション
    • overrides : 機能拡張に関する項目を定義します。
    • defaults : 取得失敗時等のdefault文字列を定義します。
    • binaries : シナリオのバイナリデータ利用に関する項目を定義します。
    • braintree : シナリオのダンプ出力に関する項目を定義します。
    • services : SubAgent連携機能に関する項目を定義します。
    • nlu : NLU通信に関する項目を定義します。
    • security : 利用制限に関する項目を定義します。
    • oob : OOB(Out of Band)処理に関する項目を定義します。
    • dynamic : 動的データ処理に関する項目を定義します。
    • tokenizer : 単語分解や文字列結合に関する項目を定義します。
    • debugfiles : 異常情報の出力に関する項目を定義します。

ログコンフィグ

ログコンフィグについては、 ログ設定 を参照してください。

コンフィグの置換

ライセンスキーの置換

license.keysの設定値を置換する機能です。
LICENSE_KEY:VALUE をコンフィグの構成アイテムに指定した場合に、license.keysの値が置換します。

設定例

以下のように、コンフィグファイルに LICENSE_KEY:VALUE と記載しておきます。
LICENSE_KEY: は固定値で、 VALUE はlicense.keysに記載するキー名を指定します。
client:
  email:
    username: LICENSE_KEY:EMAIL_USERNAME
    password: LICENSE_KEY:EMAIL_PASSWORD

license.keysに以下のように記載すると、実行時に上記のLICENSE_KEY:VALUEをlicense.keysの内容で置換し動作します。

EMAIL_USERNAME=sample@somewere.com
EMAIL_PASSWORD=qwerty

gitを利用する場合、license.keysを.gitignoreに設定することで意図せず登録してしまうことが防げます。

コマンドラインオプション置換

substitutions.txtファイルをコマンドライン引数にし、対話エンジンを起動すると、起動時の引数として置換するパラメータを指定することが出来ます。
コマンドラインオプション –subs で指定したファイルで置換を行います。

設定例

以下のように、コンフィグファイルに $ +VALUE と記載しておきます。
VALUEはsubstitutions.txtに記載するキー名を指定します。
client:
  email:
    host: $EMAIL_HOST
    port: $EMAIL_PORT

substitutions.txtを以下のように記載すると、実行時に上記の$VALUEをsubstitutions.txtの内容で置換し、動作します。

$EMAIL_HOST:prod_server.com
$EMAIL_PORT:9999

これにより、 --subs substitutions.txt と起動時に置換リストを設定するだけで、configの内容は編集せず実行時に設定内容を変更することができます。

ログ設定

対話エンジンのログ出力は、Pythonのロギング機能を用いて行います。 ログ設定オプションを指定する方法の詳細については、 Pythonロギングドキュメント を参照してください。

以下は、ログコンフィグの指定として、/tmp/y-bot.logにログ出力する設定例です。

version: 1
disable_existing_loggers: False

formatters:
  simple:
    format: '%(asctime)s  %(name)-10s %(levelname)-7s %(message)s'

handlers:
  file:
    class: logging.handlers.RotatingFileHandler
    formatter: simple
    filename: /tmp/y-bot.log

root:
  level: DEBUG
  handlers:
      - file

Bot コンフィグレーション

botコンフィグレーションには共通定義と機能別定義があり、共通定義では、対話エンジンの全体的な動作を制御する複数の項目があり、次の様に分類できます。

また、機能別に、botの文字列処理や、付加機能に関する指定を行う為に、次のサブセクションを使用します。

  • conversations : 対話履歴に関する項目を定義します。
  • splitter : 発話文の分解に関する項目を定義します。
  • joiner : 応答文生成時の終端文字に関する項目を定義します。
  • spelling : スペルチェックに関する項目を定義します。
  • translation : 翻訳制御に関する項目を定義します。
  • sentiment : 感情判定に関する項目を定義します。

コンフィグレーションの記述方法は、yamlフォーマットを例に説明します。 jsonおよびxmlでも記載方法が異なるだけで名称は同じとなるため、jsonおよびxmlを用いる場合は読み替えてください。

設定例

bot:
    version: v1.0
    brain: brain

    default_response: unknown
    default_response_srai: YEMPTY
    exception_response: Exception
    empty_string: YEMPTY

    max_question_recursion: 1000
    max_question_timeout: 60
    max_search_depth: 100
    max_search_timeout: 60
    max_search_condition: 20
    max_search_srai: 50
    max_categories: 20000
    max_properties: 10000

    initial_question: おはよう。
    initial_question_srai: コンバンワ
    exit_response: 終了します。
    exit_response_srai: YEXITRESPONSE

    conversations:
        initial_topic: '*'
        max_histories: 100

    splitter:
        classname: programy.dialog.splitter.splitter_jp.SentenceSplitter
        split_chars: 。

    joiner:
        classname: programy.dialog.joiner.joiner_jp.SentenceJoiner
        join_chars: .?!。?!
        terminator: 。

    spelling:
        classname: programy.spelling.norvig.NorvigSpellingChecker
        alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ
        check_before: false
        check_and_retry: false

    translation:
        classname: programy.translate.textblob_translator.TextBlobTranslator
        from: EN
        to: JP

    sentiment:
        classname: programy.sentiment.textblob_sentiment.TextBlobSentimentAnalyse
        scores: programy.sentiment.scores.SentimentScores

共通定義項目

構成情報定義

botの基本情報を定義します。

設定項目一覧
設定値 内容 初期値
version templateの program 要素で出力するバージョン名。 propertiesに記載する version が、本設定よりも優先して使用されます。 (空文字)
brain botが利用するbrain定義の名称。(’brain’固定で、変更しても無効、) brain
brain_selector 複数のbrainが存在する場合のセレクターの処理クラス。(指定は無効) (なし)
tab_parse_output パターンマッチ時のログ出力で、深度表現用のタブ挿入を制御する指定。 true

応答文定義

応答文生成時のデフォルト処理の内容を定義します。

設定項目一覧
設定値 内容 初期値
default_response_srai マッチするpatternがなかった場合に実行する発話文。発話文に対応するシナリオがある場合に応答文を再生成します。 (空文字)
default_response マッチするpatternがなかった場合に返す応答文。default_response_sraiに対応するシナリオが記載されていない場合にも返します。propertiesに記載する default-response が、本設定よりも優先して使用されます。 (空文字)
exception_response 処理例外が発生した場合に返す応答文。propertiesに記載する exception-response が、本設定よりも優先して使用されます。 (空文字)
empty_string pre_processorの処理結果が無い場合に設定する発話文。pre_processorの処理結果が無い場合、設定値を発話文としてシナリオが動作し応答文を生成します。 (空文字)

制限値定義

対話処理における、時間・数量に関する制限値を定義します。

設定項目一覧
設定値 内容 初期値
max_question_recursion 文探索最大回数。長文が入力され、分割文字で分割し、内部的に複数回対話シナリオを実行した場合の最大探索回数を指定します。最大回数に達すると exception-response を返します。 100
max_question_timeout 文探索最大時間。長文が入力され、分割文字で分割し、内部的に複数回対話シナリオを実行した場合の最大処理時間を秒単位で指定します。最大処理時間を超過すると exception_response を返します。 -1(制限なし)
max_search_timeout 単語探索最大時間を秒単位で指定します。文探索中に長いpatternが記載されていた場合など、文探索中の単語探索での最大探索時間を秒単位で指定します。最大処理時間を超過すると exception-response を返します。 -1(制限なし)
max_search_depth 単語探索分岐最大数。 ワイルドカードset 等の指定で単語の探索が膨大になった場合の単語の探索最大深度を指定します。単語の探索回数が最大深度を超過すると exception-response を返します。 100
max_search_condition condition要素でのloop の最大回数。conditionのloop記載時にconditionの条件にマッチしなかった場合無限ループになるため、ループの最大回数を指定します。ループが最大回数を超過すると exception-response を返します。 100
max_search_srai srai の最大探索回数。sraiの記述が再帰呼び出しになった場合の再帰呼び出しの最大回数を指定します。最大回数を超過すると exception-response の設定値を返します。 50
max_categories 最大読み込みcategory数。AIMLの最大読み込みcategory数を指定します。AIMLで記載したcategoryが上限を越えると読み込みを行いません。読み込みを行わなかったcategoryは、 errors のdescriptionに Max categories [n] exceeded として出力されます。 5000
max_properties 利用可能なグローバル変数の最大数。name型・data型の変数の最大利用数を指定します。該当変数の数が上限を越えると新たな変数を登録することはできず、 exception-response を返します。 2500

起動終了文定義

コンソール等での処理の場合の、bot起動・終了時の応答文に関する内容を定義します。

設定項目一覧
設定値 内容 初期値
initial_question_srai 起動時発話文。client起動時に処理する発話文。発話文に対応するシナリオがある場合に応答文が生成されます。 (空文字)
initial_question 起動時応答文。initial_question_sraiに対応するシナリオが記載されていない場合に返す応答文を指定します。 Hello
exit_response_srai 終了時発話文。client終了時に処理する発話文。発話文に対応するシナリオがある場合に応答文が生成されます。 (空文字)
exit_response 終了時応答文。exit_response_sraiに対応するシナリオが記載されていない場合にも返します。 Bye!

conversations

対話履歴の管理に関する制御項目を定義します。

設定項目一覧
設定値 内容 初期値
initial_topic 対話履歴の初回生成時に設定するTopicの初期値。 *
max_histories 対話履歴の最大保持数。 100

splitter

入力された発話文を複数文に分割するための定義を行います。

設定項目一覧
設定値 内容 初期値
classname 利用するSplitterの処理クラス。 programy.dialog.splitter.regex.RegexSentenceSplitter
split_chars propertiesに記載する splitter_split_chars が、本設定よりも優先して使用されます。発話文の分割に使用する文字群。 [:;,.?!]

日本語での対話を行う場合には、classname に、’programy.dialog.splitter.splitter_jp.SentenceSplitter’ を指定します。

joiner

最終的な応答文を生成する際に、複数文を結合させるための定義を行います。

設定項目一覧
設定値 内容 初期値
classname 利用するJoinerの処理クラス。 programy.dialog.joiner.joiner.SentenceJoiner
terminator 応答文の末尾に付加する文字。propertiesに記載する joiner_terminator が、本設定よりも優先して使用されます。 .
join_chars terminaterの付加を抑止する、応答文の末尾文字群。propertiesに記載する joiner_join_chars が、本設定よりも優先して使用されます。 .?!

日本語での対話を行う場合には、classname に、’programy.dialog.joiner.joiner_jp.SentenceJoiner’ を指定します。

spelling

スペルチェックを行う場合の定義を行います。

設定項目一覧
設定値 内容 初期値
classname 利用するスペルチェッカーの処理クラス。 (なし)
alphabet 対象となるアルファベット文字群。 (空文字)
check_before 事前チェックの実施指定。 false
check_and_retry チェック異常時の再処理指定 false

translation

応答文を翻訳して返す場合の定義を行います。

設定項目一覧
設定値 内容 初期値
classname 利用するTranslatorの処理クラス。 (なし)
from 翻訳の対象となる言語種別。ISO-639 言語コードで指定します。 (空文字)
to 翻訳後の言語種別。ISO-639 言語コードで指定します (空文字)

sentiment

感情を判定する場合の定義を行います。(本機能は、使用していません)

設定項目一覧
設定値 内容 初期値
classname 感情判定を行う処理クラス。 (なし)
scores 感情を数値化する処理クラス。 (なし)

Brain コンフィグレーション

brainのコンフィグレーションでは、brainが行う対話処理に関する設定や、各要素に依存する個別設定等を行います。
機能別に定義を行う為に、次のサブセクションで構成します。
  • overrides : 機能拡張に関する項目を定義します。
  • defaults : 取得失敗時等のdefault文字列を定義します。
  • binaries : シナリオのバイナリデータ利用に関する項目を定義します。
  • braintree : シナリオのダンプ出力に関する項目を定義します。
  • services : SubAgent連携機能に関する項目を定義します。
  • nlu : NLU通信に関する項目を定義します。
  • security : 利用制限に関する項目を定義します。
  • oob : OOB(Out of Band)処理に関する項目を定義します。
  • dynamic : 動的データ処理に関する項目を定義します。
  • tokenizer : 単語分解や文字列結合に関する項目を定義します。
  • debugfiles : 異常情報の出力に関する項目を定義します。

コンフィグレーションの記述方法は、yamlフォーマットを例に説明します。 jsonおよびxmlでも記載方法が異なるだけで名称は同じとなるため、jsonおよびxmlを用いる場合は読み替えてください。

設定例

brain:

   overrides:
     allow_system_aiml: true

   defaults:
     default-get: unknown
     default-property: unknown
     default-map: unknown

   binaries:
     save_binary: true
     load_binary: true
     load_aiml_on_binary_fail: true

   braintree:
     create: true

   services:
     REST:
         classname: programy.services.rest.GenericRESTService
         method: GET
         host: 0.0.0.0
     __PublishedREST__:
         classname: programy.services.publishedrest.PublishedRestService
     __PublishedBot__:
         classname: programy.services.publishedbot.PublishedBotService

   nlu:
       classname: programy.services.rest.GenericRESTService
       url: http://localhost:3000/run
       apikey: test_key
       use_file: false
       max_utterance_length: 300

   security:
       authorisation:
         classname: programy.security.authorise.usergroupsauthorisor.BasicUserGroupAuthorisationService
         denied_srai: AUTHORISATION_FAILED
         denied_text: parmission error

   oob:
     default:
       classname: programy.oob.defaults.default.DefaultOutOfBandProcessor
     alarm:
       classname: programy.oob.defaults.alarm.AlarmOutOfBandProcessor
     camera:
       classname: programy.oob.defaults.camera.CameraOutOfBandProcessor
     clear:
       classname: programy.oob.defaults.clear.ClearOutOfBandProcessor
     dial:
       classname: programy.oob.defaults.dial.DialOutOfBandProcessor
     dialog:
       classname: programy.oob.defaults.dialog.DialogOutOfBandProcessor
     email:
       classname: programy.oob.defaults.email.EmailOutOfBandProcessor
     geomap:
       classname: programy.oob.defaults.map.MapOutOfBandProcessor
     schedule:
       classname: programy.oob.defaults.schedule.ScheduleOutOfBandProcessor
     search:
       classname: programy.oob.defaults.search.SearchOutOfBandProcessor
     sms:
       classname: programy.oob.defaults.sms.SMSOutOfBandProcessor
     url:
       classname: programy.oob.defaults.url.URLOutOfBandProcessor
     wifi:
       classname: programy.oob.defaults.wifi.WifiOutOfBandProcessor

   dynamic:
       sets:
           numeric: programy.dynamic.sets.numeric.IsNumeric
           roman:   programy.dynamic.sets.roman.IsRomanNumeral
       maps:
           romantodec: programy.dynamic.maps.roman.MapRomanToDecimal
           dectoroman: programy.dynamic.maps.roman.MapDecimalToRoman
       variables:
           gettime: programy.dynamic.variables.datetime.GetTime

   tokenizer:
     classname: programy.dialog.tokenizer.tokenizer_jp.TokenizerJP
     punctuation_chars: ;'",!()[]:’”;、。!()「」
     before_concatenation_rule: '.*[ -~]'
     after_concatenation_rule: '[ -~].*'

   debugfiles:
     save-errors: true
     save-duplicates: true
     save-errors_collection: true

overrides

機能毎の処理制限等を制御する定義を行います。

設定項目一覧
設定値 内容 初期値
allow_system_aiml templateの system 要素でのシステムコマンド(OS依存)の実行可否。 false

defaults

取得処理を行う要素での取得失敗時の設定文字列を定義します。

設定項目一覧
設定値 内容 初期値
default-get 未定義変数に対し、 get 要素等でデータ取得を行なった場合に設定される文字列。propertiesに記載する default-get が、本設定よりも優先して使用されます。 unknown
default-property bot 要素で未定義の変数名を指定した場合に設定される文字列。propertiesに記載する default-property が、本設定よりも優先して使用されます。 unknown
default-map map 要素で変換対象の文字列がなかった場合に設定される文字列。propertiesに記載する default-map が、本設定よりも優先して使用されます。 unknown

default-get の設定値は、json や、RDFの検索 select 等の要素での取得失敗時に設定されるとともに、default-propertydefault-map が未定義の場合の値としても使用されます。

binaries

シナリオを展開したバイナリデータの利用に関する定義を行います。

設定項目一覧
設定値 内容 初期値
load_binary Bot起動時のバイナリデータ読み込みの実施。 false
save_binary シナリオ展開時のバイナリデータ保存の実施。 false
load_aiml_on_binary_fail バイナリデータ読み込み失敗時のシナリオ再展開の実施。’false’の場合、起動時の処理例外発生により終了します。 false

braintree

シナリオの展開結果のダンプ出力に関する定義を行います。

設定項目一覧
設定値 内容 初期値
create シナリオの展開結果のファイル生成を実施。 false

services

外部サービスと連携する為に、SubAgent連携機能で使用する処理クラスや、URLの定義を、サービス名を単位として定義します。

以下は、サービス名毎に設定可能な項目ですが、使用される項目は処理クラスに依存します。(サービス名毎の処理クラスの指定は必須です。) サービス毎の処理クラスの作成については、カスタム外部サービス実装 を参照してください。

設定項目一覧
設定値 内容 初期値
classname 外部サービスと通信する処理クラス。 (なし)
url 外部サービスの接続URL。 (なし)
host 外部サービスを提供するサーバのhost名、または、IPアドレス。 (なし)
port 外部サービスを提供するサーバのport番号。 (なし)
method HTTP通信のmethod名。 (なし)
denied_srai 通信に失敗した場合に実行する発話文。シナリオ中に該当する発話文がない場合は空文字が返ります。 (なし)

設定例にある次のサービス定義は、SubAgent機能を提供するための定義であり、常に指定が必要です。

nlu

マッチ処理に使用するNLUサーバに関する定義を行います。
NLUサーバの接続先情報として有効な定義がない場合には、NLUを利用したマッチ処理は行いません。
NLUに関する詳細は、NLU を参照してください。
設定項目一覧
設定値 内容 初期値
classname NLUサーバと通信する処理クラス。 programy.nlu.nlu.NluRequest
url NLUサーバの接続URL。 http://localhost:3000/run
apikey NLUサーバとの通信時に付加するapi-key。HTTPヘッダ:’x-api-key’で送信します。 (空文字)
timeout NLUサーバ毎の通信時間の最大値(秒単位)を共通値として指定。最大値の時間を超えた場合、該当サーバとの通信は失敗したものとして扱います。 10
use_file NLUサーバの接続定義に nlu_serversファイル を利用する指定。 false
max_utterance_length NLUサーバに送信する発話文の最大長。制限長を超える発話文が指定された場合には、通信を行いません。 -1(制限なし)
classname には、’programy.nlu.cotobadesignNlu.CotobadesignNlu’ を指定します。
本処理クラスは、sraix要素で直接NLUからの結果を取得する NLU通信 処理でも利用します。

尚、複数のNLUサーバを利用する場合には、use_file: true を指定して、nlu_serversファイルで定義を行ってください。

security

ユーザ毎でのシナリオの利用制限等の定義を行います。
securityの制御には、次の3つの種類があります。
  • authentication: brain処理での利用制限を行います。(使用していません。)
  • account_linker: 外部サービスを連携して利用制限を行います。(使用していません。)
  • authorisation: templateの authorize 要素で利用を制限します。

従って、authorisation のみの定義が有効です。詳細については、Security を参照してください。

設定項目一覧
設定値 内容 初期値
classname 利用制限制御を行う処理クラス。 (なし)
denied_srai 認証に失敗した場合に実行する発話文。発話文に対応するシナリオがある場合に応答文を再生成します。該当するシナリオが無い場合は空文字になります。 (なし)
denied_txt 認証に失敗した場合に返す文字列。 (なし)

denied_sraidenied_txt の両方が指定されている場合、 denied_sraiの結果が空文字の場合に、denied_txtの文字列が使用されます。

oob

OOBの設定 を参照してください。

dynamic

データの取得・変換を値を定義する形式ではなく、処理クラスを利用して行う場合の定義を行います。
dynamicが利用できる項目には、次の3つの種類があります。
  • sets: patternの set 要素に対するマッチ処理を指定された処理クラスで実施します。
  • maps: templateの map 要素に対する変換処理を指定された処理クラスで実施します。
  • variables: グローバル変数(name)の get に対して処理クラスの結果を返します。

それぞれで、次の定義を行います。

設定項目一覧
設定値 内容 初期値
エントリ名 エントリ名に該当する要素の処理クラス。 (なし)

設定例にある各処理クラスでは、以下の処理を行います。

設定項目一覧
種類 エントリ名 処理クラス 処理内容
sets numeric programy.dynamic.sets.numeric.IsNumeric set要素のマッチ処理で該当文字列が数値の場合にマッチします。
  roman programy.dynamic.sets.roman.IsRomanNumeral ”setのマッチ処理で該当文字列が英数字の場合にマッチします。”
maps romantodec programy.dynamic.maps.roman.MapRomanToDecimal ”mapの処理として、アラビア数字表記をローマ数字表記に変換します。”
  dectoroman programy.dynamic.maps.roman.MapDecimalToRoman mapの処理として、ローマ数字表記をアラビア数字表記に変換します。
variables gettime programy.dynamic.variables.datetime.GetTime name変数のgetに対して、現在日時の情報を返します。

尚、これらの定義が有効な場合、各要素の処理として優先されるため、ファイル定義:’sets’, ‘maps’, ‘defaults’ での同一名称の指定は無効になります。

tokenizer

発話文の単語分解や、応答文生成時に行う文字列結合(templateの要素単位に実施)に使用するクラスに関する定義を行います。

設定項目一覧
設定値 内容 初期値
classname 利用するTokenizerの処理クラス。 programy.dialog.tokenizer.tokenizer.Tokenizer
punctuation_chars 区切り文字扱いを行う文字を指定します。区切り文字はマッチング対象外として、発話文や、topic・thatの対象文から除外してマッチング処理を行います。propertiesに記載する punctuation_chars が、本設定よりも優先して使用されます。 ”(なし)”
before_concatenation_rule 応答文生成等で、生成された複数の文字列を連結する時点で空白を挿入する場合の前文字列の形式を正規表現で指定します。propertiesに記載する before_concatenation_rule が、本設定よりも優先して使用されます。 .*[ -~]
after_concatenation_rule 応答文生成等で、生成された複数の文字列を連結する時点で空白を挿入する場合の後文字列の形式を正規表現で指定します。propertiesに記載する after_concatenation_rule が、本設定よりも優先して使用されます。 [ -~].*
日本語での対話を行う場合には、classname に、’programy.dialog.tokenizer.tokenizer_jp.TokenizerJP’ を指定します。
before_concatenation_rule , after_concatenation_rule は、日本語用の設定項目です。

debugfiles

シナリオや設定ファイルの展開における異常情報の出力に関する定義を行います。

設定項目一覧
設定値 内容 初期値
save-errors シナリオ展開時の異常記述や、整合性の不正に関する情報の出力指定。’true’の場合 errosエンティティ に対する出力処理が行われます。 false
save-duplicates シナリオ展開時の定義重複情報の出力指定。’true’の場合 duplicatesエンティティ に対する出力処理が行われます。 false
save-errors_collection 各種設定ファイルの異常に関する情報の出力指定。’true’の場合 erros_collectionエンティティ に対する出力処理が行われます。。 false

OOBの設定

OOB(Out of Band)処理には、使用するOOBの機能毎にPythonクラスが必要です。 このクラスはAIMLのoob要素で引き渡された文字列を引数として処理し、クライアント側で該当するシステムコマンドを実行します。

以下は、対話エンジンが保持する実装クラスの例です。実行関数内は引数チェックを行なっているだけで具体的な動作は実施していません。 実際に利用する場合は、個々のシステムに応じた実装が必要です。

oob:
  default:
    classname: programy.oob.defaults.default.DefaultOutOfBandProcessor
  alarm:
    classname: programy.oob.defaults.alarm.AlarmOutOfBandProcessor
  camera:
    classname: programy.oob.defaults.camera.CameraOutOfBandProcessor
  clear:
    classname: programy.oob.defaults.clear.ClearOutOfBandProcessor
  dial:
    classname: programy.oob.defaults.dial.DialOutOfBandProcessor
  dialog:
    classname: programy.oob.defaults.dialog.DialogOutOfBandProcessor
  email:
    classname: programy.oob.defaults.email.EmailOutOfBandProcessor
  geomap:
    classname: programy.oob.defaults.map.MapOutOfBandProcessor
  schedule:
    classname: programy.oob.defaults.schedule.ScheduleOutOfBandProcessor
  search:
    classname: programy.oob.defaults.search.SearchOutOfBandProcessor
  sms:
    classname: programy.oob.defaults.sms.SMSOutOfBandProcessor
  url:
    classname: programy.oob.defaults.url.URLOutOfBandProcessor
  wifi:
    classname: programy.oob.defaults.wifi.WifiOutOfBandProcessor
パラメータ 説明 デフォルト
classname OOB実装のフルPythonクラスパス programy.oob.defaults.alarm.AlarmOutOfBandProcessor None

OOBの処理方法は、OOB を参照してください。