Skip to content
Luca Zanchi / Tech Blog

Progettare software comprensibile anche dagli agenti AI

Integrare un agente AI in un processo software può sembrare relativamente semplice.

Si sceglie un modello, si prepara un prompt, si espongono alcuni strumenti e si permette all’agente di leggere informazioni o avviare operazioni.

Una prima dimostrazione può funzionare in poco tempo.

L’agente consulta un documento, analizza un repository, genera una query, compila una risposta oppure utilizza un’API per modificare un dato.

Il risultato iniziale è spesso convincente perché mostra una capacità nuova: il software non si limita più a eseguire una sequenza definita in anticipo, ma può interpretare una richiesta e scegliere quali azioni compiere.

Il problema emerge quando quella dimostrazione deve diventare parte di un processo reale.

A quel punto compaiono domande meno spettacolari, ma molto più importanti:

Un agente può essere tecnicamente capace e produrre comunque risultati poco affidabili se il sistema che lo circonda è ambiguo.

Per questo l’agent readiness non dipende soltanto dalla qualità del modello.

Dipende dalla capacità del software e dell’organizzazione di rendere espliciti il contesto, i contratti, i permessi, lo stato e le procedure operative.

In altre parole, un sistema comprensibile per un agente deve essere prima di tutto un sistema progettato per essere compreso.

1. Un agente non conosce implicitamente il sistema

Le persone che lavorano a lungo su un’applicazione accumulano una grande quantità di conoscenza non documentata.

Sanno, per esempio:

Queste informazioni raramente si trovano tutte nello stesso posto.

Una parte vive nel codice, una nella documentazione, una nei ticket, una nelle conversazioni e una nella memoria delle persone.

Un agente non possiede automaticamente questo contesto.

Può leggere ciò che gli viene fornito, usare gli strumenti disponibili e inferire alcune relazioni. Non può però sapere con certezza quali convenzioni siano ancora valide o quali comportamenti impliciti siano importanti.

Se chiediamo a un agente di “aggiornare il cliente nel gestionale”, la richiesta può nascondere molte decisioni:

Per una persona esperta del processo, alcune risposte possono sembrare ovvie.

Per l’agente, ciò che non è esplicito deve essere dedotto. E ogni deduzione introduce incertezza.

2. L’agent readiness non è una proprietà del modello

Quando un agente produce un risultato errato, è naturale attribuire il problema al modello.

A volte è corretto. Il modello può interpretare male una richiesta, ignorare un vincolo o generare informazioni non attendibili.

In molti casi, però, il problema si trova nell’ambiente in cui gli è stato chiesto di operare.

L’agente può aver ricevuto:

Migliorare il prompt può attenuare alcuni problemi, ma non sostituisce la progettazione del sistema.

Un prompt molto dettagliato non risolve un’API incoerente. Non definisce la fonte autorevole di un dato. Non impedisce a uno strumento pericoloso di eseguire un’operazione distruttiva. Non rende verificabile un processo che non registra il proprio stato.

Considero quindi l’agent readiness una proprietà distribuita.

Dipende contemporaneamente da:

Il modello è soltanto uno dei componenti.

3. Cinque segnali che un sistema non è pronto per gli agenti

Alcuni problemi diventano visibili già durante le prime prove.

3.1 Il prompt deve spiegare ogni volta come funziona il sistema

Se ogni attività richiede un prompt molto lungo che ricostruisce architettura, regole, convenzioni e vincoli, il contesto non è realmente disponibile all’agente.

Il prompt sta compensando una mancanza strutturale.

Una certa quantità di istruzioni sarà sempre necessaria. Il problema emerge quando le informazioni essenziali devono essere copiate manualmente per ogni richiesta.

Questo approccio produce:

Il contesto stabile dovrebbe vivere vicino al sistema e poter essere recuperato in modo controllato.

Il prompt dovrebbe descrivere soprattutto l’obiettivo specifico, non ricostruire ogni volta l’intera organizzazione.

3.2 Gli strumenti espongono operazioni troppo generiche

Uno strumento chiamato execute_query, run_command o update_record può essere molto potente.

Può anche essere troppo ambiguo.

L’agente deve decidere autonomamente:

Più uno strumento è generico, più la correttezza dipende dalla capacità dell’agente di ricostruire vincoli non espressi.

In molti contesti è preferibile esporre operazioni più specifiche, come:

Questi strumenti incorporano parte del contratto operativo e riducono lo spazio delle azioni possibili.

3.3 Non è chiaro quando il lavoro sia completato

Un agente può produrre una risposta plausibile senza aver completato realmente il processo.

Può modificare un file senza eseguire i test. Può inviare una richiesta senza verificarne l’esito. Può generare una query corretta sintatticamente, ma non controllare i dati restituiti.

Se il sistema non definisce criteri di completamento, l’agente tende a fermarsi quando il risultato appare ragionevole.

Per un’attività tecnica, invece, il completamento può richiedere:

Senza una definizione esplicita di “fatto”, l’output dell’agente rimane difficile da valutare.

3.4 I permessi riflettono quelli di un amministratore

Durante una demo è comune fornire all’agente credenziali ampie per evitare ostacoli.

In un processo reale, questa scelta rende difficile limitare l’impatto di un errore.

Un agente che può leggere e modificare qualsiasi risorsa non è necessariamente più utile. È semplicemente più difficile da controllare.

I permessi dovrebbero riflettere l’attività specifica:

Un agente dovrebbe poter fare ciò che serve, non tutto ciò che tecnicamente è possibile.

3.5 Nessuno riesce a ricostruire le sue decisioni

Quando un agente utilizza più strumenti, è importante poter ricostruire almeno:

Non è necessario registrare ogni dettaglio interno del modello.

È però necessario conservare una traccia operativa sufficiente a comprendere il comportamento del sistema.

Se un risultato non può essere ricostruito, diventa difficile correggere un errore, migliorare il workflow o attribuire responsabilità.

4. Il contesto deve essere selezionabile, non semplicemente abbondante

Fornire più informazioni non garantisce risultati migliori.

Un agente può ricevere una grande quantità di documenti e trovare comunque difficile individuare quelli rilevanti.

Il problema non è soltanto la disponibilità del contesto, ma la sua qualità.

Un contesto utile dovrebbe essere:

Supponiamo che un agente debba modificare un servizio.

Potrebbe aver bisogno di:

Se questi materiali esistono ma contengono versioni contraddittorie, l’agente deve scegliere autonomamente quale seguire.

La quantità di informazioni aumenta, ma aumenta anche l’ambiguità.

4.1 Separare contesto stabile e contesto operativo

È utile distinguere tra informazioni relativamente stabili e informazioni legate alla singola esecuzione.

Il contesto stabile può comprendere:

Il contesto operativo può comprendere:

Questa separazione rende più semplice aggiornare le informazioni e fornire all’agente soltanto ciò che serve.

4.2 Rendere visibile la provenienza

Un’informazione senza fonte è difficile da valutare.

L’agente dovrebbe poter distinguere, per esempio, tra:

La provenienza aiuta a stabilire il livello di affidabilità e a gestire eventuali conflitti.

4.3 Riconoscere il contesto scaduto

La documentazione obsoleta è pericolosa perché appare autorevole pur descrivendo un sistema che non esiste più.

Per ridurre questo rischio sono utili:

La manutenzione del contesto diventa quindi una parte dell’infrastruttura dell’agente.

5. Contratti espliciti per strumenti e API

Un agente interagisce con il software attraverso strumenti.

Uno strumento può essere una funzione, un endpoint, un comando, una query predefinita o un workflow.

Per essere utilizzabile in modo affidabile, dovrebbe avere un contratto chiaro.

Nome dello strumento
↓
Scopo
↓
Input ammessi
↓
Precondizioni
↓
Effetti
↓
Output
↓
Errori possibili

5.1 Nomi orientati all’intenzione

Il nome dovrebbe esprimere l’operazione dal punto di vista del dominio.

update_data comunica poco.

update_customer_shipping_address rende più evidente:

Nomi più specifici aiutano l’agente a scegliere lo strumento corretto e rendono più leggibile la traccia delle operazioni.

5.2 Input limitati e validabili

Gli input dovrebbero essere strutturati e, quando possibile, vincolati.

Invece di accettare una stringa generica, uno strumento può richiedere:

La validazione riduce gli errori prima che l’operazione raggiunga il sistema destinatario.

5.3 Effetti dichiarati

Uno strumento dovrebbe chiarire se:

Questa distinzione è importante per applicare permessi, approvazioni e controlli differenti.

5.4 Errori comprensibili

Un messaggio come operation failed fornisce poche informazioni.

È più utile distinguere tra:

L’agente può reagire correttamente soltanto se il sistema rende comprensibile la natura del fallimento.

6. Esporre capacità, non accesso indiscriminato

Una delle decisioni principali riguarda il livello al quale esporre il sistema.

Un agente potrebbe ricevere accesso diretto al database, alla shell o a un’API amministrativa.

Questo offre grande flessibilità, ma trasferisce all’agente molte responsabilità:

Un’alternativa consiste nell’esporre capacità più delimitate.

Accesso generico
Database → qualsiasi query
Capacità delimitata
Servizio clienti → recupera cliente
→ mostra ordini aperti
→ prepara correzione
→ richiede approvazione
→ applica modifica

La seconda soluzione può sembrare meno potente, ma è spesso più affidabile.

Le capacità delimitate:

L’obiettivo non dovrebbe essere offrire all’agente il massimo numero di possibilità.

Dovrebbe essere offrirgli il minimo insieme di capacità sufficiente a completare il processo.

7. Separare lettura, proposta ed esecuzione

Non tutte le attività devono essere automatizzate allo stesso livello.

Una distinzione utile è quella tra:

  1. raccolta delle informazioni;
  2. elaborazione di una proposta;
  3. applicazione della modifica.
Osservazione
↓
Proposta
↓
Verifica
↓
Esecuzione

Un agente può essere autorizzato a leggere dati e preparare una soluzione senza poterla applicare direttamente.

Questo schema è utile quando:

7.1 Lettura

L’agente raccoglie informazioni e ricostruisce lo stato.

In questa fase può:

I rischi operativi sono limitati, ma rimangono importanti quelli relativi alla riservatezza e all’accesso ai dati.

7.2 Proposta

L’agente prepara un’azione senza eseguirla.

Può generare:

La proposta deve essere rappresentata in una forma verificabile da una persona o da un controllo automatico.

7.3 Esecuzione

L’azione viene applicata soltanto quando sono soddisfatte le condizioni previste.

Queste possono includere:

Separare le fasi rende più semplice introdurre gradualmente l’automazione senza affidare immediatamente all’agente il controllo completo del processo.

8. Definire confini e permessi

La gestione dei permessi non dovrebbe essere aggiunta dopo la realizzazione del workflow.

Fa parte del suo comportamento.

8.1 Principio del minimo privilegio

L’agente dovrebbe disporre soltanto dei permessi necessari per l’attività corrente.

Un agente che analizza errori non ha necessariamente bisogno di modificare dati. Un agente che prepara una pull request non deve poter distribuire direttamente in produzione.

Ridurre i privilegi limita l’impatto di:

8.2 Permessi legati al contesto

La stessa operazione può richiedere autorizzazioni differenti in base all’ambiente o ai dati coinvolti.

Per esempio:

I confini dovrebbero essere applicati dal sistema, non affidati esclusivamente alle istruzioni testuali.

8.3 Autorizzazioni temporanee

Alcune capacità possono essere concesse soltanto per una singola attività o per un periodo limitato.

Questo riduce il rischio che credenziali ampie rimangano disponibili oltre il necessario.

8.4 Operazioni irreversibili

Le azioni distruttive richiedono una gestione specifica.

Quando possibile, considero preferibile:

Un agente non dovrebbe poter eseguire un’operazione irreversibile soltanto perché ha interpretato una richiesta come autorizzazione sufficiente.

9. Rendere il workflow esplicito

Molti processi funzionano perché le persone conoscono l’ordine corretto delle attività.

Un agente ha bisogno che quell’ordine sia rappresentato.

Un workflow operativo può specificare:

Obiettivo
↓
Precondizioni
↓
Raccolta delle informazioni
↓
Scelta dell’azione
↓
Controlli
↓
Approvazione eventuale
↓
Esecuzione
↓
Verifica
↓
Registrazione dell’esito

9.1 Precondizioni

Prima di iniziare, deve essere possibile verificare che il sistema si trovi in uno stato compatibile con l’operazione.

Per esempio:

9.2 Condizioni di arresto

Un agente deve sapere anche quando non procedere.

Può essere necessario fermarsi quando:

Fermarsi non rappresenta necessariamente un fallimento.

In un processo controllato, riconoscere l’incertezza è spesso il comportamento corretto.

9.3 Criteri di completamento

Il workflow deve definire quale evidenza dimostra che l’attività è conclusa.

Una modifica al codice può essere considerata completa quando:

Questi criteri aiutano l’agente a non confondere la produzione di un output con il completamento del lavoro.

10. Verifica automatica e supervisione umana

La supervisione umana non deve essere necessariamente presente in ogni passaggio.

Dovrebbe concentrarsi nei punti in cui il giudizio, il rischio o l’ambiguità sono maggiori.

10.1 Verifiche automatiche

Molti risultati possono essere controllati attraverso regole deterministiche:

Questi controlli sono particolarmente utili perché non dipendono dalla stessa capacità probabilistica che ha generato la proposta.

10.2 Revisione umana

La revisione umana è più utile quando riguarda:

Il revisore deve però ricevere informazioni sufficienti.

Una richiesta di approvazione generica, priva del contesto e delle conseguenze, trasferisce semplicemente il problema alla persona.

Una buona richiesta dovrebbe includere:

10.3 Livelli progressivi di autonomia

L’autonomia può crescere nel tempo.

Un possibile percorso è:

  1. l’agente osserva e sintetizza;
  2. propone azioni;
  3. esegue azioni reversibili dopo approvazione;
  4. esegue autonomamente attività a basso rischio;
  5. richiede supervisione soltanto per eccezioni definite.

Questa progressione permette di raccogliere evidenze prima di aumentare i privilegi.

11. Osservabilità e audit

Un workflow con agenti deve essere osservabile come qualsiasi altro processo operativo.

La presenza di un modello non riduce questa necessità. La rende più importante, perché alcune decisioni non derivano da una sequenza completamente deterministica.

Una traccia operativa dovrebbe includere almeno:

11.1 Correlare tutte le operazioni

Ogni passaggio dovrebbe essere collegato allo stesso identificativo.

Task: TASK-2048
↓
Contesto recuperato
↓
Repository analizzato
↓
Modifica proposta
↓
Test eseguiti
↓
Revisione approvata
↓
Pull request creata

Questo consente di ricostruire il percorso completo senza cercare manualmente tra sistemi differenti.

11.2 Registrare gli effetti, non soltanto le richieste

Sapere che l’agente ha chiamato uno strumento non dimostra che l’operazione abbia prodotto il risultato desiderato.

È necessario registrare anche:

11.3 Proteggere i dati dell’audit

I log possono contenere informazioni sensibili, prompt, dati personali o credenziali.

L’osservabilità deve quindi essere progettata insieme alle regole di:

Registrare tutto senza criteri può creare un nuovo rischio.

12. Il ruolo della documentazione

Un sistema pronto per gli agenti non richiede necessariamente una documentazione enorme.

Richiede documentazione utilizzabile.

È utile che le informazioni siano:

12.1 Documentare le decisioni

Il codice mostra spesso come funziona il sistema, ma non perché sia stato progettato in un certo modo.

Decisioni architetturali brevi possono spiegare:

Queste informazioni aiutano sia le persone sia gli agenti a evitare modifiche che contraddicono vincoli non visibili nel codice.

12.2 Preferire informazioni verificabili

Una documentazione che descrive manualmente ogni endpoint può diventare obsoleta.

Quando possibile, è preferibile generare o verificare parte delle informazioni attraverso:

Più il contesto è collegato al sistema effettivo, minore è il rischio che diverga dalla realtà.

12.3 Esplicitare i limiti

La documentazione dovrebbe descrivere anche ciò che il sistema non garantisce.

Per esempio:

Un limite esplicito è più utile di una promessa generica di affidabilità.

13. Un esempio: agente per la gestione di sincronizzazioni fallite

Consideriamo un agente incaricato di assistere nella gestione degli errori tra e-commerce ed ERP.

Un’implementazione poco controllata potrebbe fornirgli:

L’agente dovrebbe ricostruire autonomamente:

Un workflow più esplicito potrebbe invece esporre queste capacità:

list_failed_order_syncs
↓
get_sync_details
↓
classify_sync_error
↓
prepare_retry
↓
validate_retry
↓
request_approval
↓
execute_retry
↓
verify_order_state

Ogni strumento avrebbe input e output definiti.

L’agente non riceverebbe accesso generico all’ERP. Utilizzerebbe operazioni specifiche che applicano controlli e registrano gli effetti.

Il workflow potrebbe inoltre stabilire che:

In questo scenario, l’agente non sostituisce il processo.

Opera all’interno di un processo progettato per limitare ambiguità e rischio.

14. Preparare progressivamente un sistema esistente

Non è necessario riprogettare l’intera architettura prima di sperimentare con gli agenti.

È però utile evitare di compensare ogni mancanza attraverso prompt sempre più complessi.

Un percorso progressivo può partire da alcuni interventi.

14.1 Individuare un processo delimitato

Il primo caso d’uso dovrebbe avere:

Attività troppo ampie, come “gestire l’assistenza” o “mantenere il software”, nascondono un numero elevato di decisioni e responsabilità.

È preferibile iniziare da un compito specifico, come classificare anomalie note o preparare una proposta di modifica.

14.2 Mappare il contesto necessario

Prima di costruire l’agente è utile chiedersi quali informazioni utilizzi oggi una persona per completare l’attività.

Queste possono provenire da:

La mappa rende visibili le dipendenze informative e le conoscenze ancora implicite.

14.3 Rendere espliciti gli strumenti

Le operazioni necessarie possono essere esposte attraverso funzioni specifiche, anche se inizialmente utilizzate soltanto in lettura.

Questo consente di definire:

14.4 Introdurre una fase di proposta

Prima di consentire modifiche automatiche, l’agente può produrre proposte strutturate.

Questa fase permette di valutare:

14.5 Automatizzare soltanto i casi stabili

Dopo aver osservato un numero sufficiente di esecuzioni, alcuni casi possono essere considerati abbastanza prevedibili da non richiedere sempre approvazione.

L’automazione dovrebbe crescere dove esistono evidenze, non dove esiste soltanto entusiasmo.

15. Progettare per gli agenti migliora anche il software per le persone

Molte proprietà necessarie agli agenti sono già desiderabili nei sistemi tradizionali:

Gli agenti rendono più evidenti le lacune perché non possono affidarsi alla conoscenza informale nello stesso modo delle persone.

Se un agente non riesce a stabilire quale sistema possieda un dato, è possibile che anche il team non abbia una risposta realmente condivisa.

Se non esiste un modo sicuro per ripetere un’operazione, il problema riguarda anche gli operatori umani.

Se una modifica può essere verificata soltanto dalla persona che conosce storicamente il sistema, l’organizzazione possiede già una dipendenza fragile.

Da questo punto di vista, progettare per gli agenti può diventare un esercizio utile per migliorare la qualità complessiva dell’architettura.

Costringe a rendere visibili contratti, confini e procedure che in precedenza potevano rimanere impliciti.

16. L’autonomia è il risultato, non il punto di partenza

Il valore di un agente non dipende dal numero di operazioni che può eseguire senza intervento umano.

Dipende dalla capacità di produrre risultati utili all’interno di confini comprensibili.

Un agente molto autonomo, ma privo di contesto affidabile e controlli, può aumentare il lavoro necessario per verificare e correggere i suoi output.

Un agente più limitato può invece generare valore concreto se:

Per questo considero l’autonomia una conseguenza della maturità del processo.

Prima vengono il contesto, i contratti, i controlli e la supervisione.

Poi, dove le evidenze lo consentono, può crescere la delega.

17. Rendere esplicito ciò che oggi è implicito

Integrare un agente AI non significa semplicemente collegare un modello alle API esistenti.

Significa preparare un ambiente nel quale le decisioni possano essere prese e verificate senza dipendere da conoscenze nascoste.

Un sistema è più pronto per gli agenti quando:

Queste proprietà non eliminano l’incertezza dei modelli.

La inseriscono però in un processo capace di contenerla.

L’agent readiness nasce quindi meno dalla capacità di “far fare qualcosa all’AI” e più dalla disciplina con cui rendiamo il software comprensibile, interrogabile e governabile.

Un agente può operare bene soltanto quando il sistema gli permette di capire cosa può fare, quali informazioni deve utilizzare, come verificare il risultato e quando deve fermarsi.

Prima di essere autonomo, deve poter essere affidabile.