如何修復 LangChain 代理在長對話中的記憶遺失問題

如果 LangChain 代理在長對話中遺忘細節,請先修復架構,而不是增加模型的上下文視窗。在目前的 LangChain v1 風格代理中,對話連續性由兩個獨立的層級構成:用於短期、執行緒範圍狀態的檢查點器(checkpointer),以及必須跨執行緒存活的長期資訊儲存庫(store)。長對話還需要處理第三個問題:上下文管理,通常是在舊訊息壓垮模型之前進行修剪或摘要。

本指南遵循於 2026 年 9 月 11 日查閱的 LangChain 官方文件。目前的文件建議新代理使用 langchain.agents.create_agent,並將 LangGraph 持久化描述為底層的記憶系統。基於 ConversationChainConversationBufferMemoryinitialize_agent 的舊範例可能仍出現在遺留資料中,但 LangChain 的 v1 遷移指南已將遺留鏈和其他棄用功能移至 langchain-classic。請參閱官方 LangChain v1 遷移指南

LangChain 代理在長對話中遺忘早期使用者細節的插圖
AI 生成插圖:症狀很簡單:之前提供了一個事實,但後來的回答不再使用它。此插圖為概念性示意,並非擷取自 LangChain 介面。

LangChain 中「記憶遺失」的真正含義

在修改程式碼之前,請區分三個從使用者角度來看往往看起來相同的問題。

症狀可能原因應修復的正確層級
伺服器重啟後代理遺忘狀態僅存儲在程序記憶體中持久化檢查點器或儲存庫
同一聊天中的兩個請求之間代理遺忘沒有檢查點器,或使用了不同的 thread_id執行緒持久化
代理在存儲中記得早期輪次,但在極長聊天中停止使用它們模型上下文變得過大或雜訊過多摘要、修剪、檢索
代理在一個聊天中記得偏好,但在新聊天中不記得該事實僅存在於執行緒狀態中長期儲存庫

LangChain 的短期記憶文件將短期記憶定義為單一執行緒內的狀態。其長期記憶文件將長期記憶定義為跨不同對話和會話持續存在的資訊。

對話訊息流入代理記憶的概念圖
AI 生成插圖:將短期記憶視為單一對話執行緒的狀態。目前的 LangChain 透過檢查點器而非舊教程中常顯示的遺留記憶類別來實現這種連續性。

開始前您需要準備的內容

您需要一個當前的 LangChain/LangGraph 應用程式、一個模型整合,以及一個用於持久化狀態的地方。對於本地實驗,InMemorySaver 就足夠了。對於生產環境,請使用資料庫支援的檢查點器。LangChain 的官方文件展示了透過獨立的 langgraph-checkpoint-postgres 套件使用 PostgreSQL。

請保持四個識別符號清晰:

  • 對話或聊天 ID:您的應用程式向使用者暴露的識別符號。
  • thread_id用於恢復單一執行緒狀態的 LangGraph 持久化鍵。
  • 使用者 ID:用於命名空間長期記憶的持久身份。
  • 記憶鍵:儲存庫命名空間內單一持久項目的鍵。

它們不應自動成為相同的值。一個使用者可以有多個執行緒,而一個執行緒可以包含多個事實。

步驟 1:透過雙請求測試重現失敗

從最小的可能測試開始。要求代理記住一個獨特的細節,然後再次呼叫它並詢問該細節。不要透過單個 invoke() 呼叫來測試記憶,因為即使持久化損壞,模型也能在那一個請求中看到所有內容。

config = {"configurable": {"thread_id": "debug-thread-001"}}

agent.invoke(
    {"messages": [{"role": "user", "content": "Remember that my project codename is Juniper."}]},
    config,
)

result = agent.invoke(
    {"messages": [{"role": "user", "content": "What is my project codename?"}]},
    config,
)

如果第二個請求遺忘了「Juniper」,請在修改提示之前檢查檢查點器配置和實際的 thread_id

步驟 2:為同一執行緒記憶添加檢查點器

檢查點器(checkpointer)持久化代理圖狀態的快照。LangGraph 將其用於短期記憶、中斷恢復、人在迴圈流程以及容錯。目前的持久化指南將檢查點器描述為執行緒範圍,並說明應用程式透過傳遞 thread_id 來存取狀態。請參閱官方 LangGraph 持久化指南

from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()

agent = create_agent(
    model="your-provider:your-model",
    tools=[],
    checkpointer=checkpointer,
)

config = {"configurable": {"thread_id": "customer-42:case-7"}}

InMemorySaver 非常適合確認您的執行緒連線是否正常運作,但它將檢查點存儲在 RAM 中。LangGraph 明確警告 MemorySaver/InMemorySaver 不會在程序重啟後持久化。

步驟 3:為同一對話保持相同的 thread_id

最常見的應用程式層級錯誤是在每個 HTTP 請求上建立新的 thread_id。資料庫可能運作完美,但每個請求都啟動了不同的 LangGraph 執行緒。

例如,假設您的前端有聊天 ID chat_8bf4。將該值確定性地映射到 LangGraph 執行緒,並在該聊天的每一輪中重複使用它。新聊天應接收新的執行緒 ID。

模型上下文視窗劃分為指令、聊天歷史、當前訊息和工作上下文的插圖
AI 生成插圖:持久化並不能消除模型上下文限制。穩定的執行緒可能包含比模型每次呼叫應接收的更多的歷史記錄。

不要為屬於同一使用者的所有聊天使用一個永久的 thread_id。這會將不相關的對話合併到一個狀態流中。如果您使用 PostgreSQL,LangGraph 目前的疑難排解指南也指出 thread_id 應保持在 255 個字元以內;UUID 或確定性雜湊比巨大的序列化物件更安全。

步驟 4:在生產環境前替換記憶體持久化

一旦雙請求測試通過,請測試程序重啟。儲存一個事實,停止應用程式,再次啟動,然後使用相同的執行緒 ID 詢問該事實。如果您仍使用 InMemorySaver,遺忘是預期行為。

官方短期記憶文件展示了使用 PostgresSaver 的 PostgreSQL 支援的生產環境設置:

from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver

DB_URI = "postgresql://user:password@db-host/app"

with PostgresSaver.from_conn_string(DB_URI) as checkpointer:
    checkpointer.setup()
    agent = create_agent(
        model="your-provider:your-model",
        tools=[],
        checkpointer=checkpointer,
    )

關於 LangChain 目前記錄的套件設置,請參閱短期記憶。不要將真實的資料庫憑證直接放在原始碼中;請使用您正常的秘密管理系統。

不可靠代理記憶常見原因的圖解清單
AI 生成插圖:一個特別重要的項目是程序本地存儲:記憶體檢查點器在重啟後會故意丟失,因此重啟測試屬於記憶測試套件的一部分。

步驟 5:管理長歷史記錄,而不是永遠發送所有內容

上下文視窗(context window)是模型在單次模型呼叫中可以處理的輸入和輸出上下文量。檢查點可以在存儲中保留非常長的對話,但這並不意味著每個歷史訊息都應該永遠發送回模型。

LangChain 的短期記憶指南指出,長歷史記錄可能會超過模型上下文視窗,即使能夠接受完整歷史記錄的模型也可能被過時或離題的內容分散注意力,從而導致更高的延遲和成本。記錄的策略包括修剪、刪除、摘要或應用自定義策略。

當舊細節仍然重要時使用摘要

SummarizationMiddleware 是目前的內建選項,用於用緊湊的摘要替換較舊的歷史記錄,同時保留最近的訊息。其觸發條件可以基於令牌數量、訊息數量或模型上下文的比例。

from langchain.agents import create_agent
from langchain.agents.middleware import SummarizationMiddleware

agent = create_agent(
    model="your-provider:your-model",
    tools=[],
    checkpointer=checkpointer,
    middleware=[
        SummarizationMiddleware(
            model="your-provider:summary-model",
            trigger=("fraction", 0.8),
            keep=("fraction", 0.3),
        )
    ],
)

上述數字是示例策略,並非通用設置。在測量您自己的提示、工具輸出、模型上下文限制、延遲和摘要品質後選擇閾值。請參閱 LangChain 的內建中間件文件以了解目前支援的觸發和保留選項。

測試代理在多次對話輪次後是否能回憶事實的插圖
AI 生成插圖:在足夠多的輪次後測試回憶,以啟動您的修剪或摘要策略;短聊天可能會隱藏長上下文錯誤。

不要盲目修剪工具訊息

如果您實施自定義刪除或修剪,請保留有效的訊息序列。LangChain 警告許多供應商要求包含工具呼叫的助理訊息必須後跟相應的工具結果訊息。移除該配對的一半可能會導致供應商錯誤或令人困惑的模型行為。

步驟 6:將持久事實移至長期儲存庫

儲存庫(store)是 LangGraph 用於單一執行緒圖狀態之外的應用程式定義資料的持久化層。目前的 LangChain 文件使用儲存庫來存儲應跨對話可用的資訊,例如使用者偏好、事實或共享應用程式知識。

長期儲存庫項目是透過命名空間(namespace)鍵(key)組織的 JSON 文件。實用的命名空間通常包含使用者或組織識別符號:

namespace = ("users", user_id, "preferences")
store.put(
    namespace,
    "response_style",
    {"value": "concise", "source": "explicit_user_request"},
)

這與儲存整個對話記錄不同。儲存您的產品故意視為持久化的資訊。如果事實是私有的或受監管的,請應用您正常的保留、授權、加密和刪除政策,而不是假設「代理記憶」可以豁免於這些政策。

包含資料庫持久化和上下文管理概念的 AI 生成生產記憶清單
AI 生成插圖:此插圖使用廣泛的概念標籤,而非字面上的當前 API 名稱。對於新的 LangChain v1 程式碼,請使用文字和官方文件中描述的檢查點器/儲存庫區別。

在生產環境中使用資料庫支援的儲存庫

官方長期記憶指南展示了 InMemoryStorePostgresStore,並明確指出記憶體實現在生產環境中應由資料庫支援的儲存庫替換。它還列出了 PostgreSQL 之外的儲存庫整合。請使用適合您部署和運營要求的後端,而不是僅僅因為涉及「記憶」一詞就選擇向量資料庫。

僅在需要模糊回憶時添加語義搜尋

LangGraph 儲存庫可以配置索引,以便 store.search() 可以透過語義相似度檢索項目。當您有很多記憶且不知道確切鍵時,這很有用。對於一組結構化偏好,直接命名空間/鍵查找通常更簡單且更具確定性。

步驟 7:使記憶讀寫路徑明確

持久化長期項目並不保證代理會使用它。應用程式仍然需要檢索路徑。目前的 LangChain 代理允許工具透過 ToolRuntime 存取提供的儲存庫。

from dataclasses import dataclass
from langchain.tools import tool, ToolRuntime

@dataclass
class Context:
    user_id: str

@tool
def get_response_style(runtime: ToolRuntime[Context]) -> str:
    store = runtime.store
    if store is None:
        return "No memory store configured"

    namespace = ("users", runtime.context.user_id, "preferences")
    item = store.get(namespace, "response_style")
    return item.value["value"] if item else "default"

您還可以構建動態提示或中間件,在模型呼叫之前讀取狀態和持久記憶。重要的設計規則是檢索路徑應該是可觀察和可測試的。「資訊存在於資料庫的某個地方」是不夠的。

使用記憶的使用者偏好進行長對話回憶測試的插圖
AI 生成插圖:有用的回歸測試會在多輪後詢問早期事實,並驗證答案來自預期的記憶層,而不是來自意外重複的提示文字。

步驟 8:分別測試四個記憶邊界

可靠的記憶測試套件應涵蓋的不僅是「模型記得我的名字一次」。請至少使用以下四個案例:

測試預期結果
兩次呼叫,相同執行緒 ID執行緒範圍資訊可用
兩次呼叫,不同執行緒 ID短期執行緒歷史不會洩漏
應用程式重啟,相同執行緒 ID 與持久化檢查點器執行緒狀態可以恢復
新執行緒,相同使用者與長期儲存庫僅能回憶故意儲存的持久事實

然後添加一個超過您摘要閾值的長對話測試。斷言重要的持久事實存活,最近的工具呼叫序列保持有效,且提示大小保持在您的目標預算內。

測試記憶、上下文大小、持久化和過時實施的最佳實踐表格
AI 生成插圖:將其視為概念性 QA 清單。當前的 LangChain v1 架構應針對官方檢查點器、儲存庫和中間件 API 進行驗證,而不是遺留記憶類別範例。

最小生產架構

對於許多代理應用程式,穩健的設計如下所示:

  1. API 接收 user_idconversation_id 和新的使用者訊息。
  2. 應用程式將 conversation_id 映射到穩定的 LangGraph thread_id
  3. 持久化檢查點器恢復執行緒狀態。
  4. 長期儲存庫僅檢索請求所需的持久使用者或應用程式事實。
  5. 摘要或修剪使面向模型的歷史記錄保持在測量的上下文預算內。
  6. 代理執行工具和模型。
  7. 檢查點器提交更新的執行緒狀態。
  8. 僅將批准的事實寫入長期儲存庫。

如果您透過 LangGraph Agent Server 部署,目前的持久化指南指出伺服器會自動處理持久化基礎設施,因此在未檢查部署模型之前不要重複該層。

使記憶看起來損壞的常見錯誤

為每個請求生成新的 thread_id

這會在每一輪建立新的對話狀態。在您的應用程式聊天 ID 旁邊記錄執行緒 ID 並驗證重複使用。

在多工作程序或可重啟服務中使用 InMemorySaver

RAM 本地狀態會隨程序消失,且可能不會在工作程序之間共享。使用持久化後端以確保生產環境連續性。

假設檢查點器解決了上下文視窗問題

檢查點器保留狀態;它並不保證不斷增長的對話記錄對模型有用。添加明確的上下文管理策略。

將每個歷史事實放入提示中

更多的上下文並不自動意味著更好的上下文。檢索與當前輪次相關的資訊,並單獨保留最近的對話連續性。

將摘要視為完美資料庫

摘要是壓縮的模型生成表示。如果事實必須精確——帳戶識別符號、合約約束、使用者批准的偏好或工作流程狀態——請將其存儲為結構化資料,而不是希望它在重複摘要中存活。

混合短期和長期範圍

執行緒歷史不應靜默地成為全域使用者檔案。相反,旨在跨聊天跟隨使用者的使用者偏好不應僅存在於一個執行緒中。

複製 v1 之前的記憶教程而不檢查匯入

如果範例從遺留鏈或舊記憶類別開始,請在新應用程式中使用之前將其與當前的 v1 遷移和記憶文件進行比較。

除錯清單

  • 確認代理是使用檢查點器建立的。
  • 記錄並比較連續請求之間的 thread_id
  • 在責怪模型之前檢查存儲的執行緒狀態。
  • 重啟程序並重複相同的執行緒測試。
  • 在生產環境中用持久化檢查點器替換 InMemorySaver
  • 測量長聊天中的訊息/令牌增長。
  • 在歷史記錄變得過多之前啟用摘要或修剪。
  • 在移除訊息時保持工具呼叫/結果序列有效。
  • 將跨執行緒事實移至命名空間長期儲存庫。
  • 測試相同使用者的新執行緒以驗證故意的長期回憶。
  • 測試不同的使用者以驗證記憶隔離。
  • 追蹤每個答案檢索了哪些記憶項目。

結論

LangChain 代理記憶遺失很少能透過一個更大的上下文視窗解決。首先透過檢查點器和穩定的 thread_id 使執行緒狀態持久化。然後透過修剪或 SummarizationMiddleware 控制長歷史記錄。最後,將必須跨對話存活的事實放在命名空間長期儲存庫中,並故意檢索它們。

這種分離為您提供了比「記憶」更有用的東西:一個您可以重啟、擴展、測試、審計並在使用者詢問「為什麼代理忘記了?」時進行推理的系統。

留下評論

如何阻止 CrewAI 代理執行冗餘任務:實用去重指南

如何阻止 CrewAI 代理執行冗餘任務:實用去重指南

透過修復任務所有權、依賴關係、委託、重試、流程觸發器、狀態持久性、快取和冪等性,防止 CrewAI 代理重複工作。

HubSpot Free CRM vs Zoho CRM for Solo Real Estate Agents: Which Fits Better in 2026?

HubSpot Free CRM vs Zoho CRM for Solo Real Estate Agents: Which Fits Better in 2026?

Compare HubSpot Free CRM and Zoho CRM Free for solo real estate agents, including contact limits, pipelines, email, automation, mobile tools, and upgrade tradeoffs.

如何在 Windows 11 上使用 LM Studio 離線執行 DeepSeek

如何在 Windows 11 上使用 LM Studio 離線執行 DeepSeek

在 Windows 11 上使用 LM Studio 本地執行 DeepSeek。了解適合一般 PC 的模型、如何下載與載入、驗證離線使用,以及解決常見問題。

如何利用提示詞壓縮技術將 API Token 成本降低 50%

如何利用提示詞壓縮技術將 API Token 成本降低 50%

透過四種實用的提示詞壓縮技術、緩存友好的佈局、結構化輸出以及保留品質的評估計畫,來降低 LLM API 成本。

如何使用 n8n 和 Claude 建立免費的 AI 內容再利用流程(真正免費的部分是什麼)

如何使用 n8n 和 Claude 建立免費的 AI 內容再利用流程(真正免費的部分是什麼)

使用自託管的 n8n 和 Claude 建立可免費託管的 AI 內容再利用流程,包含結構化輸出、審核閘門以及現實的 API 成本指南。

如何將本地 Ollama 模型連接至 Obsidian 以進行個人知識管理

如何將本地 Ollama 模型連接至 Obsidian 以進行個人知識管理

將 Ollama 連接至 Obsidian 以實現本地 AI 聊天與感知資料庫的 PKM。學習設定、品質檢查、本地嵌入、隱私限制,以及何時更換模型。

逐步指南:使用 AI 代理自動化每週競爭對手監控

逐步指南:使用 AI 代理自動化每週競爭對手監控

使用 AI 代理、網路搜尋、有證據支持的變更偵測、GitHub Actions 排程以及人工審核,建立每週競爭對手監控工作流程。

Claude 系統提示詞:如何為技術文件設定語氣界線

Claude 系統提示詞:如何為技術文件設定語氣界線

學習如何使用 Claude 系統提示詞,為一致的技術文件設定清晰的語氣、受眾、格式、不確定性及風格界線。

如何保護您的本地 RAG 系統免受提示注入攻擊

如何保護您的本地 RAG 系統免受提示注入攻擊

透過針對資料攝取、檢索、存取控制、提示邊界、工具權限、輸出驗證及紅隊測試的實用控制措施,保護本地 RAG 系統免受提示注入攻擊。

如何修復 Outlook「無法傳送郵件但可接收」錯誤

如何修復 Outlook「無法傳送郵件但可接收」錯誤

Outlook 能收信但無法寄信?按實用順序診斷寄件匣、離線模式、密碼、SMTP 設定、帳戶限制、設定檔及增益集。