RAG01-RAG08课程笔记
2026/8/22 17:50:09 网站建设 项目流程

RAG 开发‑01 LangChain 简介 笔记

1. LangChain 基础介绍

  • 诞生:由 Harrison Chase 于2022 年 10 月创建
  • 定位:围绕大语言模型 LLM 构建的 Python 第三方开发框架
  • 关键点:LangChain 本身不开发大模型
  • 核心理念:
    1. 为各式各样 LLM 提供统一通用接口
    2. 将 LLM 相关各类组件 “链接” 串联起来
    3. 降低复杂 LLM 应用的开发难度,快速搭建 LLM 业务应用
  • 地位:做 RAG 检索增强生成的主力开发框架

2. LangChain 六大核心模块

表格

模块作用
Prompts提示词优化,提示词工程(模板、Few‑Shot 等)
Models统一调用各类大模型(通义千问、GPT、本地 Ollama 等)
History会话记忆,管理聊天历史记录,实现多轮对话
Indexes文档索引,文档加载、切分、向量化、文档分析管理,RAG 核心模块
Chains执行链,把多个组件拼接串联,按流水线顺序执行业务逻辑
Agent智能体,让大模型自主思考、调用工具、完成复杂任务

3. 总结

  1. LangChain 是 LLM 业务开发的集大成 Python 库,提供全套开箱即用 API。
  2. 覆盖能力:提示词工程、模型调用、会话记忆、文档处理、链式执行、Agent 智能体。
  3. 学习路径:后续 RAG 开发全部基于 LangChain 框架完成。

通俗理解

不用 LangChain:自己手写代码处理提示词、文档分割、向量库调用、拼接消息,全部从零写。 使用 LangChain:直接调用封装好的 API,把各个组件 “拼接链接”,快速实现 RAG、聊天机器人、智能体。

RAG 开发‑02 LangChain 的环境部署 笔记

1、需要安装的包

安装命令(推荐使用清华镜像源,下载更快)

bash

pip install langchain langchain-community langchain-ollama dashscope chromadb -i https://pypi.tuna.tsinghua.edu.cn/simple

表格

包名作用
langchainLangChain 核心包,基础能力
langchain‑community社区扩展包;对接阿里云通义千问等第三方模型需要该包
langchain‑ollamaOllama 对接包,调用本地 Ollama 部署大模型
dashscope阿里云通义千问官方 Python SDK
chromadb轻量级本地向量数据库,RAG 用来存储向量

2、安装校验

  1. 命令行输入python进入 python 交互环境
  2. 执行导入:

python

运行

import langchain

没有报错代表环境安装成功。

3、常见小提示

  1. 镜像源-i https://pypi.tuna.tsinghua.edu.cn/simple,解决国内 pip 下载慢、超时问题。
  2. 建议使用虚拟环境,防止包版本冲突。
  3. 版本:课程使用langchain‑1.2.1langchain‑community‑0.4.1
  4. 导入不报错不等于全部功能可用,后续用到对应模块缺包时再补装。

RAG 介绍 课程笔记

一、什么是 RAG

RAG(Retrieval‑Augmented Generation)检索增强生成公式:RAG = 检索技术 + LLM 提示

含义:从外部数据源检索相关信息,补充给大模型,修正、完善模型回答。

二、原生大模型存在 4 大痛点

  1. 知识滞后:模型训练完成后知识固定,不会自动更新
  2. 领域知识不足:训练数据多为公开互联网数据,缺少企业内部、专业私有知识
  3. 幻觉问题:输出看起来合理、实际错误的编造内容
  4. 数据安全:私有内部数据不能直接喂给公有大模型

✅ RAG 对应的解决能力:

  • 加载私有 / 领域知识库
  • 支持实时最新文档
  • 减少幻觉,降低生成不确定性
  • 提升数据安全性

对比微调 Fine‑tuning:RAG不需要重训模型,只更新知识库,成本更低、迭代更快。

三、RAG 两条工作主线

  1. 离线准备线(索引 Indexing,知识库预处理):提前执行,一次处理多次使用文档/私有知识加载 → 文本分割(chunk) → 向量化(Embedding) → 存入向量数据库

  2. 在线服务线(检索 + 生成,用户提问时实时跑):用户每一次问答都会走用户提问 → 检索环节 → Prompt融合(问题+检索到的上下文) → LLM生成回答

四、RAG 三大标准阶段

1. 索引阶段 Indexing(离线)

  1. 加载各类文档文件
  2. 提取文档文本内容
  3. 文本切分,生成文本块chunk
  4. 对 chunk 做 Embedding 文本向量化
  5. 将向量 + 原始文本存入向量数据库

2. 检索阶段 Retriever(在线)

  1. 用户问题query做向量化
  2. 在向量库做相似度匹配,取出最相似的top_k个文本块

3. 生成阶段 Generation(在线)

  1. 把检索出来的上下文片段 + 用户原始问题,拼接组装到 Prompt
  2. 将完整 Prompt 交给大模型,输出答案

五、核心本质

大模型本质只做:输入→输出。RAG 的本质:在输入大模型之前做加工,把检索拿到的参考资料塞到 prompt 输入里,不给模型凭空记忆的机会。

六、RAG 核心价值

  1. 解决知识时效性:接入最新文档,不用重训模型,回答与时俱进
  2. 降低大模型幻觉:回答依托检索到的真实资料,减少编造
  3. 成本优于微调:更新知识只改知识库,不用训练权重,效率高
  4. 支持私有内部知识库,保护业务数据

面试简答版(可以背)

RAG 分为离线索引、在线检索、生成三个阶段。离线把文档加载、切分、向量化存入向量库;用户提问时,问题向量化检索相似片段,把片段和问题一起封装进 Prompt 交给 LLM 输出。主要解决大模型知识过时、领域知识缺失、幻觉问题,对比微调不需要训练模型,成本更低。

RAG 开发‑04 向量的基础概念笔记

一、向量库在 RAG 中的位置

RAG 分为离线流程(索引)在线流程(检索 + 生成)两大阶段,向量库是核心存储节点。

  1. 离线流程(索引阶段)知识 / 文档信息 → 向量嵌入(向量化) → 存入向量库

文档处理链路:知识库 (书籍 / 文档 / 报告) → 提取文本字符串 → 切分 chunk 文本块 → 向量嵌入 → 写入向量库

  1. 在线流程(检索 + 生成阶段)用户提问 → 向量嵌入(向量化) → 向量库做相似度匹配

用户问题链路:用户输入问题 → 向量化得到问题向量 → 和向量库内向量做相似匹配,召回 Top‑K 相关文本块 → 把原始问题 + 召回参考片段组装成 Prompt → 交给大模型 LLM 输出最终回答。

二、向量 (Vector) 是什么

向量:文本的数学身份证把一段文本的语义信息,转换成一串固定长度数字列表,让计算机可以读懂语义,做相似度计算。

  • 作用:让计算机判断两段文字是不是同一个意思,不看字面,看语义。
  • 示例:
    • “如何快速学习 RAG”
    • “RAG 如何快速学会” 两句话字面不一样,语义一致,生成出来的向量数字序列很接近。

三、向量嵌入(生成向量)

  1. 向量嵌入:文本→向量的转换过程依靠文本嵌入模型完成,例:text‑embedding‑v1

原理:深度学习模型,抽取文本语义特征,输出固定长度数字序列。

四、向量相似度计算:余弦相似度

拿到两段文本的向量,使用余弦相似度算法,计算语义相似程度。

  • 相似度取值范围:0~1,越接近 1 代表语义越相似。 例子:
  • A:如何快速学打篮球 → [0.2,0.5,0.8]
  • B:打篮球怎么学得快 → [0.18,0.52,0.79]
  • C:运动后吃什么好呢 → [0.9,0.1,0.2] 计算结果:
  • A 与 B 相似度:0.999789(语义高度接近)
  • A 与 C 相似度:0.361446(语义不相关)

五、向量维度

向量维度:代表描述文本的抽象语义特征数量,每一维数字代表文本在该语义特征上的得分 / 强度。 举例:

  • 3 维向量:情绪、动作、倾向 3 个特征
  • 1536 维向量 (text‑embedding‑v1 输出):1536 个抽象语义特征

维度权衡

  1. ✅维度越高:保存语义信息越丰富,语义匹配精度越高
  2. ❌维度越高:存储、计算、检索开销变大,性能压力上升

工程选择:精度和性能之间做权衡,1536 维是工业常用选择

六、核心知识点总结

  1. 向量:文本语义转为固定长度数字数组,计算机用来做语义比对。
  2. 向量生成(嵌入):文本嵌入模型(text‑embedding‑v1)。
  3. 向量比对:余弦相似度算法,数值越靠近 1 语义越像。
  4. 向量维度:语义特征数量;维度↑精度↑,存储计算开销↑;1536 维常用。
  5. RAG 完整链路:文档加载→切分 chunk→embedding 向量化→入库;用户 query 向量化→向量库相似度检索召回→拼接 prompt→LLM 生成答案。

⭐面试简答版(方便背诵)

问:什么是文本向量 /embedding? 答:文本向量是文本的数学身份证,通过嵌入模型把文本语义转为定长数字列表。语义相近文本向量数值接近,我们使用余弦相似度计算向量相似度。向量维度代表语义特征数量,维度越高语义表达越强,但存储计算成本上升。在 RAG 中,文档切分 chunk 后转向量存入向量库;用户查询也转向量,检索召回语义相关片段,辅助大模型回答。

余弦相似度 课程笔记

一、概念

余弦相似度:忽略向量长度,只看向量在高维空间的方向夹角,夹角越小,向量越相似。

RAG 场景:文本会转为向量,余弦相似度用来判断两段文本语义是否相近。

  • 值范围:[-1,1]
    • 1:方向完全相同(最相似)
    • 0:方向垂直,完全无关
    • -1:方向完全相反

二、公式

\(cosine\ similarity(\vec A,\vec B)=\frac{\vec A \cdot \vec B}{||\vec A|| \times ||\vec B||}\)

  1. 点积(分子):两个向量同维度相乘,全部累加

\(dot = A_0*B_0 + A_1*B_1 + ...+A_n*B_n\) 2.模长(分母部分):单个向量每个维度平方求和,再开根号

\(||vec||=\sqrt{vec_0^2+vec_1^2+...+vec_n^2}\) 3. 余弦相似度 = 点积 ÷ (向量 A 模长 × 向量 B 模长)

示例

向量 A=[0.5,0.5],向量 B=[0.7,0.7]

  • 点积 =0.5*0.7 + 0.5*0.7 = 0.7
  • A 模长 = \(\sqrt{0.5^2+0.5^2}\)
  • B 模长 = \(\sqrt{0.7^2+0.7^2}\)
  • 余弦相似度 = \(0.7 \div (\sqrt{0.5^2+0.5^2} * \sqrt{0.7^2+0.7^2}) = 1.0\),代表方向完全一致。

三、RAG 中的意义

文本 Embedding 之后得到向量,余弦相似度用来做向量检索,找出知识库中和用户问题语义最接近的片段。只关心语义方向,不关心向量的长度大小。

四、完整可运行代码

python

运行

import numpy as np def get_dot(vec_a, vec_b): """计算2个向量的点积,2个向量同维度数字乘积之和""" if len(vec_a) != len(vec_b): raise ValueError("2个向量必须维度数量相同") dot_sum = 0 for a, b in zip(vec_a, vec_b): dot_sum += a * b return dot_sum def get_norm(vec): """计算单个向量的模长:对向量的每个数字求平方在求和在开根号""" sum_square = 0 for v in vec: sum_square += v * v # numpy sqrt函数完成开根号 return np.sqrt(sum_square) def cosine_similarity(vec_a, vec_b): """余弦相似度:2个向量的点积 除以 2个向量模长的乘积""" result = get_dot(vec_a, vec_b) / (get_norm(vec_a) * get_norm(vec_b)) return result if __name__ == '__main__': vec_a = [0.5, 0.5] vec_b = [0.7, 0.7] vec_c = [0.7, 0.5] vec_d = [-0.6, -0.5] print("ab:", cosine_similarity(vec_a, vec_b)) print("ac:", cosine_similarity(vec_a, vec_c)) print("ad:", cosine_similarity(vec_a, vec_d))

运行输出

plaintext

ab: 0.9999999999999999 ac: 0.9863939238321437 ad: -0.9961537343407902

ab 输出接近 1,代表向量 A 和 B 同向;ad 接近‑1 代表方向几乎相反。

易错坑点

代码中括号不能写错:

python

运行

# ❌错误写法,运算优先级出错 result = get_dot(vec_a, vec_b) / get_norm(vec_a) * get_norm(vec_b) # ✅正确写法,分母是两个模长相乘,必须括号包裹 result = get_dot(vec_a, vec_b) / (get_norm(vec_a) * get_norm(vec_b))

RAG 开发‑06 LangChain 调用大语言模型 笔记

⭐星级:★★★ 分值:10 分

一、LangChain 三类模型

LangChain 提供统一接口,支持 3 大类模型:

  1. LLMs(大语言模型)Transformer 架构,大参数量,面向文本生成;输入字符串,输出字符串。

注意:qwen‑max属于 LLM;qwen3‑max属于 ChatModel 聊天模型,不要混用。

  1. Chat Models(聊天模型)在 LLM 基础上专门优化对话轮次交互,面向聊天对话场景。

  2. Embeddings Models(嵌入模型)接收文本输入,输出文本向量,用于 RAG 检索。

第三方模型实现大多放在langchain_community包。 Ollama 本地模型:独立包langchain_ollama

二、两个模型源下载地址

  • HuggingFace:https://huggingface.co/models
  • ModelScope 魔搭:https://modelscope.cn/models

三、核心 API

  • model.invoke(input="你的问题"):同步调用模型,传入字符串 prompt,返回模型生成文本。

四、可运行完整代码

1)调用阿里云通义千问 LLM(qwen‑max)

前置:安装依赖pip install langchain‑community dashscope环境变量配置:DASHSCOPE_API_KEY阿里云 API‑KEY

python

运行

# 02LangChain访问阿里云通义千问大模型.py from langchain_community.llms.tongyi import Tongyi # 实例化LLM对象,qwen‑max是大语言模型,不要传qwen3‑max(聊天模型) model = Tongyi(model="qwen-max") # invoke方法发起提问 res = model.invoke(input="你是谁呀能做什么?") # 打印结果 print(res)

2)调用 Ollama 本地 LLM(qwen3:4b)

前置:

  1. 安装依赖pip install langchain‑ollama
  2. 本地 Ollama 软件必须启动;执行过ollama pull qwen3:4b拉取模型

python

运行

# 03LangChain访问Ollama本地模型.py from langchain_ollama import OllamaLLM # 实例化本地Ollama模型对象 model = OllamaLLM(model="qwen3:4b") # invoke调用 res = model.invoke(input="你是谁呀能做什么?") print(res)

五、关键注意点

  1. 包来源区分
  • 通义千问 LLM:langchain_community.llms.tongyi.Tongyi
  • Ollama 本地 LLM:langchain_ollama.OllamaLLM
  1. 模型名称区分:qwen‑max:LLM 大语言模型;qwen3‑max:Chat 聊天模型,二者不能混用。
  2. Ollama 运行前提:Ollama 服务后台运行,模型已经提前 pull 下载,否则报错。
  3. 统一调用方式:实例化模型对象后,一律用.invoke(input="xxx")做推理。

面试简答记忆点

LangChain 对各种大模型做了封装,对外提供统一 invoke 接口; 云模型来自 langchain_community,Ollama 本地模型来自 langchain_ollama; LLM 输入输出都是原始字符串,ChatModel 是消息对象。

调用大模型(LangChain 视角)

调用大模型核心就两步:

  1. 创建大模型实例:指定模型、api‑key、参数,完成模型对象初始化
  2. 调用invoke()方法执行:传入输入内容,发起请求,拿到模型返回结果

代码示例

python

运行

from langchain_openai import ChatOpenAI # 第一步:创建大模型实例 llm = ChatOpenAI( model="gpt‑3.5‑turbo", api_key="你的key", temperature=0.7 ) # 第二步:invoke() 执行调用,传入prompt res = llm.invoke("讲一个简短小故事") print(res.content)

补充小知识点

  • invoke()是 LangChain 标准统一调用接口,不管是 chat 模型、普通 LLM、Chain 都用invoke()
  • 返回值不是字符串,是消息对象,需要.content取出文本结果
  • 老版本还有predict()/__call__,现在官方推荐统一使用invoke()

07 LangChain 模型的流式输出 笔记

核心知识点 ⭐⭐⭐(面试高频)

LangChain 1.0+ 基于Runnable统一接口,几乎所有组件(模型、prompt、chain、检索器)都支持下面两套方法:

  1. invoke():同步一次性调用,等待模型全部生成完毕,一次性返回完整结果
    • 优点:简单,直接拿到完整字符串
    • 缺点:用户需要等待全部生成,体验像卡住,网页聊天框不会一个字一个字蹦出来
  2. stream():流式输出,逐段返回生成内容(chunk 块),返回迭代器,可以 for 循环遍历。
    • 优点:模拟 ChatGPT 打字效果,边生成边展示,用户体感更快
    • 缺点:需要循环接收每一小段文本,代码多一层 for 循环

关键概念:chunk:模型返回的一小段碎片文本,多次 chunk 拼接起来才是完整回答。

print 参数解释

python

运行

print(chunk, end="", flush=True)
  • end="":打印不要换行,文字连续输出
  • flush=True:强制刷新缓冲区,立刻把文字打印到控制台,不要缓存攒一堆再输出

模型区分

  • qwen‑maxLLM 大语言模型,输出纯文本字符串,适合本示例
  • qwen3‑maxChat 聊天模型,返回消息对象,.content拿文本,不要混用

流程对比

  • invoke 两步:①创建模型实例 ②invoke()→拿到完整结果
  • stream 两步:①创建模型实例 ②stream()→拿到迭代器,for 循环读取每一块 chunk

注意:stream 返回的不是最终字符串,是可迭代对象,必须 for 循环遍历读取。

完整可运行代码(旧版 community,课程原版,能跑但是会有弃用警告)

python

运行

# 04LangChain的流式输出.py from langchain_community.llms.tongyi import Tongyi # 第一步:创建模型实例 model = Tongyi(model="qwen-max") # 第二步:调用stream 获取流式迭代器 res = model.stream(input="你是谁呀能做什么?") # for循环遍历迭代器,取出每一块chunk for chunk in res: print(chunk, end="", flush=True)

✨新版无警告代码(langchain‑alibaba,推荐以后写这个)

python

运行

# 先安装依赖:pip install langchain-alibaba from langchain_alibaba import Tongyi # 第一步:创建模型实例 model = Tongyi(model="qwen-max") # 第二步:stream流式调用 res = model.stream(input="你是谁呀能做什么?") # 循环打印每一个片段 for chunk in res: print(chunk, end="", flush=True)

invoke 和 stream 对照完整示例(放一起对比记忆)

python

运行

# 04LangChain的流式输出.py from langchain_community.llms.tongyi import Tongyi model = Tongyi(model="qwen-max") # -------- invoke 一次性输出 -------- print("==== invoke一次性输出 ====") result = model.invoke("简单介绍python") print(result) # -------- stream 流式打字机输出 -------- print("\n==== stream流式输出 ====") stream_res = model.stream("简单介绍python") for chunk in stream_res: print(chunk, end="", flush=True)

面试简答背诵

问:LangChain invoke 和 stream 区别? 答:

  1. invoke():一次性调用,等待模型全部生成完成,返回完整结果;适合后台脚本处理。
  2. stream():流式调用,返回迭代器,循环拿到每一段 chunk,实现边生成边输出;适合前端聊天界面,实现打字效果。
  3. 两者是 Runnable 接口的标准方法,模型、Chain、提示词模板都统一支持这两个 API。

拓展小补充(还有 batch 方法)

  • batch([问题1,问题2]):批量传入多个问题,一次性批量调用多个请求。

Runnable 三大方法:invoke(单个)、stream(流式)、batch(批量)。

08 LangChain 调用聊天模型 ChatModels 笔记

⭐⭐⭐⭐ 重点:LLM(大语言模型) vs ChatModel(聊天模型)

  1. LLM(Tongyi):输入输出都是纯字符串model="qwen‑max"
  2. ChatModel(ChatTongyi):输入输出是消息对象 Messagemodel="qwen3‑max",专门用于多轮对话,是现在开发主流。

三种消息对象(langchain_core.messages)

表格

消息类对应 OpenAI 角色作用
SystemMessagesystem系统提示,设定 AI 角色、规则、背景,放在消息列表最前面
HumanMessageuser用户发送给 AI 的问题
AIMessageassistantAI 历史返回的回答,用于多轮上下文记忆

messages 是列表,按对话顺序存放消息,实现多轮对话记忆。 ChatModel 返回的 chunk 不是字符串对象,要用.content属性拿到文本内容。

Runnable 接口同样生效

聊天模型同样支持三大方法:

  1. invoke(messages):一次性返回完整消息对象
  2. stream(messages):流式迭代返回 chunk,chunk.content拿文本
  3. batch([msg1,msg2]):批量请求

注意坑:写print(chunk)会打印对象;必须写print(chunk.content),否则输出一堆对象描述文本。

代码 1:仅 HumanMessage(单轮对话,课程原版)

文件名:05LangChain调用聊天模型.py

python

运行

# 课程原版(会有弃用警告,可以跑) from langchain_community.chat_models.tongyi import ChatTongyi from langchain_core.messages import HumanMessage # 1.初始化聊天模型 qwen3‑max是聊天模型 chat_model = ChatTongyi(model="qwen3-max") # 2.构造消息列表 messages = [ HumanMessage(content="给我写一首唐诗") ] # 3.stream流式输出 res = chat_model.stream(input=messages) for chunk in res: # .content获取文本内容 print(chunk.content, end="", flush=True)

代码 2:SystemMessage + HumanMessage(设定 AI 角色)

python

运行

from langchain_community.chat_models.tongyi import ChatTongyi from langchain_core.messages import HumanMessage, SystemMessage chat_model = ChatTongyi(model="qwen3-max") messages = [ SystemMessage(content="你是一名来自边塞的诗人"), HumanMessage(content="给我写一首唐诗") ] res = chat_model.stream(input=messages) for chunk in res: print(chunk.content, end="", flush=True)

代码 3:SystemMessage + HumanMessage + AIMessage(模拟多轮上下文)

AIMessage 用来填入 AI 历史回答,让模型参考上一轮输出格式、内容。

python

运行

from langchain_community.chat_models.tongyi import ChatTongyi from langchain_core.messages import HumanMessage, SystemMessage, AIMessage chat_model = ChatTongyi(model="qwen3-max") messages = [ SystemMessage(content="你是一名来自边塞的诗人"), HumanMessage(content="给我写一首唐诗"), AIMessage(content="锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦。"), HumanMessage(content="按照你上一个回复的格式,再写一首唐诗。") ] res = chat_model.stream(input=messages) for chunk in res: print(chunk.content, end="", flush=True)

✨新版无弃用警告代码(langchain‑alibaba,推荐工程使用)

python

运行

# pip install langchain-alibaba from langchain_alibaba import ChatTongyi from langchain_core.messages import HumanMessage, SystemMessage, AIMessage chat_model = ChatTongyi(model="qwen3-max") messages = [ SystemMessage(content="你是一名来自边塞的诗人"), HumanMessage(content="给我写一首唐诗") ] res = chat_model.stream(input=messages) for chunk in res: print(chunk.content, end="", flush=True)

invoke 完整示例(一次性返回,对比记忆)

python

运行

from langchain_alibaba import ChatTongyi from langchain_core.messages import HumanMessage chat_model = ChatTongyi(model="qwen3-max") messages = [HumanMessage(content="简单介绍LangChain")] # invoke返回完整消息对象 resp_msg = chat_model.invoke(input=messages) # .content取出字符串 print(resp_msg.content)

📝面试简答背诵

Q:LLM 和 ChatModel 有什么区别?

  1. LLM 输入输出都是普通字符串,适合简单单轮调用;
  2. ChatModel 输入输出是消息对象(SystemMessage/HumanMessage/AIMessage),天然支持多轮对话上下文;
  3. ChatModel 调用返回的结果对象,需要读取.content属性获取文本内容;
  4. ChatModel 同样遵循 Runnable 接口,支持invoke / stream / batch

易错点总结

  1. ❌错误:print(chunk),打印对象;✅正确:print(chunk.content)
  2. 区分模型:qwen‑max给 LLM;qwen3‑max给 ChatModel,不要混用。
  3. messages 是列表,顺序很重要,SystemMessage 一般放列表最前面。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询