Google home mini で ChatGPT に質問して音声回答してほしい


# はじめに
自宅でGoogle home miniを導入以来、気軽に疑問を投げかけるようになり、検索回数が増えました。使い出すと気になる点も出てきました。「うまく理解できませんた」、「〇〇でレシピが見つかりました。こちらで良いですか？」「近くにお店が数件ありました。１つ目は…」などが満足の得られない回答例にあたります。回答の精度、回答の仕方を改善するために私にできることは何でしょう？調査してみました。ちなみに、見切り発車の投稿で、随時更新していきます。

# 何をしたの(してるの)？
Google Home mini + ChatGPT + chrome book(linux環境) による回答精度の向上を考えています。
個々の取り組みは、先人の方々の取り組みがありますので、参考にさせて頂きつまづいた部分をメインに紹介させて頂きます。当初予定していた作業は終了たんですが、回答精度、使い勝手としてはまだ微妙なのでさらに改善が必要です。

本質的にGoogle Homeのプロンプト(聞き方)開発をChatGPTのプロンプト開発に置き換えという行為かと思います。後者の活動が活発な気がするので、回答精度が上がると思っていますが、どうなんでしょう？　Google Homeのプロンプト開発って行われているのか未調査です。

Google Home miniに同じように聞いても答え方が変わることもあり、内部で更新作業しているのだと思いますが、必ずしも良い方向に進んでる気がしません。Bardもそのうち統合されるかもしれませんが、単体の回答精度とか考えるとまだまだ先な気がします。最近は朝におはようと話しかけても、こんにちはと答えが返ってきたり、突然英語を喋りだしたり、読み間違いしていたり、決め打ちからAI変更したのか回答に違和感を感じることがあります。

# 先人の知恵
下記の記事では、音声でChatGPTに質問する類似の技術を含めた紹介がありました。
1. PC、スマホ、アップルウォッチ、アレクサからで、おしいGoogle homeがありません。アレクサスキルからのVoiceflow、アレクサコンソールや、make(IFTTT integrations)経由でChatGPTへ接続する模様。
[【ChatGPT】音声で操作できる？グーグルホームやアレクサ、AppleWatchから使うには？ - ChatGPTの教科書](https://www.kyoukasho.net/entry/googlehome-chatgpt)  
1. 上記にもあったVoiceflowはGoogleアシスタントのスキルが作成できるとあり、応用できる可能性があるかも。
[Voiceflow単体で、ChatGPT APIに連携するAlexaスキルを作る手順](https://zenn.dev/allforbigfire/books/9d4021bca0c96d)  
1. GoogleHomeからありました。ありがたいです。こちらを参考にできるか考えます。
[Googleの代わりにOpenAIのGPT-3で質問に答えるようにした - Qiita](https://qiita.com/kobbeko/items/a6079f13f98b35790a1a)  
下記のようなやりとりでGoogleHome(GH)と会話します。
聞き方や回答精度は改善の余地ありですがここまでできるように頑張ってみます。

会話例
| 私 | Google Home mini | 
| ---- | --------------- | 
| OK google タスク | 追加するものを教えて下さい |
|AI "なぜ電車のつり革には丸と三角の形があるのですか？"|はい、〇〇を追加しました
||…考え中(長い沈黙、どうしよう耐えられません)…|
||電車のつり革には丸と三角の形があるのは、安全性を高めるためです。丸いつり革は乗客が滑り落ちないように、手を滑りにくくするために使われています。また、三角形のつり革は、乗客が乗り降りしやすくするために使われています|

# できるかな？
上記3の方法は、ローカルlinux環境上のプログラム、python、javascript、perl、shスクリプトを利用して、cloudサービスを接続しています。複雑ですね。

1. コマンド＋質問内容を音声入力　Google Home
1. コマンド＋質問内容を保存　Google keepサービス
1. Google keepを監視するプログラム(gkeeper.py)
1. firebaseにコマンドと変数を分けて書き込むプログラム(task.js)
1. コマンドと変数を分けて保存  [firebase](https://firebase.google.com/)　は使いませんでした。
1. GPT-3で質問に回答するプログラム(ai.py)
1. Google homeを喋らせる？プログラム(~~speak.sh googletts-cli.pl~~ google-home-voicetextを使用)


linux環境にはWSLやラズパイなどが挙げられていました。クラウドで完結したいですが、自宅のGoogleHomeに接続するにはローカル環境が必要なのでしょうか？
残念ながら自宅には自由にできるWindowsPCや、ラズパイはなく、あるのはChromeBookなので、こちらにlinux環境構築から始めて、出力があったほうが動作確認しやすいので上記フローの下から検討していきます。
下記にフロー図にしてみましたが分かりづらいですね(まだまし？mermaidの練習)。
```mermaid
flowchart TB;
    私--"タスクAI〇〇"-->gh[google home mini];
    私-.ブラウザ.->firestore;
    gh--回答-->私;
    gh-->gk[google keep];
    gk<-->gkpy[gkeeper.py];
    subgraph linux;
      direction LR;
      gkpy-->task[task.js];
      task-->aipy[ai.py];
      aipy-->ght[google-home-voicetext];
      task -.-> 任意プログラム
    end;
    subgraph cloud;
      gk;
      openai;
      firebase;
    end;
    aipy <--> openai
    firestore --> ght
    ght --> gh
      subgraph firebase;
        firestore[cloud firestore];
        rd[Realtime Database];
      end;
```
# linuxとdocker環境構築
下記記事を参考にlinux環境を構築します。
環境に合わせて多少変更しました。
Docker、docker-composeまでインストール完了です(2023/4/16)。
[chromeOSでローカルにdocker環境を作る - ポエム](https://yutarotani.hatenablog.com/entry/2018/12/30/070854)

変更点
- ChromeBook ASUS C302C
- ChromeOS バージョン: 112.0.5615.62（Official Build） （64 ビット）
- lxc(linuxコンテナ)は既存のpenguinを使用(独自コンテナは作成しない）
Ctrl+Alt+t だとCroshが起動して面倒なので、左下のアプリ実行からターミナルを起動し、penguinを選択。
- archを環境に合わせて設定
- apt-keyの非推奨対応のため、signed-byにてgpgファイル指定
- python3、pip3の明示使用
```bash:bash
sudo apt update
sudo apt install -y apt-transport-https ca-certificates curl gnupg2 software-properties-common

prog="docker"
sudo mkdir /etc/apt/keyrings
key=/etc/apt/keyrings/${prog}.asc
arch=$(dpkg --print-architecture)
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o ${key}

https="https://download.docker.com/linux/debian $(lsb_release -cs) stable"
echo "deb [arch=${arch} signed-by=${key}] ${https}" | sudo tee /etc/apt/sources.list.d/${prog}.list

sudo apt-get update
sudo apt-get install docker-ce
sudo service docker restart
sudo systemctl enable docker

sudo apt upgrade python3
sudo apt install pip
pip install --upgrade pip

curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python3
sudo pip3 install docker-compose

#確認
sudo docker run hello-world
sudo docker container run -d -p 8081:80 --name nginx nginx
sudo docker ps 
```
hostname -I　で表示されるIPのうち100.115.92.xxx がローカルPCからアクセスできるeth0のアドレス。 ブラウザからhttp://100.115.92.xxx:8081でアクセスしたらnginxのページがでる。

確認　ローカルPCブラウザからのnginxアクセス可否
OK　100.115.92.xxx:8081 　　　linuxコンテナ内で hostname -I
OK　localhost:8081           
OK　penguin.linux.test:8081
OK　penguin.termina.linux.test:8081

# 外部PC(google home mini)とアクセスできるネットワーク設定とチェック
[linux on Chromebookのポート転送の設定](https://blog.oyasu.info/2020/12/17/8023/)を参考にしました。
ChromeOS　　[デベロッパー]→[Linux環境設定]→[ポート転送]
　　下記ポート[追加]して有効化
　　　　tcp 8080,8888  本番用 google-home-voicetext
　　　　tcp 8081       確認用 nginx

確認　同一メットワークPC,スパマのブラウザからのnginxアクセス可否
OK　192.168.1.xxx:8081　　　　ルータのDHCPから割り振られるIP

当初、独自で作成したlinuxコンテナ上にDocker構築しても、転送ポート[追加]までできましたが、トグルで有効化ができず、ポート転送できませんでした。
上記のポート転送の設定は、既存コンテナpenguinにしか対応しないようです。

また、chromeアプリ[Connection Forwarder](https://chrome.google.com/webstore/detail/connection-forwarder/ahaijnonphgkgnkbklchdhclailflinn/related)も試すもうまく動作しませんでした。

[Chrome ターミナル (Crosh) と Chromebook の Linux ターミナルを混同しないでください。](http://jp.tipsandtricks.tech/chromebook-%E3%81%A7-linux-%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%82%92%E9%96%8B%E3%81%8F%E6%96%B9%E6%B3%95)すみません混同していました。
以前chromebook でCtrl+Alt+t だとlinuxターミナル起動した記憶があるのですが、現在はCroshが起動します。

# GoogleHomeに喋らせる

上記のspeak.shの情報が辿れず、下記リンクを参考にしました。
上記ネットワーク設定に手間取りましたがGoogle Home miniが喋ると感動です(2023/4/19)。
linuxからだと
使用方法
```bash:bash
cd /your_install_dir/google-home-voicetext-docker
sudo docker-compose up -d
curl -X POST -d text='こんにちは世界' "http://100.115.92.xxx:8080/google-home-voicetext"
```
[【Docker】Google HomeやNestを自在に喋らせる方法](https://zenn.dev/sikkim/articles/f50571ae778df51dd098#fnref-fc42-1)  
[Google Homeを手軽に喋らせる仕組み(google-home-voicetext)を作った（Dockerにも対応） - Qiita](https://qiita.com/sikkim/items/f03df7e2db13ea7f5a2b)  

インストール
まだであれば、[node,npmをインストール](https://qiita.com/TsutomuNakamura/items/7a8362efefde6bc3c68b)
firebaseのバージョン8,9で記述変更があったらしく？9.20.0ではエラーあります。
バージョン9合わせてtask.jsの修正は後回しにして、ここではバーション8を指定して動作を確認します。
```bash:bash
sudo apt update
sudo apt install nodejs
sudo apt install npm@8.6.8
npm install firebase
```
[【Firebase】firebaseConfigの設定・確認](https://god48.com/firebaseconfig-setting-confirmation)
firebaseプロジェクトの設定
マイアプリ　タイプnode?　< // >
npmを使用する
注意点
- Firebaseの設定だけではdatabaseURL(FIREBASE_DATABASE_URLに設定する値)が表示されませんでした。Realtime Databaseの設定をすると表示されました。
- VOICETEXT_API_KEYは最後に`:`を追加します。
- WIRELESS_IPは192.168.1.xxx(ルータDHCPから割り振られるIP)を使用します。

google-home-voicetextの設定ファイル
```conf:~/work/docker/google-home-voicetext-docker/.my.env
# TimeZone
TZ=Asia/Tokyo

# VoiceText API key
# Refer to https://cloud.voicetext.jp/webapi
VOICETEXT_API_KEY=XXXXXXXXXXXXXXXX:

# Host IP address
WIRELESS_IP=192.168.1.xxx

# Google Home / Nest IP address
GOOGLE_HOME_IP=192.168.1.yyy

# Your Firebase database URL
FIREBASE_DATABASE_URL=https://XXXXXXXXXX.firebaseio.com

# Your Firebase service account key's path
# Don't change it.
FIREBASE_SECRET_KEY_PATH=/google-home-voicetext/firebase.json

# Speaker type
VOICETEXT_SPEAKER=HIKARI        #女性の声
VOICETEXT_SPEAKER=BEAR          #凶暴なクマ
VOICETEXT_SPEAKER=HARUKA        #HIKARIよりも落ち着いた女性の声
VOICETEXT_SPEAKER=SANTA         #浮かれたサンタクロース
VOICETEXT_SPEAKER=SHOW          #「モヤモヤさまぁ～ず」のナレーター
VOICETEXT_SPEAKER=TAKERU        #落ち着いた男性の声
```

# GPT-3で質問に回答するプログラム(ai.py)

使用方法`python3 /home/xxxx/ai.py 電気料金の節約方法`
インストール`pip install openai
`
ai.pyの変更点
openaiからAPIキーを入手してopenai.api_keyに設定。
Google Homeに喋らせるプログラムの置き換え
```python:ai.py
   #cmd = "/home/xxxxx/speak.sh" + ' ' + data;
   cmd = "curl -X POST -d text=" + data + " http://100.115.92.xxx:8080/google-home-voicetext"
```

# firebaseにコマンドと変数を分けて書き込むプログラム(task.js)
task.js内でAI(上記ai.py実行)はfirebaseは使いませんので設定不要でした。AI以外にもキーワードにプログラムを割り当てれば、いろいろできそうです。

# Google keepを監視するプログラム(gkeeper.py)
設定は下記のとおりです。実行すると一定時間ごとにgoogle keepのタスクを確認し、タスクがあればtask.jsを実行します。

1. アプリパスワード作成
[google account](https://myaccount.google.com/security)/セキュリティ/Google にログインする方法/2 段階認証プロセス/アプリパスワード
アプリパスワード作成
　パスワードをメモる。
1. インストール`pip install gkeepapi`

# Google Home Mini 設定
Google Home アプリのルーティン設定にて、下記を実行できるようにする
タスク　→　タスクリストに設定

# 課題
- 聞き方が不自然、冗長
    OK google タスク　→　OK google 先生
- 受け答え、復唱が冗長(Google keep)
    いかんともし難そう
- 返答までの時間が長い
    つなぎの会話を準備？
- 回答精度向上
    CHatGPTプロンプト開発
- 長文回答対策
    VOICETEXTの200語？制限　→　文章を分割
    Google Home miniの連続会話対策
　　(会話中に次の会話の指示が届くと、前の会話の途中で次の会話が始まる)
　　→　どうしよう？会話の終了トリガとかでてないか？
- dockerにまとめる(忘れてた)

# 備忘録
下記はchrome book上で
Ctrl+Alt+T キーを押して crosh(chrome shell?) ターミナルを開き
vmc(virtual machien) で仮想マシンTerminaを起動
lxc(Linuxコンテナ)で自作Linuxコンテナを起動したときの様子です。
結局、自作Linuxコンテナで、ポート転送の仕方が分からず使わずじまいでした。
この様子を再現するMarkDownはあるんだろうか？下記は` ```console:crosh`
```console:crosh
crosh> vmc list
crosh> vmc start termina
(termina) chronos@localhost ~ $ lxc list
(termina) chronos@localhost ~ $ run_container.sh --container_name forDocker --shell --user dog
(termina) chronos@localhost ~ $ lxc start forDocker 
(termina) chronos@localhost ~ $ lxc exec forDocker bash
root@forDocker:~# su - dog
$ sudo docker-compose up -d
```