0. 背景
今天,我们将综合以上技能,完成 网络数据+RAG 问答的实践,并且学习如何在返回结果中添加结果的来源(原文档)。
在结果中添加该结果的参考来源是RAG问答中非常重要的一环,一方面让我们更加了解答案的生成原理和参考内容,防止参考错误的文档,另一方面,可以展示给用户,我们的答案是有参考的,不是胡说,增加信任度。例如下面这个检索工具的展示,有了来源之后,显得更加专业和更高的可信度:
1. 代码实现
参考:
1.1 加载网页数据
python代码解读复制代码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()
代码中以加载 https://lilianweng.github.io/posts/2023-06-23-agent/
链接的数据为例。
使用 WebBaseLoader
进行数据加载。WebBaseLoader
是LangChain封装的专门用于加载网页数据的类。其定义和初始化参数如下,原理就是利用 urllib
加载html页面,然后通过BeautifulSoup
进行Html
解析,找出其中指定tag
的内容。以上代码中 class_=("post-content", "post-title", "post-header")
表明只提取HTML
页面中这些tag
的数据。
python代码解读复制代码class WebBaseLoader(BaseLoader):
"""Load HTML pages using `urllib` and parse them with `BeautifulSoup'."""
def __init__(
self,
web_path: Union[str, Sequence[str]] = "",
header_template: Optional[dict] = None,
verify_ssl: bool = True,
proxies: Optional[dict] = None,
continue_on_failure: bool = False,
autoset_encoding: bool = True,
encoding: Optional[str] = None,
web_paths: Sequence[str] = (),
requests_per_second: int = 2,
default_parser: str = "html.parser",
requests_kwargs: Optional[Dict[str, Any]] = None,
raise_for_status: bool = False,
bs_get_text_kwargs: Optional[Dict[str, Any]] = None,
bs_kwargs: Optional[Dict[str, Any]] = None,
session: Any = None,
) -> None:
"""Initialize loader.
Args:
web_paths: Web paths to load from.
requests_per_second: Max number of concurrent requests to make.
default_parser: Default parser to use for BeautifulSoup.
requests_kwargs: kwargs for requests
raise_for_status: Raise an exception if http status code denotes an error.
bs_get_text_kwargs: kwargs for beatifulsoup4 get_text
bs_kwargs: kwargs for beatifulsoup4 web page parsing
"""
怎么查看网页中想要提取的数据的tag?参考这篇文章:【提效】让GPT帮你写爬虫程序,不懂爬虫也能行
1.2 数据分块
指定分块方式:RecursiveCharacterTextSplitter
,这个在之前咱们也介绍过(这篇文章),它就是将文本块分成 1000 字左右的段,相邻段之间有 200 字左右的重复,以保证相邻段之间的上下文连贯。
python代码解读复制代码text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
1.3 数据向量化和存储
使用 Chroma
作为向量数据库,向量化计算采用 OpenAIEmbeddings
接口和模型。
python
代码解读
复制代码vectorstore = Chroma.from_documents(documents=splits, embedding=OpenAIEmbeddings())
1.4 向量检索
将向量数据库作为 retriever。
python
代码解读
复制代码retriever = vectorstore.as_retriever()
1.5 组装Chain
python代码解读复制代码prompt = hub.pull("rlm/rag-prompt")
llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)
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()
)
(1)首先是Prompt,直接使用 hub.pull("rlm/rag-prompt")
加载一个Prompt模板,也可以自己写。加载到的Prompt模板内容:
(2)以上Prompt接收两个参数:context
和 question
,所以chain组装的第一步就是传递这两个参数。
(3)整体解释下以上 rag_chain 的数据流:
- retriver先运行,检索回来信息
- 检索回来的信息给 format_docs,组装信息
- 组装信息后填到
context
Key里,连同question
Key内容一起给 prompt - prompt 给 llm
- llm 结果给 StrOutputParser
1.6 运行
通过 invoke
函数运行。
python代码解读复制代码result = rag_chain.invoke("What is Task Decomposition?")
print(result)
别忘了所有的依赖:
python代码解读复制代码import bs4
from langchain import hub
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
运行结果:
2. 加入Sources(答案来源)
2.1 代码修改
加入Sources很简单,主要改下 Chain 的组装:
python代码解读复制代码from langchain_core.runnables import RunnableParallel
rag_chain_from_docs = (
RunnablePassthrough.assign(context=(lambda x: format_docs(x["context"])))
| prompt
| llm
| StrOutputParser()
)
rag_chain_with_source = RunnableParallel(
{"context": retriever, "question": RunnablePassthrough()}
).assign(answer=rag_chain_from_docs)
先不管它是如何实现的,先运行看下结果:
python代码解读复制代码result = rag_chain_with_source.invoke("What is Task Decomposition")
print(result)
2.2 代码解释
看到结果后应该就对这段程序有了一个感性的认识。下面我们来看下这段程序是如何实现的。
从 rag_chain_with_source
开始看。
python代码解读复制代码rag_chain_with_source = RunnableParallel(
{"context": retriever, "question": RunnablePassthrough()}
).assign(answer=rag_chain_from_docs)
它使用了 RunnableParallel
来传递 context
的值 和 question
的值。
RunnableParallel().assign()
实现的功能就是将以上{}
的内容传递给assign
函数的参数,也就是传递给rag_chain_from_docs
。
那么rag_chain_from_docs
中RunnablePassthrough.assign(context=(lambda x: format_docs(x["context"])))
,这里的x
就知道是什么了:{"context":xxxx, "question":xxxx}
。x["context"]
也就是将检索出的文档进行组装。
然后rag_chain_from_docs
的返回值:answer=rag_chain_from_docs
,就是将返回值填到 "answer"
为Key的值中。
最后,rag_chain_with_source
的返回值就是刚开始的 "context"
, "question"
,再加上后面的 "answer"
。
3. 总结
简单总结一下本文内容。
本文利用 LangChain 实现了一个完整的问答RAG应用。
其中RAG中的数据源采用加载网页数据的形式获取,而不是采用之前实践中传统的本地知识库(加载本地PDF文件)的方式。
然后我们还在RAG的返回中增加了参考文本的输出,这是之前我们没有实践过的,算是一点新知识。在实现这个功能的过程中,最主要的是学会使用 LangChain 中提供的 RunnablePassthrough
和 RunnableParallel
进行值的传递。
大模型资源分享
针对所有自学遇到困难的同学,我为大家系统梳理了大模型学习的脉络,并且分享这份LLM大模型资料:其中包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等。😝有需要的小伙伴,可以扫描下方二维码免费领取↓↓↓
一、全套 AGI 大模型学习路线
AI 大模型时代的精彩学习之旅:从根基铸就到前沿探索,牢牢掌握人工智能核心技能!
二、640 套 AI 大模型报告合集
此套涵盖 640 份报告的精彩合集,全面涉及 AI 大模型的理论研究、技术实现以及行业应用等诸多方面。无论你是科研工作者、工程师,还是对 AI 大模型满怀热忱的爱好者,这套报告合集都将为你呈上宝贵的信息与深刻的启示。
三、AI 大模型经典 PDF 书籍
伴随人工智能技术的迅猛发展,AI 大模型已然成为当今科技领域的一大热点。这些大型预训练模型,诸如 GPT-3、BERT、XLNet 等,凭借其强大的语言理解与生成能力,正在重塑我们对人工智能的认知。而以下这些 PDF 书籍无疑是极为出色的学习资源。
阶段 1:AI 大模型时代的基础认知
-
目标:深入洞悉 AI 大模型的基本概念、发展历程以及核心原理。
-
内容
:
- L1.1 人工智能概述与大模型起源探寻。
- L1.2 大模型与通用人工智能的紧密关联。
- L1.3 GPT 模型的辉煌发展历程。
- L1.4 模型工程解析。
- L1.4.1 知识大模型阐释。
- L1.4.2 生产大模型剖析。
- L1.4.3 模型工程方法论阐述。
- L1.4.4 模型工程实践展示。
- L1.5 GPT 应用案例分享。
阶段 2:AI 大模型 API 应用开发工程
-
目标:熟练掌握 AI 大模型 API 的运用与开发,以及相关编程技能。
-
内容
:- L2.1 API 接口详解。
- L2.1.1 OpenAI API 接口解读。
- L2.1.2 Python 接口接入指南。
- L2.1.3 BOT 工具类框架介绍。
- L2.1.4 代码示例呈现。
- L2.2 Prompt 框架阐释。
- L2.2.1 何为 Prompt。
- L2.2.2 Prompt 框架应用现状分析。
- L2.2.3 基于 GPTAS 的 Prompt 框架剖析。
- L2.2.4 Prompt 框架与 Thought 的关联探讨。
- L2.2.5 Prompt 框架与提示词的深入解读。
- L2.3 流水线工程阐述。
- L2.3.1 流水线工程的概念解析。
- L2.3.2 流水线工程的优势展现。
- L2.3.3 流水线工程的应用场景探索。
- L2.4 总结与展望。
阶段 3:AI 大模型应用架构实践
-
目标:深刻理解 AI 大模型的应用架构,并能够实现私有化部署。
-
内容
:- L3.1 Agent 模型框架解读。
- L3.1.1 Agent 模型框架的设计理念阐述。
- L3.1.2 Agent 模型框架的核心组件剖析。
- L3.1.3 Agent 模型框架的实现细节展示。
- L3.2 MetaGPT 详解。
- L3.2.1 MetaGPT 的基本概念阐释。
- L3.2.2 MetaGPT 的工作原理剖析。
- L3.2.3 MetaGPT 的应用场景探讨。
- L3.3 ChatGLM 解析。
- L3.3.1 ChatGLM 的特色呈现。
- L3.3.2 ChatGLM 的开发环境介绍。
- L3.3.3 ChatGLM 的使用示例展示。
- L3.4 LLAMA 阐释。
- L3.4.1 LLAMA 的特点剖析。
- L3.4.2 LLAMA 的开发环境说明。
- L3.4.3 LLAMA 的使用示例呈现。
- L3.5 其他大模型介绍。
阶段 4:AI 大模型私有化部署
-
目标:熟练掌握多种 AI 大模型的私有化部署,包括多模态和特定领域模型。
-
内容
:- L4.1 模型私有化部署概述。
- L4.2 模型私有化部署的关键技术解析。
- L4.3 模型私有化部署的实施步骤详解。
- L4.4 模型私有化部署的应用场景探讨。
学习计划:
- 阶段 1:历时 1 至 2 个月,构建起 AI 大模型的基础知识体系。
- 阶段 2:花费 2 至 3 个月,专注于提升 API 应用开发能力。
- 阶段 3:用 3 至 4 个月,深入实践 AI 大模型的应用架构与私有化部署。
- 阶段 4:历经 4 至 5 个月,专注于高级模型的应用与部署。