Vai al contenuto principale
Torna al blog
LLM IA Architettura Prompt Engineering Prestazioni

Da un mega-prompt a una pipeline: come abbiamo portato un processo IA da 58s a 14s

Dividere un prompt monolitico in passi specializzati ha ridotto la latenza da 58s a 14s. Architettura, misure reali, esempi di prompting e i compromessi che nessuno racconta.

JM
Javier Manzano
CEO & Co-founder • 11 agosto 2026
Da un mega-prompt a una pipeline: come abbiamo portato un processo IA da 58s a 14s

Qualche mese fa abbiamo dovuto metter mano a un sistema che trasformava testo libero — appunti di commerciali, trascrizioni di chiamate, email inoltrate — in record strutturati di CRM: clienti, opportunità, prossimi passi, riassunti cumulativi. La logica di business era ben pensata e il prompt lo aveva scritto qualcuno che conosceva molto bene il dominio commerciale.

Il problema era un altro: impiegava tra i 46 e i 68 secondi per ogni voce.

Cinquantotto secondi di media. Più di un minuto di spinner ogni volta che un commerciale salvava un appunto dal telefono. Oggi lo stesso processo risponde in 8-12 secondi: fino a 8 volte più veloce, con le stesse funzionalità, lo stesso modello di base e senza eliminare un solo campo dal risultato.

Questo articolo racconta come abbiamo portato quel processo sotto i 20 secondi senza togliere una sola funzionalità. Non c’è nessun trucco di prompt. Il cambiamento è stato architetturale, e la conclusione — che già intuivamo, ma che qui è stata misurata — è che un prompt gigantesco non è un’architettura, è un rinvio dell’architettura.

Il progetto è di un cliente, quindi tutto ciò che segue è anonimizzato: niente nomi, niente prompt letterali, niente dati di business. Ciò che è reale è la struttura del problema, le misure e le decisioni.

Passo 1: tutto in un’unica chiamata

Il punto di partenza era quello classico, e non lo dico con disprezzo: è così che inizia il 90% delle funzionalità IA validate prima in una chat. Un’unica chiamata al modello, con un system prompt di diverse migliaia di parole, che faceva tutto questo insieme:

  • Rilevare quali eventi commerciali c’erano nel testo
  • Classificarli per tipo
  • Interpretare il sottotesto e decidere quale fosse la mossa più importante
  • Costruire un JSON per evento con più di trenta campi
  • Generare narrativa: fotografie di stato, insight tattici, briefing, script di chiamata
  • Consolidare i riassunti cumulativi di ogni cliente e di ogni opportunità, rispettando lo storico

Funzionava. In una chat, con un esempio ben scelto, funzionava piuttosto bene. Ma in produzione, con temperatura 0.7 e dieci richieste consecutive, i tempi erano questi:

MetricaTempo
Minimo45,6 s
Massimo67,9 s
Media58,3 s
P9567,9 s

Abbassare la temperatura a 0.2 — il sospetto abituale — non ha cambiato nulla: media di 59,1 s. A quel punto sapevamo già che il problema non era di configurazione.

Passo 1: un'unica chiamata al modello che rileva, classifica, struttura un JSON da oltre 30 campi, scrive narrativa e consolida entità, con 58,3 secondi di attesa

Il punto di partenza: una chiamata, cinque responsabilità, un output enorme e 58,3 secondi di attesa.

Perché un’unica chiamata era il problema

Ci sono tre ragioni, e conviene separarle perché si risolvono in modi diversi.

La latenza la determina l’output, non l’input. Un LLM genera token uno alla volta. Puoi dargli 8.000 token di contesto e li elaborerà in fretta, ma ogni token che scrive costa tempo. Un prompt che chiede un JSON da trenta campi più cinque testi narrativi per ogni evento rilevato non è lento perché pensa molto: è lento perché scrive moltissimo. E se il testo in ingresso contiene tre eventi commerciali, l’output triplica.

L’attenzione si diluisce. Quando metti regole di formato, definizioni di campi, istruzioni di tono, criteri di priorità e logica condizionale nello stesso prompt, tutte competono per lo stesso budget di attenzione. Una regola di naming può rubare capacità di ragionamento al rilevamento degli eventi. È lo stesso effetto che ottieni chiedendo a una persona di, in un’unica passata, leggere un testo, classificarlo, compilare un modulo di trenta campi, scrivere tre paragrafi di analisi strategica e aggiornare uno storico. Ci riesce. Lo farà peggio che se glielo chiedi per parti.

Il ragionamento è opaco. Se il sistema rileva male un evento, l’errore si trascina nella strutturazione, nella narrativa e nel consolidamento. Non c’è modo di sapere dove ha fallito né di riprovare solo quella parte. E non puoi nemmeno ottimizzare nulla separatamente: se la narrativa è lenta, non puoi toglierla senza rompere il resto dell’output.

Questo terzo punto è quello che costa di più a medio termine, ed è il meno visibile in una demo.

Passo 2: dividere il prompt per vedere, non per correre

Il primo cambiamento non l’abbiamo fatto per ottimizzare. L’abbiamo fatto per capire.

Abbiamo separato la chiamata unica in fasi con ingressi e uscite espliciti, misurato ciascuna separatamente e lasciato il resto invariato. Niente parallelizzazione, niente modelli diversi, niente tagli al prompt. Solo suddividere e cronometrare.

Il risultato è stato un miglioramento modesto — da 58 a 28,4 secondi, sostanzialmente perché ogni chiamata generava meno testo in una volta sola —, ma non era quello il punto. Il punto è che siamo passati da una scatola nera a un sistema osservabile. Per la prima volta potevamo rispondere a “dove finiscono i secondi?”.

Passo 2: la chiamata unica divisa in rilevamento, strutturazione e consolidamento, con 28,4 secondi totali e ogni fase misurabile separatamente

Stesso lavoro, tre fasi misurabili. Il guadagno di tempo è stato modesto; quello di visibilità, totale.

E la risposta è stata chiara: il passo di strutturazione era ancora un mini-cervello completo. Rilevava, strutturava, dava priorità, scriveva narrativa e consolidava entità. Avevamo spezzato il monolite in pezzi, ma uno dei pezzi era ancora un monolite.

Questo passo intermedio sembra superfluo quando lo racconti a posteriori. Non lo è. Se fossimo saltati direttamente al disegno finale, avremmo ottimizzato alla cieca, e probabilmente il passo sbagliato.

Passo 3: specializzare, parallelizzare e togliere dal percorso critico

Con le misure davanti, la riprogettazione si è fatta da sola. Tre decisioni:

  1. Una responsabilità per chiamata. Il passo grande è stato diviso di nuovo, separando l’operativo (dati che finiscono in database) dal narrativo (testi che legge una persona).
  2. Ciò che non dipende da nessuno, in parallelo. Diversi passi avevano bisogno solo dell’output del rilevamento iniziale, non di quello degli altri. Non c’era motivo di eseguirli in serie.
  3. Ciò che non blocca, in background. La narrativa è la cosa più lenta da generare e la meno urgente: nessuno legge un briefing di riunione nello stesso secondo in cui salva un appunto.

La pipeline è rimasta così:

PassoCosa faModelloTempoBlocca l’utente?
1. RilevamentoIdentifica e classifica gli eventi nel testoLeggero3-5 s
2. StrutturazioneConverte ogni evento in un record operativoPrincipale5-10 s
3. ConsolidamentoAggiorna i riassunti cumulativi di ogni entitàPrincipale5-10 sSì, in parallelo con il 2
4. Azioni automaticheRileva modifiche esplicite di dati applicabili senza giudizioLeggero2-4 sSì, in parallelo con 2 e 3
5. ArricchimentoGenera narrativa, insight e contenuti di agendaPrincipale10-15 sNo

I passi 2, 3 e 4 partono insieme non appena finisce l’1, perché tutti e tre consumano la stessa cosa: la lista di eventi rilevati. Il passo 5 viene lanciato dopo aver risposto all’utente e aggiorna i record quando termina.

Passo 3: il rilevamento alimenta tre passi in parallelo, si risponde all'utente in 14,2 secondi e l'arricchimento narrativo gira in background

Il disegno finale: un passo leggero che apre il grafo, tre passi in parallelo e tutta la narrativa fuori dal percorso critico.

I numeri

PrimaPipeline sequenzialePipeline parallela
Tempo totale58,3 s28,4 s14,2 s
Tempo percepito58,3 s28,4 s8-12 s

Confronto: da 58,3 secondi con un'unica chiamata a 8-12 secondi percepiti con la pipeline parallela

In una frase: il processo è diventato più di 4 volte più veloce da capo a fondo e fino a 8 volte più veloce in ciò che l’utente percepisce. L’attesa è passata da 58,3 secondi — più di un minuto davanti a uno spinner — a 8-12 secondi. L’83% in meno, con la stessa funzionalità e lo stesso modello di base.

E non è nemmeno il confronto più duro. Il caso peggiore misurato sul sistema originale è stato di 67,9 secondi: più di un minuto per salvare un appunto. Oggi il tratto più lento dell’intero processo — la narrativa, 10-15 secondi — non è più sul percorso critico. L’utente non lo aspetta mai.

Cosa significano 48 secondi in meno

Le percentuali si dimenticano; il tempo accumulato no. Con 100 voci al giorno, un volume modesto per un team commerciale di medie dimensioni:

PrimaAdesso
Attesa accumulata al giorno1 h 37 min17 min
Al mese (20 giorni lavorativi)32 ore6 ore

Sono 26 ore al mese — più di tre giornate intere — che un team ha smesso di passare davanti a uno schermo che non risponde.

Ma il cambiamento importante non è aritmetico, è comportamentale. Sopra i 40 secondi, le persone lanciano la richiesta e se ne vanno: aprono un’altra scheda, salgono in macchina, dimenticano. Sotto i 20, restano a guardare il risultato — e se qualcosa è uscito storto, lo correggono a caldo, mentre ricordano ancora la conversazione appena avuta. Quella differenza non compare in nessun grafico di latenza ed è quella che decide se la funzionalità viene usata o abbandonata.

E c’è una parte che non compare nemmeno nella tabella: ora sappiamo quale passo fallisce quando qualcosa fallisce, possiamo riprovare solo quello, possiamo cambiare il modello di un passo senza toccare gli altri e possiamo aggiungere un passo nuovo senza riscrivere un prompt da 4.000 parole.

Come sono rimasti i prompt in pratica

Niente di tutto questo si regge solo su un’architettura di scatole e frecce. Dietro ogni passo ci sono tecniche concrete di prompting, ed è la parte che di solito non si racconta. Non possiamo mostrare il prompt reale del cliente — è di sua proprietà —, ma sì il pattern, che è riutilizzabile in qualsiasi progetto con questa forma.

Prima: un system prompt con cinque lavori dentro

Il prompt originale aveva la forma classica del “fai tutto”: una lista lunga di istruzioni, tutte allo stesso livello, in competizione per la stessa attenzione e con il JSON di output descritto in prosa alla fine.

Sei un assistente che elabora appunti commerciali.

1. Rileva tutti gli eventi commerciali nel testo (riunione, offerta, obiezione, chiusura...)
2. Per ogni evento, classificalo per tipo e per urgenza
3. Costruisci un JSON con: cliente, opportunità, tipo, data, importo, probabilità,
   prossimi passi, contatti menzionati... (30+ campi)
4. Scrivi una narrativa di stato, un briefing di riunione e uno script di chiamata
5. Aggiorna il riassunto cumulativo del cliente e dell'opportunità, fondendolo
   con lo storico senza perdere informazioni precedenti

Rispondi sempre in JSON con questo formato: {...}

Genericamente corretto e molto difficile da mantenere. Chiedere di “rispondere in JSON” in testo libero — invece di forzare l’output tramite schema — provoca errori di parsing con una certa regolarità, e qualsiasi aggiustamento di tono al punto 4 rischia di rompere il punto 3, perché i due vivono nello stesso blocco di testo.

Dopo: un prompt, un lavoro, una tecnica diversa per ciascuno

Passo 1 — Rilevamento. Prompt corto, modello leggero, temperatura 0, e output forzato tramite tool calling invece di chiedere JSON in prosa:

const result = await client.messages.create({
  model: "modello-leggero",
  temperature: 0,
  system: "Rileva gli eventi commerciali nel testo. Nient'altro.",
  tools: [{
    name: "eventi_rilevati",
    input_schema: {
      type: "object",
      properties: {
        eventi: {
          type: "array",
          items: {
            type: "object",
            properties: {
              tipo: { enum: ["riunione", "offerta", "obiezione", "chiusura"] },
              frammento: { type: "string" }
            },
            required: ["tipo", "frammento"]
          }
        }
      },
      required: ["eventi"]
    }
  }],
  tool_choice: { type: "tool", name: "eventi_rilevati" }
});

Forzare l’output tramite schema invece di chiedere “rispondi in JSON” elimina alla radice un’intera categoria di errori: JSON mal chiuso, commenti infilati, campi inventati che non erano nel contratto. Il passo 3 del prompt originale — quello che dava più errori silenziosi — è scomparso quasi del tutto solo con questo cambiamento.

Passo 2 — Strutturazione. Stesso pattern, schema più grande, ma un unico lavoro: convertire un evento già rilevato in un record. Non decide cosa è rilevante né scrive una sola riga di narrativa; questo lo ha già risolto il passo 1 e lo risolverà il passo 5.

Passo 5 — Arricchimento. Qui cambia quasi tutto il resto: temperatura alta (0.7-0.8), il modello principale, e un system prompt che non compete più per spazio con regole di formato:

Sei [la voce dell'assistente]. Il tuo unico compito è scrivere, a partire da questo
record già strutturato e validato, una narrativa breve per il commerciale:
cosa è successo, cosa è in gioco nel prossimo passo, come aprire la prossima chiamata.

Tono: diretto, vicino, senza riempitivi aziendali.
Non inventare dati che non sono nel record.

Quel prompt non ha regole di formato JSON, né definizioni di campo, né logica di classificazione. Solo tono e un compito. È la differenza tra chiedere a qualcuno di scrivere bene e chiedergli di scrivere bene mentre compila un modulo di trenta campi allo stesso tempo.

Tre tecniche che hanno cambiato le cose più del ridisegno in sé

  • Tool calling / structured outputs in ogni passo operativo, mai “rispondi in JSON” in testo libero. È il cambiamento con il miglior rapporto sforzo-beneficio di tutto il progetto: trasforma un errore di parsing imprevedibile in un errore di validazione dello schema, che si può catturare e riprovare.
  • Prompt caching del contesto condiviso. I passi 2, 3 e 4 riutilizzano buona parte dello stesso contesto — l’evento rilevato, le regole di business del dominio —. Mettere in cache quel blocco evita di pagarlo per intero come token nuovi in ciascuna delle tre chiamate parallele.
  • Un dataset di valutazione per passo, non uno globale. Prima di toccare un prompt in produzione, lo facciamo passare per 20-30 casi di esempio con output atteso per quella fase specifica. Senza questo, ogni aggiustamento di prompt è un esperimento senza controllo: puoi migliorare il rilevamento e non accorgerti di aver rotto il consolidamento finché un cliente non lo nota.

Niente di tutto questo è esotico né richiede una nuova libreria. È prompting di base — temperatura per compito, schema invece di prosa, contesto in cache, valutazione per fase — applicato in modo disciplinato, passo dopo passo, invece che ammassato in un unico blocco di testo.

Le regole che ne abbiamo ricavato

Se hai una funzionalità IA che fa troppo in un’unica chiamata, questo è l’ordine con cui la affronteremmo oggi:

1. Separa i dati dalla narrativa. È la divisione più redditizia di tutte e quasi sempre esiste. I campi operativi sono brevi, deterministici e validabili contro uno schema. I testi narrativi sono lunghi, soggettivi e traggono vantaggio da un prompt con personalità. Mescolarli obbliga il modello a cambiare registro a metà generazione e rende costosa ogni rigenerazione: se vuoi solo ritoccare il tono di un briefing, non dovresti dover riestrarre i dati.

2. Manda in background tutto ciò che l’utente non legge adesso. Il criterio non è l’importanza, è il momento del consumo. Un riassunto che verrà letto domani prima di una riunione può impiegare 20 secondi a generarsi. Un dato che appare a schermo al salvataggio, no.

3. Parallelizza per dipendenze reali, non per ordine logico. È facile concatenare i passi nell’ordine in cui li hai pensati. Disegna di cosa ha bisogno davvero ogni passo: nel nostro caso, tre dei cinque dipendevano solo dal primo.

4. Usa il modello economico dove non c’è giudizio. Classificare, rilevare ed estrarre modifiche esplicite è lavoro meccanico. Non serve il modello più costoso: servono istruzioni chiare e temperatura bassa. Riserva il modello buono a dove c’è interpretazione.

5. Comincia misurando, non ottimizzando. Suddividere per osservare è un passo con valore proprio anche se non migliora i tempi. Senza misure per fase, ottimizzare è indovinare.

Cosa ti costa questa architettura

Chiunque ti venda pipeline di agenti senza raccontarti questa parte ti sta vendendo la metà.

Più punti di guasto. Cinque chiamate sono cinque cose che possono andare in timeout, restituire JSON rotto o fermarsi a metà. Servono retry per passo, validazione di schema su ogni output e una politica chiara su cosa fare quando fallisce un passo in background (riprovare? lasciarlo vuoto? avvisare?). Quel codice non esisteva quando era tutto una chiamata sola.

Token di input ripetuti. Ogni passo ha bisogno della sua parte di contesto, e c’è contesto che viaggia in più chiamate. Il costo di input sale. Nel nostro caso è stato ampiamente compensato dal calo dei token di output — quelli cari — e dalla cache dei prompt, ma è un conto da fare, non da dare per scontato.

Coerenza di voce. Separando la narrativa in un passo a sé, quel passo non vede più il prompt completo con tutta la personalità dell’assistente. Se non gli passi abbastanza contesto di tono, il risultato esce corretto ma piatto. Ci sono volute un paio di iterazioni per calibrarlo.

Orchestrazione vera. Qualcuno deve gestire il parallelismo, i timeout, l’ordine di scrittura in database e cosa succede se il passo in background finisce dopo che l’utente ha modificato il record a mano. È lavoro di ingegneria normale, ma è lavoro.

Nessuno di questi compromessi ci ha fatto dubitare della decisione. Tutti ci hanno fatto dedicare giorni che non avremmo dedicato al mantenimento del monolite.

Il cambiamento più importante non è stato tecnico

C’è un beneficio che non compare in nessuna metrica e che, col tempo, si è rivelato il più prezioso.

In un progetto così ci sono due tipi di conoscenza diversi. C’è quella di chi definisce cosa è un evento commerciale rilevante e come si struttura, che è conoscenza di dominio e di dati. E c’è quella di chi definisce come parla l’assistente, che è conoscenza di prodotto, di tono e di marca. Con un prompt monolitico, quelle due persone modificano lo stesso blocco di testo da 4.000 parole e si pestano i piedi di continuo. Qualsiasi aggiustamento di tono obbliga a rivalidare l’estrazione dei dati, e qualsiasi aggiustamento di estrazione può rovinare la voce.

Separando i passi, ognuno ha un proprietario. Chi definisce la voce itera sul prompt di arricchimento senza toccare nulla dell’operativo. Il team tecnico regola l’estrazione senza riscrivere la personalità. Si può versionare, confrontare e ripristinare separatamente.

Detto in altro modo: abbiamo smesso di cercare di far fare tutto al modello e abbiamo iniziato a progettare come volevamo che pensasse. E l’effetto collaterale è stato che è diventato chiaro anche chi decide cosa.

Come replicarlo nel tuo progetto

Se sei al punto di partenza — una funzionalità IA che va bene nella demo e così così in produzione — l’ordine che seguiremmo è:

  1. Strumenta prima di toccare qualsiasi cosa. Misura latenza, token di input e di output per richiesta. Se non sai dire quanti token genera il tuo caso peggiore, non sai ancora qual è il tuo problema.
  2. Elenca le responsabilità del prompt attuale. Se enumerandole ti escono più di tre verbi diversi (rilevare, classificare, redigere, consolidare…), hai una pipeline nascosta dentro un prompt.
  3. Suddividi e misura, senza ottimizzare. Accetta che la prima versione suddivisa migliori poco. L’obiettivo è vedere.
  4. Disegna il grafo delle dipendenze reali e parallelizza ciò che non dipende dal resto.
  5. Togli dal percorso critico tutto ciò che è narrativo e restituiscilo quando è pronto.
  6. Fissa una valutazione per passo prima di continuare a ottimizzare: un insieme di input di esempio con output attesi, per ogni fase. Senza questo, ogni miglioramento di velocità è una scommessa sulla qualità.

Il punto 6 è quello che più persone saltano e quello che costa di più. Un’architettura modulare senza valutazione per modulo è un’architettura modulare di cui non sai se funziona.

Niente di tutto questo ha richiesto un modello migliore, né più budget di token, né una libreria di agenti. Ha richiesto di decidere cosa dovesse pensare il modello in ogni momento — e quel cambiamento, misurato, è valso 48 secondi per ogni voce.


Se stai costruendo funzionalità IA sopra LLM e ti trovi con tempi di risposta che non tornano, o con un prompt che ormai nessuno del team osa toccare, parliamone. È uno schema che abbiamo visto abbastanza volte da riconoscerlo in fretta.

E se ti interessa la parte economica di questa decisione, in quanto costa davvero eseguire LLM in produzione analizziamo i numeri di token, infrastruttura e ottimizzazione con dati attuali.

Non perderti nulla

JM

Javier Manzano

CEO & Co-founder in Soamee

Appassionato di tecnologia e sviluppo software. Condividendo conoscenze e esperienze per aiutare altri sviluppatori a crescere.

Ti è piaciuto questo articolo?

Se hai bisogno di aiuto con il tuo progetto di sviluppo, siamo qui per te.

Mega-prompt vs pipeline LLM: da 58s a 14s

Raccontaci la tua sfida. Ti proponiamo la soluzione.

Senza impegno. In meno di 24 ore riceverai una proposta con ambito, tempistiche e budget. Nessuna clausola nascosta.

Prenota una call gratuita →