LoginSignup
9
7

More than 5 years have passed since last update.

My Alexa の知見5 ASK(Alexa Skills kit) Intent と Slots と Utterance

Last updated at Posted at 2017-02-22
1 / 16

はじめに

この投稿は私がラズパイで自作Alexaを開発した知見を投稿するシリーズです。


今回のテーマ

今回のテーマはASKで避けては通れない Intent, Slots, Utterance について、少し突っ込んだお話です。


前提

ASKについてざっくりと理解している。(出てくるワードがざっくりどういうものか理解できる程度です)


超概要

スキルの種類

スクリーンショット 2017-02-22 9.16.17.png

Custom Skill

今回のテーマです。ユーザーの意図(Intent)とキーワード(Slots)を定義して作るスキルです。

Smart Home Skill

デバイスに対してリクエストを送るためのスキルです。(「電気つけて」など)

Flash Briefing Skill API

ユーザーのキーワードにあったニュースや記事を読み上げるスキルです。

他にも有益な記事がたくさんありますので、参考にしてください。

Alexa Skills Kit の勘所
Alexa Skill を公開する流れ
Smart Home Skillsを使ってみる
Amazon AlexaにJAWS-UGのイベントを教えてもらう


Intent

ユーザーの発話に対する意図を定義します。以下のようなjsonです。

スクリーンショット 2017-02-22 9.14.34.png

{
  "intents": [
    {
      "intent": "AppointmentIntent"
    },
    {
      "intent": "NotifyIntent"
    },
    {
      "intent": "DestinationIntent",
      "slots":[
        {
          "name":"Event",
          "type":"AMAZON.EventType"
        },
        {
          "name":"CustomEvent",
          "type":"CUSTOM_EVENTS"
        },
        {
          "name":"City",
          "type":"AMAZON.US_CITY"
        },
        {
          "name":"Date",
          "type":"AMAZON.DATE"
        },
        {
          "name":"Duration",
          "type":"AMAZON.DURATION"
        }
      ]
    },
    {
      "intent": "NotifyCancelIntent"
    },
    {
      "intent": "TurnLightsIntent"
    },
    {
      "intent": "AMAZON.YesIntent"
    },
    {
      "intent": "AMAZON.NoIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    }
  ]
}

Slots

Intent に対して、期待するワード(キーワードとして採取したいワード)を定義します。developer.amazon.comのAlexa Skill のGUIで定義します。

スクリーンショット 2017-02-22 9.30.35.png


Utterance

各Intentに対して、ユーザーの発話パターンを記載します。

スクリーンショット 2017-02-22 9.15.37.png

AppointmentIntent Can I get the appointment some hotel?
AppointmentIntent I want to get the appointment hotel.
AppointmentIntent book any hotel
AppointmentIntent book pleese

NotifyIntent notify
NotifyIntent notify please
NotifyIntent inform
NotifyIntent inform please
NotifyIntent please inform

NotifyCancelIntent cancel notification
NotifyCancelIntent cancel notification please
NotifyCancelIntent please cancel notification
NotifyCancelIntent cancel informing
NotifyCancelIntent cancel informing please
NotifyCancelIntent please cancel informing

DestinationIntent I have a {Event} on {Date} for {Duration}
DestinationIntent I have a {CustomEvent} on {Date} for {Duration}
DestinationIntent I have a {Event} on {Date} for a {Duration}
DestinationIntent I have a {CustomEvent} on {Date} for a {Duration}
DestinationIntent I will go to {City} for {Event} for {Duration}
DestinationIntent I will go to {City} for {CustomEvent} for {Duration}
DestinationIntent I will go to {City} for {Event} for a {Duration}
DestinationIntent Yes I will go to {City} for {Event} for a {Duration}
DestinationIntent I will go to {City} on {Date} for a {Duration}
DestinationIntent Yes I will go to {City} on {Date} for a {Duration}
DestinationIntent I will go to {City}
DestinationIntent I will go to {City} for {Duration}
DestinationIntent for {Event} I will go to {City} on {Date}
DestinationIntent for {CustomEvent} I will go to {City} on {Date}

TurnLightsIntent turn off please
TurnLightsIntent please turn off
TurnLightsIntent turn off
TurnLightsIntent turn off
TurnLightsIntent turn off the light please
TurnLightsIntent please turn off the light
TurnLightsIntent turn off the light
TurnLightsIntent set off to the light

AMAZON.StopIntent good bye
AMAZON.StopIntent bye bye
AMAZON.StopIntent bye
AMAZON.StopIntent thank you bye
AMAZON.StopIntent okay good bye
AMAZON.StopIntent okay bye


ポイント4つ

  • Built in Intentを拡張する
  • Built in Slotsを拡張する
  • AMAZON.DATE, AMAZON.DURATIONの活用
  • AMAZON.YesIntent, AMAZON.NoIntent, AMAZON.StopIntent

Built in Intentを拡張

ASK では、一般的な意図を採取するための Built in Intentが定義できます。

Built in Intent

このBuilt in Intent は、Utteranceで拡張できます。

Extending Built in Intents

AMAZON.StopIntentを拡張する例

スクリーンショット 2017-02-22 15.36.46.png

特定の言葉で特定のIntentに入って欲しい時は、Built in Intentsの拡張を検討します。


Built in Slotsを拡張する

Built In Intents 同様 Slotsにも Built in されたものがあり、こちらも拡張できます。
ただし、Built in Slots には、拡張できるものとできないものがあります。

拡張可能なスロットタイプ

Slot Type Reference

AMAZON.EUROPE_CITYを拡張する例

スクリーンショット 2017-02-22 15.42.43.png


AMAZON.DATE と AMAZON.DURATION Slot Type.

AMAZON.DATE と AMAZON.DURATION を利用して、ユーザーの旅行への出発日、滞在期間、目的地、目的を採取するフレーズを考えます。

英語だと以下のようになるでしょう。

I will go to Washington.D.C for business trip on this weekend for 6 days.

このときの Intent はこのようになります。

DestinationIntent I will go to {City} for {Event} on {Date} for {Duration}

それぞれのスロットの意味です。

  • {City} に目的地
  • {Event} に目的
  • {Date}に出発日
  • {Duration}に滞在期間

IntentSchema に、どのスロットにどんなワードが入ってほしいかを定義します。

:
    {
      "intent": "DestinationIntent",
      "slots":[
        {
          "name":"Event",
          "type":"AMAZON.EventType"
        },
        {
          "name":"CustomEvent",
          "type":"CUSTOM_EVENTS"
        },
        {
          "name":"City",
          "type":"AMAZON.US_CITY"
        },
        {
          "name":"Date",
          "type":"AMAZON.DATE"
        },
        {
          "name":"Duration",
          "type":"AMAZON.DURATION"
        }
      ]
    },
:

AMAZON.DATE

AMAZON.DATE は、検知した日付をISO-8601 date format. の形に変換してスキルに伝えます。

例文の "this weekend" は "2015-W48-WE" という形でスキル側に伝えられます。
2015年 第48週目の週末 という意味です。

例えば、こんな会話のパターンがあったとします。

ユーザー: "I will go to Washington.D.C for business trip on this weekend for 6 days."

Alexa : "OK. I have scheduled and register to your calendar. on 2017.02.22. for 6 days. you will go to Washington.D.C for business trip."

このとき、スキル側でやることは2つ。

  1. 2017-W48-WE"を再変換して、発話の形に修正する。
    2017-W48-WE ー> 2017-12-01

  2. SSML で 日付を話させる。
    "2017-12-01."

Alexa は、December.1, 2017 と話してくれます。

余談
1.の変換にpythonが持つ日付のライブラリが対応してないので、自前で頑張しかありません。
(よい方法をおしえてください。)

AMAZON.DATE


AMAZON.DURATION

さきほどのAMAZON.DATEの例で、"for 6 days"と alexaが応答することを考えます。

AMAZON.DURATION は、検知した日付をISO-8601 date format. の形に変換してスキルに伝えます。

例文の "for 6 days" は "P6D" という形でスキル側に伝えられます。
*P は接頭辞。6D が6日間という意味です。 *

こちらも、AMAZON.DATEと同様に、変換して話させます。

  1. 2017-W48-WE"を再変換して、発話の形に修正する。
    P6D ー> for 6 days

  2. 日付を話させる。
    今の場合は、for 6 days とそのまま発話させることができるので、SSMLでなくてもかまいません。

AMAZON.DURATION


AMAZON.YesIntent, AMAZON.NoIntent, AMAZON.StopIntent

こちらも、こんな会話設計を考えます。

user : Ask booking
alexa : Hi. where you go?
user : Boston.
alexa : OK. There are many hotels in Boston. Would you select highest one?
user : Yes, please.
alexa : OK. Are you pay now?
user : Yes, please.

ここで、5行目と7行目の "Yes, please" は意味が異なります。

5行目の意図: 「一番高いホテルを選ぶよ」
7行目の意図: 「今ホテル代支払っとくよ」

この場合、スキル側では、以下のようにIntentを作ります。

:
    {
      "intent": "SearchHotelIntent",
      "slots":[
        {
          "name":"City",
          "type":"AMAZON.US_CITY"
        }
      ]
    },
    {
      "intent": "PayNowIntent"
    },
    {
      "intent": "AMAZON.YesIntent"
    },

:

Built in intentには、Yes, No, No thanks, のような発話に反応する AMAZON.YesIntent があります。
ユーザーの "Yes,Please"は YesIntent として、Alexaに伝わります。


session_attributes変数に今何を期待している状態かを保持する。

ユーザーがalexaのスキルに入ると、スキルから抜ける間は、session_attributesに値を保持できます。
このsession_attributesに会話の状況を保持して、YesIntentがどのIntentのYesかを判断します。

コード例を示します。

:
def search_hotel(intent, session):
    session_attributes = session.get('attributes', {})
    session_attributes["state"] = "SearchHotelIntent"
      :
    return build_response(session_attributes, build_speechlet_response(
            intent['name'], speech_output, reprompt_text, should_end_session))


def pay_now(intent, session):
    session_attributes = session.get('attributes', {})
    session_attributes["state"] = "PayNowIntent"
      :
    return build_response(session_attributes, build_speechlet_response(
            intent['name'], speech_output, reprompt_text, should_end_session))


def yes(intent, session):
    card_title = intent['name']
    session_attributes = session.get('attributes', {})
    speech_output = ""
    reprompt_text = ""
    should_end_session = False
    if session_attributes.has_key('state'):
        if attributes['state'] == 'SearchHotelIntent':
            return search_hotel(intent, session)
        elif attributes['state'] == 'PayNowIntent':
            return pay_now(intent, session)

    return build_response(session_attributes, build_speechlet_response(
            intent['name'], speech_output, reprompt_text, should_end_session))


def on_intent(intent_request, session):
    print("on_intent requestId=" + intent_request['requestId'] +
          ", sessionId=" + session['sessionId'])

    intent = intent_request['intent']
    intent_name = intent_request['intent']['name']
    print(intent_name)

    # Dispatch to your skill's intent handlers
    if intent_name == "SearchHotelIntent":
        return search_hotel(intent, session)
    elif intent_name == "PayNowIntent":
        return pay_now(intent, session)
    elif intent_name == "AMAZON.YesIntent":
        return yes(intent, session)
    elif intent_name == "AMAZON.CancelIntent" or intent_name == "AMAZON.StopIntent":
        return handle_session_end_request()
    else:
        raise ValueError("Invalid intent")
:
9
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7