大模型 RAG 实战:从零手把手构建知识库问答系统,建议收藏
本文详解如何利用 RAG 技术解决大模型“幻觉”问题从零构建基于私有知识库的问答系统。涵盖文档分割、向量化存储、检索增强生成及提示词工程等核心环节结合 LangChain、Ollama 等工具实现完整代码并探讨了增量更新与混合检索等进阶优化方案。一、理解 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-5 const 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 的应用场景将会越来越广泛让我们一起探索更多可能性最后对于正在迷茫择业、想转行提升或是刚入门的程序员、编程小白来说有一个问题几乎人人都在问未来10年什么领域的职业发展潜力最大答案只有一个人工智能尤其是大模型方向当下人工智能行业正处于爆发式增长期其中大模型相关岗位更是供不应求薪资待遇直接拉满——字节跳动作为AI领域的头部玩家给硕士毕业的优质AI人才含大模型相关方向开出的月基础工资高达5万—6万元即便是非“人才计划”的普通应聘者月基础工资也能稳定在4万元左右。再看阿里、腾讯两大互联网大厂非“人才计划”的AI相关岗位应聘者月基础工资也约有3万元远超其他行业同资历岗位的薪资水平对于程序员、小白来说无疑是绝佳的转型和提升赛道。对于想入局大模型、抢占未来10年行业红利的程序员和小白来说现在正是最好的学习时机行业缺口大、大厂需求旺、薪资天花板高只要找准学习方向稳步提升技能就能轻松摆脱“低薪困境”抓住AI时代的职业机遇。如果你还不知道从何开始我自己整理一套全网最全最细的大模型零基础教程我也是一路自学走过来的很清楚小白前期学习的痛楚你要是没有方向还没有好的资源根本学不到东西下面是我整理的大模型学习资源希望能帮到你。扫码免费领取全部内容最后1、大模型学习路线2、从0到进阶大模型学习视频教程从入门到进阶这里都有跟着老师学习事半功倍。3、 入门必看大模型学习书籍文档.pdf书面上的技术书籍确实太多了这些是我精选出来的还有很多不在图里4、AI大模型最新行业报告2026最新行业报告针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估以了解哪些行业更适合引入大模型的技术和应用以及在哪些方面可以发挥大模型的优势。5、面试试题/经验【大厂 AI 岗位面经分享107 道】【AI 大模型面试真题102 道】【LLMs 面试真题97 道】6、大模型项目实战配套源码适用人群四阶段学习规划共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 项目内容安全互联网信息服务算法备案…扫码免费领取全部内容3、这些资料真的有用吗这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理现任上海殷泊信息科技CEO其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证服务航天科工、国家电网等1000企业以第一作者在IEEE Transactions发表论文50篇获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。资料内容涵盖了从入门到进阶的各类视频教程和实战项目无论你是小白还是有些技术基础的技术人员这份资料都绝对能帮助你提升薪资待遇转行大模型岗位。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2430784.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!