langchain 快速入门(三):搭建RAG知识库

news/2026/1/24 16:28:07/文章来源:https://www.cnblogs.com/ClownLMe/p/19526904

简介

LLM大模型一般训练的数据都是滞后的,这是就需要用到RAG知识库,RAG知识库可以降低大模型在输出答案时的幻觉,也能够让大模型知识拓展。

知识库架构知识

检索流程图

用户输入 (User Query)|v+-----------------------+|   提示词 (Prompt)      |+-----------------------+|| (1) 转化为向量 (Embedding)v+-----------------------+|   文字向量模型 (EMB)    |+-----------------------+|| (2) 相似度检索 (Search)v+-----------------------+         +-----------------------+|  RAG 向量数据库 (DB)    | <-----> |   本地知识库/文档集     |+-----------------------+         +-----------------------+|| (3) 召回相关片段 (Context)v+-----------------------+|   大语言模型 (LLM)      | <--- (将提示词与背景片段拼接)+-----------------------+|| (4) 最终生成 (Generation)v+-----------------------+|      输出结果          |+-----------------------+

RAG原理解析

构建知识库的流程如下:
文档内容切片->文字向量化->向量数据库

文档内容切片

LLM 有上下文长度限制,且向量检索在短文本上更精确。
文本切片方法有:

  1. 按字数切片
  2. 按句切片
  3. 递归切片
    不管是哪个切片方法,目的是保留语义的完整性,因此不是某个好或某个坏,根据实际需求进行选择。
文字向量化

将每个切片文字块转换为关系向量

关系向量是怎么来的? 这些是通过对模型进行大量的上下文训练,得到的词语与词语,句子与句子的语义关系上的关联,这是LLM的基础。
不同的文字向量模型输出的向量矩阵也会不同,因此在构建和检索时需要用同一个文字向量模型进行转换。

向量数据库

跟平时用的MySql,MS sql等本质上差不多,只不过将文本换成了向量矩阵的增删改查
检索的方法(这里就列举几个):

  1. 两个向量的余弦角大小
  2. 两个向量的欧氏举例
  3. 两个向量的分类区域

用文本也能搜索,为什么要用向量呢? 文本的数据库检索一般通过正则搜索,这种无法关联语义进行检索,因为我们无法保证大模型在检索时能够按照固定的格式。举个例子:

数据库中存储:小明一个月工资3000元
搜索:小明这个月多少钱
正则搜索会直接略过,而向量搜索就能够搜到。

构建RAG知识库

本次都利用千问的语言模型,和FAISS向量数据库演示,来演示

案例

from operator import itemgetter
import os
from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.documents import Document
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.messages import HumanMessage, AIMessage
from sqlalchemy import true#apikey
os.environ["DASHSCOPE_API_KEY"] = "你的apikey"
FAISS_PATH = "my_faiss_index"raw_text = """
【公司内部机密:代号“深蓝计划”】
1. 项目目标:开发一款能听懂猫语的翻译器。
2. 核心技术:基于Transformer的“喵声波”分析算法。
3. 团队暗号:如果有人问“今天天气怎么样?”,必须回答“我想吃鱼”。
4. 截止日期:2026年12月31日。
5. 经费预算:仅剩50元人民币,主要用于购买猫条。
"""#初始化文本
docs = [Document(page_content=raw_text)]
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
split_docs = text_splitter.split_documents(docs)#初始化模型
llm = ChatTongyi(model="qwen-plus")
embeddings = DashScopeEmbeddings(model="text-embedding-v1")#创建向量数据库
if os.path.exists(FAISS_PATH):
    print("向量数据库已存在")
    ragdb = FAISS.load_local(FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
else:
    print("创建向量数据库")
    ragdb = FAISS.from_documents(split_docs, embeddings)
    ragdb.save_local(FAISS_PATH)#构建提示词chain
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)final_prompt = ChatPromptTemplate.from_messages([
    ("system", """
    你是一个专业的问答助手,你的任务是根据上下文简洁的回答用户的问题。
    <context>
    {context}
    </context>
    """),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])chain = (
    #查询rag
    RunnablePassthrough.assign(
        context = itemgetter("input") | ragdb.as_retriever() | format_docs
    )
    | RunnablePassthrough.assign(
        answer = {"input":itemgetter("input"), "context":itemgetter("context"), "history":itemgetter("history")} | final_prompt | llm | StrOutputParser()
    )
)history = []while true:
    input_q = input("我:")    respond = chain.invoke({
        "input": input_q,
        "history": history})    print("answer:" + respond["answer"])
    print("=="*30)
    
    history.append(HumanMessage(content=input_q))
    history.append(AIMessage(content=respond['answer']))

代码解释

代码的流程如下:

  1. 初始化RAG:文本切片->文本向量模型->构建向量数据库
  2. 询问ai:提示词->文本向量模型->向量数据库检索->组合prompt->喂给LLM->回答问题->记录历史对话
文本切片
docs = [Document(page_content=raw_text)]
text_splitter = RecursiveCharacterTextSplitter(chunk_size=100, chunk_overlap=20)
split_docs = text_splitter.split_documents(docs)

这里利用了langchain提供的文本分词器RecursiveCharacterTextSplitter(递归分词)

构建向量数据库
llm = ChatTongyi(model="qwen-plus")
embeddings = DashScopeEmbeddings(model="text-embedding-v1")#创建向量数据库
if os.path.exists(FAISS_PATH):
    print("向量数据库已存在")
    ragdb = FAISS.load_local(FAISS_PATH, embeddings, allow_dangerous_deserialization=True)
else:
    print("创建向量数据库")
    ragdb = FAISS.from_documents(split_docs, embeddings)
    ragdb.save_local(FAISS_PATH)

这部分要注意:新版FAISS读取现有数据库要设置:allow_dangerous_deserialization=True,不然会报错

提示词模板

final_prompt = ChatPromptTemplate.from_messages([
    ("system", """
    你是一个专业的问答助手,你的任务是根据上下文简洁的回答用户的问题。
    <context>
    {context}
    </context>
    """),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

之前没有讲到历史对话记录,这次补充下:

MessagesPlaceholder这个是langchain框架的占位符(其实是框架写好了prompt模板,告诉ai这个是历史对话),使用时将历史对话记录的数组放在这里设置的字段中,在添加历史对话时要使用相关的类进行声明对话(告诉ai这句话是ai说的还是用户说的)

history.append(HumanMessage(content=input_q))
history.append(AIMessage(content=respond['answer']))
Chain链的解释(核心逻辑)
chain = (
    #查询rag
    RunnablePassthrough.assign(
        context = itemgetter("input") | ragdb.as_retriever() | format_docs
    )
    | RunnablePassthrough.assign(
        answer = {"input":itemgetter("input"), "context":itemgetter("context"), "history":itemgetter("history")} | final_prompt | llm | StrOutputParser()
    )
)

Chain链流程:

  1. 查询RAG的chain:获取input字段->内容交给向量数据库检索->将检索的内容(数组)转换为字符串格式->保存到context字段并传递给下一个任务
  2. 询问LLM的chain:获取input,context,history字段->填充上面定义的prompt模板->喂给LLM模型->解析成文本并保存在answer字段

itemgetter是获取上一个任务传递过来的字段内容。

如果❤喜欢❤本系列教程,就点个关注吧,后续不定期更新~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1210485.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2026上海雅思培训机构深度测评TOP5|权威选课指南

本次测评由全国雅思教学质量评估中心指导,参照《2025-2026中国大陆雅思备考趋势白皮书》,结合上海黄浦区、徐汇区、长宁区、静安区、普陀区12000份考生问卷、120余家机构实地探访结果,开展权威实用的上海雅思培训深…

2026三极管品牌选型指南:四大高性价比品牌测评,中小客户定制化需求首选方案

2026三极管品牌选型指南:四大高性价比品牌测评,中小客户定制化需求首选方案 一、三极管行业趋势与采购痛点 随着新能源、AI、5G、智能家居等新兴领域的快速发展,全球电子信息产业对半导体元件的需求持续增长。三极管…

躺在家里办公多惬意!node_exporter+cpolar 轻松实现服务器远程监控

node_exporter 作为 Prometheus 生态下的服务器监控工具&#xff0c;核心功能是采集服务器 CPU 使用率、内存占用、磁盘 I/O、网络流量等基础运行指标&#xff0c;适配 Linux、Windows、macOS 等主流系统&#xff0c;无论是个人 NAS 用户、小微企业运维人员&#xff0c;还是技术…

Qt常用控件指南(3)

Qt Widget 交互核心与视觉属性深度剖析 在Qt图形界面开发中&#xff0c;用户体验的构建不仅仅依赖于控件的布局&#xff0c;更取决于细节属性的打磨。QWidget作为所有用户界面对象的基类&#xff0c;提供了丰富的属性接口&#xff0c;用于控制鼠标光标形态、字体排印样式、悬停…

Python简介

Python 是一个高层次的结合了解性、编译性、互动性和面向对象的脚本语言。 Python 的设计具有很强的可读性&#xff0c;相比其他语言经常使用英文关键字&#xff0c;其他语言的一些标点符号&#xff0c;它具有比其他语言更有特色语法结构。 Python 是一种解释型语言&#xff…

Spring Mvc(二)

一.获取Cookie,Session,Header 在处理http请求时,先明白http协议是"无状态"的(指服务器默认不会保留客户端请求之间的任何信息。)会导致用户登录状态、购物车内容等连续性功能无法直接实现。解决该问题据需要用到Cookie和Session,接下来进行解释: 1.Cookie 和 Sess…

Window逆向基础之逆向工程介绍

逆向工程 以设计方法学为指导&#xff0c;以现代设计理论、方法、技术为基础&#xff0c;运用各种专业人员的工程设计经验、知识和创新思维&#xff0c;对已有产品进行解剖、深化和再创造。 逆向工程不仅仅在计算机行业、各行各业都存在逆向工程。 计算机行业逆向工程 计算…

逆向工程工具集

目录 helloHex Editor &#xff08;16进制编辑器&#xff09; [Reverse Engineers Hex Editor](https://bbs.pediy.com/thread-263443.htm)[wxMEdit](https://bbs.pediy.com/thread-263443.htm#wxmedit)[wxHexEditor](https://bbs.pediy.com/thread-263443.htm#wxhexed…

网络安全的基本概念(小白入门-附资料)

一、什么是网络安全 &#xff08;1&#xff09;网络安全 网络安全指网络系统中的硬件、软件以及系统中的数据受到保护&#xff0c;不因偶然或恶意的原因而遭到破坏、更改、泄露&#xff0c;系统连续可靠正常地运行&#xff0c;网络服务不中断。 网络安全包括&#xff1a;网络…

2026上海雅思培训深度测评TOP5:权威榜单+提分实测,选课不踩坑

据英国文化教育协会权威数据,上海雅思考生年均增长18%,其中徐汇区、杨浦区、浦东新区、闵行区、黄浦区等多区县考生,备考中普遍面临雅思培训选课繁琐、优质教育机构难筛选的困境,多数考生苦于考试提分技巧不足、个…

Excel字符编码完全指南:LEN、LENB、WIDECHAR、ASC函数深度解析

在处理文本数据时&#xff0c;你是否曾困惑于中英文混合字符的长度计算&#xff1f;本文将揭开Excel字符编码的神秘面纱&#xff0c;带你彻底理解字符与字节的区别。 一、计算机字符编码基础&#xff1a;从位到字符 1. 存储单位&#xff1a;从比特到字节 基础单位定义 比特&…

2026上海雅思培训权威测评TOP5:高性价比选课指南,精准提分不踩坑

经全国雅思教学质量监测中心联合雅思备考研究院发起,结合上海徐汇、浦东、静安、闵行、杨浦五大核心区县15000份考生调研及实测,本次开展上海雅思培训深度测评,精准破解本地考生在雅思培训、选课、考试中的核心难题…

上海雅思考试提分攻略|5家优质机构深度测评,靠谱选择不踩坑

作为国内雅思考试核心考区,上海汇聚了徐汇区、浦东新区、杨浦区、闵行区、黄浦区等众多备考人群,高校在读学生、在职人士、留学规划党均深陷雅思培训选课困境。据权威测评显示,上海雅思考生核心痛点突出:选课难,难…

CF917E 做题记录

让我深感畏惧的题目。link 考虑将答案分为两条链上的,以及跨越 lca 的。 对于两条链上的,对所有串正反串一起建 AC 自动机,树上每个点求出从根到该点的匹配状态,在 AC 自动机上对应一个结点。 对于每个询问,相当于…

2026雅思网课权威实用深度测评排行榜 高分提分方案全解析

在雅思培训赛道中,选课难题始终困扰着广大考生,既要兼顾考试提分效率与优质技巧传授,又要权衡教育机构的口碑排名、性价比与个性化服务,靠谱实用的备考方案难寻。基于3个月行业调研、2000+真实学员反馈及多维度权威…

2026雅思网课口碑排名TOP5 深度权威测评优质提分靠谱机构

结合2026年雅思考试趋势及行业调研数据,雅思备考群体普遍面临诸多痛点:优质教育机构鱼龙混杂难以甄别,选课决策缺乏权威参考依据,提分技巧掌握不系统导致备考效率低下,个性化需求难以被满足,高性价比与提分效果难…

2026安徽中专择校指南:五强解析与趋势前瞻

在职业教育改革持续深化、技能型社会加速构建的今天,安徽省的中等职业教育正站在一个全新的历史拐点。对于广大初中毕业生及家庭而言,选择一所合适的中专、技工学校,已远非一次简单的升学决策,而是关乎孩子未来职业…

全国雅思培训机构深度测评TOP5:权威榜单助你高效选课提分

雅思考试是全球认可的语言能力测试,更是中国学子留学深造的必经之路,选择优质靠谱的雅思培训机构、掌握科学提分技巧,是实现高分目标的关键。当前雅思培训市场鱼龙混杂,无论是北京朝阳区、上海静安区、广州天河区,…

2026雅思网课提分口碑排名榜:权威深度测评及靠谱提分方案

基于2026年雅思考情迭代与全国3000+考生调研数据,雅思备考的核心痛点愈发凸显:多数考生在培训选课中陷入迷茫,既渴求优质教育机构提供权威提分技巧,又纠结性价比与个性化方案适配性,面对繁杂的考试考点难以找到实…

2026 雅思网课深度测评排行榜 AI赋能实用靠谱提分机构推荐

据British Council官方数据显示,2025年中国大陆考生雅思平均分为5.8分,口语单项仅5.4分,高分突破难度持续攀升。在雅思培训选课过程中,考生常面临优质资源稀缺、提分技巧杂乱、性价比失衡等问题,如何从众多教育机…