Una guida per sviluppatori avverte che mantenere aperta una transazione del database per l'intera durata di una chat basata su IA può corrompere le risposte e soffocare il DBMS sottostante. La nota, rivolta ai team che costruiscono strumenti basati su LLM, afferma che tale pratica «non dovrebbe essere effettuata» e propone invece quattro pattern a breve durata per la coerenza dei dati.

Perché l'avvertimento è importante

Gli assistenti basati su LLM spesso pongono una serie di domande di approfondimento: leggono un record, richiedono un dettaglio e poi chiedono un totale. Se i dati sottostanti cambiano tra questi passaggi, l'assistente può restituire cifre contraddittorie: una risposta sarà errata. La soluzione tentatrice è quella di aprire una singola transazione all'inizio della conversazione e mantenerla attiva fino alla fine della chat. In pratica, questo approccio occupa le versioni delle righe, riempie il tempdb, mantiene i lock e interferisce con il connection pooling.

Cosa porta a transazioni di lunga durata

  • Prompting multi-turno – Gli LLM solitamente generano diversi prompt prima che l'utente riceva una risposta.
  • Tool call che interrogano il database – Ogni turno può invocare una stored procedure, una SELECT o una UPDATE.
  • Ambito della transazione non controllato – Gli sviluppatori a volte racchiudono l'intera chat in un blocco BEGIN…COMMIT, assumendo che questo garantisca la coerenza.

Quando la chat si protrae, il motore del database deve mantenere le versioni originali delle righe affinché la transazione veda una vista stabile. Queste versioni risiedono nel tempdb, consumando spazio e I/O. I lock mantenuti per lo stesso periodo bloccano gli scrittori concorrenti, e la connessione inattiva può esaurire il pool, costringendo i nuovi chiamanti ad attendere uno slot libero.

Quattro pattern a breve durata

La guida raccomanda di trattare la coerenza come una questione relativa a ogni singola tool call, piuttosto che all'intera conversazione. I quattro pattern sono:

  1. Istruzioni live – Ogni chiamata viene eseguita con il livello di isolamento predefinito, vedendo solo i dati che sono stati confermati al momento dell'esecuzione. Questo è il modello più semplice; chi chiama accetta che i dati possano essere cambiati rispetto al turno precedente.
  2. Transazioni delimitate – Uno sviluppatore raggruppa un piccolo numero di istruzioni all'interno di una singola transazione breve che termina prima del turno successivo dell'LLM. Ciò garantisce l'atomicità per quel batch senza protrarsi oltre la tool call.
  3. Letture snapshot – L'operazione inizia con un timestamp di snapshot definito, fornendo una vista stabile del database per la durata della chiamata. Tutte le letture all'interno della chiamata vedono gli stessi dati, anche se si verificano scritture concorrenti.
  4. Report materializzati – Lo strumento legge da un set di risultati pre-generato e versionato che riflette il database in un punto di cutoff noto. La paginazione o ulteriori calcoli operano quindi su quel set di dati congelato.

In SQL Server, verifica se READ_COMMITTED_SNAPSHOT è attivo. Non dare per scontato che il nome dica tutto.

Regole pratiche per le app basate su LLM

  • Raggruppa (batch) ciò di cui hai bisogno – Se una domanda richiede molti valori, calcolali in una singola tool call invece di emettere query separate che avviano ciascuna una nuova transazione.
  • Paginazione deterministica – Quando presenti i risultati su più pagine, utilizza una chiave di ordinamento stabile, un cursore o un set di risultati materializzato. Non mantenere mai una transazione aperta mentre l'utente scorre la pagina.
  • Restituisci le evidenze – Insieme ai dati, includi metadati che rendano esplicito il modello di coerenza: la classe di coerenza, l'ora di inizio dello snapshot, il punto di cutoff del report, la freschezza dei dati,