当前位置: 首页 > news >正文

大白话拆解 RAG:从零搭建一个“有背景知识”的智能问答系统

当大模型开始“胡说八道”,我们该如何给它装上“外挂大脑”?

前言:当 AI 开始“一本正经地胡说八道”

你有没有遇到过这种情况:兴致勃勃地跑去问大模型:“昨天我们公司内部会议讨论了什么?”结果它给你编了一个激情澎湃但完全没发生过的故事。

这真不怪它。大模型就像一个超级学霸,它的大脑里装满了训练时看过的书籍和资料。但对于训练后才发生的事情,或者你公司内部的私有文档,它确实是一无所知的。更麻烦的是,它不会坦白说“我不知道”,而是会基于已有的知识强行推理,这就产生了所谓的“幻觉”

说白了就是:你不知道的事,它也不知道;但不同的是,它不知道还会硬答。

今天,我们就来聊聊如何用 RAG(检索增强生成)技术,给大模型装上一个“外挂知识库”,让它学会“先查资料,再回答问题”。

一、RAG 是什么?简单到离谱!

RAG 的全称是Retrieval-Augmented Generation,中文叫检索增强生成。名字虽然高大上,但本质原理极其朴素,就三步:

  1. 检索(Retrieval):当用户提问时,先去知识库里“翻书”,找到相关的文档片段。
  2. 增强(Augmented):把这些找到的文档片段,作为“背景知识”塞进 Prompt 里,增强提示词。
  3. 生成(Generation):大模型看着手里的“小抄”(Prompt 里的背景知识),给出最终的靠谱回答。

你可以把它理解为开卷考试:传统大模型是闭卷考,不会的题就瞎蒙;而 RAG 允许它带着参考书进考场,答案自然准确得多。

二、核心技术一:语义检索,告别“关键词”的尴尬

既然要“翻书”,怎么翻就很有讲究了。直接 Ctrl+F 关键词匹配?那搜“苹果”可能出来一堆“苹果公司”的新闻,而你想要的是水果“苹果”的营养价值。

这里的主角是向量(Vector)嵌入模型(Embedding Model)

1. 万物皆可“向量化”

你可以把向量理解为一串用来描述事物特征的数字。比如描述水果,我们有两个维度:

  • 食用性:0 到 1
  • 硬度:0 到 1

那么:

  • 苹果 =[0.9, 0.5]
  • 香蕉 =[0.9, 0.1]
  • 石头 =[0.1, 0.9]

在数学上,余弦值越小,夹角越大,相关性越低。显然,苹果和香蕉的夹角更小,它们更相似。而石头则被远远地甩在一边。

在实际应用中,我们使用专门的嵌入模型(Embedding Model)将文本、图片甚至语音转化为成百上千维的高维向量。这种向量包含了丰富的语义信息,能够精准地捕捉“苹果是一种水果”和“香蕉是一种水果”这种深层的相关性,远比关键词匹配更“懂”你的意思。

2. 查询流程

  1. 离线阶段:把知识库里的所有文档分片,通过 Embedding 模型变成向量,存入向量数据库
  2. 在线阶段:用户提问时,同样把问题通过 Embedding 模型变成向量。
  3. 在向量数据库里找出与问题向量最相似(余弦夹角最小)的前 K 个文档片段。

金句:如果说关键词搜索是“按图索骥”,那向量检索就是“灵魂匹配”。

三、核心技术二:文档分片(Chunking)

知识库里的文档动辄几十页,你不能把整本书直接塞给大模型(上下文窗口有限)。所以需要分片

  • 按章节:逻辑清晰,但章节太长不适合。
  • 按页:简单粗暴,但语义可能不完整。
  • 按段落最推荐。保证每一块内容都有完整的自然语义。

比如下面代码中,我们把“光光和东东”的故事按情节发展分成了 7 个 Document 片段,每个片段都有独立的主题。

四、实战!手把手搭建一个极简 RAG 系统

说了这么多理论,不如直接看代码来得痛快。下面我们使用LangChainOpenAI API(或兼容接口),基于我们准备的光光和东东的故事,搭建一个最简 RAG。

环境准备

import 'dotenv/config'; import { ChatOpenAI, // 负责生成回答的大模型 OpenAIEmbeddings, // 负责向量化的嵌入模型 } from 'langchain/openai'; import { Document } from 'langchain/core/documents';

第一步:初始化模型

这里同时初始化了两种模型:一种是负责“说话”的ChatOpenAI,一种是负责“理解语义”的OpenAIEmbeddings

// 1. 生成模型:负责根据背景知识回答问题 const model = new ChatOpenAI({ temperature: 0, // 温度设为 0,让回答更保守、准确 model: process.env.MODEL_NAME, apiKey: process.env.OPENAI_API_KEY, configuration: { baseURL: process.env.OPENAI_BASE_URL, } }); // 2. 嵌入模型:负责将文本变成向量(价格比生成模型便宜很多) const embeddings = new OpenAIEmbeddings({ apiKey: process.env.OPENAI_API_KEY, model: process.env.EMBEDDING_MODEL_NAME, configuration: { baseURL: process.env.OPENAI_BASE_URL, } });

第二步:构建知识库(Document 列表)

这里我们把光光和东东的故事拆分成带有元数据(Metadata)的 Document。元数据虽然不参与向量计算,但非常有用,可以用来过滤或溯源。

const documents = [ new Document({ pageContent: `光光是一个活泼开朗的小男孩...(略)`, metadata: { chapter: 1, character: "光光", type: "角色介绍" }, }), // ... 其余 6 个 Document ];

第三步:向量化存储与检索(最核心逻辑)

以下代码是本次实战的灵魂所在。我们创建一个内存向量存储(MemoryVectorStore),将文档向量化。当用户提问时,自动检索最相关的文档片段。

import { MemoryVectorStore } from 'langchain/vectorstores/memory'; // 1. 创建向量存储:把 documents 通过 embeddings 模型向量化并存入内存 const vectorStore = await MemoryVectorStore.fromDocuments(documents, embeddings); // 2. 用户提问 const query = "光光和东东是怎么成为朋友的?"; // 3. 语义检索:把 query 也向量化,去数据库中找最相似的文档 // 这里的 2 表示返回最相关的 2 个片段 const relevantDocs = await vectorStore.similaritySearch(query, 2); // 看看我们检索到了啥 console.log("检索到的相关片段:"); relevantDocs.forEach((doc, index) => { console.log(`\n片段 ${index + 1}:`); console.log(`内容:${doc.pageContent}`); console.log(`来源:第 ${doc.metadata.chapter} 章`); });

执行后你会发现,即使问题里没有直接提到“足球比赛”等关键词,向量检索依然能精准定位到描述他们相识和共同训练的那几个片段(第 2、3 章),这就是语义搜索的强大之处。

第四步:增强生成

拿到检索到的文档后,我们把它们拼接进 Prompt,再让大模型回答。

// 4. 构建增强 Prompt const context = relevantDocs.map(doc => doc.pageContent).join('\n'); const prompt = ` 请根据以下参考资料回答用户的问题。 如果参考资料中没有相关答案,请坦诚地告诉用户你不知道。 参考资料: ${context} 用户问题:${query} 请基于参考资料给出准确、详细的回答: `; // 5. 调用大模型生成最终答案 const response = await model.invoke(prompt); console.log(`\n最终回答:\n${response.content}`);

运行结果预期

最终大模型会基于参考资料回答,而不是瞎编。它会告诉你:光光和东东是在幼儿园认识的,性格互补,通过一次足球比赛的经历,光光帮助东东练习,最终他们一起赢得了比赛,友谊变得更加深厚。

有没有发现?如果没有 RAG,大模型是不知道“光光和东东”这两个人物的。有了 RAG,它就成了这个故事的专家。

五、总结与避坑指南

  1. RAG 的核心在于“开卷”:它完美解决了 LLM 无法获取私有数据或实时数据的问题,是现阶段落地企业应用的最佳方案之一。
  2. 分片是门手艺活:分片太大,检索不精准;分片太小,上下文不完整。一般建议按段落切分,或在代码中通过RecursiveCharacterTextSplitter设置chunk_sizechunk_overlap(重叠部分)来保证语义连贯。
  3. 模型各司其职生成模型(贵)负责推理回答,嵌入模型(便宜)负责检索。它们分工明确,千万不要用生成模型去做向量化,浪费资源。
  4. 检索质量决定回答质量:如果向量检索没把相关文档找回来,大模型再厉害也无能为力。这就是经典的“Garbage in, Garbage out”

最后送大家一句话:在未来,大模型的能力会越来越趋同,而真正决定应用上限的,是你如何驾驭和利用外部知识的能力。希望这篇实战文章能帮你迈出坚实的第一步。

http://www.cnnetsun.cn/news/3376133.html

相关文章:

  • 2026年学安全运营,不会用AI辅助等于自带 handicap
  • C++变量与类型深度解析:从内存布局到高性能编程实践
  • 【小程序计算机毕业设计案例】 基于 Android 和 Java 的智能住宿管理系统的设计与实现酒店数据统计系统的设计与实现(程序+文档+讲解+定制)
  • OpenClaw技能库解析:GitHub热门AI助手生态与自动化实践
  • 多通道数据采集模块中136路模拟通道的配置架构与通道管理技术分析
  • JCMsuite应用:闪耀光栅
  • 基于YOLOv8的工地安全检测系统:从数据标注到部署实战
  • Windows系统盘清理指南:安全释放C盘空间,无需第三方工具
  • 如何快速批量下载抖音内容:开源工具实战指南
  • Agent配置总报“context overflow”?20年SRE手把手拆解Dify上下文管理引擎与token分配黄金公式
  • ChatGPT造数≠随便造!12个行业真实案例告诉你:哪些字段绝对不能交给AI生成,否则引发线上资损
  • LLM 长上下文的工程陷阱:百万 Token 窗口不是白给的
  • 想彻底掌控你的Mac键盘吗?让Karabiner-Elements成为你的键盘魔法师
  • 3分钟快速解锁百度网盘SVIP:macOS破解插件完整指南
  • bkill 批量操作实战:从手动到脚本的集群作业管理进阶
  • 智能媒体同步器深度解析:MultiFunPlayer的多设备联动实战指南
  • Omi开源AI可穿戴:构建你的第二大脑完整指南
  • 终极指南:使用Whisky在Apple Silicon Mac上无缝运行Windows应用和游戏
  • 用AI多智能体打造你的专属股票分析平台:TradingAgents-CN新手完整指南
  • 今天不配置这5个关键约束条件,你的ChatGPT健身计划正在悄悄损伤膝关节——运动生物力学权威预警
  • VisualCppRedist AIO:Windows系统DLL错误的终极解决方案
  • 如何3分钟搞定APA第七版参考文献?免费工具让你效率提升80%
  • 微信聊天记录如何永久保存?WeChatMsg终极免费导出教程
  • (六)卡尔曼滤波(KALMAN):从理论推导到代码实现的完整闭环
  • Boogu-Image-0.1-Base-4bit快速入门:5分钟搭建你的第一个AI图像生成环境
  • Snap Hutao:从零到精通的Windows原神工具箱实战指南
  • BiliTools:免费B站视频下载与AI智能总结终极指南
  • Windows系统优化新方案:探索Win11Debloat的模块化定制能力
  • 电商行业常用:电商账单下载机器人——技术演进、合规挑战与主流方案测评
  • 如何快速掌握Linux硬件检测:CPU-X的完整专业指南