Come risolvere la perdita di memoria degli agenti LangChain nelle conversazioni lunghe

Se un agente LangChain dimentica dettagli durante una conversazione lunga, correggete l'architettura prima di aumentare la finestra di contesto del modello. Negli attuali agenti in stile LangChain v1, la continuità della conversazione è costruita su due livelli separati: un checkpointer per lo stato a breve termine con ambito di thread e un store (archivio) per le informazioni a lungo termine che devono sopravvivere tra i thread. Le conversazioni lunghe richiedono poi una terza attenzione: la gestione del contesto, solitamente tramite il taglio o il riassunto dei messaggi più vecchi prima che sovraccarichino il modello.

Questa guida segue la documentazione ufficiale di LangChain verificata l'11 settembre 2026. Gli attuali documenti raccomandano langchain.agents.create_agent per i nuovi agenti e descrivono la persistenza LangGraph come il sistema di memoria sottostante. Esempi più vecchi basati su ConversationChain, ConversationBufferMemory o initialize_agent possono ancora apparire in materiale legacy, ma la guida alla migrazione di LangChain v1 ha spostato le catene legacy e altre funzionalità deprecate in langchain-classic. Vedere la guida ufficiale alla migrazione di LangChain v1.

Illustrazione di un agente LangChain che dimentica un dettaglio utente precedente in una conversazione lunga
Illustrazione generata da AI: Il sintomo è semplice: un fatto è stato fornito in precedenza, ma una risposta successiva non lo utilizza più. L'illustrazione è concettuale, non un'interfaccia LangChain catturata.

Cosa significa realmente "Perdita di memoria" in LangChain

Prima di modificare il codice, separate tre problemi che spesso appaiono identici dal punto di vista dell'utente.

SintomoCausa probabileLivello corretto da correggere
L'agente dimentica dopo il riavvio del serverLo stato era memorizzato solo nella memoria del processoCheckpointer o store persistente
L'agente dimentica tra due richieste nella stessa chatNessun checkpointer, o è stato utilizzato un thread_id diversoPersistenza del thread
L'agente ricorda le prime interazioni nello storage ma smette di usarle in chat molto lungheIl contesto del modello è diventato troppo grande o rumorosoRiassunto, taglio, recupero
L'agente ricorda una preferenza in una chat ma non in una nuova chatIl fatto esiste solo nello stato del threadStore a lungo termine

La documentazione sulla memoria a breve termine di LangChain definisce la memoria a breve termine come lo stato all'interno di un singolo thread. La sua documentazione sulla memoria a lungo termine definisce la memoria a lungo termine come informazioni che persistono attraverso diverse conversazioni e sessioni.

Diagramma concettuale dei messaggi di conversazione che fluiscono nella memoria dell'agente
Illustrazione generata da AI: Pensate alla memoria a breve termine come allo stato di un singolo thread di conversazione. L'attuale LangChain implementa quella continuità attraverso un checkpointer piuttosto che le classi di memoria legacy spesso mostrate nei tutorial più vecchi.

Cosa vi serve prima di iniziare

Vi serve un'applicazione LangChain/LangGraph attuale, un'integrazione del modello e un posto dove persistere lo stato. Per un esperimento locale, InMemorySaver è sufficiente. Per la produzione, utilizzate un checkpointer basato su database. I documenti ufficiali di LangChain mostrano PostgreSQL attraverso il pacchetto separato langgraph-checkpoint-postgres.

Mantenete chiari quattro identificatori:

  • ID conversazione o chat: l'identificatore che la vostra applicazione espone agli utenti.
  • thread_id: la chiave di persistenza LangGraph utilizzata per riprendere lo stato di un thread.
  • ID utente: l'identità durevole utilizzata per namespace le memorie a lungo termine.
  • Chiave di memoria: la chiave per un singolo elemento durevole all'interno di un namespace dello store.

Non dovrebbero automaticamente avere lo stesso valore. Un utente può avere molti thread, e un thread può contenere molti fatti.

Passaggio 1: Riprodurre il fallimento con un test a due richieste

Iniziate con il test più piccolo possibile. Chiedete all'agente di ricordare un dettaglio unico, poi invocatelo di nuovo e chiedete quel dettaglio. Non testate la memoria con una singola chiamata invoke() perché il modello può vedere tutto in quell'unica richiesta anche quando la persistenza è rotta.

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,
)

Se la seconda richiesta dimentica "Juniper", ispezionate la configurazione del checkpointer e l'effettivo thread_id prima di modificare i prompt.

Passaggio 2: Aggiungere un Checkpointer per la memoria dello stesso thread

Un checkpointer persiste gli snapshot dello stato del grafo dell'agente. LangGraph lo utilizza per la memoria a breve termine, il recupero dalle interruzioni, i flussi human-in-the-loop e la tolleranza ai guasti. L'attuale guida alla persistenza descrive i checkpointers come con ambito di thread e afferma che l'applicazione accede allo stato passando un thread_id. Vedere la guida ufficiale alla persistenza di 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 è eccellente per confermare che il vostro collegamento del thread funziona, ma memorizza i checkpoint nella RAM. LangGraph avverte esplicitamente che MemorySaver/InMemorySaver non persistono attraverso i riavvii del processo.

Passaggio 3: Mantenere lo stesso thread_id per la stessa conversazione

Il bug più comune a livello di applicazione è creare un nuovo thread_id su ogni richiesta HTTP. Il database potrebbe funzionare perfettamente mentre ogni richiesta avvia un diverso thread LangGraph.

Ad esempio, supponiamo che il vostro front-end abbia l'ID chat chat_8bf4. Mappate quel valore deterministico al thread LangGraph e riutilizzatelo per ogni turno in quella chat. Una nuova chat dovrebbe ricevere un nuovo ID thread.

Illustrazione della finestra di contesto del modello divisa tra istruzioni, cronologia chat, messaggio corrente e contesto di lavoro
Illustrazione generata da AI: La persistenza non rimuove il limite di contesto del modello. Un thread stabile può contenere più cronologia di quella che il modello dovrebbe ricevere su ogni chiamata.

Non utilizzate un thread_id permanente per tutte le chat appartenenti allo stesso utente. Questo fonde conversazioni non correlate in un unico flusso di stato. Se utilizzate PostgreSQL, l'attuale guida alla risoluzione dei problemi di LangGraph afferma anche che thread_id dovrebbe rimanere sotto i 255 caratteri; un UUID o un hash deterministico è più sicuro di un enorme oggetto serializzato.

Passaggio 4: Sostituire la persistenza in memoria prima della produzione

Una volta superato il test a due richieste, testate un riavvio del processo. Salvate un fatto, fermate l'applicazione, avviatela di nuovo, poi chiedete il fatto con lo stesso ID thread. Se utilizzate ancora InMemorySaver, la dimenticanza è un comportamento atteso.

I documenti ufficiali sulla memoria a breve termine mostrano una configurazione di produzione supportata da PostgreSQL utilizzando 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,
    )

Per la configurazione del pacchetto attualmente documentata da LangChain, vedere Memoria a breve termine. Non mettete credenziali di database reali direttamente nel codice sorgente; utilizzate il vostro normale sistema di gestione dei segreti.

Checklist illustrata delle cause comuni di memoria dell'agente inaffidabile
Illustrazione generata da AI: Un elemento particolarmente importante è l'archiviazione locale al processo: un checkpointer in memoria viene intenzionalmente perso dopo il riavvio, quindi i test di riavvio appartengono alla suite di test della memoria.

Passaggio 5: Gestire le cronologie lunghe invece di inviare tutto per sempre

Una finestra di contesto è la quantità di contesto di input e output che un modello può gestire in una singola chiamata al modello. Il checkpointing può preservare una conversazione molto lunga nello storage, ma ciò non significa che ogni messaggio storico dovrebbe essere inviato al modello per sempre.

La guida sulla memoria a breve termine di LangChain afferma che le cronologie lunghe possono superare la finestra di contesto del modello e che anche i modelli capaci di accettare la cronologia completa possono essere distratti da contenuti obsoleti o fuori tema, con maggiore latenza e costo. Le strategie documentate sono il taglio, l'eliminazione, il riassunto o l'applicazione di una politica personalizzata.

Utilizzare il riassunto quando i dettagli vecchi contano ancora

SummarizationMiddleware è l'opzione integrata attuale per sostituire la cronologia più vecchia con un riassunto compatto mantenendo i messaggi recenti. Il suo trigger può essere basato sul conteggio dei token, sul conteggio dei messaggi o su una frazione del contesto del modello.

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),
        )
    ],
)

I numeri sopra sono un esempio di politica, non impostazioni universali. Scegliete le soglie dopo aver misurato i vostri prompt, gli output degli strumenti, i limiti di contesto del modello, la latenza e la qualità del riassunto. Vedere la documentazione del middleware integrato di LangChain per le opzioni di trigger e keep attualmente supportate.

Illustrazione del test per verificare se un agente può ricordare un fatto dopo molti turni di conversazione
Illustrazione generata da AI: Testate il richiamo dopo abbastanza turni da attivare la vostra politica di taglio o riassunto; una chat breve può nascondere bug di contesto lungo.

Non tagliare i messaggi degli strumenti alla cieca

Se implementate un'eliminazione o un taglio personalizzato, preservate una sequenza di messaggi valida. LangChain avverte che molti provider richiedono che un messaggio dell'assistente contenente chiamate agli strumenti sia seguito dai corrispondenti messaggi di risultato degli strumenti. Rimuovere una metà di quella coppia può creare errori del provider o comportamenti confusi del modello.

Passaggio 6: Spostare i fatti durevoli in uno Store a lungo termine

Uno store è il livello di persistenza di LangGraph per i dati definiti dall'applicazione al di fuori dello stato del grafo di un singolo thread. Gli attuali documenti LangChain utilizzano gli store per informazioni che dovrebbero essere disponibili attraverso le conversazioni, come preferenze utente, fatti o conoscenza condivisa dell'applicazione.

Gli elementi dello store a lungo termine sono documenti JSON organizzati da un namespace e una chiave. Un namespace pratico spesso contiene un identificatore utente o organizzazione:

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

Questo è diverso dal salvare l'intera trascrizione. Memorizzate le informazioni che il vostro prodotto tratta intenzionalmente come durevoli. Se un fatto è privato o regolamentato, applicate le vostre normali politiche di conservazione, autorizzazione, crittografia ed eliminazione piuttosto che assumere che la "memoria dell'agente" ne sia esente.

Checklist di memoria di produzione generata da AI con idee di persistenza del database e gestione del contesto
Illustrazione generata da AI: Questa illustrazione utilizza etichette concettuali ampie piuttosto che nomi API attuali letterali. Per nuovo codice LangChain v1, utilizzate la distinzione checkpointer/store descritta nel testo e nei documenti ufficiali.

Utilizzare uno store basato su database in produzione

La guida ufficiale sulla memoria a lungo termine mostra sia InMemoryStore che PostgresStore, e nota esplicitamente che l'implementazione in memoria dovrebbe essere sostituita da uno store basato su database per la produzione. Elenca anche integrazioni dello store oltre a PostgreSQL. Utilizzate il backend che si adatta ai vostri requisiti di distribuzione e operativi piuttosto che selezionare un database vettoriale semplicemente perché la parola "memoria" è coinvolta.

Aggiungere ricerca semantica solo quando si necessita di richiamo sfocato

Gli store LangGraph possono essere configurati con un indice così che store.search() possa recuperare elementi per similarità semantica. Questo è utile quando avete molte memorie e non conoscete la chiave esatta. Per un piccolo insieme di preferenze strutturate, la ricerca diretta namespace/chiave è spesso più semplice e deterministica.

Passaggio 7: Rendere espliciti i percorsi di lettura e scrittura della memoria

Persistere un elemento a lungo termine non garantisce che l'agente lo utilizzi. L'applicazione ha ancora bisogno di un percorso di recupero. Gli attuali agenti LangChain permettono agli strumenti di accedere allo store fornito attraverso 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"

Potete anche costruire prompt dinamici o middleware che leggono lo stato e la memoria durevole prima di una chiamata al modello. La regola di progettazione importante è che il percorso di recupero dovrebbe essere osservabile e testabile. "L'informazione esiste da qualche parte nel database" non è sufficiente.

Illustrazione di un test di richiamo di conversazione lunga utilizzando una preferenza utente ricordata
Illustrazione generata da AI: Un utile test di regressione chiede un fatto precedente dopo molti turni e verifica che la risposta provenga dall'inteso livello di memoria, non da testo del prompt accidentalmente duplicato.

Passaggio 8: Testare i quattro confini della memoria separatamente

Una suite di test di memoria affidabile dovrebbe coprire più di "il modello ha ricordato il mio nome una volta". Utilizzate almeno questi quattro casi:

TestRisultato atteso
Due invocazioni, stesso ID threadLe informazioni con ambito di thread sono disponibili
Due invocazioni, diversi ID threadLa cronologia del thread a breve termine non trapela
Riavvio dell'applicazione, stesso ID thread con checkpointer persistenteLo stato del thread può riprendere
Nuovo thread, stesso utente con store a lungo termineSolo i fatti durevoli intenzionalmente memorizzati possono essere richiamati

Poi aggiungete un test di conversazione lunga che supera la vostra soglia di riassunto. Affermate che i fatti durevoli importanti sopravvivono, le sequenze recenti di chiamate agli strumenti rimangono valide e la dimensione del prompt rimane entro il vostro budget di contesto target.

Tabella delle migliori pratiche per testare memoria, dimensione del contesto, persistenza e implementazioni obsolete
Illustrazione generata da AI: Trattate questo come una checklist QA concettuale. L'attuale architettura LangChain v1 dovrebbe essere validata contro le API ufficiali di checkpointer, store e middleware piuttosto che esempi di classi di memoria legacy.

Un'architettura di produzione minima

Per molte applicazioni di agenti, un design robusto appare così:

  1. L'API riceve user_id, conversation_id e il nuovo messaggio utente.
  2. L'applicazione mappa conversation_id a un LangGraph thread_id stabile.
  3. Un checkpointer persistente ripristina lo stato del thread.
  4. Uno store a lungo termine recupera solo i fatti utente o applicazione durevoli necessari per la richiesta.
  5. Il riassunto o il taglio mantiene la cronologia rivolta al modello entro un budget di contesto misurato.
  6. L'agente esegue gli strumenti e il modello.
  7. Il checkpointer committa lo stato del thread aggiornato.
  8. Solo i fatti approvati sono scritti nello store a lungo termine.

Se distribuite tramite LangGraph Agent Server, l'attuale guida alla persistenza afferma che il server gestisce automaticamente l'infrastruttura di persistenza, quindi non duplicate quel livello senza controllare il modello di distribuzione.

Errori comuni che fanno sembrare la memoria rotta

Generare un nuovo thread_id per ogni richiesta

Questo crea un nuovo stato di conversazione ogni turno. Registrate l'ID thread accanto all'ID chat della vostra applicazione e verificate il riutilizzo.

Utilizzare InMemorySaver in un servizio multi-worker o riavviabile

Lo stato locale alla RAM scompare con il processo e potrebbe non essere condiviso tra i worker. Utilizzate un backend persistente per la continuità di produzione.

Assumere che un checkpointer risolva il problema della finestra di contesto

Un checkpointer preserva lo stato; non garantisce che una trascrizione in continua crescita sia utile al modello. Aggiungete una politica esplicita di gestione del contesto.

Mettere ogni fatto storico nel prompt

Più contesto non è automaticamente un contesto migliore. Recuperate le informazioni rilevanti per il turno corrente e preservate la continuità conversazionale recente separatamente.

Trattare i riassunti come un database perfetto

I riassunti sono rappresentazioni compresse generate dal modello. Se un fatto deve essere esatto—un identificatore di account, un vincolo contrattuale, una preferenza approvata dall'utente o uno stato del workflow—memorizzatelo come dati strutturati piuttosto che sperare che sopravviva a riassunti ripetuti.

Mescolare gli ambiti a breve e lungo termine

La cronologia del thread non dovrebbe diventare silenziosamente un profilo utente globale. Viceversa, una preferenza utente destinata a seguire l'utente attraverso le chat non dovrebbe vivere solo in un thread.

Copiare tutorial di memoria pre-v1 senza controllare gli import

Se un esempio parte da catene legacy o vecchie classi di memoria, confrontatelo con l'attuale migrazione v1 e i documenti sulla memoria prima di usarlo in una nuova applicazione.

Checklist di debug

  • Confermate che l'agente è stato creato con un checkpointer.
  • Registrate e confrontate thread_id tra richieste consecutive.
  • Ispezionate lo stato del thread memorizzato prima di incolpare il modello.
  • Riavviate il processo e ripetete lo stesso test dello stesso thread.
  • Sostituite InMemorySaver con un checkpointer persistente per la produzione.
  • Misurate la crescita dei messaggi/token nelle chat lunghe.
  • Abilitate il riassunto o il taglio prima che la cronologia diventi eccessiva.
  • Mantenete valide le sequenze di chiamata/risultato degli strumenti quando rimuovete messaggi.
  • Spostate i fatti cross-thread in uno store a lungo termine con namespace.
  • Testate un nuovo thread per lo stesso utente per verificare il richiamo a lungo termine intenzionale.
  • Testate un utente diverso per verificare l'isolamento della memoria.
  • Tracciate quali elementi di memoria sono stati recuperati per ogni risposta.

In conclusione

La perdita di memoria degli agenti LangChain è raramente risolta da una finestra di contesto più grande. Prima rendete lo stato del thread persistente con un checkpointer e un thread_id stabile. Poi controllate le cronologie lunghe con il taglio o SummarizationMiddleware. Infine, posizionate i fatti che devono sopravvivere attraverso le conversazioni in uno store a lungo termine con namespace e recuperateli deliberatamente.

Quella separazione vi dà qualcosa di molto più utile della "memoria": un sistema che potete riavviare, scalare, testare, auditar e ragionare quando un utente chiede, "Perché l'agente ha dimenticato?"

Lascia un commento

Come impedire agli agenti CrewAI di eseguire attività ridondanti: una guida pratica alla deduplicazione

Come impedire agli agenti CrewAI di eseguire attività ridondanti: una guida pratica alla deduplicazione

Impedisci agli agenti CrewAI di ripetere il lavoro correggendo la proprietà delle attività, le dipendenze, la delega, i tentativi, i trigger di Flow, la persistenza dello stato, la memorizzazione nella cache e l'idempotenza.

Modello di tracciamento delle spese per lavoratori autonomi indipendenti negli Stati Uniti

Modello di tracciamento delle spese per lavoratori autonomi indipendenti negli Stati Uniti

Crea un tracker delle spese per freelance USA, con categorie conformi all'IRS, registri delle ricevute, tariffe chilometriche 2026 e segnalazioni per la revisione fiscale.

Modello gratuito di pianificazione turni dipendenti in Excel con calcolatore ore

Modello gratuito di pianificazione turni dipendenti in Excel con calcolatore ore

Crea un piano turni gratuito per dipendenti in Excel con calcolatore ore, formule per turni notturni, totali settimanali, controlli di qualità e limiti chiari.

Come creare un semplice sistema di tracciamento dei lead in Excel prima di acquistare un CRM

Come creare un semplice sistema di tracciamento dei lead in Excel prima di acquistare un CRM

Crea un tracker lead pratico in Excel con tabelle, menu a tendina, avvisi di follow-up e un riepilogo semplice della pipeline, oltre a segnali chiari che è il momento di passare a un CRM.

Modello Excel per il registro di manutenzione delle attrezzature per responsabili di officina: Configurazione pratica 2026

Modello Excel per il registro di manutenzione delle attrezzature per responsabili di officina: Configurazione pratica 2026

Crea un registro di manutenzione delle attrezzature in Excel pratico per gli asset dell'officina, con storico dei servizi, scadenze, tempi di fermo, costi, registri di ispezione e chiari confini di sicurezza.

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.

Come eseguire DeepSeek offline su Windows 11 con LM Studio

Come eseguire DeepSeek offline su Windows 11 con LM Studio

Esegui DeepSeek localmente su Windows 11 con LM Studio. Scopri quale modello è adatto a un PC normale, come scaricarlo e caricarlo, verificare l'uso offline e risolvere i problemi comuni.

Come ridurre i costi dei token API del 50% utilizzando tecniche di compressione dei prompt

Come ridurre i costi dei token API del 50% utilizzando tecniche di compressione dei prompt

Riduci i costi delle API LLM con quattro tecniche pratiche di compressione dei prompt, layout adatti alla cache, output strutturati e un piano di valutazione che preserva la qualità.

Come creare una pipeline gratuita di riproposizione dei contenuti AI con n8n e Claude (cosa è realmente gratuito)

Come creare una pipeline gratuita di riproposizione dei contenuti AI con n8n e Claude (cosa è realmente gratuito)

Crea una pipeline di riproposizione dei contenuti AI a costo di hosting zero con n8n self-hosted e Claude, con output strutturati, gate di revisione e una guida realistica sui costi API.

Checklist per la pianificazione di eventi stampabile e modello di budget per Word

Checklist per la pianificazione di eventi stampabile e modello di budget per Word

Utilizza una pratica checklist stampabile per la pianificazione di eventi e un modello di budget per Word, con tempistiche, monitoraggio dei fornitori, costi stimati vs. effettivi, pagamenti e attività del giorno dell'evento.