用 Java 接入大模型(十二):RAG 全景——為何要做、何時不應做
用 Java 接入大模型(十二):RAG 全景——为什么要做,什么时候不要做
RAG 適用於資料量大、需要更新且超出上下文窗口的知識補充場景;資料量小或問題涉及行為、精確計算時,應先考慮提示詞、微調或程式碼等更合適的方法。文章指出,RAG 只能降低而非消除模型幻覺,其效果上限取決於資料質素。
2026-10-30 10
版权
版权声明:
本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《 阿里云开发者社区用户服务协议》和 《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写 侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
简介: 本文是RAG实践指南,直击核心问题:**该不该做RAG?** 明确其仅解决“模型不知道”(非“没听懂”),提出五大禁用场景——知识量小、需行为矫正、要精确计算、更新极慢等,并厘清RAG与微调的分工。强调:资料能塞进上下文就别上RAG;效果上限取决于资料质量,而非技术选型。
阶段二收尾之后,进入整个系列里篇幅最大的一块:RAG。开始之前先要回答一个很多人直接跳过的问题——这个东西到底该不该做。 它解决的问题很明确,但被滥用的程度也很高,不少项目上了向量库之后发现"还不如把文档直接贴进提示词"。这一篇给一套判断标准,以及什么时候该用别的手段。
一、RAG 解决的是哪一类问题
第七篇讲 Prompt 工程时,把一个关键区分立了起来:模型表现不对,要么是"模型不知道",要么是"模型没听懂"。
RAG 针对的完全是第一类。
它的做法可以拆成三步理解:
- 检索:拿用户的问题,去你自己的资料库里找出最相关的若干段内容;
- 增强:把这些内容拼进提示词,一起发给模型;
- 生成:模型基于这些内容回答。
所以从工程角度看,RAG 的本质非常朴素:它不是让模型变聪明,而是让模型在回答这一题时,手里正好有该有的资料。 模型的能力没有变化,变的是它眼前有没有那份材料。
这一点想清楚,很多关于 RAG 的困惑就消失了。它做不好"模型没听懂"这一类问题,也改不了模型的行为习惯——那些是提示词和微调的事。
二、什么时候不要做 RAG
这一节是本文的重点,因为多数教程只讲"怎么做 RAG",不讲"什么时候不该做"。
情况一:知识量很小,而且基本不变。
这是最典型的过度设计。如果你的知识就是一份几百字的产品说明、一页 FAQ、一张字段对照表,那直接放进提示词就行,根本不需要向量库。
算一笔账:引入向量库要增加一套中间件(部署、备份、监控、升级)、一套向量化流程(切分、Embedding 调用、增量更新)、一套检索逻辑(相似度阈值、重排)。这些加起来的维护成本,远远超过"在提示词里多塞 2000 字"的代价。
一个可以直接用的判断:如果你的全部资料能塞进上下文窗口,就先别上 RAG。 等资料量确实超出窗口、或者更新频率高到手工维护不现实,再考虑。
情况二:问题出在"模型没听懂"。
这是第七篇讲过的:输出结构不稳定、术语用错、语气不对——这些改提示词就能解决,跟资料无关。RAG 帮不上,加了只是白干。
情况三:要的是行为改变,不是知识补充。
想让模型固定用某种写作风格、掌握某套很难用语言描述的判断标准——这是微调的领域。RAG 给的是资料,不是习惯。
情况四:要的是精确计算或确定性结果。
金额汇总、日期推算、规则判定。这些应该交给代码,模型只负责理解题意和组织表达。RAG 检索得再准,模型算错的还是会算错。
情况五:知识更新极慢,且一次加载就够。
如果资料一年不变,那"每次请求都去检索一遍"就是纯浪费。启动时加载进提示词,或者干脆做成静态说明,效果一样但链路短得多。
把这五条收成一句话:RAG 是为"资料多、要更新、超出窗口"设计的。缺任何一个条件,都该先问问有没有更简单的办法。
三、RAG 和微调的分工
这两个经常被放在一起比较,但它们解决的不是同一件事。
- 知识型问题用 RAG:模型不知道某个事实、某份文档、某条规则。改的是"给它看什么",不改模型本身。
- 行为型问题用微调:模型知道该怎么做,但做得不稳定、风格不对、格式总是差一点。改的是"它的习惯"。
几个对比维度值得说明:
更新速度。 RAG 更新资料只需替换文档,分钟级生效;微调改一次要重新准备数据、训练、验证、发布,周期以天或周计。
可解释性。 RAG 能告诉你"这句话出自哪份文档的第几段",用户可以核对;微调做不到——你只知道模型被训练过,说不清它为什么这么答。
成本结构。 RAG 的成本主要花在每次请求的检索和额外的 token 上(持续开销);微调的成本主要在训练和后续维护上(前期开销)。请求量大的场景,RAG 的持续成本会更明显。
能力边界。 RAG 没法让模型学会它本来就不会的任务;微调也很难塞进大量会变的事实性知识。
实践中的顺序一般是:先提示词,再 RAG,最后才考虑微调。 因为这三者的投入是递增的,而多数需求在前两步就能满足。
四、架构总览
RAG 的链路比前面几篇的"一次调用"长不少,先看全貌,再逐个环节展开。
离线部分(资料入库,不参与线上请求):
- 文档收集与解析:把 PDF、Word、网页、数据库记录统一转成纯文本。这一步的坑比想象中多——扫描件要 OCR、表格会散架、页眉页脚会混进正文。
- 切分:把长文档切成适合检索的小块。切得好不好,直接决定检索能不能命中。
- 向量化:用 Embedding 模型把每块文本转成向量。
- 入库:写进向量库,同时保留原文和元数据(来源、时间、权限标签)。
在线部分(每次请求都走):
- 查询处理:用户的问题往往口语化、有指代、缺关键词,直接拿去检索效果差,可能要先改写或拆解。
- 检索:按相似度召回一批候选片段。
- 重排:对候选做更精细的相关性排序。检索到了不等于排对了,这一步的收益常常比想象中大。
- 上下文拼装:把选中的片段按一定结构塞进提示词,同时控制总长度(第九篇的预算问题)。
- 生成:模型基于拼装好的上下文回答,答案里最好带上出处。
上面这些环节,正好对应后面的六篇:切分(#13)、Embedding 选型(#14)、向量库落地(#15)、检索质量优化(#16)、效果评测(#17)、接入已有服务(#18)。
一个容易被低估的环节是"查询处理"。 很多 RAG 效果不好,根源不在向量库也不在模型,而在用户那句话本身就不适合直接检索。用户问"这个怎么退",文档里写的是"退款流程说明"——字面相似度很低,但语义是一回事。这类问题靠查询改写能救回来,靠调阈值救不回来。
五、Java 技术栈怎么选
RAG 生态里的教程和工具大多以 Python 为主,Java 这边相对少一些,但该有的都有。
向量库这一层,建议先跟着你已有的数据库走。 如果你已经在用 PostgreSQL,那 pgvector 扩展往往是最省事的选择——不用引入新中间件,事务、备份、权限体系都复用现有的。选独立向量库(Milvus、Elasticsearch 等)的理由通常只有两个:数据量很大,或者对检索性能有更高要求。为了 RAG 单独引入一套中间件,是很多团队过渡设计的第一步。
框架这一层,Spring AI 和 LangChain4j 是目前 Java 侧比较主流的选择。 它们提供了文档加载器、切分器、向量库客户端、对话记忆等组件的统一封装。
但这里有个取舍值得提前想清楚:框架能省掉大量胶水代码,也会把链路细节藏起来。 当检索效果不好需要排查时,你得知道框架在哪一步做了什么——如果你对链路的每个环节没有概念,排查就只能靠猜。所以建议是:先用框架跑通,但一定要能说清它内部经过了哪几步,必要的时候能把它替换掉。
六、一个常见误解:RAG 能治幻觉
这是被传得最广的一个错误期待。RAG 对幻觉的作用是降低,不是消除。
原因在于,整条链路里有多个环节都可能出错:
- 检索没命中:资料里有答案,但没被召回。这时候模型手里没有依据,只能靠自己编——而且它不知道自己缺了东西,会答得很自信。
- 检索命中了但排错了:正确片段排在十几名开外,拼进上下文时被截掉了。
- 上下文里有噪音:召回了一批不相关的内容,模型被误导。
- 模型无视了资料:上下文里明明写着答案是 A,模型仍然按自己的先验答了 B。这在小模型或矛盾信息并存时更容易出现。
所以正确的期待是:RAG 把"完全靠模型记忆"变成"有据可依",但"据"本身可能不全、不准、没被用上。
这也直接推出了一个工程要求:答案要能标出处。 让模型在回答里指明依据来自哪一段,用户才能核对。这不只是体验问题——它是唯一能让用户发现"检索错了"的机制。 如果答案看起来通顺但来源是错的,没有出处标注的话,用户根本无从判断。
七、小结与决策路径
把这一篇收成一条可以照着走的判断路径:
- 资料能塞进上下文窗口,且更新不频繁 → 直接放进提示词,不要上 RAG
- 问题是"没听懂"(格式、语气、术语) → 改提示词(第七篇)
- 要改的是行为习惯、写作风格 → 微调
- 要精确计算或确定性结果 → 交给代码
- 资料多、要更新、超出窗口 → 这才是 RAG 的适用场景
决定要做之后,按这个顺序推进:先把离线链路做对(切分、向量化、入库),再优化在线检索(查询处理、重排),最后做评测。 顺序反了的话,你会在一堆没调好的变量里找不到问题在哪。
还有一条经验:RAG 的效果上限取决于你的资料质量,而不是向量库的选型。 资料本身零散、过时、互相矛盾,换再好的检索方案也救不回来。所以在动技术方案之前,先看看资料是什么状态——这一步经常被跳过,但它往往是决定性的。
下一篇
下一节开始拆解离线链路的第一环:文本切分。这件事看着简单(按长度切开不就行了),实际上是 RAG 里最容易被低估的一步——切得太碎会丢上下文,切得太大会引入噪音,切错了边界还会把一句话拦腰截断。下一篇讲几种切分策略各自适合什么内容,以及怎么判断切得好不好。
本文是「用 Java 接入大模型」系列第十二篇,阶段三开篇。前一篇讲了模型不可用时的降级方案,建议按顺序看。文中技术选型建议以通用实践为例,具体组件能力以你使用的产品文档为准。
來源:阿里雲開發者社區 AI · developer.aliyun.com