專案

一般

配置概況

動作

Feature #325

進行中
SC

ICD-10 快查品質大改造:SapBERT 醫學模型 + L1 檢索強化 + autocomplete + 章節相關性排序(90/90 benchmark)

Feature #325: ICD-10 快查品質大改造:SapBERT 醫學模型 + L1 檢索強化 + autocomplete + 章節相關性排序(90/90 benchmark)

是由 Sashiba Chou28 天 前加入.

狀態:
New
優先權:
Normal
被分派者:
-
開始日期:
2026-07-04
完成日期:
完成比例:

0%

預估工時:

概述

ICD-10 快查品質大改造:SapBERT 醫學模型 + L1 混合檢索強化 + autocomplete + 章節相關性排序(90/90 benchmark)

背景

#318(向量庫 cosine 重建 + L1 字面比對)。實測仍有兩層準確度缺口:① 通用多語模型 MiniLM 對醫學單字表徵弱(epistaxis 被拼字相近的 Epididymitis 壓過);② 快查缺臨床相關性排序,病史/家族史(Z 章)、周產期(P 章)、病理性骨折(M 章)洗版正解。本 ticket 系統性補齊,並建立快查專屬回歸 benchmark 作為「只升不降」關卡。

變更內容

1. Embedding 升級 SapBERT(醫學特化,env 可秒退)

  • rag_service.py 導入 ICD_EMBED profile 機制(minilm | sapbert),model 與 collection 綁成 profile 成對切換。切換/回滾 = .env 改一行重啟,兩套向量庫並存不需重建。
  • SapBERT(cambridgeltl/SapBERT-UMLS-2020AB-all-lang-from-XLMR,CLS pooling,cosine+normalize)。快查與外傷 faceted 雙軌各建獨立 collection(icd10_codes_sapbert / icd10_codes_faceted_sapbert),GPU 重建腳本 build_sapbert_collection.pybuild_faceted_sapbert.py
  • 純向量層 benchmark(1,100 案例):exact@5 11.4%→17.1%、MRR 0.068→0.115(+69%);外傷 faceted E2E 24/24 無退步。

2. L1 混合檢索強化(main.py)

  • 詞幹化(對稱 s/es/ed/ing/e 去尾):複數/時態可命中(abrasions→abrasion、fractured→fracture)。
  • 兩層命中:tier 0 全詞命中;tier 1 恰缺 1 詞(≥3 詞查詢才啟用),救「deep laceration…」多修飾詞、展開詞過嚴。
  • A4 修正不破壞:typo 修正改為「修正字 + 原字」雙 variant 合併 —— 修正猜錯時(empyema 不再被改成 emphysema/肺氣腫)原字結果仍在;raw fallback 只回收不確定的 typo 修正、保留高信心縮寫展開(AGE 不退回噪音字 age)。前端加「改用原字搜尋」逃生按鈕。

3. 章節相關性排序(臨床先驗)

  • _rank_penalty:Z 章(病史/家族史/狀態)大幅降權;P 章(周產期/新生兒)降權,兒童急診使用者可於設定保留(keep_perinatal,前端偏好開關);M 章骨折碼(壓力/病理性)僅在「查詢帶骨折意圖」時降權讓外傷性 S 章勝出(關節炎等非骨折 M 碼不受影響);unspecified/未明示 通用碼於字面層加分(語意層不套,避免不相關 unspecified 壓過近距離正解)。

4. Autocomplete 打字即建議(main.py + 前端)

  • GET /suggest:純字面比對(縮寫/俗名字典 + 英文詞前綴 + 中文子字串 + 代碼前綴),毫秒級,不走向量/LLM。初次就診碼優先。
  • 前端 combobox:方向鍵/Enter/滑鼠選取、中文輸入法 composition 防抖、debounce 150ms、請求可中止。選建議即答案(方案 A),底層仍保留語意查詢當後盾。修正:Enter/選取後取消 pending debounce,下拉確實關閉不擋結果。

5. 縮寫/俗名字典校準(medical_terms.py)

  • 移除本院不使用:szr / cap / t1dm / t2dm / disloc
  • 新增/修正:HIVD→椎間盤突出(防誤改 HIV)empyema→pyothorax(防誤改 emphysema)HF+intoxication→氫氟酸GB / GBS / MG / PPH / TTP / OHSS / PAOD / PPU / Af / afl / stroke / 中風 / anaphylaxis / AGE
  • 片語展開加冪等保護(empyema 不再重複展開)。

6. 快查回歸 benchmark(表二)

  • run_lookup_benchmark.py + lookup_benchmark.json(90 案例:回報回歸、typo 陷阱、縮寫、中英主訴、代碼前綴;含 forbid 反例一票否決)。改動前後對照為 ship 關卡。

Benchmark 結果(90 案例)

指標 改動前 本次
Pass 84.4% 100% (90/90)
MRR 0.756 0.911
Forbid 違規 1 0
平均延遲 7.9s 2.1s

驗收標準

  • 快查 benchmark 90/90 全過、forbid 0(python backend/tests/run_lookup_benchmark.py)。
  • epistaxis/abrasion/丹毒/鼻出血 正解置頂;骨折/fractured femur 不再被 M 章病理性骨折污染;stroke/中風/pneumonia/糖尿病 不被 Z 章家族史洗版。
  • empyema 不再被改成肺氣腫;AGE→A09/K52;HF intoxication→T59.5 氫氟酸。
  • Autocomplete 打字浮現建議,Enter 後下拉關閉不擋結果;中文輸入法組字不誤觸發。
  • 兒童急診設定開啟後 新生兒 查詢 P 章碼浮現;預設關閉時降權。
  • 前端 tsc --noEmit 零錯誤;外傷 faceted pipeline E2E 24/24 無退步。

部署注意

  • 切換 SapBERT 需成對更新程式碼與向量庫:部署機(有 GPU)裝 CUDA 版 torch + sentencepiece + tiktoken,.envICD_EMBED=sapbert,並複製或重建 icd10_codes_sapbert / icd10_codes_faceted_sapbert 兩個 collection(GPU 約數分鐘;或整包複製 chroma_db/)。首次啟動會下載 SapBERT 模型 ~1.1GB(可連 HF 快取一起複製以離線部署)。
  • 回滾:.env 改回 ICD_EMBED=minilm 重啟即退(MiniLM 兩套向量庫原封保留)。

後續(另案)

  • A1 複製行為記錄(隱性相關性標註,餵未來排序)。
  • 中文多型別疾病(如「糖尿病」E10/E11 因描述以「第X型」開頭落 tier-1)排序待 A1 數據優化。
  • 外傷 pipeline B 區塊(Stage1 點名比對、per-injury 排序、facet 標籤掃描、外因碼)另開 ticket。

沒有任何資料可供顯示

動作

匯出至 PDF Atom