我觉得这道题其实就是在问一个核心问题:当大模型知识跟不上业务变化时,怎么低成本给它配个外脑。[[RAG]]就是这套方案,它不像微调那样要动模型参数,而是把外部知识塞进上下文里,让模型基于检索结果回答。所以它的架构可以拆成三个环节:先把知识存好,再从里面捞相关片段,最后让模型读着这些片段生成答案。我先说索引。离线阶段最容易被忽视的一个细节是[[切块]]。很多人上来就用固定长度切,比如256个token一刀切,但业务文档往往有自然段落,比如客服退款政策里,「退货条件」和「退款时长」写在不同段落,一刀切会把逻辑打断。我一般会优先用语义切分,按标题和段落边界来切,如果文档结构不清晰,再用[[滑动窗口]]加重叠,保证每个chunk上下文完整。切完之后用 [[Embedding]] 模型转成向量,存到 [[Vector Database]] 里。这里有个前提:如果你的知识库是纯关键词匹配场景,比如查订单号或错误码,向量检索反而不好使,因为短文本语义不丰富,这时候 [[BM25]] 的精确匹配更靠谱。所以真正落地,我倾向于 [[Hybrid Search]],把稀疏和稠密两条路结合起来。然后说检索。在线阶段用户来了一个query,直接去向量库搜往往不够。比如用户问「退货怎么退」,但库里文档标题是「退款流程」,语义有偏差。所以我会先做一遍 Query改写,用大模型把问题扩写成更完整的表达,或者生成几个假设文档去检索。检索出来Top-K之后,不能直接塞给生成器,因为向量检索的排序不一定是语义最相关的。我会加一层 [[Rerank]],用 [[Cross-Encoder]] 对候选文档和query做精细打分,把不相关的滤掉。这个环节成本高,但收益也大,我一般只对Top-30做重排,保留前5个。重排之后还要按token预算动态截断,比如模型上下文只有4K,我就只拿能塞进去的最相关文档。最后是生成。检索结果怎么喂给模型,直接影响回答质量。我会在 [[System Prompt]] 里明确说:请基于以下资料回答,如果资料里没有,就回答不知道。同时把检索文档按相关性降序排列,用明确的格式标出每段来源。这里有个常见失败场景:如果检索结果质量差,模型会强行用内部知识补,导致 [[Hallucination]]。所以我上线时会特别关注Rerank分数,设一个阈值,低于阈值的直接触发「知识不足」回复,而不是硬答。再一个优化点是多轮对话,上一轮已经查过的内容,下一轮没必要重复检索,可以维护一个检索历史缓存,新的query先和历史做融合,减少延迟。整体来看,检索质量决定了RAG的上限。所以我会把更多精力放在检索侧的Query改写和Rerank上,生成侧反而相对成熟,调好Prompt和温度就行。还有一个延伸方向是让模型自己判断检索质量,比如 [[Self-RAG]] 或者 [[Corrective RAG]],模型不仅能基于检索结果生成,还能主动说「这部分资料不够,我需要再查一下」。这个方向其实把RAG从被动喂料变成了主动思考,挺有意思的。