Guida

Memoria dell'agente AI tra le sessioni: file di avanzamento, registro delle decisioni, git e script di init

Aggiornato: · Skillaria.Top

L'agente AI non ha memoria tra le sessioni: tutto ciò che non è scritto nei file del repository non è noto alla nuova sessione. La memoria dell'agente si costruisce con degli artefatti: PROGRESS.md (a che punto siamo), DECISIONS.md (perché così e che cosa è stato scartato), commit git con la spiegazione dell'intento e un protocollo di passaggio in AGENTS.md che obbliga a leggerli all'inizio e ad aggiornarli alla fine; uno script di init verifica l'ambiente e stampa lo stato attuale.

Perché l'agente non ricorda nulla

Il modello non conserva lo stato tra un'esecuzione e l'altra. Tutto ciò che l'agente «sa» del vostro compito si trova nella finestra di contesto della sessione corrente: i file letti, l'output dei comandi, il dialogo con voi. Quando la sessione si chiude o il contesto si riempie, la nuova parte da zero e vede solo ciò che è stato scritto su disco.

Un modello utile: un ingegnere brillante che ogni mattina arriva al lavoro con la memoria completamente cancellata. Capisce rapidamente il codice, ma non ricorda quale architettura è stata scelta ieri, perché le altre sono state scartate e in quale stato sono i test. Senza appunti, impiegherà quindici-venti minuti di esplorazione e con buona probabilità rifarà qualcosa che avete già scartato di proposito.

Quindi la memoria dell'agente AI non è una proprietà del modello, ma una parte dell'harness: un insieme di file e regole che progettate voi. La buona notizia è che non servono database vettoriali né servizi speciali. Bastano pochi file Markdown, git e un po' di disciplina.

Perché una finestra di contesto più grande non risolve il problema

Si pensa che basti aspettare un modello con una finestra più ampia. Ma un compito complesso riempie qualsiasi finestra: l'agente legge la base di codice, accumula la storia delle decisioni, riceve output verbosi dei test e tiene l'intero dialogo. Le esigenze crescono insieme alla finestra. È un problema architetturale, non una questione di dimensioni.

C'è anche un secondo effetto. Vicino al limite della finestra molti modelli iniziano ad affrettarsi a concludere: saltano la verifica, scelgono la soluzione semplice invece di quella giusta. Anthropic descrive questa osservazione per i propri modelli, ma l'intensità dell'effetto varia da modello a modello. Una sessione lunga al limite del contesto non rischia solo di perdere informazioni, ma anche di peggiorare la qualità del lavoro.

Compattazione: che cosa si conserva e che cosa si perde

La compattazione è la riduzione della parte iniziale del dialogo in un riassunto breve, per liberare spazio nella stessa sessione. In Claude Code la fa il comando /compact, ma la compressione avviene anche automaticamente quando ci si avvicina al limite. Il comando /clear, al contrario, cancella la cronologia e ricomincia la conversazione da capo.

Il problema della compattazione è che il riassunto di solito conserva il «che cosa» e perde il «perché». Il codice finito resta nei file, ma i ragionamenti — perché è stata scelta la variante B, perché non si è usata una libreria, perché si è deliberatamente saltata un'ottimizzazione — si riducono a due parole o spariscono. Il passo successivo dell'agente «migliora» una decisione consapevole, perché non vede più le ragioni.

CompattazioneRipartenza (nuova sessione)
Che cosa succedeLa parte iniziale del dialogo viene sostituita da un riassuntoLa sessione si chiude, la nuova legge i file di stato
Che cosa si conservaCiò che il modello ha ritenuto importante nella compressioneEsattamente ciò che avete scritto nei file
Fretta al limite della finestraPuò restareSi azzera
Quando è opportunaIl compito sta sicuramente nella sessione correnteL'orizzonte del compito è lungo o poco chiaro

Regola pratica senza metriche complesse: quando il compito ha occupato circa il 60% della finestra, smettete di scrivere codice e preparate il passaggio di consegne. Se invece il contesto è occupato per il 40% e la fine del compito è vicina, basta la compattazione.

Quattro artefatti che compongono la memoria dell'agente

Invece di sperare nella memoria del modello, create un giornale di bordo. È composto da quattro parti, ciascuna con un ruolo proprio.

  1. PROGRESS.md — a che punto siamo.
  2. DECISIONS.md — perché si è fatto così e non diversamente.
  3. Commit git — checkpoint gratuiti dello stato.
  4. Protocollo di passaggio in AGENTS.md — che cosa fare all'arrivo e alla partenza.

PROGRESS.md: il file di avanzamento

Risponde a una sola domanda: in che stato si trova il progetto in questo momento. L'agente lo legge per primo all'inizio della sessione e lo aggiorna per ultimo prima di andarsene. Il file è breve, si riscrive invece di aggiungere in fondo all'infinito: la storia vive in git.

# PROGRESS.md

## Obiettivo attuale
Ricerca nel catalogo prodotti (funzione search-01)

## Stato
- HEAD: 4f2a9c1
- make check: verde, 142/142 test
- Fatto: indice in PostgreSQL (tsvector), endpoint GET /search
- Verificato: test unitari + richiesta curl manuale su 3 query

## Blocchi
- Mancano dati di morfologia per la lingua kazaka — in attesa di una decisione

## Prossimo passo
Aggiungere la paginazione a GET /search, criterio: test sulla seconda pagina

Notate i quattro campi che bastano per un passaggio di consegne: hash del commit, quota di test che passano, blocchi e prossimo passo. Se una sessione nuova non riesce a riprendere il lavoro in modo univoco da questo file, nel modello manca un campo.

DECISIONS.md: il registro delle decisioni

Conserva proprio il «perché» che si perde con la compattazione. Il formato di una voce: decisione, motivazione, che cosa è stato scartato e perché, vincoli.

## 2026-03-14 — Cache delle impostazioni utente in Redis
- Decisione: Redis, TTL di 5 minuti, invalidazione attiva alla scrittura.
- Motivo: viene letta a ogni richiesta, il volume di dati è minimo.
- Scartato: materialized view in PostgreSQL — modifiche troppo frequenti,
  la manutenzione non si ripaga.
- Vincolo: non mettere in cache le impostazioni di pagamento.

La riga più preziosa è «Scartato». È lei che impedisce alla sessione successiva di «ottimizzare» la decisione tornando alla variante già considerata e rifiutata. Il registro delle decisioni, a differenza del file di avanzamento, si limita ad crescere: le voci vecchie non si cancellano, ma si contrassegnano come sostituite da quelle nuove.

La storia di git come checkpoint

I commit sono snapshot versionati dello stato, già integrati nel lavoro. L'agente può leggere git log e git diff e ricostruire che cosa è cambiato. Perché la storia funzioni come memoria, il messaggio del commit deve spiegare l'intento, non riassumere il diff.

# male
git commit -m "update search.py"

# bene
git commit -m "search: indice tsvector al posto di LIKE

LIKE '%q%' non usa l'indice, su 200k prodotti la query impiega 1,8 s.
La paginazione non è ancora fatta, vedi PROGRESS.md."

Commit piccoli e frequenti dopo ogni esecuzione verde dei test offrono anche un punto di ritorno. Se la sessione è andata nella direzione sbagliata, è più semplice tornare all'ultimo stato verificato che districare modifiche a metà.

Protocollo di passaggio in AGENTS.md

I file di stato non servono a nulla se l'agente non li conosce. Per questo nel file di istruzioni di ingresso (AGENTS.md o CLAUDE.md) si scrive un protocollo breve: che cosa fare all'arrivo e alla partenza.

## Arrivo in turno
1. Leggere PROGRESS.md e DECISIONS.md.
2. Trovare la funzione attiva in .agent/feature_list.json.
3. Eseguire make check — verificare che il repository sia coerente.
4. Continuare dal «Prossimo passo», senza riaprire ciò che è già deciso.

## Partenza dal turno
1. Eseguire make check, fare il commit dello stato verde.
2. Aggiornare PROGRESS.md: HEAD, test, blocchi, prossimo passo.
3. Aggiungere le nuove decisioni in DECISIONS.md.
4. Non lasciare lavoro a metà nell'albero di lavoro.

Il protocollo conviene tenerlo breve: sono poche righe nel file di ingresso, non un papiro a parte.

Script di init: come accelerare l'avvio della sessione

Perché l'agente non ricostruisca il quadro a mano, datele uno script unico che verifica l'ambiente e stampa lo stato. Lo script deve essere idempotente — si può eseguire quante volte si vuole — e terminare con un messaggio esplicito di pronto.

#!/usr/bin/env bash
set -euo pipefail

echo "== 1. Ambiente =="
command -v uv >/dev/null || { echo "FAIL: uv non installato"; exit 1; }
uv sync --frozen

echo "== 2. Repository =="
if [ -n "$(git status --porcelain)" ]; then
  echo "WARN: albero di lavoro sporco"
else
  echo "OK: pulito"
fi
echo "HEAD: $(git log -1 --oneline)"

echo "== 3. Verifica =="
make check

echo "== 4. Stato =="
cat PROGRESS.md

echo "Pronto al lavoro"

Nel protocollo di arrivo basta allora una riga: «esegui scripts/init.sh». In Claude Code questo avvio si può automatizzare con un hook all'avvio della sessione (evento SessionStart), ma anche senza hook l'agente esegue lo script seguendo l'istruzione del file.

Che cosa mettere nella memoria dell'agente e che cosa no

L'errore principale è trasformare la memoria in una discarica. Ogni riga che l'agente legge all'avvio occupa spazio nel contesto, e il superfluo confonde l'importante.

MettereNon mettere
Obiettivo attuale e prossimo passoRiassunto del codice che l'agente leggerà da sé
Decisioni con motivazioni e alternative scartateLog completo del dialogo e output dei comandi
Hash del commit e stato dei testElenco delle dipendenze — è già nel manifest dei pacchetti
Blocchi e domande aperte«Ho fatto un lavoro ottimo, tutto funziona» senza dire come è stato verificato
Vicoli ciechi: che cosa si è provato e perché non ha funzionatoSegreti, token, password
Compiti con criteri di accettazioneNote obsolete su compiti chiusi

Separate anche per durata di vita. Le regole del progetto cambiano di rado e riguardano tutti i compiti: il loro posto è il file di istruzioni di ingresso. Lo stato cambia a ogni sessione: il suo posto è il file di avanzamento. Se le mescolate, il file di ingresso cresce in fretta con note superate.

Prima sessione: l'inizializzazione come fase a sé

La memoria tra le sessioni non serve se la prima sessione è finita nel caos. Scenario tipico: sul repository appena creato scrivete «aggiungi la ricerca», e dopo mezz'ora si scopre che il framework di test è configurato male e il formato delle migrazioni non va bene. La ricerca c'è, ma le fondamenta sono storte.

Il motivo è che realizzazione e inizializzazione ottimizzano cose diverse: la prima il numero di funzioni pronte in questa sessione, la seconda la velocità e l'affidabilità di tutte le sessioni successive. L'agente tende verso il risultato visibile, cioè il codice. Per questo conviene separare l'inizializzazione in una sessione dedicata, con un criterio di completamento chiaro in quattro condizioni.

  • Avviarsi: make setup e make dev funzionano partendo da un clone pulito.
  • Verificarsi: esistono make test e almeno un test reale che passa.
  • Vedere il progresso: il file di stato esiste e si legge.
  • Riprendere il lavoro: c'è un elenco di compiti con criteri di accettazione.

Se avviate spesso progetti nuovi, preparate un template di repository: Makefile, framework di test, scheletro di AGENTS.md, la cartella .agent/, scripts/init.sh, linter e CI. Così l'inizializzazione si riduce alla sola specificità del progetto.

Come verificare che la memoria funzioni

La misura più onesta è il tempo che passa dall'inizio di una nuova sessione alla prima modifica significativa del codice. Senza artefatti sono di solito quindici-venti minuti di esplorazione, con un buon passaggio di consegne due-tre. Misuratelo una volta prima e una volta dopo, e si vedrà se la disciplina ripaga.

Il secondo metodo è il test di avvio a freddo. Aprite una sessione nuova, scrivete «continua» e fate cinque domande: qual è l'obiettivo attuale, in che stato sono i test, quale decisione è stata presa sul tema chiave e perché, che cosa blocca, qual è il prossimo passo. Se l'agente risponde a tutte e cinque basandosi sui file, senza supposizioni, la memoria è costruita bene. Ogni risposta incerta indica un campo mancante nel template.

Errori tipici

  • Il file di avanzamento cresce soltanto. Dopo un mese contiene centinaia di righe di storia. Riscrivetelo in base allo stato attuale: la storia sta in git.
  • Manca la riga «scartato». Un registro delle decisioni senza alternative scartate non protegge dalle discussioni ripetute.
  • L'agente aggiorna lo stato «a occhio». Scrivete come è stato verificato: comando e risultato, non «tutto funziona».
  • Passaggio di consegne al limite della finestra. Vicino al bordo del contesto l'agente ha già fretta; avviate l'handoff in anticipo, intorno al 60%.
  • Albero di lavoro sporco alla fine. Modifiche a metà senza commit disorientano la sessione successiva.

In breve

La memoria dell'agente AI tra le sessioni non si costruisce sul modello, ma sui file: PROGRESS.md conserva lo stato attuale, DECISIONS.md le motivazioni e le alternative scartate, i commit git sono checkpoint con la spiegazione dell'intento, e il protocollo di passaggio in AGENTS.md obbliga a leggere e aggiornare tutto questo. Lo script di init riduce l'avvio a un solo comando, e il test di avvio a freddo mostra se le annotazioni bastano. Il giornale di bordo dell'agente e il contratto di bootstrap sono illustrati in pratica nel corso sull'harness engineering.

Domande frequenti

Posso semplicemente chiedere all'agente di ricordare qualcosa per il futuro?

L'agente lo ricorderà solo se lo scrive in un file che la sessione successiva leggerà. In Claude Code esistono i file di memoria e CLAUDE.md, ma per lo stato di un compito specifico è più affidabile un file di avanzamento esplicito nel repository.

In che cosa PROGRESS.md differisce dal CHANGELOG?

Il CHANGELOG descrive le modifiche per gli utenti, per versione. PROGRESS.md descrive lo stato di lavoro attuale per la sessione successiva dell'agente e viene riscritto ogni volta che lo stato cambia.

Serve un database vettoriale per la memoria di un agente programmatore?

Di solito no, quando si lavora in un solo repository: lo stato di un compito sta in pochi file brevi, e il codice l'agente lo legge direttamente. La ricerca vettoriale ha senso quando bisogna cercare in un grande volume di documenti esterni.

Conviene committare i file di stato in git?

Sì: così lo stato è disponibile a ogni sessione e a ogni membro del team, e la storia delle sue modifiche si conserva. Fanno eccezione le note personali e tutto ciò che contiene segreti.

Che cosa fare se l'agente dimentica di aggiornare PROGRESS.md alla fine?

Rendete l'aggiornamento parte del criterio di completamento nel protocollo di partenza e verificatelo in modo meccanico, per esempio con un hook o uno script che confronta l'HEAD scritto nel file con il commit attuale.

Impara l’argomento in video

Questo argomento è trattato in modo approfondito, con pratica, nel corso «Harness Engineering: инженерия надёжности AI-агентов».

Vai al corso