公司动态

RAG从原理到实战:Embedding、向量检索与LangChain知识库搭建

📅 2026/8/26 13:14:13
RAG从原理到实战:Embedding、向量检索与LangChain知识库搭建
大家做 AI 应用落地时经常被“RAG”“Embedding”“向量检索”这一串概念绕晕。网上的资料大多是孤立地讲某个点要么只讲 Embedding 原理要么只贴一段 LangChain 代码很少有人把“文档加载 → 切片 → Embedding → 向量存储 → 检索 → 重排 → 大模型生成”这条完整链路讲清楚。这篇教程会从原理到实战把 RAG 的完整业务流程拆开揉碎讲明白新手能顺着思路建立整体认知有基础的开发者可以直接拿到一套可运行的最小工程。我们首先会解释 RAG 到底解决了什么问题它和大模型微调有什么区别然后深入 Embedding 嵌入模型的运行机制搞懂文本是怎么变成向量的紧接着梳理向量检索的工作原理包括相似度计算、向量数据库选型最后用 Python 完整实现一个基于 LangChain 和 FAISS 的本地知识库问答系统并介绍混合检索和 Rerank 的进阶方案。1. 为什么需要 RAG大模型的知识困境1.1 大模型的“记忆力”是有限且滞后的大语言模型LLM本质是一个超大的概率模型它的“知识”在训练完成那一刻就固定了。不管模型参数是 70 亿还是 1000 亿它都只能通过训练语料来理解世界。这带来两个核心问题知识有截止日期模型无法知道训练之后发生的事情。比如你的企业内部最新发布了 V3.2 版本的接口文档模型根本不认识 V3.2 这个版本号。幻觉问题当模型遇到不知道、不确定的问题时它不会诚实地说“我不知道”而是会根据概率“编造”一个看起来合理的答案。这在企业知识库场景中是致命的用户问“报销流程是什么”模型可能一本正经地告诉你一个完全不存在的流程。RAGRetrieval-Augmented Generation检索增强生成解决的就是这个问题。它的核心思想非常朴素既然模型不知道答案那我们就先从一个外部知识库中检索出相关的资料片段把这些资料片段和用户的问题一起拼进 Prompt 中让模型“阅读”资料后再回答。相当于给模型开卷考试而不是闭卷考试。1.2 RAG 与模型微调的区别很多刚接触大模型开发的读者会问为什么不直接微调模型这里先做一个清晰的对比。维度RAG模型微调Fine-tuning知识更新更新知识库即可无需重新训练需要重新训练模型周期长实现成本相对较低有现成框架需要高质量标注数据和高算力幻觉控制可追溯答案基于检索内容无法完全控制模型输出来源适用场景知识库问答、文档解读、实时数据查询改变模型语气、格式、特定领域推理能力延迟增加检索环节有额外延迟推理时无额外处理两者不是互斥关系。实际工程中常见做法是先用 RAG 解决知识时效性和准确性问题如果业务还要求模型用特定风格输出再叠加微调。2. Embedding 嵌入模型运行机制2.1 什么是 EmbeddingEmbedding 是一个将高维离散数据映射到低维稠密向量的过程。在 NLP 领域Embedding 模型做的事情是把一段文本句子、段落、整篇文档转换成一个固定维度的浮点数数组。例如句子什么是RAG经过 Embedding 模型后可能得到这样一个 768 维的向量[0.012345, -0.023456, 0.045678, ..., 0.001234] # 共 768 个浮点数关键在于语义相近的文本它们的向量在向量空间中的距离就越近。比如“如何申请报销”和“报销流程是什么”这两个句子虽然字面表达不同但语义几乎相同它们的向量在空间中的欧氏距离或余弦相似度会非常高。而“今天天气怎么样”对应的向量则距离它们很远。这就像给每段文字分配了高维空间中的一个坐标语义相近的文本坐标聚集在一起。2.2 Embedding 模型的训练逻辑Embedding 模型的核心是学习一个映射函数 f使得以下条件成立相似(文本A, 文本B) ≈ 相似(向量A, 向量B)这里“相似”的定义由训练数据决定。目前主流的 Embedding 模型如 BGEBAAI General Embedding、OpenAI 的 text-embedding-3-small、智谱的 embedding-2 等都采用了对比学习的方法正样本对同一个问题的不同表达方式或问题与其对应答案组成的样本对。模型需要让这些样本对的向量距离更近。负样本对不相关的问题和文档组成的样本对。模型需要让这些样本对的向量距离更远。通过大量这样的训练模型学会了捕捉文本的语义信息而不只是字面重叠。这也是为什么 Embedding 模型能处理“同义词替换”和“语序调整”这类传统关键词搜索难以解决的问题。2.3 主流 Embedding 模型选型选择 Embedding 模型时需要考虑语言支持、向量维度、最大输入长度、推理速度、部署成本。常见的几类选择OpenAI text-embedding-3-small / 3-large英文效果较好调用 API 方便但中文场景需要注意数据出境和成本问题。BGE 系列bge-large-zh / bge-m3智源研究院开源的中文向量模型中文表现优秀。bge-m3 支持 8192 长度的输入并支持多语言。M3EMoka AI 开源的 Embedding 模型针对中文优化社区使用广泛。GTE 系列阿里通义实验室开源中文效果稳定适合与阿里云服务结合使用。本地化部署场景中BGE 和 M3E 是主流选择因为它们体积较小可以用 CPU 推理也可以通过 ONNX Runtime 加速。比如microsoft.ml.onnxruntime配合 BGE 模型可以很方便地在 .NET 或 Python 中实现本地化部署。2.4 Embedding 模型的适用场景Embedding 模型不止用于 RAG它的适用场景包括语义搜索搜索引擎的召回阶段不依赖关键词匹配。文本聚类对新闻、工单、客服对话做自动分类。文本相似度计算查重、相似问题匹配、代码重复检测。推荐系统根据用户行为序列和内容向量的相关性做召回。RAG 知识库本教程重点场景将文档内容向量化后存入向量数据库。3. 向量检索工作原理3.1 从文档到向量的全过程一个完整的 RAG 向量检索链路首先需要构建知识库。这个流程如下原始文档PDF/Word/Markdown/HTML ↓ 文本提取 纯文本内容 ↓ 文本切片Chunking 文本片段1、文本片段2、... ↓ Embedding 模型 向量1、向量2、... ↓ 存储 向量数据库FAISS / Milvus / Chroma / Qdrant切块Chunking是决定 RAG 检索效果的关键前置环节。切块策略要考虑两个因素块大小chunk_size通常以字符数或 token 数计算。块太小语义信息不完整块太大检索到的内容混杂无关信息给大模型的上下文也更大。块重叠chunk_overlap相邻块之间保留重叠部分避免一句话被硬生生切断导致语义断裂。常见的切块方式有三种固定长度切块按固定字符数切分实现简单但容易切断句子。递归字符切块按段落、句子、子句的层级逐步切分优先保持段落完整。LangChain 的RecursiveCharacterTextSplitter是这个思路。语义切块通过 Embedding 判断句子间语义差异在语义转折处切分。效果最好但计算成本较高。3.2 相似度计算向量检索的数学基础向量检索的核心是计算查询向量和文档向量之间的相似度。常见方法有三种余弦相似度最常用计算两个向量之间的夹角余弦值值越接近 1 表示越相似similarity (A · B) / (||A|| * ||B||)欧氏距离计算两个向量在空间中的直线距离距离越小越相似。注意它和余弦相似度是负相关且对向量模长敏感。内积点积直接计算两个向量的内积。如果向量已经归一化内积等于余弦相似度。在实际向量数据库中大多数索引结构如 HNSW、IVF都会将向量归一化后使用内积计算以提高效率。查询时系统计算查询向量与库中所有向量的相似度返回 Top-K 个最相似的文档片段。这个过程就是召回Recall。3.3 向量数据库选型把向量存到普通数据库字段里然后用 Python 遍历计算相似度只适合数据量很小的演示项目。生产环境需要专门的向量数据库因为它们使用了近似最近邻ANN索引能在海量向量中快速返回 Top-K 结果。常见选择数据库特点适用场景FAISSMeta 开源的向量检索库纯内存索引单机、中小规模数据集入门首选Chroma轻量级支持本地持久化API 友好原型验证、个人项目Milvus分布式向量数据库支持水平扩展大规模生产环境亿级向量QdrantRust 实现性能高支持丰富过滤条件生产环境需要复杂过滤pgvectorPostgreSQL 扩展兼顾业务数据和向量已有 PostgreSQL 业务体系热词中出现了embedding milvus llamaindex项目实战说明很多开发者在生产项目中会用 Milvus 搭配 LlamaIndex。Milvus 的优点在于支持标量过滤和向量检索混合比如先过滤文档分类再在过滤结果中做向量检索。3.4 混合检索向量检索并非万能向量检索解决了“语义相似但字面不同”的问题但它也有明显短板对专有名词、编号、代码符号不友好。比如查询“接口返回 502 错误”向量检索可能找到语义相关的文档但如果知识库中只有“HTTP 502 Bad Gateway 排查手册”字面上的“502”反而不是向量检索的强项。向量检索对输入文本的微小变动可能不敏感精确匹配能力弱。所以工程实践中常用混合检索Hybrid Search同时执行关键词检索如 BM25和向量检索再将两路结果合并去重后排序。这样“关键词精确匹配”和“语义相似扩展”互补。热词中提到的向量混合检索加bm25多路召回正是这一思路。BM25 是经典的信息检索算法它根据词频和逆文档频率给文档打分擅长精确匹配。多路召回后一般还要接一个 Rerank重排模型对召回结果做精细排序进一步提升答案相关性。4. RAG 完整业务流程4.1 整体架构一个标准的 RAG 系统包含两个主要阶段索引阶段Indexing和查询阶段Querying。索引阶段离线执行负责构建知识库。原始文档经过加载、切块、Embedding、入库四步变成向量数据库中的索引。查询阶段在线执行用户提问时依次完成问题向量化、向量检索召回 Top-K 片段、拼接 Prompt、大模型生成回答。下面用一张 ASCII 流程简图展示完整流程【离线索引阶段】 文档加载 → 文本切块 → Embedding 向量化 → 写入向量数据库 ↓ 向量数据库索引 【在线查询阶段】 用户问题 → Embedding 向量化 → 向量相似度检索 → Top-K 文本片段 ↓ 拼接 Prompt问题 检索片段 ↓ 大模型生成回答并输出这个流程中的每一步都可能影响最终回答质量。比如切块大小影响检索相关性Embedding 模型选择影响语义理解能力Top-K 设置影响上下文信息量Prompt 模板影响大模型的输出格式。4.2 RAG Pipeline 中的关键参数Top-K召回片段数量。设置太小可能漏掉答案设置太大容易引入噪声。一般建议 3-5 个片段。相似度阈值过滤低相关片段。低于阈值的片段不进入 Prompt避免模型被无关信息干扰。Prompt 模板需要明确告诉模型“只根据上下文回答不要编造”。这是控制幻觉的第一道关卡。5. 实战基于 LangChain FAISS 构建本地 RAG 系统下面从零搭建一个最小可运行的 RAG 系统。选择 LangChain 作为框架FAISS 作为向量存储嵌入模型使用开源的 BGE 系列或 M3E大模型部分可以选择 OpenAI API也可以接入本地 Ollama 部署的模型。5.1 环境准备建议使用 Python 3.9 及以上版本。安装依赖pip install langchain langchain-community langchain-openai langchain-huggingface pip install faiss-cpu pip install sentence-transformers如果要接入本地 Ollama 模型需要先安装并启动 Ollama 服务然后拉取模型ollama pull qwen2.5:7b如果是使用 OpenAI 兼容 API确保环境变量中配置了 API Keyexport OPENAI_API_KEY你的Key注意不同版本的 LangChain 包名和类路径有差异。文中示例以当前主流版本为基础如果遇到ImportError优先检查 LangChain 版本并参考官方迁移文档调整导入路径。5.2 准备测试文档在项目目录下创建data/文件夹放入一个 Markdown 或 TXT 文件作为知识库。也可以加载 PDF本文为了简化直接用 TXT。示例文档data/rag_intro.txtRAGRetrieval-Augmented Generation检索增强生成是一种将信息检索与大语言模型 生成能力相结合的技术方案。它的核心思路是在大模型回答问题之前先从外部知识库中 检索与问题相关的文档片段并把检索到的内容作为上下文拼接到提示词中让大模型在 已有资料的基础上生成更准确、更可靠的回答。 RAG 主要解决两个问题第一个是大模型知识时效性不足第二个是大模型幻觉现象。 通过外部知识库的实时更新RAG 可以让模型在不重新训练的情况下掌握最新信息。 RAG 系统的典型流程包括文档加载、文本切块、向量化、索引构建、检索召回、提示词 拼接和答案生成等环节。其中文本切块策略和向量检索质量直接影响最终答案的准确度。5.3 编写核心代码项目结构如下rag_demo/ ├── data/ │ └── rag_intro.txt ├── ingest.py # 索引阶段文档加载、切块、Embedding、入库 └── query.py # 查询阶段检索 生成ingest.py完整代码from langchain_community.document_loaders import TextLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS # 1. 加载文档 loader TextLoader(data/rag_intro.txt, encodingutf-8) documents loader.load() # 2. 文本切块 text_splitter RecursiveCharacterTextSplitter( chunk_size200, chunk_overlap50, separators[\n\n, \n, 。, , , , ], ) chunks text_splitter.split_documents(documents) print(f切块数量: {len(chunks)}) # 3. 加载 Embedding 模型这里使用开源的 BGE 中文模型 embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, encode_kwargs{normalize_embeddings: True}, ) # 4. 创建向量库并持久化 vectorstore FAISS.from_documents(chunks, embedding_model) vectorstore.save_local(faiss_index) print(向量库构建完成已保存到 faiss_index 目录)这里做一个说明RecursiveCharacterTextSplitter会按优先级依次尝试separators中的分隔符切分优先按段落\n\n再按\n、句号等尽量保证语义完整。chunk_size200表示每个块大约 200 字符按文档实际情况调整。HuggingFaceEmbeddings会自动下载 BGE 模型到本地缓存。首次运行需要网络连接后续可离线使用。query.py完整代码from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate # 加载向量库 embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, encode_kwargs{normalize_embeddings: True}, ) vectorstore FAISS.load_local( faiss_index, embedding_model, allow_dangerous_deserializationTrue, # 本机示例使用生产环境注意安全 ) # 构造检索器返回 Top-K 片段 retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 初始化大模型这里以 OpenAI 兼容接口为例 llm ChatOpenAI( modelqwen2.5:7b, base_urlhttp://localhost:11434/v1, # Ollama 的 OpenAI 兼容地址 api_keyollama, # Ollama 本地服务不需要真实 Key temperature0.2, ) # 构建 Prompt 模板 prompt_template ChatPromptTemplate.from_messages([ (system, 你是一个知识库问答助手。请严格根据以下上下文内容回答问题。 如果上下文中没有答案请直接说根据已有资料无法回答。不要编造内容。), (human, 上下文内容\n{context}\n\n用户问题{question}), ]) def ask(question: str): # 检索相关文档片段 docs retriever.invoke(question) context \n\n.join([doc.page_content for doc in docs]) print( 检索到的片段 ) for i, doc in enumerate(docs): print(f[{i1}] {doc.page_content}) print() # 构造消息并调用大模型 messages prompt_template.format_messages(contextcontext, questionquestion) response llm.invoke(messages) return response.content if __name__ __main__: while True: user_input input(\n请输入你的问题输入 exit 退出) if user_input.lower() exit: break answer ask(user_input) print(f\n助手回答{answer})5.4 运行与验证按顺序执行python ingest.py python query.py预期ingest.py输出类似切块数量: 3 向量库构建完成已保存到 faiss_index 目录查询阶段输入RAG 是什么控制台会先打印检索到的片段再输出模型的回答。由于知识库中已经包含了 RAG 的定义回答内容应该与文档中的表述保持一致而不是模型凭记忆编造的答案。5.5 关于 FAISS 反序列化安全代码中出现了allow_dangerous_deserializationTrue。这是 LangChain 基于 Pythonpickle序列化机制的安全开关。在加载他人分享的 FAISS 索引时需要特别注意恶意构造的 pickle 文件可能导致任意代码执行。生产环境建议只加载自己生成的索引文件或者改用 JSON 格式的持久化方案。6. 进阶混合检索与 Rerank 重排基础版本已经可以实现知识库问答但真实业务中检索质量往往不够。下面介绍两个重要优化方向。6.1 BM25 向量或多路召回只用 FAISS 向量检索前面提过对精确匹配不友好。一个成熟的方案是同时用 BM25 关键词检索和向量检索两路结果合并后去重再交给大模型。LangChain 的EnsembleRetriever支持这个功能from langchain.retrievers import BM25Retriever, EnsembleRetriever from langchain_huggingface import HuggingFaceEmbeddings from langchain_community.vectorstores import FAISS # 准备文档列表 chunks_texts [doc.page_content for doc in chunks] # BM25 检索器 bm25_retriever BM25Retriever.from_texts( chunks_texts, k3, ) # 向量检索器 embedding_model HuggingFaceEmbeddings( model_nameBAAI/bge-small-zh-v1.5, ) vectorstore FAISS.from_texts(chunks_texts, embedding_model) vector_retriever vectorstore.as_retriever(search_kwargs{k: 3}) # 组装集成检索器 ensemble_retriever EnsembleRetriever( retrievers[bm25_retriever, vector_retriever], weights[0.4, 0.6], # 调整两路权重 )6.2 使用 Rerank 模型精确排序Rerank 模型的任务是对召回的候选文档进行精排。它和 Embedding 模型不同Embedding 模型是把文本压缩成向量后用相似度排序而 Rerank 模型会直接对“问题-文档”对计算相关性分数精度更高但速度较慢因此适合在召回之后、送入大模型之前使用。常见的开源 Rerank 模型有bge-reranker-base、bge-reranker-large。在 LangChain 中使用示例如下from langchain.retrievers import ContextualCompressionRetriever from langchain_community.document_compressors import CrossEncoderReranker from langchain_community.cross_encoders import HuggingFaceCrossEncoder reranker HuggingFaceCrossEncoder(model_nameBAAI/bge-reranker-base) compressor CrossEncoderReranker(modelreranker, top_n2) compression_retriever ContextualCompressionRetriever( base_compressorcompressor, base_retrieverensemble_retriever, )经过 Rerank 后最终进入 Prompt 的片段数量更少但相关性大幅提升能明显降低大模型输出无关内容或幻觉的概率。热词中提到的embedding模型 rerank 模型正是 RAG 生产落地的标准组合。6.3 RAG 框架的选择LangChain 与 LlamaIndexLangChain 和 LlamaIndex 是目前最流行的两个 RAG 开发框架LangChain的生态丰富除了 RAG还能处理 Agent、工具调用等复杂流程。文档切分器种类多适合灵活组装。LlamaIndex专注于数据索引和检索对文档加载、索引结构、查询引擎的支持更细粒度。适合重检索场景。两者可以结合使用。实践中也可以用 Dify 这类低代码平台快速搭建 RAG 应用原型企业内部非技术人员也能通过可视化界面维护知识库。热词中的dify和rag指的就是这类工具链的结合使用方式。7. 常见问题与排查思路7.1 高频问题排查表问题现象常见原因解决思路检索到的文档片段完全不相关Embedding 模型与语料语言不匹配或未开启向量归一化中文语料使用 BGE 中文模型检查normalize_embeddings设置答案包含幻觉内容不基于检索片段Prompt 未约束模型“只根据上下文回答”强化 Prompt 指令增加“若上下文中无答案则直接说明”切块后一句话被截断chunk_size 太小或分隔符未包含中文标点调大 chunk_size在separators中加。检索片段太多上下文过长Top-K 设置过大减小k值或使用 Rerank 压缩到 Top-2本地模型回答速度慢大模型部署在 CPU 环境使用量化模型升级硬件或改为 API 调用导入 LangChain 类失败LangChain 版本升级导致路径变更检查版本号使用langchain_community或langchain_huggingface中的目标类Ollama 调用接口报 404本地模型名错误或未启动服务执行ollama list确认模型名启动ollama serve7.2 中文文本切块容易踩的坑LangChain 的RecursiveCharacterTextSplitter默认separators包含英文换行符和英文句号但不包含中文句号、问号、感叹号。如果直接沿用默认配置中文文档会被硬生生截断。建议在中国项目里始终加入中英文标点混合的分隔配置。另外chunk_size 参数在 LangChain 中默认按字符数计算但在某些组件中按 token 数计算。如果你使用的是 OpenAI Embedding 接口要注意 token 限制。例如text-embedding-3-small的最大输入是 8191 token超长文本需要先切块。7.3 结果不理想的排查顺序当 RAG 系统回答质量不佳时建议按以下顺序排查先看打印出的检索片段如果片段本身就不相关那问题出在切块或 Embedding 阶段。再看检索片段是否包含答案如果不包含检查切块大小是否太小、Top-K 是否过小、知识库是否有对应文档。如果片段包含答案但模型回答错误问题在 Prompt 指令或模型生成参数检查 temperature 是否过高、Prompt 是否明确要求基于上下文。如果片段相关但过于冗余引入 Rerank 或降低 Top-K。8. RAG 工程落地最佳实践8.1 数据质量优先RAG 的效果上限取决于知识库质量。一个文档格式混乱、内容互相矛盾的知识库无论 Embedding 模型多强、大模型多聪明都无法产出稳定的答案。落地时建议清洗原始文档去除页眉页脚、导航噪声、广告信息。统一文档格式优先使用 Markdown 或纯文本处理再考虑 PDF、Word。对专业术语建立同义词表必要时在索引前对文本做归一化处理。8.2 切块策略需要实验验证没有一种切块策略适用于所有场景。法律合同、代码文档、技术手册、客服 FAQ 的结构差异很大。推荐做法先用递归字符切块作为基线。对比不同 chunk_size 下的检索命中率。针对结构化文档考虑按标题层级切块针对 FAQ考虑按“问题-答案”对切块。记录切片与原文的映射关系便于溯源。8.3 安全与权限边界如果 RAG 系统在企业内部使用必须考虑检索权限控制。不能让一个普通员工通过知识库问答查到涉密文档。工程上的做法在每个文档片段入库时打上权限标签如部门、密级。检索阶段根据当前用户身份过滤标签只允许检索用户有权访问的片段。使用支持标量过滤的向量数据库如 Milvus、Qdrant在向量检索的同时完成权限过滤。8.4 监控与评估RAG 系统上线后不能用“感觉还行”来评估。建议建立三层评估体系检索质量计算召回率、命中率、MRR 等指标评估检索器是否能找到正确答案。生成质量用专门的评测集请业务专家打分或使用 LLM-as-Judge 自动评估答案准确性、完整度、相关性。业务指标客服场景关注解决率、转人工率内部知识库关注搜索点击率、问题重复率。线上监控方面关注检索平均延迟、大模型推理延迟、Token 消耗成本。热词中提到的集体暴涨 大模型还用得起吗正是企业关心的成本问题RAG 场景可以通过本地小模型、量化部署、减少冗余 Token 等方式控制成本。8.5 大模型选型建议RAG 场景中大模型不一定越大越好。检索到的上下文已经提供了核心依据生成模型主要做“阅读理解 归纳总结”因此 7B 级别的量化模型在很多场景下已经足够。本地部署优先考虑 Ollama 或 vLLM。Ollama 适合个人开发和轻量级部署vLLM 适合高并发生产环境。如果团队有 GPU 资源推荐用vLLM Qwen2.5系列部署如果没有 GPU可以先用 Ollama 的 CPU 量化版本做原型验证。8.6 从原型到生产的注意事项很多时候演示环境跑通 RAG 很简单但生产环境会遇到各种实际问题文档更新频率高时需要增量索引而不是全量重建。向量数据库容量增长后需要分片和归档策略。多人同时对话时要复用 LLM 实例而不是每次新建连接。检索延迟要控制在几百毫秒内否则用户感知明显。可以用缓存热点问题减少重复计算。9. 总结与下一步学习方向到这里RAG 的完整业务流程已经清晰了从文档加载、文本切块、Embedding 向量化、向量存储到查询时的语义检索、多路召回、重排、Prompt 拼接最后交给大模型生成答案。这套流程中Embedding 决定了语义理解的上限切块策略决定了信息完整度向量检索决定召回质量Rerank 决定最终输入大模型的上下文质量而 Prompt 设计决定了模型输出的可靠性。建议下一步可以沿着三个方向深入把检索做得更精细研究 HNSW 索引结构、混合检索调参、Rerank 模型微调。把链路做得更自动化尝试 LlamaIndex 的各类索引结构或用 Dify 搭建可维护的知识库后台。把系统做得更工程化研究如何用 Milvus 部署分布式向量检索服务如何在 Kubernetes 上部署 RAG 服务如何做全链路监控和成本治理。RAG 是当前大模型落地性价比最高的技术路线之一哪怕预算有限、硬件一般也能快速搭建一套可用的知识库问答系统。建议直接按文中示例动手跑一遍再结合自己的业务数据调参优化。实践过程中遇到的问题欢迎在评论区一起讨论。