news 2026/9/29 7:48:56

RAG问答准确度优化实战:从切分、召回重排到Agentic RAG选型

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RAG问答准确度优化实战:从切分、召回重排到Agentic RAG选型

做RAG应用最怕的不是模型答不上来,而是它回答得特别流畅,结果通篇都是编的。我这两年接手过好几个检索增强生成项目,很多团队最初都以为“文档丢进向量库、接上大模型就算做完了”,真上线之后才发现问答准确度根本没法看——要么检索回来的内容驴唇不对马嘴,要么模型一本正经地脑补答案,再要么一问跨文档的关联问题就哑火。这篇要聊的,就是我实际优化RAG问答准确度时动过的每个环节:文本怎么切、检索怎么召回、上下文怎么塞、模型怎么约束,以及当你确实需要处理复杂知识关联时,Agentic RAG、GraphRAG、本体RAG这些进阶方案到底值不值得上。不管你是刚拿Ollama搭了一个简易本地RAG知识库,还是在折腾LangChain、LangChain4j、Spring AI的RAG流程,这套优化思路基本是通用的,区别只在工具写法。

1. 优化前先定位:RAG问答准确度差,到底差在哪一环

1.1 一条RAG链路里的典型丢分点

RAG看起来简单:文档解析、切分、向量化、召回、拼Prompt、生成。但实际评估的时候,每个环节都在偷偷丢分。我习惯把整个链路画成一条“丢分点流水线”来排查,不然很容易出现一种结果:你调了半天模型,答案还是不对,最后发现是召回阶段压根没把该找的内容找回来。

第一个丢分点是文档解析。很多真实场景里的PDF根本不是纯文本,里面是扫描件、嵌套表格、双栏排版。用普通解析器一抽,表格结构没了,页码混进正文,公式变成乱码。这个阶段损失的往往是精确信息,比如合同金额、法条编号、产品参数,后端的向量检索很难把已经丢失的信息找回来。

第二个是切分。固定按500字硬切,一整段讲完一个概念的文字被拦腰截断,后半段的关键解释跑到下一个chunk里。检索时如果只命中了前半段,模型手里就只有半截信息,自然答不准。这个问题在高密度术语的领域文档里特别明显,因为一个知识点往往跨越好几个自然段。

第三个是嵌入模型和领域不匹配。通用embedding模型对日常语义没问题,但遇到行业黑话、缩写、专有实体名,向量空间里根本拉不开距离。我遇到过客户问“工单怎么升级”,系统检索回来的全是不相干的“服务等级协议”段落,就是因为“工单”和“升级”两个词在通用模型里语义绑定太弱。

第四个是只召回不重排。向量数据库返回的top-k直接塞给大模型,这里面但凡混进一两条高相似度但不是正确答案的噪声,模型就会开始“加权平均”地编答案。第五个是上下文组织混乱。检索回来的20个chunk一股脑全拼进去,关键信息淹没在无关段落里。第六个在生成端:Prompt里没有任何约束,模型默认自己无所不知,资料里没有的答案它也能给你圆出来。

这六个丢分点里,真正需要换大模型才能解决的几乎没有。大多数时候,把切分、召回、重排、Prompt这几处修好,准确度就能有一个档次的提升。

1.2 先把评估指标定下来:Hit Rate、忠实度与答案相关性

优化RAG最忌讳“边调边看感觉”。因为你改了切分参数、换了embedding、加了重排,如果没一个客观指标,根本分不清是哪个改动起了作用。我建议动手前先花半天时间做一套测评集。

对于“检索准不准”,最核心的指标是Hit Rate。它的定义很朴素:对一组已知答案的问题,用你的检索器取top-k,统计“正确答案出现在这k个结果里”的比例。比如准备了50个问题,每个问题都知道正确答案出自哪份文档、哪个chunk,然后跑检索看top5里有没有命中,命中了35个,Hit Rate就是70%。这个指标快速、直观,能直接告诉我们检索环节行不行。

比Hit Rate再严格一点是MRR(Mean Reciprocal Rank)。它不只看答案有没有出现在top5里,还看排在第几位。第一位的得1.0,第二位的得0.5,第三位得0.33。比如用户的问题是“报销额度上限是多少”,正确答案排在第三位,即使Hit Rate判了命中,模型还是要跟前面两条噪声做斗争,所以MRR能反映排序质量。

生成侧也有两个指标:忠实度和答案相关性。忠实度衡量的是“模型回答的内容是否都能从检索到的上下文里找到依据”,相关性衡量的是“回答是否真的解决了用户问题”。这两个指标可以用RAGAS这类评估框架自动算,但初期建议人工抽样打分,因为自动评估本身也有误差。

我的经验是:先把Hit Rate提到85%以上,再谈生成侧优化。如果检索环节本身就漏,Prompt再怎么约束都白搭。

2. 检索侧优化:切分、混合召回与重排序三板斧

2.1 文本切分:固定chunk size是最容易踩的坑

检索准确度的地基是文本切分。很多教程里写的“chunk_size=500, overlap=50”只是一个起点,不是标准答案。直接套用在你的业务文档上,大概率会踩坑。

我现在的做法是“按结构切分优先于按长度切分”。如果文档本身有清晰的标题层级,比如Markdown、HTML、政府公文、技术手册,那就顺着标题把每个章节切成一个或多个chunk,保证一个chunk内在讲一个完整概念。如果是没有结构的纯文本,再用递归字符切分,先按段落切,段落太长再往句子级别拆,避免硬生生把一个概念劈成两半。

切分参数也不是拍脑袋定的。我一般在chunk_size等于300到500字、overlap等于50到100字这个区间起步,然后针对你的文档类型微调。overlap一定不能省,它的作用是保存边界信息。比如一个句子跨了两个chunk,没有overlap的话,后一个chunk看到的是半句话,语义严重残缺。

这里还有一个容易忽视的点:中文切分要考虑“字”和“token”的换算。embedding模型和LLM的tokenizer大多是按子词切分的,中文一个字的平均token数可能接近1,所以500“字”对应的token数往往比500“token”要多。你在设置chunk_size时,务必说清楚自己用的是字符数还是token数。

如果切得太碎导致上下文不足,我强烈建议用“父子块方案”。子块切得小一点用于精确召回,命中的子块再映射回更大的父块,把父块作为上下文喂给大模型。这样既保留了检索精度,又给模型提供了足够的信息密度的上下文。LangChain里的ParentDocumentRetriever就是干这个的,很多框架也有类似实现。

2.2 混合检索:让向量召回和关键词召回互补

向量检索有它的天然盲区。用户输入一个精确的型号、编号、法律条文号或者人名,比如“PRD-2024-0715需求文档”,向量检索可能把语义相近的需求文档排了前面,唯独没把这个精确编号当回事。这种场景下,关键词检索比向量检索可靠得多。

所以我在生产级RAG里基本都会上混合检索:向量召回负责“语义相似”,BM25这类稀疏检索负责“字面精确”,两者互补。举个例子,“报销流程”这种问题,用户可能会说“差旅费用怎么走单”,向量检索能抓住语义;但如果用户问“文档AAA-123”,就明显是BM25的菜。

混合之后怎么融合排序?最简单靠谱的是RRF(Reciprocal Rank Fusion),公式是score = Σ 1/(k + rank),k通常取60。它不看两路检索的具体分数,只看排名,天然解决了向量分数和BM25分数不可比的问题。另一种做法是加权和,但对分数做归一化很麻烦,效果未必比RRF好。

需要注意混合检索不是万能药。BM25召回的结果里也可能混入大量“字面相似但语义不符”的噪声,所以混合之后必须有重排兜底。

2.3 重排序:召回之后再加一道精准闸门

很多RAG项目为了省事,向量检索top5直接拼给模型。这样做的问题在于,向量检索的双塔结构为了效率牺牲了精度,query和文档在同一个向量空间里算相似度,但真正决定答案质量的往往是深层语义交互,比如“问题里有否定词”“两个文档描述的是同件事但结论相反”,这些双塔模型很难把握。

重排(Rerank)是解决这个问题的标准手段。做法很清晰:先用廉价的检索方式召回50到100个候选,然后交给一个cross-encoder重排模型,把query和每个候选文档拼在一起做深度交互打分,重新排序后只取前5到10个。Cross-encoder慢,但准,作为最后一公里把关非常值得。

我常用的重排模型是bge-reranker系列,比如bge-reranker-v2-m3,效果不错而且能处理多语言。使用重排时有一条经验:重排分数本身没有太多跨查询可比性,所以不要设定“分数低于0.5就丢弃”这种生硬的阈值,而是按排序位次截断,再配合最小分数兜底。

重排阶段还要保留元数据,因为下一步组装上下文时要按来源分组、去重、按文档优先级排序。别等重排完才想起来“这个chunk是从哪份文档来的”,再回头翻索引就费劲了。

3. 知识库结构设计:从“文档堆”到可精准命中的索引

3.1 元数据过滤:给向量库加上业务边界

很多RAG应用最隐蔽的问题不是检索算法不行,而是索引里混入了不该出现的东西。你的向量库里可能同时有今年和去年的政策文档、内部和公开的资料、不同产品线的FAQ。如果检索时不做任何过滤,一个关于“旧版退市产品”的问题,系统会同时召回今年最新版的介绍,最后模型把两个矛盾信息拼在一起,答案自然错得离谱。

解决办法是给每个chunk打上结构化的元数据:来源文档、所属章节、发布日期、部门、文档类型、权限级别。在检索时根据场景注入过滤条件。比如只检索2024年之后的有效制度,或者只检索某个产品线的FAQ,或者做多租户隔离时只允许检索当前用户有权访问的知识范围。

向量数据库基本都支持元数据过滤,比如Qdrant的Payload Filter、Milvus的expr过滤、pgvector的WHERE条件。我的规划习惯是:先设计好知识库的“业务边界”,再入库。知识库不是把所有文档倒进一个池子里,而是像图书馆一样按分类、按权限、按时间线组织好。

这里要特别注意权限隔离。内部资料一旦因为没做元数据过滤而被检索出来,再被大模型生成出来,就是安全事故。所以只要是多用户场景,“索引隔离”是RAG优化的前置条件。

3.2 父子块与小文档优先:命中得更准、喂给模型更干净

前面提到父子块,这里再展开说。它的设计思路是:小chunk负责精确召回,父chunk负责提供完整上下文。比如你在技术手册里检索“如何配置超时时间”,命中了一个只有两三句话的子chunk,但它讲的不完整,这时候把它升级回整个小节,模型就能看到完整的“配置超时时间的步骤和注意事项”。

另外一个原则我称之为“小文档优先”:把一个章节、一篇FAQ条目、一段产品说明作为一个独立知识单元来管理,而不是把一整本书切成几百个碎片。原因很简单,一个完整知识单元内部的概念是自洽的,检索命中它时,模型拿到的上下文更干净,不需要从几百个碎片里拼凑答案。

表格类内容要单独处理。通用切分器会把表格切成断断续续的碎片,非常影响检索。我通常把表格按“表头+每一行”转成一句结构化描述,比如“产品名:XX,价格:XX,库存:XX”,必要时再附上表格的原始Markdown文本。还有一个实用技巧:把当前章节的标题层级(H1/H2/H3)作为前缀拼到每个chunk开头,模型读到“【3.2节 配置超时时间】”和只读“配置超时时间”的感知完全不同,这相当于给chunk加了浅层上下文。

3.3 知识割裂的初步解法:先建立文档间的关系

“知识割裂”是RAG经典瓶颈之一,我理解它的本质是:单个chunk只有局部信息,但用户问题需要跨多个概念、多份文档才能回答。比如用户问“这个新功能对现有数据迁移流程有什么影响”,答案可能要同时参考新功能说明、数据迁移手册、兼容性列表三份资料,普通向量检索很难把这三个孤立chunk的关系建立起来。

初步解法不需要一上来就上知识图谱。可以先做两件事:第一,在入库阶段人工或半自动地给相关文档打“关联标签”,比如把同一项目的所有文档打上一个项目ID,检索时按项目ID做相关性加权;第二,对高频问题做预构建的“答案框架”,把所有涉及关联内容的chunk预先组织成一个组合文档,检索时直接命中组合文档。

这两步能解决一部分“知识割裂”问题,但要做彻底,还是得上GraphRAG或本体RAG。具体差异放到第5章详细说。

4. 生成侧优化:上下文压缩、Prompt约束与多轮记忆

4.1 上下文不是越多越好:压缩与去噪

检索回来的信息“塞得越多越准”是一个常见的错觉。你让模型看20个chunk、几万token的上下文,它确实有能力读完,但注意力会被大量无关信息稀释。更现实的问题是成本:每轮问答都把所有候选喂进模型,token消耗直线上升,延迟也上来了,实际用起来又贵又慢。

我的做法是把“上下文组装”当做一个专门的优化点。第一步,重排后只取前5到8个chunk;第二步,对chunk做压缩。最简单的是句子级抽取:用规则判断哪些句子包含问题的关键词或语义相关词,只保留这些句子。更高级一点,可以用一个小模型对候选chunk做“与query相关的摘要”,或者用LLMLingua这类工具做token级压缩。

压缩之后要检查一件事:压缩后的文本是否还保留关键数字、专有名词和结论句。我踩过坑,规则压缩把“每年报销额度上限5000元”里的数字抽丢了,模型拿到的材料里没有具体数值,只好自己猜了一个。所以压缩逻辑里要加入“关键信息保护”,对数字、金额、日期、型号做保留。

这里有个判断方法:把压缩后的上下文当作一份独立文档,让另一个模型不看原始材料只读压缩结果,看能不能回答测评集问题。如果能,说明压缩没有伤筋动骨;如果不能,就是压缩过头了。

4.2 Prompt设计:让模型学会引用、拒答、承认无知

生成侧最立竿见影的优化其实是Prompt。很多人把大模型想象成“什么都知道的答题机器”,但其实在RAG场景里,你需要把它训练成“只依据材料作答的办事员”。一个清晰的指令能大幅降低幻觉。

我会在Prompt里写这几条约束:第一,只依据【参考资料】回答用户问题,不要使用模型内部知识;第二,如果资料中没有答案,直接回复“资料中未找到相关信息”,不要编造;第三,回答中每个关键要点都需要标注引用来源编号,比如[1]、[2],便于用户追溯;第四,如果参考资料之间存在矛盾,明确指出矛盾。这几条听起来很简单,但真能显著改善生成质量。

举一个实际Prompt模板(示意):

你是一个严谨的知识库问答助手。 回答规则: 1. 只能依据【参考资料】回答,禁止使用你的内部知识补充。 2. 如果【参考资料】中找不到答案,请直接回答:资料中未找到相关信息。 3. 每个事实性要点后标注来源编号,格式如[1]、[2]。 4. 若资料之间存在矛盾,请分别列出并说明差异,不要自行调和。 【参考资料】 [1] ... [2] ... 用户问题:...

另外,给大模型提供一两个“资料不足”的few-shot示例特别有用。模型很擅长模仿示例风格,你给它看过“资料里没有提到,所以无法回答”的范例,它就更愿意拒答而不是硬编。

4.3 多轮对话场景:查询改写与记忆维护

多轮问答是RAG准确度下降的重灾区。用户第二句问“那它的价格呢”,如果不结合前文,“它”根本不知道指什么,检索必然跑偏。最简单也最有效的方法是做查询改写:用LLM或轻量规则,把当前问题结合对话历史改写成一个包含完整实体的独立查询,再拿去检索。这个查询可以是:“综合前文提到的产品XXX,用户现在询问它的价格,请检索产品XXX的价格信息。”

多轮对话还有个问题是记忆过长。历史对话全是token,全塞进去既不经济也干扰检索。我的做法是分三层:短期记忆保留最近两到三轮对话用于查询改写;任务记忆保留当前问题相关的关键实体和约束;长期记忆负责用户偏好或常用上下文,这部分可以用向量存储做二次检索。

在LangChain里你可以用ConversationalRetrievalChain这类组件,但不要止步于它自带的“把历史拼进检索”。核心是把改写后的query独立出来,这样才能保证检索质量。

5. 进阶方案:Agentic RAG、GraphRAG与本体RAG怎么选

5.1 Agentic RAG:从单次检索变成多步推理

当你发现“单次检索->单次生成”这个模式已经碰到天花板,比如用户问题里包含了对比、多跳推理、条件判断,普通RAG就有点撑不住了。这时候可以考虑Agentic RAG。

Agentic RAG的核心变化是:把检索从“一步到位”变成“按需多步”。系统先理解问题,决定需要哪些信息,然后路由到合适的知识库,必要时分步检索多个来源,甚至调用工具,最后综合生成答案。比如用户问“A方案和B方案哪个更适合我们公司”,Agentic RAG可以先检索A方案资料、再检索B方案资料,再检索公司现状文档,三次检索的结果合并后统一作答。

LangChain的Agent、LangChain4j的AiServices、Spring AI的Advisors都能实现这类流程。但我要提醒一句:Agentic RAG不等于所有问题都走Agent。多步推理意味着更多LLM调用,时延和token成本都是成倍增加的。我通常做一个分层策略:简单问题走一条快的普通RAG链路,复杂问题才进入Agentic链路。

Agentic RAG的实现里一定要设置步数上限,并且每一步都要有“检索结果可信度判断”,避免agent在一个错误方向上反复打转,浪费资源又跑偏。

5.2 GraphRAG与本体RAG:解决跨文档知识关联的两种思路

热搜词里反复出现“graphrag”“ontology rag”“解决了知识割裂rag”,这几个词指向的是同一个困扰:普通向量库擅长找“相似段落”,但不懂“概念之间的关系”。GraphRAG和本体RAG分别是解决这个问题的两条路线。

GraphRAG的思路是:在入库阶段用LLM从文档中抽取实体和关系,构建一张知识图谱,然后通过社区检测把关联密集的实体聚成社区,支持“全局性”问答。比如你库里有一百篇关于公司产品线的文档,用户问“我们所有产品里哪些依赖同一个底层平台”,这就是典型的跨文档全局问题。GraphRAG能通过图结构把散落在不同文档里的产品收敛到同一个平台节点上,给出全局视角。

本体RAG(Ontology RAG)走的是另一条更“重”的路线:先由领域专家定义一套本体schema,明确有哪些实体类型、哪些关系、哪些属性约束,再让LLM按这个schema从文档中抽取知识。它的优点非常明显:知识组织的边界清晰,术语对齐到标准词汇表,查询可以结构化。比如在医疗领域,统一把“阿司匹林”“拜阿司匹灵”都映射到标准实体“乙酰水杨酸”,就不会出现同一药物不同叫法导致的知识割裂。

两条路线的取舍在于:GraphRAG的图谱是自动抽取的,构建成本低,适合大规模文档但关系不太需要严格约束的场景;本体RAG需要人工设计schema,前期投入大,但准确性和可解释性更强,适合专业领域、术语规范要求高的场景。

我用一个表来对比:

方案构建成本术语一致性可解释性典型场景
普通向量RAG低弱弱常见文档问答
GraphRAG中中中跨文档全局问题、关系密集数据
本体RAG高强强医疗、法律、金融等专业术语场景

需要注意的是,这两个方案不是替代关系,更多是互补。很多项目会先用普通向量RAG做基础问答,再叠加GraphRAG处理全局问题,本体RAG则作为知识组织和术语对齐的底座。

5.3 选型判断:数据规模、成本与时延的权衡

“要不要上GraphRAG/本体RAG/Agentic RAG”这个问题,我给的答案通常是:先别急着上,把普通RAG优化到极限再说。因为重型方案带来的部署复杂度和推理成本都是实打实的。

我的判断维度有三个。看数据规模:如果只有几百份文档、概念关联并不密集,普通向量RAG加上混合检索和重排足够用了;如果上万份文档,且文档间实体关联密集,GraphRAG收益明显。看问题类型:用户问题大多是“事实型查询”,比如“这个功能的参数是多少”,普通RAG就够;如果大量问题是“比较型”“全局型”“推理型”,考虑Agentic RAG和GraphRAG。看时延和成本预算:多步Agent每轮会调用多次LLM,GraphRAG的建库和查询开销也远高于向量检索,要评估你的业务是否扛得住。

我见过一个不错的折中方案:普通向量RAG作为主检索器,面向80%简单问题;GraphRAG作为“全局问答”的补充通道,只有检测到用户问题涉及多文档聚合时再启用;Agentic RAG作为最上层的路由和编排。这个层级结构不会让系统过于臃肿,又能覆盖大多数复杂场景。

6. 实操复盘:一套可复现的优化流程与排查清单

6.1 工具选型:Ollama、LangChain、LangChain4j与Spring AI怎么选

很多人问我用什么框架。我的回答是:框架不是重点,你的团队技术栈和部署环境才是。这里把常见选项梳理一遍,方便你选型。

如果只是想快速做本地验证,或者零基础想跑通一个可复制的RAG知识库,Ollama是个非常好的起点。它把llama3、qwen2.5这些模型打包成一条命令就能跑的本地服务,再配一个embedding模型如bge-m3或nomic-embed-text,加上一个轻量向量库如Qdrant,半天就能搭出一个“简易本地RAG知识库”原型。这个方案胜在无云依赖、数据不出本机,适合学习和小规模内网应用。

在Python生态里,LangChain是最主流的RAG框架,组件齐全,文档切分、混合检索、重排、Agent都有成熟的接口,社区资料也最多。如果你们是Java技术栈,LangChain4j是LangChain的Java移植版,专门适配了Spring Boot,写起来很顺手。Spring AI则是Spring官方出的AI框架,和Spring Boot的配置体系、AOP这些结合得最深。选哪个取决于团队熟,而不是哪个更“火”。

还有一个趋势是“把RAG做成服务”,有些平台开始提供RAG as Service的托管化能力,你只需要上传文档、调API。这类服务适合不想维护基础设施的团队,但要注意数据隐私和自定义能力的天花板。

工具选型的核心建议是:不要为了框架而框架。如果你的业务只是“给内部文档做问答”,LangChain和LangChain4j都能胜任;如果有复杂Agent流程,LangChain更灵活;如果是Java老项目,LangChain4j或Spring AI会让你少踩很多集成坑。

6.2 分步优化操作清单:从基线到可用的完整路径

下面是我惯用的一套优化流程,你可以直接照抄,在每一步做完后跑测评集记录指标。

第一步,搭一个最朴素的基线:文档解析、固定长度切分(chunk_size=500, overlap=50)、用通用embedding模型向量化、存进向量库、top5检索、把结果塞进最简单的“根据资料回答”Prompt。这通常就是很多团队所谓的“已完成”版本。先记录Hit Rate和主观答案质量作为对照。

第二步,处理切分和元数据。改成按文档结构切分,给每个chunk补充来源、章节、日期等metadata。如果文档切得太碎,上父子块方案。再次跑Hit Rate,这一步通常能把Hit Rate提升十个点左右。

第三步,加混合检索。引入BM25,与向量检索做RRF融合。重点测试精确编号类的查询,看看之前召回失败的问题是否命中。

第四步,加重排。用bge-reranker-v2-m3对召回top50重排后取top5,观察MRR是不是更好了。这一步能明显感觉到“检索结果更对症”。

第五步,优化Prompt和上下文组装。做上下文压缩,只保留相关句子,保留数字和专有名词。Prompt里加上引用来源、拒答指令、资料不足示例。

第六步,构造多轮对话的查询改写,处理指代问题。最后再用测评集完整跑一遍,对比最初的Hit Rate、忠实度、答案相关性。

为了让你有直观印象,我给一个LangChain里混合检索+重排的简化示意:

from langchain_community.retrievers import BM25Retriever from langchain_community.vectorstores import Qdrant from langchain.retrievers import EnsembleRetriever from langchain.retrievers.document_compressors import CrossEncoderReranker vectorstore = Qdrant.from_documents(docs, embedding=embedding_model) vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 50}) bm25_retriever = BM25Retriever.from_documents(docs, k=50) ensemble = EnsembleRetriever( retrievers=[vector_retriever, bm25_retriever], weights=[0.5, 0.5] ) reranker = CrossEncoderReranker(model_name="BAAI/bge-reranker-v2-m3", top_n=5) final_docs = reranker.compress_documents(ensemble.invoke(query), query=query)

这段代码描述的是“混合召回50个候选,再通过cross-encoder压缩到5个”的完整链路。真实项目里还要加metadata过滤、权限校验、上下文压缩和多轮改写,但骨架就是这样的。

6.3 常见问题与排查技巧实录

最后分享一份我长期在RAG项目里用的排查速查表。遇到准确度问题,先按表格对号入座,能省下很多瞎调参的时间。

症状可能原因排查方法与解决
模型总编造答案检索未命中或Prompt无拒答约束先看Hit Rate;加“资料不足时拒答”指令;要求引用来源
答非所问召回噪声大、top-k太靠后加大召回量后重排;加混合检索;检查embedding模型是否匹配领域
精确编号查不到只有向量检索引入BM25混合检索;确认切分没有把编号拆分
上下文过长/费用高chunk数量太多重排后截断;做句子级压缩;控制召回上限
跨文档问题答不出单文档chunk割裂先打关联标签;考虑GraphRAG/本体RAG
多轮追问失败query指代不明做查询改写;维护短期记忆;不要把全部历史塞进检索

这个表背后有一条我反复验证的经验:RAG准确度的问题,90%出在检索和上下文组织上,而不是模型能力上。你在优化时坚持“先看Hit Rate,再看MRR,最后看生成质量”的顺序,就不会被“换更强的大模型”这个诱惑带偏。换模型确实可能带来一点提升,但检索不到的材料,再强的模型也答不对。

最后再分享一个小技巧:把每次优化前的测评集和指标结果单独存档。不要改了参数又找不到原来跑出的基线数值。有基线才有对比,有对比才知道每一次改动是赚是亏。这套流程我一直在用,稳定可靠,至少能让你的RAG应用从“像有个玩具”变成“真能顶业务”。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 7:42:52

CompletableFuture 组合与异常处理:用 TaoToken 统一 Key 构建复杂异步流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 7:42:43

从Word设计文档到可运行Java代码的落地指南

简介:本资源是一份面向计算机专业本科生及Java初学者的毕业设计类文档,聚焦外卖点餐系统的完整设计与实现过程,解决传统餐饮信息化程度低、点餐流程不透明、管理效率低下等实际问题。文档以B/S架构为背景,系统梳理了需求分析、功能…

作者头像 李华