RAG检索结果不准如何解决?
RAG检索结果不准如何解决?
1. 实际案例
用户问“布洛芬能不能和感冒药一起吃?”但回答不相关
最初系统返回的检索内容是:
- 布洛芬的退烧作用
- 感冒的症状介绍
- 药品剂量说明
检索不准
没有召回“药物相互作用”相关内容,导致大模型回答很泛,甚至出现模糊建议。
2. 排查过程
① 文档切分方式
发现说明书被固定长度切分,导致:
- “药物相互作用”段落被拆散
- 语义完整性丢失
- 向量表达不准确
② 查询语义问题
用户说“感冒药”,但知识库中是:
- 复方氨酚烷胺
- 对乙酰氨基酚
- 抗组胺类
口语表达与医学术语不一致
③ 检索排序问题
只做了向量相似度排序,没有:
- 关键词过滤
- 领域优先级控制
导致高频“药品介绍”被优先召回。
3. 解决方案
1️⃣ 语义切分优化
- 按说明书结构切分(适应症 / 用法 / 相互作用)
- 保证每个 chunk 语义完整
提高向量表达质量
2️⃣ 查询增强(Query Rewrite)
对用户问题进行结构化增强,例如:
原问题:
布洛芬能不能和感冒药一起吃
增强后检索 query:
布洛芬 药物相互作用 联合用药 禁忌
👉 让检索更偏医学语义
3️⃣ 检索结果过滤与重排
- 设定领域优先级:相互作用 > 功效介绍
- 向量召回 + 关键词匹配双重筛选
- 限制 topK 并设置相关度阈值
👉 降低无关内容进入上下文
4. 优化后:
- 能稳定召回“联合用药风险”相关内容
- 医疗问答准确性明显提升
- 幻觉回答明显减少
5. 具体解决方案
医疗说明书结构切分
正确切分方式应该是:
| chunk | 内容 | metadata |
|---|---|---|
| 1 | 适应症段落 | type=indication |
| 2 | 用法用量 | type=dose |
| 3 | 不良反应 | type=adverse |
| 4 | 相互作用 | type=interaction |
自定义结构切分器
1 | |
👉 把一整篇医疗文档按医学结构拆开
👉 给每一块打上语义标签(metadata)
👉 输出适合做向量化的知识块
结合 TokenTextSplitter 做二次切分
有些段落仍然很长,可以:
1️⃣ 先结构切分
2️⃣ 再限制 token 长度
1 | |
利用metadata 参与检索
例如存储:
1 | |
查询时可以:
✔ 只检索 interaction 类别
✔ 提高联合用药问题召回率
Spring AI 查询示例思路:
1 | |
在 RAG 入库阶段,我没有采用默认的固定长度切分,而是根据医疗说明书的结构进行语义切分,比如适应症、用法用量和药物相互作用分别作为独立知识块,并为每个 chunk 添加结构化 metadata。
这样在向量检索时可以结合语义相似度和结构过滤,提高特定问题场景下的召回准确率。对于较长段落,我会再结合 token 切分控制上下文长度,然后统一写入 Milvus 向量库。