Quando l’AI accelera il lavoro, tenere il passo diventa un casino. In Anthropic usano automazioni agentiche semplici: girano in background, raccolgono informazioni, e ti avvisano quando serve. Il problema è che costruirle è complicato. Perdono accesso alle fonti senza dirtelo, ignorano le tue preferenze, si dimenticano cosa hanno già fatto.
Hanno pubblicato un’implementazione di riferimento completa: un agente che legge da fonti custom — tipo Slack e GitHub — su schedule, traccia cosa è cambiato dall’ultima esecuzione, e posta dove serve. Con codice funzionante e sei regole per non farsi male.
Le fondamenta: sei componenti
L’agente è costruito su sei pezzi: fonti da cui leggere, una destinazione dove scrivere, l’agente con modello e tool, uno schedule cron, memoria persistente tra le run, e guardrail che limitano danni e costi.
Gira su infrastruttura Anthropic. Niente daemon sulla tua macchina, niente script che si impalla alle 3 di notte.
Credenziali isolate in vault
Con Claude Managed Agents le credenziali vivono in vault. L’agente le referenzia ma i valori reali stanno fuori dalla sandbox dove gira il codice di Claude. Due modalità: server MCP per GitHub, dove il proxy fuori dalla sandbox trova la credenziale giusta per URL, e shell per Slack, dove l’agente usa curl con un placeholder opaco tipo $SLACK_BOT_TOKEN. La piattaforma sostituisce il token vero solo quando la richiesta esce verso host autorizzati.
Crei il vault con ant apply vault.yaml, poi aggiungi ogni credenziale via TypeScript SDK. Ogni credenziale ha nome, tipo, valore segreto, host permessi. Il vault ID finisce in deployment.md.
La prima regola: bookmark, non finestre fisse
Errore classico: chiedere all’agente di leggere «le ultime 24 ore». Una run in ritardo crea buchi, una in anticipo ripete roba. La soluzione è un bookmark per fonte.
Alla fine di ogni run, l’agente scrive il timestamp dell’item più recente letto da ogni fonte in bookmarks.json. Entry tipo 'slack': '2026-09-14T13:02:11Z'. La run successiva parte da lì. La finestra si allunga o si accorcia per coprire tutto dal bookmark in poi: zero gap, zero duplicati.
I bookmark vivono nel memory store chiamato state: una cartella di file di testo che la piattaforma monta in /mnt/memory/ a ogni run e mantiene tra le esecuzioni. L’agente ci legge e scrive con i suoi tool normali.
Quando una fonte fallisce
Se un server MCP è giù o il token è scaduto, la run parte lo stesso. Solo che quegli strumenti mancano. Il log registra l’errore, ma l’agente non vede niente da quella fonte e riporta «niente di nuovo».
Tre regole in agent.md prevengono il disastro. Quando una fonte fallisce: il bookmark di quella fonte resta dov’è, il brief viene scritto dalle altre fonti, e alla fine del brief compare una riga che nomina cosa non si è potuto leggere — «pull request non disponibili questa run». Chi legge lo sa.
Postare senza ripetersi
L’agente posta su Slack con bash tool, stesso bot token usato per leggere. Niente approval da aspettare: il bash tool gira senza chiedere permesso di default, e slack.com è nella allowlist dell’environment.
Il post è una richiesta curl. Semplice. Ma c’è un problema: come confermi che il post è atterrato davvero prima di segnarlo come fatto?
Conferma prima di registrare
Se l’agente registra un post mai atterrato, i bookmark avanzano e quegli item spariscono per sempre. Se posta di nuovo perché non è sicuro del primo tentativo, il lettore riceve lo stesso brief due volte.
Tre regole risolvono il problema. Prima, l’agente cerca il titolo di oggi nei messaggi recenti del canale: se l’edizione c’è già, non posta. Seconda, il post conta come inviato solo se Slack restituisce 'ok': true e un message timestamp. Terza, ledger e bookmark si aggiornano solo dopo quella conferma. Risultato non chiaro? Marca la run come «forse postato» e non cambia nient’altro. Niente si perde.
Ogni run ha un record in runs/<data>.md. Stato: «posting» prima del post, poi «posted» con ID messaggio, oppure «maybe posted».
L’agente: configurazione e istruzioni
In Claude Managed Agents un agente è una configurazione versionata: modello, prompt di sistema, tool. Ogni run segue i suoi step e si ferma.
L’implementazione di riferimento ha la configurazione in agent.md: frontmatter con nome agente, modello — Claude Sonnet 5.5 — server MCP, tool. Il corpo contiene otto step numerati. I tool MCP chiedono approval di default ma nessuno è lì a darla, quindi il toolset GitHub è impostato su always_allow e il token GitHub è read-only.
Brief corti, verifiche live
Le istruzioni in agent.md spingono Claude verso la brevità. Un item merita una riga quando il lettore agirebbe oggi, o cambierebbe una decisione imminente. Nel dubbio, lascialo fuori. Di solito sono pochi item, a volte zero. Un conteggio — «12 review aperte» — non è un item: linka quelle bloccate. Un item già nel ledger e ancora aperto viene portato come riga marcata — «ancora in attesa, giorno 3» — non ri-riportato.
Gli item possono cambiare tra quando l’agente legge le fonti e quando posta. Quindi, proprio prima di postare, agent.md istruisce l’agente a ri-controllare lo stato live di ogni item. Risolto nel frattempo? Buttalo. Ancora aperto ma cambiato? Aggiorna la riga. Non riesci a confermare? Buttalo e elencalo nei tagli del run record. Una singola notifica stantia tipo «ancora in attesa di te» costa più fiducia di dieci item mancanti. Mai indovinare lo stato di un item: affermalo o lascialo perdere.
Schedule e deployment
L’agente è solo un file di configurazione. Un deployment lo esegue. Il deployment nomina agente, environment, primo messaggio di ogni run, e contiene schedule, vault, memory store, budget. Ogni volta che lo schedule scatta, la piattaforma avvia una sessione agente fresca.
Il deployment è in deployment.md. Schedule cron tipo '32 7 * * 1-5' — lunedì-venerdì alle 7:32. Timezone America/New_York. Vault ID. Due memory store: preferences in sola lettura — le preferenze del lettore, ri-lette ogni run — e state in read-write — bookmark, ledger, note, proposte, record delle run.
Crei il deployment con ant apply deployment.md. Per testare senza aspettare lo schedule: ant beta:deployments run --deployment-id <id>.
Date nel tuo fuso orario
Bug comune: l’agente chiama stamattina «ieri» perché calcola le date nel fuso del server. Il campo timezone in deployment.md imposta quando la run parte, e la seconda riga del corpo dice all’agente quale zona usare per le date.
Memoria tra le run
Ogni run parte in sandbox fresca. Senza memoria, il feedback non attacca. Ma memoria stantia confonde: riporta un item come ancora in attesa dopo che è stato risolto, o butta uno ancora aperto perché «già riportato».
Due memory store sotto /mnt/memory/. preferences — tue, read-only per l’agente — quali canali e repo leggere, cosa escludere, cap di lunghezza, destinazione, quando fermarsi. state — dell’agente, read-write — bookmark, ledger di cosa ha riportato, un record per run, proposte di modifica alle tue preferenze, note su come si comporta ogni fonte.
ant apply deployment.md crea lo store preferences, ma non il file dentro. Prima della prima run, scrivi preferences.md lì dentro con lo script scripts/seed-preferences.sh dal repo.
Rileggi le preferenze ogni volta
Problema ricorrente: una copia delle preferenze finisce incorporata nel prompt, che continua ad applicare regole già cambiate. Fai leggere all’agente il file fresco ogni run. Se non riesce a leggerlo, si ferma e lo dice, invece di girare su default.
Il ledger: cosa hai già detto
L’agente tiene ledger.md con ogni item riportato. Il brief non si ripete. Ogni riga: quando è stato riportato, fonte, ID che non cambia — timestamp Slack o numero pull request — ultimo stato noto. Esempio: 2026-09-09 slack:C0123456789 1788963600.000100 refund thread: customer waiting on a decision.
Guardrail: limiti e budget
L’automazione gira in background su schedule. Serve limitare cosa può fare e quanto può spendere.
L’agente legge messaggi e issue scritti da altri. Quel testo può essere interpretato come istruzioni. Limita cosa potrebbe fare se le seguisse. Nell’esempio: token GitHub e store preferences sono read-only, environment raggiunge solo host in allowlist. Un’istruzione piantata può ancora cambiare cosa dice il brief — anche attraverso le note che l’agente conserva tra run — ma non può scrivere su GitHub o editare le tue regole.
Slack è l’eccezione: stesso token per postare, quindi invita il bot solo dove deve leggere o postare.
Budget da run reali
Un cap di spesa protegge da costi fuori controllo. Parti da tre-cinque volte il costo di una run normale, poi stringi vedendo i numeri veri. Una run che tocca il cap si mette in pausa invece di fallire — quindi un cap troppo basso sembra un brief che è andato in silenzio. Il cap è il budget in deployment.md. Ogni run riceve l’importo pieno. Una run che lo raggiunge si ferma con stop reason budget_reached. Esempio: max_list_cost: '500' — stringa, in centesimi, quindi 5 dollari.
Le sei regole
L’implementazione si riduce a sei regole. Leggi ogni fonte da un bookmark, non una finestra temporale fissa. Riporta una lettura fallita come illeggibile, mai come giornata tranquilla. Ri-controlla ogni item subito prima di postare. Conta un post come inviato solo quando Slack lo conferma, poi aggiorna bookmark e ledger. Rileggi le preferenze ogni run, da uno store che l’agente non può editare. Dai all’agente accesso read-only dove legge soltanto, e imposta un cap su quanto ogni run può spendere.
Claude Code può guidarti attraverso questa configurazione. Prima: claude update. Poi usa la skill claude-api: /claude-api managed-agents-onboard https://claude.dev/blog/building-effective-agent-automations/. La skill legge il post, propone un setup, scrive i file in una cartella agents/ nel progetto, e crea le risorse con ant apply. Personalizza per le tue fonti, destinazione, preferenze di memoria.
