LangChain:LLM应用程序开发(中)——文档问答、评估、Agents(代理)

文章目录

    • 四、文档问答
      • 4.1 快速入门
      • 4.2 逐步实现
      • 4.3 其它方法
    • 五、评估
      • 5.1 创建QA app
      • 5.2 生成测试数据点
        • 5.2.1 Hard-coded examples
        • 5.2.2 LLM-Generated examples
      • 5.3 link chain debug手动评估
      • 5.4 LLM assisted evaluation
      • 5.5 LangChain Evaluation platform
    • 六、Agents(代理)
      • 6.1 使用内置的LangChain tools进行代理
      • 6.2 使用Python Agent
      • 6.3 调试agent chains
      • 6.4 自定义代理工具
    • 七、总结

  • deeplearning官网课程《LangChain for LLM Application Development》(含代码)、 B站中文字幕视频《LLM应用程序开发的LangChain》
  • LangChain官网、LangChain官方文档、LangChain 🦜️🔗 中文网、langchain hub
  • OpenAI API Key(创建API Key,以及侧边栏Usage选项查看费用)

  官方原版视频含有代码,可以直接跑。右侧有英文文本,点此安装 immersive-translate插件(沉浸式翻译),可以直接双语对照查看,效果更好。

在这里插入图片描述

四、文档问答

4.1 快速入门

  给定一段来自PDF/网页/markdown等文档的文本,使用LLM来回答有关这些文本的问题,以便深入了解这些信息,这就是文档问答。这个过程会引入一些LangChain组件,例如embedding模型和向量存储。

#pip install --upgrade langchain
import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import CSVLoader
from langchain.vectorstores import DocArrayInMemorySearch
from IPython.display import display, Markdown
  • RetrievalQA:对文档进行检索
  • CSVLoader:CSV文档加载器
  • DocArrayInMemorySearch:内存中的向量存储,不需要连接到外部数据库,适合入门
  • display, Markdown:jupyter中用于显示信息的工具

下面我们先导入户外服装的CSV数据,然后创建向量存储。

#pip install docarray
file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file)

# 创建向量存储
from langchain.indexes import VectorstoreIndexCreator
index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch).from_loaders([loader])

  创建一个query,然后使用索引查询来获得响应。打印出来之后,我们得到了一个markdown格式显示的表格,里面是所有具有防晒功能的衬衫的名称和描述,最后是一个LLM的简介摘要。

query ="Please list all your shirts with sun protection in a table in markdown and summarize each one."
response = index.query(query)
display(Markdown(response))
NameDescription
Men’s Tropical Plaid Short-Sleeve ShirtUPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets
Men’s Plaid Tropic Shirt, Short-SleeveUPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets
Men’s TropicVibe Shirt, Short-SleeveUPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, wrinkle resistant, front and back cape venting, two front bellows pockets
Sun Shield Shirt byUPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, wicks moisture, fits comfortably over swimsuit, abrasion resistant

所有的衬衫都提供UPF 50+的防晒保护,可以阻挡98%的有害阳光辐射。这些面料抗皱且干燥迅速,全部都配有前后背部通风口和两个前置鼓包口袋(翻译后)。

4.2 逐步实现

  LLM一次只能处理上千个tokens,但如果文档的tokens数量远远超过这个数该怎么办呢?这就需要embedding和向量存储了。

  文本可以转换为embedding进行表示,相似内容的文本应该具有相似的embedding,这一点可以通过在向量空间中进行比较来判断。

  vector database:向量数据库,用于存储文本的向量表示(embedding)。我们可以将大文档分割成各个小块,然后将其embedding表示存储到向量数据库,这就是创建向量索引是发生的操作。有了这个索引,就可以用它来查找与输入相关的文本片段。

在这里插入图片描述
  当模型输入一个query时,先将其转为embedding,然后将其与向量数据库中所有的向量进行比较,返回最相似的前n个结果。最后将这个结果传递给LLM,就能得到最终的响应。4.1节中我们使用几行代码就可以实现文档问答,下面我们将逐步了解其底层实现。

loader = CSVLoader(file_path=file)
docs = loader.load()
docs[0]
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})

  可以看到,这些文档已经很小了,不需要进一步分割,所以下面直接使用OpenAIEmbeddings创建其embedding表示。我们还可以使用embeddings.embed_query方法,来查看传入一段具体的文本之后会创建什么embedding。

from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
embed = embeddings.embed_query("Hi my name is Harrison") # 
print(len(embed))
print(embed[:5])
1536
[-0.021913960576057434, 0.006774206645786762, -0.018190348520874977, -0.039148248732089996, -0.014089343138039112]

  下面我们将所有csv文本数据创建embeddings,并保存到向量数据库中,通过from_documents方法可以实现这一点。之后,我们就可以输入query并查找与其相似的文本。

db = DocArrayInMemorySearch.from_documents(docs, embeddings)
query = "Please suggest a shirt with sunblocking"
docs = db.similarity_search(query)
len(docs)
4
docs[0]
Document(page_content=": 87\nname: Women's Tropical Plaid Shirt\ndescription: Our lightest hot-weather shirt lets you beat the heat with a flattering fit.\n\nSize & Fit\n- Slightly Fitted: Softly shapes the body.\n- Falls at hip.\n\nFabric & Care\n- 52% polyester/ 48% nylon.\n- UPF 50+ rated – the highest rated sun protection possible.\n\nAdditional Features\n- Keeps you cool and comfortable by wicking perspiration away from your skin, then dries in minutes.\n- Smooth buttons are easy on your hands.\n- Wrinkle resistant.\n- Front and back cape venting for ventilation.\n- Low-profile pockets and side shaping offer a more flattering fit.\n- Two front pockets, tool tabs and eyewear loop.\n- Imported.\n\nQuestions?\nContact us for more information.", metadata={'source': 'OutdoorClothingCatalog_1000.csv', 'row': 87})

  接下来如何利用向量查询来进行文档问答呢?首先我们需要创建一个检索器,这是一个通用接口,可以接受任何的query输入,并返回指定的文档内容(向量查询是其中一种方法,还有其他方法可以实现)。

  由于我们想进行文本生成并返回自然语言响应,所以我们需要导入一个语言模型,然后将文档文本进行合并,这里是将文本中所有页面合并到一个变量qdocs中。接着将qdocs传递到prompt中,然后输入LLM得到响应。

retriever = db.as_retriever()
llm = ChatOpenAI(temperature = 0.0)
qdocs = "".join([docs[i].page_content for i in range(len(docs))])

response = llm.call_as_llm(f"{qdocs} Question: Please list all your shirts with sun protection in a table in markdown and summarize each one.") 
display(Markdown(response))
Shirt NameDescription
Women’s Tropical Plaid ShirtA lightweight, UPF 50+ rated shirt that wicks away perspiration and dries quickly. Features front and back cape venting, low-profile pockets, and side shaping for a flattering fit.
Performance Plus Woven ShirtA breathable summer shirt made with quick-dry fabric that provides UPF 40+ sun protection. Dries in less than 14 minutes and is abrasion-resistant for durability.
Tropicview Baseball CapA sun-blocking baseball hat with UPF 50+ rated sun protection. Features a rear flap for extra coverage, elastic cord for adjustable fit, and Coolmax sweatband for moisture-wicking.
Smooth Comfort Check Shirt, Slightly FittedA men’s check shirt with TrueCool® fabric that wicks away moisture and provides wrinkle-free performance. Features a button-down collar and single patch pocket.

每件衬衫都提供防晒功能,具有从50+到40+不等的UPF等级。它们采用轻薄透气的面料制成,可以吸湿快干。女士的热带格子衬衫和Tropicview棒球帽还具有额外的通风设计,提供更多舒适感。Smooth Comfort格子衬衫专为男士设计,采用TrueCool®面料,具有吸湿快干和防皱性能(翻译后)。

以上这些可以通过chain封装起来,即创建一个检索问题的回应链,来对检索的文档进行问答。

qa_stuff = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=retriever, 
    verbose=True)

  stuff是一种简单的链类型,只是单纯地将所有文档都放入上下文中,并对语言模型进行一次调用。retriever是用于获取文档的接口,将文档内容传递给语言模型。

  下面我们创建一个query,运行此链式操作。

query =  "Please list all your shirts with sun protection in a table in markdown and summarize each one."
response = qa_stuff.run(query)

display(Markdown(response))
> Entering new  chain...

> Finished chain.
Shirt NameSun ProtectionFabricAdditional Features
Women’s Tropical Plaid ShirtUPF 50+52% polyester/ 48% nylonWicks perspiration, wrinkle-resistant, front and back cape venting, low-profile pockets, tool tabs, eyewear loop
Performance Plus Woven ShirtUPF 40+100% nylonQuick-dry fabric, moisture-wicking, abrasion-resistant
Tropicview Baseball CapUPF 50+Body: 71% nylon, 29% polyester. Mesh: 85% polyester, 15% S.Cafe polyester. Sweatband: 100% polyester.Rear flap, elastic cord, Coolmax sweatband, dark underbrim, mesh side panels
  • Women’s Tropical Plaid Shirt: A lightweight, hot-weather shirt with UPF 50+ sun protection. It wicks perspiration, dries quickly, and has front and back cape venting for ventilation. It also has low-profile pockets, tool tabs, and an eyewear loop.
  • Performance Plus Woven Shirt: A breathable summer shirt made of quick-dry fabric that is UPF 40+ rated. It is moisture-wicking and abrasion-resistant, making it perfect for trail or travel.
  • Tropicview Baseball Cap: A sun-blocking baseball hat with UPF 50+ rated sun protection. It has a rear flap for extra coverage that can be tucked away when not needed. It also has an elastic cord for infinite adjustment, a Coolmax sweatband, and mesh side panels for ventilation.

  以上是详细的步骤,我也依旧可以使用4.1 节的简单代码来实现这一些。我们可以指定embedding或者是不同的vectorstore类型,

index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch,
    embedding=embeddings,
	).from_loaders([loader])
	
response = index.query(query, llm=llm)
display(Markdown(response))
NameDescription
Men’s Tropical Plaid Short-Sleeve ShirtUPF 50+ rated, 100% polyester, wrinkle-resistant, front and back cape venting, two front bellows pockets
Men’s Plaid Tropic Shirt, Short-SleeveUPF 50+ rated, 52% polyester and 48% nylon, machine washable and dryable, front and back cape venting, two front bellows pockets
Men’s TropicVibe Shirt, Short-SleeveUPF 50+ rated, 71% Nylon, 29% Polyester, 100% Polyester knit mesh, wrinkle resistant, front and back cape venting, two front bellows pockets
Sun Shield Shirt byUPF 50+ rated, 78% nylon, 22% Lycra Xtra Life fiber, wicks moisture, fits comfortably over swimsuit, abrasion resistant

4.3 其它方法

  stuff方法是将所有的文档内容都传递给一个prompt,然后输入模型进行响应,这个方法简单而有效。但如果我们想对许多不同类型的文档进行相同类型的问答,该怎么办呢?
在这里插入图片描述
接下来介绍几种其它的方法:

  • Map_reduce:将所有相同类型的文本片段一起传递给模型,得到一个回答。然后调用另一个语言模型对所有不同类型文本的回答进行汇总,得到最终的答案,这样可以并行处理无数的文档。缺点是,Map_reduce将所有的文档都视为独立的,这不一定是最优解。
  • Refine:迭代循环,基于前一个答案的基础上来构建,这对于信息合并以及逐步作答非常有用,一般会得到比较长的答案,缺点是不能并行处理。
  • Map_rerank:为每个文档执行一次LLM调用,对答案进行排序后返回最高分。所以你需要告诉模型,如果文档和输入越相关,得分越高,并做精确的指导说明。Map_rerank也可以并行处理,但是调用相对昂贵。

以上方法,除了问答链之外,也可以用于其它的链条。例如Map_reduce常用于摘要链,

在这里插入图片描述

五、评估

  当用LLM构建复杂的应用程序时,一个重要的问题是如何评估应用程序的性能。另外,如果要改变一些参数,比如更换LLM模型、向量数据库使用策略、检索通道或者其它参数等等,如何确定效果是变好还是变坏?由此,本节将介绍一些评估工具。

  应用程序本质上是不同步骤的链式和序列化组合,所以首先你需要了解每一步的输入和输出。一些工具可以作为可视化监视器或者调优器,还有一种办法是使用LLM本身和chains本身来评估其它语言模型。其它chains和APP。随着许多开发基于prompt,整个LLM开发APP的整个工作流的评估过程正在被重新定义。

  • 示例生成:Example generation
  • 手动评估(和调试):Manual evaluation (and debugging)
  • LLM辅助评估:LLM-assisted evaluation
import os
import openai

os.environ["OPENAI_API_KEY"] = 'your openai_api_key '
openai.api_key = os.environ['OPENAI_API_KEY']

5.1 创建QA app

  首先我们用上一节的QA chains作为需要被评估的chains。如果中间出现报错,根据报错信息选择安装docarray或tiktoken。

from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import CSVLoader
from langchain.indexes import VectorstoreIndexCreator
from langchain.vectorstores import DocArrayInMemorySearch

# 加载数据
file = 'OutdoorClothingCatalog_1000.csv'
loader = CSVLoader(file_path=file,encoding='utf-8')
data = loader.load()

#一行代码创建索引
#!pip install docarray -i http://pypi.douban.com/simple
#!pip install tiktoken -i http://pypi.douban.com/simple

index = VectorstoreIndexCreator(
    vectorstore_cls=DocArrayInMemorySearch
).from_loaders([loader])

下面通过制定LLM、chains类型、检索器来创建QA chains

llm = ChatOpenAI(temperature = 0.0)
qa = RetrievalQA.from_chain_type(
    llm=llm, 
    chain_type="stuff", 
    retriever=index.vectorstore.as_retriever(), 
    verbose=True,
    chain_type_kwargs = {"document_separator": "<<<<>>>>>"}
)

下面我们需要弄清楚要对QA chains进行评估的datapoints是什么。

5.2 生成测试数据点

  生成测试数据点(test datapoints)的目的是模拟真实世界中模型将要面对的数据。这些数据点应该具有与实际应用场景相似的特征和分布,以测试模型在实际环境中的表现。生成测试数据点的方法可以有多种,例如从已有数据集中抽样、合成数据或手动创建具有特定特征的数据点。

  下面介绍的第一种方法是,根据查看一些数据,然后自己提出示例问题及答案,用于后续评估。

5.2.1 Hard-coded examples

下面我们查看两条数据,然后提出一些简单的问题进行回答。

data[10]
Document(page_content=": 10\nname: Cozy Comfort Pullover Set, Stripe\ndescription: Perfect for lounging, this striped knit set lives up to its name. We used ultrasoft fabric and an easy design that's as comfortable at bedtime as it is when we have to make a quick run out.\n\nSize & Fit\n- Pants are Favorite Fit: Sits lower on the waist.\n- Relaxed Fit: Our most generous fit sits farthest from the body.\n\nFabric & Care\n- In the softest blend of 63% polyester, 35% rayon and 2% spandex.\n\nAdditional Features\n- Relaxed fit top with raglan sleeves and rounded hem.\n- Pull-on pants have a wide elastic waistband and drawstring, side pockets and a modern slim leg.\n\nImported.", metadata={'source': 'OutdoorClothingCatalog_1000.csv', 'row': 10})
data[11]
Document(page_content=': 11\nname: Ultra-Lofty 850 Stretch Down Hooded Jacket\ndescription: This technical stretch down jacket from our DownTek collection is sure to keep you warm and comfortable with its full-stretch construction providing exceptional range of motion. With a slightly fitted style that falls at the hip and best with a midweight layer, this jacket is suitable for light activity up to 20° and moderate activity up to -30°. The soft and durable 100% polyester shell offers complete windproof protection and is insulated with warm, lofty goose down. Other features include welded baffles for a no-stitch construction and excellent stretch, an adjustable hood, an interior media port and mesh stash pocket and a hem drawcord. Machine wash and dry. Imported.', metadata={'source': 'OutdoorClothingCatalog_1000.csv', 'row': 11})
examples = [
    {
        "query": "Do the Cozy Comfort Pullover Set have side pockets?",
        "answer": "Yes"
    },
    {
        "query": "What collection is the Ultra-Lofty 850 Stretch Down Hooded Jacket from?",
        "answer": "The DownTek collection"
    }
]

5.2.2 LLM-Generated examples

  人工标注的缺点就是比较贵,所以我们可以考虑使用LLM自动生成问答示例。在langchain中,我们可以导入QA生成链,它将接受文档输入,然后自动创建问答对。apply_and_parse方法会将输出解析器应用于输出,将原本字符串类型的输出转换为包含query-answer pairs的字典。

from langchain.evaluation.qa import QAGenerateChain

example_gen_chain = QAGenerateChain.from_llm(ChatOpenAI())
new_examples = example_gen_chain.apply_and_parse(
    											[{"doc": t} for t in data[:5]]
												)
new_examples[0]
{'query': "What is the weight of each pair of Women's Campside Oxfords?",
 'answer': "The approximate weight of each pair of Women's Campside Oxfords is 1 lb. 1 oz."}

现在让我们检查一下这个问答对所对应的文档输入。

data[0]
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})

合并以上所有示例:

examples += new_examples

  现在我们有了一些示例,接下来该如何评估呢?一个直接的想法就是将其传递给QA chains,看看输出是什么。

  下面我们传入一条query并运行,可以看到打印的结果有限。我们输入模型的prompt是什么?它检索到的文档是什么?如果这是一个复杂链条,有很多中间步骤,那么中间结果又是什么?这些都没有显示出来。

qa.run(examples[0]["query"])
[1m> Entering new RetrievalQA chain...[0m

[1m> Finished chain.[0m





'The Cozy Comfort Pullover Set, Stripe does have side pockets.'

5.3 link chain debug手动评估

  为了解决以上问题,我们可以使用langchain中的一个小工具——link chain debug。设置langchain.debug = True,再次运行示例,可以看到模型输出了更详细的信息。

  模型输入首先进入了检索问答链RetrievalQA,然后进入StuffDocumentsChain。这个链使用stuff方法进入LLMChain,其中有几个不同的输入(question、context)。因此,当模型在进行问答时出错,不一定是LLM本身出错了,也有可能是检索步骤出错了,我们可以仔细查看question和context进行确认。

  再深入一层,我们看看输入语言模型ChatOpenAI的内容。这里我们可以看到传入ChatOpenAI的prompt、system message和context。

  这之后,生成了提问,LLM根据提问生成了答案“The Cozy Comfort Pullover Set, Stripe does have side pockets”,并逐步冒泡回传到上一层链条,最终到达RetrievalQA chain,输出最终结果。中间我们还可以看到tokens信息和使用的模型信息,这些信息让我们可以跟踪链式调用过程中总令牌数,这和使用成本息息相关。

import langchain

langchain.debug = True
qa.run(examples[0]["query"])
[chain/start] [1:RunTypeEnum.chain:RetrievalQA] Entering Chain run with input:
{
  "query": "Do the Cozy Comfort Pullover Set        have side pockets?"
}
[chain/start] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain] Entering Chain run with input:
[inputs]
[chain/start] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain > 3:RunTypeEnum.chain:LLMChain] Entering Chain run with input:
{
  "question": "Do the Cozy Comfort Pullover Set        have side pockets?",
  "context": ": 10\nname: Cozy Comfort Pullover Set, Stripe\ndescription: Perfect for lounging, this striped knit set lives up to its name. We used ultrasoft fabric and an easy design that's as comfortable at bedtime as it is when we have to make a quick run out.\n\nSize & Fit\n- Pants are Favorite Fit: Sits lower on the waist.\n- Relaxed Fit: Our most generous fit sits farthest from the body.\n\nFabric & Care\n- In the softest blend of 63% polyester, 35% rayon and 2% spandex.\n\nAdditional Features\n- Relaxed fit top with raglan sleeves and rounded hem.\n- Pull-on pants have a wide elastic waistband and drawstring, side pockets and a modern slim leg.\n\nImported.<<<<>>>>>: 73\nname: Cozy Cuddles Knit Pullover Set\ndescription: Perfect for lounging, this knit set lives up to its name. We used ultrasoft fabric and an easy design that's as comfortable at bedtime as it is when we have to make a quick run out. \n\nSize & Fit \nPants are Favorite Fit: Sits lower on the waist. \nRelaxed Fit: Our most generous fit sits farthest from the body. \n\nFabric & Care \nIn the softest blend of 63% polyester, 35% rayon and 2% spandex.\n\nAdditional Features \nRelaxed fit top with raglan sleeves and rounded hem. \nPull-on pants have a wide elastic waistband and drawstring, side pockets and a modern slim leg. \nImported.<<<<>>>>>: 632\nname: Cozy Comfort Fleece Pullover\ndescription: The ultimate sweater fleece – made from superior fabric and offered at an unbeatable price. \n\nSize & Fit\nSlightly Fitted: Softly shapes the body. Falls at hip. \n\nWhy We Love It\nOur customers (and employees) love the rugged construction and heritage-inspired styling of our popular Sweater Fleece Pullover and wear it for absolutely everything. From high-intensity activities to everyday tasks, you'll find yourself reaching for it every time.\n\nFabric & Care\nRugged sweater-knit exterior and soft brushed interior for exceptional warmth and comfort. Made from soft, 100% polyester. Machine wash and dry.\n\nAdditional Features\nFeatures our classic Mount Katahdin logo. Snap placket. Front princess seams create a feminine shape. Kangaroo handwarmer pockets. Cuffs and hem reinforced with jersey binding. Imported.\n\n – Official Supplier to the U.S. Ski Team\nTHEIR WILL TO WIN, WOVEN RIGHT IN. LEARN MORE<<<<>>>>>: 151\nname: Cozy Quilted Sweatshirt\ndescription: Our sweatshirt is an instant classic with its great quilted texture and versatile weight that easily transitions between seasons. With a traditional fit that is relaxed through the chest, sleeve, and waist, this pullover is lightweight enough to be worn most months of the year. The cotton blend fabric is super soft and comfortable, making it the perfect casual layer. To make dressing easy, this sweatshirt also features a snap placket and a heritage-inspired Mt. Katahdin logo patch. For care, machine wash and dry. Imported."
}
[llm/start] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain > 3:RunTypeEnum.chain:LLMChain > 4:RunTypeEnum.llm:ChatOpenAI] Entering LLM run with input:
{
  "prompts": [
    "System: Use the following pieces of context to answer the users question. \nIf you don't know the answer, just say that you don't know, don't try to make up an answer.\n----------------\n: 10\nname: Cozy Comfort Pullover Set, Stripe\ndescription: Perfect for lounging, this striped knit set lives up to its name. We used ultrasoft fabric and an easy design that's as comfortable at bedtime as it is when we have to make a quick run out.\n\nSize & Fit\n- Pants are Favorite Fit: Sits lower on the waist.\n- Relaxed Fit: Our most generous fit sits farthest from the body.\n\nFabric & Care\n- In the softest blend of 63% polyester, 35% rayon and 2% spandex.\n\nAdditional Features\n- Relaxed fit top with raglan sleeves and rounded hem.\n- Pull-on pants have a wide elastic waistband and drawstring, side pockets and a modern slim leg.\n\nImported.<<<<>>>>>: 73\nname: Cozy Cuddles Knit Pullover Set\ndescription: Perfect for lounging, this knit set lives up to its name. We used ultrasoft fabric and an easy design that's as comfortable at bedtime as it is when we have to make a quick run out. \n\nSize & Fit \nPants are Favorite Fit: Sits lower on the waist. \nRelaxed Fit: Our most generous fit sits farthest from the body. \n\nFabric & Care \nIn the softest blend of 63% polyester, 35% rayon and 2% spandex.\n\nAdditional Features \nRelaxed fit top with raglan sleeves and rounded hem. \nPull-on pants have a wide elastic waistband and drawstring, side pockets and a modern slim leg. \nImported.<<<<>>>>>: 632\nname: Cozy Comfort Fleece Pullover\ndescription: The ultimate sweater fleece – made from superior fabric and offered at an unbeatable price. \n\nSize & Fit\nSlightly Fitted: Softly shapes the body. Falls at hip. \n\nWhy We Love It\nOur customers (and employees) love the rugged construction and heritage-inspired styling of our popular Sweater Fleece Pullover and wear it for absolutely everything. From high-intensity activities to everyday tasks, you'll find yourself reaching for it every time.\n\nFabric & Care\nRugged sweater-knit exterior and soft brushed interior for exceptional warmth and comfort. Made from soft, 100% polyester. Machine wash and dry.\n\nAdditional Features\nFeatures our classic Mount Katahdin logo. Snap placket. Front princess seams create a feminine shape. Kangaroo handwarmer pockets. Cuffs and hem reinforced with jersey binding. Imported.\n\n – Official Supplier to the U.S. Ski Team\nTHEIR WILL TO WIN, WOVEN RIGHT IN. LEARN MORE<<<<>>>>>: 151\nname: Cozy Quilted Sweatshirt\ndescription: Our sweatshirt is an instant classic with its great quilted texture and versatile weight that easily transitions between seasons. With a traditional fit that is relaxed through the chest, sleeve, and waist, this pullover is lightweight enough to be worn most months of the year. The cotton blend fabric is super soft and comfortable, making it the perfect casual layer. To make dressing easy, this sweatshirt also features a snap placket and a heritage-inspired Mt. Katahdin logo patch. For care, machine wash and dry. Imported.\nHuman: Do the Cozy Comfort Pullover Set        have side pockets?"
  ]
}
[llm/end] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain > 3:RunTypeEnum.chain:LLMChain > 4:RunTypeEnum.llm:ChatOpenAI] [80.07s] Exiting LLM run with output:
{
  "generations": [
    [
      {
        "text": "Yes, the Cozy Comfort Pullover Set has side pockets.",
        "generation_info": null,
        "message": {
          "content": "Yes, the Cozy Comfort Pullover Set has side pockets.",
          "additional_kwargs": {},
          "example": false
        }
      }
    ]
  ],
  "llm_output": {
    "token_usage": {
      "prompt_tokens": 734,
      "completion_tokens": 13,
      "total_tokens": 747
    },
    "model_name": "gpt-3.5-turbo"
  },
  "run": null
}
[chain/end] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain > 3:RunTypeEnum.chain:LLMChain] [80.08s] Exiting Chain run with output:
{
  "text": "Yes, the Cozy Comfort Pullover Set has side pockets."
}
[chain/end] [1:RunTypeEnum.chain:RetrievalQA > 2:RunTypeEnum.chain:StuffDocumentsChain] [80.08s] Exiting Chain run with output:
{
  "output_text": "Yes, the Cozy Comfort Pullover Set has side pockets."
}
[chain/end] [1:RunTypeEnum.chain:RetrievalQA] [80.65s] Exiting Chain run with output:
{
  "result": "Yes, the Cozy Comfort Pullover Set has side pockets."
}
'Yes, the Cozy Comfort Pullover Set has side pockets.'

5.4 LLM assisted evaluation

  上一节我们调试了链式调用单个示例输入的情况,如果是输入很多示例,该怎么办呢?一种方法是同样进行手动的链式调用评估,看看每个示例输入时发生了什么,以此判断中间步骤是否是正确的,但这样做非常乏味且耗时。

  回到我们最喜欢的解决方式,用LLM来做这一切。首先关闭debug模式,免得打印的信息太多,然后预测所有问题的输出。

# Turn off the debug mode
langchain.debug = False
predictions = qa.apply(examples)
> Entering new  chain...


> Finished chain.


> Entering new  chain...

> Finished chain.


> Entering new  chain...

> Finished chain.

> Entering new  chain...

> Finished chain.


> Entering new  chain...

> Finished chain.


> Entering new  chain...

> Finished chain.


> Entering new  chain...

> Finished chain.

接着,我们导入QA评估链及其评估函数evaluate,用语言模型来帮助我们进行评估。

from langchain.evaluation.qa import QAEvalChain

llm = ChatOpenAI(temperature=0)
eval_chain = QAEvalChain.from_llm(llm)
graded_outputs = eval_chain.evaluate(examples, predictions)

  导入示例和预测结果,打印一系列分级输出。其中,Question和Real Answer是LLM生成的,Predicted Answer也由语言模型生成,Predicted Grade由语言模型评估得到。

for i, eg in enumerate(examples):
    print(f"Example {i}:")
    print("Question: " + predictions[i]['query'])
    print("Real Answer: " + predictions[i]['answer'])
    print("Predicted Answer: " + predictions[i]['result'])
    print("Predicted Grade: " + graded_outputs[i]['text'])
    print()
Example 0:
Question: Do the Cozy Comfort Pullover Set have side pockets?
Real Answer: Yes
Predicted Answer: The Cozy Comfort Pullover Set, Stripe does have side pockets.
Predicted Grade: CORRECT

Example 1:
Question: What collection is the Ultra-Lofty 850 Stretch Down Hooded Jacket from?
Real Answer: The DownTek collection
Predicted Answer: The Ultra-Lofty 850 Stretch Down Hooded Jacket is from the DownTek collection.
Predicted Grade: CORRECT

Example 2:
Question: What is the weight of each pair of Women's Campside Oxfords?
Real Answer: The approximate weight of each pair of Women's Campside Oxfords is 1 lb. 1 oz.
Predicted Answer: The weight of each pair of Women's Campside Oxfords is approximately 1 lb. 1 oz.
Predicted Grade: CORRECT

Example 3:
Question: What are the dimensions of the small and medium Recycled Waterhog Dog Mat?
Real Answer: The dimensions of the small Recycled Waterhog Dog Mat are 18" x 28" and the dimensions of the medium Recycled Waterhog Dog Mat are 22.5" x 34.5".
Predicted Answer: The small Recycled Waterhog Dog Mat has dimensions of 18" x 28" and the medium size has dimensions of 22.5" x 34.5".
Predicted Grade: CORRECT

Example 4:
Question: What are some features of the Infant and Toddler Girls' Coastal Chill Swimsuit?
Real Answer: The swimsuit features bright colors, ruffles, and exclusive whimsical prints. It is made of four-way-stretch and chlorine-resistant fabric, ensuring that it keeps its shape and resists snags. The swimsuit is also UPF 50+ rated, providing the highest rated sun protection possible by blocking 98% of the sun's harmful rays. The crossover no-slip straps and fully lined bottom ensure a secure fit and maximum coverage. Finally, it can be machine washed and line dried for best results.
Predicted Answer: The Infant and Toddler Girls' Coastal Chill Swimsuit is a two-piece swimsuit with bright colors, ruffles, and exclusive whimsical prints. It is made of four-way-stretch and chlorine-resistant fabric that keeps its shape and resists snags. The swimsuit has UPF 50+ rated fabric that provides the highest rated sun protection possible, blocking 98% of the sun's harmful rays. The crossover no-slip straps and fully lined bottom ensure a secure fit and maximum coverage. It is machine washable and should be line dried for best results.
Predicted Grade: CORRECT

Example 5:
Question: What is the fabric composition of the Refresh Swimwear V-Neck Tankini Contrasts?
Real Answer: The body of the Refresh Swimwear V-Neck Tankini Contrasts is made of 82% recycled nylon and 18% Lycra® spandex, while the lining is made of 90% recycled nylon and 10% Lycra® spandex.
Predicted Answer: The Refresh Swimwear V-Neck Tankini Contrasts is made of 82% recycled nylon with 18% Lycra® spandex for the body and 90% recycled nylon with 10% Lycra® spandex for the lining.
Predicted Grade: CORRECT

Example 6:
Question: What is the fabric composition of the EcoFlex 3L Storm Pants?
Real Answer: The EcoFlex 3L Storm Pants are made of 100% nylon, exclusive of trim.
Predicted Answer: The fabric composition of the EcoFlex 3L Storm Pants is 100% nylon, exclusive of trim.
Predicted Grade: CORRECT

5.5 LangChain Evaluation platform

auto-evaluator

  最后介绍link chain评估平台,可以完成上面实现的所有评估步骤,并在用户界面中持久化展示,打印的结果也更加的美观。下面是一个名为DeepLearningai的会话,我们可以看到每一步中输入输出是什么,可以点击某条链查看更具体的信息。一直点到底,可以看到输入LLM的system message、context和answer。 点击右上按钮还可以导入数据。这种方式可以在后台持续运行,并逐步添加示例进行评估。
在这里插入图片描述
在这里插入图片描述

六、Agents(代理)

  比起知识库,LLMs更应该被看作是一个推理引擎。你可以给它提供文本片段或其他信息来源,LLMs就可以使用从互联网上学到的新的背景知识,帮助你回答问题、推理内容或者甚至决定下一步该做什么,这就是LangChain的Agents(代理)框架所帮助你实现的。(感觉就是chatgpt的插件系统)

  下面将了解代理是什么、如何创建和使用代理,以及如何为其配备不同类型的工具(如LangChain内置的搜索引擎);以及如何创建自己的工具,使代理能够与任何数据存储、任何API或任何你想要的函数进行交互。

  • Using built in LangChain tools: DuckDuckGo search and Wikipedia
  • Defining your own tools
import os

from dotenv import load_dotenv, find_dotenv
_ = load_dotenv(find_dotenv()) # read local .env file

import warnings
warnings.filterwarnings("ignore")

6.1 使用内置的LangChain tools进行代理

导入相关库,使用ChatOpenAI语言模型作为Agents的推理引擎,连接到其它的数据源和计算资源。

#!pip install -U wikipedia
from langchain.agents.agent_toolkits import create_python_agent
from langchain.agents import load_tools, initialize_agent
from langchain.agents import AgentType
from langchain.tools.python.tool import PythonREPLTool
from langchain.python import PythonREPL
from langchain.chat_models import ChatOpenAI


llm = ChatOpenAI(temperature=0)

  加载LLM数学工具和维基百科工具。llm-math实际上是一个链,使用语言模型和计算器来解决数学问题。wikipedia可以对维基百科进行搜索和查询。然后使用tools、llm、agent来初始化agent。

  “AgentType”将用于指定我们要使用的代理类型,“CHAT_ZERO_SHOT_REACT_DESCRIPTION”中的chat是针对聊天模型进行优化的,React是一种提策略,旨在使语言模型推理性能最优化。

  在第一节课我们讨论了输出解析器,以及如何将LLM的输出(字符串)解析为我们可以在下游使用的特定格式。这里我们设置handle_parsing_errors=True,表示碰到输出解析错误时,将错误格式的文本传回语言模型,进行更正,这一点很重要。

tools = load_tools(["llm-math","wikipedia"], llm=llm)
agent= initialize_agent(
    tools, 
    llm, 
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    handle_parsing_errors=True,
    verbose = True)

agent("What is the 25% of 300?")

在这里插入图片描述
根据打印的输出,可以看到整个模型处理的过程:

  • Thought
  • Action:一个json块,包含两个字段
    • action:要使用的工具是计算器,后者是。
    • action input:传入工具的输入
  • Observation:观察。计算器的答案是75(蓝色)
  • Thought:回到语言模型,计算器返回的答案是75
  • Final Answer: 25% of 300 is 75.0

  下面是一个维基百科的示例,我们想了解一下Tom M. Mitchell,模型意识到它应该调用维基百科来进行回答。

question = "Tom M. Mitchell is an American computer scientist \
and the Founders University Professor at Carnegie Mellon University (CMU)\
what book did he write?"
result = agent(question) 
> Entering new AgentExecutor chain...
Thought: I should use Wikipedia to find the answer to this question.

Action:
```
{
  "action": "Wikipedia",
  "action_input": "Tom M. Mitchell"
}
```


Observation: Page: Tom M. Mitchell
Summary: Tom Michael Mitchell (born August 9, 1951) is an American computer scientist and the Founders University Professor at Carnegie Mellon University (CMU). He is a founder and former Chair of the Machine Learning Department at CMU. Mitchell is known for his contributions to the advancement of machine learning, artificial intelligence, and cognitive neuroscience and is the author of the textbook Machine Learning. He is a member of the United States National Academy of Engineering since 2010. He is also a Fellow of the American Academy of Arts and Sciences, the American Association for the Advancement of Science and a Fellow and past President of the Association for the Advancement of Artificial Intelligence. In October 2018, Mitchell was appointed as the Interim Dean of the School of Computer Science at Carnegie Mellon.

Page: Tom Mitchell (Australian footballer)
Summary: Thomas Mitchell (born 31 May 1993) is a professional Australian rules footballer playing for the Collingwood Football Club in the Australian Football League (AFL). He previously played for the Sydney Swans from 2012 to 2016, and the Hawthorn Football Club between 2017 and 2022. Mitchell won the Brownlow Medal as the league's best and fairest player in 2018 and set the record for the most disposals in a VFL/AFL match, accruing 54 in a game against Collingwood during that season.
Thought:The book that Tom M. Mitchell wrote is "Machine Learning".

Action:
```
{
  "action": "Wikipedia",
  "action_input": "Machine Learning (book)"
}
```


Observation: Page: Machine learning
Summary: Machine learning (ML) is a branch of artificial intelligence that leverages data to improve computer performance by giving machines the ability to "learn".Machine learning algorithms build a model based on sample data, known as training data, in order to make predictions or decisions without being explicitly programmed to do so. Machine learning algorithms are used in a wide variety of applications, such as in medicine, email filtering, speech recognition, agriculture, and computer vision, where it is difficult or unfeasible to develop conventional algorithms to perform the needed tasks.A subset of machine learning is closely related to computational statistics, which focuses on making predictions using computers, but not all machine learning is statistical learning. The study of mathematical optimization delivers methods, theory and application domains to the field of machine learning. Data mining is a related field of study, focusing on exploratory data analysis through unsupervised learning.Some implementations of machine learning use data and artificial neural networks in a way that mimics the working of a biological brain.In its application across business problems, machine learning is also referred to as predictive analytics.

Page: Quantum machine learning
Summary: Quantum machine learning is the integration of quantum algorithms within machine learning programs. The most common use of the term refers to machine learning algorithms for the analysis of classical data executed on a quantum computer, i.e. quantum-enhanced machine learning. While machine learning algorithms are used to compute immense quantities of data, quantum machine learning utilizes qubits and quantum operations or specialized quantum systems to improve computational speed and data storage done by algorithms in a program. This includes hybrid methods that involve both classical and quantum processing, where computationally difficult subroutines are outsourced to a quantum device. These routines can be more complex in nature and executed faster on a quantum computer. Furthermore, quantum algorithms can be used to analyze quantum states instead of classical data. Beyond quantum computing, the term "quantum machine learning" is also associated with classical machine learning methods applied to data generated from quantum experiments (i.e. machine learning of quantum systems), such as learning the phase transitions of a quantum system or creating new quantum experiments. Quantum machine learning also extends to a branch of research that explores methodological and structural similarities between certain physical systems and learning systems, in particular neural networks. For example, some mathematical and numerical techniques from quantum physics are applicable to classical deep learning and vice versa. Furthermore, researchers investigate more abstract notions of learning theory with respect to quantum information, sometimes referred to as "quantum learning theory".

Page: Timeline of machine learning
Summary: This page is a timeline of machine learning. Major discoveries, achievements, milestones and other major events in machine learning are included.
Thought:Tom M. Mitchell wrote the book "Machine Learning".

Final Answer: "Machine Learning".

> Finished chain.

  模型调用了Wikipedia,其观察结果是黄色(langchain使用不同颜色来表示不同工具的观察结果)。结果显示有两个Tom M. Mitchell,分别是计算机学家和足球运动员。问题所需要的书名包含在第一位Tom M. Mitchell的摘要介绍中。接下来模型尝试了解Machine Learning (book)这本书的更多信息,然后模型意识到正确答案就是Machine Learning ,于是将其返回。

6.2 使用Python Agent

使用Python Agent实现类似copilot的功能,这里使用的工具是PythonREPLTool。REPL是一种与代码进行交互的方式,可以看作是jupyter。

agent = create_python_agent(
    llm,
    tool=PythonREPLTool(),
    verbose=True)

customer_list = [["Harrison", "Chase"], 
                 ["Lang", "Chain"],
                 ["Dolly", "Too"],
                 ["Elle", "Elem"], 
                 ["Geoff","Fusion"], 
                 ["Trance","Former"],
                 ["Jen","Ayai"]
                ]

agent.run(f"""Sort these customers by last name and then first name and print the output: {customer_list}""") 

模型意识到可以使用sorted函数来解决这个问题,然后调用Python REPL来解决。

> Entering new AgentExecutor chain...
I can use the sorted() function to sort the list of customers by last name and then first name. I will need to provide a key function to sorted() that returns a tuple of the last name and first name in that order.
Action: Python REPL
Action Input:
```
customers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]
sorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))
for customer in sorted_customers:
    print(customer)
```
Observation: ['Jen', 'Ayai']
['Lang', 'Chain']
['Harrison', 'Chase']
['Elle', 'Elem']
['Trance', 'Former']
['Geoff', 'Fusion']
['Dolly', 'Too']

Thought:The customers are now sorted by last name and then first name. 
Final Answer: [['Jen', 'Ayai'], ['Lang', 'Chain'], ['Harrison', 'Chase'], ['Elle', 'Elem'], ['Trance', 'Former'], ['Geoff', 'Fusion'], ['Dolly', 'Too']]

> Finished chain.
"[['Jen', 'Ayai'], ['Lang', 'Chain'], ['Harrison', 'Chase'], ['Elle', 'Elem'], ['Trance', 'Former'], ['Geoff', 'Fusion'], ['Dolly', 'Too']]"

6.3 调试agent chains

  下面设置langchain.debug=True打印所有级别,来深入了解一下模型运行的过程。有时,agent的调用有点奇怪,这种调式模式会很有用。

import langchain
langchain.debug=True
agent.run(f"""Sort these customers by \
last name and then first name \
and print the output: {customer_list}""") 
langchain.debug=False
[chain/start] [1:chain:AgentExecutor] Entering Chain run with input:  # 这一步是顶级代理执行器
{
  "input": "Sort these customers by last name and then first name and print the output: [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]"
}
[chain/start] [1:chain:AgentExecutor > 2:chain:LLMChain] Entering Chain run with input: # 这一级是LLMchain
{
  "input": "Sort these customers by last name and then first name and print the output: [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]",
  "agent_scratchpad": "",
  "stop": [
    "\nObservation:",
    "\n\tObservation:"
  ]
}
[llm/start] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] Entering LLM run with input:  # 对LLM的真正调用,输入包括格式化的prompt,包含可以访问的工具和如何格式化输出的说明。
{
  "prompts": [
    "Human: You are an agent designed to write and execute python code to answer questions.\nYou have access to a python REPL, which you can use to execute python code.\nIf you get an error, debug your code and try again.\nOnly use the output of your code to answer the question. \nYou might know the answer without running any code, but you should still run the code to get the answer.\nIf it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer.\n\n\nPython REPL: A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Python REPL]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: Sort these customers by last name and then first name and print the output: [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nThought:"
  ]
}
[llm/end] [1:chain:AgentExecutor > 2:chain:LLMChain > 3:llm:ChatOpenAI] [5.34s] Exiting LLM run with output:
{
  "generations": [
    [
      {
        "text": "I can use the `sorted()` function to sort the list of customers. I will need to provide a key function that specifies the sorting order based on last name and then first name.\nAction: Python REPL\nAction Input: \n```python\ncustomers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nsorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))\nsorted_customers\n```",
        "generation_info": null,
        "message": {
          "content": "I can use the `sorted()` function to sort the list of customers. I will need to provide a key function that specifies the sorting order based on last name and then first name.\nAction: Python REPL\nAction Input: \n```python\ncustomers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nsorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))\nsorted_customers\n```",
          "additional_kwargs": {},
          "example": false
        }
      }
    ]
  ],
  "llm_output": {
    "token_usage": {
      "prompt_tokens": 326,
      "completion_tokens": 129,
      "total_tokens": 455
    },
    "model_name": "gpt-3.5-turbo"
  }
}
[chain/end] [1:chain:AgentExecutor > 2:chain:LLMChain] [5.34s] Exiting Chain run with output:
{
  "text": "I can use the `sorted()` function to sort the list of customers. I will need to provide a key function that specifies the sorting order based on last name and then first name.\nAction: Python REPL\nAction Input: \n```python\ncustomers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nsorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))\nsorted_customers\n```"
}
[tool/start] [1:chain:AgentExecutor > 4:tool:Python REPL] Entering Tool run with input:
"```python
customers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]
sorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))
sorted_customers
```"
[tool/end] [1:chain:AgentExecutor > 4:tool:Python REPL] [0.383ms] Exiting Tool run with output:
""
[chain/start] [1:chain:AgentExecutor > 5:chain:LLMChain] Entering Chain run with input:
{
  "input": "Sort these customers by last name and then first name and print the output: [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]",
  "agent_scratchpad": "I can use the `sorted()` function to sort the list of customers. I will need to provide a key function that specifies the sorting order based on last name and then first name.\nAction: Python REPL\nAction Input: \n```python\ncustomers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nsorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))\nsorted_customers\n```\nObservation: \nThought:",
  "stop": [
    "\nObservation:",
    "\n\tObservation:"
  ]
}
[llm/start] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] Entering LLM run with input:
{
  "prompts": [
    "Human: You are an agent designed to write and execute python code to answer questions.\nYou have access to a python REPL, which you can use to execute python code.\nIf you get an error, debug your code and try again.\nOnly use the output of your code to answer the question. \nYou might know the answer without running any code, but you should still run the code to get the answer.\nIf it does not seem like you can write code to answer the question, just return \"I don't know\" as the answer.\n\n\nPython REPL: A Python shell. Use this to execute python commands. Input should be a valid python command. If you want to see the output of a value, you should print it out with `print(...)`.\n\nUse the following format:\n\nQuestion: the input question you must answer\nThought: you should always think about what to do\nAction: the action to take, should be one of [Python REPL]\nAction Input: the input to the action\nObservation: the result of the action\n... (this Thought/Action/Action Input/Observation can repeat N times)\nThought: I now know the final answer\nFinal Answer: the final answer to the original input question\n\nBegin!\n\nQuestion: Sort these customers by last name and then first name and print the output: [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nThought:I can use the `sorted()` function to sort the list of customers. I will need to provide a key function that specifies the sorting order based on last name and then first name.\nAction: Python REPL\nAction Input: \n```python\ncustomers = [['Harrison', 'Chase'], ['Lang', 'Chain'], ['Dolly', 'Too'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Jen', 'Ayai']]\nsorted_customers = sorted(customers, key=lambda x: (x[1], x[0]))\nsorted_customers\n```\nObservation: \nThought:"
  ]
}
[llm/end] [1:chain:AgentExecutor > 5:chain:LLMChain > 6:llm:ChatOpenAI] [2.41s] Exiting LLM run with output:
{
  "generations": [
    [
      {
        "text": "The customers have been sorted by last name and then first name.\nFinal Answer: [['Jen', 'Ayai'], ['Harrison', 'Chase'], ['Lang', 'Chain'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Dolly', 'Too']]",
        "generation_info": null,
        "message": {
          "content": "The customers have been sorted by last name and then first name.\nFinal Answer: [['Jen', 'Ayai'], ['Harrison', 'Chase'], ['Lang', 'Chain'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Dolly', 'Too']]",
          "additional_kwargs": {},
          "example": false
        }
      }
    ]
  ],
  "llm_output": {
    "token_usage": {
      "prompt_tokens": 460,
      "completion_tokens": 67,
      "total_tokens": 527
    },
    "model_name": "gpt-3.5-turbo"
  }
}
[chain/end] [1:chain:AgentExecutor > 5:chain:LLMChain] [2.41s] Exiting Chain run with output:
{
  "text": "The customers have been sorted by last name and then first name.\nFinal Answer: [['Jen', 'Ayai'], ['Harrison', 'Chase'], ['Lang', 'Chain'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Dolly', 'Too']]"
}
[chain/end] [1:chain:AgentExecutor] [7.75s] Exiting Chain run with output:
{
  "output": "[['Jen', 'Ayai'], ['Harrison', 'Chase'], ['Lang', 'Chain'], ['Elle', 'Elem'], ['Geoff', 'Fusion'], ['Trance', 'Former'], ['Dolly', 'Too']]"
}

6.4 自定义代理工具

  Anget的一大特点是可以连接自己的信息源,自己的API和数据库。下面介绍如何创建一个自定义工具,连接到你自己的数据源。下面创建一个工具,用来获取当前日期。

#!pip install DateTime

导入tool修饰符,它可应用于任何函数,并将其转换为chain link可以调用的工具。

from langchain.agents import tool
from datetime import date

  下面定义time函数,接受任何文本字符串作为输入,但实际我们不会使用它,而是调用date来返回今天的日期。

  在time函数的说明中,我们编写了非常详细的文档字符串,用于让angent明白它该何时以及如何调用这个工具。如果我们对输入有更严格的要求,例如有一个函数应该始终接受搜索查询或SQL语句,那么必须在这里进行说明。

@tool
def time(text: str) -> str:
    """Returns todays date, use this for any questions related to knowing todays date. \
    The input should always be an empty string, and this function will always return todays date - any \
    date mathmatics should occur outside this function."""
    return str(date.today())

  现在我们将创建另一个代理。这次我们将时间工具添加到现有工具列表中。最后,让我们调用代理并问一下今天的日期是什么。

agent= initialize_agent(
    tools + [time], 
    llm, 
    agent=AgentType.CHAT_ZERO_SHOT_REACT_DESCRIPTION,
    handle_parsing_errors=True,
    verbose = True)

Note:
The agent will sometimes come to the wrong conclusion (agents are a work in progress!).
If it does, please try running it again.

try:
    result = agent("whats the date today?") 
except: 
    print("exception on external access")
> Entering new AgentExecutor chain...
Thought: I need to use the `time` tool to get today's date.
Action:
```
{
  "action": "time",
  "action_input": ""
}
```

Observation: 2023-06-27
Thought:I have successfully retrieved today's date using the `time` tool.
Final Answer: Today's date is 2023-06-27.

> Finished chain.

  可以看到,模型知道他要调用time工具,且action_input为空字符串,最后返回了今天的日期。

  这就是关于代理的课程。这是LangChain中较新、更令人兴奋和更具实验性的部分之一。所以我希望你喜欢使用它。希望它向你展示了如何将语言模型作为推理引擎,执行不同的操作,并连接其他功能和数据源。

七、总结

  在这个简短的课程中,你看到了一系列的应用,包括处理客户评论,构建一个可以回答文档问题的应用,甚至使用LLM决定何时调用外部工具(如网络搜索)来回答复杂问题。在这个简短的课程中看到了,只需相当合理的几行代码,你就可以使用LangChain相当高效地构建所有这些应用。

  你可以用语言模型做很多其他应用。这些模型之所以强大,是因为它们适用于如此广泛的任务,无论是回答有关CSV文件的问题、查询SQL数据库还是与API进行交互。

  在LangChain中,有许多不同的例子可以使用链式结构、提示和输出解析器的组合,以及更多的链式结构来完成所有这些任务。其中大部分要归功于LangChain社区。如果你还没有这样做,我希望你打开你的笔记本电脑或台式电脑,运行pip install LangChain,然后使用这个工具去构建一些令人惊奇的应用。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文笔记 CPU Accounting for Multicore Processors

Abstract 确定了对CPU utilization的不准确测量是如何影响OS的几个关键方面的这篇文章提出来了一个比CPU utilization更准确的性能评估指标 In this paper, we identify how an inaccurate measurement of the CPU utilization affects several key aspects of the system suc…

Python 基本数据类型(三)

文章目录 每日一句正能量数值运算数值类型实例String&#xff08;字符串&#xff09; 每日一句正能量 人的相处&#xff0c;靠的是真心&#xff0c;不是套路。合得来的人&#xff0c;坦诚相待&#xff0c;合不来的人&#xff0c;客气寒暄&#xff1b;谁也别给谁冷脸看&#xff…

期末复习【计算机网络】

期末复习【计算机网络】 前言推荐期末复习如何快速阅读电子书重点第1章 概述1.6 计算机网络的性能1.6.2 计算机网络的性能指标√ 1.7 计算机网络体系结构1.7.3 具有五层协议的体系结构√ 第2章 物理层2.3 物理层下面的传输媒体 *2.4 信道复用技术2.4.1 频分复用、时分复用和统计…

LeetCode 剑指 Offer 13. 机器人的运动范围(深度遍历)

LeetCode 剑指 Offer 13. 机器人的运动范围 原题思路代码运行截图收获 原题 LeetCode 剑指 Offer 13. 机器人的运动范围 思路 通过深度遍历来找出所有可达的格子通过0、1、2来区分未遍历、可到达、不可到达三种状态 代码 class Solution { public:int visited[109][109];i…

【计算机网络】数据链路层--点对点协议PPP

1.概念 2.构成 3.封装成帧 - 帧格式 4.透明传输 4.1字节填充法&#xff08;面向字节的异步链路&#xff09; 4.2.比特填充法&#xff08;面向比特的同步链路&#xff09; 5.差错检测 6.工作状态 7.小结

Webpack和Vite简单使用

目录 WebPack 介绍 基础使用 初始化使用 webpack.config.js文件 webpack开发服务器 vite 介绍 使用 使用vite创建vue框架项目 WebPack 介绍 当我们习惯了在node中编写代码的方式后&#xff0c;在回到前端编写html、css、js这些东西会感觉到各种的不便。比如: 不能放心…

【Linux】硬链接 和 软链接

为了方便用户访问文件&#xff0c;Linux提供了一种称为连接&#xff08;link&#xff09;的机制&#xff0c;可以将一个文件或目录与另一个文件或目录建立关联&#xff0c;从而实现多个路径指向同一个文件或目录的效果。 一、概述二、硬链接和软链接详解2.1 硬链接2.11 硬链接的…

C++ 模板

模板是泛型编程的基础&#xff0c;泛型编程即以一种独立于任何特定类型的方式编写代码。 模板是创建泛型类或函数的蓝图或公式。库容器&#xff0c;比如迭代器和算法&#xff0c;都是泛型编程的例子&#xff0c;它们都使用了模板的概念。 每个容器都有一个单一的定义&#xf…

微信小程序的跨页面传参以及data-方法的相关细节

&#x1f642;博主&#xff1a;小猫娃来啦 &#x1f642;文章核心&#xff1a;微信小程序的跨页面传参以及data-方法的相关细节 目录 前言wx.navigateTo()方法微信小程序传参的几种方式通过data-属性传参关于data-方法配合点击事件传参的细节 前言 其实在学习新东西的过程中&a…

记录一次对STM32G4串口硬件FIFO的调试

记录一次对STM32G4串口硬件FIFO的调试 前言&#xff1a;通常我们使用串口接收多字节数据会使用中断和DMA两种方式。使用中断方式&#xff0c;每接收到一个字节就会触发一次中断&#xff0c;我们可以在中断函数里将接收到的这一字节保存在内存中然后等待其他程序处理&#xff0c…

ruoyi-vue版本(三十)Spring Security 安全框架中token的生成与解析

目录 1 使用2 写工具类3 使用工具类 1 使用 1 项目里面添加依赖 <!-- Token生成与解析--><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency>2 写工具类 package com.ruoyi.framework.we…

ethtool 原理介绍和解决网卡丢包排查思路

前言 之前记录过处理因为 LVS 网卡流量负载过高导致软中断发生丢包的问题&#xff0c;RPS 和 RFS 网卡多队列性能调优实践[1]&#xff0c;对一般人来说压力不大的情况下其实碰见的概率并不高。这次想分享的话题是比较常见服务器网卡丢包现象排查思路&#xff0c;如果你是想了解…

【数据库四】MySQL备份与恢复

MySQL备份与恢复 1.数据库备份的分类1.1 数据备份的重要性1.2 数据库备份的分类1.3 常见的备份方法 2.MySQL完全备份与恢复2.1 MySQL完全备份2.2 数据库完全备份分类2.3 MySQL物理冷备份及恢复2.4 数据迁移DST2.5 mysqldump进行逻辑备份2.5.1 mysqldump备份数据库2.5.2 mysqldu…

Nvidia官方视频编解码性能

NVIDIA VIDEO CODEC SDK | NVIDIA Developer 1080P解码性能&#xff1a; 720P解码性能&#xff1a; 详细的参见官方的链接地址&#xff0c;对于GPU的解码fps能力&#xff0c;可以作为评估参照&#xff01;

视频与AI,与进程交互(二) pytorch 极简训练自己的数据集并识别

目标学习任务 检测出已经分割出的图像的分类 2 使用pytorch pytorch 非常简单就可以做到训练和加载 2.1 准备数据 如上图所示&#xff0c;用来训练的文件放在了train中&#xff0c;验证的文件放在val中&#xff0c;train.txt 和 val.txt 分别放文件名称和分类类别&#xff…

【JavaSE】初步认识

目录 【1】Java语言概述 【1.1】Java是什么 【1.2】Java语言重要性 【1.3】Java语言发展简史 【1.4】Java语言特性 【1.5】 Java开发环境安装 【2】初识Java的main方法 【2.1】main方法示例 【2.2】运行Java程序 【3】注释 【3.1】基本规则 【3.2】注释规范 【4】…

C语言--消失的数字

文章目录 1.法一&#xff1a;映射法2.法二&#xff1a;异或法3.法三&#xff1a;差值法4.法四&#xff1a;排序查找 1.法一&#xff1a;映射法 时间复杂度&#xff1a;O&#xff08;N&#xff09; 空间复杂度&#xff1a;O&#xff08;N&#xff09; #include<stdio.h>…

Tree树形控件做权限时,保持选项联动的同时,解决数据无法回显的问题

项目需求&#xff1a; 要求树形控件要有父子联动&#xff0c;也就是选择父级选项&#xff0c;子级也要选中&#xff0c;那么check-strictly属性就不能设置死,我的是 :check-strictlycheckStrictly,在data中赋值有变量。我之前设置check-strictly&#xff0c;就没了联动效果&…

补码的定义

补码的定义 补码的概念引入 补码的定义 例题