今天内容涉及如下:
1.initialize_agent,:执行gent工作,并把工具Tool传入
2.Tool:选取行为函数工具类
之前我们学习的都是把问题给AI,让AI模型给出答案,那么这种情况下应该怎么处理呢,我需要根据不同的问题选择不同的答案,比如我问AI我想选择一件衣服就去调用挑选衣服的方法,如果是查询订单,那么就专门去调用搜索订单的方法,如果是查询物流就专门去调用物流方面的方法,但是怎么识别出来哪个调用哪个呢?
我们下面代码先模拟出怎么让AI根据我们的话语做选择,
#! pip install openai! pip install langchainimport openai,osfrom langchain.prompts import PromptTemplatefrom langchain.llms import OpenAIChatfrom langchain.chains import LLMChainos.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, Toolfrom langchain.llms import OpenAIllm=OpenAI(temperature=0)# 模拟问关于订单def search_order(input:str) ->str: return "订单状态:已发货;发货日期:2023-09-15;预计送达时间:2023-09-18"# 模拟问关于推荐产品def recommend_product(input:str)->str: return "红色连衣裙"# 模拟问电商faqdef 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 ProductAction Input: ClothingObservation: 红色连衣裙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 orderAction: Search OrderAction Input: 2022ABCDEObservation: 订单状态:已发货;发货日期:2023-09-15;预计送达时间:2023-09-18Thought: I now know the final answerFinal 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 timeAction: FAQAction Input: Shipping policy and delivery timeObservation: 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 timeAction: FAQAction Input: Delivery timeObservation: 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 SanyaAction: FAQAction Input: Delivery to SanyaObservation: 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 answerFinal 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 policyAction: FAQAction Input: Shipping policyObservation: 7天无理由退货Thought: I need to find out the shipping timeAction: FAQAction Input: Shipping timeObservation: 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-cpufrom langchain.embeddings.openai import OpenAIEmbeddingsfrom langchain.vectorstores import FAISSfrom langchain.text_splitter import SpacyTextSplitterfrom langchain import OpenAI, VectorDBQAfrom langchain.document_loaders import TextLoaderllm = 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: FAQAction Input: shipping policy and delivery time> Entering new VectorDBQA chain...> Finished chain.Observation: 我们支持全国大部分省份的配送,一般情况下,大部分城市的订单在2-3个工作日内送达,偏远地区可能需要5-7个工作日。具体送货时间可能因订单商品、配送地址和物流公司而异。Thought: I now know the final answerFinal 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 CharacterTextSplitterfrom langchain.document_loaders import CSVLoaderproduct_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 ProductAction Input: Clothes for park in spring> Entering new VectorDBQA chain...> Finished chain.Observation: 长款风衣、卫衣连衣裙、长款卫衣。Thought: I now know the final answerFinal Answer: 我建议你可以考虑长款风衣、卫衣连衣裙、长款卫衣,这些款式都很适合在春天去公园穿。> Finished chain.我建议你可以考虑长款风衣、卫衣连衣裙、长款卫衣,这些款式都很适合在春天去公园穿。
4.优化 Prompt,让 AI 不要胡思乱想
关于订单号的搜索,我们用向量库不合适,可以用数据库查询就可以,我们模拟一下不同的订单号匹配,然后匹配到返回什么,匹配不到返回什么,业务如下:
import jsonimport reORDER_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 orderAction: SearchOrderAction Input: 2022ABCDEObservation: 对不起,根据2022ABCDE没有找到您的订单Thought: I need to find out more information about the orderAction: SearchOrderAction Input: 2022ABCDEObservation: 对不起,根据2022ABCDE没有找到您的订单Thought: I need to provide more information about the orderAction: FAQAction 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 answerFinal 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: SearchOrderAction Input: 2022ABCDEObservation: 对不起,根据2022ABCDE没有找到您的订单Thought: 我需要再次确认订单号是否正确Action: SearchOrderAction Input: 2022ABCDEObservation: 对不起,根据2022ABCDE没有找到您的订单Thought: 我现在知道最终答案Final Answer: 对不起,根据您提供的订单号2022ABCDE没有找到您的订单,请确认订单号是否正确。> Finished chain.对不起,根据您提供的订单号2022ABCDE没有找到您的订单,请确认订单号是否正确。
5.订单查询多伦对话
我们再继续优化:
我们应该支持多轮聊天。因为用户不一定是在第一轮提问的时候,就给出了自己的订单号。
我们其实可以直接让 Search Order 这个 Tool,回答用户的问题,没有必要再让 Agent 思考一遍,使用return_direct这个参数就不回在经过Thought,直接把回答传给用户。
from langchain.memory import ConversationBufferMemoryfrom langchain.chat_models import ChatOpenAIfrom langchain.prompts import PromptTemplatefrom langchain.chains import LLMChainanswer_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? YesAction: SearchOrderAction 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? YesAction: SearchOrderAction Input: 20230101ABCObservation: 尊敬的用户,以下是您的订单信息:订单编号:20230101ABC订单状态:已发货发货日期:2023年1月3日预计送达日期:2023年1月5日如有任何问题,请随时与我们联系。感谢您的支持!> Finished chain.尊敬的用户,以下是您的订单信息:订单编号:20230101ABC订单状态:已发货发货日期:2023年1月3日预计送达日期:2023年1月5日如有任何问题,请随时与我们联系。感谢您的支持!
本篇文章视频:
让AI做决策,学会langChain的Agent_哔哩哔哩_bilibili