LangChain 在生命科学与医疗保健领域的应用

148 阅读52分钟

包括OpenAI的Sam Altman、Google DeepMind的Demis Hassabis以及Anthropic的Dario Amodei在内的多家知名AI公司领导者,均对其AI技术在医疗领域的变革潜力表达了坚定的信心。

前几章探讨了生成式AI如何变革科研、生物学、化学及药物发现。随着大数据的发展,谷歌、微软、IBM等大型科技公司开始大力投资医疗健康领域,利用AI提升医疗诊断、患者管理及整体医疗系统效率。早期成果包括基于AI的医学影像分析、疾病进展预测分析以及医院自动化工作流程。如今,生成式AI持续推动药物发现和个性化医疗的创新边界。

谷歌通过其AI研究部门DeepMind及健康项目,成为AI应用于医学的领军者。Google Health致力于医学影像和电子健康记录(EHR)等AI工具的开发,DeepMind则凭借AlphaFold在蛋白质结构预测领域取得突破。2021年,谷歌以21亿美元收购Fitbit,强化其在可穿戴健康技术和AI驱动的个人健康数据洞察领域的地位。

苹果也进入了健康领域,凭借Apple Watch设备自第四代起具备经FDA认证的心电图(ECG)功能。苹果与斯坦福大学合作开展了针对40万Apple Watch用户的苹果心脏研究,检测心房颤动。其手表现已支持糖尿病管理功能,并在部分实体店销售One Drop Chrome血糖监测仪及配件。苹果CEO蒂姆·库克表示:“如果你从未来回顾,苹果对人类最大的贡献将会是健康。”

微软在医疗领域同样取得重大进展。其云平台Azure已成为众多医院和医疗服务提供商的热门选择,提供预测性医疗和数据管理的AI工具。微软的AI工具帮助医生分析患者数据,预测潜在健康风险。此外,微软Dragon Copilot通过多种AI工具优化临床工作流程,让医护人员更多关注患者护理,减少行政负担。

亚马逊通过Amazon Care和Amazon Pharmacy进入医疗领域。Amazon Care提供远程医疗服务,支持虚拟诊疗;Amazon Pharmacy致力于简化患者获取药物的流程。类似谷歌和微软,亚马逊云服务(AWS)为医疗提供云端AI工具,涵盖患者数据管理及疾病爆发预测等方面。

在公共医疗领域,全球各国政府正采用数据实践和AI技术,管理大量健康数据,优化医院管理,提升患者护理质量。例如,英国国家医疗服务体系(NHS)已部署AI工具,辅助疾病诊断和患者记录管理。AI驱动的预测模型帮助政府预测医疗需求、合理分配资源,应对公共卫生危机。美国国立卫生研究院(NIH)大力投资AI研究,支持药物发现、疾病诊断和个性化医疗项目。美国食品药品监督管理局(FDA)处于监管AI医疗设备的前沿,制定相关安全有效的指导原则。加拿大卫生研究院(CIHR)支持AI在医疗中的应用研究,重点涵盖医学影像、基因组学和群体健康。

AI在个性化医疗中的潜力巨大,能够帮助医生根据患者的病史、遗传信息和生活方式定制治疗方案。AI工具分析海量患者数据,优化诊断并推荐个性化疗法。苹果、Fitbit等可穿戴设备持续采集实时健康指标,如心率、活动量和睡眠模式,AI处理这些数据,向用户提供可操作的健康洞察,预警潜在风险并鼓励预防措施。随着AI技术发展,其与医疗的融合持续加深,但数据隐私、算法偏见和临床验证等挑战仍需重点关注。Kerrie Holley和Manish Mathur的《LLMs and Generative AI for Healthcare》(O’Reilly)一书涵盖了多个相关用例。

远程医疗也是AI影响深远的领域。AI驱动的远程医疗平台实时连接患者与远程医生,利用AI对患者需求进行分诊并提供即时医疗建议。

随着技术进步,医生配备了更先进的设备。许多设备输出为视觉形式,因此医学影像成为AI重要应用之一。AI帮助放射科医生识别扫描中的异常,识别X光、MRI和CT扫描中的模式,标记肿瘤、骨折等潜在问题,协助医生更快更准确地诊断。

越来越多医疗企业采用AI改善行政工作。AI可自动化排班、账单处理和保险理赔,减轻医务人员的行政负担,释放更多时间专注患者护理(Kerrie Holley和Siupo Becker的《AI-First Healthcare》详细介绍了更多基于AI的医疗应用)。通过分析患者数据,AI帮助医生更好地理解患者病史,提供个性化护理。医院和诊所越来越多地使用聊天机器人和AI虚拟助手处理基本患者咨询,缩短等待时间,帮助医护人员集中精力处理更重要的任务。

生成式人工智能在医疗健康领域的应用

随着越来越多机构认识到生成式AI在简化运营和提升患者护理方面的潜力,医疗健康企业对其采用率稳步提升。各类医疗机构开始利用通用及医疗专用的大型语言模型(LLMs)辅助临床医生完成文档工作,并促进护理班次之间的顺畅交接。根据Fierce Healthcare与Sermo的调查,约有四分之三的医生可能在临床实践中使用LLMs。AI的主要应用包括药物相互作用检测、诊断支持、临床文档生成、治疗方案规划、患者教育和文献检索。

注意
market.us近期报告显示,2022年全球医疗健康市场中的生成式AI价值约为8亿美元,预计到2032年将达到172亿美元。

本章将探讨更多应用案例,并开发一个多任务医疗应用,充分利用AI的优势。在此之前,我们先来看看常被忽视的潜在挑战。

一个主要问题是数据隐私和安全。鉴于医疗数据的高度敏感性,使用这些数据训练LLM时,必须实施强有力的保护措施以保障患者隐私和机密性。美国的HIPAA等法规对医疗数据处理有严格要求,使得机构在创新与合规之间难以平衡。确保数据隐私的同时使用大规模数据集,会减缓开发速度并引发伦理问题,尤其是涉及个人健康信息时。第10章对此话题有更深入的探讨。

另一个重大挑战是AI模型中的偏见。生成式AI系统可能无意中继承训练数据中的偏见,导致医疗结果不公平或不准确。例如,若数据集中某些人群代表性不足,AI可能无法为这些群体提供准确的诊断或治疗方案。此外,LLMs的“黑盒”特性使得决策过程难以理解(尽管可以解释下一个词元的预测和追踪推理模型的逻辑),这带来了医疗专业人员和患者在可解释性及信任方面的问题。

此外,将生成式AI集成到现有医疗系统中,是一项技术和部署上的挑战。对于自托管LLMs,扩展性和与现有基础设施的兼容性常成为技术和财务上的障碍。更重要的是,AI在医疗领域中的伦理使用问题,尤其是在诊断和治疗方案规划等关键决策环节,凸显了制定健全指南以确保AI驱动医疗的责任性和可问责性的必要性。

创建生成式医疗应用

本书迄今主要使用OpenAI的LLMs,医疗领域更适合微调或专门训练的模型。本节展示本地医疗模型、谷歌Healthcare API、Google和Anthropic推出的替代模型Gemini和Claude(分别对应ChatVertexAI和ChatAnthropic),以扩展模型选择和用户灵活性。还将探讨语音转文本、基于SQL的RAG、摘要和报告生成,最后组建多智能体AI助手团队回答问题。

头脑风暴助手

第6章实验过化学调优模型,第7章微调过基于生物数据的DeepSeek R1模型。医疗微调模型效果更佳,因医疗文本数据量远超化学、生物领域。医疗模型基于海量医疗数据训练,能发现常见词元间的关联,如特定症状对应疾病。

示例9-1展示两个本地可部署医疗LLM——medalpaca和medllama,任务是根据医生笔记推测可能疾病和治疗。示例保持提示一致以便比较输出。使用@tool装饰器便于后续在头脑风暴智能体中调用。

import transformers
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

model_name = "medalpaca/medalpaca-7b"
model = AutoModelForCausalLM.from_pretrained(model_name)

# 或者
model = AutoModelForCausalLM.from_pretrained(
    "PrunaAI/medalpaca-medalpaca-7b-bnb-4bit-smashed",
    trust_remote_code=True, device_map='auto')

tokenizer = AutoTokenizer.from_pretrained(model_name)

@tool
def call_medalpaca(text):
    """基于医生笔记,回答可能疾病及治疗的医疗模型medalpaca"""
    prompt = f"""You are a professional doctor.\n
        Context: Doctors notes: {text}.\n
        Question: List all potential illnesses and treatment\n
        Answer: Possible illnesses and treatment: """
    input_ids = tokenizer(prompt, return_tensors='pt').to(model.device)["input_ids"]
    outputs = model.generate(input_ids,
        max_new_tokens=256, do_sample=True, temperature=0.001, top_k=5, top_p=0.95
    )
    answer = tokenizer.decode(outputs[0])
    return answer

model = "johnsnowlabs/JSL-MedLlama-3-8B-v17-8bits"
tokenizer = AutoTokenizer.from_pretrained(model)
js_pipeline = transformers.pipeline(
    "text-generation",
    model=model,
    torch_dtype=torch.float16,
    device_map= "auto",
)

@tool
def call_medllama(text):
    """基于医生笔记,回答可能疾病及治疗的医疗模型medllama"""
    messages = [
        {
            "role": "system", "content": """
                You are a professional doctor. You are given doctors notes.
                Suggest possible illnesses and treatment.""",
        },
        {"role": "user", "content": text},
    ]
    prompt = tokenizer.apply_chat_template(
        messages, tokenize=False, add_generation_prompt=True
    )
    pipe = js_pipeline(prompt,
        max_new_tokens=256, do_sample=True, temperature=0.001, top_k=5, top_p=0.95
    )
    return pipe[0]["generated_text"]

两模型针对以下医生笔记的回答示例:

doctors_notes_raw_input = """
Patient is John Baker. The patient's reason for the visit was due to cough and
high temperature,  which should be noted as fever and cough. Physical
examination reveals no significant abnormalities in vital signs, with a blood
pressure reading of 120/80 mmHg and a heart rate of 72 bpm. No visible edema or
significant weight changes noted; the patient weighs 160 lbs and has a height
of 5'10".
The patient is in good health and prescribed antibiotics with instructions to
take one tablet every 8 hours with food. Additionally, the patient's next
appointment is scheduled for a follow-up in 2 weeks.
"""

medalpaca给出多种可能感染,但未聚焦于患者的具体症状,泛泛而谈各种感染类型及通用治疗方案;medllama则聚焦呼吸道感染,区分病毒性与细菌性感染,结合体检结果和抗生素处方进行临床推理,提供详细分析和治疗建议,帮助医生确定后续问诊和检查方向,尤其有助于罕见疾病诊断。

随后将介绍谷歌的医疗AI工具。由于medGemini未公开,我们用LangChain调用包含医疗上下文的Gemini模型,设计多智能体LangGraph系统(前章已有示例)。示例9-2只给出本章相关代码片段,完整代码和输出见LangChain4LifeSciencesHealthcare仓库。

作为谷歌Healthcare API的一部分,我们将使用两套许可词汇表:

  • SNOMEDCT_US(美国临床术语系统化命名)
  • ICD10CM(美国疾病分类第十版临床修订版)

两者均用于标准化临床术语和诊断分类。SNOMEDCT_US为多语种临床术语库,涵盖疾病、发现、操作及其他临床数据。ICD10CM主要用于美国医疗账单和报告中的诊断编码。

以下为示例9-2的代码与输出:

def healthcare_nl(text: str) -> str:
    """ 向Healthcare自然语言API发送REST请求 """
    url = f"https://healthcare.googleapis.com/...nlp:analyzeEntities"
    # 需要Google Cloud Platform的token
    headers = {
        "Authorization": f "Bearer {token}",
        "X-Goog-User-Project": PROJECT_ID,
    }
    data = {
        "documentContent": text,
        "licensedVocabularies": ["SNOMEDCT_US", "ICD10CM"]
    }
    response = requests.post(url, headers=headers, data=json.dumps(data))
    return response.json()

# 工具设置
toolkit = [list_of_medical_terms, medical_llm]
tool_node = ToolNode(toolkit)

# 模型绑定工具
model = llm.bind_tools(toolkit, parallel_tool_calls=False)

# 配置带记忆的langgraph智能体(参见第5章、第7章)
medical_graph_app = workflow.compile(checkpointer=memory)

config = {"configurable": {"thread_id": "1"}}
input_message = HumanMessage(content=doctors_notes_raw_input)
for event in medical_graph_app.stream(
        {"messages": [input_message]}, config, stream_mode="values"
    ):
    > event["messages"][-1].pretty_print()

输出显示,谷歌的analyzeEntities服务将“咳嗽”识别为“问题”,并且“很可能”与患者相关。list_of_medical_terms工具提取了多项医疗术语,medical_llm结合原始文本及提取术语生成诊断意见。以下为Gemini-2.0-flash-001模型给出的初步诊断:

初步诊断:可能为上呼吸道感染(如支气管炎、肺炎)。

推理依据:患者出现发热和咳嗽,为呼吸道感染典型症状。体征和体检无明显异常(无水肿或体重变化)提示感染较轻。抗生素处方指向细菌性感染。两周后复诊为常规监测治疗反应及感染情况。

重要提示:尽管信息指向常见呼吸道感染,依据症状严重度及持续时间,或患者未对抗生素响应,可能需进一步检查(如胸片、痰培养)。该初步诊断需后续评估确认。

各模型输出结果一致,能为医生提供不同视角、后续问诊方向及结论。LangGraph支持配置应用参数,如选择LLM、系统消息、会话等,相关信息通过“configurable”键传入,详见示例9-2和9-3。示例9-3演示了切换线程ID查询病人信息,因线程独立,预期结果为智能体无法获知病人详情。

config = {"configurable": {"thread_id": "2"}}
query = "What the situation with John Baker"

input_message = HumanMessage(content=query)
for event in medical_graph_app.stream(
        {"messages": [input_message]}, config, stream_mode="values"
    ):
    >event["messages"][-1].pretty_print()

输出:

========== Human Message ==========
What is the situation with John Baker
========== Ai Message ==========
I need more information to understand John Baker's situation. Can you provide me
with some text describing his medical condition, doctor's notes, or lab results?

LangChain在医疗头脑风暴中的作用不仅是简单的LLM查询或RAG信息检索,还能通过提供基于证据的建议辅助医疗决策。此方法优势包括响应迅速,允许医护人员在患者就诊时即时提出后续问题,尤其降低罕见病漏诊风险。同时,可调节头脑风暴创造力,平衡事实与创意,优化诊疗思路。

高级头脑风暴场景

让我们考虑一个更高级的病人就诊用例。病人带着初步主诉前来,随后会根据医生建议进行两项检查。示例9-4使用了示例9-2和9-3中同样的LangGraph智能体。我们假设数据已经被提取(这可以通过多种方法实现,比如使用相同的医疗API或利用大模型,关于这部分我们将在“报告生成”章节详细讨论)。和示例9-3一样,为了便于阅读,生成的输出内容放在代码段下方。

示例9-4 病人的首次就诊

data = [{
    "gender": "male",
    "age": 48,
    "systolic_blood_pressure": 135,
    "diastolic_blood_pressure": 85,
    "Symptoms": "fatigue and occasional mild lower back discomfort",
    "notable_details": "increased frequency of nocturia",
}]
prompt_chat = f"""
    You are a doctors assistant.\n\nPatients data: {data}. Suggest
    potential illnesses, methods how to understand that's the true illness and
    further treatment. Summarize the diagnostic methods to define next steps."""
config = {"configurable": {"thread_id": "3"}}

input_message = HumanMessage(content=prompt_chat)
for event in medical_graph_app.stream(
        {"messages": [input_message]}, config, stream_mode="values"
    ):
    >event["messages"][-1].pretty_print()

让我们来看下面代码片段中的AI生成内容。AI智能体(medical_graph_app)基于症状识别潜在疾病,并建议包括实验室检查在内的诊断方法。后续治疗步骤将依据分析结果而定,但对医疗专业人员给出了一般性建议。该medical_graph_app可调用之前提到的专用medical_llm模型和list_of_medical_terms工具。外部大模型负责管理沟通并根据工具响应生成答案,最终只格式化medical_llm的响应:

(前例续)
#-------------------------AI生成内容开始-------------------------
========== 人类消息 ==========
你是医生助理。患者数据:[{'gender': 'male', 'age': 48, 'systolic_blood_pressure': 135, 'diastolic_blood_pressure': 85, 'symptoms': 'fatigue and occasional mild lower back discomfort', 'notable_details': 'increased frequency of nocturia'}]。请建议潜在疾病,说明如何确认真正的疾病及进一步治疗方法。总结诊断步骤并定义后续方案。
========== AI消息 ==========
...
首先,我会使用 list_of_medical_terms 工具识别患者症状和显著细节中的医学术语。这将帮助我聚焦案件最相关的方面。
...
类别类型: ['BODY_FUNCTION', 'MED_FREQUENCY', 'PROBLEM', 'SEVERITY']
医学术语: ['fatigue', 'mild', 'nocturia', 'discomfort']
========== 工具消息 ==========
名称: list_of_medical_terms
["fatigue", "mild", "nocturia", "discomfort"]
========== AI消息 ==========
现在我有了医学术语,将调用 medical_llm 工具,基于患者数据和识别出的术语获取医学意见。
...
参数: 文本:男,48岁,收缩压135,舒张压85,疲劳及偶发轻度腰部不适,夜尿频率增加
术语: ['fatigue', 'mild', 'nocturia', 'discomfort']
========== 工具消息 ==========
名称: medical_llm
潜在疾病
初步结论:这位48岁男性患者表现出早期良性前列腺增生(BPH)的典型症状。其血压轻度升高(临界高血压),可能相关或另有问题。疲劳、轻度腰部不适和夜尿是BPH的典型表现。需进一步评估,包括直肠指检和尿液分析,以确认诊断并排除尿路感染或其他前列腺疾病。建议监测血压。
========== AI消息 ==========
基于现有信息和工具分析,以下是潜在疾病、诊断方法及后续治疗的总结:

潜在疾病:

  • 早期良性前列腺增生(BPH)
  • 临界高血压

诊断方法:

  • 直肠指检
  • 尿液分析
  • 血压监测

后续步骤(诊断方法总结):

  1. 直肠指检: 评估前列腺大小及状态。
  2. 尿液分析: 排除尿路感染或其他前列腺问题。
  3. 血压监测: 确认临界高血压并评估是否需进一步管理。

进一步治疗(根据工具建议):
工具建议需进一步评估以确认BPH诊断并排除其他可能病因。诊断结果将决定治疗方案,可能包括生活方式调整、药物治疗或手术。临界高血压的管理则可能涉及生活方式改变或用药。
#-------------------------AI生成内容结束---------------------------

总结来说,智能体基于症状识别出良性前列腺增生和临界高血压两种潜在疾病。为明确病因,建议做直肠指检、尿液分析和血压监测。在本场景中,医生安排了尿液分析,并决定进行多项血液检测。患者首次检查结果见表9-1。

我们的 medical_graph_app 智能体可以将检测结果作为反馈使用。输出格式没有限制——它可能是医疗中心实验室分析中使用的标准医学表格。

表9-1 初步检查结果

检测项目结果参考范围备注
血红蛋白(Hb)13.8 g/dL13.5–17.5 g/dL正常
白细胞计数(WBC)6000 cells/mm³4500–11000 cells/mm³正常
血小板(PLT)250,000 cells/mm³150,000–450,000 cells/mm³正常
血清肌酐(SCr)1.2 mg/dL0.6–1.2 mg/dL正常上限
血尿素氮(BUN)15 mg/dL7–20 mg/dL正常
尿液分析—蛋白微量阴性轻度异常
尿液分析—血液阴性阴性正常
血压(BP)135/85 mmHg<120/80 mmHg边缘升高

如你所见,大多数结果都在参考范围内。理想情况下,AI智能体应重点关注边缘值或异常值,而不是被正常值干扰。在接下来的代码中,注意“微量蛋白”被提取出来并作为关键词之一,与之前提取的患者症状(疲劳、轻度、夜尿、不适)一起传入模型,这促使模型将早期慢性肾病作为主要考虑方向。

小贴士
将表格转换成 JSON 格式并以字符串形式传递,通常比直接传递表格效果更好。

下一段代码显示模型能够合理关联实验室发现与患者临床表现,正确建议后续诊断措施,包括重复尿液分析、计算估算肾小球滤过率(eGFR)以及进一步评估。所有数据和代码可在 LangChain4LifeSciencesHealthcare 仓库中找到:

prompt_chat = f"""Below are the patient's lab analysis: """
prompt_chat += str(kidney_scenario_data['initial_examination'])
input_message = HumanMessage(content=prompt_chat)
for event in medical_graph_app.stream(
        {"messages": [input_message]}, config, stream_mode="values"
    ):
    >event["messages"][-1].pretty_print()

#-------------------------AI生成内容开始-------------------------
========== 人类消息 ==========
下面是患者的实验室分析:{'CBC': {'血红蛋白(Hb)': {'result': '13.8 g/dL', ...}}}
========== AI消息 ==========
好的,我将把实验室分析结果纳入评估。
工具调用:
medical_llm (4b572531-5760-426b-a3d2-497c1c134101)
...
关键词: ['fatigue', 'mild', 'nocturia', 'discomfort', 'trace protein']
========== 工具消息 ==========
名称: medical_llm

初步结论:这位48岁男性患者表现出疲劳、轻度腰部不适及夜尿症状。血压轻度升高(135/85 mmHg),实验室结果显示肌酐轻度升高(1.2 mg/dL),尿中有微量蛋白。其他血液指标(血红蛋白、白细胞、血小板、BUN)均在正常范围内。症状组合和肌酐轻度升高提示早期慢性肾病(CKD)的可能性。夜尿和腰部不适也可能与良性前列腺增生(BPH)有关,后者在该年龄段较为常见。需进一步检查以明确症状原因及微量蛋白尿和肌酐升高的临床意义。建议重复尿液分析、计算eGFR及可能进行前列腺检查。

========== AI消息 ==========
基于实验室分析和更新的医学意见,修订后的评估如下:

潜在疾病:

  • 早期慢性肾病(CKD)
  • 良性前列腺增生(BPH)
  • 临界高血压

诊断方法:

  • 重复尿液分析
  • 估算肾小球滤过率(eGFR)计算
  • 前列腺检查(直肠指检)
  • 血压监测

后续步骤(诊断方法总结):

  1. 重复尿液分析: 确认蛋白尿的持续性,排除暂时性蛋白尿。
  2. eGFR计算: 评估肾功能。
  3. 前列腺检查: 进行直肠指检评估前列腺状态。
  4. 血压监测: 继续监测血压变化。

进一步治疗(根据工具响应):
建议进一步检查以明确症状的病因及蛋白尿和肌酐升高的临床意义。根据诊断结果确定后续治疗方案。
#-------------------------AI生成内容结束---------------------------

可以看到,AI智能体展现了从实验室报告中提取并响应关键信息的强大能力,特别是识别了肌酐轻度升高这一虽在参考范围边缘但却是肾功能微弱异常的重要指标。它还将尿中微量蛋白与潜在肾脏问题联系起来,强调了进一步评估的必要性。模型展现的是类推和推理能力,而非简单的复述或机械生成。未来模型会更加智能,但从这段文字已能看到AI的初步智能火花。

表9-2 显示了患者第二轮实验室检查结果。注意与表9-1相比,部分指标已超出参考范围。我们可以在将这些数据录入智能体后,分析模型得出的结论。

表9-2 复查结果

检测项目结果参考范围备注
血红蛋白(Hb)12.5 g/dL13.5–17.5 g/dL略低
白细胞计数(WBC)5800 cells/mm³4500–11000 cells/mm³正常
血小板(PLT)260,000 cells/mm³150,000–450,000 cells/mm³正常
血清肌酐(SCr)1.7 mg/dL0.6–1.2 mg/dL升高
血尿素氮(BUN)22 mg/dL7–20 mg/dL升高
尿液分析—蛋白1+阴性异常(蛋白尿)
尿液分析—血液微量阴性轻度异常(显微镜下血尿)
血压(BP)140/90 mmHg<120/80 mmHg升高

第二轮检查结果显示肾功能显著恶化,应作为主要关注点。肌酐较之前边缘值(1.2 mg/dL)明显升高至1.7 mg/dL,同时伴有血尿素氮(BUN)升高(22 mg/dL)和尿蛋白增加(1+),均提示肾脏损伤。此外,尿中出现血液及血压进一步升高(140/90 mmHg),表明肾脏问题加重,同时高血压可能反过来加剧肾损害。诊断重心已从最初怀疑的泌尿系统疾病(BPH/前列腺炎)明显转向急性或慢性肾损伤,需立即专科干预。

AI 智能体准确捕捉到血清肌酐从1.2 mg/dL升至1.7 mg/dL;血尿素氮(BUN)升高至22 mg/dL,超出正常范围7–20 mg/dL;尿液分析显示尿蛋白为1+,尿中微量血液存在。它还正确指出蛋白尿加重及显微镜下血尿的出现,这在首次分析中未被提及:

prompt_chat = f"""Below are the patients follow-up analysis: """
prompt_chat += str(kidney_scenario_data['follow_up_examination'])
input_message = HumanMessage(content=prompt_chat)
for event in medical_graph_app.stream(
        {"messages": [input_message]}, config, stream_mode="values"
    ):
    >event["messages"][-1].pretty_print()

#-------------------------AI生成内容开始-------------------------
========== 人类消息 ==========
下面是患者的复查分析:{'CBC': {'血红蛋白(Hb)': {'result': '12.5 g/dL' ...}}}
========== AI消息 ==========
工具调用:
medical_llm (e819bb6b-5270-499d-aa38-0ef5ff5c426a)
...
关键词: ['fatigue', 'mild', 'nocturia', 'discomfort', 'proteinuria', 'hematuria']
========== 工具消息 ==========
名称: medical_llm

初步结论:这位48岁男性患者表现出早期慢性肾病(CKD)和可能的高血压的相关症状和体征。血压升高(140/90 mmHg)、疲劳、夜尿、以及肌酐(1.7 mg/dL)和血尿素氮(22 mg/dL)升高均指向肾功能障碍。尿蛋白(1+)和显微镜下血尿(微量血液)的存在进一步支持该诊断。轻度腰部不适可能与肾脏问题相关,但也应考虑其他原因。需要进一步检查以确定慢性肾病的病因和分期。建议重复测量血压,进行24小时尿蛋白和肌酐清除率测定,以及肾脏超声检查。同时应加强高血压的管理。

========== AI消息 ==========
基于复查分析和更新的医学意见,修订后的评估如下:

潜在疾病:

  • 早期慢性肾病(CKD)
  • 高血压

诊断方法:

  • 重复血压测量
  • 24小时尿蛋白及肌酐清除率测定
  • 肾脏超声检查

后续步骤(诊断方法总结):

  1. 重复血压测量: 通过多次测量确认高血压诊断。
  2. 24小时尿液收集: 定量尿蛋白排泄及测算肌酐清除率,更准确评估肾功能。
  3. 肾脏超声检查: 评估肾脏结构,排除结构异常。

进一步治疗(根据工具响应):
建议进一步检查明确慢性肾病病因及分期,同时对高血压进行管理。
#-------------------------AI生成内容结束---------------------------

可以看到,智能体先分析了复查结果,比较了前后数据,优先考虑可能的疾病。它将所有发现综合起来,给出了比最初更严肃的临床评估。医学判断从最初怀疑早期慢性肾病与良性前列腺增生并存,逐步明确为以早期慢性肾病和高血压为主要关注点。诊断方案也从简单的复查尿液和估算肾小球滤过率,升级为24小时尿蛋白和肌酐清除率测定及肾脏超声,评估更全面细致。

如本章所述,类似此案例的AI诊断助手系统,结合更多功能模块,将成为医疗领域的变革力量,极大提升诊断准确率、效率和医疗服务的可及性。这类系统能分析复杂的医疗数据——包括实验室结果、患者症状、生命体征及医学影像——识别模式和潜在诊断。通过持续提供一致的分析支持,突出关键检测结果,AI助手有助减少诊断错误,加快诊断流程,使医护人员更快制定治疗方案。它们还可集成于内建数据管道系统,借助更多上下文提升推理能力,并及时提醒急诊医生。尤其在资源有限的环境中或需早期干预显著改善预后的疾病管理上,这类系统价值尤为突出。

整合语音转文本技术

第2章讨论了文本通常作为不同信息源之间的“中介”,比如图像、音频、分子结构等。为了实现文本的生成,我们将在示例9-5中实现一个语音转文本(STT)智能体。

准确捕捉病人与医护人员的每一句交流极为重要,但同时也很具挑战性。市场上存在多个STT服务提供商,除非另有说明,我们默认使用OpenAI的Whisper模型。尽管Whisper存在“幻觉”问题,医疗行业仍快速采用此类模型,这些模型有时会生成似是而非但不准确的内容。例如,据报道Whisper错误识别了患者未提及的特征,医疗文档中出现错误过敏信息,还会不适当地插入训练数据中常见的短语(比如“感谢观看”)。

这些问题的根源在于AI模型的基本工作机制。类似大型语言模型(LLM),Whisper基于训练数据预测最可能出现的下一个词元,而非确保生成语句的准确性。Whisper训练时用到了超过50万小时的网络音频数据,主要是带字幕的YouTube视频和网络电影。这些大量带时间戳的人工标注音频为训练自动语音识别(ASR)模型提供了绝佳素材。

注释
ASR(自动语音识别)和STT(语音转文本)两词常被交替使用,但含义略有不同。ASR强调技术和流程,侧重于准确识别和理解语音模式并转写成文本;STT则是更简化的说法,强调最终用户看到的功能,即将口语转换为文本。

当遇到音频不清晰或语境陌生时,模型往往根据训练数据生成统计上最可能的回答,而非依据实际内容,这可能导致“过拟合”——将训练集中常见短语错误插入结果中。例如,在音频录音沉默时,Whisper常会“幻觉”般地生成典型YouTube结尾语,如“感谢观看”或“订阅我的频道!”

另一个问题出现在最新微调的Whisper v3多语言版本上。假设你已抓取了所有YouTube和电影数据,但无法获得更多高质量人工标注数据用于进一步训练,尤其是低资源语言(因为超过半数数据是英语)。你可能会认为利用现有AI能力自动给未标注数据打标签,再投入训练是最经济的方式。但实际上,虽然数据量增加,生成内容中的错误也会同步增加!告诉模型它生成的内容质量很高,可能导致模型性能停滞甚至退步。

注释
评估字错误率(WER,ASR常用指标)常用的基准测试有WSJ、FLEURS、Swbd,测试中说话者在清晰环境下朗读或对话。但这些受控条件远比真实环境下处理音频要简单得多。更大的问题是训练数据中的偏差,往往缺乏性别、年龄和韵律多样性。

标点符号识别率下降也是个问题,因Whisper按30秒音频块处理,容易遗漏块间标点。模型试图同时预测下一个词和转录内容,有时会基于上下文做出错误假设。

那么LangChain如何助力?在使用不同STT和ASR模型时,我发现它们有时比我更“准确”。真实音频中常有含糊、口误,我不希望这些错误直接呈现在文本里。在某些场景下,模型预测下一个词的尝试可能带来更多益处而非伤害。基于ASR构建LangChain应用,可以实现从纯STT向医疗笔记转录的正确过渡,如图9-1所示。这个过渡可多种方式实现:从提示工程,到高亮可能发音错误的文本,再到结合多个ASR模型和LLM的混合技术。第6章中也简要讨论过类似的拼写错误修正(以化学数据库拼写为例)。

图9-1中,普通Whisper出现了多处错误,比如把“auscultation”(听诊)误听为“oscillation”(振荡)、“medical”误为“medial”等。尽管模型受到批评,Whisper仍是最优ASR模型之一。我也见过其他STT服务将“thromboplebitis”误转录为“from both the business”和“palpable cord indicative as cable cord in the cave”等奇怪短语。

虽然STT转换的核心是声学转录,用户普遍期望输出内容“有意义”。有效的STT系统会尽力利用上下文信息和语言模型,不仅生成语音的音素对应文本,还保证语义合理。第3章和第4章介绍了多个LangChain组件,其中之一即加载器(loader)。

image.png

示例9-5创建了一个工具,使用OpenAIWhisperParser对音频进行转录,转录结果会传递给基于gemini-1.5-pro模型的链进行拼写错误修正。正如图9-1所示,改进后的结果仅有一个错误。这个简单且灵活的示例将在后续示例中作为更大LangGraph应用的一部分使用。

示例9-5 使用LangChain进行拼写错误修正

@tool
def load_and_transcribe_audio(filename):
    """语音转文本工具。
       通过文件名加载音频文件并转录文本"""
    loader = GenericLoader.from_filesystem(
        filename,
        parser=OpenAIWhisperParser()
    )
    docs = loader.load()
    return docs[0].page_content

prompt_template = """你是一名医疗助理。
    以下转录文本取自语音识别,可能包含拼写错误。
    请勿添加或删除词语——仅在合理情况下,修改发音相近的现有词语。
    转录文本:{text}"""

transcript = load_and_transcribe_audio(filename)
llm = VertexAI(
    model_name="gemini-1.5-pro", max_output_tokens=8042, temperature=0
)
prompt = PromptTemplate.from_template(prompt_template)
chain = prompt | llm | StrOutputParser()

> vertex_ai_response = chain.invoke({"text": transcript})

将ASR模型和大语言模型(LLM)串联的主要优势之一是具备上下文理解能力。在医疗领域,许多术语并非日常用语,LangChain应用可以大幅减轻手工笔录的负担。这些链不仅可以辅助患者与医生对话中的作者身份确认,还能集成进电子健康记录(EHR)等其他工具,或接入更多数据管道和数据源。

RAG(检索增强生成)应用于SQL

第4章介绍了使用RAG管道避免幻觉问题,第8章讨论了基于图数据库的RAG。将RAG应用于SQL,能实现类似之前提到的自然语言与结构化数据库的交互。核心思路是:将自然语言查询转换成SQL语句,执行生成的查询以检索数据,并利用提取的上下文返回生成的结果。

RAG over SQL可架起复杂医疗数据库与非SQL专家医护人员之间的桥梁。该方法允许医疗人员使用自然语言查询患者记录、治疗历史和临床数据,确保答案基于真实数据库记录,而非潜在幻觉信息。此外,医护人员能生成复杂查询,从而更全面地洞察患者数据,支持知情决策并提升患者疗效。

我们将在RAG管道中使用若干表。patients_visits表记录多个患者的就诊信息(部分内容见表9-3),包括ID、姓名、年龄、诊断、检测结果及就诊次数和日期。

表9-3 患者就诊表

Patient_IDNameAgeDiagnosisTest_ResultsSessionDate
1John Doe35HypertensionNormal blood pressure12022-01-01
1John Doe35HypertensionHigh cholesterol22022-01-15
2Jane Smith28AsthmaPulmonary function test12022-02-01
2Jane Smith28AsthmaChest X-ray22022-02-15
2Jane Smith28AsthmaAllergy testing32022-03-01
3Bob Johnson42DiabetesGlucometer readings12022-03-15
3Bob Johnson42DiabetesKidney function test22022-04-01
3Bob Johnson42DiabetesEye exam32022-04-15
7Michael Brown45DiabetesGlucometer readings12022-08-01
7Michael Brown45DiabetesKidney function test22022-08-15

每位患者可有多条记录,取决于就诊次数。例如Jane Smith和Bob Johnson均有三次就诊记录。备注简短,记录医生与患者的交流内容,如药物变更或检测结果,便于跟踪病情进展和回顾既往治疗。

第3章介绍了链与智能体的原理。示例9-6演示了一个基础链,用于生成并执行SQL语句。该链遵循先前描述的线性流程:解析→生成→执行→返回。链的开发有两种方法:基础和高级。基础方法使用create_sql_query_chain和QuerySQLDataBaseTool,调用Claude LLM基于用户提问生成SQL查询并执行。高级方法配置更完整,先生成查询,执行时让模型根据问题、SQL语句和结果写出答案,产生更具上下文的回答。

示例9-6 问:40岁以上患糖尿病的患者有哪些?

from operator import itemgetter
from langchain_anthropic import ChatAnthropic
from langchain_community.utilities import SQLDatabase
from langchain_community.tools.sql_database.tool import QuerySQLDataBaseTool
from langchain_core.prompts import PromptTemplate
from langchain_core.runnable import RunnablePassthrough
from langchain.chains import create_sql_query_chain

llm = ChatAnthropic(model="claude-3-5-sonnet-20240620", temperature=0)
db = SQLDatabase.from_uri(
    'sqlite:///patients.db',
    include_tables=['patients_info', "patients_visits"],
    sample_rows_in_table_info=2
)

# 基础方法
execute_query = QuerySQLDataBaseTool(db=db)
write_query = create_sql_query_chain(llm, db)
chain = write_query | execute_query

> chain.invoke({"question":"What patients over 40 are diagnosed with diabetes?"})

生成内容报错:SQL语句前多写了说明文字,导致语法错误。

高级方法同样出现问题,因模型输出中含多余描述,导致SQL无法执行。

此问题根本原因是模型生成的SQL语句未与纯SQL内容严格分离。解决方案有多种,包括提示工程和输出解析,但最优方法是使用智能体(agent)。前章提及,LangChain的create_react_agent实现的智能体具备以下优势:

  • 通过ReAct框架逐步推理
  • 内置错误处理与查询验证
  • 可在查询前探索数据库结构
  • 遇错时能动态修正

示例9-7演示使用create_react_agent创建智能体,结合SQLDatabaseToolkit调用sql_db_list_tables、sql_db_schema、sql_db_query_checker、sql_db_query等工具,完成目标表识别、SQL查询生成和执行。

示例9-7 使用LangChain的create_react_agent实现RAG over SQL

from langchain_community.agent_toolkits import SQLDatabaseToolkit
from langchain.agents import AgentExecutor, create_react_agent

sql_toolkit = SQLDatabaseToolkit(db=db, llm=llm)
sql_tools = sql_toolkit.get_tools()
template = """Answer the following questions as best you can. You have access
        to the following tools: {tools}
        Use the following format:
        Question: the input question you must answer
        Thought: you should always think about what to do
        Action: the action to take, should be one of [{tool_names}]
        Action Input: the input to the action
        Observation: the result of the action
        ... (this Thought/Action/Action Input/Observation can repeat N times)
        Thought: I now know the final answer
        Final Answer: the final answer to the original input question

        Begin!
        Question: {input}
        Thought:{agent_scratchpad}"""

prompt = PromptTemplate.from_template(template)
agent = create_react_agent(llm, sql_tools, prompt)
agent_executor = AgentExecutor(
    agent=agent, tools=sql_tools, handle_parsing_errors=True, verbose=True
)

> agent_executor.invoke({"input": "What patients over 40 are diagnosed with diabetes?"})

智能体执行过程示例输出:

  • 首先列出数据库中可用表
  • 检查相关表结构以定位查询字段
  • 生成SQL查询并用查询检查器验证
  • 确认无误后执行查询
  • 返回包含患者姓名、年龄、诊断的结果

最终回答:
40岁以上诊断为糖尿病的患者包括:

  1. Bob Johnson,42岁
  2. Michael Brown,45岁

总结来看,智能体通过生成并校验SQL语句,成功执行查询并得到最终结果。如生成SQL有语法错误,智能体会将错误信息与生成的SQL返回给前一工具,生成新的有效查询,体现了其动态错误处理能力。

在最新版本的 LangChain 中,越来越多的关注点转向了 LangGraph。create_react_agent 方法同样可以通过 LangGraph 实现,如示例 9-8 所示,相较于传统链式方法,它还带来了一些额外优势:

  • 对智能体状态管理的更细粒度控制
  • 通过状态持久化实现更好的错误恢复
  • 增强的信息传递能力
  • 通过图结构架构实现更灵活的工具集成

出于可读性考虑,前述提示中的修改版 SQL_PREFIX 未在正文展示,但可在本书的 LangChain4LifeSciencesHealthcare 仓库中找到。

示例 9-8 使用 LangGraph 的 create_react_agent 实现 RAG over SQL

from langchain_core.messages import SystemMessage
from langgraph.prebuilt import create_react_agent

SQL_PREFIX = """You are an agent designed to interact with a SQL database..."""
system_sql_message = SystemMessage(content=SQL_PREFIX)
agent_executor = create_react_agent(
    llm, sql_tools, messages_modifier=system_sql_message
)
> agent_executor.invoke({"messages": [HumanMessage(content="What patients over 40 are diagnosed with diabetes?")]})

#-------------------------AI生成内容开始-------------------------
智能体交互示例输出片段:

  • “当然!为回答关于40岁以上诊断糖尿病患者的问题,我需要查询数据库。先查看数据库中有哪些表。”(调用 sql_db_list_tables)
  • “很好,数据库中有 patients_info 和 patients_visits 两个表。接下来检查它们的表结构,找出我们需要的信息。”(调用 sql_db_schema)
  • “根据表结构,patients_visits 包含我们需要的信息,有 Age 和 Diagnosis 列。现在构造SQL查询语句查找40岁以上诊断为糖尿病的患者。查询语句如下:…”(调用 sql_db_query_checker)
  • “查询语句正确,开始执行查询。”(调用 sql_db_query)
  • “根据查询结果,我可以回答你的问题:有两位40岁以上诊断为糖尿病的患者:1. Bob Johnson,42岁;2. Michael Brown,45岁。查询限制为5条,但数据库中只有这两位患者符合条件。请问你还想了解这些患者的其他信息或关于糖尿病的其他问题吗?”

#-------------------------AI生成内容结束---------------------------

上述示例揭示了成功实现的几个关键点:

  • 合理的系统提示对维护上下文至关重要
  • 应在多个层级实现错误处理
  • 医疗领域的响应格式应符合医学文档标准

未来可以通过集成更多工具和智能体,提升对医学术语的理解能力,处理命名边界情况,使LangGraph应用更加强大和灵活。

摘要

在医疗领域引入大语言模型(LLM)用于摘要,代表了一种变革性的手段,帮助应对每天产生的大量医疗文档——包括电子健康记录、临床笔记、研究论文,以及现场就诊和消息系统中的患者交流(正如我们在语音转文本章节中讨论的)。这种文档负担不仅加剧医生的职业倦怠,还增加了因冗长文本遗漏关键信息的风险。摘要应用场景多样,包括:

  • 临床笔记合成
    自动将冗长的患者就诊记录浓缩成可操作的摘要,加快医护人员之间的信息交接。
  • 研究文献综述
    汇总医学研究论文,帮助临床医生及时掌握最新领域进展。
  • 临床试验文档
    总结试验方案和结果,辅助决策制定与合规管理。

小贴士
考虑到LangChain应用,数据摘要也适用于上下文记忆管理。因此在第3章中,我们使用了ConversationSummaryBufferMemory,这种内存类型存储对话摘要,而非完整文本。

摘要文本主要有两种流行方法。第一种是使用专门微调的模型。就医疗领域而言,示例9-9中展示的Falconsai/medical_summarization模型是一种选择。该类模型专门针对医疗语料训练,优化了医疗专业术语和语境的处理。

示例9-9 使用领域微调模型进行摘要

from transformers import pipeline
summarizer = pipeline("summarization", model="Falconsai/medical_summarization")

@tool
def summarize_medical_text(text):
    """摘要工具,用于总结医生的医疗笔记"""
    summary = summarizer(text, max_length=100, min_length=50, do_sample=False)
    return summary[0]['summary_text']

第二种方法借助提示工程技术,使用通用LLM,通过精心设计的提示指导摘要过程。示例9-10展示了一种结构化的摘要提示,要求模型围绕医疗文本生成并详细回答五个关键问题。

示例9-10 使用提示工程进行摘要

summarization_prompt = """
    1.) 分析输入文本,生成5个关键问题,这些问题的答案能抓住文本的主要观点和核心含义。
    2.) 设计问题时应:
        a. 聚焦中心主题或论点
        b. 确认关键支持观点
        c. 突出重要事实或证据
        d. 揭示作者目的或视角
        e. 探讨重要的影响或结论
    3.) 逐条详细回答所有生成的问题。
"""

chain = prompt | llm | StrOutputParser()

选择哪种方法取决于具体使用场景。专门模型适合对速度和准确性要求极高的关键临床应用;而提示工程则适用于更通用的医疗文档或需要更大灵活性的情况。表9-4比较了这两种策略的优缺点。

表9-4 模型摘要与提示工程摘要方法对比

方面专门模型提示工程
准确度对医疗术语准确率较高准确度不稳定,依赖提示质量
灵活性限于训练场景适应多样化需求
定制化受限于模型参数通过提示高度定制
实现复杂度实现较简单需要精心设计提示
成本较高(模型训练/授权)较低(使用通用LLM)

随着LLM技术不断发展,未来将出现结合两者优势的更复杂方法及其他创新方案。医疗和健康组织在考虑实施LLM摘要时,应综合评估自身需求、技术能力及合规要求,合理选择方案。结合两种技术并从试点项目开始,有助于找出针对具体用例的最优解决方案。

报告生成

LangChain 应用在医疗领域中另一个能够显著自动化流程的场景是报告生成。在这种情况下,LangChain 让你能够利用大语言模型(LLM)最强大的能力之一——将纯文本转换为结构化数据。这极大减少了人为错误的风险,确保每份报告都能被信赖用于患者护理。

举例来说,我们来看一个简单的医生就诊表单。大多数医院和医疗机构已经有现成的模板可用,但这里我们采用一个简化的通用表单,并写一个脚本来创建模板。示例9-11包含了从纯文本中提取数据、查询数据库,并基于检索到的数据、系统时间字段、组织信息、患者就诊原因及健康评估、处方和下次就诊信息生成报告的代码。从生成式AI的角度看,我们根据之前定义的schema生成JSON或字典格式的数据。

示例9-11 从医生笔记提取数据

from datetime import datetime
current_datetime = datetime.now()
system_data = {
    "date": current_datetime.strftime("%Y-%m-%d"),
    "time": current_datetime.strftime("%I:%M %p"),
    "hospital": "St. Mungo's Hospital",
    "doctor_name": "Dr. Miriam Strout",
}
schema = {
    "title": "doctors_visit",
    "description": "Doctors visit template",
    "type": "object",
    "properties": {
        "patient_id": {
            "type": "string",
            "description": "患者的内部ID"
        },
        "patient_name": {
            "type": "string",
            "description": "患者姓名"
        },
        ...,
        "required": ["patient_name", "reason_for_visit_doctor", ...]
    }
}
doctors_notes_raw_input = """Patient is John Baker.
    The patient's reason for the visit was due to cough
    and high temperature,  which should be noted as fever and cough. Physical
    examination reveals no significant abnormalities in vital signs, with a blood
    pressure reading of 120/80 mmHg and a heart rate of 72 bpm. No visible edema or
    significant weight changes noted; the patient weighs 160 lbs and has a height
    of 5'10".
    The patient is in good health and prescribed antibiotics with instructions to
    take one tablet every 8 hours with food. Additionally, the patient's next
    appointment is scheduled for a follow-up in 2 weeks."""

@tool
def extract_data_from_doctors_notes(doctors_notes_raw_input):
    """从医生笔记中提取数据并保存为结构化字典"""
    structured_llm = llm.with_structured_output(schema)
    result = structured_llm.invoke(doctors_notes_raw_input)
    return result

> extract_data_from_doctors_notes(doctors_notes_raw_input)

#-------------------------AI生成内容开始-------------------------

{
  "patient_name": "John Baker",
  "reason_for_visit_patient": "cough and high temperature",
  "reason_for_visit_doctor": "fever and cough",
  "weight": "160 lbs",
  "height": "5'10"",
  "blood_pressure": "120/80 mmHg",
  "heart_rate": "72 bpm",
  "prescription": "antibiotics",
  "prescription_instruction": "Take one tablet every 8 hours with food.",
  "next_appointment_reason": "follow-up in 2 weeks"
}

#-------------------------AI生成内容结束---------------------------

...
<用于将 <<figure-9-2>> 中占位符替换为提取值的逻辑>

完成繁重的数据提取工作后,我们即可基于提取的数据生成报告。这是最简单的部分,我们将系统数据(日期、时间、医院等)、数据库数据(ID、年龄、地点)和提取数据(症状、健康状况、下次就诊)汇总到一个字典中,填充原始文档的占位符。生成的报告(见图9-2)可以设计成可编辑,便于医生后续修改。这些细微调整远比自己完整撰写报告节省大量时间。

image.png

多团队应用

让我们再次回顾本章涵盖的场景。我们开发了一个头脑风暴助理,帮助医疗专业人员进行诊断和治疗;将医生的语音录音转换处理为文本;从SQL数据库中检索数据;总结医生笔记;并为患者就诊生成报告。

如果想开发一个统一的应用,它可能符合经典的三幕结构:起始(Setup)、冲突(Confrontation)和解决(Resolution)。LangChain 的优势在于,它能够轻松将所有应用通过链式或图结构串联到一个整体中。

在前几章构建 LangGraph 团队时,我们创建了多个智能体,分别负责不同任务,并借助工具完成工作。本章中的 report_graph 团队包含了这些智能体和工具——语音转文本(STT)、基于SQL的RAG、报告生成及解析智能体。图9-3展示了该智能体结构。完整代码可在 LangChain4LifeSciencesHealthcare 仓库获得。

示例9-12 演示如何调用 report_graph,从音频生成报告,并观察团队执行的全部步骤。

for s in report_graph.stream(
    # 根据团队代码,此处可能是字符串 "Generate report of ..."
    {
        "messages": [
            HumanMessage(content= """Generate report of the patients visit
                                     from .../doctors_notes_001.mp3?"""
            )
        ],
    },{"recursion_limit": 250}
):
    pass  # 处理或打印流式输出

#-------------------------AI生成内容开始-------------------------
智能体执行流程示例:

  • {'supervisor': {'next': 'SpeechTranscriber'}}
  • {'SpeechTranscriber': {'messages': [HumanMessage(content="...")]}}
  • {'supervisor': {'next': 'DatabaseEngineer'}}
  • {'DatabaseEngineer': {'messages': [HumanMessage(content="...")]}}
  • {'supervisor': {'next': 'ReportGenerator'}}
  • {'ReportGenerator': {'messages': [HumanMessage(content="...")]}}
  • {'supervisor': {'next': 'FINISH'}}
    #-------------------------AI生成内容结束---------------------------

尽管有多个智能体,这类图团队仍缺乏解决复杂任务所需的多样性。第5章和第7章讨论并实现了分层团队的概念,即将已有团队视为超级图的节点。在图9-3中,构建了一个超级分层团队,其中 ReportTeam(示例9-12)和 BrainstormTeam 实际上是子团队。

image.png

示例9-13演示了对super_graph的调用。请注意流式通信的层级——只显示了子团队对话的最终结果。这类团队能够解决更广泛的任务。

示例9-13 执行多层团队智能体(头脑风暴)

# SQL数据库中的数据片段:
# 8,Sarah Taylor,40,Female,345 Spruce St,666-777-8888,
# sarah.taylor@email.com,High cholesterol,Obesity,Nuts

for s in super_graph.stream(
    {
        "messages": [
            HumanMessage(content= "What might be the reason of high sugar
                                   levels of Sarah Taylor?"
            )
        ],
    }, {"recursion_limit": 250},
):
    pass  # 处理或打印流式输出

#-------------------------AI生成内容开始-------------------------
智能体交互示例片段:

  • {'supervisor': {'next': 'DatabaseEngineer'}}
  • {'DatabaseEngineer': {'messages': [HumanMessage(content="...")]}}
  • {'supervisor': {'next': 'BrainstormTeam'}}
  • {'BrainstormTeam': {'messages': [HumanMessage(content='Sarah Taylor有高胆固醇和肥胖病史。她近期的就诊显示被诊断为高胆固醇,已被开具阿托伐他汀并建议饮食调整。\n\n血糖升高可能由多种因素影响,包括:\n1. 肥胖:常与胰岛素抵抗相关,导致血糖升高。\n2. 饮食:若饮食调整未见效或摄入高糖食物,可能促使血糖升高。\n3. 药物:阿托伐他汀主要调控胆固醇,但其他药物或药物相互作用也可能影响血糖。\n4. 缺乏运动:缺乏规律运动也可能导致血糖升高。\n\n建议她与医疗提供者全面咨询,针对这些问题制定方案。')]}}
  • {'supervisor': {'next': 'FINISH'}}
    #-------------------------AI生成内容结束---------------------------

在头脑风暴环节,我们可以使用不同API和模型,涵盖本地部署、云服务、通用模型和医疗微调模型。从生成的假设来看,所有内容均基于DatabaseEngineer从数据库检索并传递给BrainstormTeam的数据。

你可以用同样的结构创建多个团队来应对不同的解决方案。例如,可以创建临床试验团队、远程医疗团队、医疗政策团队等,利用本章介绍的智能体和子团队:

临床试验团队
专注于临床试验的管理和分析:

  • SpeechTranscriber:转录与试验相关的访谈或讨论
  • SummarizationAgent 和 ParsingAgent:协助总结和结构化大量数据
  • ReportGenerator:汇编调查结果形成预定义报告
  • BrainstormerResearcher:协助研究最新方法和最佳实践
  • ClinicalTrialEvaluator:评估试验的有效性和安全性

远程医疗团队
回答患者健康相关问题:

  • SpeechTranscriber:转录患者投诉或反馈
  • SummarizationAgent 和 ParsingAgent:总结和结构化产生的数据,ReportGenerator汇总成报告
  • BrainstormerResearcher:访问并分析科学文献
  • MedicalImagingAnalyst:解读医学影像

医疗政策团队
专注于医疗政策的制定与分析:

  • BrainstormerResearcher:提出创意,获取数据,探索相关文献
  • SummarizationAgent:总结复杂的政策文件
  • ReportGenerator:生成政策分析报告

正如你所见,AI智能体可以复用于不同工作场景。每个团队和用例场景都利用智能体的独特能力,针对医学和医疗中的具体挑战提供支持,从研发、患者护理到公共健康领域均有所覆盖。

在医疗与医学领域采用人工智能

在我们回顾了多个LangChain应用的潜在用例后,不得不正视一个重要问题:数据隐私、伦理考量以及确保公平访问仅仅是需要克服的诸多障碍中的一部分。医疗模型训练需要大量数据,但使用个人信息必然带来隐私问题。数据的缺乏和多样性不足,都会导致未来AI模型存在潜在偏见。

一个重大缺口是对建立消费者信任重视不够。虽然很多消费者已开始在医疗决策中使用AI,但他们希望对自身数据的使用过程保持透明。可扩展性也是关键挑战,数据管道集成与机器学习运维等技术和运营难题需被精心规划,以保障医疗AI的可持续部署。第10章将介绍生成式AI部署的最佳实践。

另一个显著问题是幻觉现象(详见第4章),这在对患者安全和临床决策至关重要的医学领域是不可接受的。如果AI模型在病历中产生误导信息或建议错误诊断,后果可能非常严重。还有担忧认为,即使表现良好的AI系统,也可能无法理解复杂医学案例的细微差别,若医疗人员过度信任其输出,可能造成伤害。

再有一个问题是合规监管。许多生成式AI工具,如AI驱动的转录和助记解决方案,在全球100多个国家被归类为医疗设备软件(SaMD),必须遵守国际医疗器械监管论坛(IMDRF)的指导原则。这些工具旨在辅助临床决策,使用未经批准或验证不足的设备将面临重大法律和职业风险。在其他情境下,医疗机构绝不会使用未经批准的医疗器械,如手术刀或呼吸机,因而尽管生成式AI技术有价值,目前仍无法被广泛应用。此种矛盾凸显了急需明确的监管框架以及医疗从业者对AI风险的深入理解。

医疗中心正急于利用生成式AI工具抢占市场。正如本章开头提到的,多项调查显示,绝大多数日常使用生成式AI的医生会对AI进行临床决策支持审核,调研同行评审文献,并咨询同事。有人认为,医生在使用AI生成内容(无论是纳入报告还是发送给患者)前必须进行审核。然而透明度存在疑虑——部分医疗系统不要求披露AI的使用情况,医生甚至可删除消息中的AI披露声明。缺乏统一标准和监管引发了对正确实施的质疑。第10章将讨论生成式AI应用相关的监管内容。

医疗和医学领域将持续采用并规范生成式AI方法。效率需求和成本降低潜力推动医疗组织采纳AI,但越来越多的声音呼吁建立恰当的保障措施。重点逐渐从使用通用LLM转向开发专用医疗AI工具,更加注重准确性和安全性而非单纯效率。美国食品药品监督管理局(FDA)已批准数千款AI/ML医疗设备,并积极构建监管框架。FDA发布了草案指导,阐明其对这类技术监管的思路,预计未来AI工具提交审查和授权的数量将持续增长。此外,国家卫生信息技术协调办公室(ONC)将从2025年起要求技术供应商披露其AI工具如何与电子健康记录系统交互,以提升透明度。

我认为生成式AI的采用将走向更为结构化的路径。预计专用医疗AI工具将更加普遍,逐渐取代通用LLM。在安全性方面,未来几年内应会实现完善的验证和测试流程,结合多种验证方法(如临床决策支持工具、同行评审、同事介入),开发防止AI幻觉进入医疗记录的安全机制,并建立完善的患者告知与披露流程。

“你希望[监管]是深思熟虑的,而不是扼杀创新。但你也希望它保护社会。”
—— Brian Anderson 医学博士,健康AI联盟首席执行官

总结

本章展望了人工智能在医疗领域的未来,探讨了生成式AI和LangChain如何变革医疗与医学,基于此前关于AI在科研、生物学和药物发现中的应用讨论。章节重点介绍了谷歌、苹果、微软和亚马逊等大型科技公司对医疗技术的兴趣,尤其是利用AI提升医学诊断、患者管理和医疗系统效率的潜力。

本章通过多个实际案例展示了LangChain在医疗领域的应用。包括使用专门调优的医疗大语言模型(如medalpaca和medllama)辅助诊断,构建基于谷歌医疗API的多智能体LangGraph系统以提取和分析医学实体,实现医疗对话的语音转文本功能。示例强调AI不仅能辅助医疗专业人员进行诊断头脑风暴、分析实验室结果,还能关联表面看似无关的症状,且在过程中解释推理逻辑,而非简单复述信息。章节还涵盖了基于SQL数据库的RAG,实现患者记录的自然语言查询,医疗文档的摘要技术,以及医生笔记的自动报告生成。

章节专门介绍了构建分层AI智能体团队结构以处理复杂医疗任务。这些超级团队整合了SpeechTranscriber、DatabaseEngineer、ReportGenerator、BrainstormTeam等多个专业智能体,实现从音频录音生成报告或对患者数据进行诊断分析的端到端综合工作流。

最后一章探讨了在生产环境中部署生成式AI应用的关键考量,聚焦安全防护、最佳实践和替代框架,以确保在医疗和生命科学等敏感领域安全有效地实施。内容包括企业AI应用的数据安全、隐私保护、合规框架,以及基于大语言模型应用的评估和监控方法。章节还全面回顾了LangChain与LangGraph的替代方案和补充工具,从数据集成框架到多智能体系统一应俱全。