在医疗健康与医疗设备这类高风险应用领域,AI问答系统的准确性与可靠性直接决定了其实际应用价值,甚至可能影响临床或操作层面的关键决策。检索增强生成(RAG)技术通过结合信息检索与大语言模型的能力,本应成为支撑医疗问答的核心架构。然而,传统RAG采用固定流程,在面对医疗场景中复杂的跨知识库问题、未覆盖的新发信息时,往往表现乏力——要么返回不相关内容,要么产生事实性错误的“幻觉”,难以满足医疗行业对答案真实性和全面性的严苛要求。
正是在此背景下,智能体RAG(Agentic RAG)应运而生。它在传统RAG基础上引入了推理与决策机制,具备动态选择检索源、评估信息相关性以及迭代优化答案的能力。其中,LangGraph为实现这种多步推理提供了灵活的工作流编排支持。本文将围绕医疗问答和医疗设备手册两大典型应用场景,详细演示如何构建一套具备自主推理能力的智能体RAG系统,从而显著提升AI在医疗领域的回答精准度与可信度。
医疗场景下的RAG挑战与核心价值解析
RAG的基本原理清晰明了:当用户提出问题时,系统不会依赖大模型凭空作答,而是先从外部知识库中检索最相关的片段,再将这些内容作为上下文输入给大模型以生成最终答案。这种“先检索、后生成”的模式,不仅缓解了大模型上下文长度受限的问题,也大幅降低了生成虚假信息的风险,使输出更具事实依据。
然而,医疗领域的特殊性对RAG提出了远高于通用场景的要求:
- 知识高度专业化且细分:既包括疾病症状、诊疗方案等通用医学问答,也涵盖医疗设备的操作说明、禁忌症、适配条件等专用文档,不同类型的问题需匹配相应的知识库;
- 信息更新速度快:如新型新冠治疗药物的批准、医保政策调整、国际医疗法规变更等,仅依靠静态本地数据库无法及时覆盖;
- 容错率极低:任何误导性或错误的回答都可能带来严重后果,因此必须确保检索结果与问题高度相关,并能有效识别并剔除无关或冲突信息。
传统RAG在应对上述需求时暴露出明显不足:
- 单次检索限制:只能执行一次检索动作,缺乏多跳推理能力。例如无法先从诊疗库获取基础治疗建议,再从设备库查找配套器械信息,最后通过网络搜索补充最新指南;
- 语义相似导致误检:仅基于向量相似度进行检索,容易混淆语义相近但实质不同的术语(如“川崎病”与“克拉伯病”),进而引发模型生成错误答案;
- 检索源固定不变:无论问题是关于设备使用还是最新政策,均从同一知识库中检索,缺乏根据问题类型动态切换数据源的灵活性;
- 扩展性差:受制于上下文窗口大小,难以整合来自多个来源的信息,在处理大规模医疗数据时效率低下,信息融合效果不佳。
要突破这些瓶颈,关键在于赋予RAG“思考”能力——即让系统能够分析问题意图、判断所需知识类型、选择最优检索路径、验证信息有效性,并在初次检索失败时主动尝试替代策略。这正是智能体RAG的设计初衷。
技术选型依据:LangGraph + ChromaDB + SerperAPI 的协同优势
构建智能体RAG的第一步是合理选择技术组件。结合医疗场景的实际需求与部署成本,我们采用了一套轻量化、易集成的技术组合:
- Python:作为主要开发语言,拥有丰富的AI生态支持,便于快速集成各类自然语言处理工具与数据处理模块;
- LangGraph:取代传统的线性流程框架,支持节点定义与条件分支编排,可轻松实现“决策→检索→校验→再检索→生成”的闭环推理结构;
- LangChain:作为LangGraph的辅助工具集,提供现成封装接口,如SerperAPI调用、文档加载器等,加快开发进度;
- Chroma DB:轻量级向量数据库,无需复杂运维配置,支持快速创建集合与文本嵌入存储,适用于医疗问答与设备手册这类中等结构化程度的数据;
- SerperAPI:对接Google搜索引擎的API服务,免费版本提供每月2500次调用额度,可用于实时获取本地知识库未收录的最新医疗资讯;
- OpenAI API:实验阶段选用gpt-5-nano模型完成决策判断、信息校验与答案生成任务,降低计算开销;实际部署时可根据性能需求升级至gpt-5-mini或gpt-5以提升输出质量。
为验证系统有效性,实验选取两个医疗相关CSV数据集(各采样500行,兼顾运行效率与数据多样性):
- 一是医疗问答数据集,包含常见疾病的症状描述、诊断流程与治疗建议等内容,每条记录被格式化为“Question: … Answer: … Type: …”的形式,便于后续向量化检索;
- 二是医疗设备手册数据集,涵盖设备名称、型号、生产厂家、适用范围及禁忌症等字段,统一整理为“Device Name: … Model: … Manufacturer: … Indications: … Contraindications: …”结构,以适配设备类问题的查询需求。
环境搭建与数据准备:向量库初始化与预处理流程
在实现核心推理逻辑前,需首先完成数据清洗、格式转换与工具初始化工作,这是整个系统稳定运行的基础。
1. 数据加载与结构化处理
读取两个医疗数据文件,进行采样与文本规范化处理,构建适合向量检索的统一格式:
import pandas as pd
import os为了优化数据处理流程,首先通过以下方式加载环境配置:
from dotenv import load_dotenv
load_dotenv()
该步骤用于初始化环境变量,确保后续API调用时能够正常获取认证信息。
接下来对医疗领域的两个关键数据集进行预处理。首先是医疗问答数据集的读取与采样:
df_qa = pd.read_csv("medical_q_n_a.csv")
df_qa = df_qa.sample(500, random_state=0).reset_index(drop=True)
为增强语义理解效果,将问题、答案和类型字段合并为统一文本格式:
df_qa['combined_text'] = (
"Question: " + df_qa['Question'].astype(str) + ". " +
"Answer: " + df_qa['Answer'].astype(str) + ". " +
"Type: " + df_qa['qtype'].astype(str) + ". "
)
其次是医疗设备手册数据集的处理:
df_medical_device = pd.read_csv("medical_device_manuals_dataset.csv")
df_medical_device = df_medical_device.sample(500, random_state=0).reset_index(drop=True)
同样构造结构化文本以提升向量化表示能力:
df_medical_device['combined_text'] = (
"Device Name: " + df_medical_device['Device_Name'].astype(str) + ". " +
"Model: " + df_medical_device['Model_Number'].astype(str) + ". " +
"Manufacturer: " + df_medical_device['Manufacturer'].astype(str) + ". " +
"Indications: " + df_medical_device['Indications_for_Use'].astype(str) + ". " +
"Contraindications: " + df_medical_device['Contraindications'].fillna('None').astype(str)
)
这种统一的文本组织形式有助于向量模型更准确地捕捉上下文含义,在检索阶段实现更高精度的匹配。
构建ChromaDB向量数据库
ChromaDB具备轻量级部署优势,支持本地持久化存储而无需复杂配置。下面为上述两类数据分别创建独立集合,类似于数据库中的“表”结构,用于分别保存医疗问答与设备手册的嵌入向量。
import chromadb
client = chromadb.PersistentClient(path="./chroma_db")
创建并填充医疗问答集合:
collection1 = client.get_or_create_collection(name="medical_q_n_a")
collection1.add(
documents=df_qa['combined_text'].tolist(),
metadatas=df_qa.to_dict(orient="records"),
ids=df_qa.index.astype(str).tolist(),
)
创建并填充医疗设备手册集合:
collection2 = client.get_or_create_collection(name="medical_device_manual")
collection2.add(
documents=df_medical_device['combined_text'].tolist(),
metadatas=df_medical_device.to_dict(orient="records"),
ids=df_medical_device.index.astype(str).tolist(),
)
完成数据导入后,可执行简单查询验证检索效果。例如输入“川崎病的治疗方案”,系统能从医疗问答集合中返回相关条目;查询“适用于新生儿的医疗设备”时,设备手册集合可准确输出如起搏器、输液泵等结果,表明向量库构建成功且具备实际检索能力。
[此处为图片2]集成外部工具接口:SerperAPI 与 OpenAI API
为使智能体具备处理未知或超出知识范围问题的能力,需接入实时网络搜索与大语言模型接口,这是实现高效RAG(检索增强生成)的核心环节。
首先配置基于Google Serper的网页搜索功能:
from langchain_community.utilities import GoogleSerperAPIWrapper
SERPER_API_KEY = os.getenv("SERPER_API_KEY")
search = GoogleSerperAPIWrapper()
此模块可用于在用户提问无法通过本地向量库解答时,自动发起网络搜索以获取最新、权威的信息来源。
[此处为图片3]在完成基础配置后,系统能够通过网页搜索获取最新的医疗资讯,同时语言模型(LLM)可根据输入的提示词生成简洁且准确的回答,为后续构建智能体RAG系统奠定技术基础。
以下代码展示了核心配置流程:
test_search = search.run("2025年新冠治疗药物有哪些")
print(test_search)
# 配置OpenAI API
from openai import OpenAI
openai_api_key = os.getenv("OPEN_AI_KEY")
client_llm = OpenAI(api_key=openai_api_key)
def get_llm_response(prompt: str) -> str:
"""调用LLM生成回答的通用函数"""
response = client_llm.chat.completions.create(
model="gpt-5-nano",
messages=[{"role": "user", "content": prompt}]
)
return response.choices[0].message.content
# 测试LLM响应
test_prompt = "用30个字简单解释相对论"
test_response = get_llm_response(test_prompt)
print(test_response)
四、传统RAG的实现及其局限性
为了更好地理解智能体RAG的优势,我们首先搭建一个传统的RAG系统,以直观展现其固定流程带来的限制。传统RAG遵循“检索—构建提示—生成答案”的线性流程,使用LangGraph中的StateGraph来定义三个关键节点。
1. 构建传统RAG的工作流
首先定义状态结构和各处理节点:
from typing import List
from langgraph.graph import StateGraph, START, END
from typing_extensions import TypedDict
# 状态定义
class GraphState(TypedDict):
query : str
prompt : str
context : List[str]
response : str
接下来是三个核心处理函数:
def retrieve_context(state):
"""从医疗问答库中检索相关上下文"""
query = state["query"]
results = collection1.query(query_texts=[query], n_results=3)
context = "\n".join(results["documents"][0])
state["context"] = context
return state
def build_prompt(state):
"""构造用于RAG的提示词"""
query = state["query"]
context = state["context"]
prompt = f"""
根据以下上下文回答问题,答案控制在50字以内。
上下文:
{context}
问题:{query}
"""
state["prompt"] = prompt
return state
def call_llm(state):
"""调用语言模型生成最终回答"""
prompt = state["prompt"]
answer = get_llm_response(prompt)
state["response"] = answer
return state
随后构建并连接整个工作流图:
# 创建状态图实例
workflow = StateGraph(GraphState)
workflow.add_node("Retriever", retrieve_context)
workflow.add_node("Augment", build_prompt)
workflow.add_node("Generate", call_llm)
# 设置执行顺序
workflow.add_edge(START, "Retriever")
workflow.add_edge("Retriever", "Augment")
workflow.add_edge("Augment", "Generate")
workflow.add_edge("Generate", END)
# 编译得到可执行的agent
rag_agent = workflow.compile()
2. 传统RAG的实际测试效果
以“川崎病的治疗方案”作为查询示例,系统能成功从知识库中检索出相关信息,并生成符合要求的答案。这表明在问题匹配已有数据时,传统RAG具备基本可用性。
然而,当提出如“2025年印度医疗片剂出口美国的关税是多少”这类超出知识范畴的问题时,系统仍会强行从医疗问答集合中提取无关内容进行作答,导致输出结果严重错误。
这一现象揭示了传统RAG的根本缺陷:检索来源固定不变,无法根据问题类型动态选择信息源,也缺乏对检索结果相关性的判断机制,容易产生误导性回答。
五、智能体RAG的关键升级:引入多步推理与动态决策能力
针对上述局限,智能体RAG通过增强系统的推理能力和流程灵活性,实现了从“被动响应”到“主动思考”的转变。其核心改进在于支持多步骤任务分解、条件分支判断以及基于反馈的自我调整,从而能够在复杂或未知问题面前做出更合理的应对策略。

智能体RAG的关键在于为系统赋予“决策”与“校验”能力,其流程优化为:查询 → 路由器(选择数据源)→ 检索 → 相关性检查 → 生成(必要时触发网页搜索重试)。该架构仍基于LangGraph实现,但引入了条件边和重试机制,使工作流具备动态调整的能力。
1. 构建智能体RAG的核心处理节点
首先定义实现智能体功能所需的关键节点,包括:数据源路由判断、多来源信息检索、上下文相关性验证、提示词构造以及最终的回答生成。
from typing import Literal
# 状态结构定义(新增数据源、相关性标识、迭代计数)
class GraphState(TypedDict):
query: str
context: str
prompt: str
response: str
source: str # 记录当前使用的检索源
is_relevant: str # 标识上下文是否相关
iteration_count: int # 控制最大重试次数
多源检索处理函数
根据不同类型的问题,从对应的知识库中提取相关信息:
def retrieve_context_q_n_a(state):
"""从医疗问答数据库中检索相关内容"""
query = state["query"]
results = collection1.query(query_texts=[query], n_results=3)
context = "\n".join(results["documents"][0])
state["context"] = context
state["source"] = "Medical Q&A Collection"
return state
def retrieve_context_medical_device(state):
"""从医疗设备手册数据库中检索内容"""
query = state["query"]
results = collection2.query(query_texts=[query], n_results=3)
context = "\n".join(results["documents"][0])
state["context"] = context
state["source"] = "Medical Device Manual"
return state
def web_search(state):
"""通过网络搜索获取补充信息"""
query = state["query"]
search_results = search.run(query=query)
state["context"] = search_results
state["source"] = "Web Search"
return state
路由器节点:智能选择检索源
根据用户提问的内容自动判断应使用哪个数据源进行检索:
def router(state: GraphState) -> Literal["Retrieve_QnA", "Retrieve_Device", "Web_Search"]:
"""依据问题类别决定检索路径"""
query = state["query"]
decision_prompt = f"""
你是路由智能体,根据用户问题选择检索源:
- Retrieve_QnA:适用于通用医疗知识、症状描述、治疗方案等问题
- Retrieve_Device:涉及医疗设备、操作手册或使用说明的问题
- Web_Search:需获取最新资讯、政策变动或外部公开数据的情况
问题:"{query}"
请仅返回以下之一:Retrieve_QnA、Retrieve_Device、Web_Search
"""
router_decision = get_llm_response(decision_prompt).strip()
state["source"] = router_decision
return router_decision
上下文相关性校验节点
用于评估所检索到的信息是否真正匹配用户问题:
def check_context_relevance(state):
"""验证检索结果与原始问题的相关性"""
query = state["query"]
context = state["context"]
relevance_prompt = f"""
请判断以下上下文是否与用户问题相关,回答仅限Yes或No。
上下文:
{context}
用户问题:{query}
"""
relevance_decision = get_llm_response(relevance_prompt).strip()
state["is_relevant"] = relevance_decision
return state
提示词构建与回答生成节点
此步骤与传统RAG方法类似,负责整合上下文并生成简洁回应:
def build_prompt(state):
query = state["query"]
context = state["context"]
prompt = f"""
根据以下上下文回答问题,答案控制在50字以内。
2. 构建智能体RAG工作流的编译过程
接下来需要定义各节点之间的连接关系,重点在于配置条件边,以实现“决策→检索→校验→必要时重试”的动态控制流程。
# 创建状态图实例
workflow = StateGraph(GraphState)
# 注册各个处理节点
workflow.add_node("Router", router)
workflow.add_node("Retrieve_QnA", retrieve_context_q_n_a)
workflow.add_node("Retrieve_Device", retrieve_context_medical_device)
workflow.add_node("Web_Search", web_search)
workflow.add_node("Relevance_Checker", check_context_relevance)
workflow.add_node("Augment", build_prompt)
workflow.add_node("Generate", call_llm)
# 设置初始路径:从START指向路由器节点
workflow.add_edge(START, "Router")
# 配置路由器的条件跳转逻辑
workflow.add_conditional_edges(
"Router",
route_decision,
{
"Retrieve_QnA": "Retrieve_QnA",
"Retrieve_Device": "Retrieve_Device",
"Web_Search": "Web_Search",
}
)

# 所有检索分支均汇入相关性检查节点
workflow.add_edge("Retrieve_QnA", "Relevance_Checker")
workflow.add_edge("Retrieve_Device", "Relevance_Checker")
workflow.add_edge("Web_Search", "Relevance_Checker")
# 定义相关性判断后的走向:若内容相关则进入提示构建,否则触发网络搜索重试
workflow.add_conditional_edges(
"Relevance_Checker",
relevance_decision,
{
"Yes": "Augment",
"No": "Web_Search",
}
)
# 最终执行链路:构建提示 → 调用语言模型生成答案 → 结束流程
workflow.add_edge("Augment", "Generate")
workflow.add_edge("Generate", END)
# 完成并编译整个智能体RAG流程
agentic_rag = workflow.compile()
[此处为图片2]
3. 多场景测试用于验证智能体RAG的实际效果
通过四个典型用例对智能体系统进行测试,评估其在复杂任务中的多步推理与决策能力:
测试场景一:常规医疗知识问答(如川崎病的治疗方案)
系统经由路由器判定应使用医疗问答库,选择“Retrieve_QnA”路径。成功检索到对应医学资料后,经过相关性验证节点确认信息匹配度高,直接进入答案生成阶段。输出结果准确,表现与传统RAG相当,但整体流程更具结构化和可调控性。
测试场景二:特定医疗器械查询(例如透析机的功能用途)
路由模块识别问题属性后,转向设备文档数据库执行检索(即“Retrieve_Device”)。获取到包括型号参数、临床应用范围及禁忌症等详细信息,且校验环节判定内容高度相关,最终生成的回答精准贴合专业设备使用语境。
测试场景三:超出本地知识范围的政策类问题(如2025年印度向美国出口药片的关税政策)
由于该类前瞻性政策数据未存在于内部知识库中,初始检索无法获得有效内容,相关性检测返回“No”。系统随即根据条件边规则转入“Web_Search”路径进行外部信息补充,并尝试重新评估可用资源。此机制确保了面对未知或动态更新问题时仍具备响应能力。
通过路由器直接决策“Web_Search”,系统调用SerperAPI成功检索到2025年美国对印度药品实施100%关税的相关信息。经相关性校验确认无误后,生成的回答与事实一致,验证了该路径的有效性。
在场景4中,面对关于新冠治疗药物的提问,系统初始选择“Retrieve_QnA”策略。然而,在医疗问答知识库中未匹配到相关内容,相关性校验结果为“No”。此时,系统自动切换至“Web_Search”模式,成功获取当前主流新冠治疗药物(如Paxlovid、Remdesivir等)的最新数据,并据此生成准确答案。

上述四个测试场景的结果表明,智能体RAG具备根据问题类型动态选择最优检索源的能力,能够有效进行信息相关性判断,并在初次检索失败时主动重试。这一机制从根本上缓解了传统RAG所面临的诸多核心问题。
六、智能体RAG的价值分析与落地实践思考
从传统RAG演进至智能体RAG,表面上仅是增加了若干节点和条件分支,实则实现了系统行为的根本转变——由被动执行转向主动推理。尤其在医疗这类高风险领域,这种升级带来的实际价值尤为突出:
- 提升回答精准度:借助路由决策和相关性校验机制,系统可有效规避使用无关上下文生成答案的风险,显著降低幻觉现象的发生概率,这对保障医疗信息准确性至关重要。
- 增强场景适配能力:既能高效响应本地知识库覆盖范围内的常规问题,也能通过网络搜索获取最新的医学进展、政策变动等超出预置知识的内容,实现更全面的信息覆盖。
- 降低部署门槛:整体架构采用轻量级工具构建,无需依赖复杂的基础设施支持,使得中小企业或基层医疗机构也能快速完成部署并投入使用。
尽管如此,当前版本的智能体RAG仍有进一步优化空间。例如,可通过引入医疗领域专用关键词词典来优化路由策略,减少大模型在判断过程中的偏差;也可扩展多轮对话功能,以支持用户连续追问;此外,接入更多权威数据源(如最新临床指南、药品说明书等)也将进一步提升系统的专业性和可靠性。
即便如此,这套轻量化的智能体RAG方案已能胜任大多数常见医疗问答需求,标志着RAG技术正朝着更智能、更稳健的方向迈进。
结语
RAG的核心意义在于确保AI输出的内容有据可依,而智能体RAG则在此基础上赋予系统推理与决策能力。本文结合医疗应用场景,利用LangGraph搭建了一个具备多步逻辑推理能力的智能体RAG系统,完整呈现了从数据处理、向量化存储、传统RAG实现,到最终升级为智能体架构的全流程。
该方法论不仅适用于医疗行业,还可迁移应用于金融、法律等对信息准确性要求极高的领域。其关键不在于技术堆叠的复杂程度,而在于为RAG流程注入“判断”与“验证”的环节,使系统能根据不同问题灵活调整应对策略。
展望未来,随着大语言模型能力的持续增强以及工作流编排工具的发展,智能体RAG有望成为RAG架构的主流形态,推动AI在更多高风险、高标准的应用场景中发挥实质性作用。


雷达卡


京公网安备 11010802022788号







