很多人第一次做知识库问答,流程特别顺:
把 PDF 拖进去。
点一下“构建知识库”。
然后问一句:这篇论文的核心贡献是什么?
如果答案看起来还行,就觉得 RAG 跑通了。
但真正麻烦的地方,往往要到第二天才出现。
你问一个细节,它答偏了。
你问一个实验设置,它把两篇论文混在一起。
你让它给出处,它给了一个看起来相关、但其实不支撑结论的片段。
这时候不要急着换模型。
很多 RAG 的问题,不是发生在“生成答案”的最后一秒,而是发生在前面几步:PDF 解析、文本切片、元数据、召回排序、证据引用。
这篇不讲宏大的 RAG 原理。
只讲一套研究生自己能用的排故工作流。

很多人调 RAG,只盯着最终回答。
这个习惯很危险。
因为最终回答只是结果,不是病因。
一个知识库问答系统,至少要经过五步:
PDF 被解析成文本; 文本被切成 chunk; chunk 带着元数据进入向量库; 查询时召回 top-k 片段; 模型基于片段组织答案。
任何一步出问题,最后都会表现成“模型答得不准”。
但它们的处理方式完全不同。
如果 PDF 解析把表格读坏了,你调 prompt 没用。
如果 chunk 太碎,关键上下文被切断,你换更贵的模型也只是让它更有礼貌地猜。
如果召回 top-k 里没有正确段落,模型再强也只能在错误材料上写作文。
所以做 RAG,第一件事不是追求“答案像不像人写的”。
第一件事是追问:
它回答这个问题时,到底看见了哪几段原文?

切片是最容易被低估的一步。
LlamaIndex 文档里,SentenceSplitter(chunk_size=1024, chunk_overlap=20) 是一个很典型的示例配置;它也说明 node parser 会把文档拆成 node,并继承父文档的 metadata。
这个细节很重要。
因为 chunk 不是“随便截一段文本”。
它应该同时保留三件东西:
当前段落本身; 它来自哪篇文档、哪一页、哪个章节; 它前后一点点上下文。
太小的问题是:一句话可能被切出来了,但它对应的实验设置、变量定义、表格标题都没了。
太大的问题是:召回命中了一大块文本,里面有多个主题,模型容易挑错重点。
我更建议研究生先用一个保守起点:
这不是标准答案。
它只是一个能开始排故的参数区间。
真正的判断标准只有一个:召回出来的 chunk,能不能单独支撑答案里的那一句话。

很多知识库做不出专业感,不是因为没有向量库。
而是因为每个 chunk 都像无名小卒。
只有正文,没有来源。
只有内容,没有页码。
只有相似度,没有章节位置。
这样一来,答案即使对了,你也很难验证。
最低限度,建议每个 chunk 都带这几类 metadata:
doc_id:文档唯一编号; title:论文或资料标题; year:年份; source_type:论文、网页、报告、导师主页; page:页码或网页段落位置; section:章节名; chunk_id:该文档内部的切片编号。
如果是做导师库,还可以加:
school; department; research_area; lab_name; homepage_url。
这些字段看起来像工程细节,但它们会直接改变内容质量。
没有 metadata,你只能问“它说了什么”。
有 metadata,你才能问:
只基于 2023 年之后的论文回答。只看方法章节,不要混入 introduction。给我列出同一导师主页里出现过的方向关键词。每个结论后面标出文档、页码和 chunk_id。
这时知识库才不像一个会背资料的聊天框,而像一个可以追溯的科研助手。

很多教程会告诉你设置 top_k=3、top_k=5、top_k=10。
但真正调系统时,只改 top-k 很粗。
你要看的是召回列表本身。
建议每次测试,都把下面这张表记录下来:
这张表比“感觉效果不错”有用得多。
它能告诉你下一步该调什么:
正确片段没进 top-k:优先调切片、embedding、query rewrite; 正确片段进了 top-k 但排得低:考虑 rerank; 正确片段进了 top-k 但答案仍错:检查 prompt 和引用约束; 召回片段本身读不懂:回去修 PDF 解析。
LangChain 文档里有“contextual compression”这类检索后压缩思路;LlamaIndex 也有 CitationQueryEngine 这类强调引用粒度的组件。它们背后的共同逻辑是:不要把一堆粗糙材料直接塞给模型,要让模型看到更相关、更可引用的上下文。

很多人做知识库,没有测试集。
每次调完参数,就随便问两句。
这会让你永远不知道系统到底变好了,还是只是这次问题刚好命中。
建议研究生先做一个 20-30 个问题的小测试集。
不用复杂。
按五类问题分就行:
- 定位型问题
:某个定义、公式、数据集在哪里出现; - 对比型问题
:两篇论文的方法差异是什么; - 证据型问题
:哪个实验支撑某个 claim; - 限制型问题
:只允许基于某一年、某个章节、某类来源回答; - 反事实型问题
:资料里没有的信息,模型是否会承认不知道。
最关键的是第五类。
一个 RAG 系统如果只会答,不会说“不知道”,它在科研场景里很危险。
因为研究里最贵的不是少答一句。
是把不存在的证据写进开题、综述或论文。

如果你已经有一个知识库,但感觉它“不太准”,可以按这个顺序查。
第一步,抽 5 个错误答案。
不要抽你最满意的,专门抽出错的。
第二步,把每个问题对应的 top-5 召回片段导出来。
不要只看最终回答。
第三步,判断正确证据有没有进入 top-5。
没有进入,就先修检索;进入了但答错,再修生成。
第四步,检查 chunk 是否完整。
看它有没有标题、页码、表头、前后文。
第五步,给每条答案加引用约束。
例如:
你的每一句结论后面都必须给出来源编号。如果来源片段不能支撑结论,就写“资料不足”。不允许使用知识库之外的信息补全。
第六步,保留一张调参记录表。
每次只改一个变量:chunk_size、overlap、top_k、rerank、query rewrite、prompt。
不要一次全改。
一次全改,看起来很勤奋,实际上是在制造迷雾。
把 PDF 扔进去,只是开始。
能不能用,取决于它能不能稳定回答三个问题:
它看见了什么?
它为什么这么答?
我能不能回到原文复核?
如果这三件事做不到,知识库再漂亮,也只是一个会聊天的资料堆。
如果这三件事做到了,它才真的能进入科研流程:
帮你读论文。
帮你整理导师信息。
帮你写开题综述。
帮你把一个模糊方向拆成可验证的证据链。
如果你最近也在搭知识库、做导师信息整理、读论文、做开题,或者想把 RAG / AI 工作流用到自己的课题里,可以来找我聊。
导师选择、课题方向、技术路线、文献工具、AI 知识库搭建,都可以。

参考资料:
LlamaIndex 文档:Node Parser Usage Pattern;CitationQueryEngine。 LangChain 文档:Text splitters;Retrieval / contextual compression 相关文档。
夜雨聆风