HiZex Herald × HiZex Avatar
文字對話走到需要「人」的時候,交給 AI 顧問
HiZex Avatar 是 HiZex AI 的語音/視訊顧問產品。Herald 的 handoff 節點帶著這個人的脈絡把對話交過去;對談結束後,摘要、事實與結果回到 Herald,劇本繼續走。
流程
握手時帶去,結束時帶回
1 劇本 handofftarget=avatar;Herald 建立 handoff(15 分鐘有效)
2 LINE 卡片「跟 AI 顧問聊 5 分鐘」;連結開外部瀏覽器(LiveKit 需要麥克風)
3 前端讀 contextGET /v1/handoffs/{id}(X-Handoff-Key)→ subject、vars、facts、greeting
4 加入 roomfacts / vars 注入記憶脈絡;開場白由顧問先說
5 對談結束回呼POST /v1/webhooks/avatar(HMAC):summary、facts、outcome
6 劇本續走condition:done / abandoned;facts 併入記憶;LINE 後續推播
同一個人
Avatar 端以 herald:<subjectId> 作為使用者身分,四層記憶自然落在同一個人底下;接上共用 AI core 時兩邊的身分可連結成一人。
15 分鐘有效
handoff 過期或已完成回 410;第一次讀取把狀態改為 opened,回呼把它改成 completed 或 abandoned。
沒有 Avatar 也不壞
未設定 AVATAR_WEB_URL 時,handoff 節點送「AI 顧問目前無法連線」並沿 condition:abandoned 續走;平台不當機。
Context
能帶什麼過去
前端以共享密鑰讀取;Herald 只給前端需要的欄位。
GET /v1/handoffs/{id}
X-Handoff-Key: ****
{
"id": "01J…", "state": "created",
"subject": { "id": "sub-015", "displayName": "王小明",
"locale": "zh-TW", "authId": "herald:sub-015" },
"serviceUuid": "svc-admission-ai",
"scenario": { "id": "sc-admission", "nodeId": "n-avatar" },
"vars": { "interest": "AI 系所", "grade": "高三" },
"facts": [
{ "category": "interest", "content": "對 AI 相關科系有興趣" },
{ "category": "constraint", "content": "數學成績不理想,擔心跟不上" }
],
"greeting": "你好,我是招生顧問。你剛在 LINE 提到想了解 AI 系所…",
"callback": { "url": "https://hizexai.com/v1/webhooks/avatar",
"keyId": "avatar-2027" },
"expiresAt": "2027-09-03T10:15:00+08:00"
}
- subject
- 顯示名、語言、跨系統身分 ref;不含地址明文
- vars
- 劇本進行到 handoff 為止收集到的變數(choice / collect / lookup 的結果)
- facts
- 此人目前有效的記憶事實(category / content / confidence);永遠不含成績與金額
- greeting
- Herald 依劇本產生的開場白,顧問在第一句話就接上脈絡
- callback
- 回呼 URL 與簽章 key id;Avatar 端以 HMAC 回報
同意範圍仍然適用:handoff 只會發生在此人同意的分類之下;Avatar 端讀到的 facts 也只來自 Herald 願意給的範圍。
結果回流
對談結束後,Herald 收到什麼
簽章與系統事件相同:X-PU-Key-Id、X-PU-Timestamp、X-PU-Signature(HMAC-SHA256,±300 秒,重放保護)。
POST /v1/webhooks/avatar
{
"eventId": "hub-01J…-end", "type": "avatar.session.ended",
"handoffId": "01J…", "durationSeconds": 312,
"status": "completed", // completed | abandoned
"summary": "學生關心數學門檻;已說明課程與輔導資源;有意願參加 9/15 說明會。",
"facts": [ { "category": "intent",
"content": "有意願參加 9/15 線上說明會", "confidence": 0.9 } ],
"outcome": { "kind": "registration",
"patternInstanceId": "pi-…",
"data": { "session": "9/15 19:00" } },
"avatarAuthId": "avatar:u-42" // 選填:身分連結
}
| Herald 端 | 動作 |
|---|---|
| handoff | state → completed / abandoned;outcome 存檔 |
| 記憶 | facts → 此人的記憶(source=avatar);summary → 摘要(scope=avatar) |
| 回應 | outcome.kind=registration → 寫入 pattern 回應表,等同在 LINE 內報名 |
| 劇本 | 從 handoff 節點沿 condition:done 或 condition:abandoned 繼續,通常是一則 LINE 確認卡 |
| 身分連結 | 接上共用 AI core 時,把 herald:<id> 與 avatar ref 連成一人;best-effort,失敗只記稽核 |
部署組合
少了任何鄰居都不會壞,只有對應功能降級
| 組合 | 記憶在哪 | handoff 行為 |
|---|---|---|
| (a) 只有 Herald | Herald 內建 | avatar 節點送「無法連線」、走 condition:abandoned |
| (b) Herald + 共用 AI core | 共用服務,ref herald:<subjectId> | 同 (a)(沒有 Avatar 可轉) |
| (c) Herald + HiZex Avatar | 各自;握手帶去、結束帶回 | 正常;avatarAuthId 只進稽核 |
| (d) 全部 | 共用;handoff 時把兩邊身分連成一人 | 正常;identityLinked=true |
目前是哪一種,GET /v1/health 的 integrations 與主控台儀表板的「整合狀態」卡都會顯示。