构建一个检索增强生成(RAG)应用程序

:::tips
此文档是LangChain官方教程的实践总结:
https://python.langchain.com/v0.2/docs/tutorials/rag/
实践前你需要准备:
OPENAI_API_KEY Generator:根据检索到的信息和用户的查询生成自然语言的回答。
LANGCHAIN_API_KEY 密切监控和评估您的应用程序,以便您可以快速、自信地开发。
py 环境准备(conda)。
:::

简介

我们将在网站上构建一个 QA 应用程序。我们将使用的具体网站是 Lilian Weng 的 LLM Powered Autonomous Agents 博客文章,该网站允许我们提出有关帖子内容的问题。

一步一步成功

数据收集

我们需要首先加载博客文章内容。为此,我们可以使用 DocumentLoaders,它们是从源加载数据并返回文档列表的对象。 Document 是一个带有一些 page_content (str) 和 metadata (dict) 的对象。
在本例中,我们将使用 WebBaseLoader,它使用 urllib 从 Web URL 加载 HTML,并使用 BeautifulSoup 将其解析为文本。我们可以通过 bs_kwargs 将参数传递给 BeautifulSoup 解析器来自定义 HTML -> 文本解析(请参阅 BeautifulSoup 文档)。在这种情况下,只有类为“post-content”、“post-title”或“post-header”的 HTML 标记是相关的,因此我们将删除所有其他标记。

import bs4
from langchain_community.document_loaders import WebBaseLoader# Only keep post title, headers, and content from the full HTML.
bs4_strainer = bs4.SoupStrainer(class_=("post-title", "post-header", "post-content"))
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),bs_kwargs={"parse_only": bs4_strainer},
)
docs = loader.load()
len(docs[0].page_content)
43131
print(docs[0].page_content[:500])
######LLM Powered Autonomous AgentsDate: June 23, 2023  |  Estimated Reading Time: 31 min  |  Author: Lilian WengBuilding agents with LLM (large language model) as its core controller is a cool concept. Several proof-of-concepts demos, such as AutoGPT, GPT-Engineer and BabyAGI, serve as inspiring examples. The potentiality of LLM extends beyond generating well-written copies, stories, essays and programs; it can be framed as a powerful general problem solver.
Agent System Overview#
In

数据分块

我们加载的文档长度超过 42k 个字符。这太长了,无法适应许多模型的上下文窗口。即使对于那些可以在其上下文窗口中容纳完整帖子的模型,模型也可能很难在很长的输入中找到信息。
为了解决这个问题,我们将把 Document 分割成块以进行嵌入和向量存储。这应该可以帮助我们在运行时仅检索博客文章中最相关的部分。
在本例中,我们将把文档分成 1000 个字符的块,块之间有 200 个字符的重叠。重叠有助于降低将语句与与其相关的重要上下文分开的可能性。我们使用 RecursiveCharacterTextSplitter,它将使用常见的分隔符(如换行符)递归地分割文档,直到每个块的大小合适。这是针对一般文本用例推荐的文本分割器。
我们设置 add_start_index=True ,以便将初始文档中每个分割文档开始的字符索引保留为元数据属性“start_index”。

from langchain_text_splitters import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200, add_start_index=True
)
all_splits = text_splitter.split_documents(docs)
len(all_splits)
66
len(all_splits[0].page_content)
969
all_splits[10].metadata
{'source': 'https://lilianweng.github.io/posts/2023-06-23-agent/','start_index': 7056}

文本嵌入+存储

现在我们需要为 66 个文本块建立索引,以便我们可以在运行时搜索它们。最常见的方法是嵌入每个文档分割的内容并将这些嵌入插入向量数据库(或向量存储)中。当我们想要搜索分割时,我们采用文本搜索查询,将其嵌入,并执行某种“相似性”搜索,以识别与查询嵌入最相似的嵌入的存储分割。最简单的相似性度量是余弦相似性——我们测量每对嵌入(高维向量)之间角度的余弦。
我们可以使用 Chroma 矢量存储和 OpenAIEmbeddings 模型将所有文档分割嵌入并存储在单个命令中。

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddingsvectorstore = Chroma.from_documents(documents=all_splits, embedding=OpenAIEmbeddings())

检索

现在让我们编写实际的应用逻辑。我们想要创建一个简单的应用程序,它接受用户问题,搜索与该问题相关的文档,将检索到的文档和初始问题传递给模型,然后返回答案。
首先,我们需要定义搜索文档的逻辑。 LangChain 定义了一个 Retriever 接口,它包装了一个索引,该索引可以在给定字符串查询的情况下返回相关的 Documents 。
最常见的 Retriever 类型是 VectorStoreRetriever,它使用向量存储的相似性搜索功能来促进检索。任何 VectorStore 都可以通过 VectorStore.as_retriever() 轻松转换为 Retriever :

retriever = vectorstore.as_retriever(search_type="similarity", search_kwargs={"k": 6})retrieved_docs = retriever.invoke("What are the approaches to Task Decomposition?")
len(retrieved_docs)
6
print(retrieved_docs[0].page_content)
Tree of Thoughts (Yao et al. 2023) extends CoT by exploring multiple reasoning possibilities at each step. It first decomposes the problem into multiple thought steps and generates multiple thoughts per step, creating a tree structure. The search process can be BFS (breadth-first search) or DFS (depth-first search) with each state evaluated by a classifier (via a prompt) or majority vote.
Task decomposition can be done (1) by LLM with simple prompting like "Steps for XYZ.\n1.", "What are the subgoals for achieving XYZ?", (2) by using task-specific instructions; e.g. "Write a story outline." for writing a novel, or (3) with human inputs.

生成

我们使用 gpt-3.5-turbo OpenAI 聊天模型,但任何 LangChain LLM 或 ChatModel 都可以替换。

import osos.environ["OPENAI_API_KEY"] = "your openai api key"from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo-0125")

我们使用已签入 LangChain 提示中心的 RAG 提示。rlm/rag-prompt

from langchain import hubprompt = hub.pull("rlm/rag-prompt")

截屏2024-06-21 下午5.43.23.png

组装链

我们将使用 LCEL Runnable 协议来定义链,使我们能够

  • 以透明的方式将组件和功能连接在一起
  • 在 LangSmith 中自动追踪我们的链条
  • 开箱即用地进行流式、异步和批量呼叫。
import osos.environ["LANGCHAIN_TRACING_V2"] = "true"
os.environ["LANGCHAIN_API_KEY"] = "your langchain api key"
os.environ["OPENAI_API_KEY"] = "your openai api key"from langchain_openai import ChatOpenAIllm = ChatOpenAI(model="gpt-3.5-turbo-0125")
import bs4
from langchain import hub
from langchain_chroma import Chroma
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter# Load, chunk and index the contents of the blog.
loader = WebBaseLoader(web_paths=("https://lilianweng.github.io/posts/2023-06-23-agent/",),bs_kwargs=dict(parse_only=bs4.SoupStrainer(class_=("post-content", "post-title", "post-header"))),
)
docs = loader.load()text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())# Retrieve and generate using the relevant snippets of the blog.
retriever = vectorstore.as_retriever()
prompt = hub.pull("rlm/rag-prompt")def format_docs(docs):return "\n\n".join(doc.page_content for doc in docs)rag_chain = ({"context": retriever | format_docs, "question": RunnablePassthrough()}| prompt| llm| StrOutputParser()
)response = rag_chain.invoke("What is Agent System Overview?")print(response)

调用

我询问了两个问题

  • What is Task Decomposition?

截屏2024-06-21 下午5.51.09.png

  • What is Agent System Overview?

截屏2024-06-21 下午5.51.30.png

剖析 LCEL(链) 以了解发生了什么

首先:这些组件中的每一个( retriever 、 prompt 、 llm 等)都是 Runnable 的实例。这意味着它们实现相同的方法 - 例如同步和异步 .invoke 、 .stream 或 .batch - 这使它们更容易连接在一起。它们可以通过 | 运算符连接到 RunnableSequence(另一个 Runnable)。
当遇到 | 运算符时,LangChain 会自动将某些对象转换为可运行对象。此处, format_docs 被转换为 RunnableLambda,带有 “context” 和 “question” 的字典被转换为 RunnableParallel。细节并不重要,重要的是每个对象都是一个 Runnable。
让我们跟踪输入问题如何流经上述可运行对象:
正如我们在上面看到的, prompt 的输入预计是一个带有键 “context” 和 “question” 的字典。因此,该链的第一个元素构建了可运行对象,它将根据输入问题计算这两个值:

  • retriever | format_docs 将问题传递给检索器,生成Document对象,然后传递给 format_docs 生成字符串;
  • RunnablePassthrough() 不变地传递输入问题。

然后 chain.invoke(question) 将构建一个格式化的提示,准备进行推理。
最后一步是 llm ,它运行推理,以及 StrOutputParser() ,它只是从 LLM 的输出消息中提取字符串内容。

遇到的问题

USER_AGENT

截屏2024-06-21 下午6.02.39.png
不阻塞运行,解决方案:
添加下面代码

user_agent = "MyPythonApp/1.0 (Language=Python/3.9; Platform=Linux/Ubuntu20.04)"
os.environ["USER_AGENT"] = user_agent

SSLError

截屏2024-06-21 下午6.04.49.png
阻塞运行,解决方案:
换个代理。

LangSmith展示

截屏2024-06-21 下午6.09.02.png
截屏2024-06-21 下午6.09.29.png
截屏2024-06-21 下午6.09.52.png

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

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

相关文章

【自然语言处理系列】掌握NLP基础:去停用词、词性标注与命名实体识别实战教程

摘要:本系列教程专注于自然语言处理(NLP)中的基础元素,包括去停用词、词性标注以及命名实体识别。这些步骤是文本预处理和分析不可或缺的组成部分。我们将通过具体的实例和技术演示,讲解如何使用Python及其相关库&…

网络安全之Windows提权(上篇)(高级进阶)

目录 一,什么是提权? 二,提权的前提 三,如何提权? 1,第一步连接服务器 2,提升权限至iuser​编辑 3,利用补丁漏洞提权至最高级 四,总结 一,什么是提权&am…

大数据集群数据传输

简单的服务器间的通信示例 netcat,简写为 nc,是 unix 系统下一个强大的命令行网络通信工具,用于在两台主机之间建立 TCP 或者 UDP 连接,并提供丰富的命令进行数据通信。nc 在网络参考模型属于应用层。使用 nc 可以做很多事情&…

重磅丨上海容大推出“容聆”智能拾音工牌,赋能线下门店运营数字化

近日,继豚音营业厅智能质检终端之后,上海容大数字技术有限公司(简称“上海容大”)在线下面对面沟通场景下语音数据采集与智能分析领域取得了新突破,重磅推出AI智能语音工牌产品——“容聆”。 据悉,“容聆”…

mybatis x插件的使用教程(详细)

MyBatisX 的主要功能 代码生成: 自动生成 MyBatis 的 Mapper、XML 配置文件和实体类,大大减少手工编写代码的工作量。 智能代码补全: 提供 SQL 语句和 MyBatis 配置的智能代码补全功能,使开发者能够更快地编写代码。 代码导航&…

铀的危害和应用,以及铀的分离提纯

铀是一种锕系放射性元素,对人体存在一定的危害,如辐射损伤、呼吸系统损伤、神经系统损伤、免疫系统损伤等。 1、辐射损伤:铀的放射性会对人体产生辐射损伤,长期接触会增加患癌症的风险。此外,还可能对人体正常细胞产生…

【网络安全的神秘世界】解决dvwa靶场报错:Illegal mix of collations for operation ‘UNION‘

🌝博客主页:泥菩萨 💖专栏:Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 🚩问题描述 当尝试执行如下 SQL 语句时: 1 union select schema_name,1 from information_schema.s…

如何挑选护眼灯?一分钟带你了解挑选护眼灯的六大准则!

小时候,对正确用眼知识一无所知,也不明白何种光线环境对眼睛最为友善,结果如今的近视度数已濒临千度大关。虽然早已习惯佩戴眼镜的生活,但近视所带来的诸多不便仍旧在日常生活中无处不在。因此,对于家中孩子的视力健康…

第六十七:iview的select组件在页面上,下拉数据被遮挡

iview的select组件在页面上,下拉数据被遮挡 加上**:transfer"true"** 代码截图: 官方解说截图:因为默认值是false 所以要改成:transfer“true”

人工智能水平国际领先,科大讯飞再获国家科学技术进步奖一等奖

科大讯飞在2023年6月24日荣获国家科学技术进步奖一等奖,这是对其在多语种智能语音技术及产业化领域取得的突破性成果的高度认可。科大讯飞的这一成就,标志着其在人工智能领域的技术实力和创新能力已达到国际领先水平。 据「TMT星球」了解,科大…

WMV 视频格式怎么转换?WMV 视频为什么不流行了?

目前有越来越多的视频格式类型,如常见的 MP4、FLV、AVI 等等,而技术的演变也逐渐让一些常见的视频格式变的越来越少了。 今天我们一起来聊下 WMV 这个视频格式,让我们看看它的发展以及为什么现在越来越少人使用了。 什么是 WMV 视频格式&…

Git 使用指南(附详细解释)

Git 是一个强大的版本控制系统,广泛用于软件开发中,用于跟踪文件的更改、协作工作等。无论你是新手还是有经验的开发者,掌握 Git 都是非常有益的。这篇博客将带你了解 Git 的基本使用,希望能帮助你快速入门并有效使用 Git。 1. 创…

【windows|011】TCP/IP5层模型常见协议及应用总结大全

🍁博主简介: 🏅云计算领域优质创作者 🏅2022年CSDN新星计划python赛道第一名 🏅2022年CSDN原力计划优质作者 ​ 🏅阿里云ACE认证高级工程师 ​ 🏅阿里云开发者社区专家博主 💊交流社…

java设计模式(二)工厂方法模式(pattern of factory method)

1、模式介绍: 工厂方法模式(pattern of factory method)是一种创建型设计模式,它定义了一个用于创建对象的接口,但将实际创建对象的工作延迟到子类中,这样可以在不改变整体结构的情况下,通过子…

第二节课 6月13日 ssh密钥登陆方式

centos和ubuntu openssh服务的初始安装 一、实验:ubuntu系统激活root用户 ubuntu系统如何激活root用户,允许root用户ssh登陆? 1、ubuntu默认root用户未设置密码,未激活 激活root用户,设置root密码 sudo passwd roo…

vray灯光导致3dmax崩溃怎么解决?

启动时崩溃 解决方法: 1、兼容模式重新打开 具体步骤:【选中会闪退3dmax版本】——【右键“兼容性疑难解答”】——【下一步】——【选择Windows7/10】——【下一步】——【启动程序】 启动完成后,【下一步】——【为我保存这些设置】—完…

强化学习专题:强化学习知识梳理(一)

2024/6/23: 前段时间有幸完成了大学期间的第一篇论文。在面试之前复盘一下关于自己论文中DQN的一些相关点。 浅谈主要区别(在线 or 离线) 首先,一切的开始是强化学习中时序差分方程,这体现了强化学习方法的优化策略。在…

JAVAEE之网络原理_传输控制协议(TCP)的滑动窗口、流量控制、拥塞控制、延迟应答、捎带应答机制

前言 在前面几节,我们讲解了TCP协议的基本概念、报文格式。还介绍了确认应答机制、超时重传、连接管理机制,在本节中 我们将会继续介绍TCP协议的其他机制。 一、滑动窗口机制(效率机制) 在前面的章节中我们讨论了确认应答策略&…

springboot微信点餐小程序-计算机毕业设计源码82910

目 录 摘要 1 绪论 1.1 项目开发背景 1.2目的和意义 1.3springboot框架介绍 2 微信点餐小程序系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 数据流程 3.3.2 业务流程 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 …

Transformer的诞生和崛起

智能问答与文本生成:Transformer模型的超能力 ©作者|wy 来源|神州问学 一、引言 NLP(自然语言处理)作为人工智能领域的一个重要分支,致力于使计算机能够理解和处理人类语言。随着互联网的发展和信息时代的到来,…