LangChain 中的會話記憶
LangChain 是建立 LLM 應用程式的強大框架。然而,強大的功能也帶來了相當多的複雜性。LangChain 提供許多提示 LLM 的方式,以及會話記憶體等基本功能。會話記憶提供 LLM 記憶您聊天內容的上下文。
在這篇文章中,我們將探討如何在 LangChain 和 Milvus 中使用會話記憶。若要跟進,您需要pip
安裝四個函式庫和 OpenAI API 金鑰。您可以透過執行pip install langchain milvus pymilvus python-dotenv
來安裝所需的四個函式庫。或執行本文CoLab Notebook中的第一個區塊。
在這篇文章中,我們將學習到
- 使用 LangChain 進行會話記憶
- 設定對話情境
- 使用 LangChain 提示會話記憶體
- LangChain 會話記憶總結
使用 LangChain 的會話記憶體
在預設狀態下,您透過單一提示與 LLM 互動。增加上下文記憶體,或稱為「會話記憶體」,意味著您不再需要透過單一提示傳送所有內容。LangChain 提供儲存您與 LLM 已經進行過的會話的功能,以便日後擷取這些資訊。
要設定向量儲存的持久性會話記憶體,我們需要 LangChain 的六個模組。首先,我們必須取得OpenAIEmbeddings
和OpenAI
LLM。我們也需要VectorStoreRetrieverMemory
和 LangChain 版本的Milvus
來使用向量儲存後端。然後,我們需要ConversationChain
和PromptTemplate
來儲存我們的對話並加以查詢。
os
,dotenv
, 和openai
函式庫主要用於操作目的。我們使用它們來載入和使用 OpenAI API 金鑰。最後一個設定步驟是啟動一個本機Milvus Lite實例。我們使用 Milvus Python 套件中的default_server
來完成。
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
from langchain.vectorstores import Milvus
embeddings = OpenAIEmbeddings()
import os
from dotenv import load_dotenv
import openai
load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")
from milvus import default_server
default_server.start()
設定對話情境
現在我們已經設定好所有的先決條件,可以開始建立會話記憶體。第一步是使用 LangChain 建立與 Milvus 伺服器的連線。接下來,我們使用一個空字典來建立 LangChain Milvus 套件。此外,我們會傳入上面建立的嵌入式資料,以及 Milvus Lite 伺服器的連線細節。
要將向量資料庫用於會話記憶,我們需要將其實體化為retriever。在這種情況下,我們只擷取前 1 個結果,設定k=1
。最後一個會話記憶體設定步驟是透過我們剛剛設定的retriever 和向量資料庫連線,使用VectorStoreRetrieverMemory
物件作為我們的會話記憶體。
要使用我們的會話記憶體,它必須有一些上下文。因此,讓我們賦予記憶體一些上下文。在這個範例中,我們提供五項資訊。讓我們儲存我最喜歡的零食 (巧克力)、運動 (游泳)、啤酒 (健力士)、甜點 (起司蛋糕) 和音樂人 (Taylor Swift)。每個項目都會透過save_context
功能儲存在記憶體中。
vectordb = Milvus.from_documents(
{},
embeddings,
connection_args={"host": "127.0.0.1", "port": default_server.listen_port})
retriever = Milvus.as_retriever(vectordb, search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever)
about_me = [
{"input": "My favorite snack is chocolate",
"output": "Nice"},
{"input": "My favorite sport is swimming",
"output": "Cool"},
{"input": "My favorite beer is Guinness",
"output": "Great"},
{"input": "My favorite dessert is cheesecake",
"output": "Good to know"},
{"input": "My favorite musician is Taylor Swift",
"output": "Same"}
]
for example in about_me:
memory.save_context({"input": example["input"]}, {"output": example["output"]})
使用 LangChain 提示會話記憶體
是時候看看我們如何使用會話記憶體了。讓我們先透過 LangChain 連接到 OpenAI LLM。我們使用溫度 0 來表示我們不希望我們的 LLM 有創意。
接下來,我們建立一個範本。我們告訴 LLM 它正在與人類進行友好的對話,並插入兩個變數。history
變數提供對話記憶體中的上下文。input
變數提供目前的輸入。我們使用PromptTemplate
物件來插入這些變數。
我們使用ConversationChain
物件來結合我們的提示、LLM 和記憶體。現在,我們準備給予對話一些提示,以檢查對話的記憶體。我們先告訴 LLM 我們的名字是 Gary,是 Pokemon 系列中的主要對手(會話記憶中的其他內容都是關於我的事實)。
llm = OpenAI(temperature=0) # Can be any valid LLM
_DEFAULT_TEMPLATE = """The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Relevant pieces of previous conversation:
{history}
(You do not need to use these pieces of information if not relevant)
Current conversation:
Human: {input}
AI:"""
PROMPT = PromptTemplate(
input_variables=["history", "input"], template=_DEFAULT_TEMPLATE
)
conversation_with_summary = ConversationChain(
llm=llm,
prompt=PROMPT,
memory=memory,
verbose=True
)
conversation_with_summary.predict(input="Hi, my name is Gary, what's up?")
下圖顯示 LLM 的預期回應可能是什麼樣子。在這個範例中,它的回應是說它的名字是「AI」。
現在讓我們測試一下目前的記憶體。我們使用之前建立的ConversationChain
物件,查詢我最喜愛的音樂家。
conversation_with_summary.predict(input="who is my favorite musician?")
下圖顯示了 Conversation Chain 的預期回應。由於我們使用了 verbose 選項,它也顯示了相關的會話。我們可以看到它如預期般返回我最喜愛的音樂家是 Taylor Swift。
接下來,讓我們查詢我最喜歡的甜點 - 乳酪蛋糕。
conversation_with_summary.predict(input="Whats my favorite dessert?")
當我們查詢我最喜歡的甜點時,我們可以看到會話鏈再次從 Milvus 挑選出正確的資訊。它發現我最喜歡的甜點是芝士蛋糕,就像我之前告訴它的一樣。
既然我們已經確認可以查詢我們之前提供的資訊,現在讓我們再檢查一件事 - 我們在對話開始時提供的資訊。對話開始時,我們告訴 AI 我們的名字是 Gary。
conversation_with_summary.predict(input="What's my name?")
我們最後的檢查結果是,對話鏈將我們的名字儲存在向量儲存的對話記憶體中。它會返回我們說我們的名字是 Gary。
LangChain 會話記憶體摘要
在本教程中,我們學習了如何在 LangChain 中使用會話記憶體。LangChain 提供像 Milvus 之類的向量儲存後端來存取持久化會話記憶體。我們可以使用會話記憶體,將歷史注入我們的提示,並將歷史上下文儲存在ConversationChain
物件中。
在這個範例教學中,我們給了 Conversation Chain 五個關於我的事實,並假扮成 Pokemon 的主要對手 Gary。接著,我們針對我們儲存的先驗知識(我最喜歡的音樂家和甜點)向 Conversation Chain 提出問題。它正確回答了這兩個問題,並顯示出相關條目。最後,我們詢問它關於我們在對話開始時所說的名字,它正確地回覆我們說我們的名字是「Gary」。
Try Managed Milvus for Free
Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.
Get StartedLike the article? Spread the word