RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?

0 阅读16分钟

目录

0. 正确知识进入 Prompt,就一定能回答正确吗?

1. 知识库内部冲突:新旧文档到底应该信谁?

1.1 不是越新的文档就越正确

1.2 不要只保存 Chunk 文本和向量

1.3 解决不了冲突怎么办?

2. 模型自身知识与 RAG 知识发生冲突怎么办?

2.1 第一层:明确回答依据

2.2 第二层:先提取证据,再生成答案

2.3 第三层:生成后验证关键事实

3. Faithfulness 不等于 Answer Correctness

4. 正确证据都在 Prompt 中,为什么还需要整理上下文?

5. 如果让我设计,我会采用怎样的方案?

最后

参考资料


RAG 检索到了正确知识,也成功把它放进了 Prompt,但 LLM 最终还是给出了错误答案。这一次,问题可能不在检索,而在模型如何理解、选择和使用这些知识。

0. 正确知识进入 Prompt,就一定能回答正确吗?

在上一篇文章中,我们讨论了一个问题:正确 Chunk 明明已经被召回,为什么经过 RRF、Rerank 等检索环节后,最终 Top-K 却没有它?

但如果正确 Chunk 已经完整进入 Prompt,问题就解决了吗?

未必。

假设企业知识库中存在两份接口文档:

文档默认请求超时时间状态
V1 接口文档60 秒历史有效版本
V2 接口文档30 秒当前有效版本

用户提问:

“V2 接口的默认超时时间是多少?”

系统把这两份文档都检索了出来,并且完整地交给 LLM。

理论上,模型应该回答 30 秒。

但它仍然有可能选择 V1 的数据,回答 60 秒。

更值得注意的是,这个错误答案并非凭空捏造。

60 秒确实存在于知识库中,只不过它属于错误的版本。

这就带来了一个比传统幻觉更复杂的问题:

回答能够找到知识库依据,不代表这份依据就适用于当前问题。

本文以企业 Wiki 和技术文档为背景,讨论知识冲突、模型先验知识与检索证据冲突,以及如何通过工程手段提高回答的可靠性。

文中的配置数据均为构造示例,不代表真实线上故障。

1. 知识库内部冲突:新旧文档到底应该信谁?

企业知识库和普通静态文档不同。

同一个接口可能有多个版本,同一项配置可能在测试环境和生产环境使用不同的值,不同团队维护的 Wiki 也可能存在差异。

因此,检索到多份互相矛盾的内容并不罕见。

最直观的想法是:

给知识添加版本号,再按照优先级选择最可信的文档。

这确实是重要的工程手段,但我认为还需要补充一个前提:

优先级判断必须建立在知识适用范围匹配的基础上。

1.1 不是越新的文档就越正确

假设用户明确问 V1 的接口参数。

即使知识库存在更新的 V2 规范,也不能拿 V2 的数据回答 V1 的问题。

类似地,一份生产环境部署文档,未必能直接用于开发环境。

所以我更倾向于按以下顺序处理:

  1. 适用范围: 产品型号、文档版本、部署环境是否匹配用户问题?

  2. 来源权威性: 是正式规范、经过审核的 Wiki,还是个人笔记?

  3. 有效状态: 文档是否已经废弃?是否存在明确的替代关系?

  4. 无法判断: 是否需要保留冲突,交给用户或知识负责人确认?

这里的顺序是推荐的业务决策思路,不是通用的行业固定标准。

比如一份最近更新的个人笔记,与较早发布、但依然有效的官方规范发生冲突,就不能简单按照 updated_at 选择个人笔记。

1.2 不要只保存 Chunk 文本和向量

如果知识库只存储:

chunk_id + content + embedding

那么很多版本信息就只能依赖模型从正文中自行理解。

我更推荐为 Chunk 保留结构化元数据:

字段示例作用
document_iddoc_1024关联原始文档
product_modelEVM-RK3588限定产品型号
versionV2区分适用版本
environmentproduction区分部署环境
source_typeofficial标记来源类别
statusactive标记有效状态
updated_at2026-10-01辅助判断时效

这不是说每个 RAG 系统都必须设计上述所有字段,而是对影响业务正确性的条件,尽可能使用可查询的结构化信息表达。

例如用户明确询问某个产品的 V2 文档,就可以在检索时利用型号和版本字段缩小候选范围。

Azure AI Search 的向量查询支持基于非向量字段的元数据过滤,其中预过滤允许检索在指定范围内寻找候选。

对于使用 PostgreSQL + pgvector 的系统,也可以采用类似的元数据约束思路。

需要注意,如果系统采用的是近似向量检索,过滤发生的阶段可能影响召回效果,不能简单认为先取全局 Top-K、再过滤,与限定范围后检索完全等价。

能够通过确定性规则解决的知识适用性问题,尽量不要完全交给 LLM 猜测。

1.3 解决不了冲突怎么办?

假设两份文档:

  • 都属于当前有效版本。

  • 都来自正式审核的来源。

  • 产品型号、环境也完全相同。

  • 但配置值互相矛盾。

这时候就不能靠“文档发布时间更近”强行选择一个。

我更倾向于保留冲突状态,并告诉用户:

“当前存在两份适用范围相同但配置不一致的文档,分别记录为 A 和 B。暂时无法确认哪份为准,请联系知识负责人核实。”

而不是让 LLM 自行生成一个看似确定的答案。

对于企业知识库,能够解释为什么不能确定,有时比给出一个未经验证的答案更重要。

2. 模型自身知识与 RAG 知识发生冲突怎么办?

上一节讨论的是知识库文档之间的冲突。

但还有一种更隐蔽的情况:

检索证据只有一份,而且内容正确,模型仍然可能受到自身已有知识影响。

例如,模型从训练中学到 SSH 通常使用默认端口 22。

但某个企业的服务器明确将 SSH 端口配置为 2222。

如果用户询问的是这台企业服务器的实际配置,那么应该以有效的企业部署文档为准。

这种冲突涉及两个概念:

  • Parametric Knowledge: 模型学习并存储在参数中的知识。

  • Retrieved Knowledge: RAG 在运行时提供的外部检索知识。

模型并不是一个能够简单关闭内部知识、只读取数据库内容的程序。

2025 年 ACL 的 FaithfulRAG 研究就讨论了这种情况:模型可能忽略检索上下文,或不一致地混合模型自身知识与外部证据。

那么工程中该怎么处理?

2.1 第一层:明确回答依据

最简单的方法是在 System Prompt 中增加约束:

回答企业内部配置、接口参数和产品版本问题时,以当前问题适用的有效知识库文档为事实依据。

不得使用通用默认值替代文档中的明确配置。

如果证据不足或存在无法判断的冲突,应说明不确定性,不得自行补全事实。

这种方式实现成本低,适合第一版系统。

但问题是:

Prompt 是对模型行为的约束,不是一个绝对可靠的事实验证器。

即使明确要求模型遵守证据,也不能保证它每次都正确执行。

2.2 第二层:先提取证据,再生成答案

我更推荐的一种思路是 Evidence-first Generation(证据先行的生成方式)。

不要直接把几段 Chunk 拼起来,让模型自由组织答案。

可以先让模型完成一个更明确的任务:

从相关 Chunk 中提取回答问题所需要的事实、适用条件和来源。

例如提取出:

{
  "attribute": "ssh_port",
  "value": 2222,
  "environment": "production",
  "source_id": "doc_1024_chunk_3"
}

然后再根据这份证据组织自然语言回答。

这不一定需要两次 LLM 调用,也可以通过一次结构化输出来完成“事实提取 + 答案生成”。

它的优势是把隐含的证据选择过程变得更加明确。

Anthropic 的长上下文提示实践也建议,在部分文档问答任务中先提取相关原文,再基于这些内容执行后续任务。

当然,这仍然不能完全杜绝错误,因为事实提取本身也可能出错。

2.3 第三层:生成后验证关键事实

如果知识库明确写着端口是 2222,最终答案却输出 22,那么我们希望在返回用户之前发现这个问题。

可以增加一层答案校验,重点检查:

  • 回答中的数字、型号、版本是否与证据一致。

  • 引用的 source_id 是否真实存在。

  • 被引用的原文是否包含对应事实。

  • 引用的文档是否适用于当前问题。

对于端口、型号、错误码等结构化信息,能够使用确定性规则校验的部分,可以优先使用程序完成。

对于复杂的自然语言结论,则可以考虑更高级的事实支持性检查。

Amazon Bedrock Knowledge Bases 提供了带来源引用的检索生成接口,可以作为答案可追溯性的工程参考。

但这里还存在一个容易被忽略的问题。

答案有来源,不等于答案一定正确。

3. Faithfulness 不等于 Answer Correctness

回到开头的例子:

用户问 V2 超时时间。

模型回答 60 秒,并引用 V1 文档。

此时:

  • 60 秒确实存在于检索上下文中。

  • 引用的 V1 文档也真实存在。

  • 但用户要求的是 V2,正确答案应该是 30 秒。

因此需要区分:

Faithfulness(忠实性): 回答中的陈述能否从给定上下文中得到支持?

Answer Correctness(答案正确性): 回答是否正确解决了用户提出的问题?

前者不能自动替代后者。

更重要的是,我们还需要检查:

引用的那份证据,是否符合用户要求的版本、型号和环境?

例如,某个校验器只是检查“60 秒是否出现在检索内容中”,就可能忽略版本不一致的问题。

所以我认为企业 RAG 的答案校验至少应该覆盖三个维度:

校验维度需要回答的问题
事实支持答案中的关键陈述是否有证据?
证据适用证据的版本、型号和环境是否匹配?
来源可追溯引用是否真实指向支持该结论的原文?

这里还有一个工程细节:

不能只让模型输出一个 source_id,就认为引用完成了。

如果模型声称引用了 Chunk A,但它实际给出的结论来自 Chunk B,引用仍然不可靠。

因此,最好同时保留模型输出的引用信息和真实检索结果,由后端验证引用关系。

4. 正确证据都在 Prompt 中,为什么还需要整理上下文?

除了知识冲突,证据的组织方式也值得注意。

假设用户询问 RK3588 的配置,但 Top-K 同时包含:

  • RK3588 当前版本的配置。

  • RK3568 的相似配置。

  • 某个旧版本的部署说明。

  • 通用 Linux 配置教程。

这些 Chunk 可能都与用户问题语义相关,但并不全部适用。

模型需要同时判断产品型号、版本、部署环境等条件,才能选出正确内容。

而在较长上下文中,证据的位置也可能影响模型使用信息的效果。

2024 年 TACL 的 Lost in the Middle 研究发现,在其测试的部分模型和任务中,相关信息位于长上下文中间时,模型表现可能下降。

不过,这不意味着所有模型、所有长度的 Prompt 都会出现同样的问题。

对于普通的非 Agent RAG,如果最终只有少量 Chunk,这种效应未必显著。

所以我认为,比起刻意调整 Chunk 在 Prompt 中的排列位置,更应该优先做好三件事:

第一,过滤明显不适用的知识。

第二,保留清晰的文档来源、版本和内容边界。

第三,避免把相互矛盾的证据不加说明地直接混在一起。

把正确知识组织清楚,往往比单纯增加 Prompt 的长度更有工程价值。

5. 如果让我设计,我会采用怎样的方案?

结合前面的讨论,我不会一开始就引入复杂的 Agent 或多轮模型验证链路。

对于常见的企业 RAG,我更倾向于设计一个分层方案:

用户 Query
    ↓
提取版本 / 型号 / 环境约束
    ↓
带元数据约束的知识检索
    ↓
有效性与来源优先级判断
    ↓
识别无法消除的知识冲突
    ↓
组织带来源标识的证据
    ↓
LLM 生成答案
    ↓
关键事实与引用校验
    ↓
返回答案 / 展示冲突并请求确认

这里有一个非常重要的取舍。

并不是每个问题都必须执行所有步骤。

比如一个简单的概念解释问题,模型直接根据一份有效文档回答,可能已经足够。

但如果问题涉及生产环境配置、接口版本、关键设备参数,那么版本校验和事实一致性检查就更值得投入。

工程设计不应该只追求处理链路复杂,而应该根据业务风险选择必要的可靠性机制。

从这个角度看,企业 RAG 的可靠性可以分成三个层面:

知识治理: 决定哪些知识是当前问题适用的。

证据组织: 帮助模型理解和选择正确事实。

生成校验: 确认最终答案没有偏离这些有效证据。

它们相互配合,但没有哪一层能够单独保证回答永远正确。

最后

经过这次对知识冲突问题的梳理,我觉得 RAG 有一个很容易被忽视的事实:

把正确知识检索出来,只是解决了模型能不能接触到答案的问题,并没有解决模型是否正确理解、选择和使用答案的问题。

对于存在多版本、多来源的企业知识库,单纯要求模型“严格根据上下文回答”还不够。

我们应该尽量通过版本管理、适用范围和来源优先级,在知识层先明确哪些证据有效。

对于无法通过规则消除的冲突,应该保留不确定性,而不是强迫模型给出一个确定结论。

在生成阶段,再通过证据提取、来源引用和关键事实校验,减少模型混用自身知识与外部证据的风险。

我认为真正可靠的企业 RAG,不是让 LLM 在一堆互相矛盾的 Chunk 中猜哪个答案正确,而是让系统先确定知识的适用性,再让模型有依据地回答。


参考资料

  1. Azure AI Search:Vector Query Filters — 向量检索的元数据过滤与过滤时机。

  2. Anthropic:Prompting Best Practices — 多文档结构化提示与证据提取。

  3. Amazon Bedrock Knowledge Bases — 检索生成与来源引用。

  4. FaithfulRAG(ACL 2025) — 模型参数化知识与检索证据冲突。

  5. Lost in the Middle(TACL 2024) — 长上下文中证据位置对信息利用的影响。