22 settembre 2026
Harness engineering: come sono evoluti i “trucchi” che fanno funzionare davvero gli agenti
Dal prompt singolo ai grafi di lavoro, fino a sistemi che ottimizzano se stessi: una mappa pratica delle idee che stanno ridisegnando l’infrastruttura tra modello e mondo.
Quando un assistente AI sembra “intelligente”, spesso lo è grazie a tutto ciò che lo circonda: prompt, tool, parser, loop, metriche, orchestrazione e controlli. In questo articolo ripercorro l’evoluzione delle principali tecniche di harness engineering (i cosiddetti harness hacks) e provo a mettere ordine in tre grandi traiettorie: la forma del lavoro, quanto il modello assorbe il harness e la scala operativa. Con implicazioni concrete per chi costruisce agenti, automazioni e prodotti AI in ambienti reali (Slack, IDE, API, sistemi aziendali).
Costruire agenti AI non significa “scrivere un prompt migliore”. Significa progettare un harness: tutto ciò che si frappone tra il mondo reale (utenti, file, API, database, UI, policy) e il modello (inferenzia, genera token, chiama strumenti). L’harness è l’ingegneria che rende l’AI operativa: affidabile, veloce, controllabile, integrabile.
Negli ultimi anni abbiamo visto una progressione chiara: ogni volta che il solo testo non bastava, abbiamo aggiunto struttura attorno al modello. E ogni volta che quella struttura diventava troppo complessa, abbiamo trovato un modo per farla “mangiare” al modello, oppure per delegare al modello la sua stessa ottimizzazione.
Qui metto in fila i passaggi più utili da capire — non come cronologia da museo, ma come cassetta degli attrezzi per chi costruisce prodotti agentici.
Cos’è un harness (in pratica)
Un harness è tutto ciò che sta tra “il mondo” e “il modello”:
- prompt di sistema e istruzioni
- esempi few-shot / template
- orchestrazione (catene, loop, grafi)
- tool calling, sandbox, permessi
- parser, validatori, schemi
- memoria (short/long-term), retrieval
- policy, guardrail, auditing
- telemetria, metriche, valutazioni
- persino parti del decoding e dell’inference pipeline, quando vengono usate per vincolare l’output
Se un agente in produzione “automatta mezza azienda”, non è magia: è harness engineering fatto bene.
1) Dal few-shot alla “programmazione” via prompt
All’inizio i modelli non “seguivano istruzioni”: completavano testo. Il primo hack funzionale è stato rendere l’output desiderato il più probabile possibile.
Few-shot: esempi come priming
Mettere esempi prima del task serve a impostare lo stato latente: il modello riconosce pattern e li continua.
Zero-shot: istruzione diretta
A un certo punto si è capito che, spesso, un’istruzione ben scritta può portare a uno stato interno simile agli esempi. Nasce l’idea di prompt programming: non solo “chiedere”, ma progettare un input per ottenere una distribuzione di output più utile.
Implicazione pratica: prima di introdurre tool e framework, verifica se il comportamento desiderato è ottenibile con una sola variazione di framing. È la leva a costo più basso.
2) Catene: quando un prompt non basta
Quando il lavoro diventa composto (ricerca → sintesi → trasformazione → verifica), un singolo passaggio degrada.
La risposta è stata spezzare il compito in più prompt: le chains. Non è solo “più chiamate”, è progettare passaggi con output intermedi che riducono ambiguità e aumentano controllabilità.
Implicazione pratica: catene = debuggabilità. Se non riesci a spiegare perché un agente fallisce, spesso è perché stai chiedendo troppo in un passo solo.
3) Loop: ReAct e il lavoro con side effect
Con l’arrivo degli agenti “che fanno cose”, il testo non è più innocuo: produce azioni che cambiano lo stato del mondo.
Il pattern base diventa un loop:
- osservazione (stato, output tool)
- ragionamento (piano/decisione)
- azione (tool call)
- nuova osservazione
Questo è il cuore di gran parte degli agenti moderni: l’harness non genera solo testo, ma gestisce un ciclo di interazione con l’ambiente.
Implicazione pratica: se un agente è instabile, spesso non è “colpa del modello”, ma di un loop progettato male: osservazioni incomplete, azioni troppo potenti, mancanza di controlli o di criteri di stop.
4) Aumentare le dimensioni: dall’albero al “best path”
Dopo catene e loop, la naturale estensione è esplorare più alternative.
Tree of Thoughts (e varianti)
Invece di un’unica traiettoria, si generano più rami, si valuta e si sceglie.
- Pro: più probabilità di trovare una soluzione corretta
- Contro: costi di inference più alti (token, tool calls, tempo)
Implicazione pratica: utile quando il costo dell’errore è alto (migrazioni, refactor complessi, query delicate), meno quando serve latenza bassa.
5) Output affidabile: dal “premio in JSON” ai vincoli nel decoding
Molti team hanno provato a ottenere JSON valido promettendo ricompense testuali o minacciando retry. Funziona… finché non funziona.
Un salto di qualità arriva quando sposti l’affidabilità dalle parole alle regole:
- parsing strutturato
- schema validation
- grammar-constrained decoding: il decoder ammette solo token compatibili con una grammatica
Qui l’inference pipeline diventa parte del harness: non “speri” nel formato, lo imponi.
Implicazione pratica: se l’output alimenta sistemi downstream (UI, DB, workflow), vincolare il decoding è spesso più efficace di qualsiasi prompt.
6) Prompt che ottimizzano prompt: hill climbing sul linguaggio
Un’altra svolta è usare i modelli per esplorare lo spazio dei prompt e migliorare una metrica.
L’idea è semplice:
- definisci un obiettivo misurabile
- generi varianti di prompt
- valuti
- tieni i migliori e iteri
Sembra banale, ma cambia la mentalità: non cerchi “il prompt giusto”, costruisci una procedura di ottimizzazione.
Implicazione pratica: appena hai una metrica affidabile (accuracy, pass rate, human rating, cost/latency), ha senso trasformare il prompting in un ciclo sperimentale ripetibile.
7) Sampling massivo e selezione: qualità via quantità
Un pattern sempre più comune: generare molte soluzioni e selezionare le migliori.
- ripeti la generazione N volte
- valuti con rubriche, test, esecuzione, self-check
- scegli la traiettoria migliore
È un modo pragmatico per ottenere qualità senza aspettare “il modello perfetto”. Ed è anche un ponte verso sistemi che migliorano col tempo, perché le traiettorie migliori diventano dati preziosi.
Implicazione pratica: per codegen, l’accoppiata “molte candidate + test automatici” spesso batte qualunque prompt sofisticato.
8) Oltre la context window: spezzare il lavoro su più finestre
Quando i task superano i limiti del contesto, smetti di comprimere tutto in un prompt.
La strategia efficace è distribuire:
- segmenti di lavoro in finestre separate
- contesti “freschi” per ciascun segmento
- consolidamento finale
In pratica: invece di forzare il modello in condizioni peggiori di quelle per cui è ottimizzato, lo riporti in una zona “nativa”.
Implicazione pratica: per analisi di codebase grandi, è spesso meglio pianificare una pipeline di chunking + subtask + merge, anziché aumentare il contesto e sperare.
9) Il modello “mangia” il harness: agenti che si costruiscono gli strumenti
Un cambio di paradigma: invece di progettare un harness enorme, parti minimale e lasci che il modello lo estenda.
Esempio tipico:
- pochi tool fondamentali (es. eseguire comandi, leggere/scrivere file)
- il modello decide come combinare, creare wrapper, definire routine
Qui sfrutti un fatto scomodo ma vero: i modelli hanno assorbito moltissima conoscenza su tool, pattern di orchestrazione e “come ci si aspetta che funzioni un agente”, perché questi pattern compaiono ovunque nei dati.
Implicazione pratica: riduci configurazione manuale e boilerplate, ma aumenta la necessità di policy, permessi, sandbox e osservabilità. Un agente che si auto-estende è potente e pericoloso se non lo contieni.
10) Prestazioni: eseguire codice mentre i token arrivano
Quando l’AI diventa commodity, la latenza diventa intollerabile: nessuno aspetta decine di secondi per il primo risultato.
Un hack interessante è speculative tool execution:
- il modello inizia a generare una chiamata a tool / funzione
- appena è sintatticamente valida, la esegui subito
- quando il modello termina, hai già risultati pronti da reiniettare
Invece di aspettare token, sfrutti che l’esecuzione di funzioni può essere più veloce e parallelizzabile.
Implicazione pratica: se la tua UX soffre sul “time-to-first-useful-result”, valuta strategie speculative soprattutto su tool deterministicamente sicuri (letture, calcoli, query con limiti rigidi).
Tre traiettorie per capire cosa sta succedendo (e cosa progettare)
Guardando questi hack, emergono tre direzioni ricorrenti.
A) La forma del lavoro: testo → catena → loop → albero → grafo
La prossima forma naturale non è “più catene”, ma grafi di lavoro:
- fan-out / fan-in
- parallelismo
- join e barriere
- branch condizionali
- retry mirati
- dipendenze esplicite tra risultati intermedi
Un grafo può contenere catene e loop come casi particolari, ma offre un modello mentale più adatto al lavoro reale.
B) Il modello assorbe il harness
Sempre più spesso:
- servono meno istruzioni fisse
- servono più contratti (schema, policy, vincoli)
- il modello può proporre (o scegliere) la strategia di esecuzione
In altre parole: meno “prompt lunghi”, più “sistemi che valutano e vincolano”.
C) La scala cresce: da una call a una “città di esperti”
Sampling, sub-agent, parallelismo, grafi: la tendenza è amplificare la capacità tramite molte istanze coordinate, non solo tramite un modello più grande.
Cosa significa per chi costruisce prodotti (frontend e non solo)
Se stai integrando agenti in strumenti reali (IDE, ticketing, Slack/Teams, dashboard interne), le implicazioni pratiche sono abbastanza nette:
- Tratta il prompting come UI/UX del ragionamento, ma non come unica leva.
- Metti struttura dove serve affidabilità: schema, parsing, vincoli nel decoding.
- Preferisci grafi a catene monolitiche quando il task ha dipendenze e parallelismo.
- Progetta metriche e telemetria: senza segnali chiari, non ottimizzi nulla; “hill climbing” richiede feedback.
- Contieni la potenza: sandbox, permessi, rate limit, audit. Più l’agente è autonomo, più l’harness deve essere robusto.
Sintesi finale
L’harness engineering è l’arte di trasformare un generatore di testo in un sistema che lavora: osserva, decide, agisce, verifica e migliora. La storia recente mostra un pattern ripetibile: quando un approccio si satura (prompt), aggiungiamo struttura (catene/loop/grafi), poi rendiamo quella struttura ottimizzabile (hill climb), e infine deleghiamo parte della progettazione al modello stesso — mantenendo però vincoli e metriche sempre più rigorosi.
Se c’è una regola pratica che vale oggi: meno fiducia cieca nell’output, più ingegneria attorno al processo. È lì che gli agenti diventano prodotti.