今天内容涉及如下:

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=""" 请针对 >>> 和 >{question} 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.._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.._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.._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.._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.._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.._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.._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.._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