构建生产级 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 pypdfpdfplumberunstructured 保留表格、标题层级
Word python-docx 提取段落和列表
网页 BeautifulSoupcrawl4ai 去除导航、广告等噪音
数据库 转成 JSON/CSV 结构化数据需转为自然语言描述
python 复制代码
# 示例:加载多种文档
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 1

200-500 tokens
Chunk 2

200-500 tokens
...
重叠 10-20%

常见分块策略对比

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

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

python 复制代码
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

python 复制代码
# 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)

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

3.2 混合检索(Hybrid Search)

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

python 复制代码
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)重新打分,提升前几个结果的相关性。

python 复制代码
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选择性上下文 压缩不重要部分。
  • 滚动窗口:对于长对话或多轮检索,维护一个滑动窗口。
python 复制代码
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 提示模板应包含:检索到的上下文、用户问题、对话历史(可选)、明确指令。

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

【参考信息】
{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
对话历史存储

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

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 保存 sourceversion 元数据
  • 更新时先标记旧 chunk 为过期,再插入新 chunk,最后删除过期数据(双写策略)
  • 定期全量重建(如每周一次),修复累积的碎片问题

5.3 监控与告警

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

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

5.4 评估数据集的构建

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

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

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


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

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

python 复制代码
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
知识图谱

核心要点

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

相关推荐
Sammyyyyy1 小时前
月之暗面 Kimi Code 0.4.0 发布,终端 AI 编码助手全面采用 TypeScript,实现毫秒级启动
前端·javascript·人工智能·ai·typescript·servbay
IT小黄人_9991 小时前
Deepseek+dify本地化部署步骤
程序人生·ai
dozenyaoyida2 小时前
AI与大模型新闻日报 | 2026-06-12
人工智能·ai·大模型·新闻
Z-D-K2 小时前
考验AI的“自我和意识“-AI对《红楼梦》后40回的改写(21)
人工智能·ai·aigc·交互·agi
CIO_Alliance2 小时前
API激增时代,如何用iPaaS实现API全生命周期治理
人工智能·ai·ipaas·系统集成·企业ai化转型
装不满的克莱因瓶2 小时前
自然语言处理中的分词——从语言切分到模型输入的第一步
人工智能·pytorch·python·深度学习·ai·自然语言处理
算家云2 小时前
极速并行文本生成:谷歌开源 DiffusionGemma 扩散大模型
ai·google·大模型·算力
身如柳絮随风扬2 小时前
从零构建 Agent Skill:Cursor 与 Claude Code 完全集成指南
ai
qq_411262423 小时前
四博智联AI开发宝典(2/3):后端部署、OTA与AT+MCP接入
人工智能·ai·四博