AI 智能體記憶架構在 LangGraph 中的落地實現 原創
記憶是一個系統,用于記錄之前交互的信息。對于 AI 智能體(AI Agent)來說,記憶非常重要,因為它能讓 AI 智能體記住之前的交互,從反饋中學習,并適應用戶的偏好。當 AI 智能體處理更復雜的任務和大量用戶交互時,這種能力對于提高效率和用戶滿意度變得至關重要。
AI 智能體中有兩種記憶類型:短期記憶和長期記憶:

- 短期記憶(Short-term memory):也稱為線程范圍記憶(thread-scoped memory),通過在會話中維護消息歷史來跟蹤正在進行的對話。LangGraph 將短期記憶作為 AI 智能體狀態的一部分進行管理。狀態通過檢查點(checkpointer)持久化到數據庫中,以便隨時恢復線程。短期記憶會在調用圖或完成步驟時更新,并且在每個步驟開始時讀取狀態。
- 長期記憶(Long-term memory):存儲跨會話的用戶特定或應用級別的數據,并在不同的對話線程中共享。它可以在任何時間、任何線程中被回憶。記憶可以被限定在任何自定義的命名空間(namespace)中,而不僅僅是在單個線程ID內。LangGraph提供了存儲(stores),讓你可以保存和回憶長期記憶。
下文詳細剖析之。
一、AI 智能體短長期記憶架構設計與落地
1、短期記憶架構設計與落地
短期記憶讓你的 AI 智能體應用能夠在單個線程或對話中記住之前的交互。線程會組織一個會話中的多次交互,類似于電子郵件將消息分組為單個對話的方式。
LangGraph 將短期記憶作為 AI 智能體狀態的一部分進行管理,并通過線程范圍的檢查點持久化。這種狀態通常包括對話歷史以及其他狀態化數據,例如:上傳的文件、檢索的文檔或生成的工件。通過將這些內容存儲在圖的狀態中,AI 智能體可以訪問給定對話的完整上下文,同時保持不同線程之間的分離。
1.1、管理短期記憶
對話歷史是短期記憶的最常見形式,而長對話對當前的大語言模型(LLMs)來說是一個挑戰。完整的對話歷史可能無法完全放入 LLM 的上下文窗口中,從而導致無法恢復的錯誤。即使你的 LLM 支持完整的上下文長度,大多數 LLM 在處理長上下文時表現仍然不佳。它們會被過時或離題的內容“分散注意力”,同時還會導致響應速度變慢和成本增加。

聊天模型通過消息接受上下文,這些消息包括開發者提供的指令(系統消息)和用戶輸入(人類消息)。在聊天應用中,消息會在人類輸入和模型響應之間交替,隨著時間推移,消息列表會變得越來越長。由于上下文窗口有限,且消息列表中的 token 數量過多可能會導致成本增加,因此許多 AI 智能體應用可以從手動刪除或忘記過時信息。
2、長期記憶架構設計與落地
LangGraph 中的長期記憶允許系統在不同的對話或會話中保留信息。與線程范圍的短期記憶不同,長期記憶是保存在自定義的“命名空間(namespaces)中的。
長期記憶是一個復雜的挑戰,沒有一種通用的解決方案。然而,以下問題提供了一個框架,幫助你了解不同的技術:
- 記憶的類型是什么?人類使用記憶來記住事實(語義記憶)、經歷(情景記憶)和規則(程序性記憶)。AI 智能體也可以以同樣的方式使用記憶。例如:AI 智能體可以使用記憶來記住關于用戶的特定事實,以完成任務。
- 你希望何時更新記憶?記憶可以作為 AI 智能體應用程序邏輯的一部分進行更新(例如:“熱路徑”上)。在這種情況下,AI 智能體通常會在回應用戶之前決定記住事實。或者,記憶可以作為一個后臺任務進行更新(在后臺/異步運行的邏輯中生成記憶)。
3、記憶類型剖析
不同的 AI 智能體應用需要不同類型的記憶。盡管類比并不完美,但研究人類記憶類型可以提供一些見解。一些研究甚至將這些人類記憶類型映射到 AI 智能體中使用的類型。

3.1、語義記憶
語義記憶,無論是人類還是 AI 智能體,都涉及對特定事實和概念的保留。在人類中,它可能包括在學校學到的信息以及對概念及其關系的理解。對于 AI 智能體,語義記憶通常用于通過記住過去的交互中的事實或用于個性化應用的概念。
注意:語義記憶與“語義搜索”不同。語義搜索是一種通過“含義”(通常是嵌入向量)查找相似內容的技術。語義記憶是心理學中的一個術語,指的是存儲事實和知識,而語義搜索是一種基于含義而非精確匹配檢索信息的方法。
第一、用戶畫像(Profile)
語義記憶可以通過不同的方式管理。例如,記憶可以是一個單一的、不斷更新的“用戶畫像”,其中包含關于用戶、組織或其他實體(包括 AI 智能體本身)的范圍明確且具體的信息。用戶畫像通常只是一個帶有各種鍵值對的 JSON 文檔,你選擇這些鍵值對來代表你的領域。

在記住用戶畫像時,你需要確保每次都在更新畫像。因此,你需要傳入之前的畫像,并讓大模型生成一個新的畫像(或者生成一個 JSON 補丁來應用到舊畫像上)。隨著畫像變得越來越大,這可能會變得容易出錯,可能需要將畫像拆分為多個文檔,或者在生成文檔時進行嚴格解碼,以確保記憶模式保持有效。
第二、文檔集合(Collection)
或者,記憶可以是一個隨著時間不斷更新和擴展的文檔集合。每個單獨的記憶可以更狹窄地限定范圍,更容易生成,這意味著你不太可能隨著時間的推移丟失信息。對于 LLM 來說,生成新對象以存儲新信息比將新信息與現有畫像協調起來更容易。因此,使用文檔集合通常會導致更高的回憶率。
然而,這將一些復雜性轉移到了記憶更新上。大模型現在必須刪除或更新列表中的現有項目,這可能會很棘手。此外,一些大模型可能默認過度插入,而另一些大模型可能默認過度更新。
使用文檔集合還意味著將復雜性轉移到對列表的記憶搜索上。當前的存儲支持語義搜索和按內容過濾。
最后,使用記憶集合可能會使向大模型提供全面上下文變得具有挑戰性。盡管單個記憶可能遵循特定的模式,但這種結構可能無法捕捉記憶之間的完整上下文或關系。因此,當使用這些記憶來生成回應時,大模型可能會缺少在統一畫像方法中更容易獲得的重要上下文信息。

無論采用哪種記憶管理方法,核心要點是 AI 智能體將使用語義記憶來支撐其回應,這通常會導致更個性化和相關的互動。
3.2、情景記憶
情景記憶,無論是人類還是 AI 智能體,都涉及回憶過去的事件或行動。事實可以寫入語義記憶,而經歷可以寫入情景記憶。對于 AI 智能體,情景記憶通常用于幫助 AI 智能體記住如何完成任務。
在實踐中,情景記憶通常是通過少量樣本提示(few-shot example prompting)來實現的,AI 智能體通過學習過去的序列來正確執行任務。有時“展示”比“告訴”更容易,LLM 從示例中學習得很好。少量樣本學習讓你可以通過在提示中更新輸入-輸出示例來“編程”你的 LLM,以展示預期的行為。盡管可以使用各種最佳實踐來生成少量樣本示例,但挑戰通常在于根據用戶輸入選擇最相關的示例。
注意:記憶存儲只是存儲少量樣本數據的一種方式。如果你想更多地參與開發,或者將少量樣本更緊密地與你的評估框架聯系起來,你也可以使用LangSmith 數據集來存儲你的數據。然后可以使用現成的動態少量樣本示例選擇器來實現相同的目標。LangSmith 會為你索引數據集,并根據關鍵詞相似性(使用類似 BM25 的算法)檢索與用戶輸入最相關的少量樣本示例。
3.3、程序性記憶
程序性記憶,無論是人類還是 AI 智能體,都涉及記住執行任務所使用的規則。在人類中,程序性記憶就像內化的任務執行知識,例如:通過基本的運動技能和平衡感學會騎自行車。而情景記憶則涉及回憶特定的經歷,比如:你第一次在沒有輔助輪的情況下成功騎自行車,或者一次難忘的自行車騎行經歷。對于 AI 智能體,程序性記憶是模型權重、AI 智能體代碼和 AI 智能體提示詞的組合,這些共同決定了 AI 智能體的功能。
在實踐中,AI 智能體修改其大模型權重或重寫代碼的情況相對較少。然而,AI 智能體修改自己的提示詞則更為常見。
一種有效的改進 AI 智能體指令的方法是通過“反思”或元提示(meta-prompting)。這涉及將 AI 智能體當前的指令(例如:系統提示詞)以及最近的對話或明確的用戶反饋提示詞給 AI 智能體。然后,AI 智能體根據這些輸入來改進自己的指令。這種方法特別適用于那些難以提前指定指令的任務,因為它允許代理從交互中學習和適應。
例如:我們構建了一個使用外部反饋和提示詞重寫來生成高質量推文摘要的推文生成器。在這種情況下,具體的摘要提示詞很難提前指定,但用戶可以很容易地批評生成的推文,并提供關于如何改進摘要過程的反饋。
以下是使用 LangGraph 記憶存儲實現此功能的偽代碼示例。使用存儲來保存提示,??update_instructions???節點獲取當前提示(以及捕獲在??state["messages"]???中的與用戶的對話反饋),更新提示詞,并將新提示詞保存回存儲。然后,??call_model ??從存儲中獲取更新后的提示詞并使用它來生成回應。
# Node that *uses* the instructions
def call_model(state: State, store: BaseStore):
namespace = ("agent_instructions", )
instructions = store.get(namespace, key="agent_a")[0]
# Application logic
prompt = prompt_template.format(instructinotallow=instructions.value["instructions"])
...
# Node that updates instructions
def update_instructions(state: State, store: BaseStore):
namespace = ("instructions",)
current_instructions = store.search(namespace)[0]
# Memory logic
prompt = prompt_template.format(instructinotallow=instructions.value["instructions"], cnotallow=state["messages"])
output = llm.invoke(prompt)
new_instructions = output['new_instructions']
store.put(("agent_instructions",), "agent_a", {"instructions": new_instructions})
...
4、寫入記憶架構設計與落地
AI 智能體寫入記憶主要有兩種方法:“熱路徑”(in the hot path)和“后臺”(in the background)。

4.1、在熱路徑中(熱更新)
在運行時創建記憶既有優點也有挑戰。優點是,這種方法可以實現實時更新,使新記憶能夠立即用于后續交互。它還可以實現透明性,因為用戶可以在記憶被創建和存儲時得到通知。
然而,這種方法也存在挑戰。如果 AI 智能體需要一個新工具來決定要記住什么內容,這可能會增加復雜性。此外,推理要保存到記憶中的內容可能會對 AI 智能體的延遲產生影響。最后,AI 智能體需要在創建記憶和其他職責之間進行多任務處理,這可能會影響記憶的數量和質量。
例如,ChatGPT 使用一個 ??save_memories ??工具將記憶作為內容字符串插入或更新,每次用戶發送消息時,它都會決定是否以及如何使用這個工具。
4.2、在后臺(冷更新)
將創建記憶作為一個單獨的后臺任務有諸多優點。它可以消除主應用中的延遲,將應用邏輯與記憶管理分離,并讓 AI 智能體能夠更專注地完成任務。這種方法還提供了靈活的時間安排,以避免重復工作。
然而,這種方法也有自己的挑戰。確定記憶寫入的頻率變得至關重要,因為更新不頻繁可能會導致其他線程缺少新的上下文。決定何時觸發記憶形成也很重要。常見的策略包括在設定的時間后調度(如果發生新事件則重新調度)、使用 cron 調度,或者允許用戶或應用邏輯手動觸發。
5、記憶存儲架構設計與落地
LangGraph 將長期記憶作為 JSON 文檔存儲在存儲中。每個記憶都組織在一個自定義的命名空間(類似于文件夾)和一個獨特的鍵(類似于文件名)下。命名空間通常包括用戶或組織 ID 或其他標簽,以便更容易地組織信息。這種結構支持記憶的層次化組織。然后通過內容過濾支持跨命名空間搜索。
from langgraph.store.memory import InMemoryStore
def embed(texts: list[str]) -> list[list[float]]:
# Replace with an actual embedding function or LangChain embeddings object
return [[1.0, 2.0] * len(texts)]
# InMemoryStore saves data to an in-memory dictionary. Use a DB-backed store in production use.
store = InMemoryStore(index={"embed": embed, "dims": 2})
user_id = "my-user"
application_context = "chitchat"
namespace = (user_id, application_context)
store.put(
namespace,
"a-memory",
{
"rules": [
"User likes short, direct language",
"User only speaks English & python",
],
"my-key": "my-value",
},
)
# get the "memory" by ID
item = store.get(namespace, "a-memory")
# search for "memories" within this namespace, filtering on content equivalence, sorted by vector similarity
items = store.search(
namespace, filter={"my-key": "my-value"}, query="language preferences"
)本文轉載自???玄姐聊AGI?? 作者:玄姐

















