在构建基于 RAG(Retrieval-Augmented Generation)的知识库时,从原始 Markdown 文本出发,到最终形成高效可检索的向量知识库,需要经历几个关键环节。

其中,**文本切片(Chunking)**和 Metadata 管理尤为核心。本文将逐步梳理从 Markdown → 知识库的完整链路,重点讲解为什么要做、怎么做,以及参数如何取舍。


一、Metadata 结构化

Metadata(元数据),即“描述数据的数据”,常见形式包括:标题、章节、文件名、创建时间、作者、所属部门等。

为什么要做 Metadata 结构化?

  1. 过滤检索:在向量相似度搜索之前,可以先用 metadata 筛选。例如:

    • 只检索“2025 年的文档”

    • 只查“Product A 相关内容”
      类似于 SQL 的 WHERE 子句,这样能提前剔除大部分无关向量,加快搜索并提升准确率。

  2. 访问控制(Access Control):通过 metadata 字段(如 user_roledepartmentaccess_level),实现权限隔离。例如:HR 用户只能查询自己部门的数据。

  3. 溯源与解释:检索出的答案往往需要展示出处,metadata 中的 file_namechapter 等能帮助用户理解“答案来自哪里”。

如何实现 Metadata 结构化?

  • Loader 阶段:使用 LangChain 的 loader(如 MarkdownLoaderUnstructuredMarkdownLoader)加载文档时,会自动提取基础 metadata(如文件路径)。

  • Splitter 阶段:将文档拆分成 chunks 时,每个 chunk 会继承原始 Document 的 metadata。

  • 自定义注入:可额外为每个 chunk 添加更丰富的字段,如 product_idversionlast_modified 等。

  • 向量数据库存储:metadata 会随 chunk 一起保存,后续可以直接作为检索过滤条件。


二、Loader 的选择:MarkdownLoader vs. UnstructuredMarkdownLoader

在 Markdown → Document 对象的过程中,有两类常见 Loader:

  • MarkdownLoader

    • 适用:文档主体是正文,结构相对规整,代码块/表格不复杂。

    • 优点:轻量、高效。

  • UnstructuredMarkdownLoader

    • 适用:Markdown 文档格式复杂,含有大量 HTML、富文本、复杂表格、图片占位符、学术注释等。

    • 优点:依赖 unstructured 库,能智能解析多样格式,保留更多结构信息。

中文语料建议
若语料主体是普通文本(说明书、论文笔记、教学资料),优先用 MarkdownLoader

若包含混合内容(如导出的复杂 Markdown 笔记),可选 UnstructuredMarkdownLoader


三、为什么要“加载”?加载后是什么样子?

加载(load())是文档处理流程的第一步

加载的目的

  1. 统一结构:将各种文件格式(Markdown、PDF、网页、数据库等)统一转换成 LangChain 的 Document 对象。

    • 每个 Document 有两个核心属性:

      • page_content:文档正文内容

      • metadata:附加信息,如来源路径(source)、页码、文件名、时间戳等

  2. 自动提取 metadata:Loader 会自动附带文档来源信息,便于后续追踪、过滤与检索。

加载后的样例


Document( page_content="这是文档正文……", metadata={"source": "docs/intro.md", "last_modified": "2025-08-29"} )


四、文本切片(Chunking)

为什么要 Chunk?

  • 大模型输入限制:文档常常超过模型上下文长度,需要切分。

  • 检索粒度优化:切小后,每个 chunk 更专注一个主题,提升召回精度。

chunk_size 和 chunk_overlap 怎么选?

经验值(起点)
  • chunk_size:500–1,000 tokens(中文可粗略换算为 ~800–1,600 字)。

  • chunk_overlap:10%–20% 的 chunk_size,或 1–3 个句子。

计算方法

假设:

  • 模型上下文 = CCC tokens

  • 预留系统/指令/示例 = RRR tokens

  • 打算拼接 Top-K = kkk chunks

单块平均预算 ≈ (C−R)/k(C - R)/k(C−R)/k,再留 10–20% 空间给模型生成。

👉 举例:
若 C=16kC=16kC=16k,R=2kR=2kR=2k,k=4k=4k=4,则每块不超过 ~3,000 tokens 更稳妥。

取舍逻辑
  • 块太大:主题混杂,语义发散,召回精度下降;还会挤占上下文导致可拼接的块数 kkk 变少。

  • 块太小:语义不完整,容易割裂上下文;需要更多 overlap 或更多 Top-K 才能弥补。

中文语料建议

优先用 基于语义的切分器(如 MarkdownHeaderTextSplitterSentenceSplitter),再做二次 token/字符切分。能避免句子被硬性截断,提升语义完整度。


五、参考与延伸


总结

从 Markdown 到向量知识库的流程中,Metadata 结构化文本切片是两个核心步骤:

  • Metadata 提供过滤、访问控制与溯源能力;

  • 合理的 chunk 大小和 overlap 决定了召回的准确性与效率。

在中文场景下,推荐 MarkdownLoader + 语义切分 + 500–800 tokens/块 的配置作为起点,再结合实际上下文窗口、Top-K 设置与检索实验结果,迭代优化。

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐