Appearance
1.2.3 RAG 的完整工作流程是什么?
理解 RAG 的完整工作流程,一个很重要的切分方式是:把它分成离线阶段和在线阶段。
因为 RAG 不是用户提问之后才临时开始工作的。很多关键步骤,其实在用户提问之前就已经完成了。
一、离线阶段:准备知识
离线阶段的目标,是把原始资料变成“可被有效检索”的知识库。
这一阶段通常包括:
1. 收集数据
把文档、网页、FAQ、数据库内容、代码说明等资料收集起来,作为知识来源。
2. 清洗数据
去掉无关噪声,比如导航栏、页眉页脚、模板内容、重复片段、乱码和无意义文本。
3. 切块
把原始长文档拆成更适合检索的片段,也就是 Chunk。
4. 补充元数据
给每个片段补充来源、标题、章节、时间、权限范围、业务线等信息,方便后续过滤和排序。
5. 建立索引
把处理好的内容存入检索系统中,比如向量索引、关键词索引,或者两者结合。
到这里,系统才算完成了“把知识准备好”这一步。
二、在线阶段:回答问题
在线阶段的目标,是在用户真正提问时,基于现有知识库生成答案。
这一阶段通常包括:
1. 接收用户问题
系统拿到原始提问,先判断这是不是一个适合进入 RAG 链路的问题。
2. 查询理解
必要时会对问题做处理,比如:
- 改写问题
- 补充关键词
- 处理上下文
- 识别过滤条件
这一步的目的是让问题更适合检索。
3. 检索候选内容
系统根据处理后的问题,到知识库中找出最相关的若干内容。
4. 排序和筛选
检索结果往往不是最终可用结果,通常还会继续做:
- 重排
- 去重
- 过滤
- 合并
目的是把真正最有价值的内容尽量排到前面。
5. 上下文构造
把筛选后的内容组织成适合模型阅读的上下文。常见动作包括:
- 排序
- 拼接
- 压缩
- 截断
- 加引用标识
6. 生成回答
模型读取用户问题和上下文,生成最终答案。
7. 返回结果
系统把答案返回给用户。有些系统还会同时返回:
- 来源引用
- 相关文档链接
- 置信提示
三、完整链路可以怎么记
如果把整个过程压缩成一句话,可以记成:
先把知识准备好,再在用户提问时把正确知识找出来、组织好、交给模型回答。
或者更简洁一点:
数据准备 -> 建索引 -> 检索 -> 排序 -> 上下文构造 -> 生成
一个更完整的伪代码示意
如果把整条链路压缩成代码,大致会像这样:
python
# 离线阶段
raw_docs = load_documents()
clean_docs = clean_documents(raw_docs)
chunks = split_into_chunks(clean_docs)
indexed_chunks = add_metadata(chunks)
build_index(indexed_chunks)
# 在线阶段
def answer(query: str, user_id: str) -> str:
rewritten_query = rewrite_query_if_needed(query)
candidates = retrieve(rewritten_query, user_id=user_id)
filtered = filter_by_permission(candidates, user_id=user_id)
ranked = rerank(filtered, query=rewritten_query)
context = build_context(ranked[:5])
return generate(query=rewritten_query, context=context)这里最值得注意的是:真正的 RAG 不只是 retrieve -> generate 两步,中间通常还会插入很多决定稳定性的环节,比如清洗、切块、过滤、重排和上下文构造。
四、为什么一定要把流程拆开看
因为 RAG 的问题,往往不是“整个系统都不行”,而是某一环出了问题。
比如:
- 没召回到资料,问题可能在数据处理或检索
- 召回到了但答不好,问题可能在排序或上下文构造
- 资料没问题但还是乱答,问题可能在生成约束或 Prompt
只有先理解完整链路,后面你才更容易判断每个问题到底出在哪一层。