大家好,我是大志。
在 AI Agent 面试和应用开发中,RAG(Retrieval-Augmented Generation,检索增强生成)是所有AI Agent工程师必须掌握的技能。这篇文章中,我会结合实际项目开发经验,把面试中 RAG 最常见的如 Embedding、向量数据库、Chunk、TopK、Rerank 等核心知识点进行系统梳理。
另外,完整的 AI Agent 面试题文档也已经同步到了 aiflowline.cn,大家可以结合文章一起阅读。
1、什么是 RAG?
RAG(Retrieval-Augmented Generation,检索增强生成) 是指在调用 LLM 回答问题之前,先从知识库里查询与问题相关的信息,再把相关信息和用户提出的问题,一起放到提示词中,再交给 LLM,让 LLM 基于知识库信息来回答问题。
RAG基础流程图RAG 解决的最主要问题是:LLM 回答问题都是根据自身训练数据来给出答案,但实际应用中,一些内部知识库的内容是不被模型所了解的,比如说,公司的规章制度、项目的文档、产品使用说明等等,如果直接问 LLM 它不了解的问题,LLM 可能会出现幻觉而胡编乱造。
并且 LLM 的训练数据都是截止到某个时间点的信息,当我们提问一些最近发生的事情,LLM 也会出现幻觉。
因此,通过 RAG 来检索外部知识库,可以很好地解决 LLM 出现幻觉的问题。
2、在 Agent 中使用 RAG 有哪些好处?
在 Agent 中,使用 RAG 有如下好处:
企业知识库、产品文档、代码文档,这些内容不可能在 LLM 训练数据中,通过检索让 LLM 能了解这些信息。
明确让 LLM 基于 RAG 检索到的资料回答问题,很大程度上能避免幻觉的出现。
当一些知识库内容发生更新,可以直接将知识库更新到最新内容,而 LLM 要了解更多的知识需要重新训练模型。
RAG 检索完成后,可以返回给用户当前答案是引用知识库的哪篇文档、哪个章节。
3、RAG 完整流程是什么?
一个完整的 RAG 系统一般分成两个阶段:文档入库和文档检索。
文档入库阶段主要完成的工作是对文档进行解析、清洗,之后将文档拆分成文档片段,再将这些文本片段进行文本嵌入,保存到向量数据库。
文档入库阶段流程图在文档检索阶段,主要完成的是将用户提出的问题通过 Embedding 文本嵌入模型转换成向量,根据向量进行相似性检索,找出 TopK 的文本片段,这里可以和关键词检索混合使用。
最后将找到的文本片段进行 Rerank 重排序,找到真正最相关的文本片段,将这些文本片段拼接到提示词中,一起交给 LLM,LLM 生成最终答案。
文档检索阶段流程图4、Embedding 是什么?
Embedding 就是利用文本嵌入模型,将文本转换成向量的过程。
在传统的软件开发中,我们通常使用关系型数据库,通过精确匹配或者模糊匹配来做数据检索,在 Agent 开发中,我们使用 RAG 对信息匹配检索的能力有了更高的要求,不能只做关键字检索,更重要的是做语义检索。
首先需要先把一段文本利用 Embedding 模型转换成一组数字。语义越接近的文本,生成的向量距离越接近。比如:”如何申请年假”和”年假怎么请”,这两句话不完全一样,但表达的意思非常接近。这两段文本经过 Embedding 后,它们在向量空间里的距离相对也会很近。Embedding 的作用,就是让系统可以做语义检索。
一个文本经过 Embedding 之后,会生成一组数字,大概长成这样:
[0.012, -0.231, 0.548, ...]
实际上,在使用 Embedding 模型和向量数据库时,可以支持几百、上千维甚至更多。但是我们不需要关心每一维具体代表什么,只需要理解如何利用 Embedding 模型和向量数据库进行语义检索即可。
5、向量数据库是如何进行相似性搜索的?
向量数据库主要完成向量和对应元数据的存储,在进行相似性搜索时,可以快速匹配到语义最相似的文本片段。
将向量存储到向量数据库时,每个 Chunk 都会将 Embedding 向量、原文、来源等元数据一起存入向量数据库。结构类似:
{"id": "chunk_001","content": "员工入职满一年后可享受年假。","embedding": [0.12, 0.34, 0.56],"metadata": {"doc_id": "hr_policy_001","title": "员工休假制度","page": 3,"status": "published" }}
在使用相似性检索时,先把要检索的文本通过 Embedding 模型转换成向量,然后到向量数据库里找跟这个向量距离最近的几个 Chunk,一般在检索时会加上 metadata 的过滤条件,如只检索 tenant_id = t_001 的文档。
常见相似度计算方式有:
6、Chunk 如何切分?
Chunk 是指文档切分之后产生的文本片段。 在 RAG 中,我们不会把一整篇文档直接转换成向量保存到向量库中,而是先将整篇文档切成多个 Chunk,再分别使用 Embedding 模型生成向量。
Chunk 的切分主要遵循:单个片段不能太长,但是也要避免太短,单个片段尽量保证语义完整。
Chunk 切分有以下几种方案:
比如每 500 个字符进行一次切分。这种切分方式最简单,但是容易把一个完整的段落切断。
比如按标题、章节、段落、列表切。Markdown 等文档都适合这种切分方式。
按照语义来切分,把同一个主题的内容尽量放在一起。这种效果通常更好,但实现成本也更高。
除了以上切分方式外,还可以使用重叠切分 overlap,重叠切分是指为了避免上下文被破坏,相邻 Chunk 之间可以保留一部分重叠内容,比如
Chunk 1:第1-500个字符Chunk 2:第401-900个字符
这样每个 Chunk 中间重叠 100 个字符,可以减少上下文被破坏的可能性。实际项目里,比较稳的做法是:先按文档结构切,再对过长段落做二次切分,并保留一定重叠。除此之外,对于代码、表格等内容,最好按它们各自的结构进行切分,不要所有内容都用固定长度进行切分。
7、Chunk 大小如何确定?
Chunk 大小没有统一标准,要根据文档的类型、模型上下文长度、Embedding 模型能力和具体业务特点来确定。
Chunk 切分得太小,会破坏上下文。Chunk 太大,会导致一个 Chunk 里内容太多,在进行检索匹配时,无法确定重点,并且 Chunk 太长会导致最终 Prompt 太长,会造成 Token 浪费,LLM 也更难找到重点。
具体的 Chunk 切分方式,可以参考下面的一些经验。
Overlap 一般可以设置在 Chunk 大小的 10-20% 左右
实际上,确定 Chunk 方案最好的方法是用实际问题来测试,准备几十个常见问题,测试不同 Chunk 大小,召回正确内容的情况,再确定最终方案。
8、TopK 如何选择?
TopK 是指在向量检索时,取前几条最相关的结果,比如 TopK = 5,就是返回最相关的 5 个 Chunk。
在 TopK 大小的选择上,TopK 太小可能会漏掉正确答案,TopK 太大,又会带来 Token 消耗和上下文过长找不到重点。
在选择 TopK 大小时,需要考虑下面几个因素:
整体都是比较简单的问题,那么 TopK 可以设置小一点,比如 3 到 5。复杂问题需要综合多个文档的内容,TopK 可以大一点,比如 8 到 15。
Chunk 越大,每条内容占用上下文空间、消耗的 Token 越多,因此 TopK 就不能设置得太大。Chunk 越小,可能需要更多条才能找到正确的答案。
如果在检索之后有 Rerank 重排序,那可以先召回一些 Chunk,比如 TopK = 20,后面再重排序之后,再取最相关的 3-5 条。
RAG 检索的 Chunk 的多少,要考虑模型的上下文窗口大小,避免太多信息导致超过上下文大小限制。
在生产环境中常见的做法是通过相似性搜索,召回 20 条左右,再根据 Rerank 结果取前 5 条最相关内容。要注意的是 TopK 不是一成不变的,我们需要根据业务的实际情况,通过测试来调整 TopK 的大小。
9、Rerank 有什么作用?
Rerank 是指对向量数据库初步召回结果,按照相关性由高到低进行二次排序。
那么为什么需要 Rerank 呢?主要是因为通过向量数据库进行相似性检索之后,有一些召回结果看起来和我们提出的问题相关,但实际上却不是正确答案。使用向量的相似性检索,经常会召回一些看起来相似,但实际上没有关联的内容。
Rerank 的作用,就是从检索到的结果中,选择真正和问题相关的 Chunk。Rerank 会把用户问题 + 候选 Chunk 一起传给模型,让模型来判断这个 Chunk 是否真的与问题相关。
在以下场景可以考虑使用 Rerank:
10、如何提高检索准确率?
提高 RAG 检索的准确率,可以从以下这些方面来进行优化:
原始文档中的目录、页眉页脚、乱码、重复内容、无意义表格,都会影响检索效果。入库前要先清洗掉这些内容。
按语义和文档结构切分,通常比固定长度切分效果更好。其中标题、段落、表格、代码块要单独处理。
每个 Chunk 都要带上属于哪个知识库、哪个文档、哪个用户等信息,方便在检索时进行过滤。
向量相似性检索是对语义相似的内容进行检索,而关键词检索更适合精确匹配。分别使用两种方式进行检索,之后再将结果进行合并去重,再进行 Rerank,这样检索的效果会更好。
先多召回一些 Chunk,之后再进行重排
用户提问的问题可能很口语化、不明确的、依赖上下文的。可以先把问题进行改写,改写成更适合 RAG 检索的问题。
11、如何解决知识库召回错误?
知识库召回错误通常有几类原因:文档质量差、切分 Chunk 不合理、检索范围过大、TopK 设置不合理,或者知识库中的知识无法回复用户的问题。
排查问题时可以按照如下顺序进行排查:
如果正确答案被切分到两个 Chunk 中,那么召回其中任何一个都无法给出正确答案。
如果包含正确答案的 Chunk 没进 TopK,说明召回策略有问题,可以调整 Chunk 切割策略、Embedding 模型、TopK 数量,或者增加关键词检索。
如果包含正确内容的 Chunk 被检索出来了,但是排名较低,可以使用 Rerank 进行重排序。
检查是否忘记通过 metadata 过滤知识库、文档、用户。
好啦,今天这期 RAG 相关的面试题就到这里。后面我会每周至少更新 1 期面试题系列,想看后续 AI Agent 进阶面试题 的朋友,欢迎关注「大志说编程」!
觉得有用的话,转发给正在面试的小伙伴,咱们下期见~