本文将带你深入了解RAG检索增强生成技术该技术结合了信息检索和生成式AI使大语言模型能够基于特定领域的知识库提供准确、可靠的回答。文章从RAG的核心价值、系统架构设计、离线阶段构建知识库、在线阶段问答流程等方面进行详细阐述并探讨了进阶功能如增量更新。此外还分析了常见问题与解决方案并对RAG技术的未来发展趋势进行了展望。通过本文的学习你将能够掌握构建一个完整的RAG问答系统的关键步骤和最佳实践为在实际项目中应用RAG技术打下坚实基础。前言在大语言模型LLM应用日益普及的今天如何让模型基于我们自己的知识库回答问题成为了一个热门的技术话题。RAGRetrieval-Augmented Generation检索增强生成技术应运而生它巧妙地结合了信息检索和生成式 AI让大语言模型能够基于特定领域的知识库提供准确、可靠的回答。本文将带你从零开始一步步构建一个完整的 RAG 问答系统并深入解析其中的核心概念和最佳实践。一、理解 RAG 的核心价值1.1 什么是 RAGRAG 是一种混合架构它将用户的查询与知识库中的相关内容相结合然后交给大语言模型生成回答。简单来说就是先检索再生成。1.2 为什么需要 RAG大语言模型虽然强大但存在两个固有缺陷问题表现RAG 的解决方案知识过时模型训练完成后无法获取新信息知识库可随时更新幻觉问题模型可能编造不存在的答案强制基于检索到的文档回答1.3 RAG 的优势事实准确回答基于真实文档减少幻觉可更新无需重新训练模型即可更新知识可追溯可以标注答案来源成本低廉相比微调模型成本更低二、系统架构设计2.1 整体架构图整体架构2.2 核心组件职责组件职责技术选型DocumentChunker将文档分割为语义完整的片段LangChain TextSplittersEmbeddingStore存储和检索向量表示Chroma Ollama EmbeddingsKnowledgeBase协调整个知识库的构建和管理自定义类RAGChat处理用户提问协调检索和生成LangChain Ollama三、离线阶段构建知识库3.1 文本分割DocumentChunker文档分割是 RAG 的第一步也是最关键的一步。分割的好坏直接影响检索效果。为什么需要分割大语言模型有上下文长度限制向量检索需要更小的语义单元合理的分割能提高检索精度分割策略// 项目配置const chunkSize 800; // 每个 chunk 的字符数const chunkOverlap 100; // 相邻 chunk 的重叠字符数参数说明chunkSize太小会丢失上下文太大会降低检索精度推荐 500-1000chunkOverlap确保边界信息的连续性推荐 50-150LangChain TextSplitters APILangChain 提供了多种分割器本项目使用两种// Markdown 文档专用分割器const mdSplitter new MarkdownTextSplitter({ chunkSize: 800, chunkOverlap: 100});// 递归字符分割器通用型const textSplitter new RecursiveCharacterTextSplitter({ chunkSize: 800, chunkOverlap: 100, // 按优先级递归尝试的分隔符 separators: [\n\n, \n, 。, , , , , , ]});递归分割的工作原理首先尝试用\n\n分割段落级别如果结果仍然太大尝试用\n分割句子级别继续尝试标点符号直到满足 chunkSize 要求支持多文件处理export class DocumentChunker { constructor(filepath: string | string[]) { // 支持单个文件或文件数组 } async splitText(): Promisestring[] { if (Array.isArray(this.filepath)) { // 并行处理多个文件 const allChunks awaitPromise.all( this.filepath.map(fp this.processFile(fp)) ); return allChunks.flat(); } returnawaitthis.processFile(this.filepath); }}3.2 向量化与存储EmbeddingStore什么是向量向量是文本的数值表示相似的文本在向量空间中距离更近。通过计算向量之间的相似度可以找到与查询最相关的文档。向量化流程向量化流程LangChain Embeddings APIimport { OllamaEmbeddings } from langchain/ollama;const embeddings new OllamaEmbeddings({ model: qwen3-embedding:4b, baseUrl: http://localhost:11434});// 单个文本向量化const vector await embeddings.embedQuery(查询文本);// 批量向量化const vectors await embeddings.embedDocuments([文档1, 文档2]);Chroma 向量数据库Chroma 是一个开源的向量数据库专为 AI 应用设计import { Chroma } from langchain/community/vectorstores/chroma;const vectorStore new Chroma(embeddings, { collectionName: my-knowledge-base, clientParams: { host: localhost, port: 8000 }, collectionMetadata: { hnsw:space: cosine // 余弦相似度 }});相似度算法选择算法特点适用场景Cosine关注方向忽略长度文本向量推荐Euclidean关注绝对距离需要精确匹配Dot Product关注对齐程度归一化后的向量在使用Chroma API之前需要安装 Chroma 客户端比如使用 docker 安装# 拉取镜像docker pull ghcr.io/chroma-core/chroma:latest# 运行容器docker run -d \ --name chroma-server \ -p 8000:8000 \ -v chroma-data:/chroma/chroma/ \ -e IS_PERSISTENTTRUE \ -e CHROMA_WORKERS$(nproc) \ ghcr.io/chroma-core/chroma:latest文档去重机制export class EmbeddingStore { private documentHashes new Setstring(); async addDocumentsWithDeduplication(documents: string[]) { const uniqueDocs documents.filter(doc { const hash this.calculateHash(doc); if (this.documentHashes.has(hash)) { return false; // 已存在跳过 } this.documentHashes.add(hash); return true; }); awaitthis.vectorStore.addDocuments(uniqueDocs); }}3.3 知识库管理KnowledgeBaseKnowledgeBase 是整个系统的协调器负责协调整个知识库的构建和更新。export class KnowledgeBase { staticasync create(filepath: string | string[]): PromiseKnowledgeBase { const kb new KnowledgeBase(filepath); await kb.init(); return kb; } privateasync init() { const chunks await this.documentChunker.splitText(); awaitthis.embeddingStore.setVectors(chunks); }}使用工厂方法的好处确保异步初始化完成后再返回实例隐藏构造函数强制使用正确的初始化方式便于后续扩展如连接池、缓存等四、在线阶段问答流程4.1 检索相关上下文当用户提问时系统首先在向量数据库中检索最相关的文档片段。检索上下文VectorStore API 使用// 相似度搜索返回文档列表const docs await vectorStore.similaritySearch(query, k);// 相似度搜索返回文档和分数const results await vectorStore.similaritySearchWithScore(query, k);// 格式: [[Document, score], ...]// 按相似度阈值过滤const filtered results.filter(([_, score]) score 0.8);4.2 提示词工程提示词Prompt是控制模型输出的关键好的提示词能显著提升回答质量。基础提示词请基于以下上下文回答问题。上下文{context}问题{question}回答优化后的提示词你是一个专业的问答助手请基于提供的参考文档回答用户的问题。【参考文档】{context}【用户问题】{question}【回答要求】1. 只使用参考文档中的信息回答不要编造内容2. 如果参考文档中没有相关信息请明确说明文档中未找到相关答案3. 回答时要条理清晰使用恰当的段落分隔4. 如果答案是列表形式请使用项目符号回答优化要点明确角色定位使用分隔符增强可读性列出具体要求减少模型理解偏差处理无答案的情况LangChain PromptTemplate APIimport { PromptTemplate } from langchain/core/prompts;const promptTemplate PromptTemplate.fromTemplate(你是一个专业的问答助手请基于提供的参考文档回答用户的问题。【参考文档】{context}【用户问题】{question}【回答要求】1. 只使用参考文档中的信息回答不要编造内容2. 如果参考文档中没有相关信息请明确说明文档中未找到相关答案3. 回答时要条理清晰使用恰当的段落分隔4. 如果答案是列表形式请使用项目符号回答);// 格式化提示词const prompt await promptTemplate.format({ context: 检索到的文档内容..., question: 用户的问题});4.3 生成回答使用 LangChain 的链式调用机制将检索、提示词构建和生成串联起来。链式调用基础import { StringOutputParser } from langchain/core/output_parsers;// 创建链const chain llm .pipe(new StringOutputParser()) // 解析输出为字符串 .pipe((text) text.trim()); // 后处理// 调用链const result await chain.invoke(用户输入);完整的 RAG 链export class RAGChat { async answer(question: string): Promisevoid { // 步骤1检索相关上下文 const contextList await this.knowledgeBase.getEmbeddingStore() .retrieveContext(question); const context contextList?.join(\n\n); // 步骤2构建提示词 const prompt await this.promptTemplate.format({ context, question, }); // 步骤3调用模型生成回答 const chain this.llm.pipe(new StringOutputParser()); const answer await chain.stream(prompt); // 步骤4流式输出 await answer.pipeTo(writable); }}async function main() { try { console.log(正在初始化 RAG 系统...); const knowledgeBase await KnowledgeBase.create( path.resolve(__dirname, ../xxxx.md) ); const ragChat new RAGChat({ knowledgeBase }); console.log(RAG 系统初始化完成); console.log(输入您的问题输入 exit 或 quit 退出\n); const rl readline.createInterface({ input: process.stdin, output: process.stdout }); const askQuestion () { rl.question( , async (prompt) { const trimmedPrompt prompt.trim(); if (!trimmedPrompt) { askQuestion(); return; } if (trimmedPrompt exit || trimmedPrompt quit) { console.log(再见); rl.close(); return; } await ragChat.answer(trimmedPrompt); console.log(); askQuestion(); }); }; askQuestion(); } catch (error) { console.error(系统启动失败, error instanceof Error ? error.message : String(error)); process.exit(1); } }使用 RunnableSequence对于更复杂的场景可以使用RunnableSequenceimport { RunnableSequence } fromlangchain/core/runnables;const ragChain RunnableSequence.from([ { // 步骤1检索上下文 context: (input) retriever.invoke(input.question), question: (input) input.question }, // 步骤2格式化提示词 (input) promptTemplate.format(input), // 步骤3调用模型 llm, // 步骤4解析输出 new StringOutputParser()]);const response await ragChain.invoke({ question: 用户问题 });五、进阶功能增量更新生产环境中知识库需要频繁更新而不需要重新处理所有文档。5.1 文件变更检测通过文件哈希值判断文件是否发生变化class KnowledgeBase { private fileHashes new Mapstring, string(); private calculateFileHash(filepath: string): string { const content fs.readFileSync(filepath, utf-8); return crypto.createHash(md5).update(content).digest(hex); } private isFileChanged(filepath: string): boolean { const currentHash this.calculateFileHash(filepath); const previousHash this.fileHashes.get(filepath); if (previousHash ! currentHash) { this.fileHashes.set(filepath, currentHash); return true; } return false; }}5.2 增量更新流程增量更新流程5.3 实现代码export class KnowledgeBase { async update(filepath: string | string[]): Promisevoid { const filepaths Array.isArray(filepath) ? filepath : [filepath]; let updated false; for (const fp of filepaths) { if (this.isFileChanged(fp)) { const chunks await this.documentChunker.processFile(fp); awaitthis.embeddingStore.deleteDocumentsBySource(fp); awaitthis.embeddingStore.addDocumentsWithDeduplication(chunks, fp); updated true; } } if (updated) { console.log(知识库更新完成); } }}六、常见问题与解决方案Q1: 检索结果不相关怎么办可能原因chunkSize 设置不当嵌入模型不适合当前语言分割策略不合理解决方案调整 chunkSize推荐 500-1000尝试不同的嵌入模型优化分割策略增加 chunkOverlap使用混合检索关键词向量Q2: 如何处理超长文档解决方案使用章节级别分割添加目录索引实现分块检索策略Q3: 模型回答不够准确解决方案优化提示词模板增加 k 值获取更多上下文添加相似度阈值过滤使用更强的模型Q4: 如何提升系统性能优化方向批量向量化处理使用向量索引如 HNSW实现缓存机制并行处理多个文件七、总结与展望7.1 RAG 技术总结RAG 技术通过检索生成的方式让大语言模型能够基于私有知识库回答问题具有事实准确、可更新、可追溯等优势。本项目从零开始构建了一个完整的 RAG 问答系统涵盖了✅ 文本分割与向量化✅ 向量存储与检索✅ 提示词工程✅ 链式调用机制✅ 增量更新功能7.2 RAG 当前面临的挑战尽管 RAG 技术已经取得了显著进展但在实际应用中仍存在一些挑战挑战具体表现检索准确性语义鸿沟问题向量检索可能错过相关文档上下文长度限制模型上下文窗口有限难以容纳大量检索内容多轮对话能力弱难以有效利用对话历史进行检索推理能力有限跨文档的复杂推理能力不足延迟问题检索生成的链路延迟较高知识更新成本向量化存储和索引更新仍有开销7.3 新兴技术与解决方案针对上述挑战研究界和工业界正在积极探索多种解决方案1. 混合检索Hybrid Retrieval问题解决提高检索准确性结合关键词检索BM25和向量检索的优势混合检索技术代表LangChain 的BM25RetrieverVectorStoreRetrieverElasticsearch 的 dense_vector text 字段混合查询2. 重排序Reranking问题解决提升检索结果的相关性在初步检索后使用专门的排序模型对结果进行精排// 检索 Top-50 个候选const candidates await vectorStore.similaritySearch(query, 50);// 使用重排序模型精排const reranker new CohereRerank();const rankedResults await reranker.compressDocuments(candidates, query);// 取 Top-5const topResults rankedResults.slice(0, 5);技术代表Cohere Rerank APIBGE-Reranker开源ColBERTLate Interaction3. 长上下文模型Long Context LLMs问题解决突破上下文长度限制新一代支持超长上下文的模型可以直接处理更多检索内容模型上下文长度特点GPT-4 Turbo128K支持长文档直接处理Claude 3200K优秀的长文档理解能力Qwen-Long10M超长上下文适合海量检索Gemini 1.51M多模态长上下文4. 智能体 RAGAgentic RAG问题解决增强推理和多轮对话能力将 RAG 与 Agent 结合使用工具调用和思维链增强推理能力Agentic RAG技术代表LangGraphAgent 工作流AutoGPT、BabyAGIReAct 框架5. 图谱 RAGGraphRAG问题解决增强跨文档推理能力将知识库构建为知识图谱支持结构化查询和推理图谱 RAG技术代表Microsoft GraphRAGNeo4j LLMLlamaIndex Knowledge Graphs6. 自适应检索Adaptive RAG问题解决优化延迟和准确性根据问题类型动态决定是否需要检索以及检索多少内容// 判断是否需要检索const needsRetrieval await router.predict({ query: userQuestion});if (needsRetrieval yes) { // 根据问题复杂度调整检索数量 const k determineRetrievalDepth(userQuestion); const context await retrieve(userQuestion, k); return generateAnswer(context, userQuestion);} else { // 直接使用模型内部知识 return llm.invoke(userQuestion);}技术代表Self-RAG带自我反思的 RAGAdaptive RAG自适应检索Corrective RAG纠错型 RAG7. 微调 RAGFine-tuned Embeddings问题解决提升领域特定检索效果针对特定领域微调嵌入模型方案特点适用场景BGE-M3多语言、多功能通用场景E5基于对比学习问答系统Jina Embeddings开源高效成本敏感场景自定义微调领域定制垂直领域7.5 总结RAG 技术正在快速演进从最初的简单检索生成模式发展到今天融合混合检索、重排序、智能体、知识图谱等多种技术的综合方案。对于开发者而言选择合适的 RAG 方案需要考虑应用场景问答、对话、知识管理、代码辅助等数据特性文本类型、数据规模、更新频率性能要求延迟、准确性、成本团队能力技术栈、维护成本希望本文能够帮助你理解 RAG 的核心概念并在实际项目中应用这些技术。随着技术的不断发展RAG 的应用场景将会越来越广泛让我们一起探索更多可能性如何系统的学习大模型 AI 由于新岗位的生产效率要优于被取代岗位的生产效率所以实际上整个社会的生产效率是提升的。但是具体到个人只能说是“最先掌握AI的人将会比较晚掌握AI的人有竞争优势”。这句话放在计算机、互联网、移动互联网的开局时期都是一样的道理。我在一线互联网企业工作十余年里指导过不少同行后辈。帮助很多人得到了学习和成长。我意识到有很多经验和知识值得分享给大家也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限很多互联网行业朋友无法获得正确的资料得到学习提升故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。一直在更新更多的大模型学习和面试资料已经上传带到CSDN的官方了有需要的朋友可以扫描下方二维码免费领取【保证100%免费】01.大模型风口已至月薪30K的AI岗正在批量诞生2025年大模型应用呈现爆发式增长根据工信部最新数据国内大模型相关岗位缺口达47万初级工程师平均薪资28K数据来源BOSS直聘报告70%企业存在能用模型不会调优的痛点真实案例某二本机械专业学员通过4个月系统学习成功拿到某AI医疗公司大模型优化岗offer薪资直接翻3倍02.大模型 AI 学习和面试资料1️⃣ 提示词工程把ChatGPT从玩具变成生产工具2️⃣ RAG系统让大模型精准输出行业知识3️⃣ 智能体开发用AutoGPT打造24小时数字员工熬了三个大夜整理的《AI进化工具包》送你✔️ 大厂内部LLM落地手册含58个真实案例✔️ 提示词设计模板库覆盖12大应用场景✔️ 私藏学习路径图0基础到项目实战仅需90天第一阶段10天初阶应用该阶段让大家对大模型 AI有一个最前沿的认识对大模型 AI 的理解超过 95% 的人可以在相关讨论时发表高级、不跟风、又接地气的见解别人只会和 AI 聊天而你能调教 AI并能用代码将大模型和业务衔接。大模型 AI 能干什么大模型是怎样获得「智能」的用好 AI 的核心心法大模型应用业务架构大模型应用技术架构代码示例向 GPT-3.5 灌入新知识提示工程的意义和核心思想Prompt 典型构成指令调优方法论思维链和思维树Prompt 攻击和防范…第二阶段30天高阶应用该阶段我们正式进入大模型 AI 进阶实战学习学会构造私有知识库扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架抓住最新的技术进展适合 Python 和 JavaScript 程序员。为什么要做 RAG搭建一个简单的 ChatPDF检索的基础概念什么是向量表示Embeddings向量数据库与向量检索基于向量检索的 RAG搭建 RAG 系统的扩展知识混合检索与 RAG-Fusion 简介向量模型本地部署…第三阶段30天模型训练恭喜你如果学到这里你基本可以找到一份大模型 AI相关的工作自己也能训练 GPT 了通过微调训练自己的垂直大模型能独立训练开源多模态大模型掌握更多技术方案。到此为止大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗为什么要做 RAG什么是模型什么是模型训练求解器 损失函数简介小实验2手写一个简单的神经网络并训练它什么是训练/预训练/微调/轻量化微调Transformer结构简介轻量化微调实验数据集的构建…第四阶段20天商业闭环对全球大模型从性能、吞吐量、成本等方面有一定的认知可以在云端和本地等多种环境下部署大模型找到适合自己的项目/创业方向做一名被 AI 武装的产品经理。硬件选型带你了解全球大模型使用国产大模型服务搭建 OpenAI 代理热身基于阿里云 PAI 部署 Stable Diffusion在本地计算机运行大模型大模型的私有化部署基于 vLLM 部署大模型案例如何优雅地在阿里云私有部署开源大模型部署一套开源 LLM 项目内容安全互联网信息服务算法备案…学习是一个过程只要学习就会有挑战。天道酬勤你越努力就会成为越优秀的自己。如果你能在15天内完成所有的任务那你堪称天才。然而如果你能完成 60-70% 的内容你就已经开始具备成为一名大模型 AI 的正确特征了。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】