AI 面试 / 150 道 AI 面试题
5. 数据与知识工程
原文备份 · 第 6 / 22 篇 · 查看极客时间原知识库 ↗
本篇目录 · 8 节
来源:150 道 AI 面试题
RAG 的"上游":文档解析、清洗、切分、Embedding、向量库。数据质量决定 RAG 上限——"垃圾进,垃圾出"。
57. 从原始文档到向量库,哪一步最容易"悄悄毁掉" RAG 质量?怎么防?
直接答案:数据流水线(加载 → 解析 → 清洗 → 切分 → 嵌入)中,解析和切分是最容易"悄悄毁掉"质量的环节,因为它们造成的损失不会立刻报错,而是静默传导到检索结果。
- 解析的坑:PDF 文本提取乱序、表格结构丢失、扫描件当文本型处理、页眉页脚混入正文——这些让"正确内容"变成"错乱内容",且很难察觉。
- 切分的坑:固定字符硬切把一句话/一个表格腰斩,语义断裂后,即使检索命中,喂给模型的内容也是残缺的。
怎么防:
- 按文档类型选解析工具:文本型 PDF 用结构感知解析,扫描件先 OCR,表格用专用解析。
- 切分按语义边界:用语义分块/结构分块,加 overlap。
- 抽样质检:上线前人工抽一批 chunk 看质量,而非只看"跑通了"。
知识点讲解:
- 静默失败的本质:检索系统不会因为 chunk 内容错乱就报错——它照样返回"最相似"的结果,只是那个结果是坏的。这比"报错"更危险,因为没人知道出了问题。
- 质量传导链:解析错 → 清洗漏 → 切分断 → embedding 把错误固化进向量 → 检索返回错误 → 生成输出错误。每一环的误差都会向下累积。
- 投入产出比:数据质量的投入产出比往往高于调模型——修好解析和切分,比换更强的 LLM 更划算。
- 质检要落到指标:可以抽样算"chunk 语义完整率""表格结构保留率",用数字而非感觉衡量数据质量。
- 加分点:能说出"数据流水线每一步都是质量关卡,错误会静默传导"。
58. PDF 解析为什么特别难?有哪些坑和对策?
直接答案:PDF 是"排版导向"而非"内容导向"的格式,解析难在:
- 文本提取乱序:PDF 存的是"字符坐标",提取时顺序可能错乱(尤其多栏、表格)。
- 表格/图片丢失:扫描件是图片,纯文本提取拿不到内容。
- 版式干扰:页眉页脚、页码、水印混入正文。
- 编码问题:特殊字符、中文编码错乱。
对策:
- 表格用专门的解析(pdfplumber、Camelot)。
- 扫描件先 OCR(PaddleOCR、Tesseract)。
- 结构化文档用带版式感知的解析器(Marker、Docling)。
知识点讲解:
- 根因:PDF 的核心是"在页面上画字符的指令",而非"有逻辑顺序的文本流",所以"所见"和"所读"可能完全两码事。
- 文本型 vs 扫描件是两套打法:文本型 PDF 有嵌入的文本层可提取;扫描件是纯图片,必须先 OCR,且 OCR 本身引入识别错误。
- 多栏、表格、公式是重灾区:需要版式感知解析,否则内容错位。
- 没有银弹:要按文档类型组合工具,实际落地常是"多种解析器 + 规则 + 人工质检"的流水线。
- 面试加分点:能区分"文本型 PDF"和"扫描件"并给出对应方案,且知道"解析质量直接决定 RAG 效果"。
59. 表格数据在 RAG 里怎么处理?
直接答案:表格不能简单按行切分,否则结构被破坏、语义丢失。处理方式:
- 结构化提取:把表格转成结构化格式(Markdown 表、JSON、CSV)。
- 保留表头上下文:每个单元格/行的 chunk 要带上表头,否则数字失去含义。
- 按表语义切分:整表或按行切,而非按字符硬切。
- 走 SQL 检索:结构化表格存关系库,用 Text-to-SQL 查询,而非向量检索。
知识点讲解:
- 核心:表格的价值在结构关系,切碎就废了——一个数字离开表头和行列语义就失去意义。
- 两条路线:
- 简单表、做内容问答 → 转 Markdown 后向量检索(带表头的 chunk)。
- 复杂聚合查询("去年 Q3 华东区销售额 Top5")→ 存关系库 + Text-to-SQL,向量检索做不了聚合。
- 表头上下文的实现:把表头作为前缀拼进每个 chunk,或作为元数据,保证数字可解释。
- Text-to-SQL 的难点:schema 理解、SQL 正确性、注入风险,需要校验和沙箱。
- 面试加分点:能说出"表格要么保结构进向量,要么进 SQL 走结构化查询",并判断何时用哪条路。
60. RAG 里"去重"为什么重要?重复内容会怎样破坏检索质量?
直接答案:去重是数据清洗里最容易被忽视、但影响很大的一环。重复内容的危害:
- 挤占检索排名:同一段内容在语料里出现 10 次(多份文档互相复制粘贴),向量检索时它的 10 个副本会同时占据 top-k 的多个位置,把其他相关内容挤掉。
- 放大噪声:重复的错误/过时内容被反复召回,让模型基于"重复的错误"作答。
- 浪费成本:重复的 embedding 白白占存储和检索算力。
知识点讲解:
- 去重粒度:
- 完全重复(逐字相同)
- 近似重复(语义相近、略改措辞)
- 跨文档重复(模板化文档,如合同、公告)
- 近似去重技术:MinHash、SimHash(局部敏感哈希)、或 embedding 相似度聚类。
- 模板化文档陷阱:合同、公告看似不同实则高度相似,向量距离极近,会严重污染检索——这是最隐蔽的重复。
- 去重的副作用:过度去重可能删掉"同一事实的合理重复",要结合业务判断。
- 加分点:能说出"重复内容不是小问题,它会静默地污染 top-k 召回"。
61. Embedding 的批量生成怎么做?有什么注意点?
直接答案:大规模文档要批量生成 embedding,注意点:
- 批量 + 并发:用 embedding API 的批量接口或异步并发,控制限流。
- 断点续跑:记录进度,失败后能继续,不必重跑。
- 版本管理:换 embedding 模型要记录,因为向量空间变了需重建索引。
- 成本控制:embedding 也有成本,大批量要估算。
知识点讲解:
- 离线任务的工程化:embedding 生成是一次性(或增量)的离线任务,要像批量调用一样做好重试、进度、幂等。
- 换模型的破坏性:换 embedding 模型 = 向量空间变了 = 所有向量要重新生成 + 索引重建 + 检索质量重新评估,代价巨大。要从源头锁定 embedding 模型。
- 增量更新策略:新文档只生成新向量,不必全量重跑;但换模型时必须全量重跑。
- 批量 vs 实时:入库用批量接口(更便宜),实时查询的 embedding 单独走在线接口。
- 面试加分点:能说出"embedding 模型是长期锁定项,换一次代价大",且能区分全量/增量两种场景。
62. 向量库的元数据(Metadata)怎么设计?为什么重要?
直接答案:元数据是向量之外附加的结构化字段(来源、标题、时间、作者、章节、类型)。设计要点:
- 用于过滤:检索时先按元数据过滤("只看 2024 年后的政策"),再向量检索。
- 用于溯源:返回结果时展示来源。
- 用于更新:按文档 ID 精确删除/更新向量。
知识点讲解:
- 元数据的三个作用:过滤(缩小范围)、溯源(可解释)、生命周期管理(增删改)。
- "先过滤再检索"为什么更准:向量相似度是"语义近似",元数据过滤是"硬约束",两者结合能大幅提升精准度(如限定时间范围、文档类型、权限)。
- 权限过滤是合规刚需:多租户场景必须按元数据(如 tenant_id)过滤,否则会越权召回他人数据。
- 常见错误:不存元数据 → 无法过滤、无法溯源、无法增量更新。
- 设计要点:元数据字段要提前规划好(哪些要过滤、哪些要展示、哪些要排序),后期补字段可能要重建索引。
- 面试加分点:能说出"元数据 = 过滤 + 溯源 + 生命周期管理"。
63. 文档的层级结构为何不能丢?切分和检索时怎么利用它补足上下文?
直接答案:文档层级结构指章节、标题、段落之间的父子关系(如"第 3 章 → 3.1 节 → 3.1.2 小节")。
为什么要保留:层级关系蕴含语义——一个段落脱离了它的章节标题,意思可能就不完整或歧义("结论"两个字离开标题就不知道是关于什么的结论)。保留层级可以:
- 切分时按层级切(标题作为 chunk 的上下文)。
- 检索时返回"命中片段 + 它的父章节"补充上下文。
知识点讲解:
- 典型做法:把标题路径作为每个 chunk 的前缀(如"3.1.2 小节 · XXX"),或作为元数据字段(h1/h2/h3)。
- 这是"小到大检索"的思想来源:小 chunk 精确检索,父级补上下文,兼顾精度和完整性。
- 层级信息解决的核心问题:一个孤立的 chunk 缺乏"上下文锚点",层级结构就是天然的自带上下文。
- 实现方式:解析阶段就提取标题层级(用标题样式、字体大小),切分时把标题路径注入每个 chunk。
- 面试加分点:能说出"保留层级是为了检索时能补足上下文",并关联到"小到大检索"。
64. 知识库规模很大(千万级文档),数据侧怎么设计?
直接答案:先建立文档主键、版本、文档到 chunk 的映射,再做增量 upsert、删除和一致性检查;单一 collection 也可以精确更新。
分区或多库用于租户隔离、容量或性能优化,不是精确更新的必要条件。路由能缩小搜索范围,也可能误判领域而漏召回,跨域问题可能需要查多个分区。
知识点讲解:
- 精确更新的关键:文档到 chunk 的映射(doc_id → chunk_id 列表)是精确删除/更新的基础。示例:文档 v2 从 8 个 chunk 变成 6 个,更新后应只保留 v2 的 6 个 chunk,旧的 2 个不能残留(残留 = "幽灵向量",会污染检索)。
- 要测试的边界:全文替换、删除文档、路由到错误领域,分别测试。
- 分区/分片的设计:按租户隔离(多租户合规)、按领域分区(缩小搜索范围)、按容量分片(性能)。但分区会引入"路由误判漏召回"的风险。
- 一致性:删除/更新后要做一致性检查,确认向量库里的 chunk 与源文档一致。
- 规模化的代价:千万级文档要考虑索引构建时间、存储成本、检索延迟,常需分布式向量库(Milvus、Qdrant 等)。