Ancora le risposte al contesto recuperato e consenti l'astensione
Condiziona il modello ai passaggi recuperati e istruiscilo a rispondere solo da quel contesto e a dichiarare di non sapere quando il contesto è insufficiente. È il controllo più efficace contro l'allucinazione, perché rimuove l'incentivo a inventare testo plausibile. Progetta sempre esplicitamente il percorso "nessun contesto valido", o il modello riempirà il vuoto con finzione sicura di sé.
- Fai: istruisci "Rispondi solo dal contesto qui sotto; se non contiene la risposta, dichiara che il contesto non lo copre."
- Non fare: inviare passaggi recuperati senza dire al modello che può astenersi, e poi sorprenderti se inventa.
Tratta l'eval set come immutabile e fai da gate ai rilasci
Costruisci un eval set golden di domande rappresentative con risposte di riferimento ancorate, ed esegui ogni modifica contro di esso come gli unit test fanno da gate al codice. Non modificare mai una risposta di riferimento per far passare il sistema - vanifica la misura. Una soglia minima di faithfulness in CI coglie le regressioni prima degli utenti.
- Fai: congela
eval.jsonl, fai fallire la build sotto una soglia di faithfulness calibrata su un run di baseline. - Non fare: ritoccare le risposte golden finché il modello attuale ottiene un buon punteggio.
Valuta recupero e generazione separatamente
Misura se il retriever ha fatto emergere i passaggi giusti (context recall) indipendentemente dal fatto che il generatore li abbia usati con fedeltà. Un retriever debole pone un tetto alla qualità delle risposte per quanto buono sia il modello, e confondere i due nasconde la vera colpa.
- Fai: registra i passaggi recuperati per ogni domanda dell'eval e ispezionali per i casi che falliscono.
- Non fare: incolpare l'LLM per una risposta sbagliata quando l'evidenza necessaria non è mai stata recuperata.
Usa ricerca ibrida più re-ranking, non solo vettori
Combina recupero lessicale (BM25) e vettoriale denso e fondili, poi riordina la lista ristretta con un cross-encoder. I vettori mancano termini esatti e token rari; le keyword mancano le parafrasi; la combinazione più il re-ranking aumentano la precisione più di ciascuno da solo. È un default robusto per la produzione.
- Fai: recupera un ampio top-k con la ricerca ibrida, poi promuovi i pochi davvero rilevanti con un re-ranker.
- Non fare: rilasciare ricerca vettoriale pura per coseno e dare per risolto il recupero.
Dimensiona correttamente i chunk e regolali empiricamente
Suddividi i documenti in passaggi autonomi di circa 300-600 caratteri con leggera sovrapposizione, suddividendo sulla struttura (intestazioni, paragrafi) dove possibile. Poi regola osservando recall e faithfulness sui tuoi dati, perché la dimensione del chunk dipende dal corpus.
- Fai: misura la qualità del recupero su due o tre dimensioni di chunk e scegli in base alla metrica.
- Non fare: copiare a scatola chiusa una dimensione di chunk da un articolo senza misurarla sul tuo corpus.
Instrada le richieste al modello più economico che supera la soglia
Invia le richieste facili e ad alto volume a un modello più piccolo, veloce ed economico, riservando il modello più potente a quelle davvero difficili. La maggior parte del costo in produzione si vince qui, non nella contrattazione sul prezzo per token. Decidi il routing in base alla difficoltà del compito, misurata sull'eval set.
- Fai: classifica o valuta la difficoltà della richiesta e dispacciala a un set di modelli a livelli.
- Non fare: far passare ogni richiesta dal modello più costoso "per sicurezza".
Fai caching aggressivo: prefissi di prompt e risposte complete
Usa il prompt caching per prefissi stabili (system prompt lunghi, documenti, blocchi few-shot) per ridurre time-to-first-token e costo, e fai cache delle risposte complete per query identiche ripetute. La porzione cacheabile deve essere un prefisso esatto e immutabile, quindi metti il contenuto dinamico dopo di essa.
- Fai: colloca per primi il system prompt immutabile e i documenti di riferimento così che siano cacheabili.
- Non fare: intercalare dati per richiesta nel prefisso, vanificando la cache.
Tratta ogni input del modello come potenzialmente ostile
Assumi che testo dell'utente, documenti recuperati e risultati degli strumenti possano contenere istruzioni di prompt injection. Separa le istruzioni fidate dai dati non fidati, dai agli strumenti il privilegio minimo e non eseguire mai l'output del modello (SQL, shell, pagamenti) senza un controllo indipendente. La difesa è stratificata, non un singolo filtro.
- Fai: valida e vincola ogni chiamata a strumento, ed esegui un modello guardiano separato su input e output.
- Non fare: concatenare un documento recuperato subito dopo "segui queste istruzioni" e fidarti del risultato.
Imponi l'output strutturato con uno schema e validalo
Quando l'output alimenta codice a valle, vincolalo con uno schema di funzione/strumento o la modalità JSON e valida il risultato rispetto a quello schema nel codice. I modelli emettono occasionalmente JSON malformato, quindi analizza in modo difensivo e riprova o ripara in caso di errore.
- Fai: definisci uno schema JSON minimo e rifiuta o ripara l'output non conforme al confine.
- Non fare: fare
JSON.parsedel testo del modello assumendo che sia sempre valido e completo.
Strumenta ogni richiesta con tracing completo
Cattura i prompt inviati, il contesto recuperato, l'uso dei token, le chiamate agli strumenti, la latenza e l'output finale per ogni richiesta. Lo stesso input può produrre output diversi, quindi non puoi debuggare né valutare ciò che non hai registrato. Il tracing è il fondamento dell'observability LLM.
- Fai: memorizza una traccia completa per richiesta, incluso l'esatto contesto passato al modello.
- Non fare: registrare solo latenza e costo aggregati, lasciando i fallimenti irriproducibili.
Rendi gli agenti limitati, ben delimitati e idempotenti
Vincola un agente al set minimo di strumenti necessari, poni un tetto al conteggio delle iterazioni così che non possa iterare all'infinito, e rendi idempotenti le azioni con effetti collaterali perché retry e non determinismo possono ripetere una chiamata. L'affidabilità nasce da scoping stretto e validazione, non da un prompt più astuto.
- Fai: limita i loop, dai a ogni strumento il privilegio minimo e deduplica le azioni di creazione con una chiave di idempotenza.
- Non fare: consegnare a un agente strumenti ampi e un loop illimitato sperando che si comporti bene.
Fissa le versioni di modello e prompt e rivaluta a ogni cambiamento
Registra quale versione del modello, prompt e versione del corpus ha prodotto ogni risultato, e riesegui l'eval set ogni volta che uno di essi cambia - inclusi gli aggiornamenti silenziosi del modello del provider. Il drift degrada la qualità in silenzio, quindi un run pianificato dell'eval è il tuo sistema di allerta precoce.
- Fai: versiona prompt e corpus, fissa gli identificatori del modello e rivaluta a ogni cambiamento.
- Non fare: assumere che "stesso prompt, stesso provider" significhi comportamento stabile nel tempo.
Oscura la PII prima di log, indicizzazione o chiamate a terze parti
Rileva e rimuovi le informazioni personali identificabili prima che entrino in log, indici vettoriali o chiamate ad API esterne, per rispettare gli obblighi di privacy e limitare l'esposizione. La PII che finisce in un indice di embedding o in un log di un provider è difficile da richiamare indietro.
- Fai: esegui un rilevatore e un passaggio di oscuramento della PII a ogni confine che persiste o inoltra dati.
- Non fare: memorizzare trascrizioni grezze degli utenti con nomi, email o documenti nel tuo store di tracce senza filtri.
Fissa budget di latenza e usa lo streaming
Definisci obiettivi di latenza p95/p99 e fai streaming dei token così che gli utenti vedano l'output immediatamente anche quando la generazione totale è lunga. La latenza è dominata dalla lunghezza dell'output perché i token sono prodotti in sequenza, quindi anche output più brevi e modelli più piccoli aiutano.
- Fai: fai streaming delle risposte, limita la lunghezza dell'output e misura il time-to-first-token rispetto a uno SLO.
- Non fare: bloccare la UI finché un completamento lungo e non in streaming non finisce.