让AI做决策,学会langChain的Agent

今天内容涉及如下:

1.initialize_agent,:执行gent工作,并把工具Tool传入

2.Tool:选取行为函数工具类

之前我们学习的都是把问题给AI,让AI模型给出答案,那么这种情况下应该怎么处理呢,我需要根据不同的问题选择不同的答案,比如我问AI我想选择一件衣服就去调用挑选衣服的方法,如果是查询订单,那么就专门去调用搜索订单的方法,如果是查询物流就专门去调用物流方面的方法,但是怎么识别出来哪个调用哪个呢?

我们下面代码先模拟出怎么让AI根据我们的话语做选择,

#! pip install openai
! pip install langchain
import openai,os

from langchain.prompts import PromptTemplate
from langchain.llms import OpenAIChat
from langchain.chains import LLMChain


os.environ["OPENAI_API_KEY"] = ""
openai.api_key = os.environ.get("OPENAI_API_KEY")

llm=OpenAIChat(max_tokens=2048,temperature=0.5)
multiple_choice="""
请针对 >>> 和 <<< 中间的用户问题,选择一个合适的工具去回答它的问题。只要用A、B、C的选项字母告诉我答案。
如果你觉得都不合适,就选D。

>>>{question}<<<

我们有的工具包括:
A. 一个能够查询商品信息,为用户进行商品导购的工具
B. 一个能够查询订单信息,获得最新的订单情况的工具
C. 一个能够搜索商家的退换货政策、运费、物流时长、支付渠道、覆盖国家的工具
D. 都不合适
"""
multiple_choice_prompt=PromptTemplate(template=multiple_choice,input_variables=["question"])
choice_chain=LLMChain(llm=llm,prompt=multiple_choice_prompt, output_key="answer")

执行第一个问题:

question = "我想买一件衣服,但是不知道哪个款式好看,你能帮我推荐一下吗?"
print(choice_chain(question))

结果:

{'question': '我想买一件衣服,但是不知道哪个款式好看,你能帮我推荐一下吗?', 'answer': 'A. 一个能够查询商品信息,为用户进行商品导购的工具'}

执行第二个问题:

question = "我有一张订单,订单号是 2022ABCDE,一直没有收到,能麻烦帮我查一下吗?"
print(choice_chain(question)) 

结果:

{'question': '我有一张订单,订单号是 2022ABCDE,一直没有收到,能麻烦帮我查一下吗?', 'answer': 'B. 一个能够查询订单信息,获得最新的订单情况的工具'}

执行第三个问题试试:

question = "请问你们的货,能送到三亚吗?大概需要几天?"
print(choice_chain(question))

结果:

{'question': '请问你们的货,能送到三亚吗?大概需要几天?', 'answer': 'C. 一个能够搜索商家的退换货政策、运费、物流时长、支付渠道、覆盖国家的工具。'}

再问他都不符合的问题,

question = "今天天气怎么样?"
print(choice_chain(question))

结果:

{'question': '今天天气怎么样?', 'answer': 'D. 都不合适'}

通过上面给我们回馈的答案,这样我们就能够知道我们要调用哪个LLMChain进行哪些处理了,哈哈,很棒啊!那么以上我们模拟了挑选功能,那么我们怎么用LangChian既可以挑选还可以直接处理行为。

1.LangChian的Agent

Agent在这里既有中介也有特工的意思,它能根据你提供的要求既能选择出工具并还有执行能力,

代码如下:

我们定义了三个函数

1、search_order()第一个函数是关于订单搜索,最后模拟时返回订单信息

2、recommend_product()定义了关于推荐产品的函数

3、faq()定义了电商问答的函数

然后我们最重要的就是tools数组,数组里放入tool函数,参数为name,func是函数,不同的功能调用不同的函数,description这个主要是类似于Prompt,根据用户输入的是否符合描述来调用不同的函数。

创建initialize_agent()并把tools传入进来以及llm的AI模型,agent参数传递的zero-shot-react-description采用零样本分类,不给案例自己推理。

from langchain.agents import initialize_agent, Tool
from langchain.llms import OpenAI

llm=OpenAI(temperature=0)

# 模拟问关于订单
def search_order(input:str) ->str:
  return "订单状态:已发货;发货日期:2023-09-15;预计送达时间:2023-09-18"

# 模拟问关于推荐产品
def recommend_product(input:str)->str:
  return "红色连衣裙"

# 模拟问电商faq
def faq(input:str)->str:
  return "7天无理由退货"

# 创建了一个 Tool 对象的数组,把这三个函数分别封装在了三个 Tool 对象里面
# 并且定义了描述,这个 description 就是告诉 AI,这个 Tool 是干什么用的,会根据描述做出选择
tools=[
    Tool(
        name="Search Order",func=search_order,
        description="useful for when you need to answer questions about customers orders"
    ),
    Tool(
        name="Recommend Product",func=recommend_product,
        description="useful for when you need to answer questions about product recommendations"
    ),
    Tool(
        name="FAQ",func=faq,
        description="useful for when you need to answer questions about shopping policies, like return policy, shipping policy, etc."
    ),
]
# 指定使用tools,llm,agent则是zero-shot"零样本分类",不给案例自己推理
# 而 react description,指的是根据你对于 Tool 的描述(description)进行推理(Reasoning)并采取行动(Action)
agent=initialize_agent(tools,llm,agent="zero-shot-react-description", verbose=True)

咱们询问一下:

question = "我想买一件衣服,但是不知道哪个款式好看,你能帮我推荐一下吗?"
result=agent.run(question)
print(result)

结果:

> Entering new AgentExecutor chain...

WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I need to recommend a product.
Action: Recommend Product
Action Input: Clothing
Observation: 红色连衣裙
Thought:
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I now know the final answer.
Final Answer: 我推荐红色连衣裙。

> Finished chain.
我推荐红色连衣裙。

首先讲讲它打印的日志:

Action:就是根据用户的输入,选用哪个Tool,然后行动

Action Input:根据需要使用的Tool,从用户的输入里提取相关的内容,可以输入到Tool里面

Observation:就是观察通过使用 Tool 得到的一个输出结果。

Thought:就是再看一眼用户的输入,判断一下该怎么做。

Final Answer:就是 Thought 在看到 Obersavation 之后,给出的最终输出。

第二个问题:

question = "我有一张订单,订单号是 2022ABCDE,一直没有收到,能麻烦帮我查一下吗?"
result = agent.run(question)
print(result)
> Entering new AgentExecutor chain...
 I need to find out the status of the order
Action: Search Order
Action Input: 2022ABCDE
Observation: 订单状态:已发货;发货日期:2023-09-15;预计送达时间:2023-09-18
Thought: I now know the final answer
Final Answer: 您的订单 2022ABCDE 已于2023-09-15发货,预计将于2023-09-18送达。
> Finished chain.
您的订单 2022ABCDE 已于2023-09-15发货,预计将于2023-09-18送达。

第三个问题:

question = "请问你们的货,能送到三亚吗?大概需要几天?"
result = agent.run(question)
print(result)

结果:

> Entering new AgentExecutor chain...
 I need to find out the shipping policy and delivery time
Action: FAQ
Action Input: Shipping policy and delivery time
Observation: 7天无理由退货
Thought:
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I need to find out the delivery time
Action: FAQ
Action Input: Delivery time
Observation: 7天无理由退货
Thought:
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I need to find out if we can deliver to Sanya
Action: FAQ
Action Input: Delivery to Sanya
Observation: 7天无理由退货
Thought:
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I now know the final answer
Final Answer: 我们可以把货送到三亚,大概需要7天。

> Finished chain.
我们可以把货送到三亚,大概需要7天。

在最后的案例里我们看到它在反复的重试,因为发现没有合适的,最后只能给出这样的答案,而对于这种没有确切的答案,还要反复思考重试,而且也不一定准,如果希望不要反复重试,可以设定重试的限制。

2.使用max_iterations限制重试次数

我们可以把上面的案例设置为2,看看代码

agent=initialize_agent(tools,llm,agent="zero-shot-react-description",max_iterations=2,verbose=True)
question = "请问你们的货,能送到三亚吗?大概需要几天?"
result = agent.run(question)
print(result)

结果:

> Entering new AgentExecutor chain...
 I need to find out the shipping policy
Action: FAQ
Action Input: Shipping policy
Observation: 7天无理由退货
Thought: I need to find out the shipping time
Action: FAQ
Action Input: Shipping time
Observation: 7天无理由退货
Thought:

> Finished chain.
Agent stopped due to iteration limit or time limit.

这次就试了两次吗,就不再继续了,回答的也是说被限制了,这样就可以人工介入给精准的答案。

3.通过 VectorDBQA 让 Tool 支持问答

当然对于上面那种回答不了的问题,我们也可以采用之前说过的方法,我们调用faq对话,将VectorDBQA 这个 LLMChain,把它也封装成一个 Tool

也就是说我们将FAQ对话文件读取,读取完按一小块存储,并最后存储成向量,我们根据这个处理完的数据查询

#!pip install spacy;
#!python -m spacy download zh_core_web_sm
!pip install tiktoken
#!pip install faiss-cpu
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.vectorstores import FAISS
from langchain.text_splitter import SpacyTextSplitter
from langchain import OpenAI, VectorDBQA
from langchain.document_loaders import TextLoader

llm = OpenAI(temperature=0)
loader = TextLoader('./data/ecommerce_faq.txt')
documents = loader.load()
text_splitter = SpacyTextSplitter(chunk_size=256, pipeline="zh_core_web_sm")
texts = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
docsearch = FAISS.from_documents(texts, embeddings)

faq_chain = VectorDBQA.from_chain_type(llm=llm, vectorstore=docsearch, verbose=True)

然后,把这 LLMChain 的 run 方法包装到一个 Tool 里面。也就是关于faq直接就在方法里调用faq_chain.run去调用我们文件的数据了。

from langchain.agents import tool

# Python 的 decorator 功能,相当于用了tool的函数功能
@tool("FAQ")
def faq(input:str) -> str:
  """"useful for when you need to answer questions about shopping policies, like return policy, shipping policy, etc."""
  return faq_chain.run(input)

tools=[
    Tool(
        name="Search Order",func=search_order,
        description="useful for when you need to answer questions about customers orders"
    ),
    Tool(
        name="Recommend Product",func=recommend_product,
        description="useful for when you need to answer questions about product recommendations"
    ),
    faq
]
agent=initialize_agent(tools,llm,agent="zero-shot-react-description",verbose=True)

关于这样的对话,我们就调用faq里进行回答,

question = "请问你们的货,能送到三亚吗?大概需要几天?"
result = agent.run(question)
print(result)

结果:

> Entering new AgentExecutor chain...
 I need to find out the shipping policy and delivery time.
Action: FAQ
Action Input: shipping policy and delivery time

> Entering new VectorDBQA chain...

> Finished chain.

Observation:  我们支持全国大部分省份的配送,一般情况下,大部分城市的订单在2-3个工作日内送达,偏远地区可能需要5-7个工作日。具体送货时间可能因订单商品、配送地址和物流公司而异。
Thought: I now know the final answer
Final Answer: 我们支持全国大部分省份的配送,一般情况下,大部分城市的订单在2-3个工作日内送达,偏远地区可能需要5-7个工作日。具体送货时间可能因订单商品、配送地址和物流公司而异。

> Finished chain.
我们支持全国大部分省份的配送,一般情况下,大部分城市的订单在2-3个工作日内送达,偏远地区可能需要5-7个工作日。具体送货时间可能因订单商品、配送地址和物流公司而异。

对于商品的推荐,我们也可以使用类似方式,也把对应的商品信息,存到 VectorStore 里,然后通过先搜索后问答的方式来解决。

关于商品csv文件资源链接:

https://download.csdn.net/download/dfBeautifulLive/88393780?spm=1001.2014.3001.5503

from langchain.text_splitter import CharacterTextSplitter
from langchain.document_loaders import CSVLoader

product_loader = CSVLoader('./data/ecommerce_products.csv')
product_documents = product_loader.load()
product_text_splitter = CharacterTextSplitter(chunk_size=1024, separator="\n")
product_texts = product_text_splitter.split_documents(product_documents)
product_search = FAISS.from_documents(product_texts, OpenAIEmbeddings())
product_chain = VectorDBQA.from_chain_type(llm=llm, vectorstore=product_search, verbose=True)

@tool("FAQ")
def faq(intput: str) -> str:
    """"useful for when you need to answer questions about shopping policies, like return policy, shipping policy, etc."""
    return faq_chain.run(intput)

@tool("Recommend Product")
def recommend_product(input:str) ->str:
  """"useful for when you need to search and recommend products and recommend it to the user"""
  return product_chain.run(input)

tools=[
    recommend_product,
    faq
]
agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

问答:

question = "我想买一件衣服,想要在春天去公园穿,但是不知道哪个款式好看,你能帮我推荐一下吗?"
answer = agent.run(question)
print(answer)

结果:

> Entering new AgentExecutor chain...
 I need to find a product that is suitable for the user.
Action: Recommend Product
Action Input: Clothes for park in spring

> Entering new VectorDBQA chain...

> Finished chain.

Observation:  长款风衣、卫衣连衣裙、长款卫衣。
Thought: I now know the final answer
Final Answer: 我建议你可以考虑长款风衣、卫衣连衣裙、长款卫衣,这些款式都很适合在春天去公园穿。

> Finished chain.
我建议你可以考虑长款风衣、卫衣连衣裙、长款卫衣,这些款式都很适合在春天去公园穿。

4.优化 Prompt,让 AI 不要胡思乱想

关于订单号的搜索,我们用向量库不合适,可以用数据库查询就可以,我们模拟一下不同的订单号匹配,然后匹配到返回什么,匹配不到返回什么,业务如下:

import json
import re

ORDER_1="20230101ABC"
ORDER_2="20230101EFG"

ORDER_1_DETAIL={
    "order_number":ORDER_1,
    "status":"已发货",
    "shipping_date": "2023-01-03",    
    "estimated_delivered_date": "2023-01-05",
}

ORDER_2_DETAIL={
    "order_number":ORDER_2,
    "status":"未发货",
    "shipping_date": None,    
    "estimated_delivered_date": None,
}

@tool("SearchOrder")
def search_order(input:str)->str:
  """useful for when you need to answer questions about customers orders"""
  if input.strip()==ORDER_1:
    return json.dumps(ORDER_1_DETAIL)
  elif input.strip()==ORDER_2:
    return json.dumps(ORDER_2_DETAIL)
  else:
    return f"对不起,根据{input}没有找到您的订单"
tools=[search_order,recommend_product,faq]
agent=initialize_agent(tools,llm=OpenAI(temperature=0),agent="zero-shot-react-description", verbose=True)

在这里我们匹配到的就直接返回了和我们期望一致的数据,那如果我们查询一下上面没有的订单号,也就是匹配不上,会出现什么?

question = "我有一张订单,订单号是 2022ABCDE,一直没有收到,能麻烦帮我查一下吗?"
answer = agent.run(question)
print(answer)

结果:

> Entering new AgentExecutor chain...
 I need to find out the status of the order
Action: SearchOrder
Action Input: 2022ABCDE
Observation: 对不起,根据2022ABCDE没有找到您的订单
Thought: I need to find out more information about the order
Action: SearchOrder
Action Input: 2022ABCDE
Observation: 对不起,根据2022ABCDE没有找到您的订单
Thought: I need to provide more information about the order
Action: FAQ
Action Input: 订单查询

> Entering new VectorDBQA chain...

WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

> Finished chain.

Observation:  登录您的帐户,点击“我的订单”,在此页面上,您可以查看所有订单及其当前状态。
Thought:
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 4.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..
WARNING:langchain.llms.base:Retrying langchain.llms.openai.completion_with_retry.<locals>._completion_with_retry in 8.0 seconds as it raised RateLimitError: Rate limit reached for default-text-davinci-003 in organization org-WdebHKFlmMZipWcgP2HMj6CQ on requests per min. Limit: 3 / min. Please try again in 20s. Contact us through our help center at help.openai.com if you continue to have issues. Please add a payment method to your account to increase your rate limit. Visit https://platform.openai.com/account/billing to add a payment method..

 I now know the final answer
Final Answer: 登录您的帐户,点击“我的订单”,在此页面上,您可以查看所有订单及其当前状态。

> Finished chain.
登录您的帐户,点击“我的订单”,在此页面上,您可以查看所有订单及其当前状态。

最终返回的结果不是我们要的结果,想要让它返回对不起,根据2022ABCDE没有找到您的订单,但他最后却重复调用 OpenAI 的思考策略,并最终尝试从 FAQ 里拿一个查询订单的问题来敷衍用户。

解决的方案就是更改下提示语,通过这个提示语,Agent 会知道,这个工具就应该在找不到订单的时候,告诉用户找不到订单或者请它再次确认。

@tool("SearchOrder")
def search_order(input:str)->str:
  """一个帮助用户查询最新订单状态的工具,并且能处理以下情况:    
  1. 在用户没有输入订单号的时候,会询问用户订单号    
  2. 在用户输入的订单号查询不到的时候,会让用户二次确认订单号是否正确"""
  
  # 匹配多个数字以及大写字母
  pattern=r"\d+[A-Z]+"
  match=re.search(pattern,input)
  order_number=input
  if match:
    # 得到整个订单字符串
    order_number=match.group(0)
  else:
    return "请问您的订单号是多少?"

  if order_number==ORDER_1:
    return json.dumps(ORDER_1_DETAIL)
  elif order_number==ORDER_2:
    return json.dumps(ORDER_2_DETAIL)
  else:
    return f"对不起,根据{input}没有找到您的订单"
tools=[search_order,recommend_product,faq]
agent=initialize_agent(tools,llm=OpenAI(temperature=0),agent="zero-shot-react-description", verbose=True)

question = "我有一张订单,订单号是 2022ABCDE,一直没有收到,能麻烦帮我查一下吗?"
answer = agent.run(question)
print(answer)

结果:

> Entering new AgentExecutor chain...
 我需要查询订单状态
Action: SearchOrder
Action Input: 2022ABCDE
Observation: 对不起,根据2022ABCDE没有找到您的订单
Thought: 我需要再次确认订单号是否正确
Action: SearchOrder
Action Input: 2022ABCDE
Observation: 对不起,根据2022ABCDE没有找到您的订单
Thought: 我现在知道最终答案
Final Answer: 对不起,根据您提供的订单号2022ABCDE没有找到您的订单,请确认订单号是否正确。

> Finished chain.
对不起,根据您提供的订单号2022ABCDE没有找到您的订单,请确认订单号是否正确。

5.订单查询多伦对话

我们再继续优化:

我们应该支持多轮聊天。因为用户不一定是在第一轮提问的时候,就给出了自己的订单号。

我们其实可以直接让 Search Order 这个 Tool,回答用户的问题,没有必要再让 Agent 思考一遍,使用return_direct这个参数就不回在经过Thought,直接把回答传给用户。

from langchain.memory import ConversationBufferMemory
from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain

answer_order_info=PromptTemplate(
    template="请把下面的订单信息回复给用户: \n\n {order}?", 
    input_variables=["order"]
)
answer_order_llm=LLMChain(llm=ChatOpenAI(temperature=0), prompt=answer_order_info)

# return_direct这个参数是不要再经过Thought,直接把回答传给用户
@tool("SearchOrder",return_direct=True)
def search_order(input:str)->str:
  """useful for when you need to answer questions about customers orders"""
  pattern=r"\d+[A-Z]+"
  match=re.search(pattern,input)
  order_number=input
  if match:
    # 取出整个订单字符集
    order_number=match.group(0)
  else:
    return "请问您的订单号是多少?"

  if order_number==ORDER_1:
    # 通过 answer_order_llm 这个工具来组织语言文字,将python对象编码成Json字符串
    return answer_order_llm.run(json.dumps(ORDER_1_DETAIL)) 
  elif order_number==ORDER_2:
    return answer_order_llm.run(json.dumps(ORDER_2_DETAIL))
  else:
    return f"对不起,根据{input}没有找到您的订单"

tools=[search_order,recommend_product,faq]
# 更换为ChatOpenAI成本更低
chatllm=ChatOpenAI(temperature=0)
# 保留对话记录到内存
memory=ConversationBufferMemory(memory_key="chat_history",return_message=True)
# 更改agent为conversational-react-description支持多语言对话
conversation_agent=initialize_agent(tools,chatllm,
                                    agent="conversational-react-description",
                                    memory=memory, 
                                    verbose=True)

问题一:

question1 = "我有一张订单,一直没有收到,能麻烦帮我查一下吗?"
answer1 = conversation_agent.run(question1)
print(answer1)

结果:

> Entering new AgentExecutor chain...
Thought: Do I need to use a tool? Yes
Action: SearchOrder
Action Input: 我有一张订单,一直没有收到
Observation: 请问您的订单号是多少?

> Finished chain.
请问您的订单号是多少?

问题二:

question2 = "我的订单号是20230101ABC"
answer2 = conversation_agent.run(question2)
print(answer2)

结果:

> Entering new AgentExecutor chain...
Thought: Do I need to use a tool? Yes
Action: SearchOrder
Action Input: 20230101ABC
Observation: 尊敬的用户,以下是您的订单信息:

订单编号:20230101ABC
订单状态:已发货
发货日期:2023年1月3日
预计送达日期:2023年1月5日

如有任何问题,请随时与我们联系。感谢您的支持!

> Finished chain.
尊敬的用户,以下是您的订单信息:

订单编号:20230101ABC
订单状态:已发货
发货日期:2023年1月3日
预计送达日期:2023年1月5日

如有任何问题,请随时与我们联系。感谢您的支持!

本篇文章视频:

让AI做决策,学会langChain的Agent_哔哩哔哩_bilibili

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值