检索增强从零落地:检索增强系统的索引、召回与评测
一、RAG 不是向量库加聊天框
RAG 经常被简化成“文档切片、写入向量库、检索后塞给模型”。这个流程能做演示,但很难支撑生产。真实系统里,文档会更新,权限会变化,用户问题会含糊,召回结果会夹杂噪声,模型还可能把不相关片段拼成看似合理的答案。
RAG 的目标不是让模型“知道更多”,而是让答案有依据、可追溯、可评估。一个能落地的 RAG 系统至少包含五层:文档处理、索引构建、召回排序、上下文组装、答案评测。少任何一层,后期都会变成排障黑盒。
最常见的问题是召回质量差。用户问的是“退款审核超时怎么处理”,系统召回到“退款规则介绍”和“审核人员排班”,却漏掉“超时补偿流程”。模型只能基于错误材料回答。此时继续调 Prompt 没意义,应该先回到索引和召回层。
二、RAG 链路:答案质量由检索上限决定
flowchart LR A[原始文档] --> B[清洗与切片] B --> C[元数据标注] C --> D[向量索引] C --> E[关键词索引] F[用户问题] --> G[查询改写] G --> H[混合召回] D --> H E --> H H --> I[重排序] I --> J[上下文组装] J --> K[LLM 生成] K --> L[引用与评测]文档切片要保留结构。标题、章节、更新时间、权限范围、业务线都应该进入元数据。只保存纯文本,会让后续过滤和排序非常困难。切片大小也要结合内容类型。制度文档可以按章节切,FAQ 可以按问答对切,代码文档可以按函数或模块切。
召回建议使用混合策略。向量召回适合语义相近的问题,关键词召回适合专有名词、编号和接口名。两者结合后,再用重排序模型或规则排序。生产环境里,单纯向量召回很容易漏掉精确词。
三、实现要点:索引版本和引用链路
下面是一个文档切片结构。关键是把元数据放进索引,而不是只存正文。
type Chunk struct { ID string DocID string Title string Content string SectionPath []string Version string UpdatedAt time.Time Permission string } type SearchResult struct { ChunkID string Score float64 Content string Source string } func BuildPrompt(question string, results []SearchResult) string { var b strings.Builder b.WriteString("请只基于给定资料回答。资料不足时说明缺口。\n\n") b.WriteString("用户问题:") b.WriteString(question) b.WriteString("\n\n资料:\n") for i, r := range results { fmt.Fprintf(&b, "[%d] source=%s score=%.3f\n%s\n\n", i+1, r.Source, r.Score, r.Content) } b.WriteString("回答必须标注引用编号。") return b.String() }提示词里明确要求“资料不足时说明缺口”,是为了减少模型硬答。更重要的是,每段资料都带source。答案必须标注引用编号,否则无法审计。用户质疑答案时,系统要能回到具体文档和具体切片。
索引版本也不能忽略。文档更新后,旧索引可能仍在服务。如果没有版本号,线上答案会出现“明明文档改了,回答还是旧规则”的问题。建议每次构建索引都有版本,并在答案日志里记录使用的索引版本。
四、评测与边界:RAG 失败时不要只调模型
RAG 评测至少要分三层。第一是召回评测,看正确资料是否进入 top-k。第二是生成评测,看模型是否基于资料回答。第三是端到端评测,看答案是否解决用户问题。只看最终回答,会掩盖召回和生成的责任边界。
RAG 不适合处理强实时数据。比如库存、余额、订单状态,应优先调用实时接口,而不是依赖文档检索。RAG 也不适合处理权限复杂但没有元数据的资料。没有权限过滤,召回越准,泄露风险越高。
上下文长度不是越大越好。塞入过多片段会增加成本,也会引入噪声。更好的方式是提高召回和排序质量,让进入模型的上下文更干净。需要记住一句话:RAG 的上限通常由检索决定,下限由评测决定。
五、总结
RAG 落地的关键是检索、引用和评测。向量库只是其中一环。文档切片要保留结构和元数据,召回要结合语义与关键词,答案要带引用,日志要记录索引版本。
建议从小范围文档开始建设评测集。先让正确资料稳定进入 top-k,再优化生成效果。不要把所有问题都交给 Prompt。RAG 是检索系统和生成系统的组合,只有两端都可观测,答案才可控。