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

【RAG 详解:让模型学会“查资料”】

【LangChain】本文主要是我在学习 LangChain 过程中的一些理解总结,偏入门和认知梳理。

    • 一、问题:模型如何获取“它不知道的信息”?
    • 二、RAG 是什么?
    • 三、RAG 的完整流程
    • 四、Embedding(向量化)
    • 五、向量数据库
    • 六、RAG 中的 Prompt
    • 七、用 LangChain 实现 RAG
      • 1. 加载文档
      • 2. 切分文本(按 Token 数切分,保持语义完整性)
      • 3. 定义嵌入模型
      • 4. 配置 Redis 向量存储
      • 5. 将文档存入向量库(离线阶段完成)
      • 6. 创建检索器
      • 7. 定义提示词模板
      • 8. 定义文档格式化函数
      • 9. 构建 RAG 链
      • 10. 结果演示
    • 八、RAG 的本质
    • 九、小结

上一篇: LangChain 核心组件梳理:从模块到流程

一、问题:模型如何获取“它不知道的信息”?

在上一篇中,我们已经了解了:

LangChain 可以将 AI 任务拆解为多个步骤,将组件链接起来并组织成完整流程。

但还有一个关键问题没有解决:

模型如何获取“它不知道的信息”?

比如:

  • 本地文档

  • 企业知识库

  • 实时数据


LLM的训练数据有截止日期,它无法回答关于你公司内部流程的问题,也无法告诉你今天发生了什么。
原生 LLM 就像一个知识渊博但“与世隔绝”的专家——它的知识停留在训练完成的那一刻。

举个例子:假设你问 ChatGPT:“我们公司今年的年假政策是什么?”它会礼貌地告诉你它不知道,或者更糟——编造一个听起来合理但完全错误的答案(这就是“幻觉”)。因为它从未见过你们公司的内部员工手册。

这就引出了本文的核心内容:

RAG(检索增强生成)


二、RAG 是什么?

RAG = 检索(Retrieval) + 生成(Generation)

核心流程:

用户提问 → 检索相关内容 → 作为上下文输入模型 → 生成答案

举个例子:想象你在写一篇论文。

纯 LLM 模式:你不查任何资料,全凭记忆写。写到后面可能记错了某个年份,或者漏掉了重要观点。

RAG 模式:你先去图书馆,找到几本最相关的参考书,把关键段落复印下来,摊在桌上。然后你一边看这些资料,一边写论文。这样写出来的内容准确、有据可查。


本质变化:

以前:
模型“凭记忆回答”——容易产生幻觉,信息陈旧

现在:
模型“查资料再回答”——基于实时、可信的参考资料

这就像给模型配备了一个专属图书管理员:每次提问时,管理员先去资料库里找到最相关的几页内容,递到模型面前,模型再据此作答。

三、RAG 的完整流程

RAG 通常分为两个阶段,理解这个流程是掌握 RAG 的关键。

  1. 离线数据准备阶段

    加载文档 → 切分文本 → 向量化 → 存入向量数据库

这个阶段的目标是:把私有知识库“翻译”成模型能检索的形式。


举个例子:假设你要把一本 300 页的《公司员工手册》变成 RAG 知识库。

  • 加载文档:把 PDF 文件读进来。

  • 切分文本:300 页太长,一次塞给模型它看不过来(上下文窗口有限)。所以要把它切成一段一段,比如每段约 200 个 Token,像把一本大书剪成一张张卡片。

  • 向量化:把每张“卡片”上的文字转换成一串数字(向量),让计算机能“理解”它的含义。

  • 存入向量数据库:把所有卡片和它们的数字指纹(向量)存进一个专门用来快速搜索的仓库。

  1. 在线检索阶段

    用户提问 → 问题向量化 → 相似度检索 → 获取相关内容 → 组装 Prompt → 生成答案

这个阶段的目标是:根据用户问题,找到最相关的资料,让模型据此回答。


继续上面的例子:现在有员工问:“年假怎么申请?”

  • 系统把“年假怎么申请?”也转换成一串数字(向量)。

  • 在向量仓库里找哪些卡片上的向量和这个问题向量最“接近”。

  • 找到最相似的那几张卡片——上面写的恰好就是年假政策的内容。

  • 把这些卡片内容和问题一起打包,告诉模型:“嘿,参考这些资料来回答用户的问题。”

  • 模型看完资料,给出准确答案:“您可以在 OA 系统中提交年假申请,每年享有 10 天年假……”


我们可以理解为:

“先建索引,再查询”——和搜索引擎的原理异曲同工。

下面这张图清晰地展示了完整流程:

四、Embedding(向量化)

1.什么是Embedding?

Embedding 的核心思想是:把人类语言的“语义”转换为计算机能计算的“数字”。

举个例子:

“我喜欢猫” → [0.12, 0.98, -0.34, …]
这个数字列表就是向量,它的维度通常是固定的(比如 OpenAI 的 text-embedding-3-large 模型生成 3072 维向量)

一个形象的理解方式:想象你要向一个外星人描述各种动物的特征。外星人不认识文字,只懂数字。于是你发明了一套编码系统:

“毛茸茸” → +0.8

“会喵喵叫” → +0.9

“喜欢抓老鼠” → +0.7

“汪汪叫” → -0.8

那么“猫”的描述可能就接近 [0.8, 0.9, 0.7, -0.8],而“狗”的描述则是 [0.7, -0.9, -0.5, 0.9]。

Embedding 模型做的事情更复杂、更精确,但原理是一样的——用数字来代表含义。

2.为什么需要?
->用于计算语义相似度

在向量空间中,含义相近的文本,其向量也彼此接近。我们可以用余弦相似度来度量两个向量的“方向一致性”——方向越一致,语义越相似。

实验一下:

“猫是一种可爱的宠物” → 向量 A

“狗是人类忠实的朋友” → 向量 B

“今天天气真好” → 向量 C

计算相似度你会发现:A 和 B 的相似度较高(都是关于宠物的),而它们和 C 的相似度都很低。这就是向量检索的基础。

理解
把“语义相似”变成“向量接近”

这使得计算机可以用数学方法完成“找意思相近的内容”这种原本只有人类才能做的事。

五、向量数据库

1.作用

存储向量,并支持高效的相似度搜索。

一篇文档转换成一个 1536 维的向量,一百万篇文档就是约 1.5GB 的纯向量数据。如何在海量向量中快速找到与查询最相似的几条?这就是向量数据库的专长。


传统数据库 vs 向量数据库
用一个找电影的例子来理解:

传统数据库(如 MySQL):

你输入:SELECT * FROM movies WHERE title LIKE '%爱情%'

它返回:所有标题里包含“爱情”两个字的电影。

问题来了:《泰坦尼克号》标题里没有“爱情”,但它确实是一部爱情片,传统数据库找不到它。


向量数据库:

你把《泰坦尼克号》的剧情简介转换成向量存进去。

你输入:“推荐一些感人的爱情电影” → 转换成向量

向量数据库计算发现,《泰坦尼克号》的剧情向量和你的查询向量方向很接近,于是把它推荐给你——哪怕标题里压根没有“爱情”二字
将两者比较:

对比维度传统数据库向量数据库
匹配方式关键词精确匹配语义相似匹配
查询示例WHERE name = '苹果'“一种红色的水果”也能找到“苹果”相关文档
语义理解能力不懂“含义”,仅做字面匹配理解“语义”,可基于上下文和意图检索
典型工具 / 集成MySQL、PostgreSQL 等关系型数据库Chroma、Redis(RediSearch)、Pinecone、Milvus 等(LangChain 均支持集成)

我们可以理解为:

向量数据库是一个“按语义搜索”的数据库

六、RAG 中的 Prompt

1.问题:

模型本身并不知道:

哪部分是用户的问题

哪部分是我们提供的参考资料

应该基于什么来回答

所以我们需要用 Prompt 明确告诉模型


错误的 Prompt 写法(没有区分角色):

数据库表怎么设计的?
(后面跟着一大堆检索出来的文档内容)
模型会困惑:“我是应该直接回答数据库设计的问题,还是总结这些资料?”结果可能是它忽略了资料,凭自己的知识回答,完全丧失了 RAG 的意义。


正确的 Prompt 写法:

根据以下检索到的上下文片段来回答问题。
如果你不知道答案,就说你不知道。
最多只用三句话,回答要简明扼要。

问题:{question}
上下文:{context}

答案:{anwer}


这样模型就清楚了用户的需求:

角色(Role):我是一个基于资料回答的助手

输入(Intput):问题是 X,参考资料是 Y

输出要求( Limit):简明扼要,不超过三句,不知道就说不知道

  1. 本质:

让模型“基于资料回答”,而不是自己发挥。

这种 Prompt 设计是 RAG 效果的关键——既要让模型充分参考上下文,又要约束它不胡编乱造。

七、用 LangChain 实现 RAG

我们用 LangChain 的组件来完整实现一个 RAG 流程。

步骤:

加载文档 → 切分文本 → 向量化存储 → 创建检索器 → 构建 RAG 链 → 生成答案

我们可以看段实现 RAG的完整代码:

fromlangchain_openaiimportOpenAIEmbeddings,ChatOpenAIfromlangchain_redisimportRedisConfig,RedisVectorStorefromlangchain_core.output_parsersimportStrOutputParserfromlangchain_core.promptsimportChatPromptTemplatefromlangchain_core.runnablesimportRunnablePassthroughfromlangchain_community.document_loadersimportUnstructuredMarkdownLoaderfromlangchain_text_splittersimportCharacterTextSplitter

1. 加载文档

#UnstructuredMarkdownLoader 专门用于MD文档#PDF文档可用 PyPDFLoaderloader=UnstructuredMarkdownLoader("./knowledge.md")data=loader.load()

2. 切分文本(按 Token 数切分,保持语义完整性)

# ⽣成分割器text_splitter=CharacterTextSplitter.from_tiktoken_encoder(encoding_name="cl100k_base",#cl100k_base 是一种默认的编码格式chunk_size=200,#块大小chunk_overlap=50#块与块之间的重叠长度)documents=text_splitter.split_documents(data)

3. 定义嵌入模型

我们可以直接在LangChain官网搜索我们需要的嵌入模型以及如何安装和使用(需要魔法)

#这里使用OpenAi的text-embedding-3-largeembeddings=OpenAIEmbeddings(model="text-embedding-3-large")

4. 配置 Redis 向量存储

# Redis向量存储相关配置config=RedisConfig(index_name="my_knowledge_base",redis_url="redis://localhost:6666",)vector_store=RedisVectorStore(embeddings,config=config)

5. 将文档存入向量库(离线阶段完成)

vector_store.add_documents(documents)

6. 创建检索器

#通过调⽤向量数据库的as_retriever ⽅法,将向量存储⽤作检索器retriever=vector_store.as_retriever(search_kwargs={"k":4})

7. 定义提示词模板

# 提示词模板prompt=ChatPromptTemplate.from_messages([("human","""根据以下上下文回答问题。如果你不知道答案,就说不知道。 问题:{question} 上下文:{context} 答案:""")])

8. 定义文档格式化函数

#将检索到的文档转化成文本传递给提示词模板defformat_docs(docs):return"\n\n".join(doc.page_contentfordocindocs)

9. 构建 RAG 链

#自己尝试可以使用国产的千问,配置好apikey#model =ChatTongyi(model="qwen-turbo")model=ChatOpenAI(model="gpt-4o-mini")chain=(# 检索器+format_docs 分支1# question 分支2:RunnablePassthrough()在链中透传数据{"context":retriever|format_docs,"question":RunnablePassthrough()}|prompt|model|StrOutputParser())

10. 结果演示

forchunkinchain.stream("数据库表怎么设计的?"):print(chunk,end="",flush=True)

运行效果示例:
假设你的 knowledge.md 文档中有这样一段内容:

数据库表设计遵循第三范式,主要分为用户表、订单表、商品表。用户表包含用户ID、姓名、注册时间等字段。订单表通过用户ID与用户表关联,商品表通过商品ID与订单表关联。 当你运行代码并提问“数据库表怎么设计的?”时,系统会: 检索出上述这段最相关的内容 将其作为上下文喂给 LLM 模型据此生成答案,比如: 数据库设计采用第三范式,主要包含用户表(存储用户基本信息)、 订单表(记录订单数据,通过用户ID关联用户表)和商品表通过商品ID关联订单表)。

八、RAG 的本质

RAG = 模型能力 + 外部知识

我们也可以理解为:

RAG 并没有提升模型“智商”,它只是:让模型“看资料再回答”


举个例子,期末考试分开闭卷:

纯 LLM:一个闭卷考试的学生,只能靠记忆答题。

RAG:一个开卷考试的学生,可以翻书找答案。

显然,对于需要精确、实时、私有知识的问题,开卷考试的成绩会好得多


九、小结

从上文我们可以了解到RAG的总流程:

问题 → 检索 → 上下文 → 生成

这是一个“最小可运行 RAG Demo”,实际生产中还需要考虑缓存、召回优化、重排序等问题。

还有RAG 的优势:

  • 减少幻觉:答案有据可查,不再凭空编造

  • 支持私有数据:企业文档、个人笔记都可以成为知识源

  • 提高准确性:基于实时、相关的信息作答


LangChain 为 RAG 提供了完整的组件支持:

组件 作用
Document Loaders ——>加载多种格式的文档
Text Splitters——>将长文档切分为语义完整的块
Embeddings——>将文本转换为向量
Vector Stores——>存储向量并支持相似度检索
Retrievers——>统一的检索接口

今天的分享就到这里,下章再会~

http://www.jsqmd.com/news/662379/

相关文章:

  • 基于诺伊(RuoYi)管理后台开发框架的前后端分离单体架构与Java分层架构开发规范
  • 【艺术家紧急自救手册】:2026奇点大会实证——AGI接管创意流程的7个高危节点及防御策略
  • 编译型与解释型语言
  • 3个必装功能!英雄联盟玩家效率翻倍的本地化工具完全指南
  • 2026自考培训口碑机构大比拼,哪家更胜一筹?国家开放大学招生/学历提升/成人学历提升/专升本报名,自考培训学校推荐 - 品牌推荐师
  • 宿舍党福音:用旧小米路由器3搞定SCUT校园网多设备连接(附编译好的固件)
  • 【STM32】实战3.2—基于TB6600与微步进控制实现42步进电机的平滑驱动
  • 告别Keil:基于VSCode+ARM-GCC+OpenOCD的STM32一站式开发环境实战
  • Pixel Epic智识终端应用:智能硬件产品技术白皮书AI协同编写流程
  • 嵌入式设备上的轻量化Pixel Script Temple部署与实践
  • 2026年3月,热门洗涤设备直销厂家优选推荐来了,医院洗涤设备/洗涤设备/洗涤设备全套,洗涤设备实力厂家有哪些 - 品牌推荐师
  • 如何部署OpenClaw?2026年4月云端大模型Coding Plan配置步骤
  • abinit学习日记三十——tbs_5.abi
  • 【紧急预警】当前92%的AGI验证方案存在逻辑断层!资深审评官亲授4步闭环验证法
  • 【数字IC】从UART协议到Verilog实现:一个IC工程师的实践指南
  • abinit学习日记二十九——tbs_4.abi
  • 从TLS握手到威胁狩猎:实战解析JA3/JA3S指纹的攻防应用
  • 从CrossEntropyLoss倒推理解:为什么PyTorch里常用F.log_softmax?
  • 2026年选高温熔盐泵,教你选液下熔盐泵实力厂家,高效节能叠片同步自吸泵/透平自吸泵,高温熔盐泵实力厂家有哪些 - 品牌推荐师
  • 2026年3月正规的壁灯工厂推荐,景观灯照明/100w工矿灯/led户外灯具/外墙景观灯/室外照明灯具,壁灯厂家找哪家 - 品牌推荐师
  • 如何在ComfyUI中实现专业级动画效果:MTB Nodes完全指南
  • Qwen3-14B开源可部署实证:MIT许可证下商用无忧,模型权重自主可控
  • Gemini电脑版下载(gemini电脑下载)
  • 动态时间规整DTW:跨越时间轴的相似度度量实战
  • 2026年3月评价高的MBR平板膜实力厂家怎么选购,进口MBR平板膜/酸碱废气处理设备,MBR平板膜供应厂家怎么选购 - 品牌推荐师
  • 智能缝纫机与无人缝纫生产线行业研究报告 -以泉州誉财自动化为例
  • 如何免费掌握AMD Ryzen处理器调试:SMUDebugTool完整入门指南
  • 各位爱因斯坦,小白想知道:
  • 2026年3月高低温试验箱公司找哪家,冷热冲击试验箱/恒温恒湿试验箱/三综合试验箱/高低温试验箱,高低温试验箱产品有哪些 - 品牌推荐师
  • Wan2.1-umt5多轮对话效果实录:复杂任务分解与上下文连贯性展示