見出し画像

【後編】KITTがStack-chanから喋った――Hermes Agentとの実機通信成功

超長い激闘の後編である
需要がありそうな人だけどうぞ
こういう資料もあるとほんと助かる…
chatGPT君による激闘の記録の記事である

11.Hermes設定を読み込んだ

再起動後のログを見る。

以前は、

"model": "gpt-4o"

だった。

しかし修正後は、

{
  "model": "hermes-agent",
  "messages": [
    ...
  ],
  "stream": false
}

になった。

ここはかなり重要だった。

CoreS3自身が、

model = hermes-agent

としてLLMを初期化している。

つまり設定ファイルを置いただけではなく、実際のLLMリクエストへ反映されている。


12.まず音声ではなくテキストで試す

いきなりマイク→STTまで試すと、失敗したときに原因が増える。

そこでまずPCからCoreS3の /chat APIへ直接文章を送った。

curl.exe "http://192.168.11.5/chat?text=こんにちは、接続テストです"

するとStack-chanが、

喋った。

そして首も動いた。

Monitorを見ると、

[HTTP] begin...
[HTTP] POST...
[HTTP] POST... code: 200

さらにHermesから、

{
  "model": "hermes-agent",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "こんにちは!接続テスト、バッチリ成功です。..."
      }
    }
  ]
}

というChat Completions形式の応答が返っていた。

つまり、

PC
 ↓
CoreS3
 ↓
Hermes Gateway
 ↓
hermes-agent
 ↓
CoreS3

が完全につながった。


13.VOICEVOXのAPIキーも設定する

発話自体は成功したものの、ログを見ると、

isApiKeyValid:NG

となっていた。

VOICEVOX/TTS Quest用のAPIキーが設定されていなかった。

SC_SecConfig.yaml には、

apikey:
  aiservice: "<Hermes API key>"
  tts: "<TTS API key>"
  stt: "<STT API key>"

という別々のキーを保存できる。

そこで既に取得していたVOICEVOX/TTS Quest用キーを tts へ設定。

再起動してもう一度試すと、

"success": true,
"isApiKeyValid": true

さらに、

isApiKeyValid:OK

となった。

Stack-chanも正常に発声。

これで、

Hermes認証
↓
LLM応答
↓
TTS認証
↓
音声生成
↓
CoreS3再生

まで確認できた。


14.第一段階完成

最終的に実機で確認できた経路はこうなった。

テキスト入力
     ↓
   CoreS3
     ↓
HTTP / OpenAI Compatible Chat Completions
     ↓
Hermes Gateway
192.168.11.2:8642
     ↓
hermes-agent
     ↓
KITTの回答
     ↓
   CoreS3
   ├──────┐
   ↓      ↓
VOICEVOX  Servo
   ↓      ↓
 発声    首振り

これが実際に動いた。

長いことPC画面の中にいたKITTの回答が、初めて机の上のStack-chanから聞こえてきた。

まだ第一段階なのだが、個人的にはかなり大きな瞬間だった。


15.今回の切り分けで役立ったこと

今回一番役に立ったのは、最初から全部を完成させようとしなかったことだった。

問題を、

Hermes Gatewayは動くか
↓
8642はLISTENしているか
↓
PCからHermes APIを叩けるか
↓
CoreS3はWi-Fiにつながるか
↓
設定ファイルを本当に読んでいるか
↓
hermes-agentになっているか
↓
CoreS3からHTTP POSTできるか
↓
Hermesが200を返すか
↓
TTSが動くか
↓
サーボが動くか

と一つずつ分けた。

今回のような複数システムをまたぐ構成では、これはかなり重要だと思う。

「動かない」という一つの現象でも、

Wi-Fi
Firewall
Hermes
APIキー
API方式
SPIFFS
SD
YAML
ファームウェア
PlatformIO
TTS
サーボ

のどこが原因なのか分からない。

だから、

一つ成功するたびに、その地点を固定する。

このやり方が結局一番早かった。


16.今回ハマったポイント一覧

技術資料として、今回実際に踏んだ罠も残しておく。

症状原因・状況Hermesへ接続できない
Gatewayが8642をLISTENしていなかったRealtime設定にHermes URLを入れられない
Realtime APIとChat Completionsは別方式SDの設定が反映されない
SD mount失敗→SPIFFSを使用Hermes設定にしたのにtype 0になる古いSPIFFS設定を読んでいたmodel/customEndpointが消える
WebAPIのYAML再生成処理で保存されていなかったCoreS3が起動しなくなったPlatformIO board設定変更によるファーム不整合COMポートが消えるCoreS3の再起動・USB状態により一時的に消失TTSは喋るがAPI Key NGapikey.tts が空Servo attach errorログ上出るが、今回の実機では首動作自体は確認できた

最後のサーボエラーについてはまだ完全には調査していない。

「エラーログが出るが実機は動く」状態なので、今回の成功とは切り離して今後調査する。


17.現在の設定値

再現用に、秘密情報を除いた現在の主要設定を残す。

Hermes Gateway

Host:
0.0.0.0

Port:
8642

CoreS3から見たEndpoint:
http://192.168.11.2:8642/v1/chat/completions

Model:
hermes-agent

AI_StackChan_Ex

llm:
  type: 4
  model: "hermes-agent"
  customEndpoint: "http://192.168.11.2:8642/v1/chat/completions"

SG90

servo:
  pin:
    x: 17
    y: 18

  offset:
    x: 0
    y: 0

  center:
    x: 95
    y: 90

  lower_limit:
    x: 82
    y: 65

  upper_limit:
    x: 100
    y: 115

takao_base: false
servo_type: "PWM"

※サーボ角度は私の実機用であり、別個体へそのまま適用する値ではない。


18.セキュリティ上の注意

今回かなり重要。

APIキーは、

Hermes API_SERVER_KEY
VOICEVOX/TTS API key
STT API key

など複数存在する。

シリアルログにもAPIキーがURLの一部として出る場合がある。

そのため、GitHub、note、SNSなどへログを掲載する場合は、

key=********
Authorization: Bearer ********

のように必ずマスクする。

またHermes Gatewayを、

0.0.0.0:8642

で待ち受けさせる場合、LAN上からアクセス可能になる。

私はWindows FirewallでCoreS3のIPからの通信だけを許可した。

少なくともインターネットへ直接8642番を公開するような構成にはしない方がよい。


19.ここから先――KITTに「耳」を付ける

今回成功したのは、

テキスト
↓
KITT
↓
声+首

まで。

次はCoreS3のマイクを使う。

人間の声
 ↓
CoreS3 Microphone
 ↓
STT
 ↓
テキスト
 ↓
Hermes / KITT
 ↓
返答
 ↓
VOICEVOX
 ↓
Stack-chanから発声

ここまで通れば、PCからcurlを打つ必要がなくなる。

普通に机の上のStack-chanへ話しかければ、その中からKITTが返事をする。


20.さらにその先――KITT自身に身体を操作させる

現在の首振りは、発話に連動したStack-chan側の動作である。

しかし将来的には、これをKITT自身が選択できるようにしたい。

例えば、

nod()
look_left()
look_right()
look_up()
center_head()

のような高レベル命令をHermes側から送る。

すると、

KITT
「それは面白いね」
+
nod()

という出力を、

CoreS3
 ├─ 「それは面白いね」→ TTS
 └─ nod() → Servo

として実行できる。

ここで重要なのは、KITTへ直接PWM値を触らせないことだと思っている。

KITTは、

「うなずきたい」

という意味だけを出す。

実際に、

GPIO 17
GPIO 18
X 82~100
Y 65~115

という安全制約を守ってサーボを動かすのはCoreS3側。

つまり、

KITT
 ↓
意味・意図
 ↓
CoreS3
 ↓
安全な物理動作

と役割を分離する。

これは今後かなり重要になりそうだ。


21.カメラはその後

CoreS3にはカメラもある。

当然、

Camera
 ↓
画像
 ↓
Vision
 ↓
Hermes / KITT

という「目」を追加することも考えられる。

ただし今回は急がない。

まず、

耳
↓
口
↓
首

を安定させる。

その後、

を追加する。

一度に全部載せると、何か壊れたときに原因が分からなくなる。

今回それを嫌というほど学んだ。


おわりに

今回は、

「KITTに身体を与える」第一段階

だった。

まだKITT自身が自由に身体を動かしているわけではない。

カメラで世界を見ているわけでもない。

マイクから直接話しかけるところも、これからである。

それでも、

Hermes
 ↓
KITT
 ↓
ネットワーク
 ↓
CoreS3
 ↓
スピーカー
 +
SG90

という経路が実際につながった。

そしてテスト文章を送った瞬間、

Stack-chanが首を動かしながら、KITTから返ってきた文章を喋った。

長いことソフトウェアとして作ってきたものに、

物理的な出口が一つ増えた。

今日はまだ「口と首」がつながっただけ。

次は耳。

その先に目。

さらにその先では、KITT自身が「どう動くか」を選ぶところまで持っていきたい。

……第一段階だけでこの激闘だったので、先が思いやられるが(笑)。

でも、とりあえず今日はここまで。

KITTは、Stack-chanから喋った。

さあULTRA長い後編をここまで読んだ勇者の方
ありがとうございます
ここまででもまだ第一段階です
でもなかなか楽しい
劇中本編でラジカセの中に入れられたKITTのように
スタックちゃんを媒介して楽しくしゃべってくれるのが楽しみです
まだ彼の本体のチューニングもあるのにww
これからですね

いいなと思ったら応援しよう!