欢迎光临
我们一直在努力

构建生产级 RAG 系统:从索引到检索增强的全链路实践

构建生产级 RAG 系统:从索引到检索增强的全链路实践(附代码与架构图)

很多教程只教你“三步搭建 RAG”,但生产环境需要处理文档更新、检索延迟、上下文窗口限制、LLM 幻觉等一系列工程问题。本文从零开始,系统讲解如何构建并维护一个高可用、高性能的 RAG 系统,并实现精准的上下文检索与 LLM 联动。


1. RAG 系统全景架构

一个完整的生产级 RAG 系统包含离线和在线两条链路,以及评估与反馈闭环。

#mermaid-svg-ODtBSpulUkvaHDXQ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ODtBSpulUkvaHDXQ .error-icon{fill:#552222;}#mermaid-svg-ODtBSpulUkvaHDXQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ODtBSpulUkvaHDXQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ODtBSpulUkvaHDXQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ODtBSpulUkvaHDXQ .marker.cross{stroke:#333333;}#mermaid-svg-ODtBSpulUkvaHDXQ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ODtBSpulUkvaHDXQ p{margin:0;}#mermaid-svg-ODtBSpulUkvaHDXQ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster-label text{fill:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster-label span{color:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster-label span p{background-color:transparent;}#mermaid-svg-ODtBSpulUkvaHDXQ .label text,#mermaid-svg-ODtBSpulUkvaHDXQ span{fill:#333;color:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ .node rect,#mermaid-svg-ODtBSpulUkvaHDXQ .node circle,#mermaid-svg-ODtBSpulUkvaHDXQ .node ellipse,#mermaid-svg-ODtBSpulUkvaHDXQ .node polygon,#mermaid-svg-ODtBSpulUkvaHDXQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ODtBSpulUkvaHDXQ .rough-node .label text,#mermaid-svg-ODtBSpulUkvaHDXQ .node .label text,#mermaid-svg-ODtBSpulUkvaHDXQ .image-shape .label,#mermaid-svg-ODtBSpulUkvaHDXQ .icon-shape .label{text-anchor:middle;}#mermaid-svg-ODtBSpulUkvaHDXQ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ODtBSpulUkvaHDXQ .rough-node .label,#mermaid-svg-ODtBSpulUkvaHDXQ .node .label,#mermaid-svg-ODtBSpulUkvaHDXQ .image-shape .label,#mermaid-svg-ODtBSpulUkvaHDXQ .icon-shape .label{text-align:center;}#mermaid-svg-ODtBSpulUkvaHDXQ .node.clickable{cursor:pointer;}#mermaid-svg-ODtBSpulUkvaHDXQ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ODtBSpulUkvaHDXQ .arrowheadPath{fill:#333333;}#mermaid-svg-ODtBSpulUkvaHDXQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ODtBSpulUkvaHDXQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ODtBSpulUkvaHDXQ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ODtBSpulUkvaHDXQ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ODtBSpulUkvaHDXQ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ODtBSpulUkvaHDXQ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster text{fill:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ .cluster span{color:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ODtBSpulUkvaHDXQ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ODtBSpulUkvaHDXQ rect.text{fill:none;stroke-width:0;}#mermaid-svg-ODtBSpulUkvaHDXQ .icon-shape,#mermaid-svg-ODtBSpulUkvaHDXQ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ODtBSpulUkvaHDXQ .icon-shape p,#mermaid-svg-ODtBSpulUkvaHDXQ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ODtBSpulUkvaHDXQ .icon-shape .label rect,#mermaid-svg-ODtBSpulUkvaHDXQ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ODtBSpulUkvaHDXQ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ODtBSpulUkvaHDXQ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ODtBSpulUkvaHDXQ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

评估与维护

在线查询

离线索引

多源文档PDF/Word/网页/数据库

文档解析与清洗

智能分块Chunking

Embedding 模型

向量数据库

索引管理增量/全量更新

用户问题

查询预处理/改写/扩写

检索模块混合检索+重排序

上下文组装+对话记忆

LLM 生成

答案

用户反馈/标注

离线评估命中率/准确率

参数调优

🔔 核心思想:离线把文档变成可检索的向量索引;在线把用户问题转成向量去检索,再把检索到的文本块与问题一起交给 LLM 生成答案;同时通过反馈不断优化分块、检索和生成策略。


2. 构建索引:数据准备与分块策略

2.1 文档加载与清洗

不同来源的数据需要不同解析器:

数据源工具/方法注意事项
PDF pypdf、pdfplumber、unstructured 保留表格、标题层级
Word python-docx 提取段落和列表
网页 BeautifulSoup、crawl4ai 去除导航、广告等噪音
数据库 转成 JSON/CSV 结构化数据需转为自然语言描述

# 示例:加载多种文档
from langchain.document_loaders import PyPDFLoader, TextLoader, UnstructuredHTMLLoader

loaders = {
".pdf": PyPDFLoader,
".txt": TextLoader,
".html": UnstructuredHTMLLoader,
}
docs = []
for file in file_list:
ext = os.path.splitext(file)[1]
loader = loaders[ext](file)
docs.extend(loader.load())

2.2 智能分块(Chunking)

分块大小和重叠策略直接影响检索召回率与生成效果。

#mermaid-svg-j21J5UcJOo9GzD7g{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-j21J5UcJOo9GzD7g .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-j21J5UcJOo9GzD7g .error-icon{fill:#552222;}#mermaid-svg-j21J5UcJOo9GzD7g .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-j21J5UcJOo9GzD7g .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-j21J5UcJOo9GzD7g .marker{fill:#333333;stroke:#333333;}#mermaid-svg-j21J5UcJOo9GzD7g .marker.cross{stroke:#333333;}#mermaid-svg-j21J5UcJOo9GzD7g svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-j21J5UcJOo9GzD7g p{margin:0;}#mermaid-svg-j21J5UcJOo9GzD7g .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-j21J5UcJOo9GzD7g .cluster-label text{fill:#333;}#mermaid-svg-j21J5UcJOo9GzD7g .cluster-label span{color:#333;}#mermaid-svg-j21J5UcJOo9GzD7g .cluster-label span p{background-color:transparent;}#mermaid-svg-j21J5UcJOo9GzD7g .label text,#mermaid-svg-j21J5UcJOo9GzD7g span{fill:#333;color:#333;}#mermaid-svg-j21J5UcJOo9GzD7g .node rect,#mermaid-svg-j21J5UcJOo9GzD7g .node circle,#mermaid-svg-j21J5UcJOo9GzD7g .node ellipse,#mermaid-svg-j21J5UcJOo9GzD7g .node polygon,#mermaid-svg-j21J5UcJOo9GzD7g .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-j21J5UcJOo9GzD7g .rough-node .label text,#mermaid-svg-j21J5UcJOo9GzD7g .node .label text,#mermaid-svg-j21J5UcJOo9GzD7g .image-shape .label,#mermaid-svg-j21J5UcJOo9GzD7g .icon-shape .label{text-anchor:middle;}#mermaid-svg-j21J5UcJOo9GzD7g .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-j21J5UcJOo9GzD7g .rough-node .label,#mermaid-svg-j21J5UcJOo9GzD7g .node .label,#mermaid-svg-j21J5UcJOo9GzD7g .image-shape .label,#mermaid-svg-j21J5UcJOo9GzD7g .icon-shape .label{text-align:center;}#mermaid-svg-j21J5UcJOo9GzD7g .node.clickable{cursor:pointer;}#mermaid-svg-j21J5UcJOo9GzD7g .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-j21J5UcJOo9GzD7g .arrowheadPath{fill:#333333;}#mermaid-svg-j21J5UcJOo9GzD7g .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-j21J5UcJOo9GzD7g .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-j21J5UcJOo9GzD7g .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j21J5UcJOo9GzD7g .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-j21J5UcJOo9GzD7g .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j21J5UcJOo9GzD7g .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-j21J5UcJOo9GzD7g .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-j21J5UcJOo9GzD7g .cluster text{fill:#333;}#mermaid-svg-j21J5UcJOo9GzD7g .cluster span{color:#333;}#mermaid-svg-j21J5UcJOo9GzD7g div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-j21J5UcJOo9GzD7g .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-j21J5UcJOo9GzD7g rect.text{fill:none;stroke-width:0;}#mermaid-svg-j21J5UcJOo9GzD7g .icon-shape,#mermaid-svg-j21J5UcJOo9GzD7g .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-j21J5UcJOo9GzD7g .icon-shape p,#mermaid-svg-j21J5UcJOo9GzD7g .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-j21J5UcJOo9GzD7g .icon-shape .label rect,#mermaid-svg-j21J5UcJOo9GzD7g .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-j21J5UcJOo9GzD7g .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-j21J5UcJOo9GzD7g .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-j21J5UcJOo9GzD7g :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

原始文档

按语义边界切分

Chunk 1200-500 tokens

Chunk 2200-500 tokens

重叠 10-20%

常见分块策略对比:

策略实现方式优点缺点
固定长度 按 token 数切分 简单 切断句子/段落
递归字符 按段落→句子递归 保留语义完整性 需调参
语义分块 计算句子嵌入,相似度突变处切分 智能 计算开销大
文档结构 按 Markdown 标题/HTML 标签 保留层次 依赖文档格式

推荐实践:使用 RecursiveCharacterTextSplitter 作为起点,chunk_size=400-500, chunk_overlap=50,然后根据检索效果调整。

from langchain.text_splitter import RecursiveCharacterTextSplitter

splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\\n\\n", "\\n", "。", "!", "?", ";", " ", ""],
keep_separator=False,
)
chunks = splitter.split_documents(docs)

2.3 Embedding 模型选型

模型维度中文支持速度最佳场景
text-embedding-ada-002 1536 通用(需付费)
bge-large-zh-v1.5 1024 优秀 中文专业领域
bge-m3 1024 多语言 高精度需求
gte-large 1024 长文档
jina-embeddings-v2 768 多语言

选型建议:

  • 偏通用且成本不敏感 → OpenAI Ada
  • 中文本地部署 → BGE 系列
  • 需要跨语言检索 → BGE-M3 或 Jina

2.4 向量数据库选型

数据库类型索引类型特点适用规模
Chroma 嵌入式 HNSW 轻量,零配置 原型/小规模
FAISS IVF/HNSW 纯内存,极快 科研/高性能
Qdrant 服务端 HNSW 云原生,过滤强 生产 >10w 向量
Milvus 分布式 IVF/HNSW 百亿级,高可用 企业级
Pinecone 托管服务 专有 免运维 快速上线

小规模(<10万向量) :Chroma / FAISS
生产大规模:Qdrant / Milvus / Weaviate

# Chroma 本地持久化
from langchain.vectorstores import Chroma

vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./db",
collection_name="my_knowledge",
)
vectorstore.persist()


3. 检索优化:如何让 LLM 拿到真正有用的上下文?

检索质量直接决定生成效果。生产系统通常不只做简单的向量搜索。

3.1 查询预处理(Query Transformation)

用户原始问题可能太短、口语化或隐含歧义。常见技术:

#mermaid-svg-GAqx9s4D2Aq26q69{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-GAqx9s4D2Aq26q69 .error-icon{fill:#552222;}#mermaid-svg-GAqx9s4D2Aq26q69 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-GAqx9s4D2Aq26q69 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-GAqx9s4D2Aq26q69 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-GAqx9s4D2Aq26q69 .marker.cross{stroke:#333333;}#mermaid-svg-GAqx9s4D2Aq26q69 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-GAqx9s4D2Aq26q69 p{margin:0;}#mermaid-svg-GAqx9s4D2Aq26q69 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster-label text{fill:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster-label span{color:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster-label span p{background-color:transparent;}#mermaid-svg-GAqx9s4D2Aq26q69 .label text,#mermaid-svg-GAqx9s4D2Aq26q69 span{fill:#333;color:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 .node rect,#mermaid-svg-GAqx9s4D2Aq26q69 .node circle,#mermaid-svg-GAqx9s4D2Aq26q69 .node ellipse,#mermaid-svg-GAqx9s4D2Aq26q69 .node polygon,#mermaid-svg-GAqx9s4D2Aq26q69 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-GAqx9s4D2Aq26q69 .rough-node .label text,#mermaid-svg-GAqx9s4D2Aq26q69 .node .label text,#mermaid-svg-GAqx9s4D2Aq26q69 .image-shape .label,#mermaid-svg-GAqx9s4D2Aq26q69 .icon-shape .label{text-anchor:middle;}#mermaid-svg-GAqx9s4D2Aq26q69 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-GAqx9s4D2Aq26q69 .rough-node .label,#mermaid-svg-GAqx9s4D2Aq26q69 .node .label,#mermaid-svg-GAqx9s4D2Aq26q69 .image-shape .label,#mermaid-svg-GAqx9s4D2Aq26q69 .icon-shape .label{text-align:center;}#mermaid-svg-GAqx9s4D2Aq26q69 .node.clickable{cursor:pointer;}#mermaid-svg-GAqx9s4D2Aq26q69 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-GAqx9s4D2Aq26q69 .arrowheadPath{fill:#333333;}#mermaid-svg-GAqx9s4D2Aq26q69 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-GAqx9s4D2Aq26q69 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-GAqx9s4D2Aq26q69 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GAqx9s4D2Aq26q69 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-GAqx9s4D2Aq26q69 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GAqx9s4D2Aq26q69 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster text{fill:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 .cluster span{color:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-GAqx9s4D2Aq26q69 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-GAqx9s4D2Aq26q69 rect.text{fill:none;stroke-width:0;}#mermaid-svg-GAqx9s4D2Aq26q69 .icon-shape,#mermaid-svg-GAqx9s4D2Aq26q69 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-GAqx9s4D2Aq26q69 .icon-shape p,#mermaid-svg-GAqx9s4D2Aq26q69 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-GAqx9s4D2Aq26q69 .icon-shape .label rect,#mermaid-svg-GAqx9s4D2Aq26q69 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-GAqx9s4D2Aq26q69 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-GAqx9s4D2Aq26q69 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-GAqx9s4D2Aq26q69 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

用户问题

是否为多轮对话?

问题改写加入历史上下文

问题复杂?

问题分解多子查询

查询扩写生成同义查询

Search

代码示例:问题改写(使用 LLM)

def rewrite_question(original, history):
prompt = f"""根据对话历史,将当前问题改写成独立、完整的问题。
历史:
{history}
当前问题:
{original}
改写后:"""

return llm.invoke(prompt)

3.2 混合检索(Hybrid Search)

向量检索擅长语义匹配,但可能遗漏精确关键词(如产品型号“GPT-4o”)。混合检索 = 向量检索 + 关键词检索,然后融合结果。

from langchain.retrievers import BM25Retriever, EnsembleRetriever

# 关键词检索器
bm25_retriever = BM25Retriever.from_documents(chunks)
bm25_retriever.k = 5

# 向量检索器
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 加权融合
ensemble_retriever = EnsembleRetriever(
retrievers=[bm25_retriever, vector_retriever],
weights=[0.3, 0.7],
)

3.3 重排序(Re-ranking)

向量检索返回 top-k 后,用一个更精细的交叉编码器(Cross-Encoder)重新打分,提升前几个结果的相关性。

from sentence_transformers import CrossEncoder

cross_encoder = CrossEncoder("BAAI/bge-reranker-v2-m3")

def rerank(query, docs, top_n=3):
pairs = [[query, doc.page_content] for doc in docs]
scores = cross_encoder.predict(pairs)
sorted_docs = sorted(zip(docs, scores), key=lambda x: x[1], reverse=True)
return [doc for doc, _ in sorted_docs[:top_n]]

效果:在 MTEB 基准测试中,加入 rerank 可将 Recall@3 提升 10~20%。

3.4 上下文窗口管理

LLM 的上下文窗口有限(如 8k、16k、128k),但检索出的相关文本块可能超过窗口。你需要:

  • 截断:按相关度排序后,只取最相关的若干块,确保总 token 数不超过窗口(留出 prompt 和生成空间)。
  • 压缩:使用 LLMLingua 或 选择性上下文 压缩不重要部分。
  • 滚动窗口:对于长对话或多轮检索,维护一个滑动窗口。

def truncate_context(docs, max_tokens=3000):
total = 0
selected = []
for doc in docs:
tokens = num_tokens_from_string(doc.page_content)
if total + tokens > max_tokens:
break
selected.append(doc)
total += tokens
return selected


4. LLM 联动:构建高质量生成流程

4.1 提示词模板设计

一个好的 RAG 提示模板应包含:检索到的上下文、用户问题、对话历史(可选)、明确指令。

你是一个智能助手,请基于【参考信息】回答用户的问题。
如果参考信息不足以回答问题,请直接说“根据已知信息无法回答”,不要编造。

【参考信息】
{context}

【对话历史】
{chat_history}

【问题】
{question}

【回答】

4.2 对话记忆与多轮检索

在多轮对话中,需要将历史问答也纳入检索,避免丢失上下文。常见方案:

#mermaid-svg-XHjtAB4cztlnLWJE{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XHjtAB4cztlnLWJE .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XHjtAB4cztlnLWJE .error-icon{fill:#552222;}#mermaid-svg-XHjtAB4cztlnLWJE .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XHjtAB4cztlnLWJE .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XHjtAB4cztlnLWJE .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XHjtAB4cztlnLWJE .marker.cross{stroke:#333333;}#mermaid-svg-XHjtAB4cztlnLWJE svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XHjtAB4cztlnLWJE p{margin:0;}#mermaid-svg-XHjtAB4cztlnLWJE .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-XHjtAB4cztlnLWJE .cluster-label text{fill:#333;}#mermaid-svg-XHjtAB4cztlnLWJE .cluster-label span{color:#333;}#mermaid-svg-XHjtAB4cztlnLWJE .cluster-label span p{background-color:transparent;}#mermaid-svg-XHjtAB4cztlnLWJE .label text,#mermaid-svg-XHjtAB4cztlnLWJE span{fill:#333;color:#333;}#mermaid-svg-XHjtAB4cztlnLWJE .node rect,#mermaid-svg-XHjtAB4cztlnLWJE .node circle,#mermaid-svg-XHjtAB4cztlnLWJE .node ellipse,#mermaid-svg-XHjtAB4cztlnLWJE .node polygon,#mermaid-svg-XHjtAB4cztlnLWJE .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XHjtAB4cztlnLWJE .rough-node .label text,#mermaid-svg-XHjtAB4cztlnLWJE .node .label text,#mermaid-svg-XHjtAB4cztlnLWJE .image-shape .label,#mermaid-svg-XHjtAB4cztlnLWJE .icon-shape .label{text-anchor:middle;}#mermaid-svg-XHjtAB4cztlnLWJE .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XHjtAB4cztlnLWJE .rough-node .label,#mermaid-svg-XHjtAB4cztlnLWJE .node .label,#mermaid-svg-XHjtAB4cztlnLWJE .image-shape .label,#mermaid-svg-XHjtAB4cztlnLWJE .icon-shape .label{text-align:center;}#mermaid-svg-XHjtAB4cztlnLWJE .node.clickable{cursor:pointer;}#mermaid-svg-XHjtAB4cztlnLWJE .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XHjtAB4cztlnLWJE .arrowheadPath{fill:#333333;}#mermaid-svg-XHjtAB4cztlnLWJE .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XHjtAB4cztlnLWJE .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XHjtAB4cztlnLWJE .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XHjtAB4cztlnLWJE .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XHjtAB4cztlnLWJE .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XHjtAB4cztlnLWJE .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XHjtAB4cztlnLWJE .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XHjtAB4cztlnLWJE .cluster text{fill:#333;}#mermaid-svg-XHjtAB4cztlnLWJE .cluster span{color:#333;}#mermaid-svg-XHjtAB4cztlnLWJE div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XHjtAB4cztlnLWJE .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XHjtAB4cztlnLWJE rect.text{fill:none;stroke-width:0;}#mermaid-svg-XHjtAB4cztlnLWJE .icon-shape,#mermaid-svg-XHjtAB4cztlnLWJE .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XHjtAB4cztlnLWJE .icon-shape p,#mermaid-svg-XHjtAB4cztlnLWJE .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XHjtAB4cztlnLWJE .icon-shape .label rect,#mermaid-svg-XHjtAB4cztlnLWJE .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XHjtAB4cztlnLWJE .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XHjtAB4cztlnLWJE .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XHjtAB4cztlnLWJE :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

当前用户问题

结合历史重写问题

检索

组装当前+历史上下文

LLM

对话历史存储

存储结构:使用 ConversationBufferMemory 或 VectorStoreRetrieverMemory(把历史消息也向量化,自动召回相关历史)。

4.3 降低幻觉的工程技巧

技巧实现方式
来源引用 要求 LLM 在答案后标注引用自哪个 chunk
拒绝回答 如果检索到的相似度低于阈值,强制让 LLM 拒绝
两阶段验证 先生成答案,再用一个较小的 LLM 判断答案是否与检索内容一致
约束生成 使用 guidance/outlines 控制输出格式,强制引用

5. RAG 系统维护:监控、评估与持续优化

5.1 评估指标

维度指标说明
检索 Hit Rate@k、MRR 正确 chunk 是否出现在 top-k
检索 NDCG@k 排序质量
生成 ROUGE-L、BLEU 与参考答案的重叠度
生成 幻觉率(Hallucination) 人工或用 NLI 模型判断
端到端 答案相关性、忠实度 使用 LLM-as-Judge

5.2 持续更新索引

文档会过期、新增。你需要支持增量更新和全量重建策略。

#mermaid-svg-0k30PhM0HhAliP6O{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0k30PhM0HhAliP6O .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0k30PhM0HhAliP6O .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0k30PhM0HhAliP6O .error-icon{fill:#552222;}#mermaid-svg-0k30PhM0HhAliP6O .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0k30PhM0HhAliP6O .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0k30PhM0HhAliP6O .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0k30PhM0HhAliP6O .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0k30PhM0HhAliP6O .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0k30PhM0HhAliP6O .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0k30PhM0HhAliP6O .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0k30PhM0HhAliP6O .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0k30PhM0HhAliP6O .marker.cross{stroke:#333333;}#mermaid-svg-0k30PhM0HhAliP6O svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0k30PhM0HhAliP6O p{margin:0;}#mermaid-svg-0k30PhM0HhAliP6O .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0k30PhM0HhAliP6O .cluster-label text{fill:#333;}#mermaid-svg-0k30PhM0HhAliP6O .cluster-label span{color:#333;}#mermaid-svg-0k30PhM0HhAliP6O .cluster-label span p{background-color:transparent;}#mermaid-svg-0k30PhM0HhAliP6O .label text,#mermaid-svg-0k30PhM0HhAliP6O span{fill:#333;color:#333;}#mermaid-svg-0k30PhM0HhAliP6O .node rect,#mermaid-svg-0k30PhM0HhAliP6O .node circle,#mermaid-svg-0k30PhM0HhAliP6O .node ellipse,#mermaid-svg-0k30PhM0HhAliP6O .node polygon,#mermaid-svg-0k30PhM0HhAliP6O .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0k30PhM0HhAliP6O .rough-node .label text,#mermaid-svg-0k30PhM0HhAliP6O .node .label text,#mermaid-svg-0k30PhM0HhAliP6O .image-shape .label,#mermaid-svg-0k30PhM0HhAliP6O .icon-shape .label{text-anchor:middle;}#mermaid-svg-0k30PhM0HhAliP6O .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0k30PhM0HhAliP6O .rough-node .label,#mermaid-svg-0k30PhM0HhAliP6O .node .label,#mermaid-svg-0k30PhM0HhAliP6O .image-shape .label,#mermaid-svg-0k30PhM0HhAliP6O .icon-shape .label{text-align:center;}#mermaid-svg-0k30PhM0HhAliP6O .node.clickable{cursor:pointer;}#mermaid-svg-0k30PhM0HhAliP6O .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0k30PhM0HhAliP6O .arrowheadPath{fill:#333333;}#mermaid-svg-0k30PhM0HhAliP6O .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0k30PhM0HhAliP6O .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0k30PhM0HhAliP6O .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0k30PhM0HhAliP6O .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0k30PhM0HhAliP6O .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0k30PhM0HhAliP6O .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0k30PhM0HhAliP6O .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0k30PhM0HhAliP6O .cluster text{fill:#333;}#mermaid-svg-0k30PhM0HhAliP6O .cluster span{color:#333;}#mermaid-svg-0k30PhM0HhAliP6O div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0k30PhM0HhAliP6O .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0k30PhM0HhAliP6O rect.text{fill:none;stroke-width:0;}#mermaid-svg-0k30PhM0HhAliP6O .icon-shape,#mermaid-svg-0k30PhM0HhAliP6O .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0k30PhM0HhAliP6O .icon-shape p,#mermaid-svg-0k30PhM0HhAliP6O .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0k30PhM0HhAliP6O .icon-shape .label rect,#mermaid-svg-0k30PhM0HhAliP6O .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0k30PhM0HhAliP6O .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0k30PhM0HhAliP6O .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0k30PhM0HhAliP6O :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

文档变更事件

新增文档

修改文档

删除文档

解析+分块

Embedding

向量库 UPSERT

解析+分块

Embedding

向量库 DELETE

实现注意:

  • 为每个 chunk 保存 source 和 version 元数据
  • 更新时先标记旧 chunk 为过期,再插入新 chunk,最后删除过期数据(双写策略)
  • 定期全量重建(如每周一次),修复累积的碎片问题

5.3 监控与告警

生产 RAG 系统必须监控的核心指标:

  • 检索延迟:P50、P99
  • 召回空率:没有检索到任何文档的请求占比
  • 低相似度率:max_similarity < 0.7 的比例
  • LLM 生成时间
  • 用户负反馈率

5.4 评估数据集的构建

建议从真实用户日志中抽取 200~500 条问题,人工标注:

  • 预期召回的文档 ID
  • 标准答案

每次调整分块策略、检索参数、LLM 模型后,都在这套测试集上跑离线评估。


6. 完整实战代码:从索引到聊天机器人

以下使用 LangChain + Chroma + OpenAI 构建一个带对话记忆的 RAG 问答系统。

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationalRetrievalChain
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

# 1. 加载已有向量库
embeddings = OpenAIEmbeddings()
vectorstore = Chroma(persist_directory="./db", embedding_function=embeddings)

# 2. 基础检索器
base_retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 6}
)

# 3. 可选:添加上下文压缩(用 LLM 提取最相关片段)
compressor = LLMChainExtractor.from_llm(ChatOpenAI(temperature=0))
retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=base_retriever
)

# 4. 对话记忆
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)

# 5. 构建对话检索链
qa_chain = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(model="gpt-3.5-turbo", temperature=0),
retriever=retriever,
memory=memory,
verbose=True,
)

# 6. 交互
while True:
query = input("你:")
if query.lower() in ["exit", "quit"]:
break
result = qa_chain({"question": query})
print("AI:", result["answer"])


7. 高级进阶话题

  • 多模态 RAG:表格、图片、图表如何嵌入?使用 Unstructured 提取表格 Markdown,或用 GPT-4V 生成图片描述。
  • Agentic RAG:让 LLM 决定何时检索、检索什么、是否调用工具(如 SQL 查询、API)。
  • 自我反思 RAG:生成后主动检查缺失信息,触发二次检索(Self-RAG, Corrective RAG)。
  • 知识图谱 + RAG:对实体关系建立图索引,解决多跳推理问题。

8. 总结与脑图

#mermaid-svg-e2OGEcFNsBSEfoVK{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-e2OGEcFNsBSEfoVK .error-icon{fill:#552222;}#mermaid-svg-e2OGEcFNsBSEfoVK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-e2OGEcFNsBSEfoVK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-e2OGEcFNsBSEfoVK .marker.cross{stroke:#333333;}#mermaid-svg-e2OGEcFNsBSEfoVK svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-e2OGEcFNsBSEfoVK p{margin:0;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge{stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 text{fill:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth–1{stroke-width:17;}#mermaid-svg-e2OGEcFNsBSEfoVK .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-0{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-0{stroke-width:14;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-1{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-1{stroke-width:11;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 text{fill:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-2{stroke-width:8;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-3{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-3{stroke-width:5;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-4{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-4{stroke-width:2;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-5{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-5{stroke-width:-1;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-6{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-6{stroke-width:-4;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-7{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-7{stroke-width:-7;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-8{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-8{stroke-width:-10;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-9{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-9{stroke-width:-13;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 polygon,#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 text{fill:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .node-icon-10{font-size:40px;color:black;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .edge-depth-10{stroke-width:-16;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled circle,#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:lightgray;}#mermaid-svg-e2OGEcFNsBSEfoVK .disabled text{fill:#efefef;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-root rect,#mermaid-svg-e2OGEcFNsBSEfoVK .section-root path,#mermaid-svg-e2OGEcFNsBSEfoVK .section-root circle,#mermaid-svg-e2OGEcFNsBSEfoVK .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-e2OGEcFNsBSEfoVK .section-root text{fill:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-root span{color:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .section-2 span{color:#ffffff;}#mermaid-svg-e2OGEcFNsBSEfoVK .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-e2OGEcFNsBSEfoVK .edge{fill:none;}#mermaid-svg-e2OGEcFNsBSEfoVK .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-e2OGEcFNsBSEfoVK :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

构建与维护RAG系统

索引构建

文档解析

分块策略

Embedding选型

向量数据库

检索优化

查询改写

混合检索

重排序

上下文截断

LLM联动

提示词模板

对话记忆

防幻觉

运维

离线评估

增量更新

监控告警

测试集

高级

多模态

Agentic RAG

知识图谱

核心要点:

  • 离线索引质量决定上限——分块、embedding 模型、向量库选型要针对数据特点做实验。
  • 在线检索需要组合拳——查询改写 + 混合检索 + 重排序,缺一不可。
  • LLM 生成依赖上下文管理——窗口截断、对话记忆、防幻觉指令。
  • 评估驱动迭代——没有评估就没有优化方向,建立测试集和监控体系。

  • 赞(0)
    未经允许不得转载:171主机测评 » 构建生产级 RAG 系统:从索引到检索增强的全链路实践
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址