Langchain构建RAG对话应用

本文:关注 检索器与上下文的子链、父链;即检索器也需要上下文内容。

RAG是一种增强LLM知识的方法,通过引入额外的数据来实现。

实现思路:加载—》分割—》存储—》检索—》生成。

初始化

import os
import bs4
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains.history_aware_retriever import create_history_aware_retriever
from langchain.chains.retrieval import create_retrieval_chain
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain_core.runnables import RunnableWithMessageHistory
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_openai import ChatOpenAI, OpenAIEmbeddingsos.environ['http_proxy'] = '127.0.0.1:7890'
os.environ['https_proxy'] = '127.0.0.1:7890'os.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_PROJECT"] = "LangchainDemo"
os.environ["LANGCHAIN_API_KEY"] = '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'
# os.environ["TAVILY_API_KEY"] = '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'# 聊天机器人案例
# 创建模型
model = ChatOpenAI(model='gpt-4-turbo')

加载数据

通过angchain_community..document_loaders import WebBaseLoader加载博客内容数据

返回一个Document列表,每个Document包含web元数据(metadata)、内容(page_content);

## angchain_community.包含大量工具。

#WebBaseLoader 相当于一个爬虫,可以爬取多个网页

# Beautiful Soup的SoupStrainer用于解析HTML文档时仅提取特定(class_)的部分

# 1、加载数据: 一篇博客内容数据
loader = WebBaseLoader(web_paths=['https://lilianweng.github.io/posts/2023-06-23-agent/'],bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=('post-header', 'post-title', 'post-content')))
)docs = loader.load()# print(len(docs))
# print(docs)

切割

可以看到,上述Document的内容非常大;因此要进行切割。

# from langchain_text_splitters import RecursiveCharacterTextSplitter

## chunk_size:分割块大小;chunk_overlap:允许重复字符(保证语句完整性)

# splitter包含多种切割,还有split_text:切割string、bytes

# 2、大文本的切割
# text = "hello world, how about you? thanks, I am fine.  the machine learning class. So what I wanna do today is just spend a little time going over the logistics of the class, and then we'll start to talk a bit about machine learning"
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)splits = splitter.split_documents(docs)

test示例

#可以看到第一块,和第二块末尾都有how。第一块 how因补充chunk_size;第二块how因语序完整性及chunk_overlap而存在。

存储与检索

# 根据切割结果,创建向量数据库

# 2、存储
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())

# 检索器

# 3、检索器
retriever = vectorstore.as_retriever()

创建Prompt和chain

# 创PromptTemplate:系统定位、聊天历史、用户输入。

# 创 chain:create_stuff_documents_chain(model, prompt) :创建多文本的chain

# 创建一个问题的模板
system_prompt = """You are an assistant for question-answering tasks. 
Use the following pieces of retrieved context to answer 
the question. If you don't know the answer, say that you 
don't know. Use three sentences maximum and keep the answer concise.\n{context}
"""
prompt = ChatPromptTemplate.from_messages(  # 提问和回答的 历史记录  模板[("system", system_prompt),MessagesPlaceholder("chat_history"),  #("human", "{input}"),]
)chain1 = create_stuff_documents_chain(model, prompt)# 下述测试,因为没有 chat_history,因此会报错。
### 将检索器和已有chain链接
# chain2 = create_retrieval_chain(retriever, chain1)# resp = chain2.invoke({'input': "What is Task Decomposition?"})
### resp包含多个key,只取answer。
# print(resp['answer'])

子链-历史记录

'''注意:
一般情况下,我们构建的链(chain)直接使用输入问答记录来关联上下文。

但在此案例中查询检索器也需要 对话上下文 才能被理解

#解决办法
添加一个子链(chain),它采用最新用户问题和聊天历史,并在它引用历史信息中的任何信息时重新表述问题。这可以被简单地认为是构建一个新的“历史感知”检索器。
这个子链的目的:让检索过程融入了对话的上下文

#eg:HumanMessage:它的方法有哪些;这里的‘ 它 ’即需要结合上下文,才能理解。”

# 子链提示词模板:重新定义子链AI的定位(根据用户新问题和上下文,分析并返回最新真实问题)。

##create_history_aware_retriever(模型、检索器、子链Prompt):用于创建一种​​能够感知对话历史​​的检索器(Retriever)。它的核心作用是让检索过程动态结合之前的对话上下文,从而使当前查询的检索结果更精准、更相关。

##create_retrieval_chain(history_chain, chain1):整合俩个链。

# 创建一个子链
# 子链的提示模板
contextualize_q_system_prompt = """Given a chat history and the latest user question 
which might reference context in the chat history, 
formulate a standalone question which can be understood 
without the chat history. Do NOT answer the question, 
just reformulate it if needed and otherwise return it as is."""retriever_history_temp = ChatPromptTemplate.from_messages([('system', contextualize_q_system_prompt),MessagesPlaceholder('chat_history'),("human", "{input}"),]
)# 创建一个子链
history_chain = create_history_aware_retriever(model, retriever, retriever_history_temp)# 保持问答的历史记录
store = {}def get_session_history(session_id: str):if session_id not in store:store[session_id] = ChatMessageHistory()return store[session_id]# 创建父链chain: 把前两个链整合
chain = create_retrieval_chain(history_chain, chain1)# 创建携带history的Runnable对象
result_chain = RunnableWithMessageHistory(chain,get_session_history,input_messages_key='input',history_messages_key='chat_history',output_messages_key='answer'
)

1

多轮会话

# 第一轮对话
resp1 = result_chain.invoke({'input': 'What is Task Decomposition?'},config={'configurable': {'session_id': 'zs123456'}}
)print(resp1['answer'])# 第二轮对话
resp2 = result_chain.invoke({'input': 'What are common ways of doing it?'},config={'configurable': {'session_id': 'ls123456'}}
)print(resp2['answer'])

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

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

相关文章

关于模拟噪声分析的11个误区

目录 1. 降低电路中的电阻值总是能改善噪声性能 2. 所有噪声源的噪声频谱密度可以相加,带宽可以在最后计算时加以考虑 3. 手工计算时必须包括每一个噪声源 4. 应挑选噪声为ADC 1/10的ADC驱动器 5. 直流耦合电路中必须始终考虑1/f噪声 6. 因为1/f噪声随着频率降…

vue,uniapp解决h5跨域问题

如果有这样的跨域问题,解决办法: ✅ 第一步:在项目根目录下创建 vue.config.js 和 package.json 同级目录。 // vue.config.js module.exports {devServer: {proxy: {/api: {target: https://app.yycjkb.cn, // 你的后端接口地址changeOrig…

SQL通用语法和注释,SQL语句分类(DDL,DML,DQL,DCL)及案例

目录 SQL通用语法和注释 SQL语句分类(DDL,DML,DQL,DCL,TPL,CCL) DDL(数据定义语言) 数据库操作 查询(SHOW、SELECT) 创建(CREAT…

Linux:线程概念与控制

✨✨所属专栏:Linux✨✨ ✨✨作者主页:嶔某✨✨ Linux:线程概念于控制 var code “d7e241ae-ed4d-475f-aa3d-8d78f873fdca” 概念 在一个程序里的一个执行路线就叫做线程thread。更准确一点:线程是“一个进程内部的控制序列” …

人脸识别联合行为检测的办公管理新模式

基于人脸识别与行为检测的办公智能化解决方案 一、背景 在传统办公场景中,员工考勤管理、工位使用情况统计、安全监控等环节存在诸多痛点。例如,传统考勤方式如指纹打卡、刷卡等存在代打卡现象,考勤数据不准确;对于员工是否在工…

ceph weight 和 reweight 的区别

ceph osd df ID CLASS WEIGHT REWEIGHT SIZE RAW USE DATA OMAP META AVAIL %USE VAR PGS STATUS0 nvme 6.98630 0.95508 7.0 TiB 5.0 TiB 4.9 TiB 13 GiB 33 GiB 2.0 TiB 71.10 0.96 83 up1 nvme 6.98630

WInform当今技术特性分析

Windows Forms (WinForms) 技术特性分析 引言 Windows Forms (WinForms) 作为微软最早推出的基于.NET的图形用户界面开发框架,已经存在了20多年。在如今充满了各种现代UI框架的软件开发生态系统中,WinForms仍然保持着其独特的地位。本文将深入分析WinF…

Spark rdd算子解析与实践

一、RDD基础回顾 RDD(Resilient Distributed Dataset) 是Spark的核心抽象,代表一个不可变、分区的分布式数据集合。其核心特性包括: 容错性:通过血缘(Lineage)记录数据生成过程,支…

sqlite3的API以及命令行

sqlite是目前最流行的嵌入式数据库。 所谓嵌入式,就是足够简单,可以嵌入到我们自己开发的应用程序之中。 在Linux系统中,sqlite的使用只需要使用它的API,连接它的动态连接库,甚至都不用连接,sqlite的实现…

Allure测试报告按测试终端和测试类型智能分类查看

以下是实现Allure测试报告按测试终端和测试类型智能分类的完整方案: 一、测试框架分层设计 # 项目结构 project/ ├── api_tests/ # API测试 │ └── test_order.py ├── app_tests/ # 移动端测试 │ ├── android/ │ └── ios/ ├── pc_te…

Spine-Leaf 与 传统三层架构:全面对比与解析

本文将详细介绍Spine-Leaf架构,深入对比传统三层架构(Core、Aggre、Access),并探讨其与Full-mesh网络和软件定义网络(SDN)的关联。通过通俗易懂的示例和数据中心网络分析,我将帮助您理解Spine-L…

图像预处理-图像噪点消除

一.基本介绍 噪声:指图像中的一些干扰因素,也可以理解为有那么一些点的像素值与周围的像素值格格不入。常见的噪声类型包括高斯噪声和椒盐噪声。 滤波器:也可以叫做卷积核 - 低通滤波器是模糊,高通滤波器是锐化 - 低通滤波器就…

安卓手机如何改ip地址教程

对于安卓手机用户而言,ip修改用在电商、跨境电商、游戏搬砖、社交软件这些需要开多个账号的项目。因为多个设备或账号又不能在同一ip网络下,所以修改手机的IP地址防检测成为一个必要的操作。以下是在安卓手机上更改IP地址的多种方法及详细步骤&#xff0…

对象池模式在uniapp鸿蒙APP中的深度应用

文章目录 对象池模式在uniapp鸿蒙APP中的深度应用指南一、对象池模式核心概念1.1 什么是对象池模式?1.2 为什么在鸿蒙APP中需要对象池?1.3 性能对比数据 二、uniapp中的对象池完整实现2.1 基础对象池实现2.1.1 核心代码结构2.1.2 在Vue组件中的应用 2.2 …

本地部署大模型实现扫描版PDF文件OCR识别!

在使用大模型处理书籍 PDF 时,有时你会遇到扫描版 PDF,也就是说每一页其实是图像形式。这时,大模型需要先从图片中提取文本,而这就需要借助 OCR(光学字符识别)技术。 像 Gemini 2.5 这样的强大模型&#x…

《Operating System Concepts》阅读笔记:p700-p732

《Operating System Concepts》学习第 60 天,p700-p732 总结,总计 33 页。 一、技术总结 1.Virtual machine manager (VMM) The computer function that manages the virtual machine; also called a hypervisor. VMM 也称为 hypervisor。 2.types …

软件项目验收报告模板

软件项目验收报告 一、项目基本信息 项目名称XX智能仓储管理系统开发单位XX科技有限公司验收单位XX物流集团合同签订日期2023年3月15日项目启动日期2023年4月1日验收日期2024年1月20日 二、验收范围 入库管理模块(包含RFID识别、库存预警)出库调度模…

深度学习笔记39_Pytorch文本分类入门

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 一、我的环境 1.语言环境:Python 3.8 2.编译器:Pycharm 3.深度学习环境: torch1.12.1cu113torchvision…

二分查找-LeetCode

题目 给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。 示例 1: 输入: nums [-1,0,3,5,9,12], target 9 输出: 4 解释: …

从 Ext 到 F2FS,Linux 文件系统与存储技术全面解析

与 Windows 和 macOS 操作系统不同,Linux 是由爱好者社区开发的大型开源项目。它的代码始终可供那些想要做出贡献的人使用,任何人都可以根据个人需求自由调整它,或在其基础上创建自己的发行版本。这就是为什么 Linux 存在如此多的变体&#x…