想象一下,一位繁忙的临床医生身处重症监护室。他们需要知道一些具体的信息,而且现在就要知道: “有多少患者在接受静脉导管手术后的两个月内被开具了阿司匹林?”
在现代医学领域,答案是存在的。它就静静地躺在电子健康记录 (EHR) 系统中。然而,获取这个答案却出奇地困难。医生不能简单地直接询问数据库。相反,他们通常不得不去问数据工程师,然后工程师将请求转化为复杂的 SQL 查询,执行查询,检查数据,最后把结果发回来。这个循环效率低下、缓慢,并且造成了一个瓶颈,将医疗专业人员与他们自己的数据隔离开来。
为什么 AI 还没有解决这个问题?虽然像 GPT-4 这样的大型语言模型 (LLM) 令人印象深刻,但在医疗数据库这种特定、严格且高风险的环境中,它们历来表现挣扎。它们会“臆造”表名,编写无效的 SQL,或者被海量的医疗数据搞得晕头转向。
EHRAgent 应运而生。这是由佐治亚理工学院、埃默里大学和华盛顿大学的研究人员提出的一个新框架。EHRAgent 将 LLM 从一个简单的文本生成器转变为一个能够编写代码、使用工具,并且关键是能够通过调试自己的错误来回答复杂医疗问题的自主代理。

问题所在: 为什么 EHR 对 AI 来说很难
要理解为什么我们需要一个专门的代理,我们首先需要了解数据。电子健康记录不是简单的电子表格。它们是庞大的关系型数据库,包含数十个表 (例如 admissions 入院记录、prescriptions 处方、lab_events 实验室事件) ,并通过晦涩难懂的标识符 (HADM_ID、SUBJECT_ID、ITEMID) 相互连接。
在标准的文本到 SQL 任务 (比如让 AI 查询维基百科表格) 中,数据通常很小且干净。EHR 则截然相反。它们杂乱、庞大,并且需要深厚的领域知识才能驾驭。

如图 2 所示,像 WikiSQL 或 SPIDER 这样的通用领域数据集通常只涉及行数较少的小型表。相比之下,源自真实世界 EHR 的数据集 (如 MIMIC-III 或 eICU) 包含的表动辄有数十万行数据。一个单一的临床问题通常需要“多跳推理”——从患者的人口统计数据跳转到他们的入院记录,然后是实验室结果,最后是处方表。
标准的 LLM 经常在这里失败,因为它们缺乏特定的“模式 (Schema) ”知识 (不知道表之间如何连接) ,并且无法按顺序通过这些复杂的跳转进行推理。
解决方案: EHRAgent
研究人员提出了 EHRAgent,这是一个自主系统,它不将医疗问答视为翻译任务,而是视为一个工具使用规划过程 。 EHRAgent 表现得像一个程序员,而不是试图猜测答案或一次性编写一个 SQL 查询。它编写 Python 代码,针对数据库执行代码,检查是否有效,如果无效则进行修复。
该架构由四大支柱组成,使其能够进行有效推理:
- 医疗信息整合: 教模型认识数据库的“地图”。
- 长期记忆: 检索过去最好的示例来解决新问题。
- 代码接口: 使用 Python 而不仅仅是 SQL 来处理复杂逻辑。
- 交互式编码 (小黄鸭调试法) : 从错误中学习。
让我们分解一下下面可视化的架构。

1. 医疗信息整合 (地图)
LLM 面临的最大障碍之一是“上下文窗口”——即它一次能处理多少文本的限制。你不能简单地将包含数千个列描述的整个数据库架构塞进提示词 (Prompt) 中。
EHRAgent 通过引入医疗信息整合模块解决了这个问题。当一个查询 (例如关于“阿司匹林”) 输入时,系统首先咨询 EHR 的元数据。它识别出哪些表和列与问题中的特定医疗术语相关。
如果问题涉及药物,代理知道要去查 prescriptions 表。如果涉及实验室测试,它会去查 labevents。这就像一个过滤器,只向 LLM 提供它理解该特定问题所需的特定数据库结构相关的“背景知识”。
2. 长期记忆 (经验)
在 AI 中,“少样本学习 (Few-shot learning) ”是一种技术,即你给模型几个任务示例 (演示) 来告诉它该做什么。通常,这些示例是固定的。
然而,EHRAgent 维护着过去成功查询的长期记忆 。 它存储了一个包含问题及其成功代码的库。当新问题到来时,系统会在其记忆中搜索最相似的过去问题。
这使得代理能够从经验中学习。如果它过去成功回答了一个关于“计算住院时间”的问题,而新问题询问的是“入院和出院之间的时间”,它就会检索该特定逻辑。这种动态的示例选择比静态列表强大得多。
3. 代码接口: 为什么要用 Python?
以前解决这个问题的大多数尝试都试图让 LLM 编写 SQL (结构化查询语言) 。虽然 SQL 非常适合查询数据库,但在逻辑推理方面却很糟糕。它在处理复杂的日期、多步骤计算和过程逻辑时非常吃力。
EHRAgent 转而使用基于 Python 的代码接口 。 它将 LLM 视为生成 Python 脚本的规划者。代理配备了一组特定的工具 (函数) ,可以在其代码中调用:
LoadDB(): 访问表。FilterDB(): 筛选行。GetValue(): 提取特定数据点。SQLInterpreter(): 必要时运行原始 SQL。
通过生成 Python,代理可以将复杂问题分解为多个步骤: “第一步,获取患者 ID。第二步,循环遍历他们的就诊记录。第三步,计算时间差。”
4. 小黄鸭调试法 (Rubber Duck Debugging)
这可以说是 EHRAgent 最具创新性的部分。在软件工程中,“小黄鸭调试法”是一种方法,程序员向一个无生命的物体 (如橡皮鸭) 逐行解释代码以查找错误。解释的过程往往能揭示错误所在。
EHRAgent 将此过程自动化了。当它编写代码时,会立即执行。如果代码失败 (第一次尝试时经常发生) ,系统会捕获错误信息 (Traceback) 。
代理不会放弃,而是进入多轮对话 。 它查看错误信息,“思考”原因,并生成新的计划来修复它。这就建立了一个反馈循环:
- 规划: 生成代码。
- 执行: 运行代码。
- 调试: 分析错误。
- 优化: 重写代码。

上图完美地展示了这个过程。
- 首次尝试: 代理尝试使用结合了 Subject ID 和
max(INTIME)函数的条件来过滤数据库。系统抛出了“无效输入查询”的错误。 - 第二次尝试: 代理试图通过拆分逻辑来修复它,但犯了一个类型错误 (试图减去字符串而不是日期对象) 。
- 第三次尝试 (成功) : 代理意识到它需要导入
datetime模块,将字符串转换为时间对象,然后再执行减法。它编写了正确的 Python 代码并解决了问题。
这模仿了人类数据科学家的工作方式: 迭代优化,直到代码运行成功。
完整工作流程
为了总结这些部分如何协同工作,我们可以看看下面的完整工作流程图。

该过程始于用户的问题。系统整合相关的医疗元数据 (步骤 1) ,并从记忆中检索相似的过去示例 (步骤 2) 。它生成初始 Python 代码 (步骤 3) 。如果执行失败——可能是由于像 “csru” 与 “CSRU” 这样的大小写敏感性问题——代理会分析错误 (步骤 4) ,优化代码,最终生成正确答案。
实验结果
它真的有效吗?研究人员将 EHRAgent 与几个强基准进行了测试,包括:
- 标准提示 (CoT) : 只是让 GPT-4 一步步思考。
- ReAct: 一个流行的代理框架,交替进行推理和行动。
- 文本到 SQL 方法: 专门训练用于编写 SQL 的模型。
他们使用了三个数据集: MIMIC-III 和 eICU (大型真实重症监护数据库) 以及 TREQS 。
不同复杂度的性能
结果表明,EHRAgent 显著优于所有基准。最能说明问题的指标之一是模型如何处理复杂性。研究人员根据问题中有多少“要素” (约束或变量) 以及回答问题需要多少列来对问题进行分类。

在图 4 中,请看紫线 (EHRAgent) 。
- 图表 (a) - 成功率: 随着问题中要素数量的增加 (难度增加) ,所有模型的表现都会变差。然而,EHRAgent 保持了比 ReAct (蓝色) 或 Chameleon (橙色) 高得多的成功率。
- 图表 (b) - 完成率: 这衡量的是模型是否能够生成可执行的代码 (无论答案是否正确) 。即使对于复杂的查询,EHRAgent 的完成率也保持在极高水平,通常接近 90%。这证明 Python 代码接口比试图一次性编写完美的 SQL 要稳健得多。
样本效率
LLM 的另一个主要优势是它们不需要成千上万的训练样本。研究人员测试了 EHRAgent 在不同数量的“样本 (shots) ” (提示中提供的示例) 下的表现。

如图 5 所示,EHRAgent (紫线) 仅用极少的示例就实现了高性能。即使只有 4 个示例,它也大幅超越了 AutoGen 基准 (绿色) 。这对于医疗应用至关重要,因为标注训练数据 (让医生解释查询) 非常昂贵。
它在哪里失败了?
没有系统是完美的。研究人员对 EHRAgent 未能得出正确答案的案例进行了错误分析。

图 6 显示,最大的失败类别 (26.7%) 是 “调试失败 (Fail to Debug) ” 。 这意味着代理陷入了循环——它编写代码,报错,尝试修复,又报错,最终达到了允许的最大步骤数 (T=10) 。
其他常见的错误包括逻辑错误 (Incorrect Logic) (20.39%) ,即代码运行了但计算了错误的东西 (例如,平均了错误的列) ,以及上下文长度 (Context Length) 问题 (14.56%) ,即对话历史变得太长,LLM 无法处理。
结论与启示
EHRAgent 代表了大型语言模型在医疗保健领域应用的重要一步。通过从简单的文本生成转向代理工作流 (agentic workflows) ——即 AI 充当拥有工具、记忆和调试能力的程序员——我们可以弥合复杂医疗数据与需要这些数据的临床医生之间的鸿沟。
其启示是广泛的:
- 效率: 临床医生可以在几分钟而不是几天内得到答案。
- 可访问性: 你不需要懂 SQL 就能查询包含数百万患者的数据库。
- 透明度: 因为代理编写代码,人类工程师可以审查用于得出答案的确切逻辑,从而确保安全性和准确性。
尽管挑战依然存在——特别是在隐私、成本和“调试失败”循环方面——但 EHRAgent 证明了代码生成是释放 LLM 在专业、数据密集型领域推理能力的关键。
](https://deep-paper.org/en/paper/2401.07128/images/cover.png)