1. 为什么通用大模型一写论文就露馅
先聊点直观的体验。你用某款通用大模型去写一篇材料学综述或者教育学实证论文,开头两段看着还挺像那么回事,越往后越不对劲。引用文献是编的,数据是含糊的,专业术语像隔了一层纱,最关键的是论证逻辑经常在关键节点上突然垮掉。前几年大家还能用“生成式AI嘛,能帮你起个草稿就不错了”来安慰自己,但到了现在,这种安慰话已经说不过去了。
问题的本质不在模型“笨”,而在它缺少最核心的一样东西:垂直领域的可信知识。
通用大模型是靠海量公开文本训练出来的,它学到的是“语言的统计规律”,不是“某个学科的真理性结论”。你让它写一篇通用的软文、一段代码注释、一个营销方案,它确实顺手。但论文是什么?论文是学术共同体内部的知识生产活动,它有一套严格到近乎苛刻的规则,包括文献的真实性、数据的可溯源性、术语的准确性、研究边界的前提限定、以及结论的保守表达。这套规则建立在“你必须知道这个领域到底发生过什么、哪些结论已经被证实、哪些争论还没有定论”的基础之上。通用模型训练数据里确实包含了大量论文文本,但它没有能力区分一篇论文是被反复引用的奠基之作,还是一篇被撤稿的问题文章。
所以你看,通用模型写不好论文,不是质量差,而是它根本没有资格进入学术话语体系。它缺少三个东西,我总结为“三无”:
- 无边界感:它不知道一个问题的研究边界在哪里,容易把已经被推翻的观点当作有效结论继续展开论证。
- 无溯源能力:它能写出“根据某研究发现”,但那个文献编号、作者、期刊、年份全是它统计出来的“最像样”的假货。
- 无领域共识:它不理解学术共同体内部对术语的默认约束,比如“显著相关”和“因果关系”在统计语境下是完全不同的两个强度表述,它经常混着用。
这时候RAG就登场了。RAG全称是Retrieval-Augmented Generation,检索增强生成。思路不复杂:与其让模型硬着头皮去回答它自己都不确定的知识点,不如把外部知识库准备好,让模型在生成之前先去检索相关文档片段,把片段作为参考依据拼接进上下文,再基于这些内容生成回答。说白了,就是给模型配了一个外置的、可更新的、内容可控的“知识硬盘”。
这篇文章想聊的,就是为什么RAG适合做论文相关的垂直场景,以及真正做落地的时候,哪些环节容易踩坑,哪些参数值得反复调,哪些坑我实际趟过之后才知道要绕开走。
2. RAG 为什么适合垂直论文场景,而不是万能灵药
2.1 场景特点决定了RAG的技术路线
论文场景的核心特点只有一个:知识必须可验证。
这跟客服机器人场景完全不一样。客服场景里,用户问“我的订单什么时候发货”,知识库里的答案是“一般48小时发出”,模型回答错了也可以接受,最多用户再追问一句。但论文场景里,你让模型引用了一篇2021年发表在权威期刊上的文章,真实情况是这篇文献确实存在,但模型把它的研究结论理解反了,这个错误会直接毁掉整篇论文的可信度。所以论文场景下的RAG,知识准确性的权重远远高于流畅度。
另一个特点是知识更新速度极快。通用模型的训练语料往往停留在某个时间点之前,而学术研究是持续产出的。某个研究方向今年有五篇新论文发表,直接推翻了两年前的主流结论,通用模型肯定不知道。RAG可以通过更新本地知识库的方式,让模型始终保持对最新文献的感知能力。这是通用模型永远做不到的,因为重新训练一次的成本和周期完全不可接受。
我见过不少人试图把论文写作的需求直接丢给通用大模型,然后通过反复修改提示词来改善效果。这条路走到头了,顶多让模型不编造那么离谱,但根本上无法解决“引用真实文献”“复现真实论证路径”这两大硬需求。提示词不可能让模型知道它没见过的一篇论文到底讲了什么。
2.2 垂直化不等于拼数据,要做领域适配
很多人以为Vertical AI就是把行业的PDF文档灌进知识库,然后接个大模型API就完事了。这个理解太浅了。
垂直化的核心在于:整个链路都要围绕该领域的特殊性来重新设计。
拿论文场景举例,第一层是文档格式的特殊性。学术论文是高度结构化的文本,有标题、摘要、引言、方法、实验、结论、参考文献,每个部分承担的功能完全不同。如果用通用的文本切分方法,把一篇论文从头到尾切成等长的片段,检索效果会很差。因为模型检索的时候通常带着一个具体的问题,比如“这个数据集在训练时用了什么预处理方法”,如果切分后的片段没有保留章节标题的信息,模型就不知道这段内容到底属于“方法”还是“相关工作”,检索就会产生大量的噪声。
第二层是查询意图的特殊性。普通搜索里用户会输入“XX系统怎么配置”,但论文场景的查询经常是一整句复杂描述,比如“基于Transformer架构的模型在小样本条件下如何进行迁移学习才能避免过拟合”。这种查询包含了一个完整的研究问题,包含任务、方法、条件、目标四个维度。通用RAG的检索过程,对这种长句子的处理效果往往不理想,因为向量检索用的embedding模型可能把整个句子的语义压缩成了一团,丢失了关键条件词的重要性。
第三层是输出的约束性。论文里的每一个关键断言最好都有对应的文献支撑。这就意味着RAG不仅要检索到内容,还要在生成时把“来源文献”的结构信息一起带出来。很多现成的RAG框架做不到这一点,它们只会把检索到的片段拼进提示词里,但模型并不会自觉地给每个观点都配一个正确的引用标注。你需要在做系统设计的时候,把引用的生成逻辑显式地写进流程里。
说到底,RAG对于论文场景是一种必要条件,但不是一个开箱即用的充分条件。这也是为什么市面上那么多现成的RAG平台,真正拿来做论文辅助写作的时候,效果总让人觉得差一口气。
2.3 端到端生成和RAG的本质区别
顺着上面说,你可能会有个疑问:为什么不直接把一堆论文文档丢给一个超长上下文的大模型,让它一次性读完再写?最近各家都在卷上下文长度,两百K、一千万token的都有,看起来好像不必做RAG了。
这个问题我实际测过。把十篇论文全文塞进上下文里让大模型写综述,表面上看它确实“读过”了所有内容,但实际效果非常不稳定。原因有三个:
- 注意力分散:大模型面对超长上下文时,注意力的分配并不均匀,越是靠中间的内容越容易被忽略。论文的核心信息分散在全文各处,很容易漏掉关键细节。
- 噪声干扰:论文里包含引用格式、作者信息、脚注、致谢这些与主题无关的内容,长篇上下文里这些噪声会被模型一并吸收,反过来污染输出质量。
- 成本极高:每调用一次接口,输入token都按整段上下文计费,实际操作起来费用会变得非常夸张。
RAG解决的是“相关性聚焦”。它通过检索把不相关的内容先过滤掉,只留下与当前问题高度相关的片段,配合原文引用,让模型在有限的上下文里聚焦于真正有用的信息。这就像一个研究员面对堆积如山的PDF时,先抽出与问题直接相关的二十页来看,而不是把全部资料从头到尾读一遍。所以RAG在论文场景下,不是“能用”的问题,而是“必须用”的问题。
3. 完整知识库搭建:从PDF到可检索的高质量片段
3.1 数据清洗是第一个分水岭
知识库的质量直接决定了RAG效果的天花板。很多项目死在第一步:数据没洗干净。
论文PDF的来源千奇百怪。有出版社官网下载的原生PDF,有第三方平台扫描再OCR的版本,有会议论文集的合并文件,有预印本网站下载的带修订标记的版本。不同类型的PDF解析出来,文本质量差异巨大。
原生PDF解析出来的文本通常是干净的,但有两个隐藏问题:一是双栏排版会导致阅读顺序错乱,二是公式和特殊符号会被打断成碎片。扫描版PDF则需要OCR,现在的OCR引擎对印刷体英文和中文识别率都很高,但对数学公式、上下标、希腊字母依然存在较高错误率。
我踩过的坑是:PDF解析完之后没有做“段落完整性”校验,导致后续切分出来的chunk里频繁出现“半句话”现象。比如一个段落到一半就截断了,然后下一段又从无关的位置开始。模型检索到一个不完整的片段,生成的结果就很容易出现逻辑断裂。
所以数据清洗环节我建议至少做三件事:
- 段落重组:按版面布局恢复正确的阅读顺序,双栏PDF要按栏从左到右、从上到下重新拼接段落。
- 格式噪声去除:删掉页眉页脚、DOI号、参考文献列表中的无关信息,但要保留标题结构。因为后续会用到标题信息做切分。
- 内容完整性校验:检查每个段落是否以句号或问号等结束符收尾,不完整的段落要和下一段合并,直到形成完整语义块。
这三步做完,才谈得上Embedding和检索。
3.2 Chunk切分不是按字数切的,是按语义边界切的
进入切分环节,这是很多人最容易犯错误的地方。
通用的切分策略是固定字数加滑动窗口。比如每256个字符切一段,重叠32个字符。但论文场景里,这种方法很不合适。原因在于学术论文的段落本身就是按语义组织的,一个段落通常只讨论一个论点,长度可能只有100字也可能有500字。按固定字数切会把自然段落拦腰截断,导致chunk内部语义不完整,检索时经常出现词不达意的情况。
我在实际项目中采用的分层切分策略是这样的:
- 先按文档结构切分:根据PDF解析出来的标题层级,把论文拆成“章节块”,比如Introduction、Related Work、Method、Experiments、Conclusion。
- 再按段落切分:每个章节内部,以自然段为最小单位,段落过长的再做二次切分,但二次切分时必须以句子边界为切分点。
- 设置元信息:每个chunk保留“论文标题、作者、年、章节名、段落序号”这些元数据。这些元数据在后续检索排序和引用生成时至关重要。
关于chunk大小的选择,我给个经验值:纯文本段落切分的chunk大小控制在200到500个中文字符之间比较合适。太短了包含的信息量不足以让模型理解上下文,太长了又会让检索精度下降、并且消耗大量上下文空间。对于论文的方法部分,500字符都不一定够,这类内容信息密度高、术语密集,可以适当放宽到800字符。
重叠区域我建议设置在50字左右即可。论文语言本身信息密度高,不像对话文本需要大的重叠来维持连贯性,过大的重叠只是增加存储和检索的负担。
3.3 Embedding模型挑选要分语言、分领域
Embedding模型的选择直接影响检索质量。同样一句话,用不同的embedding模型编码后,在向量空间里的距离分布可能完全不同。
在论文场景里有两个特殊要求:
- 专业术语感知能力:通用embedding模型对学术术语的处理往往停留在字面层面。“随机森林”和“决策树”的关系,通用模型可能理解得不够深入,但领域微调过的embedding模型能更好地区分这些概念的层次关系。
- 多语言支持:做中文学术写作的人时常需要引用英文文献。英文论文的embedding和中文论文的embedding如果由同一个模型生成,跨语言检索时效果会打折扣。实测下来,某些中英双语模型在跨语言场景下能保持不错的对齐效果,但单语模型的跨语言表现参差不齐,需要在具体场景里测了才知道。
我的判断标准很简单:挑选embedding模型的唯一标准,是“在你自己的数据集上跑检索评测,看召回率”。不是看榜单,不是看论文指标,而是拿你自己准备的那几百篇文献、几十个真实查询,跑一遍Recall@K。这一步花不了半天时间,但对最终效果的影响远远大于后面任何一步调优。
目前实测下来,国内开源的中文学术场景里,有几类模型表现尚可,但具体名字我就不推荐了,因为这类模型迭代太快,今天好用的下个月可能就有更好的替代方案。原则就一条:选支持长文本、支持领域术语、在自有数据上实测过Recall的。
4. 检索链路:从向量相似度到混合检索
4.1 纯向量检索的迷惑性
很多初学者会误以为有了向量库和Embedding模型,检索就解决了。实际跑起来你会发现,纯向量检索的准确率在论文场景里通常只有六成上下。
原因在于向量检索本质上是一种“语义相似度”匹配。你给系统输入“有哪些方法可以缓解小样本条件下的过拟合”,向量检索会把所有在语义上接近这句话的chunk都拉出来,但它不知道哪些chunk的答案是真正符合这个问题的。比如文献里有一句话“本文提出了一种基于数据增强的小样本学习方法”,这句话跟你的问题语义高度相关,但实际它并没有回答你的问题,它只是跟你问了同一个话题。
这种“相关但不对题”的检索结果,是论文场景里最常见的失败模式。
4.2 加一个BM25,召回立刻不一样
解决这个问题的成熟方案是混合检索:向量检索和BM25关键词检索并行,然后融合结果。
BM25是一种经典的关键词匹配算法,它会对查询词进行分词,然后计算文档片段里这些词的出现频率和重要性权重。它不关心语义,只看字面的匹配程度。在论文场景里非常有效,因为学术语言有大量固定的术语组合,比如“梯度消失”“联邦学习”“样本不平衡”,这些术语在语义向量里很容易被合并进一个很大的语义簇导致区分度不够,但BM25可以精确命中那些同时出现了多个关键术语的chunk。
我在系统里实现的检索流程是:
- 向量召回top 50个候选chunk。
- BM25召回top 20个候选chunk。
- 两个集合合并去重,得到一个不超过70个chunk的候选池。
- 候选池里的chunk带着得分进入下一轮重排。
融合权重的取法,我实践中常用的起点是向量召回占0.6、BM25占0.4,然后根据评测结果调整。如果查询是长描述句(比如研究问题),向量权重可以往上调;如果查询是几个关键词的组合,BM25权重应该加大。
4.3 Query改写:模型自己都不知道自己在问什么
这是我在实际项目中捡到的一个大便宜,也是很多人不知道的细节。
用户输入的查询,往往不是最适合检索的形式。比如用户问“帮我找一些关于图神经网络在推荐系统中的应用的文献”,这个句子作为向量检索的输入,语义表达很完整,没问题。但如果用户问的是“GNN推荐哪篇比较好”,这句话的口语化程度比较高,而且“哪篇比较好”这种比较性意图会把检索带偏。
解决方案是加一个简单的查询改写模块:把用户原始输入先送给大模型,让模型把查询改写成一种更适合检索的形式。通常包括以下几种改写策略:
- 关键词抽取:把口语化的问题转换成术语组合,比如“GNN推荐哪篇比较好”改写成“图神经网络 推荐系统 论文”。
- 查询扩展:为原始查询补充同义词和相关概念,比如“深度学习的优化收敛慢的问题”扩展出“梯度消失”“学习率调度”“损失函数震荡”。
- 意图澄清:如果问题本身太宽泛,比如“讲讲注意力机制”,改写模块应该自动识别出这种宽泛问题,并把检索策略调整为“召回综述类文献”或者“引导用户细化问题”。
这个改写模块把检索端的准确率提升了明显一截。值得注意的坑是改写模块不能让模型自由发挥,必须给它严格约束:只能输出改写后的查询文本,不能加任何解释性话语,否则模型会生成一堆“这是一个关于……的查询,我认为……”这种垃圾文本污染检索输入。
4.4 重排环节:数学上叫融合,实用上叫救火
候选池里的chunk有七八十个,但最终进入大模型上下文的只能有七八个。谁留下来,谁被淘汰,这一步就是重排(Rerank)要解决的问题。
重排模型的选择有很多,也有专门的交叉编码器。这类模型会把查询和候选chunk拼接在一起输入模型,输出一个相关性分数。计算量比向量检索大得多,但因为候选集只有七八十个,完全撑得住。
我强烈建议,论文场景的RAG必须加上重排步骤。实测数据是:加了重排之后,最终答案的引用准确率能提升十个百分点以上。原因很简单,向量检索阶段找到的是语义相关的chunk,但重排模型能捕捉更细粒度的匹配关系,比如查询里的主体和候选chunk里的主体是否真的对应、时间条件是否满足、实验设置是否匹配。
重排还有一个额外价值:它能让最终进入上下文的chunk顺序更合理。大模型对上下文不同位置的注意力不同,把最相关的chunk放在上下文的前部,通常能提升生成质量。这个我后面会再展开。
5. 生成链路:引用、上下文和幻觉控制
5.1 检索到的内容,怎么填进提示词
很多人写的提示词就是把检索到的内容一字排开丢进上下文,然后告诉模型“请基于以下内容回答”。这种做法在论文场景下非常不推荐。
因为论文对引用的要求极其严格。如果模型不知道哪句话来自哪篇文献,它在生成的回答里就无法自动生成准确的引注。你需要把检索到的chunk的元信息(来源文献标题、作者、年份、所在章节)一并作为结构化文本传给模型,并且明确提示模型:在回答中引用观点时,必须同时标注原文出处。
我实际使用的提示词模板结构大致是:
你是一位学术写作助手。请根据以下检索资料回答用户的问题。 每个检索资料会以如下格式呈现: [文献1] 标题:xxx;作者:xxx;年份:xxx;段落:xxx 内容:…… [文献2] 标题:xxx;作者:xxx;年份:xxx;段落:xxx 内容:…… 写作要求: 1. 回答中的每一个实质性观点都必须有文献支撑,并在观点后标注来源编号,例如(文献1)。 2. 如果检索资料不足以支撑回答,请明确说出“现有检索资料不足以回答该问题”,不要编造。 3. 术语使用必须与原文保持一致,不能自行改写含义。这套模板的核心是让模型把“引用”和“生成”当作同一个任务来完成,而不是事后补引用。事后补引用是很多RAG系统实际效果差的根源之一,模型生成文本的时候根本不知道自己引的是哪份资料,最后引用列表看着挺齐,仔细一查文不对题。
5.2 幻觉只能压制,不能根除
必须承认一个残酷现实:大模型的幻觉问题,即便加了RAG也不可能100%消除。因为生成阶段模型仍然有可能在回答里加入一些检索资料里并不存在的信息。
在这个问题上,最有效的手段是“训”而不是“劝”。也就是在提示词里建立一个约束规则,让模型对不认识的领域直接保持沉默。学术场景里,“不知道”远比“编一个答案”要安全得多。
我给系统设置了一个三层幻觉防控机制:
- 检索缺失检测:如果检索阶段的最高分低于某个阈值,系统直接拒绝回答,并提示用户换个说法重新提问。
- 生成前约束:提示词里明确要求,回答必须源自检索资料,不得引用个人知识库。
- 生成后校验:对模型输出的每个带引用的句子,做一次源码比对,检查引用的内容片段是否真的存在于对应的检索chunk中。这一步可以用简单的字符串匹配完成。
三层机制的实现都不复杂,但对实际效果的影响非常大。尤其是生成后校验,能够在最终输出前拦截掉整段编造的引用,把幻觉的影响范围缩小到一个可容忍的程度。
5.3 上下文窗口分配策略
论文场景生成时,用户的需求往往不是简单的一句话问答,而是一段长论述。比如“写一个关于联邦学习安全威胁的研究进展综述段落”。这种任务对上下文窗口的管理提出了新要求。
我的做法是把上下文做了功能区隔:
- 前部放重排后得分最高的三到五个chunk,这些是模型生成时最重要的信息基础。
- 中间部分放次相关的chunk,这些用于补充视角,防止模型只依赖单一文献产生片面表述。
- 在功能区隔之间插入明确的分隔标记。
这样做有一个附带好处:当模型在生成的结尾需要做小结时,它能优先回顾头部的高质量chunk,而不是被中部那些不那么相关的chunk干扰。
6. 评估标准:怎么知道RAG系统到底好不好
6.1 离线评测的四个维度
RAG系统的评测,不能只看最终生成的文本质量。我把评测拆成四个独立维度,分别对应链路的不同阶段。
| 评测维度 | 考察对象 | 指标含义 | 论文场景的及格线 |
|---|---|---|---|
| 检索召回率 | 检索模块 | 相关chunk是否被成功找回 | Recall@10 不低于0.7 |
| 重排准确率 | 重排模块 | 得分最高的chunk是否真的最优 | NDCG@5 不低于0.8 |
| 生成忠实度 | 生成模块 | 回答内容是否严格基于检索资料 | 不低于0.9 |
| 答案相关度 | 全链路 | 最终答案是否回答了用户问题 | 不低于0.8 |
离线评测需要用有标注的数据集。我实践中用的方法是,抽取50篇文献,为每篇设定三到五个真实研究问题,然后人工标注每个问题对应的chunk。这个标注过程大概花费一到两天的时间,但换来的是后续每次改动之后的可靠评估基准。如果不做标注评测,后面所有参数调优都等于在盲调。
6.2 在线评估要关注用户行为
离线评测合格不等于线上体验好。论文场景里用户有一个非常重要的行为特征是追问型:用户看了答案之后,会针对答案里的某一点进行追问,“你刚才说的基线模型具体是哪个”,这类追问对检索模块的压力远大于初轮提问。
所以在线上评估阶段,我格外关注两个指标:
- 追问命中率:当用户对初始回答进行追问时,系统能否基于同一知识库检索到追问题对应的内容。
- 重复提问率:用户是不是反复用不同的话术提同一个问题,说明初次回答没有命中要害。
一个值得重视的经验:初轮检索的chunk很可能不包含追问所需的背景信息,因为追问针对的是答案里的一个细节,而不是初始问题。针对这个问题,我的做法是把上一轮生成的内容也截断成chunk,追加到当前轮的检索候选池里,让新问题能在上一轮答案的上下文中做二次检索。这个设计在十几轮深度追问测试里效果提升非常明显。
6.3 推荐参数速查表
这里整理一份我在多个论文RAG项目里沉淀下来的参数起步值,可以直接当作基线使用。但务必记得,这些值只作为起点,真正落地时要用你自己的数据集做微调。
| 参数项 | 建议值 | 调整方向 |
|---|---|---|
| chunk_size | 300字(中文),500字符(英文) | 术语密集段落加大到600-800 |
| overlap | 50字 | 段落逻辑紧凑时减小到20 |
| 向量召回k值 | 50 | 知识库总量大且噪声多时提高到80 |
| BM25召回k值 | 20 | 查询包含明确术语时提高到30 |
| 重排后进入上下文的chunk数 | 8 | 长综述任务增加到12 |
| 混合检索权重 | 向量0.6,BM25 0.4 | 长描述查询调向量,关键词查询调BM25 |
| 拒绝回答阈值 | 最高分低于0.45 | 知识库较窄时可下调到0.3,但需额外人工审核 |
调参的原则就一条:一次只动一个变量。每次改动后都跑一遍离线评测,拿数值说话。很多团队在调参阶段喜欢一口气改五六个参数,出了问题都不知道是哪一步引起的,反而浪费大量时间。
7. 实战中躲不开的几个疑难杂症
7.1 扫描版论文的质量崩塌
前面说了OCR的问题,这里专门展开讲一个真实案例。
某个项目里知识库里加了一批九十年代的老论文扫描件,OCR之后发现公式区域被识别成了乱码符号。这本来不是大问题,但因为没有清洗,这些乱码混进了chunk里,被检索到之后,模型引用了那些带乱码的句子,导致答案里出现了一堆莫名其妙的符号组合。最气人的是,在向量检索阶段,那些乱码chunk居然经常排名靠前,因为它们的向量和某些查询在字面上有奇怪的相似性。
解决方案是加一个专门的“乱码chunk过滤”:在数据管道里对每个chunk做一次非ASCII字符含量检测,如果篡改比例异常高,就标记为“低质量chunk”降权处理,严重者直接不入库。
7.2 引用编号错乱:参考文献编号跟着正文走
写综述的时候,模型经常把引用的编号搞错。比如正文里说“(文献5)”,但实际参考文献列表里第5篇是另一篇完全不相关的文章。这个问题的根源在于,生成阶段模型对编号的推理能力有限,它可以把内容写得对,但编号这种需要序列对齐的工作往往出错。
我的解决思路比较直接:不让模型自己写编号。生成阶段让模型只写“(文献1)”这种占位符,这个编号对应的是prompt里的chunk顺序。生成完成之后,用脚本把占位符映射到参考文献列表的真实编号。这个映射过程是确定性的,不会出错。这个做法看起来简单,但能直接消灭掉一大类引用错乱问题。
7.3 用户给的查询太模糊,系统怎么办
有些用户根本不知道自己想找什么。比如一个研究生刚拿到导师给的题目,只输入了“知识蒸馏”四个字。这种宽泛到极致的查询,任何RAG系统都很难给出精准的答案。
我在系统里做了一个“查询宽泛度识别”模块,如果识别到查询过于宽泛,不会直接检索,而是先返回一组引导性问题:你是想了解知识蒸馏的基础概念、最新进展、还是具体应用场景?这个交互虽然多了一步,但能显著提升后续检索的精准度,因为它把用户的真实需求给逼出来了。
类似的宽泛度阈值可以这样判断:将整个知识库做一次主题聚类,极端情况下,如果一个查询的结果把知识库中所有簇的内容都召回了,那它大概率就很宽泛。
7.4 多轮对话的索引漂移问题
这是所有对话式RAG系统都有的老大难问题。用户连续问了五个问题之后,第五个问题往往是基于前四轮的语境才能理解的,比如“那这个方法在医学影像上效果怎么样”里的“这个方法”跟前几轮的内容相关。如果系统只拿第五轮的原始文本去做检索,召回几乎必然失败。
我最初的做法是给检索模块拼接前面的对话摘要,但效果一般,因为摘要会引入噪声。后来改成了把前两轮的用户问题原文和最终回答拼接成“语境补充块”,一起送入检索模块。检索效果相对好了很多。代价是检索输入变长、耗时变长,但在论文场景里,准确性优先,这个代价值得付出。
7.5 案例:一次基准失败后的完整复盘
最后分享一个真实失败的调参案例,这个案例让我对RAG系统的评估方式有了更深的认知。
某次优化时我对重排模块进行了改版,离线评测里“重排准确率”提高了三个百分点,但端到端测试时,实际答案质量反而下降了。排查了很久,发现问题不在于重排模块本身,而在于我改了重排模型的输入格式,把原本包括章节标题的信息流砍掉了。重排模型失去了章节语义的参考,虽然它给出的相关性排序更符合“语义匹配”,但生成时模型因为缺少章节上下文而产生了多处术语误用。
这次教训我记了很久。RAG的每一个子模块都是相互牵连的,单独优化某一个模块,不带着全链路跑一遍评测,你永远不知道改动会痛击哪里。我现在的做法是,任何改动都要同时记录离线指标和端到端人工打分,两者共同决定是否保留改动。
8. 下一步:论文RAG的扩展思考
写完正文,再分享几个我在后续迭代里持续在试的方向。
第一个是知识库的动态更新机制。论文知识库不是一次性构建完就完了,总有新文献要进来。如何在新增文献入库时,不影响已有检索结果的稳定性,以及如何定期清理那些被反复引用但已经被新研究超越的旧文献,这两个问题我现在还没有完全满意的解法,但初步思路是在入库时跑一遍相似度去重,识别出与现有内容高度重合的新chunk,然后让它们通过时间戳标记去参与更细粒度的排序。
第二个是引用粒度的细化。当前的系统基本做到“引用到文献”这一级,下一步想做到“引用到论文的具体章节甚至具体实验设置”。这需要更精细的数据标注,成本不低,但对用户的价值很大。尤其在综述写作场景里,知道“哪个实验设置下得出的结论”比知道“哪篇文献提出了这个结论”要重要得多。
第三个是多文档综合论证能力的增强。现有系统更多是检索-生成模式,离真正的“看完多篇文献之后形成自己的论证框架”还有距离。那需要的不只是检索,而是对多个来源的观点进行冲突检测、归纳汇总和优先级排序。这条路很长,但它才是论文写作里真正值钱的部分。
我个人在实际项目里最深的一点体会是:RAG这件事,技术方案的成熟度已经很高了,真正拉开差距的永远是对场景的理解深度和数据工程的基本功。懂论文、愿意花时间把数据洗干净的人,哪怕用的模型接口比别人的便宜,做出来的系统也一定比那些只会调Prompt的人强得多。这行没有银弹,但也没有真正不可逾越的门槛,方法对了,剩下的就是耐心。