diff --git a/content/LangChain for LLM Application Development/5.基于文档的问答 Question and Answer.ipynb b/content/LangChain for LLM Application Development/5.基于文档的问答 Question and Answer.ipynb index f8f9719..60bc045 100644 --- a/content/LangChain for LLM Application Development/5.基于文档的问答 Question and Answer.ipynb +++ b/content/LangChain for LLM Application Development/5.基于文档的问答 Question and Answer.ipynb @@ -1 +1,925 @@ -{"cells":[{"cell_type":"markdown","id":"f200ba9a","metadata":{},"source":["# 第五章 基于文档的问答\n","\n"," - [一、设置OpenAI API Key](#一、设置OpenAI-API-Key)\n"," - [一、导入embedding模型和向量存储组件](#一、导入embedding模型和向量存储组件)\n"," - [1.1 创建向量存储](#1.1-创建向量存储)\n"," - [1.2 使用语言模型与文档结合使用](#1.2-使用语言模型与文档结合使用)\n"," - [二、 如何回答我们文档的相关问题](#二、-如何回答我们文档的相关问题)\n"]},{"cell_type":"markdown","id":"52824b89-532a-4e54-87e9-1410813cd39e","metadata":{},"source":["\n","本章内容主要利用langchain构建向量数据库,可以在文档上方或关于文档回答问题,因此,给定从PDF文件、网页或某些公司的内部文档收集中提取的文本,使用llm回答有关这些文档内容的问题"]},{"cell_type":"markdown","id":"42ccf132-cfab-4153-97b5-d545faae4d36","metadata":{"tags":[]},"source":["## 一、设置OpenAI API Key\n","\n","登陆 [OpenAI 账户](https://platform.openai.com/account/api-keys) 获取API Key,然后将其设置为环境变量。\n","\n","- 如果你想要设置为全局环境变量,可以参考[知乎文章](https://zhuanlan.zhihu.com/p/627665725)。\n","- 如果你想要设置为本地/项目环境变量,在本文件目录下创建`.env`文件, 打开文件输入以下内容。\n","\n","

\n"," OPENAI_API_KEY=\"your_api_key\" \n","

\n"," \n"," 替换\"your_api_key\"为你自己的 API Key"]},{"cell_type":"code","execution_count":1,"id":"cc33ceb1-535f-454d-988c-347a8b14fd72","metadata":{},"outputs":[],"source":["# 下载需要的包python-dotenv和openai\n","# 如果你需要查看安装过程日志,可删除 -q \n","!pip install -q python-dotenv\n","!pip install -q openai"]},{"cell_type":"code","execution_count":2,"id":"e3c97235-f101-47f2-92db-1c37f4bf9845","metadata":{"tags":[]},"outputs":[],"source":["import os\n","import openai\n","from dotenv import load_dotenv, find_dotenv\n","\n","# 读取本地/项目的环境变量。\n","\n","# find_dotenv()寻找并定位.env文件的路径\n","# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n","# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n","_ = load_dotenv(find_dotenv())\n","\n","# 获取环境变量 OPENAI_API_KEY\n","openai.api_key = os.environ['OPENAI_API_KEY'] "]},{"cell_type":"code","execution_count":52,"id":"af8c3c96","metadata":{},"outputs":[{"data":{"text/plain":["'\\n\\n人工智能是一项极具前景的技术,它的发展正在改变人类的生活方式,带来了无数的便利,也被认为是未来发展的重要标志。人工智能的发展让许多复杂的任务变得更加容易,更高效的完成,节省了大量的时间和精力,为人类发展带来了极大的帮助。'"]},"execution_count":52,"metadata":{},"output_type":"execute_result"}],"source":["from langchain.llms import OpenAI\n","\n","llm = OpenAI(model_name=\"text-davinci-003\",max_tokens=1024)\n","llm(\"怎么评价人工智能\")"]},{"cell_type":"markdown","id":"8cb7a7ec","metadata":{"height":30},"source":["## 一、导入embedding模型和向量存储组件\n","使用Dock Array内存搜索向量存储,作为一个内存向量存储,不需要连接外部数据库"]},{"cell_type":"code","execution_count":3,"id":"974acf8e-8f88-42de-88f8-40a82cb58e8b","metadata":{"height":98},"outputs":[],"source":["from langchain.chains import RetrievalQA #检索QA链,在文档上进行检索\n","from langchain.chat_models import ChatOpenAI #openai模型\n","from langchain.document_loaders import CSVLoader #文档加载器,采用csv格式存储\n","from langchain.vectorstores import DocArrayInMemorySearch #向量存储\n","from IPython.display import display, Markdown #在jupyter显示信息的工具"]},{"cell_type":"code","execution_count":4,"id":"7249846e","metadata":{"height":75},"outputs":[],"source":["#读取文件\n","file = 'OutdoorClothingCatalog_1000.csv'\n","loader = CSVLoader(file_path=file)"]},{"cell_type":"code","execution_count":24,"id":"7724f00e","metadata":{"height":30},"outputs":[{"data":{"text/html":["
\n","\n","\n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n","
012
0NaNnamedescription
10.0Women's Campside OxfordsThis ultracomfortable lace-to-toe Oxford boast...
21.0Recycled Waterhog Dog Mat, Chevron WeaveProtect your floors from spills and splashing ...
32.0Infant and Toddler Girls' Coastal Chill Swimsu...She'll love the bright colors, ruffles and exc...
43.0Refresh Swimwear, V-Neck Tankini ContrastsWhether you're going for a swim or heading out...
............
996995.0Men's Classic Denim, Standard FitCrafted from premium denim that will last wash...
997996.0CozyPrint Sweater Fleece PulloverThe ultimate sweater fleece - made from superi...
998997.0Women's NRS Endurance Spray Paddling PantsThese comfortable and affordable splash paddli...
999998.0Women's Stop Flies HoodieThis great-looking hoodie uses No Fly Zone Tec...
1000999.0Modern Utility BagThis US-made crossbody bag is built with the s...
\n","

1001 rows × 3 columns

\n","
"],"text/plain":[" 0 1 \n","0 NaN name \\\n","1 0.0 Women's Campside Oxfords \n","2 1.0 Recycled Waterhog Dog Mat, Chevron Weave \n","3 2.0 Infant and Toddler Girls' Coastal Chill Swimsu... \n","4 3.0 Refresh Swimwear, V-Neck Tankini Contrasts \n","... ... ... \n","996 995.0 Men's Classic Denim, Standard Fit \n","997 996.0 CozyPrint Sweater Fleece Pullover \n","998 997.0 Women's NRS Endurance Spray Paddling Pants \n","999 998.0 Women's Stop Flies Hoodie \n","1000 999.0 Modern Utility Bag \n","\n"," 2 \n","0 description \n","1 This ultracomfortable lace-to-toe Oxford boast... \n","2 Protect your floors from spills and splashing ... \n","3 She'll love the bright colors, ruffles and exc... \n","4 Whether you're going for a swim or heading out... \n","... ... \n","996 Crafted from premium denim that will last wash... \n","997 The ultimate sweater fleece - made from superi... \n","998 These comfortable and affordable splash paddli... \n","999 This great-looking hoodie uses No Fly Zone Tec... \n","1000 This US-made crossbody bag is built with the s... \n","\n","[1001 rows x 3 columns]"]},"execution_count":24,"metadata":{},"output_type":"execute_result"}],"source":["#查看数据\n","import pandas as pd\n","data = pd.read_csv(file,header=None)\n","data"]},{"cell_type":"markdown","id":"3bd6422c","metadata":{},"source":["提供了一个户外服装的CSV文件,我们将使用它与语言模型结合使用"]},{"cell_type":"markdown","id":"2963fc63","metadata":{},"source":["### 1.1 创建向量存储\n","将导入一个索引,即向量存储索引创建器"]},{"cell_type":"code","execution_count":25,"id":"5bfaba30","metadata":{"height":30},"outputs":[],"source":["from langchain.indexes import VectorstoreIndexCreator #导入向量存储索引创建器"]},{"cell_type":"code","execution_count":null,"id":"9e200726","metadata":{"height":64},"outputs":[],"source":["'''\n","将指定向量存储类,创建完成后,我们将从加载器中调用,通过文档记载器列表加载\n","'''\n","\n","index = VectorstoreIndexCreator(\n"," vectorstore_cls=DocArrayInMemorySearch\n",").from_loaders([loader])"]},{"cell_type":"code","execution_count":9,"id":"34562d81","metadata":{"height":47},"outputs":[],"source":["query =\"Please list all your shirts with sun protection \\\n","in a table in markdown and summarize each one.\""]},{"cell_type":"code","execution_count":21,"id":"cfd0cc37","metadata":{"height":30},"outputs":[],"source":["response = index.query(query)#使用索引查询创建一个响应,并传入这个查询"]},{"cell_type":"code","execution_count":23,"id":"ae21f1ff","metadata":{"height":30,"scrolled":true},"outputs":[{"data":{"text/markdown":["\n","\n","| Name | Description |\n","| --- | --- |\n","| Men's Tropical Plaid Short-Sleeve Shirt | UPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets |\n","| Men's Plaid Tropic Shirt, Short-Sleeve | UPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets |\n","| Men's TropicVibe Shirt, Short-Sleeve | UPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, machine wash and dry, front and back cape venting, two front bellows pockets |\n","| Sun Shield Shirt by | UPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, handwash, line dry, wicks moisture, fits comfortably over swimsuit, abrasion resistant |\n","\n","All four shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. The Men's Tropical Plaid Short-Sleeve Shirt is made of 100% polyester and is wrinkle-resistant"],"text/plain":[""]},"metadata":{},"output_type":"display_data"}],"source":["display(Markdown(response))#查看查询返回的内容"]},{"cell_type":"markdown","id":"eb74cc79","metadata":{},"source":["得到了一个Markdown表格,其中包含所有带有防晒衣的衬衫的名称和描述,还得到了一个语言模型提供的不错的小总结"]},{"cell_type":"markdown","id":"dd34e50e","metadata":{},"source":["### 1.2 使用语言模型与文档结合使用\n","想要使用语言模型并将其与我们的许多文档结合使用,但是语言模型一次只能检查几千个单词,如果我们有非常大的文档,如何让语言模型回答关于其中所有内容的问题呢?通过embedding和向量存储实现\n","* embedding \n","文本片段创建数值表示文本语义,相似内容的文本片段将具有相似的向量,这使我们可以在向量空间中比较文本片段\n","* 向量数据库 \n","向量数据库是存储我们在上一步中创建的这些向量表示的一种方式,我们创建这个向量数据库的方式是用来自传入文档的文本块填充它。\n","当我们获得一个大的传入文档时,我们首先将其分成较小的块,因为我们可能无法将整个文档传递给语言模型,因此采用分块embedding的方式储存到向量数据库中。这就是创建索引的过程。\n","\n","通过运行时使用索引来查找与传入查询最相关的文本片段,然后我们将其与向量数据库中的所有向量进行比较,并选择最相似的n个,返回语言模型得到最终答案"]},{"cell_type":"code","execution_count":26,"id":"631396c6","metadata":{"height":30},"outputs":[],"source":["#创建一个文档加载器,通过csv格式加载\n","loader = CSVLoader(file_path=file)\n","docs = loader.load()"]},{"cell_type":"code","execution_count":27,"id":"4a977f44","metadata":{"height":30},"outputs":[{"data":{"text/plain":["Document(page_content=\": 0\\nname: Women's Campside Oxfords\\ndescription: This ultracomfortable lace-to-toe Oxford boasts a super-soft canvas, thick cushioning, and quality construction for a broken-in feel from the first time you put them on. \\n\\nSize & Fit: Order regular shoe size. For half sizes not offered, order up to next whole size. \\n\\nSpecs: Approx. weight: 1 lb.1 oz. per pair. \\n\\nConstruction: Soft canvas material for a broken-in feel and look. Comfortable EVA innersole with Cleansport NXT® antimicrobial odor control. Vintage hunt, fish and camping motif on innersole. Moderate arch contour of innersole. EVA foam midsole for cushioning and support. Chain-tread-inspired molded rubber outsole with modified chain-tread pattern. Imported. \\n\\nQuestions? Please contact us for any inquiries.\", metadata={'source': 'OutdoorClothingCatalog_1000.csv', 'row': 0})"]},"execution_count":27,"metadata":{},"output_type":"execute_result"}],"source":["docs[0]#查看单个文档,我们可以看到每个文档对应于CSV中的一个块"]},{"cell_type":"code","execution_count":31,"id":"e875693a","metadata":{"height":47},"outputs":[],"source":["'''\n","因为这些文档已经非常小了,所以我们实际上不需要在这里进行任何分块,可以直接进行embedding\n","'''\n","\n","from langchain.embeddings import OpenAIEmbeddings #要创建可以直接进行embedding,我们将使用OpenAI的可以直接进行embedding类\n","embeddings = OpenAIEmbeddings() #初始化"]},{"cell_type":"code","execution_count":32,"id":"779bec75","metadata":{"height":30},"outputs":[],"source":["embed = embeddings.embed_query(\"Hi my name is Harrison\")#让我们使用embedding上的查询方法为特定文本创建embedding"]},{"cell_type":"code","execution_count":33,"id":"699aaaf9","metadata":{"height":30},"outputs":[{"name":"stdout","output_type":"stream","text":["1536\n"]}],"source":["print(len(embed))#查看这个embedding,我们可以看到有超过一千个不同的元素"]},{"cell_type":"code","execution_count":34,"id":"9d00d346","metadata":{"height":30},"outputs":[{"name":"stdout","output_type":"stream","text":["[-0.021933607757091522, 0.006697045173496008, -0.01819835603237152, -0.039113257080316544, -0.014060650952160358]\n"]}],"source":["print(embed[:5])#每个元素都是不同的数字值,组合起来,这就创建了这段文本的总体数值表示"]},{"cell_type":"code","execution_count":35,"id":"27ad0bb0","metadata":{"height":81},"outputs":[],"source":["'''\n","为刚才的文本创建embedding,准备将它们存储在向量存储中,使用向量存储上的from documents方法来实现。\n","该方法接受文档列表、嵌入对象,然后我们将创建一个总体向量存储\n","'''\n","db = DocArrayInMemorySearch.from_documents(\n"," docs, \n"," embeddings\n",")"]},{"cell_type":"code","execution_count":36,"id":"0329bfd5","metadata":{"height":30},"outputs":[],"source":["query = \"Please suggest a shirt with sunblocking\""]},{"cell_type":"code","execution_count":37,"id":"7909c6b7","metadata":{"height":30},"outputs":[],"source":["docs = db.similarity_search(query)#使用这个向量存储来查找与传入查询类似的文本,如果我们在向量存储中使用相似性搜索方法并传入一个查询,我们将得到一个文档列表"]},{"cell_type":"code","execution_count":38,"id":"43321853","metadata":{"height":30},"outputs":[{"data":{"text/plain":["4"]},"execution_count":38,"metadata":{},"output_type":"execute_result"}],"source":["len(docs)# 我们可以看到它返回了四个文档"]},{"cell_type":"code","execution_count":39,"id":"6eba90b5","metadata":{"height":30},"outputs":[{"data":{"text/plain":["Document(page_content=': 255\\nname: Sun Shield Shirt by\\ndescription: \"Block the sun, not the fun – our high-performance sun shirt is guaranteed to protect from harmful UV rays. \\n\\nSize & Fit: Slightly Fitted: Softly shapes the body. Falls at hip.\\n\\nFabric & Care: 78% nylon, 22% Lycra Xtra Life fiber. UPF 50+ rated – the highest rated sun protection possible. Handwash, line dry.\\n\\nAdditional Features: Wicks moisture for quick-drying comfort. Fits comfortably over your favorite swimsuit. Abrasion resistant for season after season of wear. Imported.\\n\\nSun Protection That Won\\'t Wear Off\\nOur high-performance fabric provides SPF 50+ sun protection, blocking 98% of the sun\\'s harmful rays. This fabric is recommended by The Skin Cancer Foundation as an effective UV protectant.', metadata={'source': 'OutdoorClothingCatalog_1000.csv', 'row': 255})"]},"execution_count":39,"metadata":{},"output_type":"execute_result"}],"source":["docs[0] #,如果我们看第一个文档,我们可以看到它确实是一件关于防晒的衬衫"]},{"cell_type":"markdown","id":"fe41b36f","metadata":{},"source":["## 二、 如何回答我们文档的相关问题\n","首先,我们需要从这个向量存储中创建一个检索器,检索器是一个通用接口,可以由任何接受查询并返回文档的方法支持。接下来,因为我们想要进行文本生成并返回自然语言响应\n"]},{"cell_type":"code","execution_count":40,"id":"c0c3596e","metadata":{"height":30},"outputs":[],"source":["retriever = db.as_retriever() #创建检索器通用接口"]},{"cell_type":"code","execution_count":55,"id":"0625f5e8","metadata":{"height":47},"outputs":[],"source":["llm = ChatOpenAI(temperature = 0.0,max_tokens=1024) #导入语言模型\n"]},{"cell_type":"code","execution_count":43,"id":"a573f58a","metadata":{"height":47},"outputs":[],"source":["qdocs = \"\".join([docs[i].page_content for i in range(len(docs))]) # 将合并文档中的所有页面内容到一个变量中\n"]},{"cell_type":"code","execution_count":null,"id":"14682d95","metadata":{"height":64},"outputs":[],"source":["response = llm.call_as_llm(f\"{qdocs} Question: Please list all your \\\n","shirts with sun protection in a table in markdown and summarize each one.\") #列出所有具有防晒功能的衬衫并在Markdown表格中总结每个衬衫的语言模型\n"]},{"cell_type":"code","execution_count":28,"id":"8bba545b","metadata":{"height":30},"outputs":[{"data":{"text/markdown":["| Name | Description |\n","| --- | --- |\n","| Sun Shield Shirt | High-performance sun shirt with UPF 50+ sun protection, moisture-wicking, and abrasion-resistant fabric. Recommended by The Skin Cancer Foundation. |\n","| Men's Plaid Tropic Shirt | Ultracomfortable shirt with UPF 50+ sun protection, wrinkle-free fabric, and front/back cape venting. Made with 52% polyester and 48% nylon. |\n","| Men's TropicVibe Shirt | Men's sun-protection shirt with built-in UPF 50+ and front/back cape venting. Made with 71% nylon and 29% polyester. |\n","| Men's Tropical Plaid Short-Sleeve Shirt | Lightest hot-weather shirt with UPF 50+ sun protection, front/back cape venting, and two front bellows pockets. Made with 100% polyester and is wrinkle-resistant. |\n","\n","All of these shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. They are made with high-performance fabrics that are moisture-wicking, wrinkle-resistant, and abrasion-resistant. The Men's Plaid Tropic Shirt and Men's Tropical Plaid Short-Sleeve Shirt both have front/back cape venting for added breathability. The Sun Shield Shirt is recommended by The Skin Cancer Foundation as an effective UV protectant."],"text/plain":[""]},"metadata":{},"output_type":"display_data"}],"source":["display(Markdown(response))"]},{"cell_type":"markdown","id":"12f042e7","metadata":{},"source":["在此处打印响应,我们可以看到我们得到了一个表格,正如我们所要求的那样"]},{"cell_type":"code","execution_count":56,"id":"32c94d22","metadata":{"height":115},"outputs":[],"source":["''' \n","通过LangChain链封装起来\n","创建一个检索QA链,对检索到的文档进行问题回答,要创建这样的链,我们将传入几个不同的东西\n","1、语言模型,在最后进行文本生成\n","2、传入链类型,这里使用stuff,将所有文档塞入上下文并对语言模型进行一次调用\n","3、传入一个检索器\n","'''\n","\n","\n","qa_stuff = RetrievalQA.from_chain_type(\n"," llm=llm, \n"," chain_type=\"stuff\", \n"," retriever=retriever, \n"," verbose=True\n",")"]},{"cell_type":"code","execution_count":46,"id":"e4769316","metadata":{"height":47},"outputs":[],"source":["query = \"Please list all your shirts with sun protection in a table \\\n","in markdown and summarize each one.\"#创建一个查询并在此查询上运行链"]},{"cell_type":"code","execution_count":null,"id":"1fc3c2f3","metadata":{"height":30},"outputs":[],"source":["response = qa_stuff.run(query)"]},{"cell_type":"code","execution_count":58,"id":"fba1a5db","metadata":{"height":30},"outputs":[{"data":{"text/markdown":["\n","\n","| Name | Description |\n","| --- | --- |\n","| Men's Tropical Plaid Short-Sleeve Shirt | UPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets |\n","| Men's Plaid Tropic Shirt, Short-Sleeve | UPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets |\n","| Men's TropicVibe Shirt, Short-Sleeve | UPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, machine wash and dry, front and back cape venting, two front bellows pockets |\n","| Sun Shield Shirt by | UPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, handwash, line dry, wicks moisture, fits comfortably over swimsuit, abrasion resistant |\n","\n","All four shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. The Men's Tropical Plaid Short-Sleeve Shirt is made of 100% polyester and is wrinkle-resistant"],"text/plain":[""]},"metadata":{},"output_type":"display_data"}],"source":["display(Markdown(response))#使用 display 和 markdown 显示它"]},{"cell_type":"markdown","id":"e28c5657","metadata":{},"source":["这两个方式返回相同的结果"]},{"cell_type":"markdown","id":"44f1fa38","metadata":{},"source":["想在许多不同类型的块上执行相同类型的问答,该怎么办?之前的实验中只返回了4个文档,如果有多个文档,那么我们可以使用几种不同的方法\n","* Map Reduce \n","将所有块与问题一起传递给语言模型,获取回复,使用另一个语言模型调用将所有单独的回复总结成最终答案,它可以在任意数量的文档上运行。可以并行处理单个问题,同时也需要更多的调用。它将所有文档视为独立的\n","* Refine \n","用于循环许多文档,际上是迭代的,建立在先前文档的答案之上,非常适合前后因果信息并随时间逐步构建答案,依赖于先前调用的结果。它通常需要更长的时间,并且基本上需要与Map Reduce一样多的调用\n","* Map Re-rank \n","对每个文档进行单个语言模型调用,要求它返回一个分数,选择最高分,这依赖于语言模型知道分数应该是什么,需要告诉它,如果它与文档相关,则应该是高分,并在那里精细调整说明,可以批量处理它们相对较快,但是更加昂贵\n","* Stuff \n","将所有内容组合成一个文档"]}],"metadata":{"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.9.12"},"toc":{"base_numbering":1,"nav_menu":{},"number_sections":false,"sideBar":true,"skip_h1_title":false,"title_cell":"Table of Contents","title_sidebar":"Contents","toc_cell":false,"toc_position":{},"toc_section_display":true,"toc_window_display":true}},"nbformat":4,"nbformat_minor":5} +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f200ba9a", + "metadata": {}, + "source": [ + "# 第五章 基于文档的问答\n", + "\n", + " - [一、设置OpenAI API Key](#一、设置OpenAI-API-Key)\n", + " - [一、导入embedding模型和向量存储组件](#一、导入embedding模型和向量存储组件)\n", + " - [1.1 创建向量存储](#1.1-创建向量存储)\n", + " - [1.2 使用语言模型与文档结合使用](#1.2-使用语言模型与文档结合使用)\n", + " - [二、 如何回答我们文档的相关问题](#二、-如何回答我们文档的相关问题)\n" + ] + }, + { + "cell_type": "markdown", + "id": "52824b89-532a-4e54-87e9-1410813cd39e", + "metadata": {}, + "source": [ + "常见的应用场景是使用大语言模型来构建一个能够回答关于给定文档和文档集合的问答系统。对于给定的文档, 比如从PDF、网页、公司主页中提取构建的内部文档集合,我们可以使用大语言模型来回答关于这些文档内容的问题,以帮助用户更有效地获取和使用他们所需要的信息。这种方式非常有效且灵活地适用于实际应用场景,因为它不仅仅利用大语言模型已有的训练集数据信息,它还能使用外部信息。\n", + "\n", + "这个过程,我们会涉及LongChain中的其他组件,比如:表征模型(Embedding Models)和向量储存(Vector Stores)" + ] + }, + { + "cell_type": "markdown", + "id": "42ccf132-cfab-4153-97b5-d545faae4d36", + "metadata": { + "tags": [] + }, + "source": [ + "## 一、设置OpenAI API Key" + ] + }, + { + "cell_type": "markdown", + "id": "83823216-ebf8-4554-9e8f-6d1b0c6878e7", + "metadata": {}, + "source": [ + "\n", + "登陆 [OpenAI 账户](https://platform.openai.com/account/api-keys) 获取API Key,然后将其设置为环境变量。\n", + "\n", + "- 如果你想要设置为全局环境变量,可以参考[知乎文章](https://zhuanlan.zhihu.com/p/627665725)。\n", + "- 如果你想要设置为本地/项目环境变量,在本文件目录下创建`.env`文件, 打开文件输入以下内容。\n", + "\n", + "

\n", + " OPENAI_API_KEY=\"your_api_key\" \n", + "

\n", + " \n", + " 替换\"your_api_key\"为你自己的 API Key" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "cc33ceb1-535f-454d-988c-347a8b14fd72", + "metadata": {}, + "outputs": [], + "source": [ + "# 下载需要的包python-dotenv和openai\n", + "# 如果你需要查看安装过程日志,可删除 -q \n", + "!pip install -q python-dotenv\n", + "!pip install -q openai" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "e3c97235-f101-47f2-92db-1c37f4bf9845", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import os\n", + "import openai\n", + "from dotenv import load_dotenv, find_dotenv\n", + "\n", + "# 读取本地/项目的环境变量。\n", + "\n", + "# find_dotenv()寻找并定位.env文件的路径\n", + "# load_dotenv()读取该.env文件,并将其中的环境变量加载到当前的运行环境中 \n", + "# 如果你设置的是全局的环境变量,这行代码则没有任何作用。\n", + "_ = load_dotenv(find_dotenv())\n", + "\n", + "# 获取环境变量 OPENAI_API_KEY\n", + "openai.api_key = os.environ['OPENAI_API_KEY'] " + ] + }, + { + "cell_type": "markdown", + "id": "8cb7a7ec", + "metadata": { + "height": 30 + }, + "source": [ + "## 一、直接" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "6fbf1fe4-411a-4d22-b362-ac8400fa31b9", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install --upgrade -q langchain\n", + "!pip install -q docarray" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "974acf8e-8f88-42de-88f8-40a82cb58e8b", + "metadata": { + "height": 98 + }, + "outputs": [], + "source": [ + "from langchain.chains import RetrievalQA #检索QA链,在文档上进行检索\n", + "from langchain.chat_models import ChatOpenAI #openai模型\n", + "from langchain.document_loaders import CSVLoader #文档加载器,采用csv格式存储\n", + "from langchain.vectorstores import DocArrayInMemorySearch #向量存储\n", + "from IPython.display import display, Markdown #在jupyter显示信息的工具" + ] + }, + { + "cell_type": "markdown", + "id": "159206b6-46a8-47ee-99a8-13bf7d554da4", + "metadata": {}, + "source": [ + "### 1.1 导入数据" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7249846e", + "metadata": { + "height": 75 + }, + "outputs": [], + "source": [ + "file = 'data/OutdoorClothingCatalog_1000.csv'\n", + "loader = CSVLoader(file_path=file)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "7724f00e", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namedescription
0Women's Campside OxfordsThis ultracomfortable lace-to-toe Oxford boast...
1Recycled Waterhog Dog Mat, Chevron WeaveProtect your floors from spills and splashing ...
2Infant and Toddler Girls' Coastal Chill Swimsu...She'll love the bright colors, ruffles and exc...
3Refresh Swimwear, V-Neck Tankini ContrastsWhether you're going for a swim or heading out...
4EcoFlex 3L Storm PantsOur new TEK O2 technology makes our four-seaso...
\n", + "
" + ], + "text/plain": [ + " name \\\n", + "0 Women's Campside Oxfords \n", + "1 Recycled Waterhog Dog Mat, Chevron Weave \n", + "2 Infant and Toddler Girls' Coastal Chill Swimsu... \n", + "3 Refresh Swimwear, V-Neck Tankini Contrasts \n", + "4 EcoFlex 3L Storm Pants \n", + "\n", + " description \n", + "0 This ultracomfortable lace-to-toe Oxford boast... \n", + "1 Protect your floors from spills and splashing ... \n", + "2 She'll love the bright colors, ruffles and exc... \n", + "3 Whether you're going for a swim or heading out... \n", + "4 Our new TEK O2 technology makes our four-seaso... " + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#用Pandas导入并查看数据\n", + "import pandas as pd\n", + "\n", + "data = pd.read_csv(file,usecols=[1, 2])\n", + "data.head()" + ] + }, + { + "cell_type": "markdown", + "id": "3bd6422c", + "metadata": {}, + "source": [ + "提供了一个户外服装的CSV文件,我们将使用它与语言模型结合使用" + ] + }, + { + "cell_type": "markdown", + "id": "2963fc63", + "metadata": {}, + "source": [ + "### 1.2 基本文档加载器创建向量存储" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "5bfaba30", + "metadata": { + "height": 30 + }, + "outputs": [], + "source": [ + "from langchain.indexes import VectorstoreIndexCreator #导入向量存储索引创建器" + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "9e200726", + "metadata": { + "height": 64 + }, + "outputs": [], + "source": [ + "# 创建指定向量存储类\n", + "# 创建完成后,从加载器中调用, 通过文档加载器列表加载\n", + "index = VectorstoreIndexCreator(vectorstore_cls=DocArrayInMemorySearch).from_loaders([loader])" + ] + }, + { + "cell_type": "markdown", + "id": "297216bf-ada7-498b-b448-7d98aadbfc27", + "metadata": {}, + "source": [ + "### 1.3 查询创建的向量存储" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "34562d81", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "query =\"Please list all your shirts with sun protection \\\n", + "in a table in markdown and summarize each one.\"" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "cfd0cc37", + "metadata": { + "height": 30 + }, + "outputs": [], + "source": [ + "response = index.query(query)#使用索引查询创建一个响应,并传入这个查询" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "ae21f1ff", + "metadata": { + "height": 30, + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "\n", + "\n", + "| Name | Description |\n", + "| --- | --- |\n", + "| Men's Tropical Plaid Short-Sleeve Shirt | UPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets |\n", + "| Men's Plaid Tropic Shirt, Short-Sleeve | UPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets |\n", + "| Men's TropicVibe Shirt, Short-Sleeve | UPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, wrinkle resistant, front and back cape venting, two front bellows pockets |\n", + "| Sun Shield Shirt by | UPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, wicks moisture, fits comfortably over swimsuit, abrasion resistant |\n", + "\n", + "All four shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. The Men's Tropical Plaid Short-Sleeve Shirt is made of 100% polyester and is wrinkle-resistant. The Men's Plaid Trop" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(Markdown(response))#查看查询返回的内容" + ] + }, + { + "cell_type": "markdown", + "id": "eb74cc79", + "metadata": {}, + "source": [ + "得到了一个Markdown表格,其中包含所有带有防晒衣的衬衫的名称和描述,还得到了一个语言模型提供的不错的小总结" + ] + }, + { + "cell_type": "markdown", + "id": "dd34e50e", + "metadata": {}, + "source": [ + "## 二、 结合表征模型和向量存储\n", + "\n", + "使用语言模型与文档结合使用时,语言模型一次只能使用几千个单词的信息。如果我们文档比较长,如何让语言模型回答关于其中所有内容的问题呢?我们通过几个通过向量表征(Embeddings)和向量存储(Vector Store)实现\n", + "\n", + "文本表征(Embeddings)是对文本语义的向量表征,相似内容的文本具有相似的表征向量。这使我们可以在向量空间中比较文本的相似性。\n", + "\n", + "向量数据库(Vector Database)用来存储文档的文本块。对于给定的文档,我们首先将其分成较小的文本块(chunks),然后获取每个小文本块的文本表征,并将这些表征储存在向量数据库中。这个流程正是创建索引(index)的过程。将文档分成小文本快的原因在于我们可能无法将整个文档传入语言模型进行处理。\n", + "\n", + "索引创建完成后,我们可以使用索引来查找与传入的查询(Query)最相关的文本片段 - 首先我们为查询获取向量表征,然后我们将其与向量数据库中的所有向量进行比较并选择最相似的n个文本块,最后我们将这些相似的文本块构建提示,并输入到语言模型,从而得到最终答案。" + ] + }, + { + "cell_type": "markdown", + "id": "20d9f53b-a4cd-44df-9ac1-8cba20db129f", + "metadata": {}, + "source": [ + "### 2.1 导入数据" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "631396c6", + "metadata": { + "height": 30 + }, + "outputs": [], + "source": [ + "#创建一个文档加载器,通过csv格式加载\n", + "loader = CSVLoader(file_path=file)\n", + "docs = loader.load()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "4a977f44", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Document(page_content=\": 0\\nname: Women's Campside Oxfords\\ndescription: This ultracomfortable lace-to-toe Oxford boasts a super-soft canvas, thick cushioning, and quality construction for a broken-in feel from the first time you put them on. \\n\\nSize & Fit: Order regular shoe size. For half sizes not offered, order up to next whole size. \\n\\nSpecs: Approx. weight: 1 lb.1 oz. per pair. \\n\\nConstruction: Soft canvas material for a broken-in feel and look. Comfortable EVA innersole with Cleansport NXT® antimicrobial odor control. Vintage hunt, fish and camping motif on innersole. Moderate arch contour of innersole. EVA foam midsole for cushioning and support. Chain-tread-inspired molded rubber outsole with modified chain-tread pattern. Imported. \\n\\nQuestions? Please contact us for any inquiries.\", metadata={'source': 'data/OutdoorClothingCatalog_1000.csv', 'row': 0})" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#查看单个文档,每个文档对应于CSV中的一行数据\n", + "docs[0]" + ] + }, + { + "cell_type": "markdown", + "id": "2c975206-3ad1-41ad-af54-b51e3b6fdefc", + "metadata": {}, + "source": [ + "### 2.2 文本向量表征模型" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "e875693a", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "#使用OpenAIEmbedding类\n", + "from langchain.embeddings import OpenAIEmbeddings \n", + "embeddings = OpenAIEmbeddings() #初始化" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "779bec75", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1536\n" + ] + } + ], + "source": [ + "#因为文档比较短了,所以这里不需要进行任何分块,可以直接进行向量表征\n", + "#使用初始化OpenAIEmbedding实例上的查询方法embed_query为文本创建向量表征\n", + "embed = embeddings.embed_query(\"Hi my name is Harrison\")\n", + "\n", + "#查看得到向量表征的长度\n", + "print(len(embed))" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9d00d346", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[-0.02194717898964882, 0.006735079921782017, -0.01816144771873951, -0.03916534036397934, -0.014086442068219185]\n" + ] + } + ], + "source": [ + "#每个元素都是不同的数字值,组合起来就是文本的向量表征\n", + "print(embed[:5])" + ] + }, + { + "cell_type": "markdown", + "id": "e60b3acd-a9ae-4085-a002-e6db3bf477f2", + "metadata": {}, + "source": [ + "### 2.3 基于向量表征创建向量存储" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "27ad0bb0", + "metadata": { + "height": 81 + }, + "outputs": [], + "source": [ + "# 将刚才创建文本向量表征(embeddings)存储在向量存储(vector store)中\n", + "# 使用DocArrayInMemorySearch类的from_documents方法来实现\n", + "# 该方法接受文档列表以及向量表征模型作为输入\n", + "db = DocArrayInMemorySearch.from_documents(docs, embeddings)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "13783b64-43ce-4e8d-8f97-ec4f07b15015", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'0.0.234'" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import langchain\n", + "langchain.__version__" + ] + }, + { + "cell_type": "markdown", + "id": "36115eae-9b8e-4150-9604-8bfa6c071b2f", + "metadata": {}, + "source": [ + "### 2.4 查询创建的向量存储" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "7909c6b7", + "metadata": { + "height": 30 + }, + "outputs": [], + "source": [ + "query = \"Please suggest a shirt with sunblocking\"\n", + "\n", + "#使用上面的向量存储来查找与传入查询类似的文本,得到一个相似文档列表\n", + "docs = db.similarity_search(query)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "43321853", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "4" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#打印返回文档的个数\n", + "len(docs)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "6eba90b5", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/plain": [ + "Document(page_content=': 255\\nname: Sun Shield Shirt by\\ndescription: \"Block the sun, not the fun – our high-performance sun shirt is guaranteed to protect from harmful UV rays. \\n\\nSize & Fit: Slightly Fitted: Softly shapes the body. Falls at hip.\\n\\nFabric & Care: 78% nylon, 22% Lycra Xtra Life fiber. UPF 50+ rated – the highest rated sun protection possible. Handwash, line dry.\\n\\nAdditional Features: Wicks moisture for quick-drying comfort. Fits comfortably over your favorite swimsuit. Abrasion resistant for season after season of wear. Imported.\\n\\nSun Protection That Won\\'t Wear Off\\nOur high-performance fabric provides SPF 50+ sun protection, blocking 98% of the sun\\'s harmful rays. This fabric is recommended by The Skin Cancer Foundation as an effective UV protectant.', metadata={'source': 'data/OutdoorClothingCatalog_1000.csv', 'row': 255})" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#打印返回的第一个文档\n", + "docs[0] " + ] + }, + { + "cell_type": "markdown", + "id": "566ee2d3-fa53-4138-8fa8-06e2c6fb8732", + "metadata": {}, + "source": [ + "我们可以看到一个返回了四个结果。输出的第一结果是一件关于防晒的衬衫,满足我们查询的要求:`请推荐一件防晒功能的衬衫(Please suggest a shirt with sunblocking)`" + ] + }, + { + "cell_type": "markdown", + "id": "fe41b36f", + "metadata": {}, + "source": [ + "### 2.5 使用向量储存回答文档的相关问题" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "c0c3596e", + "metadata": { + "height": 30 + }, + "outputs": [], + "source": [ + "#基于向量储存,创建检索器\n", + "retriever = db.as_retriever() " + ] + }, + { + "cell_type": "code", + "execution_count": 32, + "id": "0625f5e8", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "#导入大语言模型, 这里使用默认模型gpt-3.5-turbo会出现504服务器超时,因此使用gpt-3.5-turbo-0301\n", + "llm = ChatOpenAI(model_name=\"gpt-3.5-turbo-0301\",temperature = 0.0) " + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "a573f58a", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "#合并获得的相似文档内容\n", + "qdocs = \"\".join([docs[i].page_content for i in range(len(docs))]) " + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "id": "14682d95", + "metadata": { + "height": 64 + }, + "outputs": [], + "source": [ + "#将合并的相似文档内容后加上问题(question)输入到 `llm.call_as_llm`中\n", + "#这里问题是:以Markdown表格的方式列出所有具有防晒功能的衬衫并总结\n", + "response = llm.call_as_llm(f\"{qdocs} Question: Please list all your \\\n", + "shirts with sun protection in a table in markdown and summarize each one.\") " + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "8bba545b", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "| Name | Description |\n", + "| --- | --- |\n", + "| Sun Shield Shirt | High-performance sun shirt with UPF 50+ sun protection, moisture-wicking, and abrasion-resistant fabric. Fits comfortably over swimsuits. |\n", + "| Men's Plaid Tropic Shirt | Ultracomfortable shirt with UPF 50+ sun protection, wrinkle-free fabric, and front/back cape venting. Made with 52% polyester and 48% nylon. |\n", + "| Men's TropicVibe Shirt | Men's sun-protection shirt with built-in UPF 50+ and wrinkle-resistant fabric. Features front/back cape venting and two front bellows pockets. |\n", + "| Men's Tropical Plaid Short-Sleeve Shirt | Lightest hot-weather shirt with UPF 50+ sun protection, relaxed traditional fit, and front/back cape venting. Made with 100% polyester. |\n", + "\n", + "All of these shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. They also have additional features such as moisture-wicking, wrinkle-resistant, and venting for cool breezes. The Sun Shield Shirt is abrasion-resistant and fits comfortably over swimsuits. The Men's Plaid Tropic Shirt is made with a blend of polyester and nylon and is machine washable/dryable. The Men's TropicVibe Shirt is also wrinkle-resistant and has two front bellows pockets. The Men's Tropical Plaid Short-Sleeve Shirt has a relaxed traditional fit and is made with 100% polyester." + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(Markdown(response))" + ] + }, + { + "cell_type": "markdown", + "id": "12f042e7", + "metadata": {}, + "source": [ + "在此处打印响应,我们可以看到我们得到了一个表格,正如我们所要求的那样" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "32c94d22", + "metadata": { + "height": 115 + }, + "outputs": [], + "source": [ + "''' \n", + "通过LangChain链封装起来\n", + "创建一个检索QA链,对检索到的文档进行问题回答,要创建这样的链,我们将传入几个不同的东西\n", + "1、语言模型,在最后进行文本生成\n", + "2、传入链类型,这里使用stuff,将所有文档塞入上下文并对语言模型进行一次调用\n", + "3、传入一个检索器\n", + "'''\n", + "\n", + "\n", + "qa_stuff = RetrievalQA.from_chain_type(\n", + " llm=llm, \n", + " chain_type=\"stuff\", \n", + " retriever=retriever, \n", + " verbose=True\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "e4769316", + "metadata": { + "height": 47 + }, + "outputs": [], + "source": [ + "query = \"Please list all your shirts with sun protection in a table \\\n", + "in markdown and summarize each one.\"#创建一个查询并在此查询上运行链" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "1fc3c2f3", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + "\u001b[1m> Entering new RetrievalQA chain...\u001b[0m\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Input \u001b[0;32mIn [22]\u001b[0m, in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[43mqa_stuff\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\u001b[43mquery\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:440\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, callbacks, tags, metadata, *args, **kwargs)\u001b[0m\n\u001b[1;32m 438\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(args) \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m1\u001b[39m:\n\u001b[1;32m 439\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`run` supports only one positional argument.\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m--> 440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43margs\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;241;43m0\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m[\n\u001b[1;32m 441\u001b[0m _output_key\n\u001b[1;32m 442\u001b[0m ]\n\u001b[1;32m 444\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[1;32m 445\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(kwargs, callbacks\u001b[38;5;241m=\u001b[39mcallbacks, tags\u001b[38;5;241m=\u001b[39mtags, metadata\u001b[38;5;241m=\u001b[39mmetadata)[\n\u001b[1;32m 446\u001b[0m _output_key\n\u001b[1;32m 447\u001b[0m ]\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:243\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 243\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 244\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m 245\u001b[0m final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m 246\u001b[0m inputs, outputs, return_only_outputs\n\u001b[1;32m 247\u001b[0m )\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:237\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 231\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m 232\u001b[0m dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m 233\u001b[0m inputs,\n\u001b[1;32m 234\u001b[0m )\n\u001b[1;32m 235\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 236\u001b[0m outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 237\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 238\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m 239\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m 240\u001b[0m )\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/retrieval_qa/base.py:131\u001b[0m, in \u001b[0;36mBaseRetrievalQA._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m 129\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 130\u001b[0m docs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_docs(question) \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[0;32m--> 131\u001b[0m answer \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcombine_documents_chain\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrun\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 132\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_documents\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mquestion\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mquestion\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_run_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 133\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 135\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mreturn_source_documents:\n\u001b[1;32m 136\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m {\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_key: answer, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124msource_documents\u001b[39m\u001b[38;5;124m\"\u001b[39m: docs}\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:445\u001b[0m, in \u001b[0;36mChain.run\u001b[0;34m(self, callbacks, tags, metadata, *args, **kwargs)\u001b[0m\n\u001b[1;32m 440\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m(args[\u001b[38;5;241m0\u001b[39m], callbacks\u001b[38;5;241m=\u001b[39mcallbacks, tags\u001b[38;5;241m=\u001b[39mtags, metadata\u001b[38;5;241m=\u001b[39mmetadata)[\n\u001b[1;32m 441\u001b[0m _output_key\n\u001b[1;32m 442\u001b[0m ]\n\u001b[1;32m 444\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[0;32m--> 445\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtags\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtags\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mmetadata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmetadata\u001b[49m\u001b[43m)\u001b[49m[\n\u001b[1;32m 446\u001b[0m _output_key\n\u001b[1;32m 447\u001b[0m ]\n\u001b[1;32m 449\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m kwargs \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m args:\n\u001b[1;32m 450\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 451\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m`run` supported with either positional arguments or keyword arguments,\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 452\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m but none were provided.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 453\u001b[0m )\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:243\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 243\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 244\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m 245\u001b[0m final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m 246\u001b[0m inputs, outputs, return_only_outputs\n\u001b[1;32m 247\u001b[0m )\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:237\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 231\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m 232\u001b[0m dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m 233\u001b[0m inputs,\n\u001b[1;32m 234\u001b[0m )\n\u001b[1;32m 235\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 236\u001b[0m outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 237\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 238\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m 239\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m 240\u001b[0m )\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/combine_documents/base.py:106\u001b[0m, in \u001b[0;36mBaseCombineDocumentsChain._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m 104\u001b[0m \u001b[38;5;66;03m# Other keys are assumed to be needed for LLM prediction\u001b[39;00m\n\u001b[1;32m 105\u001b[0m other_keys \u001b[38;5;241m=\u001b[39m {k: v \u001b[38;5;28;01mfor\u001b[39;00m k, v \u001b[38;5;129;01min\u001b[39;00m inputs\u001b[38;5;241m.\u001b[39mitems() \u001b[38;5;28;01mif\u001b[39;00m k \u001b[38;5;241m!=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minput_key}\n\u001b[0;32m--> 106\u001b[0m output, extra_return_dict \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcombine_docs\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 107\u001b[0m \u001b[43m \u001b[49m\u001b[43mdocs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_run_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mother_keys\u001b[49m\n\u001b[1;32m 108\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 109\u001b[0m extra_return_dict[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_key] \u001b[38;5;241m=\u001b[39m output\n\u001b[1;32m 110\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m extra_return_dict\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/combine_documents/stuff.py:165\u001b[0m, in \u001b[0;36mStuffDocumentsChain.combine_docs\u001b[0;34m(self, docs, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m 163\u001b[0m inputs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_get_inputs(docs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[1;32m 164\u001b[0m \u001b[38;5;66;03m# Call predict on the LLM.\u001b[39;00m\n\u001b[0;32m--> 165\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mllm_chain\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mpredict\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43minputs\u001b[49m\u001b[43m)\u001b[49m, {}\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/llm.py:252\u001b[0m, in \u001b[0;36mLLMChain.predict\u001b[0;34m(self, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m 237\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mpredict\u001b[39m(\u001b[38;5;28mself\u001b[39m, callbacks: Callbacks \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m \u001b[38;5;28mstr\u001b[39m:\n\u001b[1;32m 238\u001b[0m \u001b[38;5;250m \u001b[39m\u001b[38;5;124;03m\"\"\"Format prompt with kwargs and pass to LLM.\u001b[39;00m\n\u001b[1;32m 239\u001b[0m \n\u001b[1;32m 240\u001b[0m \u001b[38;5;124;03m Args:\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 250\u001b[0m \u001b[38;5;124;03m completion = llm.predict(adjective=\"funny\")\u001b[39;00m\n\u001b[1;32m 251\u001b[0m \u001b[38;5;124;03m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 252\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m)\u001b[49m[\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39moutput_key]\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:243\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n\u001b[0;32m--> 243\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 244\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_end(outputs)\n\u001b[1;32m 245\u001b[0m final_outputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_outputs(\n\u001b[1;32m 246\u001b[0m inputs, outputs, return_only_outputs\n\u001b[1;32m 247\u001b[0m )\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/base.py:237\u001b[0m, in \u001b[0;36mChain.__call__\u001b[0;34m(self, inputs, return_only_outputs, callbacks, tags, metadata, include_run_info)\u001b[0m\n\u001b[1;32m 231\u001b[0m run_manager \u001b[38;5;241m=\u001b[39m callback_manager\u001b[38;5;241m.\u001b[39mon_chain_start(\n\u001b[1;32m 232\u001b[0m dumpd(\u001b[38;5;28mself\u001b[39m),\n\u001b[1;32m 233\u001b[0m inputs,\n\u001b[1;32m 234\u001b[0m )\n\u001b[1;32m 235\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 236\u001b[0m outputs \u001b[38;5;241m=\u001b[39m (\n\u001b[0;32m--> 237\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_call\u001b[49m\u001b[43m(\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 238\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported\n\u001b[1;32m 239\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call(inputs)\n\u001b[1;32m 240\u001b[0m )\n\u001b[1;32m 241\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 242\u001b[0m run_manager\u001b[38;5;241m.\u001b[39mon_chain_error(e)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/llm.py:92\u001b[0m, in \u001b[0;36mLLMChain._call\u001b[0;34m(self, inputs, run_manager)\u001b[0m\n\u001b[1;32m 87\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_call\u001b[39m(\n\u001b[1;32m 88\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 89\u001b[0m inputs: Dict[\u001b[38;5;28mstr\u001b[39m, Any],\n\u001b[1;32m 90\u001b[0m run_manager: Optional[CallbackManagerForChainRun] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 91\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Dict[\u001b[38;5;28mstr\u001b[39m, \u001b[38;5;28mstr\u001b[39m]:\n\u001b[0;32m---> 92\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\u001b[43m[\u001b[49m\u001b[43minputs\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 93\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mcreate_outputs(response)[\u001b[38;5;241m0\u001b[39m]\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chains/llm.py:102\u001b[0m, in \u001b[0;36mLLMChain.generate\u001b[0;34m(self, input_list, run_manager)\u001b[0m\n\u001b[1;32m 100\u001b[0m \u001b[38;5;250m\u001b[39m\u001b[38;5;124;03m\"\"\"Generate LLM result from inputs.\"\"\"\u001b[39;00m\n\u001b[1;32m 101\u001b[0m prompts, stop \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mprep_prompts(input_list, run_manager\u001b[38;5;241m=\u001b[39mrun_manager)\n\u001b[0;32m--> 102\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mllm\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate_prompt\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 103\u001b[0m \u001b[43m \u001b[49m\u001b[43mprompts\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 104\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 105\u001b[0m \u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mget_child\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 106\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mllm_kwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 107\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/base.py:230\u001b[0m, in \u001b[0;36mBaseChatModel.generate_prompt\u001b[0;34m(self, prompts, stop, callbacks, **kwargs)\u001b[0m\n\u001b[1;32m 222\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mgenerate_prompt\u001b[39m(\n\u001b[1;32m 223\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 224\u001b[0m prompts: List[PromptValue],\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 227\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any,\n\u001b[1;32m 228\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m LLMResult:\n\u001b[1;32m 229\u001b[0m prompt_messages \u001b[38;5;241m=\u001b[39m [p\u001b[38;5;241m.\u001b[39mto_messages() \u001b[38;5;28;01mfor\u001b[39;00m p \u001b[38;5;129;01min\u001b[39;00m prompts]\n\u001b[0;32m--> 230\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgenerate\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprompt_messages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcallbacks\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mcallbacks\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/base.py:125\u001b[0m, in \u001b[0;36mBaseChatModel.generate\u001b[0;34m(self, messages, stop, callbacks, tags, metadata, **kwargs)\u001b[0m\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n\u001b[1;32m 124\u001b[0m run_managers[i]\u001b[38;5;241m.\u001b[39mon_llm_error(e)\n\u001b[0;32m--> 125\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m e\n\u001b[1;32m 126\u001b[0m flattened_outputs \u001b[38;5;241m=\u001b[39m [\n\u001b[1;32m 127\u001b[0m LLMResult(generations\u001b[38;5;241m=\u001b[39m[res\u001b[38;5;241m.\u001b[39mgenerations], llm_output\u001b[38;5;241m=\u001b[39mres\u001b[38;5;241m.\u001b[39mllm_output)\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results\n\u001b[1;32m 129\u001b[0m ]\n\u001b[1;32m 130\u001b[0m llm_output \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_combine_llm_outputs([res\u001b[38;5;241m.\u001b[39mllm_output \u001b[38;5;28;01mfor\u001b[39;00m res \u001b[38;5;129;01min\u001b[39;00m results])\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/base.py:115\u001b[0m, in \u001b[0;36mBaseChatModel.generate\u001b[0;34m(self, messages, stop, callbacks, tags, metadata, **kwargs)\u001b[0m\n\u001b[1;32m 112\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m i, m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28menumerate\u001b[39m(messages):\n\u001b[1;32m 113\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 114\u001b[0m results\u001b[38;5;241m.\u001b[39mappend(\n\u001b[0;32m--> 115\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generate_with_cache\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 116\u001b[0m \u001b[43m \u001b[49m\u001b[43mm\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 117\u001b[0m \u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 118\u001b[0m \u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_managers\u001b[49m\u001b[43m[\u001b[49m\u001b[43mi\u001b[49m\u001b[43m]\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrun_managers\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 119\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 120\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 121\u001b[0m )\n\u001b[1;32m 122\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (\u001b[38;5;167;01mKeyboardInterrupt\u001b[39;00m, \u001b[38;5;167;01mException\u001b[39;00m) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 123\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m run_managers:\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/base.py:262\u001b[0m, in \u001b[0;36mBaseChatModel._generate_with_cache\u001b[0;34m(self, messages, stop, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 258\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 259\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mAsked to cache, but no cache found at `langchain.cache`.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m 260\u001b[0m )\n\u001b[1;32m 261\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m new_arg_supported:\n\u001b[0;32m--> 262\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_generate\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 263\u001b[0m \u001b[43m \u001b[49m\u001b[43mmessages\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mstop\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstop\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrun_manager\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrun_manager\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\n\u001b[1;32m 264\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 265\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 266\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_generate(messages, stop\u001b[38;5;241m=\u001b[39mstop, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/openai.py:371\u001b[0m, in \u001b[0;36mChatOpenAI._generate\u001b[0;34m(self, messages, stop, run_manager, **kwargs)\u001b[0m\n\u001b[1;32m 363\u001b[0m message \u001b[38;5;241m=\u001b[39m _convert_dict_to_message(\n\u001b[1;32m 364\u001b[0m {\n\u001b[1;32m 365\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcontent\u001b[39m\u001b[38;5;124m\"\u001b[39m: inner_completion,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 368\u001b[0m }\n\u001b[1;32m 369\u001b[0m )\n\u001b[1;32m 370\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m ChatResult(generations\u001b[38;5;241m=\u001b[39m[ChatGeneration(message\u001b[38;5;241m=\u001b[39mmessage)])\n\u001b[0;32m--> 371\u001b[0m response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcompletion_with_retry\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmessages\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mmessage_dicts\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 372\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_create_chat_result(response)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/openai.py:319\u001b[0m, in \u001b[0;36mChatOpenAI.completion_with_retry\u001b[0;34m(self, **kwargs)\u001b[0m\n\u001b[1;32m 315\u001b[0m \u001b[38;5;129m@retry_decorator\u001b[39m\n\u001b[1;32m 316\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_completion_with_retry\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[1;32m 317\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mclient\u001b[38;5;241m.\u001b[39mcreate(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs)\n\u001b[0;32m--> 319\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43m_completion_with_retry\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/tenacity/__init__.py:289\u001b[0m, in \u001b[0;36mBaseRetrying.wraps..wrapped_f\u001b[0;34m(*args, **kw)\u001b[0m\n\u001b[1;32m 287\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(f)\n\u001b[1;32m 288\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapped_f\u001b[39m(\u001b[38;5;241m*\u001b[39margs: t\u001b[38;5;241m.\u001b[39mAny, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkw: t\u001b[38;5;241m.\u001b[39mAny) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m t\u001b[38;5;241m.\u001b[39mAny:\n\u001b[0;32m--> 289\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mf\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkw\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/tenacity/__init__.py:379\u001b[0m, in \u001b[0;36mRetrying.__call__\u001b[0;34m(self, fn, *args, **kwargs)\u001b[0m\n\u001b[1;32m 377\u001b[0m retry_state \u001b[38;5;241m=\u001b[39m RetryCallState(retry_object\u001b[38;5;241m=\u001b[39m\u001b[38;5;28mself\u001b[39m, fn\u001b[38;5;241m=\u001b[39mfn, args\u001b[38;5;241m=\u001b[39margs, kwargs\u001b[38;5;241m=\u001b[39mkwargs)\n\u001b[1;32m 378\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m--> 379\u001b[0m do \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43miter\u001b[49m\u001b[43m(\u001b[49m\u001b[43mretry_state\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mretry_state\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 380\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(do, DoAttempt):\n\u001b[1;32m 381\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/tenacity/__init__.py:314\u001b[0m, in \u001b[0;36mBaseRetrying.iter\u001b[0;34m(self, retry_state)\u001b[0m\n\u001b[1;32m 312\u001b[0m is_explicit_retry \u001b[38;5;241m=\u001b[39m fut\u001b[38;5;241m.\u001b[39mfailed \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(fut\u001b[38;5;241m.\u001b[39mexception(), TryAgain)\n\u001b[1;32m 313\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (is_explicit_retry \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mretry(retry_state)):\n\u001b[0;32m--> 314\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfut\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mresult\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 316\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mafter \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[1;32m 317\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mafter(retry_state)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/concurrent/futures/_base.py:439\u001b[0m, in \u001b[0;36mFuture.result\u001b[0;34m(self, timeout)\u001b[0m\n\u001b[1;32m 437\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m CancelledError()\n\u001b[1;32m 438\u001b[0m \u001b[38;5;28;01melif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;241m==\u001b[39m FINISHED:\n\u001b[0;32m--> 439\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__get_result\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 441\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_condition\u001b[38;5;241m.\u001b[39mwait(timeout)\n\u001b[1;32m 443\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_state \u001b[38;5;129;01min\u001b[39;00m [CANCELLED, CANCELLED_AND_NOTIFIED]:\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/concurrent/futures/_base.py:391\u001b[0m, in \u001b[0;36mFuture.__get_result\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 389\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception:\n\u001b[1;32m 390\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 391\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_exception\n\u001b[1;32m 392\u001b[0m \u001b[38;5;28;01mfinally\u001b[39;00m:\n\u001b[1;32m 393\u001b[0m \u001b[38;5;66;03m# Break a reference cycle with the exception in self._exception\u001b[39;00m\n\u001b[1;32m 394\u001b[0m \u001b[38;5;28mself\u001b[39m \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/tenacity/__init__.py:382\u001b[0m, in \u001b[0;36mRetrying.__call__\u001b[0;34m(self, fn, *args, **kwargs)\u001b[0m\n\u001b[1;32m 380\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(do, DoAttempt):\n\u001b[1;32m 381\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 382\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43mfn\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 383\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m: \u001b[38;5;66;03m# noqa: B902\u001b[39;00m\n\u001b[1;32m 384\u001b[0m retry_state\u001b[38;5;241m.\u001b[39mset_exception(sys\u001b[38;5;241m.\u001b[39mexc_info()) \u001b[38;5;66;03m# type: ignore[arg-type]\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/langchain/chat_models/openai.py:317\u001b[0m, in \u001b[0;36mChatOpenAI.completion_with_retry.._completion_with_retry\u001b[0;34m(**kwargs)\u001b[0m\n\u001b[1;32m 315\u001b[0m \u001b[38;5;129m@retry_decorator\u001b[39m\n\u001b[1;32m 316\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_completion_with_retry\u001b[39m(\u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs: Any) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[0;32m--> 317\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mclient\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/openai/api_resources/chat_completion.py:25\u001b[0m, in \u001b[0;36mChatCompletion.create\u001b[0;34m(cls, *args, **kwargs)\u001b[0m\n\u001b[1;32m 23\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 24\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m---> 25\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43msuper\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mcreate\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 26\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m TryAgain \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 27\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m timeout \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m \u001b[38;5;129;01mand\u001b[39;00m time\u001b[38;5;241m.\u001b[39mtime() \u001b[38;5;241m>\u001b[39m start \u001b[38;5;241m+\u001b[39m timeout:\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/openai/api_resources/abstract/engine_api_resource.py:153\u001b[0m, in \u001b[0;36mEngineAPIResource.create\u001b[0;34m(cls, api_key, api_base, api_type, request_id, api_version, organization, **params)\u001b[0m\n\u001b[1;32m 127\u001b[0m \u001b[38;5;129m@classmethod\u001b[39m\n\u001b[1;32m 128\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mcreate\u001b[39m(\n\u001b[1;32m 129\u001b[0m \u001b[38;5;28mcls\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 136\u001b[0m \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams,\n\u001b[1;32m 137\u001b[0m ):\n\u001b[1;32m 138\u001b[0m (\n\u001b[1;32m 139\u001b[0m deployment_id,\n\u001b[1;32m 140\u001b[0m engine,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 150\u001b[0m api_key, api_base, api_type, api_version, organization, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams\n\u001b[1;32m 151\u001b[0m )\n\u001b[0;32m--> 153\u001b[0m response, _, api_key \u001b[38;5;241m=\u001b[39m \u001b[43mrequestor\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 154\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mpost\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[1;32m 155\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 156\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 157\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 158\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 159\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_id\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 160\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_timeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 161\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 163\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m stream:\n\u001b[1;32m 164\u001b[0m \u001b[38;5;66;03m# must be an iterator\u001b[39;00m\n\u001b[1;32m 165\u001b[0m \u001b[38;5;28;01massert\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(response, OpenAIResponse)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/openai/api_requestor.py:220\u001b[0m, in \u001b[0;36mAPIRequestor.request\u001b[0;34m(self, method, url, params, headers, files, stream, request_id, request_timeout)\u001b[0m\n\u001b[1;32m 209\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mrequest\u001b[39m(\n\u001b[1;32m 210\u001b[0m \u001b[38;5;28mself\u001b[39m,\n\u001b[1;32m 211\u001b[0m method,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 218\u001b[0m request_timeout: Optional[Union[\u001b[38;5;28mfloat\u001b[39m, Tuple[\u001b[38;5;28mfloat\u001b[39m, \u001b[38;5;28mfloat\u001b[39m]]] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[1;32m 219\u001b[0m ) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Tuple[Union[OpenAIResponse, Iterator[OpenAIResponse]], \u001b[38;5;28mbool\u001b[39m, \u001b[38;5;28mstr\u001b[39m]:\n\u001b[0;32m--> 220\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest_raw\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 221\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlower\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 222\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 223\u001b[0m \u001b[43m \u001b[49m\u001b[43mparams\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mparams\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 224\u001b[0m \u001b[43m \u001b[49m\u001b[43msupplied_headers\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 225\u001b[0m \u001b[43m \u001b[49m\u001b[43mfiles\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfiles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 226\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 227\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_id\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_id\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 228\u001b[0m \u001b[43m \u001b[49m\u001b[43mrequest_timeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_timeout\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 229\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 230\u001b[0m resp, got_stream \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_interpret_response(result, stream)\n\u001b[1;32m 231\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp, got_stream, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mapi_key\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/openai/api_requestor.py:520\u001b[0m, in \u001b[0;36mAPIRequestor.request_raw\u001b[0;34m(self, method, url, params, supplied_headers, files, stream, request_id, request_timeout)\u001b[0m\n\u001b[1;32m 518\u001b[0m _thread_context\u001b[38;5;241m.\u001b[39msession \u001b[38;5;241m=\u001b[39m _make_session()\n\u001b[1;32m 519\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 520\u001b[0m result \u001b[38;5;241m=\u001b[39m \u001b[43m_thread_context\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msession\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 521\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 522\u001b[0m \u001b[43m \u001b[49m\u001b[43mabs_url\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 523\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 524\u001b[0m \u001b[43m \u001b[49m\u001b[43mdata\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdata\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 525\u001b[0m \u001b[43m \u001b[49m\u001b[43mfiles\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mfiles\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 526\u001b[0m \u001b[43m \u001b[49m\u001b[43mstream\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mstream\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 527\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest_timeout\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mif\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mrequest_timeout\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01melse\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mTIMEOUT_SECS\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 528\u001b[0m \u001b[43m \u001b[49m\u001b[43mproxies\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m_thread_context\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msession\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mproxies\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 529\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 530\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m requests\u001b[38;5;241m.\u001b[39mexceptions\u001b[38;5;241m.\u001b[39mTimeout \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 531\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m error\u001b[38;5;241m.\u001b[39mTimeout(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mRequest timed out: \u001b[39m\u001b[38;5;132;01m{}\u001b[39;00m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(e)) \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01me\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/requests/sessions.py:529\u001b[0m, in \u001b[0;36mSession.request\u001b[0;34m(self, method, url, params, data, headers, cookies, files, auth, timeout, allow_redirects, proxies, hooks, stream, verify, cert, json)\u001b[0m\n\u001b[1;32m 524\u001b[0m send_kwargs \u001b[38;5;241m=\u001b[39m {\n\u001b[1;32m 525\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mtimeout\u001b[39m\u001b[38;5;124m'\u001b[39m: timeout,\n\u001b[1;32m 526\u001b[0m \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mallow_redirects\u001b[39m\u001b[38;5;124m'\u001b[39m: allow_redirects,\n\u001b[1;32m 527\u001b[0m }\n\u001b[1;32m 528\u001b[0m send_kwargs\u001b[38;5;241m.\u001b[39mupdate(settings)\n\u001b[0;32m--> 529\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mprep\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43msend_kwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 531\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m resp\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/requests/sessions.py:645\u001b[0m, in \u001b[0;36mSession.send\u001b[0;34m(self, request, **kwargs)\u001b[0m\n\u001b[1;32m 642\u001b[0m start \u001b[38;5;241m=\u001b[39m preferred_clock()\n\u001b[1;32m 644\u001b[0m \u001b[38;5;66;03m# Send the request\u001b[39;00m\n\u001b[0;32m--> 645\u001b[0m r \u001b[38;5;241m=\u001b[39m \u001b[43madapter\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43msend\u001b[49m\u001b[43m(\u001b[49m\u001b[43mrequest\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 647\u001b[0m \u001b[38;5;66;03m# Total elapsed time of the request (approximately)\u001b[39;00m\n\u001b[1;32m 648\u001b[0m elapsed \u001b[38;5;241m=\u001b[39m preferred_clock() \u001b[38;5;241m-\u001b[39m start\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/requests/adapters.py:440\u001b[0m, in \u001b[0;36mHTTPAdapter.send\u001b[0;34m(self, request, stream, timeout, verify, cert, proxies)\u001b[0m\n\u001b[1;32m 438\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 439\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m chunked:\n\u001b[0;32m--> 440\u001b[0m resp \u001b[38;5;241m=\u001b[39m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43murlopen\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 441\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 442\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 443\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 444\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mrequest\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 445\u001b[0m \u001b[43m \u001b[49m\u001b[43mredirect\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 446\u001b[0m \u001b[43m \u001b[49m\u001b[43massert_same_host\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 447\u001b[0m \u001b[43m \u001b[49m\u001b[43mpreload_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 448\u001b[0m \u001b[43m \u001b[49m\u001b[43mdecode_content\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[1;32m 449\u001b[0m \u001b[43m \u001b[49m\u001b[43mretries\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mmax_retries\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 450\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout\u001b[49m\n\u001b[1;32m 451\u001b[0m \u001b[43m \u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 453\u001b[0m \u001b[38;5;66;03m# Send the request.\u001b[39;00m\n\u001b[1;32m 454\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 455\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(conn, \u001b[38;5;124m'\u001b[39m\u001b[38;5;124mproxy_pool\u001b[39m\u001b[38;5;124m'\u001b[39m):\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:703\u001b[0m, in \u001b[0;36mHTTPConnectionPool.urlopen\u001b[0;34m(self, method, url, body, headers, retries, redirect, assert_same_host, timeout, pool_timeout, release_conn, chunked, body_pos, **response_kw)\u001b[0m\n\u001b[1;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_prepare_proxy(conn)\n\u001b[1;32m 702\u001b[0m \u001b[38;5;66;03m# Make the request on the httplib connection object.\u001b[39;00m\n\u001b[0;32m--> 703\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_make_request\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 704\u001b[0m \u001b[43m \u001b[49m\u001b[43mconn\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 705\u001b[0m \u001b[43m \u001b[49m\u001b[43mmethod\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 706\u001b[0m \u001b[43m \u001b[49m\u001b[43murl\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 707\u001b[0m \u001b[43m \u001b[49m\u001b[43mtimeout\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mtimeout_obj\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 708\u001b[0m \u001b[43m \u001b[49m\u001b[43mbody\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mbody\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 709\u001b[0m \u001b[43m \u001b[49m\u001b[43mheaders\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mheaders\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 710\u001b[0m \u001b[43m \u001b[49m\u001b[43mchunked\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mchunked\u001b[49m\u001b[43m,\u001b[49m\n\u001b[1;32m 711\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 713\u001b[0m \u001b[38;5;66;03m# If we're going to release the connection in ``finally:``, then\u001b[39;00m\n\u001b[1;32m 714\u001b[0m \u001b[38;5;66;03m# the response doesn't need to know about the connection. Otherwise\u001b[39;00m\n\u001b[1;32m 715\u001b[0m \u001b[38;5;66;03m# it will also try to release it and we'll have a double-release\u001b[39;00m\n\u001b[1;32m 716\u001b[0m \u001b[38;5;66;03m# mess.\u001b[39;00m\n\u001b[1;32m 717\u001b[0m response_conn \u001b[38;5;241m=\u001b[39m conn \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m release_conn \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:449\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 444\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m conn\u001b[38;5;241m.\u001b[39mgetresponse()\n\u001b[1;32m 445\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 446\u001b[0m \u001b[38;5;66;03m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m 447\u001b[0m \u001b[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m 448\u001b[0m \u001b[38;5;66;03m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[0;32m--> 449\u001b[0m \u001b[43msix\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mraise_from\u001b[49m\u001b[43m(\u001b[49m\u001b[43me\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[1;32m 450\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m (SocketTimeout, BaseSSLError, SocketError) \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 451\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_raise_timeout(err\u001b[38;5;241m=\u001b[39me, url\u001b[38;5;241m=\u001b[39murl, timeout_value\u001b[38;5;241m=\u001b[39mread_timeout)\n", + "File \u001b[0;32m:3\u001b[0m, in \u001b[0;36mraise_from\u001b[0;34m(value, from_value)\u001b[0m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/site-packages/urllib3/connectionpool.py:444\u001b[0m, in \u001b[0;36mHTTPConnectionPool._make_request\u001b[0;34m(self, conn, method, url, timeout, chunked, **httplib_request_kw)\u001b[0m\n\u001b[1;32m 441\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mTypeError\u001b[39;00m:\n\u001b[1;32m 442\u001b[0m \u001b[38;5;66;03m# Python 3\u001b[39;00m\n\u001b[1;32m 443\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 444\u001b[0m httplib_response \u001b[38;5;241m=\u001b[39m \u001b[43mconn\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mgetresponse\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 445\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mBaseException\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[1;32m 446\u001b[0m \u001b[38;5;66;03m# Remove the TypeError from the exception chain in\u001b[39;00m\n\u001b[1;32m 447\u001b[0m \u001b[38;5;66;03m# Python 3 (including for exceptions like SystemExit).\u001b[39;00m\n\u001b[1;32m 448\u001b[0m \u001b[38;5;66;03m# Otherwise it looks like a bug in the code.\u001b[39;00m\n\u001b[1;32m 449\u001b[0m six\u001b[38;5;241m.\u001b[39mraise_from(e, \u001b[38;5;28;01mNone\u001b[39;00m)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/http/client.py:1377\u001b[0m, in \u001b[0;36mHTTPConnection.getresponse\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1375\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1376\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m-> 1377\u001b[0m \u001b[43mresponse\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mbegin\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1378\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m \u001b[38;5;167;01mConnectionError\u001b[39;00m:\n\u001b[1;32m 1379\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mclose()\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/http/client.py:320\u001b[0m, in \u001b[0;36mHTTPResponse.begin\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 318\u001b[0m \u001b[38;5;66;03m# read until we get a non-100 response\u001b[39;00m\n\u001b[1;32m 319\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[0;32m--> 320\u001b[0m version, status, reason \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_read_status\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 321\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m status \u001b[38;5;241m!=\u001b[39m CONTINUE:\n\u001b[1;32m 322\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/http/client.py:281\u001b[0m, in \u001b[0;36mHTTPResponse._read_status\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 280\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_read_status\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m--> 281\u001b[0m line \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mstr\u001b[39m(\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mreadline\u001b[49m\u001b[43m(\u001b[49m\u001b[43m_MAXLINE\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m+\u001b[39;49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m)\u001b[49m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124miso-8859-1\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[1;32m 282\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(line) \u001b[38;5;241m>\u001b[39m _MAXLINE:\n\u001b[1;32m 283\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m LineTooLong(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mstatus line\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/socket.py:704\u001b[0m, in \u001b[0;36mSocketIO.readinto\u001b[0;34m(self, b)\u001b[0m\n\u001b[1;32m 702\u001b[0m \u001b[38;5;28;01mwhile\u001b[39;00m \u001b[38;5;28;01mTrue\u001b[39;00m:\n\u001b[1;32m 703\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m--> 704\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_sock\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mrecv_into\u001b[49m\u001b[43m(\u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 705\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m timeout:\n\u001b[1;32m 706\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_timeout_occurred \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mTrue\u001b[39;00m\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/ssl.py:1241\u001b[0m, in \u001b[0;36mSSLSocket.recv_into\u001b[0;34m(self, buffer, nbytes, flags)\u001b[0m\n\u001b[1;32m 1237\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m flags \u001b[38;5;241m!=\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[1;32m 1238\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\n\u001b[1;32m 1239\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mnon-zero flags not allowed in calls to recv_into() on \u001b[39m\u001b[38;5;132;01m%s\u001b[39;00m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;241m%\u001b[39m\n\u001b[1;32m 1240\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__class__\u001b[39m)\n\u001b[0;32m-> 1241\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnbytes\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbuffer\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1242\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1243\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28msuper\u001b[39m()\u001b[38;5;241m.\u001b[39mrecv_into(buffer, nbytes, flags)\n", + "File \u001b[0;32m~/opt/miniconda3/lib/python3.9/ssl.py:1099\u001b[0m, in \u001b[0;36mSSLSocket.read\u001b[0;34m(self, len, buffer)\u001b[0m\n\u001b[1;32m 1097\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m 1098\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m buffer \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m-> 1099\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_sslobj\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mread\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mlen\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mbuffer\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 1100\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 1101\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sslobj\u001b[38;5;241m.\u001b[39mread(\u001b[38;5;28mlen\u001b[39m)\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], + "source": [ + "response = qa_stuff.run(query)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "id": "fba1a5db", + "metadata": { + "height": 30 + }, + "outputs": [ + { + "data": { + "text/markdown": [ + "\n", + "\n", + "| Name | Description |\n", + "| --- | --- |\n", + "| Men's Tropical Plaid Short-Sleeve Shirt | UPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets |\n", + "| Men's Plaid Tropic Shirt, Short-Sleeve | UPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets |\n", + "| Men's TropicVibe Shirt, Short-Sleeve | UPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, machine wash and dry, front and back cape venting, two front bellows pockets |\n", + "| Sun Shield Shirt by | UPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, handwash, line dry, wicks moisture, fits comfortably over swimsuit, abrasion resistant |\n", + "\n", + "All four shirts provide UPF 50+ sun protection, blocking 98% of the sun's harmful rays. The Men's Tropical Plaid Short-Sleeve Shirt is made of 100% polyester and is wrinkle-resistant" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "display(Markdown(response))#使用 display 和 markdown 显示它" + ] + }, + { + "cell_type": "markdown", + "id": "e28c5657", + "metadata": {}, + "source": [ + "这两个方式返回相同的结果" + ] + }, + { + "cell_type": "markdown", + "id": "44f1fa38", + "metadata": {}, + "source": [ + "想在许多不同类型的块上执行相同类型的问答,该怎么办?之前的实验中只返回了4个文档,如果有多个文档,那么我们可以使用几种不同的方法\n", + "* Map Reduce \n", + "将所有块与问题一起传递给语言模型,获取回复,使用另一个语言模型调用将所有单独的回复总结成最终答案,它可以在任意数量的文档上运行。可以并行处理单个问题,同时也需要更多的调用。它将所有文档视为独立的\n", + "* Refine \n", + "用于循环许多文档,际上是迭代的,建立在先前文档的答案之上,非常适合前后因果信息并随时间逐步构建答案,依赖于先前调用的结果。它通常需要更长的时间,并且基本上需要与Map Reduce一样多的调用\n", + "* Map Re-rank \n", + "对每个文档进行单个语言模型调用,要求它返回一个分数,选择最高分,这依赖于语言模型知道分数应该是什么,需要告诉它,如果它与文档相关,则应该是高分,并在那里精细调整说明,可以批量处理它们相对较快,但是更加昂贵\n", + "* Stuff \n", + "将所有内容组合成一个文档" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.12" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": false, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": true + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}