完整题目
请描述RAG(Retrieval-Augmented Generation)系统的完整工作流程,并说明在构建向量检索库时,如何应对信息时效性问题(如时间衰减)以提升召回质量。
本文目录
RAG完整工作流程
1. 索引阶段(Offline)
- 文档切分:按语义/固定长度分块,控制chunk大小(通常256-512 tokens)
- Embedding编码:用BGE、E5等模型生成稠密向量
- 元数据存储:保留原始文本、时间戳、来源、类别等字段
- 向量入库:写入Milvus/Pinecone/ES,建立HNSW索引
2. 检索阶段(Online)
- Query改写:扩展同义词、澄清指代
- 向量检索:Top-K相似度召回
- 重排序(Rerank):Cross-Encoder精排,过滤低质结果
3. 生成阶段
- 上下文组装:按相关性排序,控制token预算
- LLM生成:结合检索内容作答
时效性优化方案
核心思路:让"新"文档在相似度计算中获得隐性加分
| 方案 | 实现方式 | 适用场景 |
|---|---|---|
| 时间衰减加权 | score_final = score_semantic × exp(-λ·Δt),λ控制衰减速率 | 新闻、社交媒体 |
| 动态时间窗口 | 优先检索近N天数据,无结果再扩展全库 | 金融公告、政策文件 |
| 时间感知Embedding | 训练时注入时间编码,或拼接时间特征向量 | 需要端到端优化 |
| 混合检索 | 时间范围过滤 + 语义检索,ES的range+knn组合查询 | 工程落地首选 |
工程实践要点:
- 时间戳作为元数据存储,检索时用于预过滤或后排序
- λ参数需业务调优:新闻类λ大(衰减快),百科类λ小
- 避免过度衰减导致"新但无关"内容压制"旧但精准"内容
学习建议
建议系统学习该知识点
换一种问法,检查是否真正理解
场景切入
假设你在做新闻推荐系统,用户搜“疫情最新政策”,库里既有昨天的文章也有去年的。你拿RAG去召回应优先返回哪个?怎么让系统自动给新内容加权,别老把旧东西翻出来?
层层追问
你平时用RAG做知识库问答,流程大概是怎样的?……那检索的时候,如果用户问的是实时信息,怎么保证召回的是最新的?……如果我想让时间越近的文档得分越高,具体在向量数据库里怎么实现?
直球架构
描述一下RAG的完整工作流程,从离线建库到在线检索生成。另外,针对信息时效性问题,你会怎么设计向量检索库,让新文档在召回时获得优势?
练习口述回答 · 约4分钟
- RAG本质是外挂知识库的查漏补缺
- 索引阶段:分块、向量化、存元数据
- 检索阶段:混合检索+重排
- 生成阶段:组装上下文、防幻觉
- 时效性:时间衰减加权+动态窗口
- 落地风险:衰减过度、新内容质量、元数据缺失
这道题其实是在问,怎么让大模型在回答时既能拿到外部知识,又能保证拿到的知识是最新的。[[RAG]] 的核心就是给 LLM 配一个可检索的外部知识库,而不是靠它自己的参数硬记。
我先说完整流程,分三个阶段。索引阶段,离线把文档切成块,chunk 大小我一般控制在 256 到 512 tokens,太短缺上下文,太长噪声多。然后拿 [[Embedding]] 模型转成向量,同时把时间戳、来源、类别这些元数据也存下来。最后写入 [[Vector Database]],比如 Milvus 或者 ES,建 [[HNSW]] 索引。这一步有个坑:[[分块]]策略要跟下游任务对齐。如果是客服退款场景,按段落切比固定长度好,因为一个退款流程的上下文往往跨好几个句子。
检索阶段,用户 query 进来,我先做改写,比如补全指代、扩展同义词。然后不是只做向量检索,我一般会加上关键词检索,也就是 [[Hybrid Search]],因为向量擅长语义但可能漏掉精确匹配,比如订单号。召回 top-K 之后再做一轮 [[Rerank]],用 [[Cross-Encoder]] 精排,把相关性低的过滤掉。这么做的前提是重排模型不能太慢,否则延迟扛不住。
生成阶段,把检索结果按相关性排序组装成上下文,控制 token 数,别超模型窗口。然后让 LLM 生成回答。这里有个常见失败场景:检索出的文档互相矛盾时,LLM 可能胡编,所以上线我会特别关注 [[Faithfulness]],比如加一层自检,让模型引用原文。
接下来重点说时效性。知识库里的内容有新旧,如果只按语义相似度取,旧的高质量文章可能永远压过新的,导致回答过时。比如商家满减政策变了,模型还按旧政策回答就会出错。
我的做法是时间衰减加权:最终得分 = 语义相似度 × exp(-λ × 时间差)。λ 控制衰减快慢,新闻类 λ 设大一点,让新内容快速出头;百科类 λ 设小,因为知识半衰期长。但有个风险:λ 调太大,新但质量差的内容会冲上来,压制旧但精准的结果。所以上线前我会用历史 query 回放,调 λ 让 Recall@K 最优。
另一个方案是动态时间窗口:先只搜最近 N 天的数据,如果召回不够再放宽。比如金融公告场景,财报发布后一周内只搜当季数据,没有结果再扩到全库。这样既保证时效,又不会完全丢掉长尾知识。
实际落地,我更倾向把时间衰减和混合检索结合起来。检索时先用时间范围过滤,比如只取最近一年,再在结果里做衰减加权。这样既快又稳。