Uno dei problemi più sottili quando si progetta l’interazione utente-LLM in un sistema RAG non riguarda la qualità del retrieval o la scelta del modello, ma qualcosa di più semplice e più trascurato: quanto deve essere lunga la risposta al primo turno?
Ho affrontato questo tema lavorando su una funzionalità specifica: quando l’utente pone una domanda che implica una sequenza di passi da compiere, il sistema dovrebbe rispondere prima in modo sintetico — solo i passi essenziali — e proporre un approfondimento solo se l’utente lo richiede esplicitamente. Un pattern conversazionale semplice da descrivere, ma che apre a considerazioni interessanti su come i diversi LLM interpretano le istruzioni comportamentali nel system prompt.

Il pattern: sintesi prima, dettaglio su richiesta
L’idea è governare questo comportamento con una regola nel system prompt, accanto alle altre _OUTPUT_FORMAT_RULES già esistenti. La logica è:
- Se la domanda dell’utente implica dei passi operativi, il modello risponde con l’elenco sintetico dei passi.
- La risposta si chiude con una domanda esplicita tipo “Vuoi che approfondisca?”.
- Solo se l’utente conferma, il turno successivo produce la versione completa e dettagliata.
Dal punto di vista implementativo, questo è possibile senza modifiche architetturali profonde: il motore RAG del progetto supporta già la multi-turnalità tramite history_context, quindi il contesto necessario per generare la risposta approfondita al secondo turno è già disponibile — non serve rieseguire il retrieval o duplicare la logica di recupero documenti.
Il compromesso: istruzione comportamentale, non vincolo strutturale
Qui arriva il punto centrale, quello che vale la pena approfondire per chiunque costruisca sistemi simili: questa è un’istruzione in linguaggio naturale rivolta al modello, non una regola deterministica imposta dal codice.
La differenza non è accademica. Un vincolo di codice — per esempio troncare programmaticamente l’output, o instradare la richiesta verso un ramo “sintetico” della pipeline — è affidabile al 100% per costruzione: non può essere ignorato. Un’istruzione nel system prompt, per quanto ben scritta, resta invece una richiesta che il modello può disattendere, specie in presenza di contesto RAG ricco che “spinge” verso una risposta più esaustiva.
Perché l’affidabilità cambia da modello a modello
Un aspetto interessante emerso discutendo l’implementazione è che questa affidabilità non è costante: dipende dal provider LLM configurato. In un sistema che supporta più backend (Anthropic, OpenAI, Ollama), la stessa istruzione comportamentale può funzionare in modo molto diverso a seconda del modello sottostante, per almeno quattro ragioni:
1. Training e RLHF differenti. Claude, GPT e i modelli distribuiti via Ollama (spesso Llama, Mistral o varianti più leggere) sono addestrati con dataset e tecniche di reinforcement learning from human feedback differenti. Questo si traduce in una diversa capacità di interpretare istruzioni comportamentali complesse — come “fermati dopo il riassunto, poi aspetta conferma” — che richiedono al modello di pianificare la propria risposta su più turni, non solo di rispondere alla domanda immediata.
2. Dimensione del modello. I modelli locali eseguiti via Ollama sono generalmente più piccoli rispetto ai modelli di fascia alta di Anthropic o OpenAI, e tendono ad avere più difficoltà con istruzioni multi-step o condizionali — quelle del tipo “se X allora fai A, altrimenti fai B, e comunque aspetta conferma prima di C”.
3. Peso relativo di system prompt e contesto recuperato. Modelli diversi danno priorità diversa alle istruzioni scritte nel system prompt rispetto al contenuto recuperato dal RAG. Se il contesto recuperato è denso e ricco di informazioni, alcuni modelli tendono a “riversarlo” per intero nella risposta, ignorando di fatto l’istruzione di sintesi — anche quando questa è formulata chiaramente.
4. Assenza di garanzie strutturali. Anche a parità di modello, il comportamento non è garantito essere identico da una run all’altra: temperatura, lunghezza del contesto e altri parametri di inferenza possono far oscillare l’aderenza all’istruzione.
Due strategie, due livelli di affidabilità
Da questa analisi emergono sostanzialmente due strade, con un trade-off netto tra semplicità implementativa e affidabilità garantita:
Strategia “soft” — istruzione nel prompt. Si aggiunge la regola alle _OUTPUT_FORMAT_RULES (o in un blocco dedicato), con esempi chiari di input/output per aiutare il modello a generalizzare il pattern. È la soluzione più semplice da implementare e da mantenere, ma non offre garanzie: va testata empiricamente sui provider effettivamente in uso, ed è comunque soggetta a occasionali violazioni, specialmente cambiando modello o provider nel tempo.
Strategia “hard” — controllo a livello di codice. Se l’affidabilità deve essere garantita indipendentemente dal provider, la soluzione più robusta è spostare il controllo dal prompt al codice applicativo: il primo turno risponde sempre in modalità sintetica (troncando o instradando programmaticamente l’output), e solo a fronte di una conferma esplicita dell’utente si effettua una seconda chiamata all’LLM con un prompt dedicato di approfondimento. In questo modo il comportamento a due fasi non dipende più dalla capacità del modello di seguire un’istruzione condizionale, ma diventa parte del flusso di controllo dell’applicazione — al costo, ovviamente, di una logica leggermente più complessa e di una chiamata LLM aggiuntiva nel percorso “sintesi + approfondimento”.
Conclusione
Il caso è un buon promemoria di un principio più generale nella progettazione di sistemi basati su LLM multi-provider: ogni comportamento che dipende esclusivamente da istruzioni in linguaggio naturale è probabilistico, non deterministico, e la sua affidabilità non è una proprietà del sistema mio quanto del modello che lo esegue in un dato momento. Quando il comportamento è puramente stilistico (tono, formattazione), affidarsi al prompt è ragionevole. Quando invece il comportamento è parte del contratto funzionale dell’applicazione — come nel caso di un flusso a due fasi che l’utente si aspetta sia rispettato — vale la pena chiedersi se non sia il caso di spostare almeno la parte critica della logica dal prompt al codice, riservando al modello il compito che sa fare meglio: generare il contenuto, non decidere quando fermarsi.

Lascia un commento
Devi essere connesso per inviare un commento.