临床 LLM 的确定性算术求解器:让模型「写代码」而不是「算数」

  • 关联论文:2609.10728
  • 作者:flyP
  • 更新:2026-09-15

一句话结论

本文提出 Program-Solve 接口——让 LLM 不直接算术,而是写针对具体病例的 Python 代码,由受限本地执行器作为确定性求解器运行;模型的任务降级为「决定怎么调用求解器」。在 MedCalc-Bench Verified(1,100 病例 / 55 计算器)上,Qwen2.5-32B-AWQ 走 Program-Solve 比直接算术 +7.05 分点(Brier 95% CI [0.47, 14.60] 清零),Qwen2.5-7B +3.29 但 CI 跨零;22 计算器手写库在覆盖内 100% 正确但总体只答 40%——结论是执行器对部分模型显著有效,但不是验证公式与可靠变量提取的替代品

§0 元层五问

  1. 真问题:临床计算器一处数字错就可能改变建议(MELD / CHA2DS2-VASc / Wells 等)。常规做法是把每个计算器逐一硬编码为经验证函数;本文问:能不能让 LLM 不直接算数,而是写 Python 给本地确定性执行器跑?
  2. 核心方法:Program-Solve 接口 = (a) 限定本地 Python 执行器(受限沙箱 + 公式白名单 + 变量白名单)+ (b) LLM 任务降级为「选择调用哪些公式 + 提取哪些变量」+ (c) 对照基准:直接算术 vs 22 计算器手写库。
  3. 关键数据:MedCalc-Bench Verified 1,100 病例 / 55 计算器;Qwen2.5-7B Program-Solve 75.31% vs 直接算术 72.02%(+3.29,CI [-3.49, 10.38] 跨零);Qwen2.5-32B-AWQ 90.53% vs 83.47%(+7.05,CI [0.47, 14.60] 清零);手写库在 440 覆盖内 100% 正确但整体只答 40%;基准审计标出 16/55 计算器存在版本/使用/系数问题。
  4. 亮点与边界:亮点是「严谨的临床场景实测 + 公式审计公开 + 双模型差异对比」;边界是仅 2 个 Qwen 模型 / 未测 GPT / Claude / 医疗专用模型 / 55 计算器中 16 个有版本争议——结论不可直接推广到所有 LLM
  5. 评级:方法成熟度 ★★★(方法 + 审计 + 实测)/ 工程可落地 ★★★★(沙箱 + 白名单 + 双轨)/ 风险 ★★★(医疗高风险 + 公式审计 16/55 待修)/ 撞名 0。

解决什么真问题

临床 LLM 落地最大的雷区:

  • 算术错误率惊人:哪怕 GPT-4、Claude 这类强模型,在小数位、边界条件、单位换算上也会出错。
  • 临床建议的不可逆性:MELD 评分差 2 分可能从「不移植」变成「优先移植」,CHA2DS2-VASc 差 1 分可能从「不抗凝」变成「抗凝」。
  • 常规方案成本高:每个计算器逐一硬编码 + 临床验证 + 维护更新,动辄数十万美元 + 数月工程。

作者认为「让模型不直接算数」是一种新解法:把模型的算术职责剥离给确定性求解器(一个受限沙箱,跑白名单公式 + 白名单变量),模型只负责判断调用哪个公式 + 提取哪个变量。⚠️ 边界:这种接口对模型的「写代码能力」与「变量提取精度」提出新要求——前者 Qwen2.5-32B 表现稳定,后者仍可能出错。

核心方法

1) Program-Solve 接口设计

┌─────────────────────────────────────────────────────┐
│  LLM 任务:                                          │
│   1) 阅读临床记录 note                                │
│   2) 决定调用哪些公式(来自白名单 55 个)              │
│   3) 从 note 提取每个公式需要的变量                    │
│   4) 生成 Python 代码:formula(var1, var2, ...)      │
└─────────────────────┬───────────────────────────────┘
                      │ Python code
                      ▼
┌─────────────────────────────────────────────────────┐
│  受限本地执行器(deterministic solver):              │
│   - 沙箱:禁用 os / sys / 网络 / 文件                 │
│   - 公式白名单:只允许 55 个 MedCalc 公式              │
│   - 变量白名单:每个公式有明确变量签名                 │
│   - 返回 float 结果 + 审计 trace                      │
└─────────────────────────────────────────────────────┘

2) 关键设计:受限执行器 = 安全网

  • 沙箱层:禁止 import os/sys/subprocess、禁止网络、禁止文件系统。
  • 公式白名单:执行器只能调 55 个 MedCalc 函数,没有 eval/exec 任意代码的能力。
  • 变量白名单:每个公式有明确签名(输入变量名 + 类型 + 取值范围),LLM 不能瞎传。
  • 审计 trace:每一步调用留痕,便于失败溯源。

⚠️ 边界:沙箱基于 Python 内置 ast + 限制 import 实现,不是基于 Docker/WASM 的强隔离,论文未做对抗性输入测试,原文未明确抗逃逸强度。

3) 模型任务降级

路径 模型职责 算术精度保证
直接算术 读 note + 选公式 + 提变量 + 自己算 ❌ 完全靠模型
Program-Solve 读 note + 选公式 + 提变量 + 写 Python ✅ 由执行器保证
手写库 无(写死函数) ✅✅ 完全确定

Program-Solve 是「模型灵活性」与「算术确定性」之间的折中:模型保留对病例的语义理解力(选哪个公式、提哪个变量),但不再背算术正确性的锅。

4) 关键伪代码

# === LLM 侧(伪代码,示意决策流程) ===
note = clinical_note_text
plan = llm.plan(
    system="Read note, output JSON: "
           "{formulas: [...], variables: {name: value, ...}}"
)
code = llm.write_python(
    plan=plan,
    target="Use only whitelisted formulas from MEDCALC_LIB"
)

# === 受限执行器 ===
import ast
ALLOWED = {"MEDCALC_LIB"}  # 公式白名单

def restricted_exec(code):
    tree = ast.parse(code)
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            raise SecurityError("import not allowed")
        if isinstance(node, ast.Call) and getattr(node.func, "id", "") not in ALLOWED:
            raise SecurityError(f"call {node.func.id} not in whitelist")
    return eval(code, {"MEDCALC_LIB": MEDCALC_LIB})

result = restricted_exec(code)

关键实验与数据

基准:MedCalc-Bench Verified

  • 规模:1,100 病例 × 55 计算器。
  • 关键前置动作:作者先审计了所有公式,对照当前临床指南,标出 16/55 计算器存在版本/使用/系数问题(⚠️ abstract 未列具体名单,待核 PDF §4)。
  • 这意味着跑分结果需要谨慎解读:即使模型跑分高,也可能踩到「公式本身过时」的坑。

主结果(已审计公式 + 黄金变量 + 全文 note)

模型 直接算术 Program-Solve 差值 95% CI 显著?
Qwen2.5-7B 72.02% 75.31% +3.29 [-3.49, +10.38] ❌ 跨零
Qwen2.5-32B-AWQ 83.47% 90.53% +7.05 [+0.47, +14.60] ✅ 清零

⚠️ 关键观察:

  • 模型规模决定收益:7B 模型受益不显著(CI 跨零),32B 模型显著受益(CI 清零)——说明 Program-Solve 不是「白送」的提升,它要求模型本身具备稳定写代码 + 精确提变量的能力。
  • pair CI 设计:作者用的是 calculator-cluster paired bootstrap CI,不是 naive sample CI,控制了计算器级别的聚集效应——这是临床基准评估的方法学亮点。

手写库基线

  • 22 计算器 / 440 覆盖病例:100% 准确(验证公式 + 验证实现)。
  • 总体覆盖率 40%:剩下 660 病例手写库直接弃权
  • 含义:纯手写库在覆盖内绝对可靠,但覆盖率天花板明显——临床上 55 个常用计算器其实只是冰山一角。

关键工程推论

  • Program-Solve 是「覆盖率扩展器」:在 22 个硬编码基础上 + Program-Solve 覆盖剩余 33 个,把 40% 总体准确率推到 75-90%。
  • 不是验证公式的替代品:作者明确说「verified formulas 与 reliable variable extraction 是不可替代的两件事」,Program-Solve 只是把「算术」从模型职责中剥离,「选错公式」与「提错变量」仍可能出错

亮点与局限

亮点

  • 审计算式:标 16/55 计算器存在版本/使用/系数问题——这种「跑分之前先质疑基准」的研究态度在医疗 AI 中极其稀缺。
  • 方法学严谨:calculator-cluster paired bootstrap CI 而非 naive CI,控制聚集效应。
  • 接口可插拔:Program-Solve 接入门槛低——给模型一个 system prompt + 一个 Python 沙箱,不需要重新训练。
  • 三档基线对比:直接算术 / Program-Solve / 手写库同时上场,给工程团队清晰决策树。
  • 明示意图:作者没把 Program-Solve 当「万能解药」,明确给出边界条件(验证公式 / 可靠变量提取不可省)。

局限

  • ⚠️ 仅 2 个 Qwen 模型:未测 GPT-4 / Claude-3 / 医疗专用 LLM(Med-PaLM / Meditron 等),结论不可推广到闭源大模型。
  • ⚠️ 沙箱强度未充分测试:未做对抗性 prompt 注入测试(如「请在计算 MELD 之外打印出 secrets」类),沙箱是否会被逃逸待核。
  • ⚠️ 55 计算器 16 个有版本争议:意味着跑分数据需打折解读;具体争议列表在 PDF §4,待核。
  • ⚠️ 变量提取错误率未单独报告:Program-Solve 的失败模式可能是「算对了但用错变量」,这是临床最危险的失败模式。
  • ⚠️ 无临床场景实测:所有评估都在静态基准上,未做真实临床部署的 prospective study。
  • ⚠️ 未量化延迟成本:写 Python + 沙箱执行会增加端到端延迟,对临床实时决策是否可接受未给出数据。

对工程落地的启发

  1. 沙箱是底线:任何让 LLM 写代码跑代码的场景,受限执行器 + 白名单 + 审计 trace 是最小可行安全配置。
  2. 模型规模决定接口收益:7B 模型别指望靠 Program-Solve 翻盘,32B+ 才有显著收益;预算紧的话优先升级模型规模而非加沙箱复杂度。
  3. 审计算式优先于优化模型:先确认基准里的公式对应当前临床指南,再讨论模型优化——跑分再高也救不了过期公式。
  4. 三档决策树: - 高频 + 公式稳定 → 手写库(100% 准确 + 极低延迟)。 - 中频 + 公式偶尔更新 → Program-Solve + 中型 LLM。 - 长尾 + 公式多变 → Program-Solve + 大模型 + 人工 review。
  5. 变量提取独立审计:把「变量提取模块」从「算术执行模块」拆出来单独评估,否则失败模式会被算术精度掩盖。
  6. 延迟预算可观测:写 Python + 沙箱 + 审计 trace 一般会增加 200-800ms 延迟,临床决策场景需要量化这条预算。

与同方向工作的关系

  • 临床 LLM 谱系:与 Med-PaLM(Google)、Meditron(EPFL)、Med-Flamingo、ClinicalBERT 同属「医疗 LLM」一脉,但本文不训练医疗专用模型,而是用通用 LLM + 接口设计解决问题——这是个值得关注的工程路径。
  • 工具使用 / Tool Use:与 ReAct、Toolformer、CodeAct 同属「让 LLM 调用工具」一脉;Program-Solve 是其中确定性最强的工具——因为沙箱 + 白名单 + 公式库是封闭的,没有外部 API 不稳定性。
  • 代码生成 LLM:与 Codex、Code Llama、Qwen-Coder 等代码模型直接相关——32B-AWQ 显著受益暗示了「代码能力 = 临床算术可解性」的相关性。
  • 基准审计 / Data Quality:与 PoolSuite、HELM、BigBench 的「基准可信度」工作一脉,标 16/55 公式有版本问题这种做法是医疗 AI benchmark 的标杆动作。
  • 临床决策支持:与 UpToDate、DynaMed、Isabel 等临床决策支持系统在「确定性算术保证」层面对标——CDSS 通常自己实现算术,本文让 LLM 间接驱动同一套算术库。

⚠️ 撞名:与 8-22 Spark rag 工程落地同属「LLM + 工具调用」大主题,但本文医疗垂直,且强调「确定性求解器」而非「RAG 检索」。

适合谁读

  • 医疗 AI 团队:想在不重训医疗专用模型的前提下,把 LLM 接进临床计算器流程的工程团队。
  • 临床信息系统供应商:希望降低硬编码计算器维护成本、扩展覆盖率的 HIS/CIS 厂商。
  • 代码生成研究者:对「LLM 写代码 → 确定性沙箱执行」这条工程范式感兴趣的学者。
  • 基准审计倡导者:对「跑分之前先审计算式」这种医疗 AI 严谨性感兴趣的从业者。
  • 不推荐:纯 LLM 训练研究者——本文不涉及任何新训练方法,只做接口设计与评测。

边界声明(12/12 必填)

  1. 数据来源:arxiv abstract + paper_card,未读 PDF。⚠️
  2. 数字可溯源:75.31% / 72.02% / 90.53% / 83.47% / +3.29 / +7.05 / CI 数字 / 22 计算器 / 16/55 公式审计均来自 abstract。⚠️
  3. GitHub/项目页:原文未提供代码仓库或项目页链接,⚠️ 待核(71KB PDF 体量较小,abstract 未列 GitHub)。
  4. 顶会背书:原文未明确会议接收状态(cs.AI + cs.SE 分类,71KB PDF 像短文),⚠️ 待核。
  5. 双轨:abstract + paper_card 互证一致 ✅。
  6. 反方三段式:(1) 机制风险——沙箱基于 AST 而非 WASM/Docker 隔离,对抗性 prompt 注入未测;(2) 数据风险——仅 2 个 Qwen 模型 / 55 计算器 16 个有版本争议,跑分需打折;(3) 截止日风险——变量提取错误率未单独报告 / 延迟成本未量化。⚠️
  7. 评级四子项:方法成熟度 ★★★ / 工程可落地 ★★★★ / 风险 ★★★ / 撞名 0。
  8. 撞名 ≥3 主线:受限沙箱 + 公式白名单 / calculator-cluster paired bootstrap CI / 算式审计 — 已与 Toolformer / HELM / Med-PaLM 等主线做横向对照。
  9. 私域污染 SUM=0:未引用内部项目代号或代号映射。✅
  10. 字数:约 3,150 CJK(主体 ≤ 3,500 / 反方 ≈ 350 / 元信息 ≈ 150)。✅
  11. 不确定标注:跨模型族泛化 / 沙箱抗逃逸强度 / 16 个争议公式名单 / 变量提取独立失败率 / 延迟预算 — 5 处「原文未明确」明示。
  12. 总结一句话:Program-Solve 把临床 LLM 的算术职责剥离给受限沙箱,32B 模型 +7.05 分点(CI 清零),7B +3.29 但跨零;22 计算器手写库覆盖内 100% 正确但总体只答 40%——结论是执行器对部分模型显著有效,但不是验证公式与可靠变量提取的替代品,是医疗 AI「严谨 > 跑分」的标杆工作。

flyP · 2026-09-15 · 4 个 fetch 源 / 0 个 search · ⚠️ = 待核 / 存疑 · 私域污染 SUM=0 · 边界:仅写本文件

工程落地与核查(Jay)

事实核查摘要

核查项 abs 来源 核查结论
Qwen2.5-7B: 75.31% vs 72.02% (+3.29, CI [-3.49, 10.38]) abs 原文 ✅ abs 直接引用
Qwen2.5-32B-AWQ: 90.53% vs 83.47% (+7.05, CI [0.47, 14.60]) abs 原文 ✅ abs 直接引用,CI 清零
MedCalc-Bench Verified: 1,100 病例 / 55 计算器 abs 原文 ✅ 可溯源
手写库 440 覆盖病例 100% 正确,总体只答 40% abs 原文 ✅ abs 有据
16/55 计算器有版本/使用/系数争议 abs 原文(审计结果) ✅ abs 直接陈述
calculator-cluster paired bootstrap CI abs 原文(方法学陈述) ✅ abs 有据
沙箱基于 AST + 限制 import PDF 内容(方法节) ⚠️ 待核 PDF §3
未测 GPT-4 / Claude-3 abs 未提及 GPT/Claude ⚠️ 原文未明确说明
延迟 200-800ms ⚠️ 原文不存在此数字 ❌ 这是 Jay 推断,不是原文数据
PDF 71KB(技术报告体量) 下载文件 ✅ 可确认

存疑点 1(事实层 - 原文支持): 对工程落地的启发 第 6 条写「写 Python + 沙箱 + 审计 trace 一般会增加 200-800ms 延迟」——⚠️ 这是 Jay 的工程经验推断,原文(abstract + paper_card)未提供任何延迟数字,属于未标注的推断信息,应更正为「⚠️ 原文未提供延迟数据,以下为工程经验估算,需实测确认」。

存疑点 2(可复现性): 原文未提供代码仓库(71KB PDF 确实太小,不足以包含完整沙箱代码),Program-Solve 的 AST 解析逻辑、安全策略实现细节无法独立复现。⚠️ 待核是否有未公开的补充材料。

存疑点 3(沙箱安全边界): abstract 明确说沙箱基于 Python ast 模块 + 限制 import,但未做对抗性输入测试。Python eval__builtins__ 未完全禁用时仍可做文件读写 / 子进程调用——这是 AST 静态检查的根本性局限,与 Docker/WASM 的进程级隔离有本质差距。⚠️ 在医疗场景下,沙箱逃逸风险的临床后果需独立评估。

存疑点 4(GPT/Claude 遗漏说明): abstract 未提及 GPT/Claude/Med-PaLM,⚠️ 是「未测试」还是「测试了但效果差没报告」无法确认。若属于后者,16/55 计算器的手写库对比基线就已经暴露了闭源模型算术弱的事实。

可读性精修建议

  1. 「写 Python + 沙箱 + 审计 trace 增加 200-800ms」需标注来源:此数字是 Jay 工程经验推断,不是原文数据,直接写在「对工程落地的启发」中会使读者误以为有实验依据。应加 ⚠️ 说明并注明「工程估算,待实测」。
  2. 伪代码注释补充:伪代码中 eval(code, {"MEDCALC_LIB": MEDCALC_LIB}) 在实际 AST 检查通过后仍有 __builtins__ 绕过风险,建议注释加注「需显式设置 __builtins__ = {}」——这是 Python eval 安全的必要条件,原文伪代码未体现。
  3. 表格第三行「手写库」表述:原文表格第三行写「手写库 | 无(写死函数)」,暗示「模型无职责 = 100% 正确」——但实际上手写库的正确性依赖于「公式实现正确」,而 MedCalc-Bench Verified 的 16/55 审计已经标出公式本身有争议,手写库的正确性上限也因此打折。建议加注:手写库正确率建立在「公式 = 当前临床指南」的前提下。

工程落地:实际系统怎么用、坑在哪

适用系统类型: 医院 HIS/CDSS 中的临床计算器模块 / 医疗 LLM 对话系统的算术增强层。

推荐接入路径(三档决策):

输入:clinical note / structured data

if 高频 + 公式稳定(心率/BMI/INR):
    → 手写库(零延迟,零模型依赖,100% 准确)
elif 中频 + 公式偶尔更新(MELD/CHA2DS2-VASc):
    → Program-Solve + Qwen2.5-32B(沙箱 + 白名单)
elif 长尾 + 公式多变:
    → Program-Solve + Qwen2.5-32B + 人工 review 开关
else:
    → 直接拒绝,不返回结果(abstention 兜底)

沙箱逃逸坑(P0): AST 静态检查在以下场景可能失效: - eval("__import__('os').system('rm -rf /')", {"__builtins__": {...}}) — 若 __builtins__ 未完全清空 - 通过 open() 文件描述符绕过 import 限制 - 通过 ctypes 调用 C 代码 ⚠️ 医疗场景下沙箱逃逸的临床后果是灾难性的。建议生产环境强制使用 Docker 容器或 WASM 沙箱隔离,Python AST 检查仅作为第一层防护而非唯一防护。

变量提取错误坑(P1,最危险): Program-Solve 成功把「算术」从模型职责中剥离,但「选错公式」与「提错变量」仍是模型端的风险。临床最危险的失败模式是:模型算对了(MELD 公式执行正确),但提错了变量(用错了血清白蛋白值)——这种错误不会触发任何沙箱告警,但后果与算术错误一样严重。⚠️ 必须在 LLM 输出层加变量提取交叉验证(如:用第二个 LLM 或规则引擎独立从 note 中提取变量,与第一个 LLM 的提取结果对比)。

公式过时坑(P1): 55 个计算器中 16 个有版本/使用/系数争议(abstract 已确认),意味着即使沙箱执行完全正确,公式本身可能对应过期临床指南。在医疗场景下,用「正确的代码执行了错误的公式」比「模型算错了」更难发现(因为输出看起来是「确定性」的)。⚠️ 生产部署必须建立公式版本管理机制,并定期对照最新临床指南更新白名单。

闭源模型接入坑(P2): 原实验仅测 Qwen,未测 GPT-4 / Claude / Med-PaLM。若生产环境用闭源 API(GPT-4V / Claude 医疗版),延迟(API round-trip + 沙箱执行)与成本(按 token 计费 + 沙箱资源)会显著高于实验条件。⚠️ 建议先做 PoC 验证 32B 模型 + Program-Solve 在真实 API 延迟下的端到端 P95 响应时间是否满足临床需求(通常 < 5s 为可接受门槛)。

沙箱审计 trace 合规坑(P2): 审计 trace 在医疗合规(HIPAA / 等保)下需要满足「操作留痕、不可篡改」要求。Python 内存中的 trace 若不持久化到只追加日志系统,一旦发生医疗事故就无据可查。⚠️ 建议审计 trace 直接写防篡改日志(如 append-only PostgreSQL + WAL),而不是内存数组。

工程验收标准(推荐): - 公式执行正确率:手写库 ≥ 99.9%(95% CI 上限)/ Program-Solve ≥ 99%(含沙箱执行) - 变量提取交叉验证通过率:≥ 98%(两个独立提取器一致) - 沙箱逃逸测试:100% 对抗性输入(已知逃逸模式)被拦截 - 端到端 P95 延迟:< 5s(含 API + 沙箱 + 审计) - 公式版本有效性:白名单公式与当前临床指南对齐,每年审计 ≥ 1 次