5. Amazon Alexa에서 대화 계속하기(세션 인계)

연재 기사



전후 관계가 있기 때문에 차례로 읽을 수 있으면 알기 쉬워지고 있습니다.

1. Amazon Alexa와 Fire TV에서 Hello World를 사용해보십시오 - Qiita
2. Amazon Alexa에서 음성에서 인수 받기 - Qiita
3. Amazon Alexa의 Custom Slot Types 설정 - Qiita
4. Amazon Alexa에서 Heroku의 Rails로 연결 - Qiita
5. Amazon Alexa에서 대화 계속하기 (세션 인계) - Qiita
6. Amazon Alexa 기술을 일본어로 만들기 - Qiita
7. 자작한 일본어의 Alexa Skill을 Echo dot로 움직이기 - Qiita

소개



전회까지의 대화에서는 「발화 => 대답」만의 1왕복의 교환이었습니다.
이번에는 "발화 => 대답 => 발화 => 대답"과 대화의 캐치볼을 해 보겠습니다.

대화의 이미지는 다음과 같이 합니다.
(1回目)僕:「Alexa Tell hello world hello my name is Bob.」
(1回目)Alexa:「Hello world! Bob. How are you?」
(2回目)僕:「That's good!」
(2回目)Alexa「That's good, Bob」

대화의 문법적인 것은 신경 쓰지 않고 적절하게 만들었습니다.
전회의 인수를 받는 Hello world를 발전시켜 만들어 보겠습니다.

Amazon Alexa에서 음성에서 인수 받기 - Qiita

인수를 세션에 넣고 인수



주목할만한 점은 첫 번째 발화에서 "Bob"이라는 이름을 말합니다.
그 이름을 두 번째 Alexa가 기억하고 대답합니다.

이것은 첫 번째 이름을 세션에 넣고 인계함으로써 실현할 수 있습니다.

코드는 이전에 Rails에서 만든 것을 기반으로 진행합니다.

Amazon Alexa에서 Heroku의 Rails로 연결 - Qiita

Alexa의 응답에는 "sessionAttributes"라는 항목이 있습니다.
여기에 키 밸류로 값을 넣어 두는 것으로 다음의 세션까지 값을 인계할 수 있게 됩니다.

Slots에서 받은 이름을 response.add_session_attributefirst_name 라는 Key로 저장합니다.

#controllers/tasks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    response.add_session_attribute :first_name, request.slots[:firstName][:value]
    ...
  end
end

위의 코드에서 생성되는 응답은 다음과 같습니다.
{
  ...
  "sessionAttributes": {
    "first_name": "bob"
  }
}

이제 다음 요청에서 다음과 같이 세션에서 이름을 검색할 수 있습니다.
request = AlexaRubykit::build_request(params)
first_name = request.session.attributes[:first_name]

첫 번째, 두 번째 발화를 인텐트 이름으로 분기



Alexa의 답변을 첫 번째와 두 번째로 변경해야합니다.
거기서 인텐트를 2종류 준비하고 인텐트명으로 분기합니다.
마지막으로 만든 HelloWorldIntent 아래에 HowAreYouIntent를 추가합니다.
{
  "intents": [
    {
      "intent": "AMAZON.CancelIntent"
    },
    {
      "intent": "AMAZON.HelpIntent"
    },
    {
      "intent": "AMAZON.StopIntent"
    },
    {
      "slots": [
        {
          "name": "firstName",
          "type": "JP_FIRST_NAME"
        }
      ],
      "intent": "HelloWorldIntent"
    },
    {
      "intent": "HowAreYouIntent"
    }
  ]
}

Utterances에도 HowAreYouIntent를 추가합니다.
HelloWorldIntent hello my name is {firstName}
HowAreYouIntent that's good

추가하면 아래와 같이 되어 있다고 생각합니다.



그런 다음 요청한 인텐트 이름으로 분기합니다.request.name 로 인텐트명을 취득할 수 있으므로 이것을 사용해 응답을 분기합니다.

#controllera/talks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    case request.name
      when 'HelloWorldIntent'
        ...
      when 'HowAreYouIntent'
        ...
    end
    render json: response.build_response
  end
end


Alexa를 발화를 받는 대기 상태로 설정



첫 번째 응답 후 Alexa를 대기 상태로 만듭니다.
거기서 응답으로 돌려준다 shouldEndSessionfalse 로 합니다.
이렇게 하면 Alexa가 응답한 후 다음 발화를 받을 수 있는 대기 상태가 됩니다.
Rails 코드는 다음과 같습니다.

#controllers/talks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    session_end = true
    case request.name
      when 'HelloWorldIntent'
        ...
        session_end = false
      when 'HowAreYouIntent'
    end
    render json: response.build_response(session_end)
  end
end

첫 번째 응답은 다음과 같습니다.
{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "text": "Hello world! bob. How are you?",
      "type": "PlainText"
    },
    "speechletResponse": {
      "outputSpeech": {
        "text": "Hello world! bob. How are you?"
      },
      "shouldEndSession": false
    }
  },
  "sessionAttributes": {
    "first_name": "bob"
  }
}

결과



이제 대화의 캐치볼을 할 수 있게 되었습니다.
지금까지의 내용을 반영한 최종적인 Rails측의 코드는 아래와 같이 됩니다.

#controllers/talks_controller.rb
class TalksController < ApplicationController
  protect_from_forgery with: :null_session

  def create
    request = AlexaRubykit::build_request(params)
    response = AlexaRubykit::Response.new
    session_end = true

    case request.name
      when 'HelloWorldIntent'
        first_name = request.slots[:firstName][:value]
        response.add_speech("Hello world! #{first_name}. How are you?")
        response.add_session_attribute :first_name, first_name
        session_end = false
      when 'HowAreYouIntent'
        first_name = request.session.attributes[:first_name]
        response.add_speech("That's good, #{first_name}.")
    end
    render json: response.build_response(session_end)
  end
end


Amazon Alexa에서 세션과 함께 대화의 캐치볼을 해 보았다. htps // t. 코 / 5에 H9fS · lv1 — tochi (@aguuu) 2017년 10월 31일


요약



이번 세션을 사용하면 대화를 여러 번 계속할 수 있습니다.

또, 인텐트의 분기를 사용하는 것으로, 보다 복잡한 처리를 실시하는 것도 가능하게 되었습니다.



이번 세션에 대한 정보 보존은 어디까지나 일시적인 데이터 보존으로 이용하는 이미지입니다.

보다 실용적인 서비스를 만들면, 사용자 정보를 보존하기 위해서는 Alexa의 단말 ID나 계정 ID를 사용하여 DB에 영속화할 것이라고 생각합니다.



Let's enjoy Alexa!


좋은 웹페이지 즐겨찾기