
这次我们来看一个已经从概念讨论阶段走到企业落地阶段的技术方向——RAG也就是检索增强生成。如果你关心大模型回答经常编造内容、知识更新滞后、内部文档无法直接接入模型这些问题RAG 是目前工程上最现实的解决方案之一。它不是要重新训练一个模型而是把“外部知识检索”和“大模型生成”拼成一条完整链路让模型在回答前先去查资料再基于资料给出答案。这篇文章会把 RAG 从零开始拆开先讲清楚它的工作原理再带你把环境、向量库、Embedding 模型、LLM 接口全部串起来最后落到一套可运行的 RAG 项目上。整体内容兼顾入门者和做企业落地的同学包含代码示例、功能验证、效果评估、常见问题和接口化部署。文章里所有代码都按通用项目结构给出命令和路径需要根据你本机的实际环境做替换。重点不是照着敲一遍就行而是理解每一层在做什么遇到问题知道去哪排查。1. RAG 核心能力速览在开始动环境之前先给 RAG 建立一张完整的能力图景。RAG 不是一个单独的模型而是一套系统组合不同层级决定它能做到什么程度。能力项说明解决的核心问题大模型幻觉、知识过时、私有知识无法即时注入系统组成文档解析层、文本切分层、Embedding 向量化层、向量检索层、Prompt 组装层、LLM 生成层是否需要训练模型不需要RAG 不微调模型参数只需选择 Embedding 模型和 LLM支持的知识类型PDF、Word、Markdown、HTML、TXT、表格、数据库记录等结构化与非结构化内容常用向量数据库Chroma、FAISS、Milvus、Qdrant、PGVector、Elasticsearch常用 LLM 接入方式OpenAI 兼容接口、本地部署模型接口、各类云厂商 API是否支持 CPU 环境支持但 Embedding 和 LLM 推理在 GPU 上性能更好是否支持批量任务支持文档导入、分块、向量化、检索测试都可以批量化是否提供 APIRAG 系统本身可通过 FastAPI、Flask 暴露检索与问答接口企业级框架Dify、FastGPT、RAGFlow、LlamaIndex、LangChain、Haystack 等从表的顺序可以看出RAG 是一个多模块组合工程。对入门者最友好的路径是先用开源框架跑通一套最小系统再逐步替换每一层组件。对企业落地则需要额外关注权限控制、知识库版本管理、监控评估和 API 接口规范。2. RAG 工作原理与完整流程拆解RAG 的完整流程可以概括为两条链路一条是知识库构建链路另一条是问答检索链路。两条链路互相独立但最终在检索环节汇合。2.1 知识库构建链路知识库构建链路是离线过程。它的目标是把你手头的原始资料转换成可检索的向量数据通常分四步第一文档加载。把 PDF、Word、Markdown 等不同格式的文件读入系统。这一步看起来简单实际最容易被低估。扫描版 PDF 需要 OCR文字版 PDF 还要处理页眉页脚、多栏排版、表格错位纯度不够的文本会直接影响后续切分和向量化效果。第二文本切分。把长文档切成固定长度或按语义边界的块。切分粒度直接决定检索质量块太大语义混杂检索结果不够精确块太小上下文断裂模型回答缺少足够背景。通用做法是先按标题结构切分再对超长段落做二次切分。第三向量化。通过 Embedding 模型将文本块转换成向量。Embedding 模型输出的向量维度从几百到几千不等不同模型适合不同语言场景中文场景需要优先考虑中文语料训练过的模型。第四写入向量数据库。向量数据库既存储原始文本也存储向量并建立索引。查询时通过相似度检索快速召回最相关的若干个文本块。2.2 问答检索链路问答检索链路是在线过程。当用户发起一个问题时系统执行如下步骤用户问题向量化。用与知识库构建时相同的 Embedding 模型把用户问题转成向量。相似度检索。在向量数据库中查询与问题向量最相似的 Top K 个文本块并返回原始文本。可选的重排序。对召回结果做一次粗排或精排去除与问题无关的噪声块。重排序可以用 Cross Encoder 模型也可以用简单的关键词重叠过滤。组装 Prompt。把用户问题与检索到的文本块拼成一个带上下文的 Prompt明确告诉模型“请根据以下资料回答如果资料中没有相关信息请直接说明不知道”。LLM 生成答案。大模型根据 Prompt 生成最终回复并把引用来源一并输出。链路越靠后对系统整体效果的影响越直接。检索质量差后面接什么模型都救不回来Prompt 设计差检索结果正确但答案还是答非所问。这也是为什么 RAG 项目调试时要一层一层排查而不是一上来就换模型。3. RAG 技术选型框架、Embedding 模型、向量库与 LLM零基础入门最容易卡住的问题是技术选型。这里给出一套“先用什么、后换什么”的思路避免一开始就陷入过多选项。3.1 RAG 框架选择框架适合人群特点LlamaIndex想自己掌控每一层细节的开发者数据连接和索引管理能力强灵活度高代码直观LangChain已经有多组件组合需求的团队生态丰富工具链多但版本迭代快学习成本偏高Dify产品经理、Java/Python 全栈快速交付团队可视化编排自带知识库、工作流、API 发布RAGFlow文档解析要求高的企业场景深度文档理解能力突出适合复杂非结构化文本FastGPT需要快速做内部知识库问答的团队可视化流程编排知识库管理友好适合中小团队从零基础角度看推荐顺序是先用 Dify 或 FastGPT 跑通“上传文档—知识库问答—API 调用”的完整体验再用 LlamaIndex 或 LangChain 手写一遍核心逻辑。前者让你建立信心后者让你真正理解原理。3.2 Embedding 模型选型Embedding 模型选型要看三个指标语言适配度、向量维度、模型体积。中文场景优先选择中文语料训练过的模型。开源可选项包括 BGE 系列、M3E 系列商用接口则有各家云厂商的 Embedding API。判断一个 Embedding 模型是否适合你的知识库最直接的方法是用一批真实问题去检索测试计算召回结果是否真正命中正确答案而不是只看某份排行榜分数。3.3 向量数据库选型向量数据库选型取决于数据量和部署环境。学习与原型验证Chroma、FAISS 足够安装简单单机可跑。生产环境小规模Qdrant 或 PGVector具备持久化能力部署可控。大规模企业级Milvus 或 Elasticsearch适合分布式场景支持复杂过滤和权限控制。3.4 LLM 选型RAG 里的 LLM 不限制必须使用某一家模型。只要模型支持通过 API 或本地服务调用且能正确处理较长的上下文 Prompt就能接入 RAG 系统。本地部署场景需要准备足够的 GPU 资源没有 GPU 时可以考虑使用云厂商的模型接口。无论选择哪种方式都要把“模型输出是否忠实于检索资料”作为重要评估指标而不是只看回答是否流畅。4. 环境准备与前置条件RAG 项目对环境的要求相对宽松但需要按功能模块拆开看。4.1 操作系统与基础依赖推荐使用 Linux 或 macOS 进行开发部署Windows 也支持但遇到路径与依赖问题时需要额外处理。需要预装以下基础环境Python 3.9 及以上版本pip 或 conda 包管理器Git网络访问能力用于下载 Python 包和模型文件查看本机基础环境python --version pip --version git --version4.2 CPU 与 GPU纯 CPU 环境可以运行 RAG 全流程但大规模向量化和 LLM 推理会明显变慢。适合学习测试和文本量小的场景。GPU 环境推荐至少具备 6G 以上显存可以较流畅地运行本地 Embedding 模型和中型 LLM。更大参数量的 LLM 需要更大显存或量化方案。具体显存占用取决于模型规模和推理参数这里不写死数字。实际测试时建议用nvidia-smi命令实时观察。4.3 磁盘空间原始文档、切分后的文本、向量索引、Embedding 模型、LLM 模型都需要占用磁盘。建议预留 20G 以上的可用空间。如果使用本地 LLM模型文件往往占据大部分空间需要按模型实际大小评估。4.4 安装 Python 依赖示例RAG 项目要装的包较多建议创建虚拟环境避免污染全局环境# 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Windows 使用 venv\Scripts\activate # 安装基础依赖 pip install openai python-dotenv chromadb sentence-transformers pypdf langchain如果安装速度慢可以临时换成国内 pip 镜像源pip install -i https://pypi.tuna.tsinghua.edu.cn/simple openai python-dotenv chromadb sentence-transformers pypdf langchain5. 手把手搭建一套完整 RAG 项目这一节直接进入实战。下面的代码是通用实现思路使用 LangChain 生态与 Chroma 向量数据库组合适合学习原理和二次改造。项目结构如下rag-demo/ ├── data/ # 存放原始文档 ├── embed/ # 存放 Embedding 模型缓存 ├── index_db/ # 存放向量数据库文件 ├── rag.py # 主脚本知识库构建 问答 ├── requirements.txt └── .env # 存放 API Key 等敏感配置5.1 读取环境变量在.env中配置模型 API 信息。如果你使用本地模型服务URL 改为本地服务地址如果使用云厂商模型填入对应密钥。# .env 示例实际值需要按你的模型服务填写 LLM_API_KEYyour-api-key LLM_BASE_URLhttps://api.example.com/v1 LLM_MODELgpt-4o-mini EMBED_MODELBAAI/bge-small-zh-v1.5这里不指定具体模型厂商只说明通用配置结构。5.2 文档加载与切分文档加载的核心目标是得到干净的纯文本。不同文件格式需要不同加载器下面以 PDF 和纯文本为例# load_docs.py from pathlib import Path from langchain_community.document_loaders import PyPDFLoader, TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter def load_documents(data_dir: str): docs [] data_path Path(data_dir) for file_path in data_path.glob(*.pdf): loader PyPDFLoader(str(file_path)) docs.extend(loader.load()) for file_path in data_path.glob(*.txt): loader TextLoader(str(file_path), encodingutf-8) docs.extend(loader.load()) return docs def split_documents(docs, chunk_size500, chunk_overlap50): splitter RecursiveCharacterTextSplitter( chunk_sizechunk_size, chunk_overlapchunk_overlap, separators[\n\n, \n, 。, , , , ], ) return splitter.split_documents(docs) if __name__ __main__: raw_docs load_documents(./data) chunks split_documents(raw_docs) print(f原始文档数量: {len(raw_docs)}) print(f切分后文本块数量: {len(chunks)})切分参数chunk_size500和chunk_overlap50是一个通用起点实际要根据文档类型调整。疑问句密集的 FAQ 类文档可以分小块长段落说明文可以分大块。5.3 向量化与写入向量数据库用 Embedding 模型把文本块向量化并写入 Chroma# build_vector_store.py from langchain_huggingface import HuggingFaceEmbeddings from langchain_chroma import Chroma from load_docs import load_documents, split_documents # 使用本地 HuggingFace Embedding 模型 embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, cache_folder./embed, ) # 也可以使用 OpenAI 兼容的 Embedding 接口 # from langchain_openai import OpenAIEmbeddings # embedding_model OpenAIEmbeddings(modeltext-embedding-3-small) docs load_documents(./data) chunks split_documents(docs) vector_store Chroma.from_documents( documentschunks, embeddingembedding_model, persist_directory./index_db, ) print(f向量库构建完成共 {vector_store._collection.count()} 条向量记录)构建完成后index_db目录下会生成向量索引文件。后续问答阶段直接复用这个目录不需要重新切分文档。5.4 检索问答主流程这一步是把检索结果和 LLM 生成串联起来# rag.py import os from dotenv import load_dotenv from langchain_chroma import Chroma from langchain_huggingface import HuggingFaceEmbeddings from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_core.output_parsers import StrOutputParser from langchain_core.runnables import RunnablePassthrough load_dotenv() embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, cache_folder./embed, ) vector_store Chroma( embedding_functionembedding_model, persist_directory./index_db, ) retriever vector_store.as_retriever( search_typesimilarity, search_kwargs{k: 4}, ) llm ChatOpenAI( api_keyos.getenv(LLM_API_KEY), base_urlos.getenv(LLM_BASE_URL), modelos.getenv(LLM_MODEL), temperature0.1, ) PROMPT_TEMPLATE 你是一个企业内部知识助手。请严格根据以下资料回答问题。 如果资料中没有相关信息请直接回答“根据现有资料无法回答”不要编造内容。 资料内容 {context} 用户问题 {question} 回答时先给出结论再简要说明依据。 prompt ChatPromptTemplate.from_template(PROMPT_TEMPLATE) def format_docs(docs): return \n\n.join(doc.page_content for doc in docs) rag_chain ( { context: retriever | format_docs, question: RunnablePassthrough(), } | prompt | llm | StrOutputParser() ) if __name__ __main__: question 请根据知识库介绍什么是 RAG answer rag_chain.invoke(question) print(问题:, question) print(回答:, answer)这个rag_chain的语义可以这样理解先把用户问题交给检索器检索器返回 Top 4 文本块格式化后作为context原始问题作为question两者拼成 Prompt 后交给 LLM最终输出答案文本。temperature0.1是相对较低的采样温度目的是减少发散性回答让模型更贴近资料内容。5.5 运行验证在项目根目录执行python rag.py预期输出是问题: 请根据知识库介绍什么是 RAG 回答: 根据资料RAG 是检索增强生成它通过外部检索为大模型提供相关知识...判断成功的标准有三条回答内容确实来自知识库而不是模型凭记忆编造。当问题超出知识库范围时模型会明确说“根据现有资料无法回答”。检索到的文本块能对应到原始文档的具体位置。如果回答仍然像漫谈优先检查 Prompt 中是否强调了“仅根据资料回答”以及检索器返回的文本块是否真正相关。6. 提升检索质量从能用走向好用最小系统跑通之后下一步是优化检索质量。这一步经常决定 RAG 项目能否走向生产环境。6.1 重排序单纯依赖向量相似度召回容易混入语义相近但实际不相关的文本块。重排序是用一个额外的相关性模型对召回结果重新打分把更相关的块排到最前。常用的实现是使用 Cross Encoder 模型进行粗排。# rerank_example.py from sentence_transformers import CrossEncoder # 加载重排序模型 rerank_model CrossEncoder(BAAI/bge-reranker-base) # 假设 query 是用户问题passages 是检索阶段召回的文本列表 query 什么是 RAG passages [ RAG 是检索增强生成结合检索模块与大模型生成。, 向量数据库用于存储文本向量。, 大模型容易出现幻觉问题。, ] # 逐个计算相关性分数 scores rerank_model.predict([(query, passage) for passage in passages]) ranked sorted(zip(passages, scores), keylambda x: x[1], reverseTrue) for passage, score in ranked: print(score, passage)重排序并不适合所有场景。当知识库切片数量少、召回质量已经很高时额外增加重排序模型会拖慢响应速度。典型做法是先用粗召回 Top 20再用重排序精排取 Top 4。6.2 混合检索向量检索擅长语义匹配但有时会忽略关键词完全一致的精确匹配比如型号编码、订单号、法律条款编号。混合检索同时使用关键词匹配与向量检索再对结果做融合排序。Elasticsearch 天然支持 BM25 关键词检索与向量检索的混合查询。使用 PostgreSQL 的场景则可以用全文检索加上 pgvector 的向量检索组合实现。6.3 查询改写用户问题往往包含口语表达、指代不明的词或隐含意图。查询改写模块在进入检索之前先让 LLM 把问题改写为更利于检索的形式。例如“它的价格是多少”改写为“产品价格是多少”。这个模块会增加一次 LLM 调用适合复杂问题场景简单知识库可以直接跳过。6.4 元数据过滤企业知识库通常包含部门、时间、文档类型等属性。在检索时只对满足条件的数据子集进行向量搜索可以大幅提升准确性。Chroma、Milvus、Qdrant 都支持在查询时附加过滤条件。7. RAG 效果评估知识库指标与调优方向没有评估体系RAG 项目就停留在“感觉回答还行”的层面。要把它做成可持续优化系统必须定义可量化的指标。7.1 核心指标指标回答的问题计算思路召回率应该被找回的相关文本是否都被找回正确答案对应的文本块是否出现在检索结果中准确率检索结果中真正相关的比例检索结果中相关文本块数除以总找回的文本块数忠实度模型回答是否完全基于资料回答中的关键事实能否在检索资料中找到依据相关性回答是否解决用户问题人工打分或 LLM 评估回答与问题的相关性幻觉率回答中出现资料没有的信息的比例逐条判断回答中的新事实是否超出资料范围7.2 评估数据集建设要给出一套可靠的评估结果至少需要准备 50 到 100 条测试问题。问题类型包括直接抽取型答案在文档某个固定位置。多文档综合型需要把多个文档的信息合并。无答案型知识库中完全没有相关信息理想回答是拒绝回答。时序变化型不同版本的文档对同一问题有不同答案需要明确回答依据的版本。每条测试问题需要标注正确答案、关联文本块、可接受回答的判定标准。评估集建设完成后每次修改切分策略、Embedding 模型或 Prompt 模板都要重新跑一遍测试集对比指标变化。7.3 调优方向如果检索召回率低优先调整切分策略和 Embedding 模型如果准确率低优先增加重排序和元数据过滤如果忠实度低优先调整 Prompt 模板和降低 LLM 采样温度如果相关性低优先优化问题改写和回复长度控制。调优顺序建议是切分策略 Embedding 模型 检索方式 重排序 Prompt 模板 LLM 参数。过早调 LLM 参数往往是在掩盖检索层的问题。8. 企业级 RAG 落地可视化框架与 API 接口如果你已经理解了核心逻辑下一步可以借助企业级框架提高交付效率。可视化 RAG 框架的核心价值在于将文档解析、文本切分、向量检索、Prompt 编排、模型调用这些步骤以可视化方式配置并提供现成的 API 接口。8.1 Dify 与企业框架部署思路使用 Dify 或 FastGPT 部署时典型路径如下通过 Docker Compose 启动框架服务。在管理后台创建知识库应用。上传文档选择切分策略与 Embedding 模型。配置 LLM 模型提供商。在调试页面测试问答效果。发布为 API 应用获取 API 密钥和调用地址。这类框架适合快速验证和交付演示项目但底层细节被封装遇到复杂检索问题时排查难度会增加。建议在业务初期使用框架提高效率在业务稳定后逐步沉淀内部知识库构建规范。8.2 API 接口化改造通过 FastAPI 将 RAG 问答能力封装为 HTTP 接口是常见的工程做法# api_server.py from fastapi import FastAPI, HTTPException from pydantic import BaseModel import rag app FastAPI() class QueryRequest(BaseModel): question: str top_k: int 4 class QueryResponse(BaseModel): question: str answer: str sources: list[str] app.post(/api/rag/query, response_modelQueryResponse) def query_rag(request: QueryRequest): if not request.question.strip(): raise HTTPException(status_code400, detail问题不能为空) answer rag.rag_chain.invoke(request.question) # 实际项目中还需要返回检索到的来源文本块 sources [] return QueryResponse( questionrequest.question, answeranswer, sourcessources, ) if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)启动 API 服务python api_server.py验证接口curl -X POST http://127.0.0.1:8000/api/rag/query \ -H Content-Type: application/json \ -d {question: 请根据知识库介绍什么是 RAG}调用示例import requests url http://127.0.0.1:8000/api/rag/query payload {question: 请根据知识库介绍什么是 RAG, top_k: 4} response requests.post(url, jsonpayload, timeout120) print(response.json())接口访问范围要严格控制。生产环境不应将 RAG 服务直接暴露在公网需要通过内部网络或网关代理访问并做请求频率限制和身份认证。8.3 批量任务设计企业级 RAG 中文档更新是高频场景。批量任务通常包含以下队列文件上传与格式检测。文档解析与文本清洗。切分策略执行。向量化与写库。索引更新与旧数据清理。批量任务建议使用消息队列管理任务状态需要可追踪。每次全量重刷知识库之前可以先跑小批数据集验证向量化效果再逐步扩大到全量。9. 资源占用与性能观察RAG 系统的性能瓶颈通常在三个位置文档解析、向量化、LLM 推理。9.1 观察显存与内存模型加载后用以下命令实时监控 GPU 状态nvidia-smi -l 2如果是 CPU 环境可以用top或htop监控内存与 CPU 占用。需要注意加载本地 Embedding 模型与 LLM 模型后即使没有任何请求显存也会被占用。多个服务共享 GPU 时要预留足够空闲显存。9.2 影响推理速度的关键参数文本块数量切分粒度越细向量库条数越多检索速度会下降。Embedding 模型大小大模型语义能力更强但推理更慢批量向量化也更耗时。LLM 上下文长度加入的检索文本块越多Prompt 越长生成速度越慢。批量数批量向量化能充分利用 GPU 并行能力但过大的批处理会导致显存溢出。9.3 降低资源占用的方法使用 Embedding 模型时添加normalize_embeddingsTrue参数减少向量计算开销。本地 LLM 使用量化版本例如 4bit、8bit 量化可以明显降低显存占用。检索结果控制在 3 到 5 个文本块避免无意义的上下文膨胀。批量任务安排在低峰时段执行避免与在线问答服务争抢资源。10. 常见问题与排查方法下表整理了 RAG 项目从零搭建到企业落地最常见的故障以及对应的排查思路问题现象可能原因排查方式解决方案安装依赖时报错Python 版本不匹配或依赖包冲突检查 Python 版本与 pip 日志使用虚拟环境按 requirements 重新安装加载 PDF 乱码PDF 为扫描件或编码异常用 PDF 阅读器打开确认接入 OCR 模块或使用带深度文档解析能力的框架向量库构建极慢Embedding 模型过大或 CPU 推理查看 CPU/GPU 占用换用更小模型或使用 GPU 批处理检索结果与问题无关切分粒度不合适或 Embedding 模型不适配打印检索到的原始文本块调整 chunk_size或替换 Embedding 模型回答包含编造内容Prompt 未限制“仅根据资料”或检索块混入不相关内容检查 Prompt 是否明确约束增强忠实度约束增加重排序LLM 调用超时网络问题或模型服务负载过高查看服务端日志和网络连接增大 timeout或切换模型服务节点API 接口返回 500参数格式不正确或中间环节异常查看应用错误日志使用 Pydantic 校验请求参数给接口添加异常捕获批量任务卡住单条文档解析卡死或依赖服务不可用查询任务队列状态增加任务超时与重试机制分批处理知识库更新后回答仍是旧知识旧向量未清理或索引未刷新检查向量数据库记录数更新时先按文档 ID 删除旧记录再写入新纪录11. 最佳实践与合规使用建议RAG 项目的工程化程度决定了它能走多远。下面的实践建议来自大量真实落地项目的共性经验值得在项目初期就纳入设计。第一知识库原始文档与向量索引要分开管理。原始文档保留在独立目录或对象存储中向量索引可以随时重建。不要把索引库当作唯一数据源。第二每个文本块保留完整元数据。包括来源文件名、页码、更新时间、所属部门、权限级别。元数据是后续做权限过滤、数据追溯、效果分析的基础。第三建立最小可运行配置模板。固定一套参数组合例如 chunk_size500、chunk_overlap50、top_k4、temperature0.1作为每次调优的基准线。每次调参只改一个变量方便对比效果。第四批量任务必须加日志和失败重试。建议记录每个文件的解析耗时、向量化耗时、错误信息。单个文件失败时不影响整个批次任务结束后统一输出失败报告。第五接口服务必须限制访问范围。RAG API 可能涉及企业内部敏感资料生产环境不要暴露公网访问。内部访问也需要鉴权设置请求频率限制防止内部接口被滥用。第六涉及人脸、声音、版权素材以及个人隐私信息时必须确认数据来源合法并获得使用授权。RAG 知识库经常包含合同、简历、客户信息等敏感数据部署时需要考虑数据脱敏和访问审计。第七发布输出前进行人工抽查。RAG 的忠实度不是百分之百保证的。即使检索和 Prompt 都做得很规范模型仍可能在边界问题上产生不准确的表述。重要场景必须有人工复核。第八知识库有更新时要触发对应文档的增量索引。建议设计一个简单的版本管理机制让用户可以在回答中看到答案依据的知识版本时间避免新旧资料混用导致回答前后矛盾。12. 总结与下一步建议RAG 是目前大模型应用落地最容易见效、也最容易验证效果的技术路线。它不需要训练模型不要求团队具备模型微调能力只要有一份知识库和一个可调用的 LLM 服务就能在几天内搭建出可演示的问答系统。核心难点从“能不能跑通”转移到“检索质量是否能持续保持”这意味着项目后期的重心在数据治理、评估体系和监控告警而不是模型本身。最先建议验证的功能是你的知识库切分与检索效果。在你自己的文档上测试远比使用公开示例更有说服力。第一次跑通时固定小批量文档打印检索环节返回的原始文本块肉眼判断是否相关再做后续优化。最容易踩的坑是跳过检索质量评估直接调 LLM。回答不满意时先问一个问题检索到的文本块是否包含正确答案如果不包含问题在切分、向量化或检索策略和 LLM 没有关系。后续可以继续扩展的方向包括多轮对话中的指代消解、多知识库路由与权限过滤、表格与图片的多模态检索、文档更新的增量索引机制、基于 LLM 自动评估 RAG 效果的回归测试集。等这些模块逐步补齐你的 RAG 项目就会从“能回答问题的 demo”变成“能长期运行的企业应用”。这篇文章建议收藏备用。动手搭一套最小 RAG 系统再慢慢往里加组件效果会比你直接套用大型框架要好得多。