Acasă
» domenii
»
Cum să remediezi pierderea memoriei agentului LangChain în conversațiile lungi
Cum să remediezi pierderea memoriei agentului LangChain în conversațiile lungi
Dacă un agent LangChain uită detalii în timpul unei conversații lungi, corectează arhitectura înainte de a mări fereastra de context a modelului. În agenții actuali de tip LangChain v1, continuitatea conversației este construită din două straturi separate: un checkpointer pentru starea pe termen scurt, cu domeniu de aplicare pe fir, și o stocare (store) pentru informațiile pe termen lung care trebuie să supraviețuiască între fire. Conversațiile lungi necesită apoi o a treia preocupare: gestionarea contextului, de obicei prin trunchierea sau rezumarea mesajelor mai vechi înainte ca acestea să copleșească modelul.
Acest ghid urmează documentația oficială LangChain, verificată pe 11 septembrie 2026. Documentația actuală recomandă langchain.agents.create_agent pentru agenții noi și descrie persistența LangGraph ca sistemul de memorie subiacent. Exemplele mai vechi bazate pe ConversationChain, ConversationBufferMemory sau initialize_agent pot apărea încă în materialele legacy, dar ghidul de migrare LangChain v1 a mutat lanțurile legacy și alte funcționalități depreciate în langchain-classic. Vezi ghidul oficial de migrare LangChain v1.
Ilustrație generată de AI: Simptomul este simplu: un fapt a fost furnizat anterior, dar un răspuns ulterior nu îl mai utilizează. Ilustrația este conceptuală, nu o interfață LangChain capturată.
Ce înseamnă de fapt „Pierderea memoriei” în LangChain
Înainte de a modifica codul, separă trei probleme care adesea arată identic din punctul de vedere al utilizatorului.
Simptom
Cauză probabilă
Stratul corect de remediat
Agentul uită după repornirea serverului
Starea a fost stocată doar în memoria procesului
Checkpointer sau stocare persistentă
Agentul uită între două cereri în același chat
Niciun checkpointer, sau a fost utilizat un thread_id diferit
Persistența firului
Agentul își amintește turele inițiale în stocare, dar nu le mai utilizează în chat-uri foarte lungi
Contextul modelului a devenit prea mare sau zgomotos
Rezumare, trunchiere, recuperare
Agentul își amintește o preferință într-un chat, dar nu într-un chat nou
Faptul există doar în starea firului
Stocare pe termen lung
Documentația memoriei pe termen scurt a LangChain definește memoria pe termen scurt ca stare în cadrul unui singur fir. Documentația memoriei pe termen lung definește memoria pe termen lung ca informație care persistă între conversații și sesiuni diferite.
Ilustrație generată de AI: Gândește-te la memoria pe termen scurt ca la starea unui singur fir de conversație. LangChain actual implementează acea continuitate printr-un checkpointer, nu prin clasele de memorie legacy adesea prezentate în tutorialele mai vechi.
Ce ai nevoie înainte de a începe
Ai nevoie de o aplicație LangChain/LangGraph actuală, o integrare cu un model și un loc pentru a persista starea. Pentru un experiment local, InMemorySaver este suficient. Pentru producție, utilizează un checkpointer bazat pe bază de date. Documentația oficială LangChain arată PostgreSQL prin pachetul separat langgraph-checkpoint-postgres.
Menține clare patru identificatori:
ID conversație sau chat: identificatorul pe care aplicația ta îl expune utilizatorilor.
thread_id: cheia de persistență LangGraph utilizată pentru a relua starea unui fir.
ID utilizator: identitatea durabilă utilizată pentru a crea spații de nume pentru memoriile pe termen lung.
Cheie memorie: cheia pentru un element durabil în interiorul unui spațiu de nume al stocării.
Acestea nu ar trebui să fie automat aceeași valoare. Un utilizator poate avea multe fire, iar un fir poate conține multe fapte.
Pasul 1: Reproduce eșecul cu un test cu două cereri
Începe cu cel mai mic test posibil. Cere agentului să țină minte un detaliu unic, apoi invocă-l din nou și cere acel detaliu. Nu testa memoria cu un singur apel invoke(), deoarece modelul poate vedea totul în acea singură cerere, chiar dacă persistența este defectă.
config = {"configurable": {"thread_id": "debug-thread-001"}}
agent.invoke(
{"messages": [{"role": "user", "content": "Ține minte că numele de cod al proiectului meu este Juniper."}]},
config,
)
result = agent.invoke(
{"messages": [{"role": "user", "content": "Care este numele de cod al proiectului meu?"}]},
config,
)
Dacă a doua cerere uită „Juniper”, inspectează configurația checkpointer-ului și thread_id-ul real înainte de a modifica prompturile.
Pasul 2: Adaugă un Checkpointer pentru memoria pe același fir
Un checkpointer persistă instantaneile stării grafului agentului. LangGraph îl utilizează pentru memoria pe termen scurt, recuperarea după întreruperi, fluxurile human-in-the-loop și toleranța la erori. Ghidul actual de persistență descrie checkpointerele ca având domeniu de aplicare pe fir și spune că aplicația accesează starea trecând un thread_id. Vezi ghidul oficial de persistență LangGraph.
InMemorySaver este excelent pentru a confirma că legătura firului tău funcționează, dar stochează checkpointere în RAM. LangGraph avertizează explicit că MemorySaver/InMemorySaver nu persistă între repornirile procesului.
Pasul 3: Menține același thread_id pentru aceeași conversație
Cea mai comună eroare la nivelul aplicației este crearea unui nou thread_id la fiecare cerere HTTP. Baza de date poate funcționa perfect, în timp ce fiecare cerere pornește un fir LangGraph diferit.
De exemplu, să presupunem că front-end-ul tău are ID-ul chat chat_8bf4. Asociază acea valoare determinist cu firul LangGraph și reutilizeaz-o pentru fiecare tură din acel chat. Un chat nou ar trebui să primească un nou ID de fir.
Ilustrație generată de AI: Persistența nu elimină limita de context a modelului. Un fir stabil poate conține mai mult istoric decât ar trebui să primească modelul la fiecare apel.
Nu folosi un singur thread_id permanent pentru toate chat-urile care aparțin aceluiași utilizator. Aceasta fuzionează conversații neînrudite într-un singur flux de stare. Dacă utilizezi PostgreSQL, ghidul actual de depanare LangGraph spune, de asemenea, că thread_id ar trebui să rămână sub 255 de caractere; un UUID sau un hash determinist este mai sigur decât un obiect serializat uriaș.
Pasul 4: Înlocuiește persistența în memorie înainte de producție
Odată ce testul cu două cereri trece, testează o repornire a procesului. Salvează un fapt, oprește aplicația, pornește-o din nou, apoi cere faptul cu același ID de fir. Dacă utilizezi încă InMemorySaver, uitarea este un comportament așteptat.
Documentația oficială privind memoria pe termen scurt arată o configurație de producție bazată pe PostgreSQL utilizând PostgresSaver:
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,
)
Pentru configurarea pachetului documentată în prezent de LangChain, vezi Memoria pe termen scurt. Nu pune credențiale reale de bază de date direct în codul sursă; utilizează sistemul tău normal de gestionare a secretelor.
Ilustrație generată de AI: Un element deosebit de important este stocarea locală a procesului: un checkpointer în memorie este pierdut intenționat după repornire, deci testele de repornire aparțin suitei de teste de memorie.
Pasul 5: Gestionează istoricele lungi în loc să trimiți totul pentru totdeauna
O fereastră de context este cantitatea de context de intrare și ieșire pe care un model o poate gestiona într-un singur apel al modelului. Checkpointing-ul poate păstra o conversație foarte lungă în stocare, dar aceasta nu înseamnă că fiecare mesaj istoric ar trebui trimis înapoi modelului pentru totdeauna.
Ghidul privind memoria pe termen scurt al LangChain spune că istoricele lungi pot depăși fereastra de context a modelului și că, chiar și modelele capabile să accepte întregul istoric pot fi distrase de conținut vechi sau irelevant, cu latență și costuri mai mari. Strategiile documentate sunt trunchierea, ștergerea, rezumarea sau aplicarea unei politici personalizate.
Utilizează rezumarea când detaliile vechi contează încă
SummarizationMiddleware este opțiunea încorporată actuală pentru a înlocui istoricul mai vechi cu un rezumat compact, păstrând în același timp mesajele recente. Declanșatorul său se poate baza pe numărul de tokeni, numărul de mesaje sau o fracțiune din contextul modelului.
Numerele de mai sus sunt o politică de exemplu, nu setări universale. Alege pragurile după măsurarea propriilor prompturi, ieșirilor instrumentelor, limitelor de context ale modelului, latenței și calității rezumatului. Vezi documentația middleware încorporat a LangChain pentru opțiunile de declanșare și păstrare acceptate în prezent.
Ilustrație generată de AI: Testează recuperarea după suficiente ture pentru a activa politica ta de trunchiere sau rezumare; un chat scurt poate ascunde erori de context lung.
Nu trunchia mesajele instrumentelor orb
Dacă implementezi ștergere sau trunchiere personalizată, păstrează o secvență validă de mesaje. LangChain avertizează că mulți furnizori necesită ca un mesaj asistent care conține apeluri de instrumente să fie urmat de mesajele corespunzătoare cu rezultatele instrumentelor. Eliminarea unei jumătăți din acea pereche poate crea erori ale furnizorului sau comportament confuz al modelului.
Pasul 6: Mută faptele durabile într-o stocare pe termen lung
O stocare (store) este stratul de persistență LangGraph pentru datele definite de aplicație în afara stării grafului unui singur fir. Documentația actuală LangChain utilizează stocările pentru informații care ar trebui să fie disponibile între conversații, cum ar fi preferințele utilizatorilor, faptele sau cunoștințele partajate ale aplicației.
Elementele din stocarea pe termen lung sunt documente JSON organizate după un spațiu de nume și o cheie. Un spațiu de nume practic conține adesea un identificator de utilizator sau organizație:
Aceasta este diferită de salvarea întregului transcript. Stochează informația pe care produsul tău o tratează intenționat ca fiind durabilă. Dacă un fapt este privat sau reglementat, aplică politicile tale normale de retenție, autorizare, criptare și ștergere, în loc să presupui că „memoria agentului” este scutită de ele.
Ilustrație generată de AI: Această ilustrație utilizează etichete conceptuale largi, nu nume API literale actuale. Pentru cod nou LangChain v1, utilizează distincția checkpointer/stocare descrisă în text și în documentația oficială.
Utilizează o stocare bazată pe bază de date în producție
Ghidul oficial privind memoria pe termen lung arată atât InMemoryStore, cât și PostgresStore, și menționează explicit că implementarea în memorie ar trebui înlocuită cu o stocare bazată pe bază de date pentru producție. De asemenea, listează integrări de stocare dincolo de PostgreSQL. Utilizează backend-ul care se potrivește cerințelor tale de implementare și operaționale, în loc să selectezi o bază de date vectorială doar pentru că este implicat cuvântul „memorie”.
Adaugă căutare semantică doar când ai nevoie de recuperare vagă
Stocările LangGraph pot fi configurate cu un index astfel încât store.search() să poată recupera elemente prin similaritate semantică. Acest lucru este util când ai multe memorii și nu cunoști cheia exactă. Pentru un set mic de preferințe structurate, căutarea directă spațiu de nume/cheie este adesea mai simplă și mai deterministă.
Pasul 7: Fă căile de citire și scriere a memoriei explicite
Persistența unui element pe termen lung nu garantează că agentul îl va utiliza. Aplicația are în continuare nevoie de o cale de recuperare. Agenții LangChain actuali permit instrumentelor să acceseze stocarea furnizată prin 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"
Poți construi, de asemenea, prompturi dinamice sau middleware care citește starea și memoria durabilă înainte de un apel al modelului. Regula importantă de proiectare este că calea de recuperare ar trebui să fie observabilă și testabilă. „Informația există undeva în baza de date” nu este suficient.
Ilustrație generată de AI: Un test de regresie util cere un fapt anterior după multe ture și verifică dacă răspunsul provine din stratul de memorie intenționat, nu din textul promptului duplicat accidental.
Pasul 8: Testează cele patru limite de memorie separat
O suită de teste de memorie fiabilă ar trebui să acopere mai mult decât „modelul și-a amintit numele meu o dată”. Utilizează cel puțin aceste patru cazuri:
Test
Rezultat așteptat
Două invocări, același ID de fir
Informația cu domeniu de aplicare pe fir este disponibilă
Două invocări, ID-uri de fir diferite
Istoricul firului pe termen scurt nu se scurge
Repornirea aplicației, același ID de fir cu checkpointer persistent
Starea firului poate fi reluată
Fir nou, același utilizator cu stocare pe termen lung
Doar faptele durabile stocate intenționat pot fi recuperate
Apoi adaugă un test de conversație lungă care depășește pragul tău de rezumare. Afirmă că faptele durabile importante supraviețuiesc, secvențele recente de apeluri de instrumente rămân valide, iar dimensiunea promptului rămâne în bugetul de context țintă.
Ilustrație generată de AI: Tratează aceasta ca pe o listă de verificare QA conceptuală. Arhitectura actuală LangChain v1 ar trebui validată împotriva API-urilor oficiale checkpointer, stocare și middleware, nu a exemplelor de clase de memorie legacy.
O arhitectură de producție minimală
Pentru multe aplicații de agenți, o proiectare robustă arată astfel:
API-ul primește user_id, conversation_id și noul mesaj al utilizatorului.
Aplicația asociază conversation_id cu un thread_id LangGraph stabil.
Un checkpointer persistent restaurează starea firului.
O stocare pe termen lung recuperează doar faptele durabile ale utilizatorului sau ale aplicației necesare pentru cerere.
Rezumarea sau trunchierea menține istoricul orientat către model în cadrul unui buget de context măsurat.
Agentul rulează instrumente și modelul.
Checkpointer-ul comite starea actualizată a firului.
Doar faptele aprobate sunt scrise în stocarea pe termen lung.
Dacă implementezi prin LangGraph Agent Server, ghidul actual de persistență spune că serverul gestionează automat infrastructura de persistență, deci nu duplica acel strat fără a verifica modelul de implementare.
Greșeli comune care fac memoria să pară defectă
Generarea unui nou thread_id pentru fiecare cerere
Aceasta creează o nouă stare de conversație la fiecare tură. Loghează ID-ul firului lângă ID-ul chat-ului aplicației tale și verifică reutilizarea.
Utilizarea InMemorySaver într-un serviciu cu mai mulți lucrători sau repornibil
Starea locală RAM dispare cu procesul și poate să nu fie partajată între lucrători. Utilizează un backend persistent pentru continuitatea în producție.
Presupunerea că un checkpointer rezolvă problema ferestrei de context
Un checkpointer păstrează starea; nu garantează că un transcript în creștere continuă este util modelului. Adaugă o politică explicită de gestionare a contextului.
Punerea fiecărui fapt istoric în prompt
Mai mult context nu este automat context mai bun. Recuperează informația relevantă pentru tura curentă și păstrează continuitatea conversațională recentă separat.
Tratarea rezumatelor ca pe o bază de date perfectă
Rezumatele sunt reprezentări comprimate generate de model. Dacă un fapt trebuie să fie exact—un identificator de cont, o constrângere contractuală, o preferință aprobată de utilizator sau o stare de flux de lucru—stochează-l ca date structurate, în loc să speri că supraviețuiește rezumărilor repetate.
Amestecarea domeniilor de aplicare pe termen scurt și lung
Istoricul firului nu ar trebui să devină silențios un profil global al utilizatorului. Invers, o preferință a utilizatorului destinată să îl urmeze între chat-uri nu ar trebui să trăiască doar într-un singur fir.
Copierea tutorialelor de memorie pre-v1 fără a verifica importurile
Dacă un exemplu pornește de la lanțuri legacy sau clase vechi de memorie, compară-l cu migrarea v1 actuală și documentația de memorie înainte de a-l utiliza într-o aplicație nouă.
Listă de verificare pentru depanare
Confirmă că agentul a fost creat cu un checkpointer.
Loghează și compară thread_id între cererile consecutive.
Inspectează starea firului stocat înainte de a învinovăți modelul.
Repornește procesul și repetă testul pe același fir.
Înlocuiește InMemorySaver cu un checkpointer persistent pentru producție.
Măsoară creșterea mesajelor/tokenilor în chat-urile lungi.
Activează rezumarea sau trunchierea înainte ca istoricul să devină excesiv.
Menține secvențele de apel/rezultat ale instrumentelor valide atunci când elimini mesaje.
Mută faptele între fire într-o stocare pe termen lung cu spațiu de nume.
Testează un fir nou pentru același utilizator pentru a verifica recuperarea pe termen lung intenționată.
Testează un utilizator diferit pentru a verifica izolarea memoriei.
Urmărește ce elemente de memorie au fost recuperate pentru fiecare răspuns.
Concluzie
Pierderea memoriei agentului LangChain este rar rezolvată de o singură fereastră de context mai mare. Mai întâi fă starea firului persistentă cu un checkpointer și un thread_id stabil. Apoi controlează istoricele lungi cu trunchiere sau SummarizationMiddleware. În final, plasează faptele care trebuie să supraviețuiască între conversații într-o stocare pe termen lung cu spațiu de nume și recuperează-le deliberat.
Această separare îți oferă ceva mult mai util decât „memoria”: un sistem pe care îl poți reporni, scala, testa, audita și analiza când un utilizator întreabă: „De ce a uitat agentul?”