Regenerate Summary
連線資訊
| 項目 | 值 |
|---|---|
| 基礎路徑 | https://vas-poc.vurbo.ai/api/v1/sse |
| 協定 | HTTP + Server-Sent Events (SSE) |
| 資料格式 | text/event-stream |
| 認證方式 | Header X-API-Key: {KEY} |
注意:瀏覽器原生 EventSource API 不支援自訂 Header,需使用 fetch API 搭配 ReadableStream,或使用支援 Header 的 SSE 客戶端套件。
端點總覽
拆成預覽 / 存檔兩個端點:
| 方法 | 端點 | 寫 DB | 儲存逐字稿 | 計費 | 用途 |
|---|---|---|---|---|---|
| GET | /api/v1/sse/regenerate/summary/{taskId} | ❌ | ❌ | ✅ | 預覽(試跑、比較不同 prompt 結果) |
| POST | /api/v1/sse/regenerate/summary/{taskId} | ✅ | ✅ + bump revision | ✅ | 存檔(正式儲存) |
已知限制:GET 預覽仍會計費 — LLM 真實消耗 token,不能讓 GET 端點白嫖。重複呼叫 GET 會重複計費,但不會改變後端儲存狀態。
共用:請求參數
GET 走 query string、POST 走 JSON body,欄位名與型別相同:
| 參數 | 類型 | 必填 | 限制 | 說明 |
|---|---|---|---|---|
taskId (path) | string | 是 | UUID | 錄音 ID |
mode | string | 是 | enum "builtin" | "custom" | 顯式路徑選擇 |
template | string | builtin 必填 / custom 禁帶 | exists prompt_templates.slug | 內建模板 slug |
prompt | string | custom 必填 / builtin 禁帶 | ≤2000 字元 | 客戶完整 prompt(取代 IPEVO 三層) |
promptSlug | string | custom 必填 / builtin 禁帶 | ≤64 字元、Unicode、禁控制字元 | 客戶自家識別碼(pass-through) |
language | string | 否 | - | 摘要輸出語言代碼(如 zh-TW、en-US),未指定時使用 transcription 第一個語言 |
plainText | boolean | 否 | 預設 false | 要求純文字輸出(後端會額外做 markdown 後處理) |
互斥規則:
mode=builtin下不可帶prompt或promptSlugmode=custom下不可帶template,但prompt與promptSlug必填
違反 → 422 validation error(summary_mode_field_mismatch)
GET /api/v1/sse/regenerate/summary/{taskId}(預覽)
功能說明
跑一次 LLM 重新生成摘要,僅串流回客戶端,不寫 DB、不更新逐字稿記錄。
適用情境:客戶端想嘗試不同 prompt / 不同 plain_text 設定,比較結果後再決定是否存檔。
請求範例
builtin mode
curl -N "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000?mode=builtin&template=meeting&language=zh-TW&plainText=true" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
custom mode
curl -N "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000?mode=custom&prompt=%E8%AB%8B%E5%BC%B7%E8%AA%BFKPI&promptSlug=acme-meeting-v2&plainText=true" \
-H "X-API-Key: vas_aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW"
副作用
- ✅ 會在
usage_logs新增一筆type=summary的計費記錄(LLM 真實消耗 token) - ❌ 不會更新
recordings.summary_mode/summary_template/summary_prompt_slug三欄 - ❌ 不會覆寫已儲存的摘要
POST /api/v1/sse/regenerate/summary/{taskId}(存檔)
功能說明
GET 預覽的所有動作 + 寫入 DB 與逐字稿記錄。
請求範例
builtin mode
curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_..." \
-H "Content-Type: application/json" \
-d '{
"mode": "builtin",
"template": "meeting",
"language": "zh-TW",
"plainText": true
}'
custom mode
curl -N -X POST "https://vas-poc.vurbo.ai/api/v1/sse/regenerate/summary/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: vas_..." \
-H "Content-Type: application/json" \
-d '{
"mode": "custom",
"prompt": "你是皮膚科專科助手。請從逐字稿萃取 Fitzpatrick 分型...",
"promptSlug": "skin-clinic-acme-v2",
"language": "zh-TW",
"plainText": true
}'
副作用
- ✅ 在
usage_logs新增一筆type=summary的計費記錄 - ✅ 依 mode 互斥寫入
recordings三欄:- builtin →
summary_mode='builtin'、summary_template=<slug>、summary_prompt_slug=NULL - custom →
summary_mode='custom'、summary_template=NULL、summary_prompt_slug=<客戶 slug>
- builtin →
- ✅ 更新逐字稿記錄的 top-level 欄位並
revision += 1:summary(純字串)、summary_language、summary_mode、summary_template(effective slug)、summary_plain_text- custom mode 強制
summary_prompt_snapshot(客戶 prompt 原樣 snapshot,是唯一重建依據)
事件序列(兩端點相同)
1. connected → 連線確認
2. summary_regeneration → 發送摘要片段(重複 N 次,累積式)
3. done → 生成完成
connected
{
"message": "Summary regeneration stream connected (recordingId: 550e8400-..., mode: custom, endpoint: preview)"
}
⚠️ 避免混淆:message 中的
mode是業務 mode(builtin/custom,即 request 帶入的 mode);endpoint才是端點模式(previewGET /persistPOST)。兩者語義不同,請勿混為一談。
summary_regeneration
{ "text": "本次會議討論了以下議題:\n1. 產品開發進度", "is_final": false }
| 欄位 | 類型 | 說明 |
|---|---|---|
text | string | 累積的摘要內容(plainText=true 時 is_final=true 的 text 為清洗後純文字) |
is_final | boolean | 是否為最終結果 |
done
{
"task_id": "550e8400-e29b-41d4-a716-446655440000",
"tokens_used": 123,
"final_content": "本次會議...(清洗後完整內容)",
"mode": "custom",
"template": "skin-clinic-acme-v2",
"plain_text": true,
"persisted": true,
"prompt_snapshot": "你是皮膚科專科助手..."
}
| 欄位 | 類型 | 說明 |
|---|---|---|
task_id | string | Recording UUID |
tokens_used | number | 總 token 用量 |
final_content | string | 完整摘要內容(plainText=true 時為清洗後純文字) |
mode | string | 業務 mode:"builtin" 或 "custom" |
template | string | effective slug — builtin → 內建模板 slug;custom → 客戶 slug |
plain_text | boolean | 是否啟用純文字模式 |
persisted | boolean | 本次摘要是否已正式儲存(GET 為 false、POST 為 true) |
prompt_snapshot | string | 僅 custom mode 出現,為客戶原樣傳入的 prompt 內容(強制 snapshot,是唯一重建依據) |
特有錯誤碼
| 錯誤碼 | HTTP | 說明 | 處理建議 |
|---|---|---|---|
recording_not_found | 404 | 找不到指定的錄音 | 確認 taskId 正確 |
sse_template_not_found | 404 | 找不到摘要模板(builtin mode) | 確認 template 正確 |
sse_transcript_not_found | 404 | 找不到逐字稿 | 錄音可能尚未處理完成 |
summary_text_empty | 400 | 逐字稿沒有可摘要內容 | 錄音內容過短或皆為靜音 |
llm_content_filtered | 400 | LLM 服務內容過濾擋下(custom prompt 或逐字稿含敏感詞) | v1.5.5 SSE 端尚未整合 fallback chain,建議改用 POST /api/v1/summary REST 端點觸發自動降級;或修改 prompt 後重試 |
LLM 服務內容過濾 fallback chain — SSE 端的當前狀態(v1.5.5):
WebSocket realtime 摘要與檔案匯入摘要已在 v1.5.5 整合 L1→L2→L3 fallback chain,被擋時會自動降級產出簡化摘要。但本端點(SSE
regenerate/summary)尚未整合,仍會直接回llm_content_filtered。Follow-up PR 將整合 fallback chain 並擴充
doneevent 加fallback_level/dropped_segments欄位。屆時客戶端可從done.fallback_level判斷是否走了 fallback。在此之前,若你的整合方需要 LLM 服務過濾的自動降級行為,建議透過POST /api/v1/summaryREST 端點觸發。 |summary_text_too_long| 400 | 逐字稿超過長度上限(100,000 字元) | 縮短錄音或拆分檔案 | |summary_invalid_mode| 422 |mode不是builtin/custom| 改為合法 mode | |summary_mode_field_mismatch| 422 | mode 與欄位組合不符(必填缺漏或禁帶被帶入) | 依 mode 規則調整欄位 | |summary_prompt_too_long| 422 |prompt超過 2000 字元 | 縮短 | |summary_prompt_slug_too_long| 422 |promptSlug超過 64 字元 | 縮短 | |summary_prompt_slug_invalid| 422 |promptSlug含控制字元(\n/\r/\t/\0等) | 移除控制字元 | |sse_summary_regeneration_failed| 500 | 摘要重新生成失敗(已 sanitize 內部錯誤,不會洩漏 LLM raw error)| 稍後重試 |
版本:V1.5.7 最後更新:2026-05-20