34.【音声生成AI設計】LLMを安全に接続する|Thinking状態にだけ置く理由
tags: [“音声生成AI”, “LLM”, “FSM”, “制御構造”, “生成AI設計”]
🤖【音声生成AI設計】LLMを安全に接続する
―― 🧩 Thinking状態にだけ置く理由
ここまでの記事で、音声AIはすでに:
- 🧩 FSMで完全に管理され
- 🔊 Speaking は制御下にあり
- ✋ 割り込みでも壊れなくなった
つまり 骨格は完成している。
ここでようやく、
LLMを戻す準備が整った。
🎯 本記事の目的
- LLMを どこに置くと壊れるかを再確認する
- LLMを どこに置くと壊れないかを確定させる
- 音声×LLMの 最小安全結合構造を提示する
👉 会話AIはまだ作らない。
まずは事故らない配置だけを決める。
❌ LLMを入れてはいけない場所(再確認)
🔊 Speaking
- 時間制約が厳しい
- 即時停止が必要
- ストリーミング制御が発生
👉 LLMは遅すぎる
👂 Listening
- 割り込み判断が必要
- 物理量で即断すべき
👉 意味理解は不要
✋ Interrupted
- 即時遷移が最優先
- 判断遅延=破綻
👉 LLMを呼ぶ余地なし
⭕ LLMを置いてよい唯一の場所
🧠 Thinking
Thinking 状態は:
- 時間制約が緩い
- 音を出さない
- 割り込みされない
- 結果がテキストで返る
👉 LLMの特性と完全一致。
🧩 FSM × LLM の正しい構造
🧩 FSM
├─ 👂 Listening
├─ 🧠 Thinking ──▶ 🤖 LLM(発話内容生成)
├─ 🔊 Speaking
└─ ✋ Interrupted
重要なのは:
- FSM → LLM は 一方向
- LLMは 状態を変えない
- LLMは 命令しない
👉 LLMは部品。
🔌 LLMに渡してよい情報・ダメな情報
⭕ 渡してよい
- 直前の入力テキスト
- 発話目的(例:応答、確認、拒否)
- 最大文字数
- トーン指定(事務的など)
❌ 渡してはいけない
- 状態遷移条件
- 割り込みルール
- 発話タイミング
- 継続判断
👉 制御情報を渡した瞬間に壊れる。
🧪 擬似コード(FSM × LLM)
if state == "Thinking":
text = llm_generate(prompt)
state = "Speaking"
play_tts(text)
ポイント:
- LLMは Thinking中に一度だけ
- 生成結果は 単なる文字列
- FSMが次の状態を決める
🚫 よくある地雷構成
❌ LLMに「次どうする?」と聞く
→ 状態管理が崩壊
❌ LLMに「喋り続けていい?」と聞く
→ 無限発話
❌ LLMに割り込み判断をさせる
→ 即死
🧠 なぜこれで安定するのか
- FSMが 時間を管理
- FSMが 入出力を管理
- FSMが 例外を吸収
- LLMは 意味生成だけ
👉 責務分離が完全。
📌 まとめ
- 🤖 LLMは Thinking 状態にのみ置く
- 🧩 FSMが常に主導権を持つ
- 🔊 Speaking に LLMを入れない
- ✋ 割り込み判断に LLMを使わない
- 🏗 LLMは「外側の知能」
🏁 シリーズの締め
本シリーズでは、
- 🎧 音声生成AIは「生成」ではなく「制御」であること
- 🧩 FSMを中心に置くと破綻しないこと
- ✋ 割り込みは例外ではなく通常動作であること
- 🤖 LLMは Thinking 状態にだけ置くべきこと
を、構造として固定した。
それでも多くの人は、こう思う。
🎭 「もっと会話っぽくしたい」
🤝 「人と話している感じを出したい」
だがそれは 設計目標ではなく演出欲求 である。
会話AIが「賢そう」に見える最低条件は、
会話を真似ることではない。
- 状態が明確で
- 遷移が予測でき
- 破綻しても戻ってこられる
という 制御の健全性 だけだ。
本シリーズは、
会話AI幻想を壊すところで終わる。
それ以上は、
必要になったときに、別シリーズでやればいい。
(GitHub上のMarkdownを正本とし、Qiitaには抜粋・調整して投稿)