REST API 規格摘要
基底路徑為伺服器根目錄(例:http://localhost:8000)。所有 JSON 回應均為 application/json。
1. POST 端到端產生 ai-draft.json
| Path | /api/v1/ai-draft |
| Content-Type | multipart/form-data |
| audio_file | (必填)錄音檔。可用同名欄位重複上傳多段音檔,副檔名:.mp3 .wav .m4a .webm .ogg,每個檔案後端應用層上限 50 MB。 |
| meta_file | (必填)錄音檔 meta.json 或個案 JSON。若含 patient_name、caseName 或 base_data.caseName,糾錯階段會以 AI 保守修正病患姓名誤聽;日期參考時間依序採 started_at_epoch_ms、ended_at_epoch_ms、uploaded_at_epoch_ms。 |
| history_file | (必填)單一 history.json。端點會和本次逐字稿融合產生歷史輔助提示、照護計畫評值;若包含新版 body_assessment[].sections,會優先作為權威身評 baseline,舊版 baseline 與 snapshots 僅在缺少新版身評時回退使用。 |
| stt_model / llm_model | (選填)模型 ID;留空使用後端預設。 |
| exclude_visit_date | (選填)YYYY-MM-DD,排除 history 文字內指定日期訪視內容。 |
回應
| 檔名 | 回應 header 會帶 Content-Disposition: attachment; filename="ai-draft.json" |
| schema_version | 固定回 ai_output_contract_v1 |
| visit_info / body / vital_signs | 依 contract v1 輸出三態葉節點:value / this_visit / source,必要時含 snippet / confidence / multiple_values |
| care_plan_evaluations | 照護計畫評值建議;plan_id 僅能來自本次 history 的候選計畫,配不到則為 null。confidence 為 0.0-0.95 的校準分數,會依 plan match 方法、score 與評值證據調整,不再以 1.0/0.0 二元表示。 |
| narrative_for_mohw | 單一字串的訪視摘要 seed,可供護理師校稿後寫入 |
| suggested_visit_date | 選填的 display-only seed。只有逐字稿明確說出完整年月日時才回傳 YYYY-MM-DD;只有月日、相對時間詞(如「今天」「昨天」「上週三」)或未提日期時整欄省略,不以錄音時間、請求時間、history 或模型值補填。 |
| _soapie_reasoning | 固定包含 S / O / A / P / I / E 六個字串欄位。各欄優先採 history 融合後的 suggested_soapie,缺漏時回退至本次 LLM 結構化萃取的 record.soapie,兩者皆無則回空字串;屬 review metadata,不得當成正式上傳欄位。 |
| review-aid 欄位 | missing_or_uncertain / suggested_record_focus / low_confidence / corrected_transcript / transcript 為 display-only,不屬於上傳資料 |
| _identity_not_from_ai | 宣告身分、日期與時段實值不是由 AI 自產 |
| _meta | 底線 metadata;含 api_version、模型與耗時、visit_date_reference_source(recording_started_at / recording_ended_at / recording_uploaded_at / current_time)、visit_date_reference_date 及 decision_trace。decision_trace.body.excretion.urine_aid_enum 會記錄 LLM 抽取、逐字稿證據、baseline 與最終 provenance;baseline 軌跡另含資料來源、選中日期、原始明細欄名與數量。此區僅供除錯,消費端不得當成正式上傳欄位。 |
curl -X POST "http://localhost:8000/api/v1/ai-draft" \
-F "audio_file=@part1.m4a" \
-F "audio_file=@part2.m4a" \
-F "meta_file=@recording.meta.json" \
-F "history_file=@history.json" \
-F "stt_model=gemini-3.5-flash" \
-F "llm_model=gemini-3.5-flash" \
-o ai-draft.json
history.json 支援欄位
plans[] | 照護計畫候選來源。支援標準鍵 category / problem / goal / measures / is_active,也支援匯出別名 type / item / note / goal_text / measures_table.rows / is_active: "Y"|"N"。 |
body_assessment[] | schema 1.4.0 以上的權威身評 baseline。取 vdate 最新一筆的 sections;若同時存在舊 baseline 或 body_assessment_snapshots[],仍以此欄為準。 |
body_assessment_snapshots[] | 舊版相容 baseline。只有 history 未提供有效 body_assessment[].sections 時才會使用。 |
| 沿用規則 | 本次逐字稿有評到的 leaf 會維持 source: visit 或依連動證據標 inferred;本次未評但權威 baseline 有非空值才輸出 source: carried、this_visit: false;兩者都沒有才輸出 not_evaluated。 |
複選欄 wire 表示
以下規則依 vendor 2026-08-01 回覆中的 contract v1.2.0 草案實作;正式 v1.2.0 交付包仍待對方核可提供。
| 甲類(8 欄) | oral.appearance_enum、oral.special_feeding_enum、oral.dentures_enum、excretion.stool_aid_enum、excretion.urine_pattern_enum、excretion.urine_aid_enum、fall.fall_main_enum、sleep.main_enum。value 放主答,multiple_values 放明細。 |
| 乙類(7 欄) | vision.location_multi、vision.aids_multi、hearing.location_multi、hearing.aids_multi、muscle.aids_multi、behavior.main_multi、sleep.med_category_multi。只在 value 放依原順序以全形頓號串接的明細,不輸出 multiple_values。 |
| 乙類否定值 | 視力/聽力/肌力的輔具欄使用 無;行為使用 無干擾行為。部位欄與睡眠藥物類別沒有否定選項,不適用時輸出 value: null、source: not_evaluated。 |
| carried 安全閥 | 只有肯定主答但缺少明細,或遇到 右(重聽、失聰) 等不可還原的早期部位摘要時,不猜測、不標 carried;改回 not_evaluated。合法 carried 的值、順序與空白必須和正規化 baseline 完全一致。 |
| 呼吸器材細項 | respiratory.aid_type / aid_type_other / nasal_cannula / nasal_cannula_lpm / face_mask / face_mask_lpm 不從 history 沿用,且一律不得標記 carried。本次有明確證據時使用 visit 或 inferred;未評估時輸出 value: null / source: not_evaluated。只有 respiratory.aux 可依一般規則沿用。 |
| 尿套 | excretion.urine_aid_enum 的本次尿套使用會輸出 value: "有"、multiple_values: ["其他"]。現行 contract 沒有排尿輔助的其他說明欄,故不額外輸出未定義欄位。 |
2. POST 從逐字稿產生 ai-draft.json
| Path | /api/v1/ai-draft/from-transcript |
| Content-Type | multipart/form-data |
| transcript | (必填)本次訪視逐字稿,建議使用已校稿或 STT 糾錯後全文。 |
| history_file | (必填)單一 history.json。支援欄位同上:plans[] 作為照護計畫候選,優先以 body_assessment[].sections 作為身評 baseline,舊版欄位僅作相容回退。 |
| llm_model | (選填)LLM 模型 ID;留空使用後端預設。 |
| exclude_visit_date | (選填)YYYY-MM-DD,排除 history 文字內指定日期訪視內容。 |
回應
回應格式與 /api/v1/ai-draft 相同,固定為 schema_version: ai_output_contract_v1。此端點只跳過錄音檔上傳、STT 與姓名糾錯,仍會執行 LLM 結構化與 history 融合。沒有錄音 metadata 時,_meta.visit_date_reference_source 仍會記錄 current_time 供除錯,但不會用來填補 suggested_visit_date。
curl -X POST "http://localhost:8000/api/v1/ai-draft/from-transcript" \
-F "transcript=本次訪視逐字稿內容..." \
-F "history_file=@history.json" \
-F "llm_model=gemini-3.5-flash" \
-o ai-draft.json
3. POST 一鍵分析護理語音
| Path | /api/v1/nursing-record/analyze |
| Content-Type | multipart/form-data |
| audio_file | (必填)音檔。副檔名:.mp3 .wav .m4a .webm .ogg,後端應用層上限 50 MB。 |
| meta_file | (選填)錄音同名 .meta.json 或個案 JSON。若含 patient_name、caseName 或 base_data.caseName,糾錯階段會以 AI 保守修正病患姓名誤聽;例如 洪秋菊 / 純換管 會取主要姓名 洪秋菊。日期參考時間依序採 started_at_epoch_ms、ended_at_epoch_ms、uploaded_at_epoch_ms,皆無時使用目前台北時間。 |
| stt_model | (選填)STT 模型 ID,如 gemini-3.5-flash、gemini-2.5-flash;留空使用預設 gemini-3.5-flash。 |
| llm_model | (選填)LLM 模型 ID,如 gemini-3.5-flash、gemini-2.5-flash、gemma-4-26b-a4b-it、gemma-4-31b-it、gemma-4-12b;留空使用預設 gemini-3.5-flash。其中 gemma-4-12b 走專案內文檔對應的 Public API(OpenAI-compatible Chat Completions)。 |
回應欄位
| visit_info / modules / soapie | 結構化護理紀錄 |
| warnings / changes / low_confidence | 字串陣列 |
| transcript | STT 原始逐字稿;後端會統一正規化為繁體中文 |
| visit_info | 訪視資訊;含 date / visit_start_time / visit_end_time。date 固定為完整 YYYY-MM-DD:明確年份以逐字稿為準,只有月日時依參考日取距離最近年份,未提日期則使用參考日。 |
| corrected_transcript | 醫療字典糾錯後全文;無實際糾錯時為 null |
| correction_segments | 高亮分段:plain / replaced |
| corrections | 替換項目:from, to, span, reason,並保留相容欄位 original, corrected, count |
| schema_version | 目前為 2.2 |
| body_assessment / vital_signs | v2.2 structured scaffold,每個 sub-field 含 value / evaluated / source_snippet;R7 12 題 body enum 已正規化,multi 欄位另含 multiple_values |
| missing_or_uncertain | 與舊 warnings 同步,供後續統一命名 |
| _meta | 效能資訊與日期參考:stt_model, stt_elapsed_ms, correction_status, correction_elapsed_ms, llm_model, llm_elapsed_ms, total_elapsed_ms, audio_duration_sec, enum_normalization, visit_date_reference_source, visit_date_reference_date |
curl -X POST "http://localhost:8000/api/v1/nursing-record/analyze" \
-F "audio_file=@sample.wav" \
-F "meta_file=@sample.meta.json" \
-F "stt_model=gemini-3.5-flash" \
-F "llm_model=gemini-3.5-flash"
4. POST 語音轉文字 (STT)
| Path | /api/v1/stt/transcribe |
| Content-Type | multipart/form-data |
| audio_file | (必填)音檔。可用同名欄位重複上傳多段音檔,副檔名:.mp3 .wav .m4a .webm .ogg;後端應用層上限 50 MB。 |
| model | (選填)STT 模型 ID;可用 gemini-3.5-flash、gemini-3-flash-preview、gemini-2.5-flash、gemini-2.5-flash-lite、gemini-2.5-pro |
回應
| transcript | 逐字稿文字;後端會統一正規化為繁體中文 |
| model_used | 實際使用的模型 ID |
| elapsed_ms | 耗時毫秒 |
| segments | 上傳檔案層級的結果;單一 300 秒檔案仍為一個 segment,伺服器內部切段數請看 segments[].chunk_count。 |
| audio_metrics | 成功回應頂層提供所有檔案的彙總值;每個 segment 另提供 duration_ms / voiced_ms / voiced_ratio / rms_dbfs / peak_dbfs。其中 voiced_ms 是 30ms frame 經 WebRTC VAD mode 2 判為 speech 的累計值,不含額外前後 padding。 |
| 無語音 | RMS 與 WebRTC VAD 未偵測到足夠語音時不呼叫模型,回 422、code: audio_no_detectable_speech、retryable: false。 |
| 內容防護 | 「無可辨識語音」回 422 audio_unrecognizable_speech;提示詞回音回 422 stt_prompt_echo_detected,兩者皆不切換模型重試。 |
| 完整性 | 超過 150 秒的音檔會平均切段。只有空白、異常結束或上游暫態錯誤會重試,每段跨模型合計最多兩次;用盡回 502 stt_incomplete_after_retries、retryable: true,表示相同請求稍後重送仍可能成功。 |
| completed_audio_ms | 代表 ffprobe 量得並送入處理的檔案/切段總長;不是模型實際成功辨識的時間戳覆蓋長度,不能用來判斷局部截斷。 |
curl -X POST "http://localhost:8000/api/v1/stt/transcribe" \
-F "audio_file=@part1.m4a" \
-F "audio_file=@part2.m4a" \
-F "model=gemini-3.5-flash"
4. POST 醫療名詞糾錯
| Path | /api/v1/correction/apply |
| Content-Type | application/json |
| Body | text 必填;後端會先套用本地醫療字典,再用 AI 保守修正明顯錯字、STT 誤聽與醫學專有名詞。patient_name 或 meta 選填;若兩者都提供,優先使用 patient_name。meta 是 request body 裡的 JSON object,可放 patient_name、caseName、base_data.caseName、patient.name 等姓名欄位。 |
Body 欄位
| text | 必填。原始 STT 逐字稿。 |
| patient_name | 選填。正確病患姓名;例如 廖振景。若含 /、/、| 或括號備註,後端會取主要姓名。 |
| meta | 選填。JSON object,不是檔案上傳。可直接放個案 meta,後端會依序尋找 patient_name、caseName、base_data.caseName、patient.name 等欄位。 |
| model | 選填。AI 醫療校稿與姓名糾錯使用的 LLM 模型 ID;留空使用後端預設。 |
回應
| corrected_text | 糾錯後全文 |
| corrections | 替換項目陣列,每筆含 from / to / span / reason |
| correction_segments | 高亮分段 |
| ai_text_correction | AI 醫療逐字稿校稿狀態、使用模型、修正數量與錯誤訊息;AI 失敗時不阻斷本地字典糾錯。 |
| patient_name_correction | 若有提供姓名,回傳姓名糾錯狀態、主要姓名、模型與修正數量;AI 失敗時不阻斷本地醫療字典糾錯。 |
| elapsed_ms | 耗時毫秒 |
curl -X POST "http://localhost:8000/api/v1/correction/apply" \
-H "Content-Type: application/json" \
-d '{"text":"個案廖曾謹,訪視日期是6月3號。","patient_name":"廖振景","model":"gemini-3.5-flash"}'
若姓名在個案 JSON 裡,請把它放在 body 的 meta 欄位:
curl -X POST "http://localhost:8000/api/v1/correction/apply" \
-H "Content-Type: application/json" \
-d '{
"text": "個案廖曾謹,訪視日期是6月3號。",
"meta": {
"base_data": {
"caseName": "廖振景",
"caseID": "P201600198"
}
},
"model": "gemini-3.5-flash"
}'
5. POST LLM 結構化萃取
| Path | /api/v1/llm/structure |
| Content-Type | application/json |
| Body | { "text": "糾錯後逐字稿", "model": "(選填) 模型 ID" } |
回應
| record | 結構化護理紀錄 JSON(含 visit_info、modules、soapie、warnings 等) |
| model_used | 實際使用的模型 ID |
| elapsed_ms | 耗時毫秒 |
curl -X POST "http://localhost:8000/api/v1/llm/structure" \
-H "Content-Type: application/json" \
-d '{"text":"患者 NG tube 已更換,SpO2 正常","model":"gemini-3.5-flash"}'
6. POST 歷史紀錄輔助提示
| Path | /api/v1/history/brief |
| Content-Type | multipart/form-data |
| history_files | (必填,可多檔)病患歷史紀錄。支援 .html .htm .txt .md .json .csv .dat |
| transcript | (必填)本次 STT 逐字稿,建議使用糾錯後全文 |
| model | (選填)LLM 模型 ID;留空使用預設 |
| exclude_visit_date | (選填)YYYY-MM-DD,從歷史 HTML 排除該日期訪視卡片,避免融合本次紀錄 |
回應
| insight.patient_baseline | 歷史可沿用的個案基線 |
| insight.current_visit_updates | 本次逐字稿提到的新狀況與處置 |
| insight.changes_from_history | 相較歷史紀錄的變化 |
| insight.suggested_record_focus | 本次紀錄建議補入的條列重點 |
| insight.care_plan_evaluations | 依歷史照護計畫分類、目標與措施,自動產生本次評值建議;每筆含 plan_id / plan_status / plan_match / evaluated / source_snippet |
| insight.missing_or_uncertain | 需人工確認的缺漏、矛盾或低信心資訊 |
| insight.risk_alerts | 風險提醒 |
| insight.suggested_soapie | SOAPIE 草稿 |
| insight.suggested_soapie_summary | SOAPIE 草稿整合後的一段式訪視摘要,硬上限 1000 字;資料充分時以 700–950 字為目標,資料不足時可較短且不得補寫未提及內容 |
| schema_version / _meta | v2.2 schema 標記、歷史過濾狀態、候選照護計畫數、模型與耗時 |
| history_files / input_chars | 解析檔案與輸入字數資訊 |
curl -X POST "http://localhost:8000/api/v1/history/brief" \
-F "history_files=@P201715443.html" \
-F "transcript=今日訪視個案..." \
-F "model=gemini-3.5-flash" \
-F "exclude_visit_date=2026-05-11"
7. POST LINE 家屬訊息摘要
| Path | /api/v1/llm/line-family-summary |
| Content-Type | application/json |
| Body | { "text": "護理口述逐字稿", "model": "(選填) LLM 模型 ID" } |
回應
| message | 適合貼在 LINE 群組給家屬的繁體中文訊息本文 |
| model_used | 實際使用的模型 ID |
| elapsed_ms | 耗時毫秒 |
curl -X POST "http://localhost:8000/api/v1/llm/line-family-summary" \
-H "Content-Type: application/json" \
-d '{"text":"今日訪視個案意識清楚,SpO2 95% 鼻導管 2L…","model":"gemini-3.5-flash"}'
8. POST 家屬訊息語音合成 (TTS)
| Path | /api/v1/tts/line-family-speech |
| Content-Type | application/json |
| text | (必填)要朗讀的家屬訊息全文 |
| model | (選填)TTS 模型 ID,如 gemini-2.5-flash-preview-tts;留空使用後端預設 |
| voice_name | (選填)預建語音名稱,預設 Kore |
| language_code | (選填)預設 zh-TW |
回應
| audio_base64 | 音訊二進位之標準 Base64 |
| mime_type | 例如 audio/mpeg |
| truncated | 若文字過長已截斷則為 true |
| model_used | 實際使用的 TTS 模型 ID |
| elapsed_ms | 耗時毫秒 |
curl -X POST "http://localhost:8000/api/v1/tts/line-family-speech" \
-H "Content-Type: application/json" \
-d '{"text":"家屬您好,今日訪視時長輩精神穩定…","model":"gemini-2.5-flash-preview-tts"}'
9. GET 可選模型清單
| Path | /api/v1/system/available-models |
| 回應 | stt_models、stt_default、llm_models、llm_default、tts_models、tts_default |
curl "http://localhost:8000/api/v1/system/available-models"
10. GET 醫療糾錯字典
| Path | /api/v1/system/mapping-dictionary |
| 回應 | mapping(鍵→值對照)、count |
curl "http://localhost:8000/api/v1/system/mapping-dictionary"
錯誤回應
HTTP 4xx / 5xx 時,FastAPI 預設為 JSON:{"detail": "…"} 或驗證錯誤時為陣列結構。請以實際 /docs 試打為準。