激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢電話:400-810-1418 服務(wù)與監(jiān)督電話:400-810-1418轉(zhuǎn)接2

利用LangChain讓AI做決策

發(fā)布時(shí)間:2024-03-15 09:07:23 瀏覽量:105次

Hi,大家好。

在第 11 講中,我向您介紹了如何將各種資料內(nèi)容向量化,借助Llama-index建立索引,對我們自己的文本資料進(jìn)行問答。在過去的3講中,我們深入了解了如何使用Langchain。該工具可幫助我們整合AI對語言的理解和組織能力、外部各種資料或者SaaS的API,以及您自己編寫的代碼。通過整合這些功能,我們可以使用自然語言完成更復(fù)雜的任務(wù),而不僅僅是閑聊。我們深入了解了如何使用Langchain。該工具可幫助我們整合AI對語言的理解和組織能力、外部各種資料或者SaaS的API,以及您自己編寫的代碼。通過整合這些功能,我們可以使用自然語言完成更復(fù)雜的任務(wù),而不僅僅是閑聊。

<!-- more -->

但到目前為止,我們所有基于ChatGPT的應(yīng)用基本上都是“單項(xiàng)技能”,例如前面關(guān)于“藤野先生”的問題或上一講中查詢最新天氣或通過Python進(jìn)行算術(shù)運(yùn)算。這本質(zhì)上是限制AI只針對我們預(yù)先索引或?qū)崟r(shí)搜索的數(shù)據(jù)進(jìn)行回答。


給AI加上多項(xiàng)選擇能力

要做一個(gè)能跑在生產(chǎn)環(huán)境上的 AI 聊天機(jī)器人,需要的不止一個(gè)技能。在電商領(lǐng)域,最起碼需要以下三個(gè)技能:

  1. “導(dǎo)購咨詢”:查詢商品信息為用戶做導(dǎo)購和推薦。
  2. “售中咨詢”:查詢訂單的物流軌跡,對買了東西還沒有收到貨的用戶給出安撫和回復(fù)。
  3. “FAQ”:索引電商網(wǎng)站的 FAQ,回復(fù)用戶有關(guān)退貨政策、運(yùn)費(fèi)、支付方式等問題的答案。

AI 需要自己判斷什么時(shí)候該用什么樣的技能,而不是需要人工介入或?qū)懸欢?if…else 的代碼。

采用 “分而治之” 的思路,對于每一個(gè)單項(xiàng)技能,可以把它們變成一個(gè) LLMChain。對于用戶問的問題,可以讓 AI 選擇使用哪一個(gè) LLMChain 來回答問題。

下面是一段代碼,通過提示語讓 AI 做一個(gè)選擇題。

 
 import openai, os
 
 openai.api_key = os.environ.get("OPENAI_API_KEY")
 
 from langchain.prompts import PromptTemplate
 from langchain.llms import OpenAIChat
 from langchain.chains import LLMChain
 
 llm = OpenAIChat(max_tokens=2048, temperature=0.5)
 multiple_choice = """
 請針對 >>> 和 <<< 中間的用戶問題,選擇一個(gè)合適的工具去回答她的問題。只要用A、B、C的選項(xiàng)字母告訴我答案。
 如果你覺得都不合適,就選D。
 
 >>>{question}<<<
 
 我們有的工具包括:
 A. 一個(gè)能夠查詢商品信息,為用戶進(jìn)行商品導(dǎo)購的工具
 B. 一個(gè)能夠查詢訂單信息,獲得最新的訂單情況的工具
 C. 一個(gè)能夠搜索商家的退換貨政策、運(yùn)費(fèi)、物流時(shí)長、支付渠道、覆蓋國家的工具
 D. 都不合適
 """
 multiple_choice_prompt = PromptTemplate(template=multiple_choice, input_variables=["question"])
 choice_chain = LLMChain(llm=llm, prompt=multiple_choice_prompt, output_key="answer")
 

對應(yīng)的,我們可以試試問不同的問題,看看它能不能選擇一個(gè)正確的工具。

問題 1:

 question = "我想買一個(gè)iPhone,但是不知道哪個(gè)款式好,你能幫我推薦一下嗎?"
 print(choice_chain(question))

輸出結(jié)果:

 {'question': '我想買一個(gè)iPhone,但是不知道哪個(gè)款式好,你能幫我推薦一下嗎?', 'answer': 'A. 一個(gè)能夠查詢商品信息,為用戶進(jìn)行商品導(dǎo)購的工具'}
 

問題 2:

 question = "我有一張訂單,訂單號是 2023Y06M11D,一直沒有收到,能麻煩幫我查一下嗎?"
 print(choice_chain(question))

輸出結(jié)果:

 {'question': '我有一張訂單,訂單號是 2023Y06M11D,一直沒有收到,能麻煩幫我查一下嗎?', 'answer': 'B. 一個(gè)能夠查詢訂單信息,獲得最新的訂單情況的工具'}

問題 3:

 question = "請問你們的貨,能送到格爾木嗎?大概需要幾天?"
 print(choice_chain(question))
 

輸出結(jié)果:

 {'question': '請問你們的貨,能送到格爾木嗎?大概需要幾天?', 'answer': 'C. 一個(gè)能夠搜索商家的退換貨政策、運(yùn)費(fèi)、物流時(shí)長、支付渠道、覆蓋國家的工具。'}
 

問題 4:

 question = "今天會不會下雨???"
 print(choice_chain(question))

輸出結(jié)果:

 {'question': '今天會不會下雨???', 'answer': 'D. 都不合適。這個(gè)問題需要使用天氣預(yù)報(bào)工具來回答。'}

我們試驗(yàn)了四個(gè)問題,ChatGPT都給出了準(zhǔn)確答案。得到答案后,您可以使用TransformChain直接匹配返回結(jié)果的前綴,以確定后續(xù)調(diào)用哪個(gè)LLMChain。

Langchain中 的Agent

在真實(shí)的業(yè)務(wù)場景中,你一定會遇到“分治法”的思路。無論是哪行哪業(yè)的客服聊天機(jī)器人,都會有能夠直接通過資料庫回答的用戶問題,也會有和用戶自己或公司產(chǎn)品相關(guān)的信息,需要通過檢索的方式提供。因此,Langchain將這種“先做一個(gè)選擇題”的思路推廣,并建立了Agent這個(gè)抽象概念。

Agent有兩個(gè)中文翻譯,一個(gè)是代理人,比如在美國買房或租房,都要通過“房產(chǎn)代理”,也就是Real Estate Agent。另一個(gè)意思是“特工”,指的是Agent具有自主行動能力,能夠直接使用提供的工具采取行動。它不僅僅是做完選擇題就完事了,而是直接拿起選中的工具并進(jìn)行下一步的行動。Langchain的Agent實(shí)際上包含這兩個(gè)意思,可以說名字取得非常得當(dāng)。

接下來我們看看如何通過Langchain提供的Agent直接采取行動來解決上面的例子。

 from langchain.agents import initialize_agent, Tool
 from langchain.llms import OpenAI
 
 llm = OpenAI(temperature=0)
 
 def search_order(input: str) -> str:
     return "訂單狀態(tài):已發(fā)貨;發(fā)貨日期:2023-01-01;預(yù)計(jì)送達(dá)時(shí)間:2023-01-10"
 
 def recommend_product(input: str) -> str:
     return "iPhone 15 Pro"
 
 def faq(intput: str) -> str:
     return "7天無理由退貨"
 
 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."
    )
 ]
 
 agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

這段代碼分為三個(gè)部分:

  1. 定義三個(gè)函數(shù): search_order、 recommend_productfaq,它們的輸入都是字符串,輸出是我們編寫的回答。
  2. 創(chuàng)建Tool對象數(shù)組,它包含三個(gè)Tool對象,每個(gè)Tool對象都封裝了一個(gè)函數(shù),并定義了一個(gè)名稱和描述。這個(gè)描述告訴AI這個(gè)Tool的作用,AI會根據(jù)問題和描述來選擇Tool。
  3. 創(chuàng)建一個(gè)agent對象,指定使用哪些Tool、LLM對象和agent類型。在這里,我們選擇了 zero-shot-react-description類型,這意味著AI將根據(jù)自己的推理能力進(jìn)行決策,并采取行動。React是指根據(jù)Tool的描述進(jìn)行推理和行動。

React并不是來自Facebook的前端框架的名字,而是來自一篇Google Brain的論文。有興趣的話,可以去閱讀一下,了解具體的原理和思路。

有了這個(gè)agent之后,我們可以嘗試重新問一遍之前的三個(gè)問題。

問題 1:

 question = "我想買一個(gè)iPhone,但是不知道哪個(gè)款式好,你能幫我推薦一下嗎?"
 result = agent.run(question)
 print(result)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to recommend a product.
 Action: Recommend Product
 Action Input: iPhone
 Observation: iPhone 15 Pro
 Thought: I now know the final answer.
 Final Answer: 我推薦iPhone 15 Pro。
 
 > Finished chain.
 我推薦iPhone 15 Pro。

問題 2:

 question = "我有一張訂單,訂單號是 2023Y06M11D,一直沒有收到,能麻煩幫我查一下嗎?"
 result = agent.run(question)
 print(result)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to find out the status of this order.
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 訂單狀態(tài):已發(fā)貨;發(fā)貨日期:2023-01-01;預(yù)計(jì)送達(dá)時(shí)間:2023-01-10
 Thought: I now know the status of the order.
 Final Answer: 您的訂單號為2023Y06M11D,已于2023-01-01發(fā)貨,預(yù)計(jì)于2023-01-10送達(dá)。
 
 > Finished chain.
 您的訂單號為2023Y06M11D,已于2023-01-01發(fā)貨,預(yù)計(jì)于2023-01-10送達(dá)。

問題 3:

 question = "請問你們的貨,能送到格爾木嗎?大概需要幾天?"
 result = agent.run(question)
 print(result)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to know the shipping policy
 Action: FAQ
 Action Input: Shipping policy
 Observation: 7天無理由退貨
 Thought: I need to know the shipping time
 Action: FAQ
 Action Input: Shipping time
 Observation: 7天無理由退貨
 Thought: I now know the final answer
 Final Answer: 我們的貨物可以送到格爾木,大概需要7天。
 
 > Finished chain.
 我們的貨物可以送到格爾木,大概需要7天。

因?yàn)樵诖a里,我們開啟了 Agent 的 Verbose 模式,所以在輸出結(jié)果中,你可以看到 Agent 思考的整個(gè)日志。你會發(fā)現(xiàn)一些有意思的現(xiàn)象。

首先,Agent 的每一步操作都可以分為 5 個(gè)步驟:Action、Action InputObservation、ThoughtFinal Answer

  1. Action 指根據(jù)用戶的輸入選擇應(yīng)該采取哪一個(gè) Tool 并執(zhí)行相應(yīng)的操作。
  2. Action Input是指從用戶的輸入中提取相關(guān)內(nèi)容,以便輸入到 Tool 中。
  3. Observation 是指觀察使用 Tool 后得到的輸出結(jié)果。
  4. Thought 是指再次查看用戶的輸入,以判斷下一步應(yīng)該采取什么操作。
  5. Final Answer 是指在觀察 Observation 后,根據(jù) Thought 得出的最終輸出。

其次,對于“貨需要幾天送到格爾木”的問題,我們沒有按照上述 5 個(gè)步驟回答,而是在 Thought 步驟之后重新回到了 Action 步驟。經(jīng)過三次類似的操作后,我們不得不強(qiáng)行回答該問題。但是,我們的回答并不一定準(zhǔn)確,因?yàn)槲覀儧]有解釋是否能將貨物送到格爾木。

這整個(gè)過程是通過一段 Prompt 實(shí)現(xiàn)的,你可以在 Langchain 源碼中尋找 mrkl 對應(yīng)的 Prompt 源代碼。

 # flake8: noqa
 PREFIX = """Answer the following questions as best you can. You have access to the following tools:"""
 FORMAT_INSTRUCTIONS = """Use the following format:
   
 Question: the input question you must answer
 Thought: you should always think about what to do
 Action: the action to take, should be one of [{tool_names}]
 Action Input: the input to the action
 Observation: the result of the action
 ... (this Thought/Action/Action Input/Observation can repeat N times)
 Thought: I now know the final answer
 Final Answer: the final answer to the original input question"""
 SUFFIX = """
 Begin!  
 Question: {input}
 Thought:{agent_scratchpad}
 """

該工具將一系列工具名稱和描述交給OpenAI,根據(jù)用戶的需求選擇相應(yīng)的工具,并提取與用戶相關(guān)的信息。本質(zhì)上,這只是我們讓AI做選擇題的一種擴(kuò)展。

限制重試次數(shù)

Agent 可以通過反復(fù)思考來提高準(zhǔn)確性,但有時(shí) AI 處理可能不準(zhǔn)確 (大語言模型運(yùn)行是黑盒)。為了避免不斷重試或強(qiáng)行回答,可以在創(chuàng)建 Agent 時(shí)設(shè)置max_iterations參數(shù)來限制嘗試次數(shù)(比如 2 次)。

 agent = initialize_agent(tools, llm, agent="zero-shot-react-description", max_iterations = 2, verbose=True)
 question = "請問你們的貨,能送到格爾木嗎?大概需要幾天?"
 result = agent.run(question)
 print("===")
 print(result)
 print("===")

輸出結(jié)果:

 > 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: I need to find out the delivery time
 Action: FAQ
 Action Input: Delivery time
 Observation: 7天無理由退貨
 Thought:
 
 > Finished chain.
 ===
 Agent stopped due to iteration limit or time limit.
 ===

可以看到,這個(gè)時(shí)候,AI 重試了兩次就不再重試。并且,也沒有強(qiáng)行給出一個(gè)回答,而是告訴你,Agent 因?yàn)?max iterations的設(shè)置而中止了。這樣,你可以把 AI 回答不上來的問題,切換給人工客服回答。

讓 Tool 支持問答

這個(gè)問題很簡單,可以用 AI 回答。目前無法回答的原因是 FQA 工具回答任何問題都是“7 天無理由退貨”。正確的方法是使用第 15 講中介紹的 VectorDBQA 工具,將其封裝成一個(gè)工具即可。首先,將第 15 講的代碼搬運(yùn)過來。

 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 方法包裝到一個(gè) Tool 里面。

 from langchain.agents import tool
 
 @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)
 
 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)

我們對 Tool 寫法進(jìn)行了改進(jìn),使得代碼更易于維護(hù)。通過 Python 的 @tool 裝飾器功能,我們將 FAQ 函數(shù)直接變成 Tool 對象,從而無需每次創(chuàng)建 Tools 時(shí)都指定名稱和描述。

然后,我們可以通過 Agent 運(yùn)行剛才的問題,同樣可以得到正確的答案。

 question = "請問你們的貨,能送到格爾木嗎?大概需要幾天?"
 result = agent.run(question)
 print(result)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to know the shipping policy
 Action: FAQ
 Action Input: Shipping policy
 
 > Entering new VectorDBQA chain...
 
 > Finished chain.
 
 Observation:  我們支持全國大部分省份的配送,包括北京、上海、天津、重慶、河北、山西、遼寧、吉林、黑龍江、江蘇、浙江、安徽、福建、江西、山東、河南、湖北、湖南、廣東、海南、四川、貴州、云南、陜西、甘肅、青海、臺灣、內(nèi)蒙古、廣西、西藏、寧夏和新疆。一般情況下,大部分城市的訂單會在2-3個(gè)工作日內(nèi)送達(dá),而偏遠(yuǎn)地區(qū)的訂單可能需要5-7個(gè)工作日。
 Thought: I need to know the estimated delivery time
 Action: FAQ
 Action Input: Estimated delivery time
 
 > Entering new VectorDBQA chain...
 
 > Finished chain.
 
 Observation:  The estimated delivery time may vary depending on the order items, delivery address, andlogistics company. Generally, orders in most cities will be delivered within 2-3 working days, while orders inremote areas may take 5-7 working days.
 Thought: I now know the final answer
 Final Answer: 我們支持全國大部分省份的配送,包括格爾木,一般情況下,大部分城市的訂單會在2-3個(gè)工作日內(nèi)送達(dá),而偏遠(yuǎn)地區(qū)的訂單可能需要5-7個(gè)工作日。
 
 > Finished chain.
 我們支持全國大部分省份的配送,包括格爾木,一般情況下,大部分城市的訂單會在2-3個(gè)工作日內(nèi)送達(dá),而偏遠(yuǎn)地區(qū)的訂單可能需要5-7個(gè)工作日。

為了推薦商品,我們可以存儲商品信息到VectorStore中,通過先搜索后問答的方式解決。數(shù)據(jù)由ChatGPT提供,代碼與FAQ類似。

重新構(gòu)建 Agent:

 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 = [
     Tool(
         name = "Search Order",func=search_order, 
         description="useful for when you need to answer questions about customers orders"
    ),
     recommend_product, faq]
 
 agent = initialize_agent(tools, llm, agent="zero-shot-react-description", verbose=True)

詢問Agent問題:

 question = "我想買一件衣服,想要在春天去公園穿,但是不知道哪個(gè)款式好看,你能幫我推薦一下嗎?"
 answer = agent.run(question)
 print(answer)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to recommend a product to the user.
 Action: Recommend Product
 Action Input: Clothing for park in spring
 
 > Entering new VectorDBQA chain...
 
 > Finished chain.
 
 Observation:  長款風(fēng)衣、衛(wèi)衣連衣裙、長款衛(wèi)衣,搭配一雙白色球鞋、黑色長靴、白色運(yùn)動鞋和小包包。
 Thought: I now know the final answer.
 Final Answer: 我建議你可以選擇長款風(fēng)衣、衛(wèi)衣連衣裙、長款衛(wèi)衣,搭配一雙白色球鞋、黑色長靴、白色運(yùn)動鞋和小包包,這樣的搭配在春天去公園穿會很漂亮。
 
 > Finished chain.
 我建議你可以選擇長款風(fēng)衣、衛(wèi)衣連衣裙、長款衛(wèi)衣,搭配一雙白色球鞋、黑色長靴、白色運(yùn)動鞋和小包包,這樣的搭配在春天去公園穿會很漂亮。

優(yōu)化 Prompt, 避免AI胡亂回答

對于訂單查詢,使用向量檢索就不太合適了。我們可以直接拿訂單號去數(shù)據(jù)庫里查找。這不是一個(gè) Python 編程課,不會在這里演示如何使用 Python 編寫 SQL。我們可以在對應(yīng)的函數(shù)里造幾條數(shù)據(jù),根據(jù)用戶輸入的訂單號返回不同的訂單狀態(tài)。如果找不到訂單,就告訴用戶訂單不存在。

 import json
 
 ORDER_1 = "20230611ABC"
 ORDER_2 = "20230611EFG"
 
 ORDER_1_DETAIL = {
     "order_number": ORDER_1,
     "status": "已發(fā)貨",
     "shipping_date" : "2023-01-03",
     "estimated_delivered_date": "2023-01-05",
 } 
 
 ORDER_2_DETAIL = {
     "order_number": ORDER_2,
     "status": "未發(fā)貨",
     "shipping_date" : None,
     "estimated_delivered_date": None,
 }
 
 import re
 
 @tool("Search Order")
 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"對不起,根據(jù){input}沒有找到您的訂單"
 
 tools = [search_order,recommend_product, faq]
 agent = initialize_agent(tools, llm=OpenAI(temperature=0), agent="zero-shot-react-description", verbose=True)

然后,我們可以讓 Agent 幫我們查詢訂單號。

 question = "我有一張訂單,訂單號是 2023Y06M11D,一直沒有收到,能麻煩幫我查一下嗎?"
 answer = agent.run(question)
 print(answer)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  I need to find out the status of the order
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 對不起,根據(jù)2023Y06M11D沒有找到您的訂單
 Thought: I need to find out more information about the order
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 對不起,根據(jù)2023Y06M11D沒有找到您的訂單
 Thought: I need to contact customer service for more information
 Action: FAQ
 Action Input: 訂單查詢
 
 > Entering new VectorDBQA chain...
 
 > Finished chain.
 
 Observation:  登錄您的帳戶,點(diǎn)擊“我的訂單”,在此頁面上,您可以查看所有訂單及其當(dāng)前狀態(tài)。
 Thought: I now know the final answer
 Final Answer: 請登錄您的帳戶,點(diǎn)擊“我的訂單”,在此頁面上,您可以查看所有訂單及其當(dāng)前狀態(tài)。
 
 > Finished chain.
 請登錄您的帳戶,點(diǎn)擊“我的訂單”,在此頁面上,您可以查看所有訂單及其當(dāng)前狀態(tài)。

我們輸入了一個(gè)不存在的訂單號,結(jié)果出乎意料。我們本來期望 AI 能夠告訴我們訂單號找不到,但實(shí)際上它重復(fù)調(diào)用了 OpenAI 的思考策略,并從 FAQ 中拿了一個(gè)查詢訂單的問題來敷衍用戶。這并不是我們想要的,也是以前很多“人工智zhang”類型的智能客服常常會遇到的問題。因此,我們需要解決這個(gè)問題。

解決方法很簡單,只需要調(diào)整 search_order 這個(gè)工具的提示語。通過這個(gè)提示語,Agent 就會知道,在找不到訂單時(shí)應(yīng)該告訴用戶找不到訂單或請用戶再次確認(rèn)。這樣,它就會根據(jù)這個(gè)答案回復(fù)用戶。下面是修改運(yùn)行后的結(jié)果。

 import re
 
 @tool("Search Order")
 def search_order(input:str)->str:
     """一個(gè)幫助用戶查詢最新訂單狀態(tài)的工具,并且能處理以下情況:
    1. 在用戶沒有輸入訂單號的時(shí)候,會詢問用戶訂單號
    2. 在用戶輸入的訂單號查詢不到的時(shí)候,會讓用戶二次確認(rèn)訂單號是否正確
    """
     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"對不起,根據(jù){input}沒有找到您的訂單"
 
 tools = [search_order,recommend_product, faq]
 agent = initialize_agent(tools, llm=OpenAI(temperature=0), agent="zero-shot-react-description", verbose=True)
 
 question = "我有一張訂單,訂單號是 2023Y06M11D,一直沒有收到,能麻煩幫我查一下嗎?"
 answer = agent.run(question)
 print(answer)

輸出結(jié)果:

 > Entering new AgentExecutor chain...
  我需要查詢訂單狀態(tài)
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 對不起,根據(jù)2023Y06M11D沒有找到您的訂單
 Thought: 我需要再次確認(rèn)訂單號是否正確
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 對不起,根據(jù)2023Y06M11D沒有找到您的訂單
 Thought: 我現(xiàn)在知道最終答案
 Final Answer: 對不起,根據(jù)您提供的訂單號2023Y06M11D沒有找到您的訂單,請您再次確認(rèn)訂單號是否正確。
 
 > Finished chain.
 對不起,根據(jù)您提供的訂單號2023Y06M11D沒有找到您的訂單,請您再次確認(rèn)訂單號是否正確。

多輪對話查詢訂單

優(yōu)化客服聊天機(jī)器人的幾個(gè)方法:

  1. 支持多輪聊天,因?yàn)橛脩艨赡懿粫诘谝惠喬峁┯唵翁枴?/span>
  2. 直接使用訂單查詢工具回答用戶問題,無需讓客服再次思考。

改進(jìn)代碼即可。

 import re
 from langchain.memory import ConversationBufferMemory
 from langchain.chat_models import ChatOpenAI
 
 answer_order_info = PromptTemplate(
     template="請把下面的訂單信息回復(fù)給用戶: \n\n {order}?", input_variables=["order"]
 )
 answer_order_llm = LLMChain(llm = ChatOpenAI(temperature=0),  prompt=answer_order_info)
 
 @tool("Search Order", 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:        
         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"對不起,根據(jù){input}沒有找到您的訂單"
 
 tools = [search_order,recommend_product, faq]
 chatllm=ChatOpenAI(temperature=0)
 memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
 conversation_agent = initialize_agent(tools, chatllm, 
                                       agent="conversational-react-description", 
                                       memory=memory, verbose=True)
 

我們對 Search Order 工具進(jìn)行了改進(jìn)。我們設(shè)置了一個(gè)名為 return_direct=True 的參數(shù),告訴 AI 在獲取回復(fù)后不要再思考,直接向用戶返回答案。這樣,當(dāng) AI 無法獲得訂單號時(shí),它不會反復(fù)嘗試使用 Search Order 工具,而是直接向用戶詢問訂單號。

為了實(shí)現(xiàn)這個(gè)改進(jìn),我們還需要使用 answer_order_llm工具來組織語言文字,而不是直接返回 JSON 字符串。

第二個(gè)改進(jìn)是我們使用的 Agent,我們將其更換為
conversational-react-description
,這樣我們就支持多輪對話了,并且我們還將對應(yīng)的 LLM 更改為 ChatOpenAI,這樣成本更低。此外,我們還為這個(gè) Agent 設(shè)置了記憶。

經(jīng)過這些改進(jìn)后,我們發(fā)現(xiàn) AI 現(xiàn)在變得更加智能了。

問題 1:

 question1 = "我有一張訂單,一直沒有收到,能麻煩幫我查一下嗎?"
 answer1 = conversation_agent.run(question1)
 print(answer1)

回答:

 > Entering new AgentExecutor chain...
 Thought: Do I need to use a tool? Yes
 Action: Search Order
 Action Input: 我有一張訂單,一直沒有收到,能麻煩幫我查一下嗎?
 Observation: 請問您的訂單號是多少?
 
 > Finished chain.
 請問您的訂單號是多少?

問題2:

 question2 = "我的訂單號是2023Y06M11D"
 answer2 = conversation_agent.run(question2)
 print(answer2)

回答2:

 > Entering new AgentExecutor chain...
 Thought: Do I need to use a tool? Yes
 Action: Search Order
 Action Input: 2023Y06M11D
 Observation: 對不起,根據(jù)2023Y06M11D沒有找到您的訂單
 
 > Finished chain.
 對不起,根據(jù)2023Y06M11D沒有找到您的訂單

問題3:

 question2 = "我還有一個(gè)訂單號是20230611ABC"
 answer2 = conversation_agent.run(question2)
 print(answer2)

回答3:

 > Entering new AgentExecutor chain...
 Retrying langchain.chat_models.openai.ChatOpenAI.completion_with_retry.<locals>._completion_with_retry in 1.0 seconds as it raised RateLimitError: That model is currentlyoverloaded with other requests. You can retry your request, or contact us through our help center athelp.openai.com if the error persists. (Please include the request ID7ea75372be3b894ead8b8af989c471ca in your message.).
 Thought: Do I need to use a tool? Yes
 Action: Search Order
 Action Input: 20230611ABC
 Observation: 尊敬的用戶,您的訂單信息如下:
 
 訂單號:20230611ABC
 訂單狀態(tài):已發(fā)貨
 發(fā)貨日期:2023年1月3日
 預(yù)計(jì)送達(dá)日期:2023年1月5日
 
 如有任何問題,請隨時(shí)聯(lián)系我們。感謝您的購買!
 
 > Finished chain.
 尊敬的用戶,您的訂單信息如下:
 
 訂單號:20230611ABC
 訂單狀態(tài):已發(fā)貨
 發(fā)貨日期:2023年1月3日
 預(yù)計(jì)送達(dá)日期:2023年1月5日
 
 如有任何問題,請隨時(shí)聯(lián)系我們。感謝您的購買!

問題4:

 question3 = "你們的退貨政策是怎么樣的?"
 answer3 = conversation_agent.run(question3)
 print(answer3)

回答4:

 > Entering new AgentExecutor chain...
 Thought: Do I need to use a tool? Yes
 Action: FAQ
 Action Input: 退貨政策
 
 > Entering new VectorDBQA chain...
 
 > Finished chain.
 
 Observation:  自收到商品之日起7天內(nèi),如產(chǎn)品未使用、包裝完好,您可以申請退貨。某些特殊商品可能不支持退貨,請?jiān)谫徺I前查看商品詳情頁面的退貨政策。
 Thought:Do I need to use a tool? No
 AI: Our return policy allows for returns within 7 days of receiving the product, as long as the product isunused and in its original packaging. Some special products may not be eligible for returns, so pleasecheck the product details page before purchasing.
 
 > Finished chain.
 Our return policy allows for returns within 7 days of receiving the product, as long as the product isunused and in its original packaging. Some special products may not be eligible for returns, so pleasecheck the product details page before purchasing.

AI 在多輪對話中理解用戶意圖并提供合適答案,但最后一個(gè)問題以英文回答。如何讓其用中文回答?這是本課程的思考題。

現(xiàn)在你已擁有基本功能的電商客服聊天機(jī)器人,只需在原代碼上做些改動并導(dǎo)入自己的數(shù)據(jù)源,便可用真實(shí)用戶問題進(jìn)行測試。

小結(jié)

今天我向你介紹了 Langchain 的 Agent 的基本功能。通過“先讓 AI 做個(gè)選擇題”的方式,AI 自動為我們選擇合適的工具進(jìn)行調(diào)用。我們可以將不同類型問題的 LLMChain 封裝成不同的工具,也可以直接讓工具調(diào)用內(nèi)部查詢訂單狀態(tài)的功能。我還為你演示了如何將 Agent、Memory、VectorStore 和 LLMChain 組合在一起,創(chuàng)建一個(gè)完整的電商聊天機(jī)器人。

Langchain 是目前大語言模型領(lǐng)域中最熱門的開源項(xiàng)目之一,具有豐富的功能。我介紹的是核心功能,還有其他豐富的工具、不同類型的 VectorStore 和內(nèi)置的其他 LLMChain,都可以在文檔中找到。

思考題

在本講末尾,我們的示例中,AI 用英語回答了中文 FAQ。請嘗試修改現(xiàn)有代碼,使 AI 使用中文回答。

上一講介紹了 EntityMemory,但本講中未使用它獲取和查詢訂單信息。請查閱 Langchain 文檔,思考如何使用 EntityMemory。

熱門課程推薦

熱門資訊

請綁定手機(jī)號

x

同學(xué)您好!

您已成功報(bào)名0元試學(xué)活動,老師會在第一時(shí)間與您取得聯(lián)系,請保持電話暢通!
確定