我觉得这道题本质上是在问:怎么让大模型在不知道答案的时候,能自己去查资料,而不是瞎编。[[RAG]]就是干这个的,它不像微调那样改变模型参数,而是给模型外挂一个知识库,每次回答前先检索相关文档,再结合上下文生成答案。
具体流程分三步:先建索引,把文档切成小块转成向量存进[[向量数据库]];然后检索,把用户问题也转成向量,到库里找最相似的Top-K;最后生成,把检索到的文档和问题拼在一起扔给大模型。听起来简单,但每一步都有坑。
先说[[切片]]。很多人直接按固定字数切,比如512个token一段,但这样容易把一句话切成两半,导致检索时语义丢失。我倾向于按语义边界切,比如段落或句子,保证每个切片是完整的意思。当然,如果文档结构很乱,比如PDF表格,那还得用[[OCR]]加版面分析。
再说向量数据库。选型时我主要看召回延迟和精度。小项目用[[Faiss]]就够了,但数据量上千万、要求实时更新,就得用Milvus或者Pinecone。这里有个前提:如果业务场景是精确匹配,比如查订单号或错误码,那向量检索不如关键词搜索[[BM25]],所以生产上我一般搞[[混合检索]],向量和关键词两条路一起走,再用[[Rerank]]精排。
说到Rerank,这是提升质量的关键。向量检索是粗筛,召回几百条,但很多不相关,这时候用[[Cross-Encoder]]模型对候选结果逐条打分,只保留Top-5。代价是多了几十毫秒延迟,但效果提升明显,尤其对客服退款这种场景,用户问“我上个月买的衣服为什么还没发货”,如果检索出的政策文档不相关,模型就容易乱说。
接下来是架构演进。[[Naive RAG]]就是一条直路,问题来了直接检索,结果直接拼进去。但问题很多:检索质量差、上下文太长、模型容易被无关信息干扰。所以生产上我更多用Advanced RAG,多了几个环节:先对用户Query做改写,比如把“它”指代清楚;然后多路检索,向量、关键词、甚至[[Knowledge Graph]]一起上;检索完做上下文压缩,只保留最相关的几句,避免超出模型窗口。
举个例子,企业做合规文档问答,用户问“我们这种跨境业务适用哪个条款”,Naive RAG可能搜出一堆不相关的政策,而Advanced RAG会先识别“跨境”关键词,从知识图谱里找到对应的业务分类,再检索具体条款,最后用重排确保答案精准。
落地时我特别关注两个风险。一是检索精度,如果[[Embedding]]模型没在领域数据上微调过,语义会漂移,比如“苹果”可能匹配到水果而不是品牌。我的做法是用[[Dense Retrieval]]加领域微调,同时做查询扩展,把同义词也搜进去。二是[[幻觉]]控制,模型有时候不忠实于检索内容,自己编答案。我会在Prompt里明确要求它只基于检索内容回答,并且输出引用原文的片段,这样出了问题能追溯。
说到追溯,我最近在关注[[Self-RAG]]的思路,让模型自己判断什么时候需要检索、什么时候信任已有知识,而不是每次都检索。这样能减少不必要的检索开销,但需要额外训练一个判断模块。我觉得这个方向挺有意思,就是不知道在实时场景下延迟能不能接受。
所以整体上,我会把RAG看成一套系统工程,不是搭积木。索引、检索、生成每个环节都要根据业务数据特点做定制,特别是混合检索和重排,几乎是必选项。