Q2272RAG 检索增强真题解析RAG(检索增强生成)AgentAlpha 社区真题库约 8 分钟更新 2026-09-29

长文档、FAQ、表格、代码文档的切块策略有什么不同

4 长文档、FAQ、表格、代码文档的切块策略有什么不同

P2 · rag

🏷 标签:rag, chunking, document, code, table

1️⃣ 考察意图

面试官想考察的不是“你会不会调chunk_size”,而是你是否理解文档结构对检索粒度的根本影响。这是一道系统设计+工程取舍题,刁钻点在于:候选人往往只背了“按段落切”的通用方案,但面对FAQ、表格、代码这类非连续文本时,通用切法会直接破坏语义单元,导致检索召回率暴跌。答好了能展示你对RAG整条链路的深度理解——从文档解析、结构保留到检索粒度的trade-off,以及针对不同场景的定制化能力。

2️⃣ 标准答

核心原则:切块策略必须尊重文档的固有结构,而不是用固定窗口暴力切割。下面按四种类型逐一拆解。

长文档(论文/报告/书籍)

  • 策略:层次化切块。先按章节(Heading 1/2/3)切分,再对每个章节按段落(paragraph)或语义边界(sentence embedding + cosine similarity 检测主题漂移)二次切分。
  • 元数据保留:每个chunk必须携带标题层级路径(如“3.2.1 实验设置”)、页码、文档ID。这在检索时能通过元数据过滤(如只搜某章节)大幅提升精度。
  • 工程取舍:层次化切块增加了预处理复杂度,但能避免跨章节的语义污染。例如一篇论文的“相关工作”和“方法”部分可能用词相似,但内容不同,混在一起会导致检索返回错误段落。
  • 实际坑:PDF解析时标题层级可能丢失(如字体大小不统一)。解法:用PyMuPDF或pdfplumber提取字体大小和坐标,结合规则(如字号>14pt且加粗视为标题)重建层级。

FAQ(问答对)

  • 策略:每个问答对作为一个独立chunk,绝不拆分。问题(Q)和答案(A)必须绑定在同一chunk中。
  • 为什么:用户查询通常与问题语义相似,如果Q和A分开,检索时可能只命中Q但返回A的chunk,导致答案不完整;或者Q被切到两个chunk,检索不到完整语义。
  • 元数据:添加“type: FAQ”标签,便于检索时优先匹配或单独索引。
  • 实际坑:FAQ文档中Q和A可能用不同格式(如“Q: ... A: ...”或“问题:... 回答:...”)。解法:用正则或LLM解析器(如基于GPT-4的few-shot提取)将Q-A对结构化,再合并为单个chunk。

表格(结构化数据)

  • 策略:保留表格结构,推荐转为Markdown或JSON格式作为chunk。如果表格过大(>100行),可按行组切分(如每10行一组),但必须保留表头作为元数据。
  • 为什么:纯文本切分会丢失行列对应关系。例如“销售额 2023: 100万”被切到两个chunk,检索“2023年销售额”时无法召回。
  • 工程取舍:Markdown表格在LLM中理解成本低,但占用token多;JSON结构紧凑但需要额外解析。推荐:对检索场景用Markdown,对需要精确计算的场景用JSON。
  • 实际坑:表格中可能包含合并单元格或跨页表格。解法:用Camelot或Tabula提取表格结构,合并跨页表格时基于表头匹配。

代码文档(API文档/函数库)

  • 策略:按函数/类/模块切分,保留语法结构。推荐使用AST(抽象语法树)解析器(如Python的ast模块)提取函数签名、docstring和代码体,每个函数作为一个chunk。
  • 为什么:按行切分会破坏函数完整性。例如用户查询“如何调用train_model()”,如果函数定义被切到两个chunk,检索可能只返回函数体但丢失参数说明。
  • 元数据:添加函数名、类名、模块路径、语言类型(Python/Java等)。这能支持按函数名精确检索。
  • 实际坑:代码中可能包含多行注释或装饰器,AST可能忽略它们。解法:在AST解析后,用正则补充提取注释和装饰器,合并到对应函数的chunk中。

总结:四种策略的核心差异在于语义单元的粒度——长文档按章节,FAQ按问答对,表格按行组+表头,代码按函数。通用策略(如固定窗口)只适用于纯文本段落,对结构化文档必须定制。

3️⃣ 答题模板(30 秒电梯版)

“这个问题我从文档结构适配、元数据设计、工程坑三个层面回答。长文档用层次化切块保留章节层级;FAQ必须保持问答对完整;表格转为Markdown或JSON并保留表头;代码用AST按函数切分。核心原则是:切块粒度必须匹配文档的语义单元,而不是用固定窗口暴力切割。总结一句:没有万能策略,必须根据文档类型定制chunking。”

4️⃣ 高频追问 & 应对

追问 1:如果文档混合了长文本、表格和代码(如技术报告),你怎么处理?

采用混合策略:先用文档解析器(如Unstructured.io)识别每个区域的类型(text/table/code),然后对每种类型应用对应的chunking策略。关键点是:不同区域的chunk大小可能不同(文本chunk 512 tokens,表格chunk 200 tokens),但必须统一向量化。trade-off:混合策略增加了解析复杂度,但能避免跨类型语义污染。实际坑:解析器可能误判类型(如把代码块识别为文本),需要后处理校验(如检查是否包含关键字def或class)。

追问 2:你提到了元数据,具体怎么用元数据提升检索精度?

元数据用于两个场景:1)过滤:检索时先按元数据过滤(如只搜“章节3”或“函数名=train_model”),减少候选集大小;2)排序:在rerank阶段,元数据匹配度(如标题层级接近度)可以作为特征。实际坑:元数据本身也会占用向量空间,如果元数据字段过多(如10+个),建议只保留关键字段(标题、类型、页码),其余用倒排索引存储。

追问 3:对于代码文档,如果函数体很长(>1000行),你怎么切?

按函数切分后,如果单个函数chunk超过token限制(如8K),需要二次切分:按代码块(如循环体、条件分支)或按注释块切分。但必须保留函数签名和docstring作为元数据,确保检索时能定位到函数。trade-off:二次切分会破坏代码的完整性,但能避免超长chunk导致检索噪声。实际解法:对超长函数,优先使用代码摘要(如用LLM生成函数功能描述)作为chunk内容,而不是直接切分代码体。

5️⃣ 避坑 · 常见错误答法

  • ❌ “所有文档都用固定窗口切块,比如512 tokens。” → ✅ “固定窗口只适用于纯文本段落,对FAQ、表格、代码会破坏语义单元,必须根据文档结构定制。”
  • ❌ “表格直接按行切分,每行一个chunk。” → ✅ “表格必须保留表头,按行组切分(如每10行一组),并转为Markdown或JSON格式,否则行列对应关系丢失。”
  • ❌ “代码文档按行切分,因为代码是连续的。” → ✅ “代码文档必须按函数/类切分,保留语法结构,否则函数定义和调用关系被破坏。”

6️⃣ 简历呼应

  • 如果你有RAG项目:从“我在项目中处理过混合文档(技术报告+FAQ+表格)”切入,具体描述如何用Unstructured.io解析文档类型,并针对每种类型设计chunking策略,最终提升检索Recall 15%。
  • 如果你只做过传统NLP:用“文本分类中的特征工程”类比——不同文档类型需要不同的特征提取方式,chunking就是特征提取的预处理步骤。强调你对结构敏感性的理解。
  • 如果你是校招无项目:聚焦“我在论文复现中对比过LangChain默认chunking和定制化chunking的效果”,用公开数据集(如MS MARCO)模拟长文档和FAQ场景,展示你对trade-off的思考。
  • 《RAG from Scratch: Chunking Strategies for Different Document Types》(博客,LangChain官方)
  • 《Unstructured.io: A Library for Document Parsing》(工具文档)
  • 《AST-based Code Chunking for Code Retrieval》(论文,EMNLP 2023)
  • 《Table Retrieval with Markdown vs JSON: A Comparative Study》(博客,Weaviate)
  • 《Hierarchical Chunking with Metadata Filtering in RAG》(论文,ACL 2024)

—— 本场面试完 ——

我们不做玩具级 Demo 教学。训练营的作业是开源项目和论文——我们想陪伴你,做出能改变生活、最后改变世界的项目。