- 25 May, 2026 7 commits
-
-
路遥 case(N=4 chains): 改前:K01 智齿拔除 / K08 种植 因 EMR.plan 有医生计划 → status=entered(误) 改后:status=discovered(正确)— 患者未预约/付款/到诊 plannedHint 仍展示 "延期种植术 · 已开计划(待执行)" 给客服暗示 W2/W3 旧版用 planned treatment 当 S2 fallback,跟 collectS2Facts 顶部注释 "医生侧动作 ≠ 患者承诺" 自相矛盾。W4 末彻底清理。 S2 真信号(只 1 路): appointment.complaint_category 匹配 → 患者主动预约(挂号/约时间/到店) planned treatment 信息没浪费: - 不进 s2Hits(不升 status=entered) - 在 S2 node 渲染时作为 plannedHint 展示 "已开计划(待执行)" + done=false - 客服看到"医生计划是 XX 但患者还没动" — 仍属召回目标 副作用预期: - 召回率会上升(之前误升 entered 的现在回 discovered,被召回) - 准确率上升(真没动作的患者被正确召回) 新加 helper:findPlannedTreatmentHint(category, byType, s1AnchorTime) 从 byType.treatment 找同 category 的 planned(s1 之后,最早一条)— 纯展示用 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
路遥 case: K05 全口牙周 + actual 牙周刮治术全口 26 牙 另有 K08 21;41 + planned 延期种植 21;41 → 之前:牙周链被"种植修复·21;41" alt-close → 显示"
✅ 已闭环",且 S3 显示"0/3 步骤" → 修后:牙周链保持 ongoing 维护期(终身),S3 "牙周刮治 · 1/3" 修 2 处: 1. chain-composer.markAlternativeClosed 加 2 个豁免: - lifelong_maintenance(periodontic 等 maxStage=4)→ 永不被替代闭环 (慢性病终身维护,做种植 21;41 不代表整体牙周不需要继续治疗) - wholeMouth(牙位 ≥ 20 颗 视为全口)→ 不被 per-tooth 链替代 (全口治疗 vs 局部种植 临床上是"维护 + 局部",不是替代) 2. canonical-codes.periodontic milestone steps: ['全口洁治','龈下刮治','牙周维护'] → ['洁治','刮治','维护'] 旧版全词匹配导致"牙周刮治术" 命中 0/3,改"词根"匹配后 1/3 ✓ 不需要重导数据(chain-composer 实时算);只需重启 pac-service。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
js-yaml strict mode 不允许 duplicate key,cold-import 时报错: treatment_actual.yaml:272 'OHI,涂氟' 重复(连续两行同 key 同值) treatment_planned.yaml:266-267 'OHI,涂氟'(中逗号)+ 'OHI,涂氟'(英逗号) 共存 normalize op 上线后 DW 中文逗号版自动归一到英文版,中逗号 yaml 条目变 dead config。 删掉 dup / dead,留唯一 'OHI,涂氟' → preventive。 100 患者验证:cold-import success patients=100 txns=0 dups=10235 facts(c=0 u=9810) (数据全部 unchanged,因 source_event_id 幂等,只刷新 fact metadata) 召回:18 plans(瑞泰 13 + 瑞尔 5),持平 / 略降于改前 23 plans — EMR 单源 actual 让排除更准(真治疗才算覆盖),净效应略降但更精确。
luoqi committed -
之前 ⑤a 排除是 patient + category 级("DW 限制" 注释); EMR.treat_plan 进来后 actual 带牙位,可以升级到 tooth-level overlap。 逻辑(3 路 OR): ① 信号无牙位(K05 全口诊断)→ 仍 patient/category 级 ② actual 无牙位(全口洁治/牙周治疗)→ 视为"全口覆盖"→ 仍排除 ③ 双方都有牙位 → tooth array overlap(PG && 操作符) 实现细节: - regexp_replace 把"15 B;24 B"非数字非分号字符替换为 ; → "15;24" - string_to_array + array_remove '' 去空元素(关键:两 array 都有 '' 时 '' = '' 误返 true) - PG && 任一元素相同即 overlap 收益例子: - 罗国标 K04 14;15 + actual endodontic 36 → tooth overlap false → 正确召回 14;15 - 之前 patient/category 级会被误排除 向下兼容:48.7% actual 带牙位 → 这部分走 tooth-level 精筛; 其余 52% actual 无牙位(全口治疗)→ 走 ② 分支,跟现状一致(全口覆盖)。 不需要重导(SQL 改动,数据不动);下次 recompute-plans 立刻生效。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
背景: DW top 200 treatName 实测,treatment 字典覆盖率仅 74%(15.8% 漏配 _default skip)。 3 大根因: ① 中英文标点不一致(yaml 写英文,DW 实际中文)— 50%+ 漏配 ② review/recommendation route 关键词不全 — 已交付纸质病历/转诊等流程性误吃 actual ③ 真治疗新词漏配 — 牙周序列治疗/桩冠修复/根管治疗后冠修复 等 修复(原则:代码跟宿主无关,宿主个性化只在 yaml): 1. transforms.derive 加 op=normalize(trim 升级版 + CJK→ASCII 中段标点) - 中括号 ()→ () | 中逗号 , → , | 中分号 ; → ; - 中冒号 : → : | 中尖括号 <> → < > | 中百分号 % → % - 顿号 、 → ,(语义等价分隔符) - 任何中文宿主通用,不是 jvs-dw 特化 — 进 transforms(通用层),不进 yaml(宿主层) 2. manifest: - § C 加 normalize derive on treat_name(treat_plan + plan 两路 in-place 覆盖) - § B.1 diagnosis message 从 trim 升级到 normalize - § C.3 review route 关键词补 ~22 项(正畸复诊/检查/咨询/会诊/复查/转诊/已交付病历/缴费等) - § C.4 plan 字段 review drop 也同步补 3. treatment_actual.yaml + treatment_planned.yaml 同步补 ~15 个新词: periodontic: 牙周序列治疗 / 系统性牙周治疗 / 全口洁治+OHI / 龈上洁治术/.../洁牙/洗牙 endodontic: 根管治疗后冠修复 / RCT+冠修复 implant: 拔除后种植 prosthodontic: 桩冠修复 restorative: 树脂充填术 orthodontic: 更换新矫治器 / 粘接上半口矫治器 / 粘接全口附件 / 精调粘接附件 / 发放新矫治器 / 去除矫正器,配戴保持器保持现有咬合关系 清理 1 个中文顿号 dead key("全口龈上洁治、抛光。" → normalize 后自动落到现有 ASCII 字典) 4. diagnosis.yaml 补 2 个高频: K05 菌斑性牙龈炎(928 hits;yaml 原有"菌斑性龈炎"长写变体) K02 深窝沟(7613 hits;早期龋兆,临床归 K02) 实测覆盖率(DW top 200,512K rows): treatment_actual: 74.0% → 99.9% (mapping 85.5 + review 11.7 + rec 2.6) 漏配从 80,879 → 598 行(剩 1 条长文本"拟涂氟知情同意"无业务价值) diagnosis: 87.1% → 90.5% 剩漏配 95% 是故意 drop(乳牙列/混合牙列/种植术后等 Z 类术后状态) 不需要重导(代码先稳定);下次 cold-import 自动生效。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
语义修正背景(真实数据验证): - EMR.treat_plan = 本次实际治疗(actual),字段名误导但语义就是 actual - EMR.plan = 未来计划(planned),2023+ host 启用 - settlement = 财务事件,不是临床事件;颗粒度 1:N、0% 带牙位 改造前: - treat_plan(actual)被当成 planned
❌ - plan 字段完全没消费❌ - settlement 反推 treatment_actual,跟 EMR 双源混叠 改造后: - treat_plan 真治疗 → treatment_actual_rows kind=actual⭐ 带 48.7% 牙位 - plan 真治疗 → treatment_planned_rows kind=planned⭐ 带牙位 - settlement 不再产 treatment_record,职责单一(LTV/退费) 文件改动: - manifest.yaml § C:treat_plan + plan 双源 split + route(MVP:plan 的复查/建议暂 drop) - manifest.yaml § D:删除 settlement → _treatment_actual_raw / treatment_actual_rows 派生 - assemblers/treatment_actual.yaml:source 切到 EMR,字典复用 treatment_planned.yaml 同款(200+ entries) - assemblers/treatment_planned.yaml:仅头部注释更新(源切到 plan 字段) - assemblers/refund.yaml / payment.yaml:不动(settlement 继续走这两路) 不动的下游: - treatment.parser.ts:kind 由 emits.action 决定,yaml 改完自动正确 - chain-composer.service.ts / treatment-initiation-recall.scenario.ts:读 fact.kind 抽象层,自动受益 待办: - 暂不重导(代码层先稳定);下一轮 TRUNCATE + cold-import 看真实效果 - recommendation_rows 双源 union(transforms 加 union op 或 parser 侧 dedup) - treatment_review_rows 双源 union + kind 区分(actual review vs planned review) - EMR 漏录 fallback:某些治疗只有 settlement 没 EMR.treat_plan 的兜底策略 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed -
主要工作(自 W3 末快照以来): 数据层(canonical-fact-layer): - 治疗链 5 阶段模型(chain-composer S1/S2/S3/S4/S5)+ TreatmentMilestones + TreatmentLifecycles 字典 - alternative-closed 闸:同位置后续替代治疗覆盖原诊断 → 标 closed - 同 (category, code) 桶按 tooth set overlap 合并(union-find);wholeMouth 桶 S2 修正 - chain.target = SQL 为准(按 plan_reasons.signals.triggers 对齐,plan-aggregate 注入) - diagnosis name_zh 末尾标点清理;cooldown 内不标 ★ 潜在新链 召回算法: - DiagnosisTreatmentMap K00-K09 全覆盖(加 K00/K01/K03/K06/K07/K09) - treatment_initiation_recall 10 个 sub-scenarios + 配套 *_RECOMMENDED 推荐码 - 移除 INTAKE_MAX_DAYS 上界;scenario SQL 加预约排除(任何 sig 后预约即排) - S2 改用预约主诉类别;S2 fallback 显示 planned 治疗 画像 Persona: - treatment_chain_status feature 直接复用 ChainComposerService - value/recall_risk/dnc feature 切到独立 fact_type(v2.1) - status: in ['active', 'fulfilled'] 加载兼容已完成 actual Plan 详情聚合: - /plans/:id/full 接 personas + chains + facts + 话术 - script 从 plan_scripts DB 加载,markdown 反 parse 4 段 sections,前端零适配 - 列表页搜索/过滤改服务端(W3 末) AI 话术(B 方案 重写): - DeepSeek V4 Pro → Flash 切换(call defaultModelId + config defaultModel) - schema 4 段 markdown 字符串(opening/followup/objection/close)对齐前端 mock - prompt @2026-05-24-d:few-shot demo +
❌ /✅ 反例 + 事实约束硬要求 - 事实漂移防护:诊所名 JVS_DW_CLINIC_NAMES 字典翻译、牙位 FDI→俗称、 主诊医生从 facts 抽、通话称呼 nameSpokenForm(姓+先生/女士) - scenario 内部 label 禁外露,opening 必须用临床事实开场 鉴权: - A 方案 refresh token 真实实现(Redis jti rotation,无 host SSO 回调) - 详情页电话查看 icon + reveal 接口 UI: - 详情页 TopBar 跟列表页 PageHeader 风格统一 - 治疗链 5 阶段词表(chainStatusVisual) - 闭环链去"建议下一步" + 闭环时间 - WhyCard 过滤 alternative-closed reasons 数据源接入: - 5 家试点诊所 JVS DW 实接(瑞尔/瑞泰双 brand,tenant_id 路由) - yaml transforms(Layer A.5)6 operator 白名单:split/route/derive/filter/project/pick_first_nonzero - 实测 5000 患者 cohort,408K facts / 2207 plans / 0 failed 待办: - task #46 cold-import --reparse mode(yaml 改后强制重 parse) - EMR.treat_plan 语义错位(标记为 planned 实际是 actual);EMR.plan 字段未消费 - 双源 actual 去重(EMR vs settlement) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>luoqi committed
-
- 22 May, 2026 1 commit
-
-
含本阶段全部成果: - L1 摄入:4 层规范化(transforms 6+2 op / AssemblerEngine / parser+zod / Layer C 预留), 4 入口统一管道,单 host 多 tenant(瑞尔/瑞泰),__source_row 真原文留底 - 诊断覆盖率 18%→63%:中文名→K码白名单 + 无码落 fact 留 LLM(code_source 溯源) - 算法:treatment_initiation_recall 4 子规则(K08/K02/K05 + 新增 K04 根管),6 因子打分 - 单一真理源 DiagnosisTreatmentMap(诊断→治疗类别,4 处引用) - 命名统一(encounter/emr/image),chain-composer 去中文关键词猜码 - Persona 4 特征,plan targetClinicId 回填,token dictionary(诊所名) - 前端:话术 3 模式(伴飞/卡片/原文)、我的任务沉浸抽屉(触底分页)、 列表 density 拉开、去头像、去无意义的推荐渠道/时间/角色 - 文档:canonical-fact-layer / potential-treatment-recall(-flow) 对齐 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
luoqi committed
-