Volevo un agente AI che non facesse danni. Sono finito a costruire un framework

Volevo un agente AI che non facesse danni. Sono finito a costruire un framework

By Yuriy Zhar 7 min read
Volevo creare un agente AI per un progetto vero. Tra prompt, policy e casi reali sono finito a costruire un framework open source in Elixir.

All’inizio doveva essere una cosa molto più piccola.

Volevo costruire un agente AI per un progetto vero. Doveva parlare con le persone, capire cosa volevano e fare alcune operazioni dentro l’applicazione.

Ho preparato il prompt, collegato qualche funzione e fatto le prime prove. Funzionava.

O almeno sembrava funzionare.

Poi ho iniziato a farmi domande un po’ fastidiose. Cosa succede se la persona risponde soltanto “sì”? Sì a cosa? E se cambia idea mentre l’azione è già partita? Se il processo si riavvia dopo la conferma ma prima di aver completato l’operazione?

La demo non rispondeva a queste domande. Nella demo tutto andava sempre nel giusto ordine.

Il problema è che le persone non parlano nel giusto ordine.

Freelance Fast mi ha tolto un po’ di illusioni

Uno dei progetti dove volevo provare queste idee era Freelance Fast.

L’idea era semplice. Un cliente scrive su WhatsApp o Telegram e racconta cosa vuole realizzare. L’agente fa qualche domanda, raccoglie le informazioni mancanti e prepara il progetto. Dall’altra parte cerca i freelance compatibili e avvisa soltanto quelli che potrebbero essere interessati.

Freelance Fast per ora non è decollato. Non ha avuto il traffico che speravo e non ha senso far finta del contrario.

Però mi è servito parecchio per capire quanto velocemente un agente apparentemente semplice diventa un casino.

Un cliente può avere un solo progetto attivo. I suoi dati non possono essere salvati prima del consenso. I contatti non devono essere condivisi prima che abbia scelto un freelance. Il progetto deve essere controllato prima di essere inviato.

Nessuna di queste regole richiede una grande intelligenza. Sono semplicemente le regole del prodotto.

All’inizio potevo metterle nel prompt. “Non condividere i contatti prima della selezione”. “Chiedi conferma”. “Non creare un secondo progetto”.

Continuavo ad aggiungere frasi e il prompt diventava una specie di programma scritto in inglese. Solo che non potevo realmente testarlo come un programma e non avevo nessuna garanzia che il modello lo interpretasse sempre nello stesso modo.

Mi sono detto: ok, questa parte non può stare qui.

Il modello può capire cosa sta chiedendo la persona. Può proporre cosa fare. Ma le regole e l’esecuzione devono rimanere nel codice.

Più cercavo di mantenere questa separazione e più uscivano nuovi problemi.

Alla fine è nato Spectre.

Non avevo pianificato di costruire un framework

Spectre non è nato perché pensavo che mancasse “il prossimo grande framework per agenti AI”.

È nato perché mi serviva una policy.

Poi mi serviva uno stato che non sparisse al primo riavvio.

Poi ho separato l’approvazione dall’esecuzione, perché approvare un’azione non significa averla già eseguita. Sembra una distinzione ovvia, però molti agenti trattano tutto come una singola chiamata.

Dopo ho aggiunto il journal. Quando qualcosa andava male volevo capire se il problema era nel modello, nel routing, nella policy oppure nella funzione che eseguiva davvero l’azione.

Un pezzo alla volta mi sono trovato con un runtime intero.

Oggi il codice di Spectre è pubblico su GitHub ed è arrivato alla versione 0.3.3.

Non è finito. È ancora una versione 0.x e alcune cose probabilmente cambieranno ancora. Non voglio fingere che sia un prodotto perfetto e pronto a risolvere qualsiasi progetto AI.

Però adesso ha una forma che mi convince molto più delle prime prove.

Un agente viene descritto come una definizione versionata. Le azioni hanno uno stato. Le policy non sono semplici frasi nel prompt. Il modello può proporre un’operazione, ma non può decidere da solo di eseguirla.

In pratica cerco di evitare che tutto dipenda dalla fiducia nel modello.

E sinceramente io dei modelli mi fido poco. Li uso ogni giorno, li trovo incredibili, ma proprio perché li uso tanto vedo anche quanto possono essere convincenti mentre stanno capendo una cosa sbagliata.

Poi sono comparse tutte le altre repository

A un certo punto Spectre non era più sufficiente da solo.

La memoria, per esempio, non poteva essere semplicemente una chat infinita buttata ogni volta nel prompt. Così ho iniziato a lavorare su Spectre Mnemonic, che gestisce ricordi, ricerca, consolidamento e provenienza dei dati senza confondere tutto con lo stato principale dell’agente.

Quando serviva trovare e preparare azioni in modo controllato è arrivato Spectre Kinetic.

Per permettere all’agente di usare il browser ho creato Spectre Lens. Anche lì la prima idea era “apre una pagina e legge”. Poi inizi a pensare a SSRF, pagine che provano a manipolare il modello, download, tab orfane, campi nascosti e tutto il resto.

Per i lavori più lunghi una conversazione non bastava. Un agente può avere una destinazione, provare una strada, fallire, fare una domanda e riprendere più tardi. Da questo problema è nato Spectre Directive.

Poi ci sono Spectre Beam per i canali esterni, Spectre Prism per scegliere modello e livello di intelligenza in base al lavoro, e Spectre Pulse per la comunicazione tra agenti.

Visto tutto insieme sembra quasi un ecosistema pensato dall’inizio.

Non lo era.

Ogni repository è arrivata quando mi sono accorto che stavo cercando di mettere troppe responsabilità nello stesso posto. Alcune sono già abbastanza mature, altre sono ancora giovani e cambieranno. Sto cercando di non farle diventare dipendenze obbligatorie una dell’altra, altrimenti alla fine avrei soltanto creato un monolite distribuito su dieci repository, che sarebbe abbastanza ridicolo.

Elixir qui mi è sembrato stranamente naturale

Ho usato Elixir perché è il linguaggio con cui lavoro di più. Non c’era dietro una grande strategia.

Andando avanti, però, mi sono accorto che OTP si adatta davvero bene al problema.

Un agente non è soltanto una richiesta HTTP verso un modello. Almeno non quello che intendo io.

Riceve messaggi, mantiene uno stato, aspetta conferme, avvia lavori, si ferma e poi riprende. A volte rimane attivo per giorni. A volte qualcosa crasha nel momento peggiore possibile.

Per OTP questa non è una cosa strana. Sono processi, messaggi, supervisori e stato con un proprietario chiaro.

Nel mondo degli agenti si parla spesso come se l’agente fosse una specie di entità magica che ragiona da sola. Io ormai lo vedo più come un insieme di processi un po’ paranoici che cercano di non perdere lo stato e di non fare due volte la stessa cosa.

Molto meno affascinante, ma mi sembra più utile.

Forse ho complicato troppo tutto

Me lo chiedo spesso.

Se devo costruire un piccolo chatbot che risponde usando alcuni documenti, probabilmente Spectre è troppo. Non servono policy, definizioni versionate, journal e rollback per rispondere agli orari di apertura di un negozio.

Ma quando un agente deve fare qualcosa, e non soltanto parlare, il discorso cambia.

Se modifica dati, usa informazioni personali, avvia operazioni oppure rimane attivo nel tempo, prima o poi qualcuno chiederà cosa ha fatto e perché.

Spectre non rende automaticamente un progetto sicuro. Non lo rende magicamente conforme al GDPR o all’AI Act. Chi lo dice sta semplificando troppo.

Quello che cerco di fare è rendere visibili le parti che altrimenti finiscono nascoste tra prompt, callback e tabelle del database. Dopo bisogna comunque progettare bene l’intera applicazione.

Magari tra un anno scoprirò che alcune idee erano inutilmente complicate. Le toglierò. Non ho problemi a cambiare strada.

Spectre per me è ancora una ricerca, oltre che una libreria.

Mi piacerebbe usarlo anche fuori dai miei progetti

Negli ultimi mesi ho capito anche un’altra cosa.

La parte che mi piace non è costruire la solita pagina con una chat e scrivere “powered by AI” sotto.

Mi piace prendere un processo reale, spesso abbastanza brutto, capire dove può rompersi e costruire la parte che nessuno vede.

È anche il motivo per cui mi piacerebbe collaborare con qualche agenzia.

Le agenzie spesso conoscono già il cliente, il settore e il prodotto. Hanno chi si occupa di design, comunicazione e del rapporto con l’azienda. Non hanno bisogno che io arrivi a vendere un altro chatbot.

Potrei invece lavorare dietro al progetto, sulla parte dell’agente che deve restare viva dopo la demo. Stato, azioni, memoria, integrazioni e tutti quei casi strani che all’inizio sembrano dettagli.

Spectre non deve nemmeno essere visibile al cliente. Non mi interessa vendere il nome del framework. Mi interessa vedere se quello che ho costruito può risolvere un problema vero.

Non ho un pacchetto con tre prezzi e una presentazione perfetta. Se un’agenzia ha un flusso confuso tra messaggi, documenti, persone e software diversi, possiamo semplicemente guardarlo insieme.

Magari serve un agente. Magari basta un’automazione molto più normale. Va bene lo stesso.

Ho iniziato Spectre perché non mi fidavo abbastanza di un agente AI per lasciargli fare un lavoro vero.

Continuo a non fidarmi.

Ora però ho almeno un posto dove mettere tutte le regole che il modello non dovrebbe poter ignorare.

Send via.chat
Strumento Consigliato

Send via.chat

Receive form leads, send login codes, and route important alerts through WhatsApp or Telegram.

Share this article:
Yuriy Zhar

Yuriy Zhar

github.com

Passionate web developer. Love Elixir/Erlang, Go, TypeScript, Svelte. Interested in ML, LLM, astronomy, philosophy. Enjoy traveling and napping.

Contattaci

Se lavori in un’agenzia e hai un progetto dove un agente AI deve fare qualcosa di reale, raccontami il caso. Possiamo guardarlo insieme, anche senza una specifica perfetta.

Book a Call

Rimani aggiornato

Iscriviti alla nostra newsletter e ricevi gli ultimi articoli direttamente nella tua casella di posta.