動作
Bug #397
進行中
SC
修正 Direct-Map 實測缺陷:兩段式即時出碼、覆蓋率補漏 1,987 組、手部側別遺失
Bug #397:
修正 Direct-Map 實測缺陷:兩段式即時出碼、覆蓋率補漏 1,987 組、手部側別遺失
狀態:
New
優先權:
Normal
被分派者:
-
開始日期:
2026-08-01
完成日期:
完成比例:
0%
預估工時:
概述
Direct-Map 實測回饋修正輪(v0.6.2)¶
背景¶
票 A–D 上線後,實際在畫面上操作時陸續發現一批缺陷。共通症狀是「明明在圖上點了,卻還要等 AI,而且 AI 還會亂加碼」,與 Direct-Map 的設計目的相違。本票把這輪實測抓到的問題一次收斂,並針對每一個根因加上護欄,避免同類問題再犯。
實測回報的問題:
- 表定的確定碼要等 AI 跑完(~3.3 秒)才一起出現
- AI 會把已由表定出碼的傷再編一次,且給出不同且較差的碼
(表定「肩鎖關節脫臼」S43.102A,AI 另出肩關節脫臼S43.005A) - 檢視頁的中文描述欄空白、英文欄夾雜中文
-
Head: 2nd degree burn查不到表 → 落給 AI 猜 - 骨盆/髖特寫、特寫圖「未指定」按鈕的傷情查不到表(84 + 7 個部位)
- 純點選、沒有任何備註的病歷,仍會呼叫 AI
-
右手閉鎖性骨折被編成
S62.90XA「未明示側性」(ICD 明明有右側碼S62.91XA) - 兩張圖上的「ICD-10 快查」仍是全 AI,沒有享受到查表直出
變更內容¶
1 兩段式出碼 + 純點選跳過 AI¶
-
/predict_icd10新增table_only:只查對照表、完全不呼叫 LLM - 前端先打
table_only立即渲染確定碼,第二段才跑 AI(實測 0.1s vs 3.3s) - 若
leftover為空且無自由文字(機轉描述/傷情備註)→ 第二段直接不發,畫面顯示「全部傷情皆由圖上標記直接對應,未使用 AI」 - lifespan 加
directmap.warmup()預載對照表與 73,681 筆碼描述
2 快查也走兩段式(本輪新增)¶
- 新檔
frontend/src/lib/icd-extract.ts:兩段式邏輯抽成共用函式 - 三個呼叫點(檢視頁籤、軟組織快查、骨骼快查)共用同一份實作,避免其中一處改了另外兩處沒跟上
- 兩張圖的「ICD-10」按鈕:秒開視窗顯示確定碼,只有需要時才跑 AI
3 AI 不再重複編碼(三道防線)¶
- Stage 1 prompt 附「ALREADY CODED — DO NOT OUTPUT」清單(治本:LLM 直接不抽該傷,也更快)
-
_matches_resolved補中文詞段比對(表單選項是中文,AI 原樣抄回時英文詞比對會漏)+ 字首 5 碼容忍humerus↔humeral - 端點碼級去重(首選碼已由表定出過 → 整條丟棄);legacy pipeline 同步套用
4 燒傷標籤正規化¶
- backend 自行正規化(認得
2nd degree burn/Burn 2nd/second…) - 只寫
Burn未選程度 → 出 ICD 未指定程度碼,不讓 AI 猜(soft 表新增Burn-unspec組)
5 描述欄修正¶
-
_icd_desc()由name_zh把「英文 中文」合併欄拆回兩欄 - 檢視頁加「確定」綠徽章
6 覆蓋率窮舉稽核(新測試 directmap_coverage_audit.py)¶
直接讀前端原始碼枚舉「兩張圖所有部位 × 所有 UI 傷情選項」全跑 resolver。
-
第一輪抓到 84 組未出碼:
PELVIS_HIP_ZONES宣告在SoftTissueTab.tsx而非BodySvgPaths,產生器只掃後者 → 骨盆/髖特寫從未進表;另補手足整體骨、骨盆未指定側、髖部燒傷落T24.x0x -
第二輪抓到 7 個動態虛擬部位:特寫圖「未指定」按鈕由
makeUnspecifiedPart()產生,不在任何 zone 陣列裡 → 這正是「Pelvis (Unspecified) 燒傷」落給 AI、進而冒出右前胸壁擦傷/女性生殖器燒傷/陰莖裂傷的根因 - 結果:1,987 / 1,987 組全部出碼
7 手部側別遺失 + 根因護欄¶
-
hand_bones修正為分側:右S62.91XA/ 左S62.92XA(開放版…B同步) - 根因:第一輪補建時比照掌骨/指骨標成不分側,但那兩者是 ICD 本身沒有側別碼,手部整體不是
-
產生器新增「側別稽核 2」:無側別列把命中碼描述裡的每個
unspecified逐一換成right,查得到字面相同的碼就報錯;白名單僅限已審核的中線構造(胸骨/薦骨/骨盆)與 ICD 本身無側碼者(掌骨/指骨) - 同規則寫進
directmap_assert.py(13b / 13c),兩道擋
護欄自身踩過坑:比對索引一開始用整個
description欄,但該欄是「英文 + 中文」合併字串,精確比對永遠不命中 → 回報 0 筆是假綠。改成只取英文段後,用已知壞案S62.90XA反測確實抓得到S62.91XA,才確認有效。新增稽核必須先用已知壞案反測。
驗收標準¶
| 項目 | 結果 |
|---|---|
| smoke_test(含新增 7.0b/7.0c) | 53 PASS / 0 FAIL |
對照表斷言 directmap_assert.py
|
38 PASS(新增 13b/13c) |
resolver 單元 directmap_resolver_test.py
|
28 PASS |
覆蓋率稽核 directmap_coverage_audit.py
|
1,987 / 1,987 出碼 |
| 快查兩段式 e2e | 7 PASS |
| AI-skip e2e / 兩段式 UI e2e | 7 PASS / 7 PASS |
| 票 C/D e2e、關節 e2e | 13 PASS / 14 PASS |
| typecheck / lint | 乾淨(僅既有 warning) |
實測驗證(使用者回報案例):
- 「Chest 擦傷 + Abdomen 挫傷 + Pelvis(未指定)二度燒傷 + 右髖挫傷 + 恥骨裂傷」→ 6 碼全確定、
leftover為空、AI 完全不跑 - 「Right Hand: Closed fracture」→
S62.91XA右側腕及手部骨折
測試維護規約¶
-
smoke_test.py新增 7.0b(table_only查表段不跑 LLM、leftover 為空)與 7.0c(右手骨折須出右側碼) -
directmap_coverage_audit.py列為前端圖層/傷情選項變更時的必跑項目 - 表或產生器變更 →
directmap_assert.py須同票更新並全 PASS
版本¶
v0.6.1 → v0.6.2(CHANGELOG 已補;變更皆為使用者可感知:即時出碼、未使用 AI 提示、快查加速、手部側別修正)
沒有任何資料可供顯示
動作