gpt-n(GPT⑶问答机器人实战【LangChain】)gpt⑶ 1看就会

 

ChatGPT 几个月前问世,并以其回答来自广泛知识集的问题的能力震惊了所有人。 在 ChatGPT 展示大型语言模型的强大功能时,Dagster 核心团队遇到了1个问题。

推荐:用 NSDT场景设计器 快速搭建3D场景1、我们的问题我们构建了 Dagster,这是1个快速增长的开源数据编排解决方案,具有大型社区 Slack 实例 提供1流的支持体验是我们项目成功的关键,但这需要我们核心团队成员的大量工作。

当我们看到 ChatGPT 可以做什么时,我们想知道我们是否可以基于可以回答基本问题的技术创建1个 Slack 机器人虽然 OpenAI 的 ChatGPT 本身没有 API,但底层技术 GP手机壁纸T 有。

因此,我们开始了1段旅程,以弄清楚我们是否可以使用 GPT 构建1个可以回答有关 Dagster 的基本技术问题的机器人值得注意的是,我没有是 AI 专家 我们可以通过多种方式改进我们在这篇博文中所做的工作。

话虽如此,让我们继续吧!2、微调还是没有微调?我们需要1种方法来向 GPT 传授 Dagster GitHub 项目的技术细节显而易见的解决方案是找到1种在 Dagster 文档上训练 GPT 的方法。

我们将从 Dagster 存储库中提取每个 Markdown 文件,并以某种方式将其提供给 GPT我们的第1直觉是使用 GPT 的微调功能来创建在 Dagster手机壁纸 文档上训练的自定义模型 但是,由于 3 个原因,我们最终没有这样做:。

我们没有确定基于 Markdown 文件构建训练提示的最佳方式,也找没有到很好的资源来帮助我们了解微调的最佳实践好像很贵 看起来每次我们想要重新训练都要花费 80 美元 如果我们希望我们的机器人回购中的最新变化保持同步(即每天重新训练),这个成本可能会增加。

我网络中的1些人进行了交谈,他们已经将 GPT 部署到生产环境中,他们都对微调持悲观态度所以我们决定在没有进行微调的情况下继续前进3、使用 LangChain 构建提示Prompt engineering 是开发1个很好的提示来最大化像 GPT 这样的大型语言模手机壁纸型的有效性的过程。

开发提示的挑战在于你通常需要1系列提示或提示链才能获得最佳答案我们遇到了1个很棒的库,可以帮助我们解决这个问题:langchain :大型语言模型 (LLM) 正在成为1种变革性技术,使开发人员能够构建他们以前无法构建的应用程序。

但是单独使用这些 LLM 往往没有足以创建1个真正强大的应用程序——当你能够将它们其他计算或知识来源相结合时,真正的力量才会出现这正是我们试图解决的问题:我们希望利用 GPT 大型语言模型的强大功能,并将其 Dagster 文档中编码的知识相结合。

幸运的是,LangChain 包含1个称为数据增强生成的功能,它允许你提供1高低文数据来增强 L手机壁纸LM 的知识 它还为像我们这样的问答应用程序预建了提示如果我们深入了解 LangChain 的源代码,我们可以看到问题回答的提示是什么(完整源代码在这里):

Given the following extracted parts of a long document and a question, create a final answer with references (

"SOURCES"). If you dont know the answer, just say that you dont know. Donttry to make up an answer. 手机壁纸 ALWAYS

return a "SOURCES" part in your answer. QUESTION: {question} ========= {summaries} ========= FINAL ANSWER:

如你所见,这个提示接受1个问题和1些来源,并返回1个答案以及最相关的来源 查看提示中提供的示例之1,以了解这在实践中的表现:QUESTION:Whichstate/countryslawgovernsthe

interpretationofthecontract?=========C手机壁纸ontent:ThisAgreementisgovernedbyEnglishlawandthepartiessubmitto

theexclusivejurisdictionoftheEnglishcourtsinrelationtoanydispute(contractualornon-contractual)concerning

thisAgreementsavethateitherpartymayapplytoanycourtforaninjunctionorotherrelieftoprotectitsIntellectual

PropertyRights.Source:28-plCont手机壁纸ent:NoWaiver.FailureordelayinexercisinganyrightorremedyunderthisAgreement

shallnotconstituteawaiverofsuch(oranyother)rightorremedy.\n\n11.7Severability.Theinvalidity,illegality

orunenforceabilityofanyterm(orpartofaterm)ofthisAgreementshallnotaffectthecontinuationinforceoftheremainder

oftheterm(ifany)an手机壁纸dthisAgreement.\n\n11.8NoAgency.Exceptasexpresslystatedotherwise,nothinginthisAgreement

shallcreateanagency,partnershiporjointventureofanykindbetweentheparties.\n\n11.9NoThird-PartyBeneficiaries.

Source:30-plContent:(b)ifGooglebelieves,ingoodfaith,thattheDistributorhasviolatedorcausedGoogletoviolate

an手机壁纸yAnti-BriberyLaws(asdefinedinClause8.5)orthatsuchaviolationisreasonablylikelytooccur,Source:4-pl=========

FINAL ANSWER:ThisAgreementisgovernedbyEnglishlaw.SOURCES:28-pl3、在 LangChain 中实现1个示例

☝ 对于本教程,我建议使用 GitPod 来获得1致的 Python 环境让我们在 LangChain 中实现它 首先安装 LangChain 和本教程其余部分所需的1些依赖项:pip install langchain==手机壁纸

0.0.55 requests openai transformers faiss-cpu 接下来,让我们开始编写1些代码 创建1个新的 Python 文件 langchain_bot.py 并从1些导入开始:。

from langchain.llms import OpenAI from langchain.chains.qa_with_sources import load_qa_with_sources_chain

from langchain.docstore.documentimport Document import requests接手机壁纸下来,我们的玩具示例需要1些示例数据 现在,让我们使用各种维基百科页面的第1段作为我们的数据源。

1个很棒的 Stack Overflow 答案,它给了我们1个获取这些数据的神奇咒语:defget_wiki_data(title, first_paragraph_only): url =

f"https://en.wikipedia.org/w/api.php?format=json&action=query&prop=extracts&explaintext=1&titles={title}

"if first_paragraph_only: url += "&e手机壁纸xintro=1" data = requests.get(url).json() return Document( page_content=list(data[

"query"]["pages"].values())[0]["extract"], metadata={"source": f"https://en.wikipedia.org/wiki/

{title}"}, )没有要太担心这个的细节 给定1个维基百科标题和1个指定你想要第1段还是整个内容的布尔值,它将返回1个 LangChain Document 对象手机壁纸,它基本上只是1个附加了1些元数据的字符串。

元数据中的来源键很重要,因为模型在引用其来源时会使用它接下来,让我们设置1个机器人将要查询的资源语料库:sources = [ get_wiki_data("Unix", True), get_wiki_data(

"Microsoft_Windows", True), get_wiki_data("Linux", True), get_wiki_data("Seinfeld", True), ]最后,让我们将所有这些连接到 LangChain:

chain = load_q手机壁纸a_with_sources_chain(OpenAI(temperature=0)) defprint_answer(question): print( chain( {

"input_documents": sources, "question": question, }, return_only_outputs=

True, )["output_text"] )这做了几件事:它创建了1个 LangChain 链,该链设置了适当的问答提示 它还表明我手机壁纸们应使用 OpenAI API 为链提供动力而没有是其他服务(如 Cohere)。

它调用链,提供要查阅的源文件和问题它返回1个原始字符串,其中包含问题的答案及其使用的来源让我们看看它的实际效果! 在开始之前,请务必注册1个 OpenAI API 密钥$ export OPENAI_API_KEY=sk-。

OpenAI API 没有是免费的 当你迭代你的机器人时,1定要监控你花了多少钱!现在我们已经设置了 API 密钥,让我们试1试我们的机器人$ python3 Python。

3.8.13 (default, Oct42022, 14:00:32) [GCC9.4.0手机壁纸] on linux Type"help", "copyright", "credits" or "license"

for more information. >>> from langchain_bot import print_answer >>> print_answer("Who were the writers of Seinfeld?"

) The writers of Seinfeld were LarryDavid, JerrySeinfeld, LarryCharles, PeterMehlman, GreggKa手机壁纸vet, Carol

Leifer, DavidMandel, JeffSchaffer, SteveKoren, JenniferCrittenden, TomGammill, MaxPross, DanOKeefe, Charlie

Rubin, MarjorieGross, AlecBerg, ElainePope and SpikeFeresten. SOURCES: https://en.wikipedia.org/wiki/Seinfeld

>>> print_answer("What are the main differences between Linux and 手机壁纸Windows?") Linux and Windows are both operating systems, but

Linuxisopen-source and Unix-like, whileWindowsis proprietary and developed by Microsoft. Linuxis used on servers, embedded systems, and desktop computers,

whileWindowsis mainly used on desktop computers. SOURCES: http手机壁纸s://en.wikipedia.org/wiki/Unix https://en.wikipedia.org/wiki/Microsoft_Windows

https://en.wikipedia.org/wiki/Linux >>> print_answer("What are the differences between Keynesian and classical economics?"

) I dont know. SOURCES: N/A >>>我没有了解你怎么看,但我认为这令人印象深刻 它正在回答问题,手机壁纸提供额外的相关高低文,引用其来源,并知道何时说没有知道所以,既然我们已经证明这是有效的,它应该像将所有 Dagster 文档填充到源代码部分1样简单,对吧?。

4、处理有限的提示窗口大小没有幸的是,这并没有像将 Dagster 文档的整个语料库放入提示中那么简单 次要有两个原因:GPT API 按令牌收费,因此我们的目标是在我们的提示中使用尽可能少的令牌以节省资金,因为我们需要在用户提出问题时将整个提示发送到 API 机器人。

GPT API 在提示中有大约 4000 个令牌的限制,所以即使我们愿意为此付费,我们也没有能给它完整的 Dagster 文档 信息太多了5、处理大量文件让我们看看当我们有手机壁纸太多文档时会发生什么 没有幸的是,在达到令牌限制之前,我们只需要再添加几个文档:。

sources = [ get_wiki_data("Unix", True), get_wiki_data("Microsoft_Windows", True), get_wiki_data(

"Linux", True), get_wiki_data("Seinfeld", True), get_wiki_data("Matchbox_Twenty", True), get_wiki_data(

"Roman_Empir手机壁纸e", True), get_wiki_data("London", True), get_wiki_data("Python_(programming_language)"

, True), get_wiki_data("Monty_Python", True), ]当重新运行示例时,我们从 OpenAI API 收到错误:$ python3 -cfrom langchain_bot

import print_answer; print_answer("What are the main differences between Li手机壁纸nux and Windows?") openai.error.

InvalidRequestError: This models maximum context length is4097 tokens, however you requested 6215 tokens (

5959in your prompt; 256for the completion). Pleasereduce your prompt; or completion length.有两种选择可以解决这个问题。

我们可以使用没有同的链,也可以尝试限制模型使用的来源数量 让我们从第1个选项开始6、使用多步链

回想手机壁纸1下我们如何在玩具示例中创建链条:chain = load_qa_with_sources_chain(OpenAI(temperature=0))实际上有1个隐式的第二个参数来指定我们正在使用的链的类型。

到目前为止,我们正在使用填充链,它只是将所有源填充到提示中 我们可以使用另外两种类型的链:map_reduce:映射所有源并对其进行汇总,以便它们更有可能适合高低文窗口 这将为每个查询处理语料库中的每个标记,但可以并行运行。

refine:连续迭代每个源,并要求底层模型根据源改进其答案 根据我的经验,这太慢了以至于完全无法使用那么,让我们看看如果我们使用 map_reduce 链会发生什么 更手机壁纸新我们的玩具示例以将其作为参数传递:。

chain = load_qa_with_sources_chain(OpenAI(temperature=0), chain_type="map_reduce")让我们重新运行这个例子$ python3 -c。

from langchain_bot import print_answer; print_answer("What are the main differences between Linux and Windows?")

Linux is an open-source Unix-like operating system based on the手机壁纸 Linux kernel, while Windows is a group

of proprietary graphical operating system families developed and marketed by Microsoft. Linux distributions are typically packaged

as a Linux distribution, which includes the kernel and supporting system software and libraries, while

Windows distributions include手机壁纸 a windowing system such as X11 or Wayland, and a desktop environment such

as GNOME or KDE Plasma. SOURCES: https://en.wikipedia.org/wiki/Unix https://en.wikipedia.org/wiki/Microsoft_Windows

https://en.wikipedia.org/wiki/Linux有效! 然而,这确实需要对 OpenAI API 进行多次调用,并且向机器人提出的每个问题都需要处理每个手机壁纸令牌,这既缓慢又昂贵 此外,答案中存在1没有准确的地方,这可能来自摘要。

我们发现使用没有同的方法 - 向量空间搜索器材链 - 是迄今为止最好的解决方案。7、使用向量空间搜索引擎提高效率

我们可以使用向量空间搜索引擎解决 map_reduce 链的问题和 stuff 链的局限性 在高层次上:提前,我们创建1个传统的搜索索引并将所有源添加到其中在查询时,我们使用问题查询搜索索引并返回前 k 个结果。

我们使用这些结果作为我们在器材链中的来源让我们1次为这1步编写代码 首先,我们需要添加1些导入:from langchain.embeddings.openai import OpenAIEmbedding手机壁纸s 。

from langchain.vectorstores.faiss import FAISS接下来,让我们为所有来源创建1个 Faiss 搜索索引 幸运的是,LangChain 包含1个使它成为单行代码的帮助程序类。

search_index = FAISS.from_documents(sources, OpenAIEmbeddings()) 这段代码做了3件事:它创建1个 Faiss 内存索引它使用 OpenAI API 为每个来源创建嵌入(即特征向量),使其易于搜索。

如果需要,你可以使用其他嵌入,但 OpenAI 会为此应用程序生成高质量的嵌入它将每个手机壁纸来源添加到索引中最后,让我们更新其余代码以利用搜索索引 对于这个例子,我们将使用前 4 个搜索结果来告知模型的答案:。

chain = load_qa_with_sources_chain(OpenAI(temperature=0)) defprint_answer(question): print( chain( {

"input_documents": search_index.similarity_search(question, k=4), "question": question, }, 手机壁纸 return_only_outputs=

True, )["output_text"] ) 当我们运行这个例子时,它起作用了! 事实上,我们现在可以在 Faiss 索引中添加尽可能多的来源(而且数量很多!),我们的模型仍然会快速执行。

$ python3 -cfrom langchain_bot import print_answer; print_answer("Which members of Matchbox 20 play guitar?") Rob Thomas, Kyle Cook, and Paul Doucette pl手机壁纸ay guitar in Matchbox 20.

SOURCES: https://en.wikipedia.org/wiki/Matchbox_Twenty8、处理太大的文档

好的,现在让我们尝试处理更大的文档 通过将最后1个参数切换为 False,更改我们的来源列表以包括完整的维基百科页面,而没有仅仅是第1部分:sources = [ get_wiki_data("Unix"

, False), get_wiki_data("Microsoft_Windows", False), get_wiki_data("Linux", False), 手机壁纸 get_wiki_data(

"Seinfeld", False), get_wiki_data("Matchbox_Twenty", False), get_wiki_data("Roman_Empire", False

), get_wiki_data("London", False), get_wiki_data("Python_(programming_language)", False), get_wiki_data(

"Monty_Python", False), ]没有幸的是,我们现手机壁纸在在查询我们的机器人时遇到错误:$ python3 -cfrom langchain_bot import print_answer; print_answer("Who plays guitar in Matchbox 20?") openai.error.

InvalidRequestError: This models maximum context length is8191 tokens, however you requested 11161 tokens (

11161in your prompt; 0for the completion). Pleasereduce手机壁纸 your prompt; or completion length. Even though we are filtering down the individual documents, each document

is now so big we cannot fit it即使我们正在过滤单个文档,每个文档现在都太大了,我们无法将其放入高低文窗口解决此问题的1种非常简单但有效的方法是将文档简单地分成固定大小的块 虽然这看起来“太笨了,无法工作”,但实际上它在实践中似乎工作得很好。

LangChain 包含1个有用的实用程序来为我们做这件事 让我们从导入它开始吧from lan手机壁纸gchain.text_splitter import CharacterTextSplitter接下来,让我们遍历源列表并创建1个名为 source_chunks 的新列表,Faiss 索引将使用该列表代替完整文档:

source_chunks = []splitter = CharacterTextSplitter(separator=" ", chunk_size=1024, chunk_overlap=0)for

source in sources:forchunk in splitter.split_text(source.page_content):source_chunks.appe手机壁纸nd(Document(page_content

=chunk, metadata=source.metadata))search_index = FAISS.from_documents(source_chunks, OpenAIEmbeddings())

这里有几点需要注意:我们已将 CharacterTextSplitter 配置为创建最大大小为 1024 个字符且无重叠的块 此外,它们在空白边界处分裂 LangChain 中包含其他更智能的拆分器,它们利用 NLTK 和 spaCy 等库,但对于本示例,我们将使用最简单的选项。

文档中的所有块共享相同的元数据最后,当我们重新运行时,我们看到模手机壁纸型给了我们1个答案:$ python3 -cfrom langchain_bot import print_answer; print_answer("Which members of Matchbox 20 play guitar?") 。

RobThomas, PaulDoucette, and KyleCook play guitar inMatchbox20. SOURCES: https://en.wikipedia.org/wiki/Matchbox_Twenty

9、应用到 GitHub 存储库

现在让我们把写的器材应用到 GitHub 仓库中 让我们首手机壁纸先添加1些必需的导入:import pathlib import subprocess import tempfile接下来,我们需要1个函数来检查 GitHub 存储库的最新副本,抓取markdown文件,并返回1些 LangChain 文档。

defget_github_docs(repo_owner, repo_name):with tempfile.TemporaryDirectory() as d: subprocess.check_call(

f"git clone --depth 1 https://github.com/{repo_o手机壁纸wner}/{repo_name}.git .", cwd=d, shell=

True, ) git_sha = ( subprocess.check_output("git rev-parse HEAD", shell=True

, cwd=d) .decode("utf") .strip() ) repo_path = pathlib.Path(d) markdown_files = list(repo_path.glob(

"*/手机壁纸*.md")) + list( repo_path.glob("*/*.mdx") ) for markdown_file in markdown_files:

with open(markdown_file, "r") as f: relative_path = markdown_file.relative_to(repo_path) github_url =

f"https://github.com/{repo_owner}/{repo_name}/blob/{git_sha}/{relative_path}"yi手机壁纸eld Document(page_content=f.read(), metadata={

"source": github_url})这做了1些事情:它将所需 GitHub 存储库的最新提交签出到1一时目录中它获取 git sha(用于构建链接,模型将在其源列表中使用)它遍历 repo 中的每个降价文件(.md 或 .mdx)。

它在 GitHub 上构造1个 markdown 文件的 URL,从磁盘读取文件,并返回1个 Document现在让我们把它连接到我们的机器人上 用以下内容替换以前的源列表:sources = get_github_docs(。

"dagster-io", "dags手机壁纸ter") 10、尝试1下!让我们尝试1下,看看它是否理解 Dagster API 的细微差别 我们将从询问有关软件定义资产的问题开始$ python3 Python 。

3.8.13 (default, Oct 42022, 14:00:32) [GCC 9.4.0] on linux Type "help", "copyright", "credits" or "license"

for more information. >>> from langchain_bot import print_answer 手机壁纸 >>> print_answer("what is a software defined asset"

) A software-defined asset is a Dagster object that couples an asset to the function and upstream assets that are used to produce its contents. It enables a declarative approach to data management,

in which code is the source of truth on手机壁纸 what data assets should exist and how those assets are computed. SOURCES: https:

//github.com/dagster-io/dagster/blob/ba3a38112867607661062a3be681244f91de11d8/docs/content/concepts/assets/software-defined-assets.mdx

https://github.com/dagster-io/dagster/blob/ba3a38112867607661062a3be6手机壁纸81244f91de11d8/docs/content/guides/dagster/enriching-with-software-defined-assets.mdx

https://github.com/dagster-io/dagster/blob/ba3a38112867607661062a3be681244f91de11d8/docs/content/tutorial/assets/defining-an-asset.md

>>> print_answer("what is the difference between ops, jobs, assets and graphs") 手机壁纸 Ops are the core unit of computation

in Dagster and contain the logic of an orchestration graph. Jobs are the main unit of execution and monitoring

in Dagster and contain a graph of ops connected via data dependencies. Assets are persistent objects

in storage, such as a table, machine learning (M手机壁纸L) model, or file. Graphs are sets of interconnected ops or sub-graphs and form the core of jobs. SOURCES: https:

//github.com/dagster-io/dagster/blob/ba3a38112867607661062a3be681244f91de11d8/docs/content/concepts/ops-jobs-graphs/graphs.mdx

https://github.com/dagster-io/dagster/blob/ba手机壁纸3a38112867607661062a3be681244f91de11d8/docs/content/concepts/ops-jobs-graphs/jobs.mdx

https://github.com/dagster-io/dagster/blob/ba3a38112867607661062a3be681244f91de11d8/我对这个回应很满意 它能够令人信服地解释小众技术概念,而没有仅仅是从文档中逐字逐句地重复句子。

但是,此时你可能已经注意到我们的小机器人变得非常慢。 让我们解决这个问题!11、使用缓存嵌入以节省时间和金钱

我们现在有1个运行良好的聊天机器人,但它有1次要问题:启动时手机壁纸间非常慢 每次我们导入脚本时,有两个步骤特别慢:我们使用 git 克隆 repo,爬取每个 markdown 文件并将它们分块我们为每个文档调用 OpenAI API,创建嵌入,并将其添加到 Faiss 索引。

理想情况下,我们只会偶尔运行这些步骤并缓存索引以供后续运行使用 这将提高性能并显着降低成本,因为我们将没有再在启动时重新计算嵌入此外,如果这个过程没有是“全有或全无”,那就太好了 如果我们每次都可以迭代我们的 Faiss 索引或嵌入而没有重新克隆 repo,我们可以大大提高迭代速度。

我们没有再有简单的 Python 脚本 我们现在有1个数据管道,数据管道需要像 Dagster 这样的编排器 Da手机壁纸gster 使我们能够快速轻松地添加这种多步缓存功能,并支持其他功能,例如添加自动调度和传感器以在外部触发器上重新运行管道。

原文链接:http://www.bimant.com/blog/gpt-chatbot-hands-on/

为您推荐

gpt-n(GPT⑶问答机器人实战【LangChain】)gpt⑶ 1看就会

gpt-n(GPT⑶问答机器人实战【LangChain】)gpt⑶ 1看就会

提供一流的支持体验是我们项目成功的关键,但这需要我们核心团队成员的大量工作。此外,如果这个过程不是“全有...

2023-05-22 栏目:科技派

当前非电脑浏览器正常宽度,请使用移动设备访问本站!