[[RAG]]这道题,其实是在问怎么给大模型配一个「外挂知识库」,让它在不重新训练的情况下也能回答私有数据的问题。核心思路就两条腿走路:离线把知识存成索引,在线把用户问题和索引匹配上,再让模型基于匹配结果回答。
先说离线阶段。原始文档五花八门,PDF、Word、网页,得先清洗成纯文本。然后最关键的一步是[[分块]],也就是 Chunk。这里有个坑:分太细,语义不完整,模型看不懂上下文;分太粗,超了上下文窗口,而且一个块里揉太多主题,检索时噪声大。我一般会看业务场景来定。比如客服退款政策,一个段落讲一个规则,那就按段落分;如果是技术文档,前后依赖强,我会用递归切分,保证块之间有重叠。分块策略没有银弹,得根据文档结构和下游任务调。分完块之后用 [[Embedding]] 模型转成向量,存到 [[Vector Database]] 里,像 Milvus 或者 PGVector。
在线阶段,用户来了一个 query,比如「七天无理由退货的运费谁出」。如果直接拿原始 query 去搜,可能搜不到,因为用户问法和文档表述不一样。所以我会先做一点查询改写,比如用 HyDE 先生成一个假设文档再去搜。然后做向量检索,用 [[HNSW]] 这类 [[ANN]] 算法快速召回 Top-K。这里有个边界问题:纯向量检索适合语义匹配,但对精确关键词比如订单号、错误码就抓瞎。所以真正落地我倾向 [[Hybrid Search]],向量加 [[BM25]] 两条路一起上,再合并排序。召回之后别急着喂给模型,先过一遍 [[Rerank]],用 [[Cross-Encoder]] 精排,把最相关的几条顶到前面。最后把检索结果和 query 拼成 prompt 给 LLM 生成答案。
关键组件我重点讲三个。Embedding 模型决定了语义理解的天花板,我一般选 BGE 或 GTE 这类开源模型,但要注意中文场景下需要领域微调,不然「退货」和「退款」的语义距离可能不对。向量数据库解决的是海量向量的快速检索,但建索引有代价,比如 HNSW 写起来慢,适合读多写少的场景,如果知识库频繁更新,得考虑增量索引或者双缓冲方案,不然索引重建太慢。Reranker 是精排,它能弥补 Embedding 召回的不准,但计算成本高,所以通常只对 Top-100 重排,不排全量。
落地中最头疼的其实是时效性问题。比如电商大促期间满减政策一天一变,离线索引跟不上。我见过一个失败案例:客服系统用 RAG,但政策更新后索引没刷新,模型还在回答旧政策,导致客诉。所以上线前我会特别关注知识更新的 pipeline,设一个强制刷新周期,或者用 [[Self-RAG]] 让模型自己判断检索内容是否过时,必要时拒绝回答。
最后说挑战。检索质量决定 RAG 的天花板,如果第一步就召不准,后面再好的模型也白搭。所以我会优先做检索评测,盯着 Recall@K 和 MRR,达标了再优化生成。另一个是[[幻觉]]问题,模型可能不看检索内容瞎编,我会在 prompt 里强制要求引用原文,甚至用 [[Faithfulness]] 指标做自动检测。我的核心取舍是:宁可不回答,也不要给错答案。 所以我会把 RAG 看成一套检索系统加上一个生成接口,重心放在检索和过滤上,而不是一味调 prompt。