这道题其实是在问,怎么让大模型不靠训练数据里的记忆,而是实时从外部知识库里查东西来回答问题。说白了,就是给模型配一个外挂知识库。整体流程分两步走,先离线建索引,再在线跑检索加生成。
先说离线索引。原始文档不能直接喂给模型,得先[[切块]]。切多大?我一般控制在256到512个token,太小上下文不够,太大噪声多。然后用 [[Embedding]] 模型转成稠密向量,存到 [[Vector Database]] 里,常用 [[Faiss]] 或 Milvus,建 [[HNSW]] 索引加速搜索。这里有个坑:chunk之间的重叠怎么处理?我会把零重叠、短窗口与较长窗口放进同一组实验,根据边界证据完整率、召回与成本选择。
再在线流程。用户来了一个 query,先检索。我基本不会只用向量相似度,因为纯语义检索对专有名词、ID号这些不敏感,所以会做 [[Hybrid Search]],向量检索加 [[BM25]] 关键词检索并行,结果合并后再用 [[Cross-Encoder]] 做一次 [[Rerank]],把真正相关的文档排到前面。这一步很关键,能过滤掉很多语义相似但实际无关的噪声。举个例子,客服场景里用户问“我退款怎么还没到”,向量检索可能召回一堆退款政策文档,但真正需要的是该笔订单的处理状态,这时候 Rerank 能把带订单号的文档顶上来。
然后生成。把召回的结果拼成 prompt,格式大概是“基于以下资料回答问题:文档1...文档K。问题:xxx。答案:”。这里有个前提,就是 prompt 模板要设计好,明确告诉模型只能基于资料回答,不然模型容易自由发挥,产生 [[Hallucination]]。而且我会要求模型输出引用标记,比如 [1][2],方便事后溯源。
再说说落地时我特别关注的几个风险。先看噪声敏感:如果检索到的文档里混了不相关的内容,模型会被带偏。所以我会在 Rerank 阶段设一个置信度阈值,低于0.3的直接丢掉,宁可少给也别给错的。再看时效性问题:知识库如果一天一更新,用户问“今天有什么优惠”,模型还是拿昨天的政策回答。所以对于高频变化的数据,比如库存、价格,我会用 [[Agent]] 配合 [[Function Calling]] 实时查数据库,而不是走静态索引。还要看查询改写成本:用户 query 经常很短或者有歧义,比如“怎么退”,需要先让模型扩写成“退货流程是什么”,但这会多一次 LLM 调用,延迟和成本都要考虑。
其实 [[Naive RAG]] 和 Advanced [[RAG]] 的核心区别不在于索引,而在于检索策略。比如 [[Self-RAG]] 让模型自己判断是否需要检索、检索结果是否够用,不够就迭代检索多次。这个方向我觉得比单纯优化 Embedding 模型更有价值,因为它解决了“什么时候该查、查几次”这个根本问题。
所以整体上,我更倾向把 RAG 看作一个检索优先的系统,生成器只是把检索结果包装成自然语言。如果检索质量不够好,再强的生成器也救不了。上线前我会用 [[RAGAS]] 指标专门测检索的 [[Context Precision]] 和 [[Context Recall]],确保召回的东西既精准又全面。