网站首页 > 技术文章 正文
在上一节我们已经了解了 为什么我们需要 RAG(上)?。这一节要更进一步,看看如何往 RAG 中写入数据——换句话说,资料是怎么被整理进“书架”的。
如果说 RAG 是一个“会说话的图书管理员”,那么 写入过程就是在替它搭建并整理好书架,让后续的检索井井有条。整个流程可以概括为:
采集与解析 → 切块(Chunking) → 元数据增强 → 向量化(Embedding) → 写入索引
接下来我们逐步拆解每一步。
1. 采集与解析
这一环节的目标:把原始资料(PDF、网页、数据库内容、代码等)转化为干净、可处理的文本。
- 采集:
- 来源:PDF/Word、Wiki 页面、API 数据、数据库表、代码仓库。
- 工具:常见的有 langchain.document_loaders、unstructured、Apache Tika、BeautifulSoup、Playwright(渲染网页),或者直接写自定义爬虫。
- 解析:
- 统一转为 UTF-8,避免乱码。
- 去掉噪音:广告、页脚、导航栏。
- 保留结构:标题、段落、表格、代码块。
通俗点说:就像把一本书扫描进电脑,去掉杂志广告和水印,只留下正文。
2. 切块(Chunking)
切块是 一类策略的统称,目的是把长文档拆成更小的片段,方便检索和输入模型。当前有如下策略:
- 结构感知切块:优先按标题、段落、代码函数边界来切,保证每块内容完整。
- 定长切块:限制在 300–600 tokens 左右,避免块太大塞不进 AI 模型的上下文。
- 滑动窗口重叠:相邻块重叠一部分(50–100 tokens),避免句子被截断导致信息丢失。
- 工具:
- langchain.text_splitter 提供了多种切分器(字符、句子、Markdown、代码函数)。
- llama_index 的 NodeParser。
- 自定义 Python 分词 + token 限制。
通俗点说:把一大本手册裁成小册子,每本控制在合适长度,还留一点重叠保证上下文不断裂。
3. 元数据增强
光有正文还不够,每个块最好带点“附加信息”,这叫元数据。
常见元数据:
- 来源信息:doc_id, title, uri, author, created_at, updated_at
- 结构标签:section_path, paragraph_id
- 权限信息:tenant_id, acl_labels
- 检索增强字段:关键词、NER 实体标签(人名、产品名)、时间戳
这些元数据有什么用?
- 在查询时可以加过滤器:比如“只查财务部的文档”。
- 在答案里能显示引用来源,比如“见《差旅报销手册》第三章”。
存储方式:
- 大部分向量数据库(Milvus、Weaviate、Pinecone、Qdrant)都支持在向量旁边存 JSON 格式的 metadata。
- 如果要支持复杂的全文检索(BM25、正则匹配),通常还要额外建一个关键词索引(比如 Elasticsearch 或 Postgres tsvector)。
通俗点说:在书页写上“属于财务部,更新时间 2025-08,作者张三”。
4. 向量化(Embedding)
把 chunk 文本转成向量。
- 工具:
- OpenAI Embedding API (text-embedding-3-small/large)
- HuggingFace 模型(bge、m3e、text2vec)
- SentenceTransformers(适合本地部署)
- 向量化的一些注意点:
- 多语场景:用多语 embedding 模型,不必翻译成英文。
- 隐私数据:敏感字段(手机号、身份证号)先脱敏再 embedding,避免“记入向量空间”。
- 向量归一化:常配合 cosine 相似度。
通俗点说:就像给每一页书生成一个“坐标标签”,相似的内容坐标靠得很近。
5. 写入索引
整理好的 chunks + 向量 + 元数据,要写入数据库,通常情况下是 双索引:
- 向量数据库(Milvus、Weaviate、Pinecone、FAISS、pgvector):做语义检索。
- 关键词索引(Elasticsearch、Postgres 全文检索):做精确匹配。
- 混合检索:把两种结果合并,再 rerank。
通俗点说:既有“按主题查”的书架,也有“按关键词找”的索引卡片。
6. 增量与重建
- 增量更新:用 content_hash 检测文档变更,只更新变化的块。
- 删除:软删(deleted 标记),避免检索越权。
- 模型升级:embedding 模型换代时,要重新生成向量。常见做法是新旧索引并行,验证效果没问题再切换。
如果用书架类比rag的话,增量与重建就相当于是 换了新分类标准时,可以先并行维护两套书架。
小结
写入的过程其实就是:
收集资料 → 拆成小块 → 加上标签 → 变成数字向量 → 放进索引库。
只有把“书架”整理好,RAG 在检索时才能快速、准确地找到资料。
猜你喜欢
- 2025-09-18 怎样实现微软云虚拟机自动关机和开机
- 2025-09-18 设计一个多租户 SaaS 系统,如何实现租户数据隔离(...
- 2025-09-18 让 Agent 拥有长期记忆:基于 Tablestore 的轻量级 Memory 框架实践
- 2025-09-18 分布式微服务中的搜索引擎:架构与实战盘点
- 2025-09-18 设计一个多租户 SaaS 系统,如何实现租户数据隔离与资源配额控制?
- 2025-09-18 设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
- 2025-09-18 MySQL 索引优化实战案例_mysql8索引优化
- 2024-08-04 Nacos搭建(nacos搭建集群)
- 2024-08-04 详解mysql常见报错之Failed to add the foreign key constraint
- 2024-08-04 数据库中间件-jdbi(数据库中间件dble)
- 最近发表
- 标签列表
-
- cmd/c (90)
- c++中::是什么意思 (84)
- 标签用于 (71)
- 主键只能有一个吗 (77)
- c#console.writeline不显示 (95)
- pythoncase语句 (88)
- es6includes (74)
- sqlset (76)
- apt-getinstall-y (100)
- node_modules怎么生成 (87)
- chromepost (71)
- flexdirection (73)
- c++int转char (80)
- mysqlany_value (79)
- static函数和普通函数 (84)
- el-date-picker开始日期早于结束日期 (76)
- js判断是否是json字符串 (75)
- c语言min函数头文件 (77)
- asynccallback (87)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- 无效的列索引 (74)