動作
Feature #325
進行中
SC
ICD-10 快查品質大改造:SapBERT 醫學模型 + L1 檢索強化 + autocomplete + 章節相關性排序(90/90 benchmark)
Feature #325:
ICD-10 快查品質大改造:SapBERT 醫學模型 + L1 檢索強化 + autocomplete + 章節相關性排序(90/90 benchmark)
狀態:
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_EMBEDprofile 機制(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.py、build_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,.env設ICD_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。
沒有任何資料可供顯示
動作