搜尋結果

×

LangChain Agents 和 Ollama 建一個有多輪對話和上下文記憶能力的 LLM 聊天機器人 Chatbot

使用 LangChain 來構建 LLM 聊天機器人。此助手具備多輪對話的能力,並能記住上下文,還可以執行特定工具來回答問題(查詢今天的日期)。

崴寶教你如何使用 LangChain 來構建 LLM 聊天機器人。此助手具備多輪對話的能力,並能記住上下文,還可以執行特定工具來回答問題(查詢今天的日期)。

所需檔案下載

Github Repositoryweitsung50110/Huggingface_Langchain_kit

本文使用裡面的 langchain_agents_conversational-react_memory.py 檔案。

initialize_agent 中有非常多的 Agents,詳細介紹可以參考這篇:
LangChain Agents 預設代理類型解析:initialize_agent 選擇最適合你的應用場景

本文使用 Conversational-react-description 進行實作。

若想使用 zero-shot-react-description 進行實作,可以參考這篇:
用 LangChain Agents 和 Ollama 建立 LLM 多功能 AI 助手:支援日期查詢與數學運算

程式架構

  1. 初始化 LLM — 使用 Ollama 的語言模型。
  2. 定義工具 — 如查詢日期的工具。
  3. 自定義 Prompt — 指導 AI 如何回應問題。
  4. 管理記憶 — 記住上下文對話。
  5. 建立對話型代理(Agent) — 將 LLM、工具和記憶結合。
  6. 互動主程式 — 實現人機互動,處理多輪對話。

Docker Image

Image 名稱: weitsung50110/ollama_flask
此為已安裝好的 Docker image 環境。

使用說明:

有關 docker run 等使用方法,請進入 Docker Hub 的說明欄查看詳細資訊。

Docker Hub 連結: weitsung50110/ollama_flask

docker pull weitsung50110/ollama_flask:1.0

1. 初始化 LLM

這一步是引入 Ollama 語言模型,並設定模型參數(使用 kenneth85/llama-3-taiwan:8b-instruct 模型)。

注意: model 是可以調整更動的。

model=’更換成你載入的模型’
Ex:llm = Ollama(model=’llama3’)

llm = Ollama(
    model="kenneth85/llama-3-taiwan:8b-instruct", 
    callback_manager=CallbackManager([StreamingStdOutCallbackHandler()])
)

CallbackManager 用於處理事件回調,而 StreamingStdOutCallbackHandler 則允許在終端上顯示輸出的過程。

2.定義工具

def get_today_date(_):
    print(datetime.now().strftime("今天是 %Y 年 %m 月 %d 日,星期%a。"))
    return datetime.now().strftime("今天是 %Y 年 %m 月 %d 日,星期%a。")

tools = [
    Tool(
        name="get today date", 
        func=get_today_date, 
        description="回答今天的日期和星期幾。"
    )
]
  • 工具函數
    定義查詢今天日期的功能,返回格式化的日期和星期。

  • 工具列表
    將工具封裝為一個 Tool,指定工具的名稱和用途。

  • 工具調用
    當用戶詢問日期時,代理 Agent 會調用此工具提供答案。

3.自定義 Prompt

custom_prompt = PromptTemplate(
    input_variables=["input", "chat_history"],
    template="""\
你是一個智慧型 AI 助手,能回答問題並記住上下文。
可以使用以下工具:
1. get today date: 提供今天的日期和星期幾。

當問題可以直接回答時,請直接回答。只有在必須使用工具時才使用它們。

以下是目前的對話記錄:
{chat_history}

使用者的最新問題是:{input}
請根據上下文回答問題,並僅在必要時使用工具。
"""
)

PromptTemplate 定義 AI 回應問題的規則

  • 包含對工具的描述
    提供工具的功能與使用方式,讓 AI 瞭解如何正確使用工具。

  • 提示 AI 考慮對話記錄
    引導 AI 根據上下文與對話記錄回答問題,保持對話的一致性。

  • 指導 AI 僅在必要時使用工具
    明確要求 AI 只在需要時調用工具,避免不必要的操作。

4.初始化記憶

memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

記憶(Memory)與 ConversationBufferMemory

  • 記憶用途
    記憶用於儲存對話歷史,ConversationBufferMemory 將每次對話記錄起來,方便 AI 回顧。

  • 主要設定

    • memory_key="chat_history":指定記憶的鍵值。
    • return_messages=True:返回完整的對話訊息。

為什麼使用 ConversationBufferMemory?

ConversationBufferMemory 是 LangChain 中一種常見的記憶類型,主要用於儲存對話的完整歷史記錄,以便在多輪對話中保持上下文連貫性。


特點

  1. 完整記錄對話
    將每次用戶與 AI 的對話訊息按順序儲存。

  2. 上下文參考
    代理可以根據歷史對話來理解當前問題,避免忘記先前的對話。

  3. 簡單易用
    設置與管理相對容易,適合基礎對話應用。

記憶方式 適合情境 優點 缺點
ConversationBufferMemory 短期對話,內容不多時適用 簡單直觀,實現快速 無法處理長對話或多主題場景
ConversationSummaryMemory 長期對話,需保持全局概念時適用 節省資源,保持上下文連貫 易丟失細節,回應可能不夠準確
VectorStoreMemory 多主題對話,需快速檢索時適用 高效檢索,支持大規模數據 複雜實現,需配置向量數據庫
CombinedMemory 複雜應用,多種需求並存時適用 彈性高,適用廣泛 資源需求高,實現成本高

5.初始化對話型代理(Agent)

agent = initialize_agent(
    tools=tools,
    llm=llm,
    agent="conversational-react-description",
    verbose=False,
    agent_prompt=custom_prompt,
    handle_parsing_errors=True,
    memory=memory
)

代理結合 LLM、工具與記憶

在這裡,我們將 LLM、工具和記憶結合到一個代理中,以實現多輪對話的功能。

結合的元素

  1. tools
    包含查詢日期的工具,用於執行特定任務。

  2. llm
    指定的語言模型,負責生成自然語言回應。

  3. agent_prompt
    使用自定義的 Prompt 指導代理的回應行為。

  4. memory
    整合對話記憶,用於儲存對話歷史,保持上下文的連貫性。

  5. handle_parsing_errors
    用於處理解析錯誤,避免因語法或其他錯誤導致程式崩潰。

  6. agent=”conversational-react-description”
    表明這是一個對話型代理,適合多輪對話應用場景。

6.主程式互動

def main():
    print("歡迎使用智慧型 AI 助手!可以進行多輪對話,並記住上下文。")
    print("隨時輸入問題,例如:『今天是幾號?』,或『你剛剛問了什麼?』")
    print("如果想結束對話,請輸入 'bye', 'exit' 或 'quit'。\n")

    while True:
        user_query = input("請輸入您的問題:")
        if user_query.lower() in ["bye", "exit", "quit"]:
            print("感謝您的使用,再見!")
            break

        try:
            response = agent.invoke({"input": user_query})
            print("\nAI 助手的回答紀錄:")
            print(response)
        except Exception as e:
            print(f"抱歉,處理你的問題時出現了一些錯誤:{e}")

用戶與 AI 助手互動的主邏輯

主邏輯步驟

  1. 提示用戶輸入問題
    當用戶輸入問題後,將其傳遞給代理處理。

  2. 檢查退出條件
    如果用戶輸入 byeexitquit,則結束程式。

  3. 捕捉錯誤
    捕捉異常情況,避免因錯誤導致程式中斷運行。

成果展示

執行程式

root@4be643ba6a94:/app# python3 langchain_agents_conversational-react_memory.py
/app/langchain_agents_conversational-react_memory.py:10: LangChainDeprecationWarning: The class `Ollama` was deprecated in LangChain 0.3.1 and will be removed in 1.0.0. An updated version of the class exists in the :class:`~langchain-ollama package and should be used instead. To use it run `pip install -U :class:`~langchain-ollama` and import as `from :class:`~langchain_ollama import OllamaLLM``.
llm = Ollama(model="kenneth85/llama-3-taiwan:8b-instruct", callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]))
/app/langchain_agents_conversational-react_memory.py:10: DeprecationWarning: callback_manager is deprecated. Please use callbacks instead.
llm = Ollama(model="kenneth85/llama-3-taiwan:8b-instruct", callback_manager=CallbackManager([StreamingStdOutCallbackHandler()]))
/app/langchain_agents_conversational-react_memory.py:44: LangChainDeprecationWarning: Please see the migration guide at: https://python.langchain.com/docs/versions/migrating_memory/
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
/app/langchain_agents_conversational-react_memory.py:47: LangChainDeprecationWarning: The function `initialize_agent` was deprecated in LangChain 0.1.0 and will be removed in 1.0. Use :meth:`~Use new agent constructor methods like create_react_agent, create_json_agent, create_structured_chat_agent, etc.` instead.
agent = initialize_agent(
歡迎使用智慧型 AI 助手!可以進行多輪對話,並記住上下文。
隨時輸入問題,例如:『今天是幾號?』,或『你剛剛問了什麼?』
如果想結束對話,請輸入 'bye', 'exit' 或 'quit'。

請輸入您的問題:

Q: 請問今天是幾號?
AI: 今天是 2024 年 12 月 5 日,星期四。

請輸入您的問題:請問今天是幾號?
Thought: Do I need to use a tool? Yes
Action: get today date
Action Input: None今天是 2024 年 12 月 05 日,星期Thu。
Do I need to use a tool? No
AI: 今天是 2024 年 12 月 5 日,星期四。
AI 助手的回答紀錄:
{'input': '請問今天是幾號?', 'chat_history': [HumanMessage(content='請問今天是幾號?', additional_kwargs={}, response_metadata={}), AIMessage(content='今天是 2024 年 12 月 5 日,星期四。', additional_kwargs={}, response_metadata={})], 'output': '今天是 2024 年 12 月 5 日,星期四。'}

Q: 我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!
AI: 你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?

請輸入您的問題:我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!
Thought: Do I need to use a tool? No
AI: 你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?
AI 助手的回答紀錄:
{'input': '我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!', 'chat_history': [HumanMessage(content='請問今天是幾號?', additional_kwargs={}, response_metadata={}), AIMessage(content='今天是 2024 年 12 月 5 日,星期四。', additional_kwargs={}, response_metadata={}), HumanMessage(content='我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!', additional_kwargs={}, response_metadata={}), AIMessage(content='你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?', additional_kwargs={}, response_metadata={})], 'output': '你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?'}

Q: 請問你記得我的ig是多少嗎
AI: 我記得你告訴我你的 Instagram 帳號是 @weibert_coding。

請輸入您的問題:請問你記得我的ig是多少嗎
Thought: Do I need to use a tool? No
AI: 我記得你告訴我你的 Instagram 帳號是 @weibert_coding。
AI 助手的回答紀錄:
{'input': '請問你記得我的ig是多少嗎', 'chat_history': [HumanMessage(content='請問今天是幾號?', additional_kwargs={}, response_metadata={}), AIMessage(content='今天是 2024 年 12 月 5 日,星期四。', additional_kwargs={}, response_metadata={}), HumanMessage(content='我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!', additional_kwargs={}, response_metadata={}), AIMessage(content='你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?', additional_kwargs={}, response_metadata={}), HumanMessage(content='請問你記得我的ig是多少嗎', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你告訴我你的 Instagram 帳號是 @weibert_coding。', additional_kwargs={}, response_metadata={})], 'output': '我記得你告訴我你的 Instagram 帳號是 @weibert_coding。'}

Q: 你記得我的yt帳號名稱嗎
AI: 我記得你告訴我你的 YouTube 頻道名稱是 Weibert好崴寶程式。

請輸入您的問題:你記得我的yt帳號名稱嗎
Thought: Do I need to use a tool? No
AI: 我記得你告訴我你的 YouTube 頻道名稱是 Weibert好崴寶程式。
AI 助手的回答紀錄:
{'input': '你記得我的yt帳號\udce5名稱嗎', 'chat_history': [HumanMessage(content='請問今天是幾號?', additional_kwargs={}, response_metadata={}), AIMessage(content='今天是 2024 年 12 月 5 日,星期四。', additional_kwargs={}, response_metadata={}), HumanMessage(content='我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!', additional_kwargs={}, response_metadata={}), AIMessage(content='你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?', additional_kwargs={}, response_metadata={}), HumanMessage(content='請問你記得我的ig是多少嗎', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你告訴我你的 Instagram 帳號是 @weibert_coding。', additional_kwargs={}, response_metadata={}), HumanMessage(content='你記得我的yt帳號\udce5名稱嗎', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你告訴我你的 YouTube 頻道名稱是 Weibert好崴寶程式。', additional_kwargs={}, response_metadata={})], 'output': '我記得你告訴我你的 YouTube 頻道名稱是 Weibert好崴寶程式。'}

Q: 你記得我的名字嗎?
AI: 我記得你提到過你的名字是好崴寶。你還想讓我查找任何其他資訊嗎?

請輸入您的問題:你記得我的名字嗎?
Thought: Do I need to use a tool? No
AI: 我記得你提到過你的名字是好崴寶。你還想讓我查找任何其他資訊嗎?
AI 助手的回答紀錄:
{'input': '你記得我的名字嗎?', 'chat_history': [HumanMessage(content='請問今天是幾號?', additional_kwargs={}, response_metadata={}), AIMessage(content='今天是 2024 年 12 月 5 日,星期四。', additional_kwargs={}, response_metadata={}), HumanMessage(content='我是好崴寶Weibert Weiberson,很高興認識你, 我的ig是@weibert_coding, 我的yt是Weibert好崴寶程式, 歡迎訂閱我!', additional_kwargs={}, response_metadata={}), AIMessage(content='你好,好崴寶!很高興認識你。謝謝你在 Instagram 和 YouTube 上追蹤我。我希望能提供有用的資訊和見解來回答你的問題或與你進行對話。請隨時提出任何問題或讓我們討論任何主題。你今天想談什麼?', additional_kwargs={}, response_metadata={}), HumanMessage(content='請問你記得我的ig是多少嗎', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你告訴我你的 Instagram 帳號是 @weibert_coding。', additional_kwargs={}, response_metadata={}), HumanMessage(content='你記得我的yt帳號\udce5名稱嗎', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你告訴我你的 YouTube 頻道名稱是 Weibert好崴寶程式。', additional_kwargs={}, response_metadata={}), HumanMessage(content='你記得我的名字嗎?', additional_kwargs={}, response_metadata={}), AIMessage(content='我記得你提到過你的名字是好崴寶。你還想讓我查找任何其他資訊嗎?', additional_kwargs={}, response_metadata={})], 'output': '我記得你提到過你的名字是好崴寶。你還想讓我查找任何其他資訊嗎?'}

崴寶總結

本教學帶你探索如何用 LangChain Agents 構建一個超聰明的 LLM 聊天機器人!

這不僅僅是一個簡單的對話機器人,它還能記住上下文,進行多輪對話,讓你感覺像是在和一位聰明的朋友聊天!

此外,崴寶還教你如何加入一個超實用的自定義工具(例如:「今天是幾號?」)來讓它完成有趣的小任務。🥰

    喜歡 好崴寶 Weibert Weiberson 的文章嗎?在這裡留下你的評論!本留言區支援 Markdown 語法