All'inizio di quest'anno, Andrej Karpathy (@karpathy) ha puntato un agente sul suo stesso codice di training e lo ha lasciato eseguire per due giorni. Ha lanciato 700 esperimenti, ha tenuto i 20 che hanno superato il benchmark e ha reso l'addestramento del modello più veloce dell'11%. Poi ha detto qualcosa di molto interessante: qualsiasi metrica che puoi valutare a basso costo può essere affidata a uno sciame di agenti.
Il tasso di risposta è una metrica che puoi valutare a basso costo. Da allora ho passato un po' di tempo a capire come sia quel ciclo applicato all'outbound.
La mia build:
Codex legge i risultati della settimana precedente, modifica i file di scoring e play eseguiti dal sistema di outbound, lancia un test e apre una pull request. Propone una modifica al playbook con le prove e il punteggio allegati, quindi aspetta l'approvazione umana. L'invio e l'unione rimangono fuori dal ciclo.
Ho costruito il primo ciclo alcune volte: percepire il mercato, valutare l'account, scrivere dal segnale, controllare il messaggio, registrare il risultato, imparare dalla risposta. Questo articolo parla del secondo ciclo, quello che modifica il primo.
Questa è la build: GTM come codice versionato che migliora grazie al mercato.

Il repository
Inizia con la cartella. La struttura è importante perché Codex può migliorare solo ciò che può leggere e modificare.
1codex-self-improving-outbound/2 AGENTS.md3 README.md4 config/5 scoring.yaml6 plays.yaml7 prompts/8 improve_scoring.md9 improve_prompt.md10 pr_summary.md11 memory/12 outcomes.jsonl13 evals/14 fixtures.yaml15 score.py16 scripts/17 append_outcome.py18 run_codex_step.sh19 propose_improvement.py20 open_pr.sh21 weekly_tune.sh22 examples/23 outcomes.sample.jsonl24 weekly-pr.md
Il repository è volutamente semplice. config/scoring.yaml contiene le regole che decidono quali segnali contano. prompts/ contiene i play che scrivono i messaggi. memory/outcomes.jsonl contiene ciò che ha fatto il mercato. evals/score.py è il gate che dice se una modifica proposta ha aiutato. AGENTS.md è la legge che Codex legge prima di toccare qualsiasi cosa.
Esegui la prima versione offline. Nessun CRM, nessun arricchimento, nessun sistema di delivery. Il ciclo di miglioramento deve dimostrarsi sui file locali prima di avvicinarsi a un vero sistema di outbound.
Step 1. Scrivi prima la legge
Prima del file di scoring, prima dei file dei prompt, scrivi AGENTS.md. Questo è il file che mantiene l'agente utile e contenuto.
1# Regole per l'Outbound Auto-Migliorante23Migliori un sistema di outbound a partire dai risultati.45Regole ferree:6- Non inviare mai messaggi.7- Non fare scraping o arricchire mai persone reali.8- Non fare mai auto-merge.9- Modifica solo i file in questo repository.10- Cambia un concetto alla volta.11- Cita i risultati da memory/outcomes.jsonl per ogni modifica proposta.12- Migliora evals/score.py prima che una modifica possa diventare una PR.13- Se la valutazione non migliora, annulla la tua modifica e fermati.1415Modifiche consentite:16- config/scoring.yaml17- config/plays.yaml18- prompts/*.md1920Output richiesto:21- file modificati22- motivo per ogni modifica23- punteggio prima24- punteggio dopo25- riepilogo della pull request
La legge ha un solo compito: restringere il lavoro. Senza di essa, Codex cercherà di aiutare ampliando l'ambito. Aggiungerà più dati, toccherà più file, chiamerà più strumenti o automatizzerà un passaggio che dovrebbe rimanere sotto il controllo umano. Qui il lavoro è più piccolo: leggere i risultati, proporre una modifica a un file, dimostrare che ha aiutato, poi aspettare.
Come si presenta un buon risultato. Puoi leggere la legge prima di approvare una PR e sapere esattamente cosa a Codex era permesso fare.
Dove si rompe. La legge diventa un documento di conformità. Se AGENTS.md ha bisogno di un indice, è già troppo grande. Mantienila operativa.
Step 2. Sposta il giudizio nella configurazione
La maggior parte del giudizio nell'outbound vive nella testa di qualcuno. Poi il team compra un software e si aspetta che il software migliori una decisione che non può vedere.
Sposta il giudizio in un file.
1segnali:2 competitor_comparison:3 peso: 84 motivo: "l'acquirente sta confrontando alternative"5 implementation_page_visit:6 peso: 67 motivo: "l'acquirente sta verificando se può essere installato"8 job_repost:9 peso: 510 motivo: "la posizione è ancora aperta e urgente"11 funding_event:12 peso: 513 motivo: "il budget o il mandato potrebbero essere cambiati"14 generic_download:15 peso: 116 motivo: "interesse per i contenuti, scarsa intenzione d'acquisto"1718soglie:19 bozza: 620 revisione_umana: 102122segnali_negativi:23 student_research: -824 vendor_pitch: -625 competitor: -10
Questo file inizia come un'ipotesi visibile. Se un download generico dovesse valere zero, il team può puntare alla riga esatta e cambiarla. Se una visita a una pagina di implementazione è un segnale più forte di quanto pensassi, Codex può proporre il diff e mostrare le righe di risultato che lo giustificano.
Non seppellire questa logica in una funzione Python. Se la regola è visibile, il team può revisionarla, discuterla e migliorarla senza trasformare un giudizio di vendita in un refactoring di ingegneria.
Come si presenta un buon risultato. Il file è abbastanza piccolo da poter essere discusso. Cinque segnali sono una buona prima versione.
Dove si rompe. Il file di scoring diventa un cassetto dei rifiuti. Venti segnali, sei soglie e regole di eccezione per ogni caso limite faranno sì che il miglioratore si adatti eccessivamente. Inizia in modo ristretto e lascia che i risultati ti dicano dove va posizionata la prossima manopola.
Step 3. Scrivi i risultati come memoria
Il file più importante è memory/outcomes.jsonl.
Una riga per contatto, scritta quando il risultato è noto:
1{"date":"2026-07-01","account":"Northwind Finance","signal":"competitor_comparison","play":"migration_note","score":8,"outcome":"reply","reason":"ha chiesto le note di migrazione"}2{"date":"2026-07-01","account":"Bluepeak Studio","signal":"generic_download","play":"resource_followup","score":1,"outcome":"no_reply","reason":"intenzione solo di contenuti"}3{"date":"2026-07-02","account":"KiteOps","signal":"implementation_page_visit","play":"implementation_angle","score":6,"outcome":"reply","reason":"ha chiesto informazioni sulla tempistica di implementazione"}4{"date":"2026-07-02","account":"Atlas Recruiting","signal":"job_repost","play":"hiring_angle","score":5,"outcome":"bad_fit","reason":"richiesta di ricerca studentesca"}
Il campo reason è il punto centrale. no_reply non ti dice quasi nulla. content-only intent dice all'esecuzione successiva che questo segnale potrebbe non meritare una bozza. bad_fit è utile solo quando il motivo spiega il perché. asked about implementation timeline è il tipo di dettaglio che può cambiare un peso.
Costruisci il validatore prima di costruire il miglioratore:
1Costruisci scripts/append_outcome.py.23Accetta:4- date5- account6- signal7- play8- score9- outcome: reply | meeting | no_reply | bad_fit | bounced10- reason1112Rifiuta:13- campi mancanti14- outcome sconosciuti15- reason vuoto16- date future1718Aggiungi righe valide a memory/outcomes.jsonl.19Stampa la riga aggiunta.
È qui che inizia il compounding. Una dashboard può dirti che una campagna è in calo. Un registro dei risultati pulito può dire a Codex quale segnale, play o frase dovrebbe cambiare prima dell'esecuzione successiva.
Come si presenta un buon risultato. Dopo una settimana, un estraneo può leggere il file e capire quali segnali hanno generato risposte, quali play hanno generato conversazioni di cattivo adattamento e quale preferito interno il mercato ha ignorato.
Dove si rompe. Il team inserisce i risultati di venerdì a memoria. I successi sopravvivono, le ragioni dei cattivi adattamenti si offuscano e il sistema impara dalla finzione. Scrivi la riga quando il risultato arriva.
Step 4. Costruisci il gate di valutazione
Prima che Codex modifichi qualcosa, ha bisogno di un test a cui non possa sottrarsi.
Crea evals/fixtures.yaml:
1casi:2 - account: Northwind Finance3 segnali: [competitor_comparison, implementation_page_visit]4 atteso: revisione_umana5 nota: "due segnali forti su un account"67 - account: Bluepeak Studio8 segnali: [generic_download]9 atteso: ignora10 nota: "intenzione solo di contenuti"1112 - account: KiteOps13 segnali: [implementation_page_visit]14 atteso: bozza15 nota: "l'intenzione di implementazione dovrebbe superare la soglia bozza"1617 - account: Atlas Recruiting18 segnali: [job_repost, student_research]19 atteso: ignora20 nota: "il marcatore di cattivo adattamento annulla il segnale"
Poi crea evals/score.py:
1Costruisci evals/score.py.23Leggi config/scoring.yaml e evals/fixtures.yaml.45Per ogni caso:61. Somma i pesi per ogni segnale.72. Aggiungi le penalità dei segnali negativi.83. Instrada l'account:9 - score >= soglie.revisione_umana => revisione_umana10 - score >= soglie.bozza => bozza11 - altrimenti => ignora124. Confronta il percorso con l'atteso.1314Stampa ogni previsione.15Stampa la precisione finale come score=0.00 a score=1.00.16Esci con 0 solo quando la precisione è 1.00.
Il primo gate dovrebbe essere abbastanza piccolo da essere compreso e abbastanza preciso da cogliere un vero errore. Nella mia prima esecuzione, la baseline ha fallito un caso:
1Northwind Finance: predicted=human_review expected=human_review2Bluepeak Studio: predicted=ignore expected=ignore3KiteOps: predicted=ignore expected=draft4Atlas Recruiting: predicted=ignore expected=ignore5score=0.75
È stato positivo. Il sistema aveva l'intenzione di implementazione al di sotto della soglia bozza, quindi ha ignorato un account che il fixture diceva meritare un messaggio. Meglio cogliere questo in un test che dopo un mese di account persi.
Come si presenta un buon risultato. Un comando dà un numero, e ogni caso fallito è facile da ispezionare.
Dove si rompe. Il fixture include solo vittorie ovvie. Poi ogni modifica sconsiderata passa. Metti casi brutti nel gate: intenzione debole, cattivo adattamento, nessuna risposta, segnali obsoleti e gli account che avresti voluto che il sistema avesse saltato.
Step 5. Lascia che Codex proponga una modifica allo scoring
Ora Codex può modificare.
Crea prompts/improve_scoring.md:
1Migliori il sistema di scoring dell'outbound.23Leggi:4- AGENTS.md5- config/scoring.yaml6- memory/outcomes.jsonl7- evals/fixtures.yaml89Il tuo compito:101. Trova una regola di scoring che dovrebbe cambiare.112. Il motivo deve citare memory/outcomes.jsonl.123. Cambia solo config/scoring.yaml.134. Esegui python3 evals/score.py.145. Se il punteggio migliora, mantieni la modifica.156. Se il punteggio rimane uguale o diminuisce, annulla la tua modifica e fermati.1617Output:18- la riga esatta modificata19- le righe di risultato che l'hanno causata20- punteggio prima21- punteggio dopo22- se la modifica dovrebbe diventare una PR2324Non modificare i prompt.25Non aggiungere nuovi segnali.26Non toccare la delivery.
Eseguilo attraverso il wrapper del repository:
1scripts/run_codex_step.sh improve_scoring
La prima versione del mio miglioratore ha fatto un errore utile. Ha inseguito il segnale di risposta più pulito. competitor_comparison aveva il tasso di risposta più forte nel piccolo registro dei risultati, quindi il miglioratore voleva aumentare quel peso. La valutazione è rimasta a 0.75, quindi la modifica è stata respinta.
Questo è esattamente il motivo per cui il gate esiste. Un sistema più debole avrebbe accettato la storia perché sembrava ragionevole. Questo ha fatto una domanda migliore: la modifica ha risolto l'errore noto?
Il secondo passaggio ha trovato la modifica più piccola che ha aiutato:
1- implementation_page_visit: 42+ implementation_page_visit: 6
La valutazione è passata:
1Northwind Finance: predicted=human_review expected=human_review2Bluepeak Studio: predicted=ignore expected=ignore3KiteOps: predicted=draft expected=draft4Atlas Recruiting: predicted=ignore expected=ignore5score=1.00
Questo è il momento in cui il ciclo diventa utile. Ha cambiato una regola, per una ragione, e ha dimostrato la modifica contro un fixture.

Come si presenta un buon risultato. Il diff proposto è noioso e tracciabile: una riga modificata, una ragione supportata dai risultati allegata, una valutazione migliorata.
Dove si rompe. Codex cambia tre pesi e due prompt contemporaneamente. Ora nessuno può dire quale modifica abbia aiutato. Mantieni la legge severa: un concetto per proposta.
Step 6. Migliora i file dei prompt separatamente
Lo scoring è solo metà del sistema. Anche i template dei messaggi decadono.
Una riga che funzionava il mese scorso inizia a suonare familiare. Una domanda che ottiene risposte in un segmento viene ignorata in un altro. Una frase che sembra incisiva internamente viene punita dal mercato. Tratta il miglioramento dei prompt come un binario separato in modo che Codex non mescoli scoring e copy nella stessa PR.
Crea config/plays.yaml:
1plays:2 migration_note:3 prompt_file: prompts/plays/migration_note.md4 usa_quando:5 - competitor_comparison6 righe_vietate:7 - "pensavo potesse essere rilevante"8 - "una domanda veloce"910 implementation_angle:11 prompt_file: prompts/plays/implementation_angle.md12 usa_quando:13 - implementation_page_visit14 righe_vietate:15 - "dai un'occhiata alla nostra soluzione"16 - "mi piacerebbe fare due chiacchiere"
Poi crea prompts/improve_prompt.md:
1Migliori un play di outbound.23Leggi:4- AGENTS.md5- config/plays.yaml6- memory/outcomes.jsonl7- il file del prompt per il play scelto89Scegli un play con almeno 10 risultati.1011Trova:12- righe o strutture che appaiono in risultati positivi13- righe o strutture che appaiono in risultati no_reply o bad_fit14- qualsiasi frase che dovrebbe essere vietata1516Fai una piccola modifica al prompt di quel play.1718Regole:19- Non modificare lo scoring.20- Non creare un nuovo play.21- Non aggiungere un nuovo canale.22- Cita le righe di risultato.23- Scrivi l'istruzione prima e dopo.2425Quindi esegui la valutazione della copia se presente.26Se non esiste una valutazione della copia, apri la PR come review_required.
Alcuni miglioramenti possono essere valutati automaticamente. Altri hanno ancora bisogno di gusto. Se non c'è una valutazione della copia, Codex può proporre la modifica al prompt, ma dovrebbe contrassegnare la PR per la revisione invece di fingere che la modifica sia provata.
Come si presenta un buon risultato. Codex dice: "Questa frase è apparsa in sette risultati no_reply, quindi l'ho aggiunta a righe_vietate", o "le risposte positive citavano il dettaglio di implementazione nella prima frase, quindi ho ristretto il play per richiederlo."
Dove si rompe. Il miglioratore riscrive l'intera voce perché un messaggio ha ottenuto una risposta. Le modifiche ai prompt dovrebbero essere più piccole del tuo istinto.
Step 7. Invia le modifiche come pull request
Questo è il livello di controllo. Codex modifica i file, esegue la valutazione e scrive il riepilogo della PR. Un umano revisiona e unisce.

Crea prompts/pr_summary.md:
1Scrivi un riepilogo della pull request per questo miglioramento dell'outbound.23Includi:41. Cosa è cambiato.52. Perché è cambiato, citando le righe di risultato.63. Punteggio prima.74. Punteggio dopo.85. File modificati.96. Rischio.107. Cosa dovrebbe controllare il revisore umano.1112Mantienilo breve.13Non affermare che la modifica è attiva.
Crea scripts/open_pr.sh:
1#!/usr/bin/env bash2set -euo pipefail34branch="codex/ottimizzazione-settimanale-$(date +%Y-%m-%d)"56git checkout -b "$branch"7git add config prompts evals memory8git commit -m "Ottimizzazione outbound settimanale Codex"910body="$(cat outputs/pr-summary.md)"1112python3 scripts/create_pr.py \13 "$branch" \14 "Ottimizzazione outbound settimanale Codex" \15 "$body"
La PR dovrebbe sembrare scritta da un compagno di squadra:
1Modificato:2- Aumentato implementation_page_visit da 4 a 6.34Perché:5- KiteOps aveva intenzione di implementazione e ha risposto con i tempi di implementazione.6- Il punteggio precedente instradava questo account verso ignora.78Prima:9- punteggio valutazione 0.751011Dopo:12- punteggio valutazione 1.001314Controllo revisore:15- Assicurati che l'intenzione di implementazione sia sufficientemente specifica.16- Mantieni bassi i download generici.17- Unisci solo se corrisponde al giudizio di vendita effettivo.
Questo è il sistema di sicurezza. Codex fa il lavoro noioso. L'operatore mantiene lo standard.
Come si presenta un buon risultato. Una PR a settimana, diff piccolo, motivo chiaro, valutazione superata.
Dove si rompe. Qualcuno dà a Codex il permesso di fare merge perché la revisione sembra un attrito. Quel minuto separa un sistema che migliora da un sistema che deriva.
Step 8. Mettilo su una cadenza
Non eseguirlo dopo ogni risposta. È così che un sistema si adatta eccessivamente a un singolo account rumoroso.
Lascia che la settimana accada, lascia che i risultati si accumulino, poi ottimizza.

Crea scripts/weekly_tune.sh:
1#!/usr/bin/env bash2set -euo pipefail34cd "$(dirname "$0")/.."56python3 evals/score.py || true7scripts/run_codex_step.sh improve_scoring8python3 evals/score.py9scripts/run_codex_step.sh pr_summary > outputs/pr-summary.md10scripts/open_pr.sh
Poi cron:
10 8 * * LUN cd ~/codex-self-improving-outbound && scripts/weekly_tune.sh
Se usi GitHub Actions, mantieni la stessa struttura:
1name: ottimizzazione-outbound-settimanale23on:4 schedule:5 - cron: "0 8 * * 1"6 workflow_dispatch:78jobs:9 ottimizza:10 runs-on: ubuntu-latest11 steps:12 - uses: actions/checkout@v413 - uses: actions/setup-python@v514 with:15 python-version: "3.11"16 - run: pip install -r requirements.txt17 - run: python3 evals/score.py || true18 - run: scripts/weekly_tune.sh
Esegui le prime due ottimizzazioni a mano. Leggi ogni diff. Osserva cosa Codex cerca di cambiare quando il campione è esiguo. Una volta che le proposte sono noiose, mettilo su un programma.
Come si presenta un buon risultato. Una PR settimanale appare con le prove, il diff e il risultato della valutazione. Unisci, modifichi o la chiudi.
Dove si rompe. Il job viene eseguito, nessuno revisiona e le PR si accumulano. Un sistema auto-migliorante ha ancora un'abitudine umana: leggere il diff.
La versione clone-and-run
Il repository dovrebbe essere fornito con quattro comandi:
1git clone <repo>2cd codex-self-improving-outbound3python3 -m venv .venv4source .venv/bin/activate5pip install -r requirements.txt6python3 evals/score.py7python3 scripts/propose_improvement.py
Prima esecuzione prevista:
1score=0.752modificato config/scoring.yaml3implementation_page_visit: 4 -> 64score=1.005apri PR per revisione umana
La demo offline prova i contratti dei file. L'esecuzione di Codex prova il ciclo di modifica. Dopodiché, sostituisci i risultati di esempio con i tuoi, rinomina i segnali, aggiungi i tuoi play e costruisci un fixture che rifletta gli account che avresti voluto che il sistema avesse instradato diversamente.
Non iniziare collegando la delivery. Inizia dimostrando il ciclo di miglioramento.
La versione completa: max
Questo repository è il livello manuale. Funziona da file, segnali pubblici e il tuo piano Codex. Insegna la struttura perché ogni regola è esposta.
yourmax.ai è lo stesso sistema con le cuciture nascoste.
Invece di un repository che colleghi da solo, max è l'agente che usi direttamente. Rileva i movimenti nel mercato, decide chi vale la pena contattare e perché ora, prepara l'outreach via email e LinkedIn per la tua approvazione e continua a migliorare dai risultati.
Il repository mostra il livello di auto-ottimizzazione che la maggior parte dei team non costruisce mai: i risultati diventano modifiche alle regole proposte, le modifiche alle regole proposte passano attraverso un gate e la fusione umana decide cosa diventa attivo. max prende la stessa logica operativa e la esegue come un sistema gestito.
Se vuoi il repository completo, fammelo sapere e te lo invierò.





