AI辅助住院病历生成:让小模型在几十秒内完成复杂任务的实战方法论

来源:公众号文章(开发者分享)
整理时间:2026-04-09
标签:#AI落地 #小模型 #任务拆分 #医疗AI #病历生成 #DAG并行 #配置驱动


前言

当没法用最强模型、又必须在几十秒内完成逻辑复杂的任务时,怎么办?

这不是AI噱头,是真实临床场景的硬需求:
- 住院病历生成:患者数据 30~300K 字符,最高 200K token
- 合规红线:数据不能出院,不能用境外模型
- 速度要求:容忍上限就是几十秒,临床节奏等不了
- 成本约束:最强模型的API调用成本医院承受不了

这个实战经验来自真实项目,以下是具体可操作的方法。


一、问题本质:为什么原方案崩了?

原始做法

用一份 5~10K token 的长提示词,把取数逻辑、组织逻辑、输出格式、示例全部塞进去,交给 Qwen3-32B 开启深度思考模式,一次性生成。

遇到的问题

问题 原因
上下文超限 Qwen3 原生窗口 32K,患者数据动不动几十上百 K
扩展到 131K 后仍有 20%+ 无法覆盖 vLLM + YaRN 技术已尽力
速度变慢 上下文逼近极限时,生成速度变成 60~120 秒一份
取数不准 模型无法区分”当天新出报告”和”查房记录里对历史报告的引用”

核心原因:提示词越来越长、上下文越来越多,模型表现反而越来越差。给模型的”以防万一”的上下文全是噪音。


二、核心解法:一句话

把病历拆成最小生成单元,让院内小模型各个击破;同时用院外最强模型持续打磨生成配置——配置越精准,小模型输出越稳定。

这不是让模型一次做对,而是根本不让它一次做。


三、具体操作方法

步骤1:元素化拆分

把一份完整的病历文书拆成 10~20 个独立元素

示例元素划分:

元素 职责
主诉 提取患者自述的主要症状
现病史 从入院记录中按时间线组织
入院情况 入院记录的事件数据(不含查房、检验引用)
体格检查 固定格式输出
初步诊断 依赖入院情况元素
鉴别诊断 依赖初步诊断和入院情况
诊疗计划 依赖所有诊断结果
出院诊断 汇总全住院期诊断
住院天数 代码计算(非LLM)
检查检验报告 代码提取当天新出数据(非LLM)

每个元素单独定义:

{
  "element_name": "鉴别诊断",
  "data_source": ["入院记录", "初步诊断"],
  "depends_on": ["入院情况", "初步诊断"],
  "generation_logic": "基于入院情况和初步诊断...",
  "output_format": "分段列表",
  "example": "【鉴别诊断】\n1. xxx:依据...排除..."
}

步骤2:建立依赖图(DAG)

元素之间不是线性串行的,而是形成 有向无环图(Directed Acyclic Graph)

[主诉] ──┬──→ [现病史] ──┐
         │               ↓
[入院情况] ─────────→ [初步诊断] ──→ [鉴别诊断] ──→ [诊疗计划]
               ↓                              ↑
        [检查检验报告] ───────────────────────┘
               ↓
        [出院诊断]

调度规则:
- 有依赖的元素等前文生成完毕后再启动
- 没有依赖关系的元素 并行执行
- 并行执行是关键加速手段

步骤3:数据裁剪(解决上下文噪音)

每个元素只拿到它需要的数据,其他全部过滤:

[入院情况] 元素 → 只收到:入院记录事件数据
              → 过滤掉:查房记录、检验报告、手术记录

[鉴别诊断] 元素 → 只收到:入院情况前文 + 初步诊断前文
              → 不含:护理记录、医嘱等无关数据

用代码在LLM生成之前就把历史引用过滤干净,只留当天新出的报告数据。

步骤4:两层模型分工

层级 模型 职责
执行层(院内) Qwen3-32B 深度思考模式 处理少量需要推理的元素(鉴别诊断、诊疗计划)
执行层(院内) Qwen3-80B-A3B 非思考模式 大量取数和内容提取操作
优化层(院外) Opus 4.6 / Gemini 3 Pro / MiniMax 打磨JSON配置(写说明书)

核心洞察
- 拆分后绝大多数元素的逻辑已经简单到不需要深度推理
- 非思考模型(Qwen3-80B-A3B)即可稳定输出
- 深度思考模型只用于真正需要推理的少数节点

步骤5:确定性操作全用代码

检查检验数据提取、住院天数计算、时间线排序等确定性操作,全部用代码执行,不走LLM

# 示例:代码模式提取当天新出报告
def extract_new_reports(patient_data, target_date):
    # 精确过滤:当天新出的报告
    new_reports = [r for r in patient_data.reports 
                   if r.date == target_date and r.type == 'lab']
    return new_reports  # 直接返回结构化数据,不走LLM

好处:
- 降低对模型智能的需求
- 进一步压缩上下文长度
- 减少LLM处理噪音

步骤6:配置持续优化闭环

院外最强模型不直接生成病历,而是帮 打磨配置(写说明书)

1. 脱敏患者数据样本 + 当前配置 → 导出到院外
2. Opus 4.6 / Gemini 3 Pro 分析医生真实书写的病历
   - 从哪些数据里取信息?
   - 取了什么?
   - 怎么组织的?
3. 调整配置的:取数逻辑、提示词措辞、few-shot示例
4. 验证效果 → 循环迭代

效果衡量标准(需专用工具):
- 并发生成验证输出稳定性
- 与医生真实文书逐字段对比
- 排除已书写内容避免”作弊”
- 真实患者数据 + 配置组合调试


四、关键技术细节

4.1 上下文扩展

技术 效果
vLLM + YaRN 原生 32K → 131K 上下文
覆盖率 从 1/3 患者可用 → 近 80%

超过 20% 仍覆盖不了的极端情况,需要通过元素拆分解决。

4.2 并行加速效果

优化前 优化后
60~120 秒/份 10~30 秒/份

加速来源:
- 无依赖元素并行执行
- 深度思考模型只用于少数节点
- 代码处理确定性操作
- LLM上下文窗口压力大幅降低

4.3 为什么自己开发配置工具而非用Dify/Coze

痛点 通用平台问题 自开发优势
数据结构 内容庞杂不公开 JSON结构清晰标准
AI优化 复杂流程下最强模型难以有效优化 格式标准,AI可直接生成初版
调试需求 真实数据组合调试、并发验证、逐字段对比
院内部署 版权问题 完全自主可控

五、方法论总结

核心原则

当模型能力不足以一次性搞定复杂任务时,不要试图换一个更强的模型,而是把任务拆到它能搞定的粒度。

操作清单

适用场景

本方法论适合以下场景:
- ✅ 复杂任务、小模型必须上、速度要求严格
- ✅ 数据量大、上下文超限是常态
- ✅ 有院外最强模型可以帮忙优化配置
- ✅ 任务可拆分为相对独立的子任务

不适用:
- ❌ 任务本身不可拆分(如需要全文上下文连贯的写作)
- ❌ 各子任务相互强依赖,拆分后无并行收益


六、下一步:怎么写好”说明书”?

原文提到的核心未展开问题:

  1. 怎么让外部强模型理解我们自定义的 JSON 配置结构?
  2. 怎么引导它生成的配置做到整体逻辑复杂、但每个元素节点生成逻辑简单且准确
  3. 患者数据怎么脱敏、怎么组织才能让它看懂?
  4. 优化后的说明书又怎么验证效果?

这是整套方案的真正核心,留待后续整理。


本文由 AI 辅助整理,仅供技术学习参考。