最近有同学拿着一份 PDF 产品手册,上传到大模型对话窗口,回车后没几秒,大模型照着文档里的退货政策回了一段话。于是他觉得自己已经把 RAG 做完了。
这个理解需要纠正一下。把 PDF 上传给大模型,不等于 RAG。它只是把 PDF 里自动解析出来的文本,当作临时上下文塞给了模型;而真正的 RAG 核心,是大模型回答之前先“检索”和问题相关的资料,再把检索到的内容拼进提示词。
这篇文章会把链路拆开,讲清楚为什么上传 PDF 不等于 RAG,以及一个能够称为 RAG 知识库的最小流程该包含哪几步。你会看到文件解析、文本分块、向量化、检索、重排、引用这些环节各自起什么作用,也会看到一套相对靠谱的评估方法。准备开始做 PDF 问答、企业内部制度问答、产品手册问答的,建议把这条链路先踩实。
1. 先想清楚:PDF 丢给大模型,大模型看到的不是“整个知识库”
1.1 上传 PDF 在实际处理里只相当于一次上下文拼接
不管你去用的是网页版 AI 助手、开源大模型的 Web UI,还是某个企业工具里的“上传文件并提问”,当一份 PDF 被上传后,后台做的事情通常是:文件解析成文本,截取前面一部分文本,然后和你的问题一起拼进提示词。
这个流程里没有“检索”。模型模型能不能答对,完全取决于文件有没有被完整解析、截取的文本是否覆盖答案来源。好处是省事,不需要建索引,也不需要向量库。代价是:文件一长,前面和中间内容很容易被截断;文件一多,问答系统根本不知道该以哪份文件为准;回答再正确,也没有办法准确告诉你“这句话来自 PDF 的第几页、第几段”。
我见过不少项目在第一版就是这么做的,测试时只挑了一篇几十页的介绍文档,效果尚可。等换成几份产品手册、合同模板、客服常见问题后,发现模型会自己把不同文件里的信息混在一起,甚至出现离谱的编造。这个阶段出现的“幻觉”,其实不是模型能力问题,而是上下文结构根本没有建立起来。
1.2 为什么单文件时够用,文件一多就“看起来傻”
单独一份 PDF 上传,通常只考验“文本提取”和“上下文长度”。如果 PDF 本身能复制文字,问题聚焦在文档前中段,体验可能不错。但这套方式有不少边界:
- 上下文长度限制:文本超过窗口大小后,要么被截断,要么被压缩,答案自然不稳定。
- 跨文档能力弱:多个 PDF 同时上传,模型能看到的文本量更有限,也无法区分知识的版本和适用范围。
- 无法做精确来源回溯:回答虽然引用了某句话,但系统里没有保留段落索引,用户想“跳到 PDF 原文看上下文”,很难实现。
- 更新成本高:文档更新后,如果直接在会话里替换文件,模型只能基于新的一轮对话理解,没有统一的知识版本管理。
- 扫描版 PDF 很容易彻底失效:文本层缺失时,上传后的模型根本读不到内容,只会在界面上给你一个“看起来读完了”的假象。
这些边界叠加起来,就是很多人觉得“上传 PDF 问答不靠谱”的原因。真正进入 RAG 体系后,情况会改变:系统不依赖“一次性看到全文”,而是先把 PDF 做成可以被检索的片段,等用户提问后,只把最相关的几段找出来交给模型。这才是检索增强生成的本意。
判断标准很简单:如果系统没有任何“根据问题把文档片段找回来”的环节,无论前端页面做了多少上传和对话功能,它都不算完整意义的 RAG。
2. 真正做 RAG,链路里至少要拆出这几件事
2.1 召回阶段:先检索,后生成
RAG 的工作顺序,和人类查资料很像。人类拿到一个问题,不会重新背诵整本手册,而是先翻目录、翻索引,找到可能相关的章节,再阅读其中一小段,最后组织回答。RAG 就是把“翻找”这一步交给程序。
一个标准流程至少包含:文档解析、文本切分、向量化、索引构建、查询向量化、检索召回、重排、生成回答。前四步通常在文档入库时执行,后四步在用户提问时执行。
很多人第一次做 RAG,最容易忽略的是“检索”之后还要“重排”。只用向量相似度召回 Top K 片段时,可能召回了语义相近但顺序混乱的段落。重排模型会重新计算候选片段与问题的相关度,把最匹配的几段调到前面,生成质量往往能提升不少。
2.2 只做“把 PDF 塞进提示词”和 RAG 的差别在哪里
这里列一个表,方便对照:
| 对比维度 | 把 PDF 上传给大模型 | 一个最基本的 RAG 流程 |
|---|---|---|
| 文档处理 | 靠平台自带解析,用户不可控 | 自己能控制解析、切分和清洗 |
| 上下文组织 | 把所有可见文本塞进窗口 | 只检索最相关的若干片段 |
| 长文件 | 超过窗口就会被截断 | 拆成片段,按需召回 |
| 多文件 | 混合后容易串内容 | 通过元数据限制范围和来源 |
| 答案引用 | 多数不支持精确到段落页码 | 每段片段可保留文档名、页码、行号 |
| 知识更新 | 变更一份文件要重新传一次 | 重新更新索引对应的文档即可 |
| 可控性 | 用户很难知道模型使用了哪些内容 | 每轮检索结果可记录、可审计 |
从这个表能理解为什么 RAG 适合知识库场景:它的价值核心是“把有限的长文本知识变成可按问题定位的小片段”,而不是让模型死记硬背。
2.3 如果你做的是 Agentic RAG 或 Ontology RAG,也是在“先检索后生成”这个底座上扩展
现在网上常看到 Agentic RAG、Ontology RAG 这类概念。它们和基础 RAG 的区别,是在上面提到的核心流程上加了新的控制逻辑。Agentic RAG 会让模型决定先检索哪个库、拆成几个子问题、检索不充分时是否换一种检索词重试。Ontology RAG 或者 Graph RAG 则更多依赖实体关系、知识图谱结构,适合“人和岗位、项目和预算、零件和型号”这类关系密集的数据。
新手不要一上来就追求这些高级形态。先能把一个 PDF 按段落切好、检索出来、带引用回答,再考虑加 Agent 决策或图谱关系,否则会叠加太多不确定性。
3. 从最小可用项目开始,跑通一份 PDF 的 RAG 闭环
3.1 一套不过分依赖框架的实验流程
我推荐的做法是,先不用特意挑选一个复杂的 RAG 平台,直接用一段脚本把流程串起来。下面这段代码是通用流程示意,不是某个发行版本的官方 API,实际使用时要根据你选用的工具替换具体函数。
# 通用 RAG 最小流程演示 from doc_loader import load_pdf # 负责解析 PDF from chunker import split_text # 负责文本切分 from embedder import embed_texts # 负责文本向量化 from vector_store import VectorStore # 负责存储和相似度检索 from llm import chat # 负责最终回答 file_path = "产品手册.pdf" # 1. 解析 PDF,保留页码 doc_pages = load_pdf(file_path, include_page_number=True) # 2. 按段落或固定窗口切分,模拟常用参数 chunks = split_text( doc_pages, chunk_size=500, overlap=100 ) # 3. 向量化并写入库 vectors = embed_texts([chunk.text for chunk in chunks]) store = VectorStore() store.add(chunks, vectors) # 4. 用户提问 question = "退货政策要求保留哪些凭证?" # 5. 查询向量化、检索候选 query_vector = embed_texts([question])[0] candidates = store.search(query_vector, top_k=20) # 6. 重排,选出最相关的 3 段 final_chunks = rerank(question, candidates, top_k=3) # 7. 组装提示词并调用大模型 answer = chat(build_instruct(question, final_chunks)) print(answer)这段流程有几个值得注意的点:
- 第 1 步解析 PDF 时,要尽量把页码保下来。后面回答时能不能给出来源,靠的就是这个页码或段落 ID。
- 第 2 步切分,是决定检索质量最关键的位置。chunk_size=500 和 overlap=100 只是示例,中文一个词平均不到 2 个字,500 字大概对应一段比较完整的说明。不能盲信固定数字。
- 第 5 步先召回 20 条候选,第 6 步再精排到 3 条,目的是先保证“没有被遗漏”,再用重排提升“顺序准确性”。如果环境里没有重排模块,可以先只做 Top K 召回,但不能忽略它对效果的贡献。
3.2 先在单文档上验证再进入批量
第一次跑通时,不要直接开批量。先用一份结构清楚、能复制文字的 PDF,问 5 到 10 个问题,覆盖开头、中间、结尾三个位置。每次跑完都检查三个结果:模型回答是否准确、检索出的片段是否真的包含答案来源、引用页码是否指向正确的原文。
如果这些问题都能稳定通过,再写批量脚本,处理整个目录下的 PDF。批量场景下,还要额外处理三件事:文件命名是否唯一、解析失败的 PDF 是否有日志、每个文档的元数据是否挂得正确。否则某个文件嵌错了公司名,后面所有答案都会跟着错。
3.3 给答案加上来源,是检验 RAG 是否成立的方法
做 RAG 时,我最看重的一项能力是“可回溯”。程序把文档切成了片段,每个片段要带着来源信息一起进入向量库。回答生成后,最好能把命中的片段放在答案下方,显示成“来源:产品手册.pdf,第 12 页”。光是这个简单的设计,就能区分真的 RAG 和伪 RAG。
如果模型输出了结论,来源里却找不到对应内容,问题很可能出在:提示词没有限制模型只能基于给定片段回答。这句话大家可以在系统提示里加一句:“如果问题无法由提供的内容回答,请明确说明”。这句话能大幅降低检索增强后的编造。
第一版不要追求复杂提示词。先把“检索片段 -> 引用来源 -> 回答”闭环跑稳,后续再优化提示词。
4. PDF 文件类型决定 RAG 成败:先做解析预检,再谈向量化
4.1 普通文本 PDF、扫描版 PDF、表格型 PDF 完全是三类输入
我见过不少团队花大把时间调参数,最后发现效果差是因为 PDF 根本没解析对。文本型 PDF 可以直接提取文字,扫描型 PDF 没有文本层,必须走 OCR 或视觉模型才能拿到内容,表格型 PDF 则要处理行列拆分和多页跨页问题。
网上经常有 PDF 转 Word、PDF 编辑器之类的工具,它们能帮助我们快速确认某个 PDF 是否有文本层、表格是否会被拆乱。但这些工具解决的是“文件内容可读”问题,不等于 RAG 里的“文本切分正确”。如果你把一张扫描图片转成了 Word,里面很可能没有任何可直接检索的文字,只是图片放在文档里。
推荐做 PDF 预检:
- 拿一段成品 PDF 在阅读器里复制文字。
- 如果复制不出任何内容,基本可以判断是扫描版。
- 用 PDF 转文本工具抽一次全文,检查中文有没有乱码、表格是否变成一列乱序字符串。
- 检查是否存在页眉页脚混入正文的情况。
- 记录哪些页面是复杂图表页,后续这些页面可能需要单独处理,不适合参与普通切分。
预检这一步暴露的问题,通常比调检索参数更严重。
4.2 切分不只按字数,还要考虑章节、列表和表格语义
固定按 500 字切分的问题在于,它可能切断一段原本完整的规则。比如退货政策和售后电话放在同一个段落里,因为被切分成了两个片段,问题“退货找谁”可能只召回一半内容。较好的做法是在切分前先做结构感知:尽量按标题层级、列表项、段落空行来切割,再对超长段落做二次切分。
这里有个实际经验:切分后的片段不宜太短,也不要太长。太短,如“本政策自 2024 年 1 月 1 日生效”,缺少上下文;太长,如整页文字 3000 字,检索出来后喂给模型的噪声会变大。常用区间介于 300 到 800 字之间,具体还要看你的知识库内容密度。
4.3 检索方式不要太早锁死成“只用 Dense Vector Search”
现在向量检索很流行,但只依赖 Dense Vector Search(稠密向量检索)不一定最适合所有医疗、法律或政策文本。有的查询涉及精确型号、订单编号、法条条款数字,稠密向量很容易忽略精确匹配。可以考虑在索引里混合一些关键词型检索,再做结果合并和重排。这个组合在 RAG 实践中很常见,也常被称为混合检索。
新建 RAG 项目时,如果发现“明明这段文字里有标准答案,向量检索却召不回来”,先去检查是不是文本解析错误,然后再考虑加入关键词检索。不要一上来就怀疑模型。
5. 想证明这不是“自嗨型 PDF 问答”,拿指标和样例集说话
5.1 一条不需要花太多时间的验收路径
很多朋友会问 RAG 评测怎么做,知识库指标到底该看哪些。答案是:先准备一个高标准的测试问题集。每条问题里要包含标准问题、正确来源、期待出现的核心要点、所属文档范围。数量不用庞大,30 到 50 条就够第一轮验证。
测试问题要覆盖这几类:
- 能从文档某一段直接找到答案的问题,如“退货周期是几天”。
- 需要跨两段拼接的问题,如“说明书某一章节引用了另一个章节的定义”。
- 文档里没有答案,测试模型会不会抵抗的问题,如“这份手册没有提到的政策是什么”。
- 来源容易混淆的问题,比如两版产品手册中同一政策的说法不同。
- 扫描版 PDF 转成 OCR 后文本有误的问题,可测试系统能否给出较稳定的回应。
跑完后,逐条记录:
- 检索出来的前 3 个片段里有没有包含答案来源。
- 模型回答时有没有只用检索到的内容。
- 最终答案和标准答案是否接近。
- 来源引用是否正确。
5.2 几个基础指标的通俗解释
在做 RAG 相关文章时,常涉及的指标如下。理解它们比记住英文缩写更重要。
| 指标 | 通俗含义 | 主要排查方向 |
|---|---|---|
| 上下文命中率 / 召回率 | 正确答案是否出现在被召回文本里 | 解析、切分、检索 |
| 上下文精确率 / 噪声敏感度 | 召回文本里是否夹杂太多无关内容 | 重排、Top K 规模、切分粒度 |
| 回答忠实度 | 最终回答是否严格基于检索文本 | 提示词、模型选择 |
| 答案相关性 | 回答是否解决了提问意图 | 提示词、检索结果质量 |
| 引用准确率 | 每条结论是否能定位到正确来源 | 元数据、页码保留、切分逻辑 |
如果“上下文命中率”很低,就算把提示词写出一朵花也救不回来。这时候系统性问题通常不在生成侧,而在前面的解析与检索链路。反过来,如果检索命中率没问题,但回答依然乱编,问题多半出在提示词太“放养”,没有约束模型使用给定的内容。
第一轮评测,跑完先别急着追问答案准不准,先回答一个问题:正确答案有没有出现在检索结果里?没有,就回头改分块和索引,不要动模型设置。
6. 不同规模场景下,什么时候该直接用 PDF 对话,什么时候该升级到 RAG
6.1 几个常见场景和推荐选择
不是所有业务都必须上 RAG。如果你的目标只是快速问一份短 PDF 里靠前的要点,直接上传 PDF 可能是成本最低的方案。反过来,当文件多、版本多、回答必须给出“来源依据”时,RAG 是不可替代的底座。
这里给一张场景对照表:
| 业务情况 | 更合适的方式 | 理由 |
|---|---|---|
| 单份少于 20 页、能复制文字、只做信息提取 | 直接用大模型文件上传 | 成本低,流程简单 |
| 单份 PDF 超过 50 页,答案可能分布在任意位置 | 基础 RAG | 避免上下文截断,能定位答案区间 |
| 多份产品手册/政策文件,版本会持续更新 | 基础 RAG + 文档元数据 | 能按库筛选来源,改一版只更新对应索引 |
| 企业制度库中经常涉及权限范围隔离 | RAG + 元数据权限过滤 | 可以在检索层限制用户只能命中允许访问的文档 |
| 问题需要跨多个文档分步推理 | Agentic RAG | 需要规划子问题、多轮检索和结果合并 |
| 问题强依赖实体关系和层级关系 | Ontology RAG / Knowledge Graph RAG | 图结构更适合表达“部门和岗位、人员和项目”的关系 |
注意,表里的“权限过滤”“元数据过滤”指的都是检索层的正常工程设置,通过索引过滤实现,属于企业知识库常见做法。不要把它理解成绕过任何平台限制的方案。
6.2 实际落地时,我更建议的推进顺序
如果你正在从 0 搭一个 PDF 问答系统,建议按下面的顺序推进:
- 先拿 3 份不同类型 PDF 做解析预检,确认文本质量。
- 搭出“切分、向量化、检索、提示词、回答”的最小闭环。
- 每条结果显示来源,方便人工检查。
- 建 30 条评测问题集,跑第一轮指标。
- 根据“检索没命中、命中但不会用、引用错误”三类问题分别修复。
- 等单文件稳定后,再扩展到批量文件、重排模型、混合检索。
- 最后才考虑是否引入 Agentic RAG 或图谱类增强。
这个过程听起来不华丽,却很稳。前期花半天做好 PDF 解析,后面会省出大量调提示词的精力和时间。
RAG 的价值,从来不是“模型再聪明一点”,而是让模型在回答前有方法地翻到正确答案。先纠正“上传 PDF 就等于 RAG”这个误解,再去设计文件、索引、评测和提示词,你的知识库问答会少踩很多看不见的坑。