首页 / 文章 / 降低医疗RAG聊天机器人流程中的幻觉现象

降低医疗RAG聊天机器人流程中的幻觉现象

了解混合搜索、重新排序以及严格的反伪造政策如何结合在一起,打造出更值得信赖的医学研究RAG聊天机器人。

1960 词

这个项目最初有一个简单的目标。

那就是打造一个能够根据医学研究论文回答问题的聊天机器人。

这应该相当简单,对吧?

事实并非如此。

最初的实现采用了相当常规的RAG架构:导入文档、生成嵌入向量、将其存储在向量数据库中、检索出相关内容片段,再传递给大语言模型。

它确实能运行。

但可靠性不足。

而在医学领域,“可靠性不足”是个严重的缺陷。

一个自信却给出错误答案的聊天机器人,远比那些承认“我缺乏足够信息来回答”的机器人更危险。

这一认识促使检索流程进入持续优化的阶段。

第一个问题:幻觉现象

最亟需解决的难题是幻觉问题。

语言模型在生成看似可信的答案方面能力极强,有时甚至过于可信。

当文档中不存在相关答案时,模型往往会用自己的内部知识填补空白,而非承认不确定性。

这种行为必须改变。

聊天机器人的答案必须严格来自所提供的研究资料,而非模型的想象。

因此,其背后的理念也发生了转变。

不再将大型语言模型视为事实的权威,取而代之的是以检索到的文档作为真正的信息来源。

大型语言模型的作用则被限制在解读这些检索到的内容,并将其整理成连贯的回复。

而当现有信息不足时呢?

系统应当拒绝猜测。

从基础RAG开始

该架构的最初版本看起来很简单:

这代表了标准的RAG模式。

大型文档会被分割成较小的片段,每个片段都会被嵌入并存储在向量数据库中。

每当用户提出问题时,该问题也会被嵌入其中。

系统随后会搜索那些嵌入向量在语义上相近的片段。

理论上很简单。

但很快就会出现一个问题。

语义相近并不保证实际相关性。

为何向量搜索不够用

想象一下用户这样提问:

“胰岛素抵抗有哪些影响?”

语义搜索很擅长把握这个问题的整体意图。

这确实很有用。

然而,医学文本充满了精确的术语。

比如这样的术语:

  • 胰岛素抵抗
  • HbA1c
  • 高血糖
  • 二甲双胍
  • 葡萄糖耐量

这些特定的词汇具有重要的意义。

有时你需要理解其总体含义。

其他时候则需要系统能精确定位到该术语本身。

为何只满足于其中一种功能呢?

解决方案就是将两者结合起来。

混合搜索

这就是混合搜索成为设计核心的原因。

它并非仅依赖基于向量的检索方式,而是将语义搜索与关键词搜索相结合。

其背后的逻辑相当直观。

语义搜索本质上是询问:

“哪些内容具有相似的含义?”

而关键词搜索则是在询问:

“关键术语实际上出现在哪里?”

每种方法都有其优势。

同时也各有缺陷。

将它们结合起来,就能覆盖更广泛的查询类型。

最终的流程如下:

User Query
                        ↓
              ┌─────────┴─────────┐
              ↓                   ↓
        Vector Search       Keyword Search
              ↓                   ↓
              └─────────┬─────────┘
                        ↓
                  Combined Results
                        ↓
                     Reranker
                        ↓
                 Best Context
                        ↓
                       LLM
                        ↓
                      Answer

这一转变改变了后续的检索方式。

但仍然存在另一个问题。

找到相关内容并不代表就是最佳结果

假设混合搜索步骤返回了20个片段。

这听起来很有希望。

但这些片段真的每一个都有用吗?

未必。

有些片段可能高度相关于主题。

另一些则可能只是共享部分词汇。

还有些片段可能与问题只有间接关联,无法真正回答问题。

直接将所有这些内容输入到大语言模型并非理想的解决方案。

获取更多上下文并不一定能带来更好的答案。

事实上,它反而可能损害结果质量。

这会增加更多标记、更多无关干扰信息以及更高的延迟。

因此引入了另一个阶段。

重新排序。

为何重新排序能带来改变

检索器的功能可概括为:

找出潜在的候选项。

而重新排序器的功能则不同:

判断这些候选项中哪些才是真正相关的。

所以不再是简单的流程:

Query → Search → LLM

而是演变成了这样的流程:

Query
 ↓
Hybrid Search
 ↓
20 Candidate Chunks
 ↓
Reranker
 ↓
Top Relevant Chunks
 ↓
LLM

这种职责分离非常重要。

第一阶段的检索可以优先考虑覆盖范围,尽可能广泛地收集候选项。

随后重新排序阶段则可以专注于相关性和精确度。

对于医学研究聊天机器人而言,这种区分尤为重要,因为仅仅包含正确术语的文本片段并不一定就是能真正回答用户问题的部分。

最关键的一点:拒绝编造

除了信息检索和重新排序之外,还在生成阶段设置了严格的约束。

核心指令可以概括为:

Use the provided context to answer.
Do not invent information.If the context doesn't contain enough information,
say that there isn't enough information available.

这看起来似乎简单到没什么作用。

然而它确实显著改变了聊天机器人的行为方式。

这种方法不会强迫模型无论如何都给出答案,而是在没有相关资料时为其提供退路。

事实证明,这种退路至关重要。

有时诚实的回应应该是这样的:

“我在提供的研究资料中找不到足够的信息。”

并非每个问题都值得给出确定的答案。

那么幻觉现象被完全消除了吗?

并非如此。

在构建该系统的过程中这一点就变得很清楚了。

RAG确实能够减少幻觉现象,让回复更紧密地基于真实来源。

但声称完全没有幻觉未免言过其实了。

仍然存在许多潜在问题。

信息检索模块可能会提取到错误的片段。

片段划分本身也可能丢失重要的上下文信息。

重新排序模块的排序结果可能不准确。

底层文档本身也可能缺少某些信息。

即便所有上游环节都正常运作,大语言模型仍可能误解其检索到的内容。

因此真正的目标并非:

“打造一个永远不会出错的聊天机器人。”

更接近于:

“构建一个出错概率更低的系统,同时让它能够认识到自身实际认知的局限。”

这才是更易实现的目标。

块状设计被证明至关重要

一个重要的认识是:将文档拆分成块并非只需配置一次的简单预处理步骤。

过大的块会包含无关内容。

过小的块则会丢失某句话所依赖的上下文。

应将每个块视为一个独立的知识单元,而非随意截取的文本片段。

设计良好的块能直接提升检索效果。

而更强的检索能力往往能带来更好的最终结果。

加快处理流程

正确性只是其中一半的挑战,另一半则是响应速度。

一个RAG请求可以触发多项不同的操作:

User Query
   ↓
Embedding
   ↓
Vector Search
   ↓
Keyword Search
   ↓
Merge Results
   ↓
Reranking
   ↓
LLM

如果严格按顺序依次执行所有这些操作,会拖慢整体速度。

为了解决这个问题,尽可能将独立的检索步骤改为异步执行。

修改后的流程大致如下:

User Query
                     ↓
              ┌──────┴──────┐
              ↓             ↓
        Vector Search   Keyword Search
              ↓             ↓
              └──────┬──────┘
                     ↓
                  Rerank
                     ↓
                    LLM

这样就能减少那些实际上并不相互依赖的步骤之间的无效等待时间。

对于一个优秀的RAG系统而言,准确性并非唯一考量因素。

用户并不希望一直等待响应。

最终的架构

经过多轮优化后,整个处理流程最终形成了类似这样的结构:

Medical Research Documents
                         ↓
                  Document Processing
                         ↓
                      Chunking
                         ↓
                     Embeddings
                         ↓
                   Vector Database
                         ↓
                      User Query
                         ↓
              ┌──────────┴──────────┐
              ↓                     ↓
       Semantic Search        Keyword Search
              ↓                     ↓
              └──────────┬──────────┘
                         ↓
                    Result Fusion
                         ↓
                      Reranker
                         ↓
                Relevant Context
                         ↓
                 Grounded Prompt
                         ↓
                       LLM
                         ↓
                 Final Response

该架构图中的每个组件都有明确的职责。

这种分工是该项目带来的最宝贵的经验之一。

向量数据库并非用于回答问题的。

检索器也不是用来生成回复的。

大语言模型默认并不具备知晓一切的能力。

每个组件都负责一项任务。

理想情况下,它们能很好地完成这些任务。

构建过程中的经验教训

整个实践过程带来的主要启示是,RAG远不止是将大语言模型与向量数据库简单结合那么简单。其中涉及多个环节,每一个都需要重视。

检索质量至关重要

即便是最强大的语言模型也无法弥补糟糕的上下文信息。如果输入的检索结果质量低下,得到的答案也会很差。这完全是“垃圾进,垃圾出”的道理。

混合搜索模式确实有效

语义搜索擅长捕捉含义与意图,而关键词搜索则在需要精确术语时更为有效。由于医学研究充斥着各种确切的术语和特定表述,将这两种方法结合使用被证明是最佳选择。

重新排序值得更多认可

首先筛选出二十个候选结果已是一大挑战,再将其中筛选出最佳五个则又是另一项独立的难题。重新排序正好介于这两步之间,填补了其中的空白。

更长的上下文窗口并不一定能带来更好的结果

早期人们认为获取更多检索内容自然会提升结果质量,但这一假设并不成立。实际上,五个高度相关的片段往往比二十个质量一般的片段表现更好。

承认不确定性是优势而非弱点

这或许是所有教训中最重要的一点:一个值得信赖的系统不应觉得有义务无论如何都要给出答案。当相关信息根本不存在时,系统应当愿意明确说明。

未来的发展方向

仍有很大的改进空间。接下来值得探索的领域包括:

  • 更完善的检索评估方法
  • 查询重写技术
  • 元数据过滤机制
  • 更优的重新排序模型
  • 包含引用信息的回复
  • 置信度评分与回避策略
  • 对检索过程的更好监控能力
  • 自动化评估数据集
  • 进一步的缓存优化与延迟降低措施

构建合理的评估流程尤为关键,因为仅手动查看少量聊天机器人的输出并不足以准确判断其质量。值得评估的问题包括:是否首先获取了正确的信息、生成的答案是否确实基于这些已获取的信息、以及系统多久会出现完全无法提供正确上下文的情况。这些指标远比主观上认为某个回复“听起来对不对”重要得多。

总结

最初只是一个简单的RAG聊天机器人,却让我深刻了解了检索系统实际的工作原理。关于人工智能应用的讨论往往集中在语言模型上,但在RAG架构中,真正的重活其实是由检索流程在幕后完成的。

最简单的架构可能是文档先流入向量数据库,然后再进入大语言模型。而更为可靠的架构则是文档先经过分块处理,再通过混合搜索,接着进行重排序,最终以基于事实的上下文形式呈现给大语言模型。即便如此,这一流程仍有改进空间。

这正是构建RAG系统如此吸引人的原因:它不仅仅是为了让语言模型生成文本,更重要的是确保在模型输出之前,这些文本已基于正确的信息。

注意:本项目仅用于技术研究和实验目的,不能替代专业的医疗建议、诊断或治疗。

相关阅读