跳到主要內容
yoAkyoku
← Work

陪伴型 AI 語音與 Agent 平台

即時語音對話的陪伴型 AI。難的不是 STT → LLM → TTS,而是錄音、播放與斷線重連之間的狀態。

  • AI / LLM
  • Agents
  • Web
Contents

概述

商業專案,工作室負責全端與 AI 應用層。這是一套陪伴型 AI 平台:語音對話之外,也處理記憶、知識檢索,以及家屬和照護人員的存取。前端有 LIFF、一般 Web 與管理介面,後端透過 Gateway 維持即時語音 Session。

問題

把 STT、LLM、TTS 串起來只是第一步。使用者可能還在錄音,上一段語音正在播放,又剛好斷線重連。部分轉錄、最終轉錄和 generation 也不一定照畫面收到的順序完成。只用一個 conversation state,這些狀態會互相蓋掉。

解法

把 utterance、generation 與播放狀態分開管理;turn 與 generation 綁定,晚到的舊轉錄不會啟動錯誤的回答。Session Continuity、identity、expiry 與 stale socket 檢查放在同一組規則。Agent 的 MCP、Tools、Skills、Knowledge Base 與外部搜尋放在後台設定與 Provider 邊界裡。

系統架構
長者 / 家屬 / 照護人員 ──▶ LIFF / Web / Admin
                              │
                              ▼
                    Fastify Gateway ──▶ WebSocket Voice Session
                                              │
                                              ▼
                                        Agent Runtime
                                  ┌─────────┼──────────┐
                              STT / LLM / TTS   External Search   PostgreSQL / Redis

主要功能

  • STT → LLM → TTS 的語音對話生命週期
  • utterance、transcript、generation 與播放狀態管理
  • WebSocket 斷線後的 Session Continuity、回放與取消
  • 後台設定 MCP、Tools、Skills、Knowledge Base 與外部搜尋
  • 長者、家屬與照護人員分開的資料權限、記憶保留與刪除流程
  • Socket、Request、Log 與 Container Resource 限制
  • 語音、閱讀模式與回放操作

架構

語音 Agent Pipeline
麥克風 ──▶ 部分轉錄 ──▶ 最終轉錄 ──▶ turn(綁定 generation id)
                                          │
                                          ▼
                                   LLM generation ──▶ TTS ──▶ 播放
                                          │
        舊 socket / 舊轉錄 ──▶ 比對 generation id ──▶ 不符則丟棄,不取消新的 generation
Agent Runtime
Conversation ──▶ Agent Runtime ──▶ Provider 邊界
                       │               ├─ MCP Servers(後台開關)
                       │               ├─ Tools / Skills(參數先受限制)
                       │               ├─ Knowledge Base
                       │               └─ External Search(不綁死單一服務)
                       └──▶ Memory(依角色決定保留與刪除)

工程決策

狀態要拆開,不能共用一個 conversation state

錄音中、播放中、重連中是三件會同時發生的事。拆成 utterance、generation、playback 三組狀態,各自有明確的轉換,互相蓋掉的問題才消失。

轉錄順序不能直接當回答順序

turn 與 generation 綁在一起。晚到的舊轉錄比對不到現行 generation 就丟棄;舊 socket 也不能取消新的 generation。

斷線要分三種結果

可以恢復、應該停止、需要提示重新開始。Session Continuity、identity、expiry 與 stale socket 檢查放在同一組規則裡,才不會每個地方各判各的。

Agent 能力要能被控制

MCP、Tools、Skills、Knowledge Base 與外部搜尋不是每個情境都要開。放進後台設定與 Provider 邊界,對話流程不直接綁某一個搜尋服務,工具參數先經過限制。

畫面

未包含正式使用者資料或服務品牌。

陪伴型 AI 首頁
語音入口
陪伴型 AI 文字對話
文字互動與回憶

技術

TypeScript、Fastify、React、LIFF、WebSocket、STT / LLM / TTS、Agent Tools、MCP、SearXNG、ElevenLabs、PostgreSQL、Redis、Docker。

結果與心得

  • 即時語音的難處在協調,不在串接。狀態拆成 utterance、generation、playback 三組之後,互相蓋掉的問題才消失。
  • 斷線先分類再處理:能恢復、該停止、要重來,三種結果各有一條路。
  • 即時語音仍受瀏覽器權限、網路與外部語音服務影響,這一段應用層只能降低、無法消除。

公開範圍

只描述應用層的狀態協調、恢復、權限與資源控制,不含第三方 Provider 的 SLA。