搜尋結果

×

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. 簡單易用
    設置與管理相對容易,適合基礎對話應用。

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 語法