假设知识库里同时放了三类资料。
第一类是一张跨两页的费用标准表。第一页有表头和前半部分数据,第二页只剩下后半部分数据。
第二类是一段 Python 代码。函数定义在上面,异常处理和返回值在下面。
第三类是一张流程图。图里真正重要的不是几个节点名称,而是节点之间谁先谁后、哪一步失败会走哪条分支。
如果把它们都转成纯文本,再按固定字数切块,会发生什么?
表格第二页只剩下一串数字,模型不知道每一列代表什么。代码可能从函数中间断开,缩进和上下文一起丢失。流程图虽然识别出所有文字,却看不出箭头关系。
这就引出一道很有区分度的 RAG 面试题:
表格、代码和图片应该怎样切成 Chunk,既能被检索,又不破坏原来的结构?
常见回答是:“表格单独成块,代码按函数切,图片先做 OCR。”
这句话只讲了入口。面试官接下来通常会问:表格太长怎么办,跨页表头怎么继承,PDF 里的代码无法做语法解析怎么办,图片描述如果编错了又怎么核验?
为什么普通文本能切,特殊内容却容易切坏?
普通段落的主要语义通常来自句子顺序。只要尽量在句号、段落和标题边界切分,单个 Chunk 往往还能独立阅读。
表格不同。一行里的值要结合表头才能解释,一张表还可能依赖表题、单位、合并单元格和前后注释。把文字按阅读顺序摊平之后,“华东、二级、三天”看起来都是词,却无法判断它们分别属于地区、等级还是时限。
代码也不同。缩进、括号、函数边界和变量作用域本身就是信息。清洗阶段把连续空格压掉,Python 逻辑可能直接改变;切分落在函数中间,调用条件和返回结果可能被分到两个互不相干的 Chunk。
图片的问题更复杂。普通截图可能主要承载文字,流程图依赖节点和连线,统计图依赖坐标轴、图例和数据变化。统一生成一句自然语言描述,看似把图片变成了可检索文本,实际上可能把模型的推断写进索引。

表格靠行列和表头,代码靠语法与缩进,图片还可能依赖连接关系。文字被提取出来,不等于结构还在。
所以,特殊内容切分的第一步不是先问“每块放多少字”,而是先判断:这个内容最小的可解释单元是什么。
跨页表格应该先合并,还是先切块?
先恢复逻辑表格,再决定怎样切。
如果解析阶段已经按页把表格拆开,第二页往往没有表头。此时直接入库,检索可能命中第二页某一行,却把一串没有列名的数值交给模型。
判断上下两页是否属于同一张表,可以综合看几个信号:列数是否一致,列位置是否接近,表头是否延续,上页是否在页面底部结束,下页是否从页面顶部继续,以及表题和上下文是否相同。
这些信号只能帮助判断,不能保证所有跨页表格都能自动合并。遇到表头变化、分页小计或列结构改变时,还要保留原页结果和异常标记,避免错误合并后再也无法回看。
逻辑表格恢复后,再看它能否整体进入一个 Chunk。
小表格可以保留为一个结构化单元,同时保存表题、表头、行列数据、页码范围和来源位置。这样用户问某个字段时,返回内容仍然自带解释。
超长表格不可能因为“结构重要”就突破上下文上限。这时应在表格内部寻找仍然可解释的边界,例如按完整行组、业务分区或重复的小节拆分。
每个子表至少需要继续携带四类信息:共同表头、原表 ID、当前分块顺序、原始页码或区域。若一行还依赖脚注、单位或备注,这些信息也要跟着相关子表,而不是只留在第一块。
跨页判断还需要一条可回退的证据链。系统可以把“列位置接近、上页在页尾结束、下页从页首继续、表题一致”记录为合并信号,同时保留合并前的两个版面区域。自动合并置信不足时,不要把两页永久写成一张确定表,可以标记为待核验,或让两段保持独立并通过共同父表候选关联。这样即使合并规则判断错了,也能回到原页重做,而不是只剩一份被改写过的 Markdown。
表格内容的检索表示也可以分层。用于展示的是原始行列与单元格,增强文本可以把“表题、列名、行名、当前行组”组织成可读陈述,metadata 则保存父表、页码、区域、单位和脚注关系。三者不能相互替代:增强文本便于检索,不代表它就是原文;原始表格可核验,不代表直接向量化后一定容易命中。

先恢复同一张逻辑表,再按完整行组拆分。切完的每一块都要带回表头、来源和父表关系。
这里有一个常见误区:先把表格转成 Markdown,就认为结构问题已经解决。
Markdown 只是表达形式。跨页关系判断错了、合并单元格丢了、表头与数据错位,换成 Markdown 仍然是在更整齐地保存错误内容。
代码块怎样切,才不会把逻辑拆散?
如果拿到的是源代码,优先使用语法结构。
类、函数、方法通常比固定字符更适合作为第一层边界。Chunk 可以保存文件路径、符号名、起止行号,以及所属类或模块。用户问“这个函数怎样处理超时”时,检索结果不仅有函数体,还能说明它位于哪个文件、属于哪个对象。
单个函数仍然过长时,可以继续按内部语法块拆分,例如参数检查、主处理流程、异常分支和返回逻辑。但子块要保留完整符号路径,并能按父 ID 取回函数级上下文。
真正棘手的是 PDF 或扫描件里的代码。
这类代码经过 OCR 后,括号、引号、下划线和缩进都可能出错。此时不能把识别文本包装成“可运行代码”。至少应同时保留原始截图、OCR 文本、页码区域和识别置信信息。低置信度内容可以参与辅助检索,却不应被当成确定实现细节直接回答。
清洗也需要区别处理。普通正文可以合并多余空格,代码却不能照搬。Python 缩进、字符串内空格和换行位置都可能影响含义。解析器应先标记 content_type,再让代码走自己的清洗和切分路径。
下面只用一段教学伪代码表达需要保存的关系。字段并不完整,也不能直接当作生产代码运行:
chunk = {
"content_type": "code",
"content": ocr_text,
"parent_id": function_or_page_id,
"symbol_path": symbol_path,
"page": page_number,
"position": bounding_box,
"source_image": image_id,
}
字段是否全部启用,要由实际资料和前端能力决定。这段示例没有声称 OCR 文本可以直接运行。
代码 Chunk 还要区分“定义”和“使用”。只按函数切分,用户问某个参数从哪里传入时,函数体可能没有调用方信息;只把调用方和定义强行拼在一个大块里,又会让每次变更产生大量重复。更稳妥的是让函数、类和文件保持各自身份,通过符号名、父级与引用关系连接。粗召回命中函数后,再按问题类型决定是否补充签名、所属类或一处关键调用,而不是把整个仓库塞回上下文。
PDF 代码无法稳定构建抽象语法树时,降级顺序也要明确。先尝试识别代码区域与行序,再保留原换行和缩进;语法校验不通过时标记为 OCR 代码,不继续声称函数边界准确;需要回答实现细节时返回截图和页码供核验。系统能检索到一段疑似代码,与系统能证明这段代码可运行,是两个完全不同的能力。
图片为什么不能只生成一句描述?
先判断图片承载的是什么信息。
界面截图通常以文字和位置为主,可以保存 OCR 结果、控件区域和原图。流程图除了文字,还要恢复节点和连接关系。数据图表则需要图例、坐标轴和数据趋势,必要时输出结构化数据。
如果让模型给所有图片写一句摘要,检索确实更容易命中,但摘要可能省略关键细节,也可能把图中没有表达的关系补进去。
更安全的做法是把机器生成描述当作辅助索引字段。真正用于核验的仍是原图、图片标题、所在章节、页码和处理方法。回答需要引用图中信息时,前端应允许读者回到原图,而不是只看到一段二次生成的文字。
图片处理最好同时保存“观察”和“推断”。OCR 识别出的可见文字、检测到的节点框与箭头属于观察结果;“这是审批流程”“失败后回到补材料”属于根据结构做出的解释。两类内容如果混成一句描述,后续无法知道错误来自视觉识别还是模型推断。检索可以使用解释扩大语义覆盖,但回答关键关系时应能回看节点、边与原图区域。
对统计图还要额外保护单位和图例。识别到一串百分数,却丢掉横轴年份或颜色对应对象,和表格丢表头是同一种结构错误。若系统没有可靠的图表结构化能力,应该明确把图像作为可打开证据,而不是生成一组看似精确的数据结论。
流程图还有一个特别容易遗漏的问题:节点都识别正确,箭头方向却错了。
例如图中“审核失败”返回补充材料,若只按从左到右的文字顺序拼接,系统可能理解成审核失败后直接结束。这个错误不会体现在 OCR 字符准确率里,却会直接改变答案。

表头丢失、代码断在函数中间、箭头关系被忽略,都可能让检索命中一段“看起来相关但无法正确解释”的内容。
三种内容最后要不要统一成同一种数据结构?
下游接口可以统一,但不能把结构差异抹掉。
比较实用的方式,是让所有 Chunk 都有正文、内容类型、来源文档、页码位置和父内容 ID,再为不同类型保留自己的扩展字段。表格可以保存表头、行组和原表编号,代码可以保存符号路径、行号与源图,图片可以保存 OCR 文本、描述来源和原图引用。
正文也最好区分用途。原始内容用于展示和核验,增强文本用于 Embedding,metadata 用于过滤、扩展和引用。比如一个表格子块的增强文本可以带上表题与表头,用户打开来源时却仍应看到原始表格,而不是系统为了检索拼出来的一段文字。
这种区分能避免两个问题。第一,给向量补充上下文时,不会污染用户看到的原文。第二,解析方法变化后,可以单独重建增强文本或索引,不必假装原始资料也发生了变化。
统一数据结构的目的,是让检索和前端知道怎样消费不同内容,不是把所有东西强行压成同一串字符。
可以把公共字段与类型扩展组织成一个明确契约。下面仍是教学伪代码,只展示“公共身份加类型载荷”的关系:
record = {
"chunk_id": stable_id,
"content_type": "table | code | image",
"raw_ref": source_region,
"display_content": original_content,
"embedding_text": enriched_text,
"parent_id": logical_object_id,
"type_payload": type_specific_fields,
}
消费方也要遵守契约。检索器读取 embedding_text,引用组件打开 raw_ref,相邻扩展只能在同一 parent_id 内发生,生成器则根据 content_type 决定提示模型如何理解证据。若所有组件仍只读取一个 content 字段,Schema 看起来再完整也没有真正进入链路。
版本字段同样重要。OCR 模型、版面分析、图像描述提示和代码识别规则变化后,同一页可能产出不同结构。至少保留解析方法版本和原始资料身份,才能对比重建前后差异,并在新结果更差时回退。
命中一个子块后,要不要把相邻内容全部带回来?
不能无条件扩展。
表格命中某个行组时,可以按父表 ID 取回表头和必要的相邻行。代码命中异常分支时,可以取回函数签名和相关初始化。图片描述被命中时,可以同时返回原图引用。
但扩展必须检查边界。相邻 Chunk 可能已经进入另一张表、另一个函数或下一幅图。只按前后 ID 把两边全部拉回,会重新引入无关内容。
比较稳妥的做法是同时使用父内容 ID、内容类型、章节路径和分块顺序。系统先确认相邻内容属于同一个逻辑对象,再按问题需要扩展,而不是把“相邻”直接等同于“相关”。
这也解释了为什么特殊内容不能只保存一段正文。没有父表、符号路径、原图和位置关系,检索命中以后就没有可靠办法恢复上下文。
怎么证明这套切分真的有用?
不要只检查系统有没有成功生成 Chunk。
表格测试要问具体字段,还要覆盖跨页和需要表头才能解释的问题。例如,正确答案位于第二页某一行,检索结果是否同时带回列名、单位和原表来源。
代码测试可以问某个函数怎样处理异常、某个参数在哪里校验。检查返回内容是否包含符号路径、必要的函数上下文,以及 OCR 代码是否被错误包装成可运行结论。
图片测试要准备必须依赖图中关系才能回答的问题。仅靠图片标题或周围正文就能回答的样本,无法证明系统真的理解并保留了图片信息。
评测时可以比较普通文本切分和结构感知切分,观察四件事:正确证据能否进入前 K 条,命中内容是否自带解释所需结构,重复扩展是否增加,引用能否回到原页或原图。
为了让结果可复现,测试样本还要带“必须看到的结构”。表格题标注所需表头、单位和目标行;代码题标注函数签名、关键分支与返回位置;图片题标注目标节点、连线或图例。只有正确答案文本而没有结构标注时,系统可能靠周围正文猜中答案,却仍然没有证明特殊内容处理有效。
测试可以主动注入故障:删掉第二页表头、打乱一处 Python 缩进、反转一条流程箭头,观察质检能否拦住,检索日志能否指出缺失字段,前端引用能否打开原始区域。主动注入不是为了制造漂亮分数,而是验证错误会在哪一层被发现,以及系统是否会把低置信结果当确定事实。
还要做普通正文回归。增加特殊内容分支后,不能让所有内容都经过昂贵的多模态处理,也不能因为类型分类错误而把正文送进图片流程。记录内容类型判定、采用的处理器、降级原因和最终证据来源,才能同时检查质量、成本与可解释性。
验收结果要落到可定位的失败类型,而不是只报一个总准确率。表格错误可以标记为跨页误合并、表头缺失、单位丢失或列错位;代码错误可以标记为字符识别、缩进破坏、符号边界或调用关系缺失;图片错误可以标记为 OCR 漏字、节点遗漏、连线方向或图例对应错误。不同标签对应不同处理器,才能知道下一步应该修解析、切分、增强文本还是检索。
面试时若被问“什么时候允许人工处理”,可以明确回答:高风险资料、自动置信不足以及结构质检失败时进入人工复核;人工修改应保留原始结果、修改人和版本,后续重建不能静默覆盖。人工复核不是用来掩盖所有失败,而是为自动链路无法可靠判断的边界提供可审计出口。
同时保留失败类型。表格错可以继续拆成表头丢失、跨页误合并和列错位;代码错可以拆成字符识别、缩进破坏和函数边界错误;图片错可以拆成文字遗漏、关系丢失和描述推断。

验收不能停在统计生成了多少 Chunk;还要分别用表格题、代码题和图片关系题检查结构是否完整、来源是否可回看。
没有现成的通用参数能替代这组验证。资料类型、问题粒度和模型上下文都不同,最终方案必须在自己的内容上测试。
面试官继续追问,怎么接?
表格太长,复制表头会不会制造大量重复?
会增加重复文本,所以不能无限细切。应先寻找业务上自然的行组,控制子表数量,再在去重和排序阶段识别同一父表。复制表头的目的是让每个子表可解释,代价是索引和候选中会出现重复,需要在评测里同时看召回与冗余。
PDF 里的代码识别错了,为什么还允许进入索引?
它可以作为低置信度的辅助检索入口,但回答时必须显示来源并保留原图核验。若场景要求代码可执行,就应该走人工校验或源文件接入,不能把 OCR 结果直接升级成确定事实。
图片描述参与 Embedding,会不会把模型幻觉写进知识库?
有这个风险。因此描述要标明生成方式,与 OCR 文本和原图分开存储。检索可以利用描述扩大候选,但最终回答与引用应回到可核验的图像内容。对高风险资料,还需要人工检查描述与原图是否一致。
为什么不把所有特殊内容都交给多模态模型?
因为成本、延迟、可复现性和定位能力都要考虑。多模态模型可以参与理解,却不能替代结构化字段和原始位置。遇到错误时,系统仍要知道问题发生在 OCR、布局、切分、检索还是生成,而不是只得到一次黑盒输出。
表格、代码和图片,怎样保证切开后仍看得懂
现场口述时,可以按“先恢复结构,再决定边界,最后验证证据”来组织:
表格、代码和图片不能直接按普通段落切,因为它们的语义依赖结构。表格需要先恢复行列、表头和跨页关系,小表可以整体入块,超长表按完整行组或业务区域拆分,每块继续携带表头、父表 ID、顺序和页码。源代码优先按类和函数切,PDF 识别出的代码还要保留缩进、原始截图、位置和置信信息,不能假设 OCR 结果可以运行。图片则要区分截图、流程图和数据图,OCR 或模型描述只作为检索辅助,回答仍要能回到原图。
检索命中子块后,可以通过父内容 ID、章节路径和内容类型取回必要上下文,但不能无条件扩展相邻块。验证时我会分别准备表格字段题、代码逻辑题和图片关系题,检查正确证据是否进入前 K 条、命中内容是否带齐理解所需结构、重复是否增加,以及引用能否回到原页或原图。没有跑过的效果只说验证方案,不用示例数字冒充项目结果。
这道题考的不是会不会列出三种切分规则。
真正的重点是:结构在哪里,超限以后按什么边界拆,拆开后怎样恢复上下文,最后又怎样证明内容没有被切坏。