当前位置: 首页 > news >正文

RAG 上下文组装:检索结果不是直接塞给大模型

现在,这些 chunk 终于被筛出来了,是不是直接拼进 Prompt,扔给 LLM 就完事了?

很多 RAG 系统,最后就是这么写的:

context = "\n\n".join([chunk.text for chunk in top_k]) answer = llm(prompt + context + question)

能跑,甚至 demo 看起来还挺像那么回事。

但到了真实业务里,这一步经常翻车。因为检索结果不是上下文,它只是上下文的原材料。

RAG 的最后一公里,不是“把材料塞进去”,而是“把材料组织成 LLM 能读懂、能引用、能判断轻重的证据包”。

一个典型 bad case

假设用户问:

“跨境订单退款,一般多久到账?”

Rerank 及其后续的一系列处理后拿到了最终 Top-5:

chunk1(0.91):退款申请通过后,系统将在 3-5 个工作日内原路退回…

chunk2(0.88):跨境订单因支付通道限制,退款到账时间可能延长至 7-15 个工作日…

chunk3(0.84):用户可在订单详情页发起售后申请,客服将在 24 小时内审核…

chunk4(0.81):特殊商品、虚拟商品、已拆封耗材不支持无理由退货…

chunk5(0.79):如退款超过预计时间,可联系人工客服查询银行处理状态…

看起来挺好,相关内容都找到了。

如果你直接按分数拼进去,LLM 很可能回答:

退款申请通过后,一般 3-5 个工作日到账;如果超过预计时间,可以联系客服。

这答案不能说完全错,但对用户这个问题来说就是错的。因为用户问的是“跨境订单”,真正关键的是 chunk2 里的7-15 个工作日

为什么会错?不是召回错了,也不是 rerank 错了。chunk2 明明就在里面。

问题出在上下文组装:系统没有告诉 LLM,chunk2 是“跨境订单”这个问题的主证据,chunk1 只是普通订单的默认规则。

chunk 不是证据,证据也不是上下文

这句话有点绕,但很重要。

chunk 是切出来的文本片段,它可能缺标题、缺上下文、缺适用范围。单独看一句“3-5 个工作日到账”,你不知道它说的是普通订单、跨境订单,还是某个支付渠道。

证据是能回答问题的信息单元。它不只包括正文,还要包括标题、来源、章节路径、适用条件、时间版本,有时候还要带上相邻段落。

上下文是给 LLM 使用的证据包。它要有顺序、有边界、有来源、有轻重,让模型知道哪些是主证据,哪些是补充,哪些只是背景。

所以 RAG 最后一段不应该叫“拼接”,更像是打包

你不是把一堆纸条扔到模型面前,而是在帮它整理案卷:主证据放前面,补充材料放后面,冲突点标出来,来源编号贴清楚。

第一步:把 chunk 还原成可读证据

很多 chunk 本身是残缺的。

比如知识库原文是这样:

售后规则 / 退款到账时间 / 跨境订单
由于跨境支付通道存在银行清算延迟,退款审核通过后,预计 7-15 个工作日到账。

但切 chunk 的时候,可能只留下了正文:

由于跨境支付通道存在银行清算延迟,退款审核通过后,预计 7-15 个工作日到账。

对人来说还勉强能猜,对 LLM 来说就少了几个关键线索:这是售后规则、说的是退款到账时间、适用对象是跨境订单

所以组装上下文时,第一件事是把结构信息补回来

来源:《售后规则》

章节:退款到账时间 / 跨境订单

适用范围:跨境订单

正文:由于跨境支付通道存在银行清算延迟,退款审核通过后,预计 7-15 个工作日到账。

这一步很像第一篇讲过的父子索引:检索可以用小 chunk,回答最好给模型更完整的父级语境

但注意,补上下文不是无限扩张。

相邻 chunk 可以扩一两个,父级标题可以带上,更新时间可以带上。不要把整篇文档都塞进来,那就又回到上一篇的超长上下文问题了。

第二步:按问题意图分组,而不是散装排列

真实问题往往不是只要一句话。

比如“跨境订单退款多久到账”,背后至少有三类信息:

主答案:跨境订单退款 7-15 个工作日到账

前置条件:退款申请需要先通过审核

异常处理:超过预计时间可以联系客服查询银行状态

如果你直接按 rerank 分数排列,这三类信息会混在一起。LLM 要自己判断谁是主答案,谁是补充说明,谁是例外条件。

它有时候能判断对,有时候不行。尤其当普通规则分数更高、跨境规则分数略低时,模型就容易把普通规则当成默认答案。

更稳的做法是:组装时先分组

直接答案组:和问题实体、条件完全匹配的证据

流程条件组:审核、申请、前置条件

异常补充组:超时、失败、人工处理

背景规则组:普通订单、通用售后规则

这样给到 LLM 的就不是一坨文本,而是一个有层次的材料包

第三步:顺序要服务答案,不是服务分数

Rerank 分数很重要,但它不是最终上下文顺序的唯一标准。

原因很简单:分数代表相关性,不代表表达顺序

一条“售后入口在哪里”的 chunk 可能分数很高,因为它包含“退款申请”这些词;但用户问的是多久到账,它就不应该压过“7-15 个工作日”这个核心证据。

我比较推荐的顺序是:

① 直接回答问题的主证据

② 适用条件和例外规则

③ 操作流程和补充解释

④ 来源、时间、低优先级背景

这和上一篇讲的 Lost in the Middle 也能接起来:最关键的证据尽量放在开头,必要时把第二关键证据放在结尾,不要把核心答案埋在中间。

简单说,rerank 负责“谁有资格进来”,上下文组装负责“进来之后坐哪儿”。

第四步:Token 预算要按价值分配

很多系统做上下文截断时,有个隐藏假设:每个 chunk 同等重要。

于是预算不够时,就按长度或者分数机械截断。

但在真实回答里,不同信息的价值完全不一样:

直接答案:必须保留

限制条件:尽量保留

操作流程:看问题需要

背景介绍:预算紧张时可以丢

所以更合理的做法是按组分配预算

比如一个 3000 token 的上下文窗口,可以大概这么切:

主证据:1500 token

限制和例外:600 token

流程补充:500 token

来源信息和引用编号:200 token

预留给问题和指令:200 token

这不是固定公式,但思路很重要:预算不是平均分,是按答案价值分

第五步:给每段材料贴上边界和来源

上下文里最怕的事情,是多段材料糊在一起。

LLM 看到一长串文本,不知道哪里是资料 1,哪里是资料 2,也不知道哪句话来自哪个文件。最后答案可能对,但引用乱了;或者引用对了,解释混了。

建议每段上下文都带一个稳定编号:

[资料1] 来源:售后规则 > 退款到账时间 > 跨境订单 适用范围:跨境订单 更新时间:2026-04-12 内容:由于跨境支付通道存在银行清算延迟,退款审核通过后,预计 7-15 个工作日到账。

[资料2] 来源:售后流程 > 退款申请 适用范围:所有订单 内容:用户提交退款申请后,客服将在 24 小时内完成审核。

这几个字段不只是给人看的,也是在给 LLM 递信号:

编号:方便引用和溯源

来源:方便判断可信度

适用范围:避免把普通规则套到特殊问题上

更新时间:遇到冲突时优先用新版本

这一步会直接影响后面的引用、溯源和答案校验。

一个推荐的组装流程

把前面几篇串起来,RAG 从 Rerank 后到送进 LLM,比较稳的流程是这样:

① 强过滤:低于阈值的候选先丢掉

② 去重:先净化候选池,避免重复内容占预算

③ 动态截断:根据分数差距和 Token 预算决定保留多少

④ 证据还原:补标题、章节、相邻段落、父级语境

⑤ 意图分组:主答案、限制条件、流程、异常、背景分开

⑥ 预算分配:关键证据优先,背景信息靠后

⑦ 位置优化:重要材料放头尾,缓解 Lost in the Middle

⑧ 编号封装:带 source id、metadata,再送进 Prompt

这里最容易被忽略的是第 ④ 到第 ⑧。

很多人以为 RAG 的难点在召回和排序,到了 Top-K 就结束了。实则不然,上下文组装也尤为重要

几个常见坑

第一个坑:只塞正文,不塞标题。

标题、章节路径、文档类型,很多时候比正文还关键。正文里写“7-15 个工作日”,标题里才写“跨境订单”。标题丢了,适用范围就丢了。

第二个坑:相邻扩展太贪。

看到一个命中 chunk,就把前后各 5 段都带上。结果主证据没增强多少,噪音先翻了几倍。相邻扩展要克制,优先扩标题、定义、前置条件,不要机械扩固定窗口。

第三个坑:metadata 越多越好。

不是。作者、文件路径、抓取任务 ID、入库批次,这些字段如果和回答无关,就别塞。metadata 也吃 token,而且会干扰模型。只带能影响回答的字段。

第四个坑:不标冲突。

如果旧文档说 3-5 天,新文档说 7-15 天,别假装它们没冲突。要么按更新时间取最新,要么在上下文里显式标出来,让 Prompt 要求模型优先使用新版本。

上下文组装的目标不是“信息最多”,而是“让模型最不容易误解”。

写在最后

走到这里,RAG 已经不再是“向量库 + 大模型”的简单组合了。

检索负责把候选证据捞出来,rerank 负责重新排序,去重和截断负责控制质量与数量,而上下文组装负责最后一件事:把这些候选证据变成 LLM 能稳定使用的材料包

很多 RAG 答案看起来“差一点”,不是因为模型不够强,也不是因为知识库没内容,而是因为证据进入模型时太散、太乱、缺少边界。

所以这一篇可以记住一句话:

检索只是拿到原料,上下文组装才是决定 LLM 实际能"吃"到什么

学AI大模型的正确顺序,千万不要搞错了

🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!

有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!

就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋

📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇

学习路线:

✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经

以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!

我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

http://www.jsqmd.com/news/1007571/

相关文章:

  • GDB 进程概念详解(上篇)—— 基础原理与单进程调试
  • 别再死记硬背公式了!用Python+Matlab仿真,带你直观理解SVPWM的电压矢量合成
  • 当AI编程助手突然罢工:Cursor试用限制的智能解决方案
  • 微服务文档协作困境:基于Cherry Markdown的企业级知识管理架构实践
  • Cursor Free VIP:破解AI编程助手限制的技术实现与深度应用指南
  • 从人脸识别到猫咪检测:手把手教你用OpenCV的预训练模型玩转计算机视觉
  • EdgeRemover深度解析:Windows系统中彻底移除Microsoft Edge的技术方案
  • GDB 进程概念详解(下篇)—— 多进程与进阶调试能力
  • Anthropic 2026 最新 Agent Harness 架构拆解:Managed Agents
  • PDF转PPT保留动画全攻略:3款免费微信工具实测+保姆级教程 - 时时资讯
  • 手把手教你用iPerf3和tc模拟长肥网络,诊断并解决TCP带宽跑不满的问题
  • 终极指南:如何用ZXing-C++库轻松实现多格式条码识别与生成
  • 从零搭建一个简易网络摄像头:手把手教你用Python+ONVIF+RTSP玩转视频流(附源码)
  • ARM9中断控制器AITC原理与MC9328MXL实战编程指南
  • 3步解决Cursor试用限制:实用技巧分享
  • 5分钟搭建专业级富文本编辑器:wangEditor v5完整教程
  • 终极指南:如何让你的惠普游戏本性能提升30%?OmenSuperHub免费解决方案
  • 深入Si24R1芯片:G01-S模块寄存器配置详解与Arduino驱动优化指南
  • 从芯片MPU寄存器到AUTOSAR内存分区:一次权限管理的“降维”解读
  • 你的Google验证码为什么30秒变一次?一文拆解TOTP算法核心与时钟同步的那些坑
  • 如何彻底掌控AMD处理器性能?开源调试工具SMUDebugTool终极指南
  • 3步搞定DevOps转型:OneDev如何让中小团队告别工具碎片化?
  • 3分钟快速解密音乐文件:Unlock Music浏览器工具终极指南
  • DBeaver驱动包终极解决方案:一键搞定30+数据库连接配置
  • 别再傻傻分不清!用示波器实测SDP/CDP/DCP,手把手教你读懂USB BC1.2握手信号
  • NXP MC56F81xxxL循环ADC:RSD架构、双核同步与PWM硬件联动详解
  • Blender建筑建模终极指南:building_tools完整使用教程
  • 商标交易避坑完全指南:10个最常见的骗局和错误,买商标前一定要看 - 速递信息
  • 别再只记结论了!通过5个PyTorch代码实验,亲手验证model.eval()与torch.no_grad()的真实影响
  • Android Studio中文语言包终极配置指南:3分钟打造母语开发环境