非结构化文本是终极BOSS:用 LLMs 解析医生笔记 🏥
Source: Dev.to
Hey devs! 👋
让我们坦诚一点。我们都生活在一个认为数据长这样子的泡沫中:
{
"patient_id": 1024,
"symptoms": ["headache", "nausea"],
"severity": "moderate",
"is_critical": false
}
它很美观。它可解析。它类型安全。 😍
但如果你曾在 HealthTech 工作(或抓取过任何传统企业系统),你会知道现实往往是一大块由凌晨 3 点疲惫的人类写成的自由文本,令人恐惧。
我最近一直在战壕里努力标准化 临床笔记,而处理医生的笔记让用正则解析 HTML 看起来像是一次度假。
现实检验:“Pt c/o…”
医生不写 JSON,他们使用一套由缩写、错别字和速记组成的秘密代码。
实际的“数据”看起来是这样的:
“Pt 45yo m, c/o SOB x 2d. Denies CP. Hx of HTN, on lisinopril. Exam: wheezing b/l. Plan: nebs + steroids.”
- 如果你仅用标准关键词搜索 “High Blood Pressure”,可能会完全漏掉这条记录,因为医生写的是 “HTN”(高血压)。
- 如果你搜索 “Pain”,可能会出现误报,因为记录中写的是 “Denies CP”(胸痛)。
传统的自然语言处理在这里会遇到困难,因为上下文至关重要。医院里的 “SOB” 代表 “Shortness of Breath”(呼吸短促),但在 Reddit 评论区却可能有完全不同的含义。 😂
The Hallucination Trap 👻
现代的解决方案常被表述为:“直接扔进 ChatGPT/LLM,行不行?”
嗯……有对也有错。
如果你让一个通用的 LLM “总结一下这位患者的情况”,它可以做得很好——直到它做不到为止。医学 AI 中最大的风险是 幻觉(hallucination)。
示例: 一个模型读取到一条笔记中提到“家族史有糖尿病”,却输出了一个结构化的 JSON,声称 患者目前患有糖尿病。
这太糟糕了。 在医疗领域,这类错误是不可接受的。
Source: …
解决方案:RAG + 微调三明治 🥪
为了让数据可查询(例如,“显示所有呼吸系统问题的患者”),且避免 AI 撰写虚假信息,我们需要一个严格的流水线。
1. 微调(教会语言)
开箱即用的模型如 gpt-3.5-turbo 往往缺乏细分专业的细微差别。对较小的模型(例如 Llama 3 或 Mistral)进行 医学文本 微调,可以让模型学习到 bid 在医学中的含义是 “一天两次”(bis in die),而不是拍卖报价。
2. 结构化抽取(翻译器)
我们不让 LLM 直接 “聊天”,而是强制它 抽取 数据到预定义的模式中,使用 Pydantic 或 Instructor 等工具。
import instructor
from pydantic import BaseModel, Field
from openai import OpenAI
# Define the structure we WANT (The Dream)
class ClinicalNote(BaseModel):
patient_age: int
symptoms: list[str] = Field(description="List of physical complaints")
medications: list[str]
diagnosis_confirmed: bool = Field(description="Is the diagnosis final or just suspected?")
client = instructor.patch(OpenAI())
text_blob = "Pt 45yo m, c/o SOB x 2d. Denies CP. Hx of HTN, on lisinopril."
resp = client.chat.completions.create(
model="gpt-4",
response_model=ClinicalNote,
messages=[
{"role": "system", "content": "You are a medical scribe. Extract data accurately."},
{"role": "user", "content": text_blob},
],
)
print(resp.model_dump_json(indent=2))
输出
{
"patient_age": 45,
"symptoms": ["Shortness of Breath"],
"medications": ["lisinopril"],
"diagnosis_confirmed": false
}
现在我们拥有可用于 SQL 查询的数据了! 🚀
3. RAG 用于验证(安全护栏)
即使完成抽取,我们仍需对结果保持信任。我们将原始笔记嵌入向量数据库(如 Pinecone 或 Weaviate)。当用户提问 “该患者有心脏问题吗?” 时,系统:
- 检索包含 “Denies CP” 与 “Hx of HTN” 的特定片段。
- 仅 将该片段喂给 LLM。
- 标注来源。
如果 AI 找不到相关片段,它会被编程为说 “我不知道”,而不是随意猜测。
结论
标准化自由文本临床笔记很痛苦,但这是释放医疗记录价值的唯一途径。我们必须摆脱“魔法黑箱”AI,转向 结构化 AI 流水线——验证输入、强制 JSON 架构,并将一切基于检索到的上下文。
这是一项凌乱的工作,但必须有人去做! 💻✨
想深入了解吗?
查看我的个人博客获取深入分析:wellally.tech/blog