😊

AlexaにGPT-3.5を接続して、回答を比べた。

2022/12/10に公開

実演

AlexaとChatGPTそれぞれに鬼滅の刃が人気の理由を聞きました。1/2 #Alexa #ChatGPT
https://twitter.com/allforbigfire/status/1601574769547042816

AlexaとChatGPTそれぞれに鬼滅の刃が人気の理由を聞きました。2/2 #Alexa #ChatGPT
https://twitter.com/allforbigfire/status/1601575213518315520

AlexaにGPT-3.5を接続してみた。 #Alexa #ChatGPT #OpenAI #スマートスピーカー
https://twitter.com/allforbigfire/status/1601828289013682176

外部APIと接続するAlexaスキルの作り方

準備-接続先の外部APIアカウント

クラスメソッドさんの記事を参照してください。
https://dev.classmethod.jp/articles/chatgpt-line-chat-bot/

取得した情報で実際にcurlが実行できるか確認しておくと良いです。
PowerShellからは実行できなかったのでAWS CloudShellで試したら接続できました。

Alexa-hostedスキル

いわゆるオウム返しするスキルを改造して実現しました。

  1. エクスペリエンスのタイプを選択します
    その他、でいいと思います。
  2. モデルを選択する
    カスタム
  3. ホスティングサービス
    Alexa-hosted (Node.js)

ホスト地域
米国東部(バージニア北部)

「次へ」を押下。

テンプレートはスクラッチで作成
Hello Worldを少しだけ改造します。
「次へ」を押下。

④審査、ってなっていますが、「Create Skill」を押下

しばし待ちます。

「Success! Your skill has been created.」と表示されているはずです。

画面左側にて
対話モデル>インテント>HelloWorldIntent とクリックしてください。

サンプル発話の入力欄に、{message}と入力します。
「追加」をクリックしてください。

{message} と言って、とも入力します。

「モデルを保存」をクリックします。

画面左側でmessageを選んで、スロットタイプを選択します。
自由な文章を取得させたいので、裏技でAMAZON.Cityを指定します。

「モデルを保存」、「モデルをビルド」とクリックします。

コードエディタをクリックします。
最初に指定したHellow world!のテンプレートのコードが表示されます。

画面左側のpackage.jsonをクリックします。

14行目のaws-sdkの末尾にカンマ、次に挿入で"axios": "^0.16.2"と入力します。

index.jsのタブに戻って、8行目からHellowWorldIntentHandlerまでを、次のコードに差し替えます。
コード中のabcdefg1234567890は、取得されたGPT-3のご自身の情報に書き換えてください。

const axios = require('axios');
const title = '人工知能お悩み相談';

const LaunchRequestHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'LaunchRequest';
    },
    handle(handlerInput) {
        const speakOutput = '人工知能お悩み相談が起動されました。お困りごとを話しかけてください。';

        return handlerInput.responseBuilder
            .speak(speakOutput)
            .withSimpleCard(
                title, 
                speakOutput)
            .reprompt(speakOutput)
            .getResponse();
    }
};


const HelloWorldIntentHandler = {
    canHandle(handlerInput) {
        return Alexa.getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
            && Alexa.getIntentName(handlerInput.requestEnvelope) === 'HelloWorldIntent';
    },
    async handle(handlerInput) {
        const speechText = handlerInput.requestEnvelope.request.intent.slots.message.value;
        console.log('speechText:'+speechText);

// ここでChatGPTに繋げる
        const response =  await getChatGptResponse(speechText);
        console.log('response:'+response);

        return handlerInput.responseBuilder
            .speak(response)
            .withSimpleCard(
                title,
                response)            
            .reprompt(response)
            .getResponse();
    }
};

async function getChatGptResponse(input) {
  const endpoint = 'https://api.openai.com/v1/completions';
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer abcdefg1234567890`,
  };
  const data = {
    prompt: input,
    max_tokens: 2000,
    model: "text-davinci-003"
  };

  try {
    const response = await axios.post(endpoint, data, { headers });
    return response.data.choices[0].text;
  } catch (err) {
    console.error(err);
    return null;
  }
}

consol.logでログ出力できるのですが、CloudWatch Logsの3つのどれかに出力されます。

画面右側の「保存」、「デプロイ」を順番にクリックします。

テストをクリックします。表示された画面で「非公開」になっていると思うので、
「開発中」に切り替えます。入力できるようになります。

入力欄に、「(設定したAlexaスキルの名称)を開いて」を入力します。

こんな感じの返答が繰り返しできるはずです。
Alexa単独ではこんな会話は出来ないので面白いですね。
なお、GPT-3から返答が返ってくるのが遅いせいかよくエラーで終了してしまいます。

コードの解説

Alexa-hostedスキルの初期状態では外部に通信する機能がないそうなので、
axiosというライブラリを読み込むためにpackage.jsonで設定します。

getChatGptResponseという関数内でaxiosを呼び出しています。
const dataの箇所でGPT-3のパラメータを設定しています。

async handle(handlerInput) でasyncを付けるのは、記事を参考にさせていただきました。

参考にさせていただいたサイト

Alexa-hostedスキルを使って 最速でオウム返しスキルを作る
https://speakerdeck.com/toranoana/alexa-hostedsukiruwoshi-tute-zui-su-deoumufan-sisukiruwozuo-ru

https://www.slideshare.net/toranoana-lab/alexahosted

Alexaスキルで位置情報を取得し、さらに外部APIを利用して住所を取得する
https://qiita.com/norippy_i/items/10215d6879d222d88077

Alexa-hostedスキルから、外部にhttpsリクエストをするサンプルコード(axiosを使った場合
https://amazon.developer.forums.answerhub.com/questions/207944/alexa-hosted%25E3%2582%25B9%25E3%2582%25AD%25E3%2583%25AB%25E3%2581%258B%25E3%2582%2589%25E5%25A4%2596%25E9%2583%25A8%25E3%2581%25ABhttps%25E3%2583%25AA%25E3%2582%25AF%25E3%2582%25A8%25E3%2582%25B9%25E3%2583%2588%25E3%2582%2592%25E3%2581%2599%25E3%2582%258B%25E3%2582%25B5%25E3%2583%25B3%25E3%2583%2595%25E3%2583%25AB%25E3%2582%25B3%25E3%2583%25BC%25E3%2583%2588axios%25E3%2582%2592%25E4%25BD%25BF%25E3%2581%25A3%25E3%2581%259F%25E5%25A0%25B4.html

Alexa API calls using Axios
https://dev.to/awedis/alexa-api-calls-using-axios-4ej1

Voiceflowでの接続方法は調査中

最初、当然のごとくVoiceflowでさくっと作ろうと思ったのですが、API ブロックでの設定でうまくいかず、エラーが出て接続できませんでした。



Discussion