如何使用代理抹布構建智能常見問題聊天機器人
人工智能代理人現在是企業大小的一部分。從醫院的填寫表格到檢查法律文件到分析視頻錄像和處理客戶支持 - 我們擁有各種任務的AI代理。公司經常花費數十萬美元來僱用客戶支持人員,他們可以根據公司的準則了解客戶的需求並解決他們的需求。今天,擁有一個智能聊天機器人來回答常見問題解答可以有效地改善客戶服務。在本文中,我們將學習如何使用Agentic抹布(檢索增強生成),Langgraph和Chromadb來構建可以在幾秒鐘內解決客戶查詢的常見問題解答。
目錄
- 代理抹布的簡介
- 智能常見問題解答聊天機器人的架構
- 關於構建智能常見問題解答聊天機器人的動手實施
- 步驟1:安裝依賴項
- 步驟2:導入所需庫
- 步驟3:設置OpenAI API密鑰
- 步驟4:下載數據集
- 步驟5:定義映射的部門名稱
- 步驟6:定義助手功能
- 步驟7:定義Langgraph代理組件
- 步驟8:定義圖形功能
- 步驟9:發起代理執行
- 步驟10:測試代理
- 結論
代理抹布的簡介
如今,抹布是一個熱門話題。每個人都在談論抹布和構建應用程序。 RAG可以幫助LLMS訪問實時數據,這使LLM比以往任何時候都更準確。但是,傳統的抹布系統在選擇最佳檢索方法,更改檢索工作流或提供多步推理時往往會失敗。這是代理抹布進來的地方。
代理抹布通過將AI代理的能力納入其中來增強傳統抹布。借助此超級大國,抹布可以根據查詢的性質,多步推理和多步檢索來動態更改工作流程。我們甚至可以將工具集成到代理抹布系統中,並且可以動態地決定使用哪種工具。總體而言,它會提高準確性,並使系統更有效和可擴展。
這是代理抹布工作流的示例。
上圖表示代理抹布框架的架構。它顯示了AI代理與抹布相結合時如何在某些條件下做出決策。該圖像清楚地表明,如果有條件節點,代理將根據提供的上下文決定選擇哪種邊緣。
另請閱讀:LLM代理商的10個業務應用
智能常見問題解答聊天機器人的架構
現在,我們將深入研究我們將要構建的聊天機器人的架構。我們將探討它的工作原理以及其重要組成部分。
下圖顯示了我們系統的整體結構。我們將使用langgraph來實施此功能,這是Langchain的開源AI代理框架。
我們系統的關鍵組成部分包括:
- Langgraph:一個強大的開源AI代理框架,可有效地創建複雜的,多代理,基於圖形的代理。這些代理可以在整個工作流程中維護狀態,並可以有效處理複雜的查詢。
- LLM:一種高效且強大的大語言模型,可以遵循用戶的說明並以其最佳知識進行相應的回复。在這裡,我們將使用OpenAI的O4-Mini,這是一個小型推理模型,專門為速度,負擔能力和工具使用而設計。
- 向量數據庫:矢量數據庫用於存儲,管理和檢索通常是數據數字表示的矢量嵌入。在這裡,我們使用的是Chromadb,這是開源AI本機向量數據庫。它旨在增強依賴相似性搜索,語義搜索和涉及向量數據的其他任務的系統。
另請閱讀:如何建立客戶支持語音代理
關於構建智能常見問題解答聊天機器人的動手實施
現在,我們將根據上面討論的體系結構來實現聊天機器人的端到端工作流程。我們將逐步進行詳細說明,代碼和样本輸出。所以讓我們開始。
步驟1:安裝依賴項
我們將首先將所有必需的庫安裝到我們的Jupyter筆記本中。這包括圖書館,例如Langchain,Langgraph,Langchain-Openai,Langchain-Community,Chromadb,Openai,Python-Dotenv,Pydantic和Pysqlite3。
!
步驟2:導入所需庫
現在,我們準備進口該項目所需的所有剩餘庫。
導入操作系統 進口JSON 從輸入導入列表,打字,註釋,dict 來自dotenv import load_dotenv #langchain&langgraph特定進口 來自langchain_openai進口chatopenai,openaiembeddings 來自langchain_core.prompts導入chatprompttemplate,MessagsPlaceHolder 來自Pydantic Import Basemodel,field 來自langchain_core.messages導入系統,人類,aimessage 來自langchain_core.documents導入文檔 來自langchain_community.vectorstores導入色度 摘自langgraph.graph Import stategraph,結束
步驟3:設置OpenAI API密鑰
輸入您的OpenAI鍵將其設置為環境變量。
從GetPass Import GetPass OpenAI_API_KEY = getPass(“ OpenAi API鍵:”) load_dotenv() os.getEnv(“ openai_api_key”)
步驟4:下載數據集
我們已經為不同部門製作了JSON格式的樣本常見問題數據集。我們需要從驅動器下載並解壓縮它。
! ! unzip -o /content/blog_faq_files.zip
輸出:
步驟5:定義映射的部門名稱
現在,讓我們定義部門的映射,以便我們的代理系統可以了解哪個文件屬於哪個部門。
#定義部門名稱(確保在攝入期間使用的這些匹配元數據) 部門= [ “客戶支持”, “產品信息”, “忠誠計劃 /獎勵” 這是給出的 unknown_department =“未知/其他” faq_files = { “客戶支持”:“ customer_support_faq.json”, “產品信息”:“ product_information_faq.json”, “忠誠度計劃 /獎勵”:“ loyalty_program_faq.json”, }
步驟6:定義助手功能
我們將定義一些輔助功能,這些功能將負責從JSON文件中加載常見問題解答並將其存儲在Chromadb中。
1。 LOAD_FAQS(…):這是一個輔助功能,可從JSON文件加載FAQ並將其存儲在稱為All_FAQ的列表中。
def load_faqs(file_paths:dict [str,str]) - > dict [str,list [dict [dict [str,str]]]: “”“為每個部門的JSON文件加載QA對。 all_faqs = {} 打印(“加載常見問題...”) 對於dept,file_path in file_paths.items(): 嘗試: 使用open(file_path,'r',encoding ='utf-8')作為f: all_faqs [dept] = json.load(f) print(f“ - 加載{len(all_faqs [dept])} FAQ for {dept}') 除了filenotfounderror: 打印(f“ - 警告:未找到{dept}的常見問題文件:{file_path}。跳過。”) 除了JSON.JSONDECODEERROR: print(f“ - 錯誤:無法從{file_path}。跳過的{dept}的json。 返回all_faqs
2。 Setup_chroma_vector_store(…):此功能設置Chromadb以存儲向量嵌入。為此,我們將首先定義Chroma配置IE,即包含Chroma數據庫文件的目錄。然後,我們將將常見問題解答轉換為Langchain的文檔。它將包含元數據和頁面內容,這是精確抹布的預定義格式。我們可以將問題和答案結合起來,以獲得更好的上下文檢索,或者只是嵌入答案。我們在元數據中將問題和部門的名稱保留下來。
#Chromadb配置 chroma_persist_directory =“ ./chroma_db_store” chroma_collection_name =“ chatbot_faqs” DEF SETUP_CHROMA_VECTOR_STORE( all_faqs:dict [str,list [dict [str,str]]], persist_directory:str, collection_name:str, embedding_model:openaiembeddings, ) - >色度: “”““創建或加載具有常見問題數據和元數據的色度矢量商店。 ”“” 文檔= [] 打印(“ \ nprexring vector Store的文檔...”) 對於部門,all_faqs.items()中的常見問題解答: 對於常見問題解答: #結合問答以獲得更好的上下文嵌入,或者只是嵌入答案 #content = f“問題:{faq ['問題']} \ nanswer:{faq ['答案']}” 內容=常見問題['答案']#通常嵌入答案對於常見問題檢索有效 doc =文檔( page_content =內容, 元數據= { “部門”:部門, “問題”:常見問題['問題']#在元數據中保持問題以進行潛在顯示 } ) Documents.Append(DOC) 打印(f“準備的總文檔:{len(documents)}”) 如果沒有文件: 提高ValueError(“沒有發現在矢量存儲中添加的文件。檢查常見問題加載。”) 打印(f“初始化chromadb vector商店(持久:{persist_directory})...”) vector_store = chroma( collection_name = collection_name, embedding_function = empedding_model, persist_directory = persist_directory, ) 嘗試: vector_store = chroma.from_documents( 文檔=文檔, 嵌入= embedding_model, persist_directory = persist_directory, collection_name = collection_name ) 打印(f“創建和填充的chromadb和{len(documents)}文檔。”) vector_store.persist()#確保創建後持久性 打印(“矢量存儲持續存在。”) 除例外為create_e: 打印(F“致命錯誤:無法創建Chroma Vector Store:{create_e}”) 提高create_e 打印(“ Chromadb設置完成。”) 返回vector_store
步驟7:定義Langgraph代理組件
現在,我們定義我們的AI代理組件,這是我們工作流的主要組成部分。
1。狀態定義:它是一個python類,在運行時包含代理的當前狀態。它包含諸如查詢,情感,部門之類的變量。
班級代理(TypedDict): 查詢:str 情感:str 部門:Str 上下文:str#檢索了抹布的上下文 響應:STR#對用戶的最終回复 錯誤:str |沒有#捕獲潛在錯誤
2. Pydantic模型:我們在這裡定義了Pydantic模型,該模型將確保結構化的LLM輸出。它包含一種情感,它將具有三個價值觀:“正”,“消極”和“中立”,以及一個由LLM預測的部門名稱。
班級分類(basemodel): “”“查詢分類的結構化輸出。”“” 情感:str = field(description =“查詢的情感(正,中性,負)”) 部門:str = field(description = f“列表中最相關的部門:{decyverments [unknown_department]}。使用'{unknown_department}'如果不確定或不適用。”)
3。節點:以下是節點函數,它將一個一個一個一個一個一個任務處理。
- clastify_query_node:它根據查詢性質將傳入查詢和目標部門名稱分類。
- retireve_context_node:它在矢量數據庫上執行抹布,並根據部門名稱過濾結果。
- generate_response_node:它基於查詢生成最終響應,並從數據庫中檢索上下文。
- HUMAN_ESCALATION_NODE:如果情緒為負面或目標部門未知,則將向人類用戶升級查詢。
- Route_Query:它根據分類節點的查詢和輸出確定下一步。
#3。節點 def classify_query_node(state:agentState) - > dict [str,str]: ”“” 使用LLM對情感和目標部門的用戶查詢進行分類。 ”“” 打印(“ ---分類查詢---”) 查詢=狀態[“ query”] llm = chatopenai(model =“ o4-mini”,api_key = openai_api_key)#使用可靠,便宜的模型 #準備分類提示 提示_template = chatprompttemplate.from_messages([[[ SystemMessage( content = f“”“您是零售公司Shopunow的專家查詢分類器。 分析用戶的查詢以確定其情感和最相關的部門。 可用部門是:{','.join(部門)}。 如果查詢不明確地適合其中之一,或者模棱兩可,則將部門分類為“ {Unknown_department}”。 如果查詢表示沮喪,憤怒,不滿或抱怨問題,則將情緒歸類為“負面”。 如果查詢問一個問題,尋求信息或做出中性陳述,則將情感歸類為“中性”。 如果查詢表示滿意,讚美或積極的反饋,則將情緒歸類為“積極”。 僅以結構化的JSON輸出格式做出響應。 ”“” ), HumanMessage(content = f“用戶查詢:{query}”) ))) #具有結構化輸出的LLM鏈 classifier_chain =提示_template | llm.with_structured_output(分類result) 嘗試: 結果:classification result = classifier_chain.invoke({})#現在似乎需要一個空dict作為輸入似乎需要 print(f“分類結果:contiment ='{結果。 返回 { “情感”:result.sentiment.lower(),#正常化 “部門”:結果 } 除例外為E: 打印(f“分類期間的錯誤:{e}”) 返回 { “情感”:“中性”,#錯誤默認 “部門”:unknown_department, “錯誤”:f“分類失敗:{e}” } defreive_context_node(state:agentState) - > dict [str,str]: ”“” 根據查詢和部門從矢量商店中檢索相關上下文。 ”“” 打印(“ ---檢索上下文---”) 查詢=狀態[“ query”] 部門=狀態[“部門”] 如果不是部門或部門== unknown_department: 打印(“跳過檢索:部門未知或不適用。”) 返回{“ context”:“”,“錯誤”:“沒有有效的部門就無法檢索上下文。”} #初始化嵌入模型和矢量存儲訪問 embedding_model = openaiembeddings(api_key = openai_api_key) vector_store = chroma( collection_name = chroma_collection_name, embedding_function = empedding_model, persist_directory = chroma_persist_directory, ) retiever = vector_store.as_retriever( search_type =“相似性”, search_kwargs = { 'k':3,#檢索前3個相關文檔 'filter':{'部門':部門}#***關鍵:部門過濾*** } ) 嘗試: retivered_docs = retriever.invoke(查詢) 如果檢索_docs: context =“ \ n \ n ---- \ n \ n”。 打印(f“檢索{len(retured_docs)}部門的文檔'{dection}'。”)。 #print(f“ context片段:{context [:200]} ...”)#可選:log Sippet 返回{“上下文”:上下文,“錯誤”:none} 別的: 打印(“該部門的矢量商店中沒有找到相關文件。”) 返回{“ context”:“”,“錯誤”:“找不到相關上下文。”} 除例外為E: 打印(f“上下文檢索期間的錯誤:{e}”) 返回{“ context”:“”,“ error”:f“檢索失敗:{e}”} def generate_response_node(state:agentState) - > dict [str,str]: ”“” 基於查詢並檢索上下文來生成響應。 ”“” 打印(“ ---生成響應(抹布)---”) 查詢=狀態[“ query”] context =狀態[“上下文”] llm = chatopenai(model =“ o4-mini”,api_key = openai_api_key)#可以使用更有能力的模型進行生成 如果不是上下文: 打印(“沒有提供上下文,生成通用響應。”) #後備如果檢索失敗,但是路由決定了抹布路徑 response_text =“我在我們的知識庫中找不到與您的查詢有關的特定信息。您能改寫或提供更多詳細信息嗎?” 返回{“響應”:response_text} #RAG提示 提示_template = chatprompttemplate.from_messages([[[ SystemMessage( content = f“”“您是ShopNow的有用AI聊天機器人。在提供的上下文上回答用戶的查詢 *僅 *。 簡潔並直接解決查詢。如果上下文不包含答案,請清楚說明。 不要彌補信息。 情境: --- {情境} ----“”“” ), HumanMessage(content = f“用戶查詢:{query}”) ))) rag_chain =提示_template | LLM 嘗試: 響應= rag_chain.invoke({}) response_text = wendment.content 打印(f“生成的抹布響應:{response_text [:200]} ...”) 返回{“響應”:response_text} 除例外為E: 打印(f“響應生成期間的錯誤:{e}”) 返回{“響應”:“對不起,我在生成響應時遇到了錯誤。”,“錯誤”:f“生成失敗:{e}”} def human_escalation_node(狀態:代理) - > dict [str,str]: ”“” 提供一條消息,表明查詢將升級給人類。 ”“” 打印(“ ---升級為人類支持---”) 原因=“” 如果state.get(“情感”)==“負”: 原因=“由於查詢的性質,” elif state.get(“部門”)== unknown_department: 原因=“由於您的查詢需要特定的注意,” response_text = f“ {原因}我需要將其升級給我們的人類支持團隊。他們將審查您的要求並儘快回到您。謝謝您的耐心配合。” 打印(f“升級消息:{Response_Text}”) 返回{“響應”:response_text} #4。條件路由邏輯 DEF ROUTE_QUERY(狀態:代理) - > str: “”“根據分類結果確定下一步。”“” 打印(“ ---路由決策---”) 情感= state.get(“情感”,“中立”) 部門= state.get(“部門”,unknown_department) 如果情感==“否定”或部門== unknown_department: 打印(f“路由到:human_escalation(情感:{contiment},部門:{部門})”) 返回“ human_esscalation” 別的: print(f“路由到:retrieve_context(情感:{contiment},部門:{部門})”) 返回“ retrieve_context”
步驟8:定義圖形功能
讓我們構建圖形函數,然後將節點和邊緣分配給圖形。
#---圖定義--- def build_agent_graph(vector_store:chroma) - > stategraph: “”“構建Langgraph代理。”“” 圖形= stategraph(agentState) #添加節點 graph.add_node(“ classify_query”,classify_query_node) graph.add_node(“ retrieve_context”,recreive_context_node) graph.add_node(“ generate_response”,generate_response_node) graph.add_node(“ human_escalation”,human_escalation_node) #設置入口點 graph.set_entry_point(“ classify_query”) #添加邊緣 graph.add_conditional_edges( “ classify_query”,#源節點 Route_Query,#確定路由的功能 {#映射:Route_query的輸出 - >目標節點 “ retrieve_context”:“ retrieve_context”, “ human_esscalation”:“ human_escalation” } ) graph.add_edge(“ retrieve_context”,“ generate_response”) graph.add_edge(“ generate_response”,end) graph.add_edge(“ human_escalation”,結束) #編譯圖形 #memory = sqlitesaver.from_conn_string(“:memory:“)#內存持續性的示例 app = graph.compile()#checkpointer =陳述對話可選內存 打印(“成功編譯了\ nagent圖。”) 返回應用程序
步驟9:發起代理執行
現在,我們將初始化代理並開始執行工作流程。
1。讓我們從加載常見問題開始。
#1。加載常見問題 FAQS_DATA = load_faqs(faq_files) 如果不是FAQS_DATA: 打印(“錯誤:未加載常見問題解答數據。退出。”) 出口()
輸出:
2。設置嵌入式模型。在這裡,我們將設置OpenAI嵌入模型,以更快地檢索。
#2。設置向量商店 embedding_model = openaiembeddings(api_key = openai_api_key) vector_store = setup_chroma_vector_store( FAQS_DATA, chroma_persist_directory, chroma_collection_name, embedding_model )
輸出:
另請閱讀:如何為抹布模型選擇正確的嵌入?
3。現在,使用預定義函數構建代理,使用美人魚圖可視化代理流動。
#3。構建代理圖 agent_app = build_agent_graph(vector_store) 來自ipython.display導入顯示,圖像,降價 display(圖像(agens_app.get_graph()。draw_mermaid_png()))
輸出:
步驟10:測試代理
我們已經到達了工作流程的最後一部分。到目前為止,我們已經構建了幾個節點和功能。現在是測試我們的代理並查看輸出的時候了。
1。首先,讓我們定義測試查詢。
#測試代理 test_queries = [ “我該如何跟踪我的訂單?” “回報政策是什麼?” “告訴我'Urban Explorer'夾克材料。” 這是給出的
2。現在讓我們測試代理。
打印(“ \ n ---測試代理---”) 對於test_queries中的查詢: 打印(f“ \ ninput查詢:{query}”) #定義圖形調用的輸入 輸入= {“ query”:query} # 嘗試: #調用圖 #配置參數是可選的,但可用於狀態執行(如果需要) #config = {“ configurable”:{“ thread_id”:“ user_123”}}#示例配置 final_state = agent_app.invoke(輸入)#,config = config) 打印(f“最終國務院:{final_state.get('departmend')}”) 打印(f“最終狀態情感:{final_state.get('contiment')}”) 打印(f“代理響應:{final_state.get('wenspy')}”) 如果final_state.get('錯誤'): 打印(f“遇到錯誤:{final_state.get('error')}”) #例外為e: #print(f“錯誤運行代理圖形的查詢'{query}':{e}”) #導入追溯 #trackback.print_exc()#打印調試的詳細追溯 打印(“ \ n ---代理測試完成---”)
打印(“ \ n-測試代理 - ”)
輸出:
我們可以在輸出中看到我們的代理商表現良好。首先,它對查詢進行了分類,然後將決策路由到檢索節點或人類節點。然後,檢索部分是從矢量數據庫中成功檢索上下文的。最後,根據需要生成響應。因此,我們製作了聰明的常見問題解答聊天機器人。
您可以在此處使用所有代碼訪問COLAB筆記本。
結論
如果您已經到達了這麼遠,則意味著您已經學會瞭如何使用Agentic Rag和Langgraph構建智能常見問題解答聊天機器人。在這裡,我們看到建立一個可以推理和做出決定的智能代理並不難。我們構建的代理聊天機器人具有成本效益,快速,並且能夠充分理解問題或輸入查詢的上下文。我們在這裡使用的架構是完全可自定義的,這意味著可以為其特定用例編輯代理的任何節點。借助Agesic抹布,Langgraph和Chromadb,製作代理從未如此簡單。從來沒有那麼容易。我敢肯定,我們在本指南中涵蓋的內容為您提供了使用這些工具構建更複雜系統的基礎知識。
以上是如何使用代理抹布構建智能常見問題聊天機器人的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

Meta的Llama 3.2:多模式和移動AI的飛躍 Meta最近公佈了Llama 3.2,這是AI的重大進步,具有強大的視覺功能和針對移動設備優化的輕量級文本模型。 以成功為基礎

嘿,編碼忍者!您當天計劃哪些與編碼有關的任務?在您進一步研究此博客之前,我希望您考慮所有與編碼相關的困境,這是將其列出的。 完畢? - 讓&#8217

本週的AI景觀:進步,道德考慮和監管辯論的旋風。 OpenAI,Google,Meta和Microsoft等主要參與者已經釋放了一系列更新,從開創性的新車型到LE的關鍵轉變

介紹 Openai已根據備受期待的“草莓”建築發布了其新模型。這種稱為O1的創新模型增強了推理能力,使其可以通過問題進行思考

介紹 想像一下,穿過美術館,周圍是生動的繪畫和雕塑。現在,如果您可以向每一部分提出一個問題並獲得有意義的答案,該怎麼辦?您可能會問:“您在講什麼故事?

Meta's Llama 3.2:多式聯運AI強力 Meta的最新多模式模型Llama 3.2代表了AI的重大進步,具有增強的語言理解力,提高的準確性和出色的文本生成能力。 它的能力t

介紹 Mistral發布了其第一個多模式模型,即Pixtral-12b-2409。該模型建立在Mistral的120億參數Nemo 12B之上。是什麼設置了該模型?現在可以拍攝圖像和Tex

SQL的Alter表語句:動態地將列添加到數據庫 在數據管理中,SQL的適應性至關重要。 需要即時調整數據庫結構嗎? Alter表語句是您的解決方案。本指南的詳細信息添加了Colu
