跳到正文

RAG 文档怎么存储和向量化?

从原始文本到向量数据库的完整流程:分块、Embedding 与索引设计

原题:在RAG系统中,文档数据如何进行存储和向量化处理?请说明从原始文本到向量数据库的完整流程,包括分块、嵌入模型选择和索引结构设计。

文档处理 · 安克科技真题

30 秒回答

  1. 分块策略的选择依据(固定长度、语义分块、递归分块等)及边界处理
  2. Embedding模型的选型考量(中英双语、上下文长度、领域适配)
  3. 向量索引结构对比(Flat、IVF、HNSW)与选型场景
  4. 完整数据流:解析→清洗→分块→向量化→元数据关联→入库

回答与解析

答案要点

  • 分块策略的选择依据(固定长度、语义分块、递归分块等)及边界处理
  • Embedding模型的选型考量(中英双语、上下文长度、领域适配)
  • 向量索引结构对比(Flat、IVF、HNSW)与选型场景
  • 完整数据流:解析→清洗→分块→向量化→元数据关联→入库

完整流程:原始文本 → 向量数据库

1. 文档解析与预处理

  • 格式兼容:PDF/Word/Markdown/网页等统一解析,处理乱码、特殊符号
  • 结构保留:提取标题层级、段落边界,为语义分块提供依据
  • 清洗降噪:去除页眉页脚、重复内容、无效HTML标签

2. 分块(Chunking)策略

策略 适用场景 关键参数
固定长度 通用场景,实现简单 chunk_size与overlap都作为候选变量,由文档结构、模型输入限制和评测结果决定
语义分块 对连贯性要求高的文档 按句子/段落边界,结合NLP工具
递归分块 层次化文档(法律、论文) 先大段后小段,父子块关联

实践经验:只有跨块证据缺失的bad case通过同一评测集验证后,才引入合适的overlap;代码和表格优先按结构分块。

3. Embedding模型选择

选型维度

  • 语言覆盖:中文场景优先m3e/bge-chinese,多语言用e5/multilingual-e5
  • 上下文长度:长文档选支持8192+的模型(如gte-large)
  • 领域适配:金融/医疗等垂直领域考虑微调或专用模型

关键指标:MTEB榜单参考,但务必用自己的召回率测试验证。

4. 向量索引结构设计

原始向量 → 索引构建 → 查询优化
    ↓
Flat:精确但慢,<10万条可用
IVF:聚类加速,平衡精度与速度  
HNSW:图索引,高召回+快速,推荐默认选择

元数据关联:每个向量携带doc_idchunk_indexsourcetitle等,支持过滤查询和结果溯源。

5. 入库与更新机制

  • 批量写入:避免逐条插入,控制batch_size防内存溢出
  • 增量更新:文档版本变更时,按doc_id删除旧块再插入新块
  • 混合存储:向量库(Milvus/Pinecone)+ 关系库(PostgreSQL)各存其责

口语版讲法(约4分钟)

  • 本质是让机器理解文档语义
  • 分块策略与边界处理
  • 嵌入模型选型与落地
  • 索引结构与元数据
  • 收尾可延伸点

这道题其实问的是,怎么让机器理解文档的语义,而不是靠关键词硬匹配。整个流程的核心,就是把非结构化文本转成可检索的向量,同时保证召回质量。

我先说分块。很多人一上来就照搬某个固定长度和overlap。但真正落地你会发现,固定长度适合新闻、百科这种通顺文本,碰到代码、表格、法律条款就崩了。比如一个退款政策文档,关键信息可能跨两个块,召回时只拿到一半,模型就瞎猜。所以我会按场景选策略:对连贯性要求高的,用语义分块,按句子或段落边界切;对层次化文档,比如企业SOP,用递归分块,先大段切分,再在小块里保留父级标题作为上下文。这里有个坑:overlap不是必选项,也没有通用比例。我会把零重叠、短窗口和较长窗口放进同一评测集,比较跨边界证据完整率、重复召回与索引成本。

再说嵌入模型。中文场景首选bge或m3e,多语言用e5。但模型不是越大越好,关键看上下文长度和领域适配。比如做客服退款场景,用户问题往往很短,但政策文档很长,如果模型输入限制较短,长文档就得切得更碎,反而可能丢失语义。所以我会结合模型文档、业务文本长度和实测结果选型。另外,千万别只看MTEB榜单,一定要拿自己的业务数据做召回测试,因为通用榜单和实际场景差异很大。

然后是索引结构。小规模用Flat,精确但慢;大规模用HNSW,高召回加快速,是默认选择。但HNSW有个前提,内存要够,如果向量量级上亿,内存扛不住,就得用IVF-PQ做量化压缩,但精度会降。所以我会这么判断:十万级用HNSW,百万级用IVF,千万级以上考虑分布式向量库。另外,元数据关联是必选项,每个向量要带上doc id、chunk index、source,这样支持过滤查询和结果溯源,比如只搜某个部门的文档。

最后说入库和更新。批量写入控制batch size,比如一次500条,防止内存溢出。增量更新时,别直接覆盖,先按doc id删除旧块再插入新块,保证一致性。这里有个常见失败场景:文档版本变了,但旧向量还在库里,导致召回混乱。所以上线我会特别关注版本管理,用时间戳或版本号做过滤。

另外,分块长度和嵌入模型上下文长度的匹配,是个容易被忽略的细节。比如模型支持较长输入,但分块始终很短,可能没有利用长文本上下文能力。反过来,分块太大,检索精度反而下降。这里需要根据实际query长度做平衡,我一般会做A/B测试来定最优参数。

关键一句:分块长度与嵌入模型上下文长度的匹配对召回效果的影响

面试官还可能这样问

  1. 问法 1 · 场景切入

    假设你做一个知识库问答系统,用户上传了几百份PDF合同,需要从中检索条款。你怎么把这些文档存到向量库里?从解析、分块到选模型和建索引,大致步骤说一下吧。

  2. 问法 2 · 层层追问

    RAG系统里文档数据怎么处理才能检索?……那原始文本读进来之后,分块你一般怎么分?……如果文档很长,比如法律条文,怎么保证语义连贯?……嵌入模型选型要考虑哪些因素?……最后存到向量库,索引结构你怎么选?

  3. 问法 3 · 直球架构

    讲一下RAG系统中从原始文本到向量数据库的完整数据流,包括文档解析、分块策略、嵌入模型选型以及向量索引结构设计,每一步的关键考量是什么?

同模块相关题目