向量数据库和RAG知识库优化策略
最近也是一直在做 Agent 开发设计相关的工作和相关内容的优化方案设计,其中就涉及到 RAG 知识库和记忆系统使用到的向量数据库检索的相关内容,然后就一直在思考怎么提升 RAG 知识库和向量数据库的检索效果,最近与朋友讨论以及一些相关的信息阅读检索得到以后文章的内容。
以下内容的场景均针对于自动化渗透测试智能体或者自动化攻防渗透智能体进行设计和相关说明,本质上也只是对 RAG 知识库和向量数据库构建上的设计,只不过会将其在相应的场景中进行一些解释。
1. 基础概念
1.1 基础介绍
向量数据库:在传统数据库(如 MySQL、ElasticSearch)中,我们搜索内容往往依赖“精确匹配”或“关键词频次”。但人类的语言充满了同义词和多义词。向量数据库就是为了解决“语义搜索”而诞生的。
- 工作原理: 它借助一种叫做 Embedding(嵌入)的技术,将文本、图像或声音转换成一串长长的数字(高维向量)。在这个多维度的数学空间里,语义相近的内容,它们在空间中的坐标距离就越近。
RAG知识库:RAG(检索增强生成,Retrieval-Augmented Generation)本身并不是一个具体的数据库软件,而是一套工作流或架构方案。它的出现是为了解决大语言模型(LLM)的两大痛点:“幻觉”和“私有数据”。
- 工作流程: 1. R (Retrieval) 检索: 接收到用户问题后,先去一个外部存储(通常就是向量数据库)里搜索相关的参考资料。 2. A (Augmented) 增强: 把搜到的参考资料连同用户的原始问题,打包拼接到一起。 3. G (Generation) 生成: 把这个巨大的“资料包”扔给大语言模型,让大模型基于这些资料进行阅读理解,生成最终的答案。
根据上述的概念解析可以知道,向量数据库是 RAG 知识库的核心组成部分,驱动 RAG 知识库的核心引擎之一。
想要 RAG 知识库架构跑起来,它的第一步“检索(Retrieval)”必须足够精准。目前业界构建 RAG 知识库时,绝大多数情况都会采用向量数据库作为底层的知识存储载体,因为它对非结构化数据(如各种内部文档、PDF)的语义匹配效果最好。
如果没有 RAG 架构的大模型生成能力,向量数据库查出来的结果只是一堆生硬的文本片段,用户体验很差。RAG 架构的系统通过将这些生硬的文本片段或者原文内容交给大语言模型LLM,为你提供总结得出一个完整意义上的答案,实现完整意义上的知识问答。
1.2 场景介绍
对于向量数据库和 RAG 知识库的应用场景可以进行粗略的划分:
- 在数据量级较大、需要规范化输出结果的场景下,采用 RAG 知识库一般能够获取更好的效果。例如:在自动化渗透测试过程中遇到一个可能存在诸多高危漏洞的指纹信息,需要获取相应版本的历史漏洞的poc信息,由于涉及到大量信息的检索和规范化,需要完整的poc可验证脚本,因此采用 RAG 知识库会更加合适。
- 在数据量级较小、且无需过于规范化的数据,仅需关键词获取,部分关键内容提取的场景下,采用向量数据库可能效果更优。例如:在渗透测试过程中,发现碰到了 WAF 或者一些防御手段导致漏洞无法验证或者利用,此时需要进行绕过 Bypass 或者逃逸 Evasion,需要对payload进行编码或者异形处理,对于这种编码操作和相关的异形操作只需要提取部分关键方式即可,通过向量数据库提取相应的方式再交给大语言模型 LLM 进行优化处理,可能会有更好的效果。
当然,以上都是个人的理解,如果有什么不对的地方,敬请指正。
目前对于Agent开发设计方面的方法论和理论都并未完全成熟,大家的理解肯定也各不相同,能够达成最好的效果的方式就是最好的方法和理论。
2. 向量数据库 & RAG 知识库的优化策略
本文中的一个向量数据库和 RAG 知识库的优化策略主要是数据构建、索引向量优化、检索优化、检索结果处理四个方面进行说明,分别说明这四个方面都能够做哪些工作进行优化搭建的向量数据库和 RAG 知识库的效果。
2.1 数据构建与处理优化
高质量的检索建立在高质量的数据基础之上。如果输入的是“垃圾”,检索出的依然是“垃圾”。
- 智能文档解析
对于PDF、Word等复杂格式的文本数据,处理提取内容的纯文本内容以外,对于其中存在的表格、图像和标题格式等,都需要进行解析以及标题层级解析。保证后续检索得到的内容具有分级以及标题等内容保证大语言模型的识别效果。
很多关键信息存在于表格结构或段落层级中。保留文档的 DOM/视觉结构,可以避免语义在强制转为纯文本时发生断裂。 - 优化分块策略
采用滑动窗口分块(带重叠度)、按文档结构分块(按段落/标题)或语义分块(Semantic Chunking)。文本块太小会导致上下文丢失,太大则会引入过多噪音(稀释了向量表征的准确度)。语义分块通过判断句子间的相似度来决定切分边界,保证每一个 Chunk 都是一个完整的语义单元。 - 元数据提取与附加
在将文本存入向量数据库时,附加上丰富的元数据(如:文档标题、作者、时间、类别、关键字等)。向量检索擅长处理“模糊的语义相似度”,但不擅长处理绝对的逻辑条件。利用元数据进行标量预过滤,可以大幅缩小向量检索的范围,既提高了准确率,又提升了检索速度。
2.2 索引与向量化优化
- 领域微调嵌入模型
可以使用领域内的正负样本对 Embedding 模型进行微调(这个方式从理论问说应该是能够实现最好的效果的方式,但是从工程和经济上来说,完全没必要) - 父子文档/层级索引
检索时使用颗粒度很小的数据块,但返回给 LLM 的是该小数据块所在的“父级大文本块”。小文本块的向量表征更精准,更容易与用户的简短 Query 匹配上;但 LLM 生成回答时需要完整的上下文。这种“小切口检索,大面积喂给大模型”的策略完美平衡了检索精度与上下文丰富度。
2.3 检索阶段优化
- 混合检索
结合关键词检索(BM25/TF-IDF)和稠密向量检索(Dense Vector Retrieval),并将两者得分进行归一化和加权(如 RRF 算法,倒数排名融合)。
向量检索擅长找“同义词”和“上下文”,但对于专有名词、序列号、产品代码等(如“iPhone 15 Pro Max 错误码 0x800”)极易失效。BM25 这种基于词频的稀疏检索能精准捕获这些关键词。两者互补是目前生产环境的标配。 - 查询充血 / 扩展
在检索前,先让 LLM 把用户的 Query 重写为更丰富、更清晰的多个 Query,然后再去各自检索,最后合并结果。
用户的原始问题可能存在歧义或指代不清(例如用户问“它怎么配置?”,LLM 根据历史记录重写为“Nginx服务器如何配置?”)。多角度展开问题可以增加命中目标知识的概率。 - 假设性文档嵌入
面对用户的 Query,先让 LLM 凭空“瞎编”一个答案,然后用这个“编出来的答案”去向量数据库里做相似度检索。
用户的 Query 通常很短(问题空间),而知识库里的文本很长(答案空间),两者在向量空间中的分布不对齐。LLM 编造的答案虽然可能在事实上是错的,但其句法结构、词汇分布与真实的文档非常相似,从而大幅提高了命中率。
2.4 结果优化与后处理
- 重排序
向量检索初筛出 Top-50 个结果后,引入专门的重排模型(Cross-encoder,如 Cohere Rerank、BGE-Reranker)对 Query 和这 50 个文档进行逐一交叉打分,重新排序,最终只取 Top-5 给 LLM。
双塔模型(Bi-encoder,即普通向量检索)因为要把文本压缩成固定维度的向量,丢失了词汇间细粒度的交互信息;而交叉编码器会让 Query 和 Document 在模型的底层就进行注意力机制的交互,判断极其精准,但算力消耗极大。因此采用“向量粗排 + 重排模型精排”的漏斗模式。 - 上下文压缩与过滤
剔除检索回来的 Chunk 中与 Query 不相关的句子(如使用 LLMLingua 等提示词压缩技术)。
哪怕是相关性很高的 Chunk,其中也可能包含废话。压缩上下文既能帮公司省去大量 LLM 调用的 API Token 费用,又能减少大模型的“注意力分散”,降低幻觉。
3. 总结
本文对向量数据库与 RAG 知识库进行了简单的介绍,并且对这两者的关系进行了简单的梳理和相关说明,对于不同的情况下选择性采用向量数据库与 RAG 知识库,实现对 Agent 开发设计的完整补充。
本文从四个方面介绍对于向量数据库和 RAG 知识库的优化策略,分别是数据构建与处理优化、索引与向量化优化、检索阶段优化、结果优化与后处理四个方面进行详细的说明,并且对其中说明了原理方法以及相关的实现方式。