· 6 min · Agenti

Come evitare che i cicli degli agenti consumino il tuo budget API

Come evitare che i cicli degli agenti consumino il tuo budget API

Scriverò direttamente l'articolo, con tecniche ingegneristiche concrete, una tabella comparativa ed esempi pratici. Lo manterrò ancorato al comportamento reale dei cicli e ai controlli dei costi, e mi assicurerò che si concluda con indicazioni applicabili.## Il modo più rapido per bruciare un budget API

Una volta ho visto un agente di programmazione “semplice” trasformare una richiesta utente di 400 token in una voce di fattura da 28,000 token in meno di due minuti.

Lo schema era fin troppo familiare: l'agente chiamava uno strumento di ricerca, riassumeva i risultati, rileggeva il proprio riepilogo, interrogava di nuovo lo stesso strumento con una formulazione leggermente diversa, poi ampliava il contesto finché ogni turno includeva l'intera conversazione, metà del repository e una scia di piani falliti. Il modello non aveva nulla che non andasse. Era la progettazione del ciclo a essere sbagliata.

Questo è il problema centrale dei sistemi ad agenti: il costo non cresce in funzione dei prompt degli utenti, ma in funzione del comportamento del ciclo. Un solo ciclo mal progettato può moltiplicare:

  • i token di input a causa di un contesto in continua crescita,
  • i token di output a causa di un “ragionamento” prolisso,
  • la spesa per gli strumenti a causa di chiamate ripetute,
  • e la latenza a causa di tentativi ripetuti in serie.

Se sviluppi agenti per la produzione, il vero lavoro non è “rendere il modello più intelligente”. È “rendere il ciclo meno costoso, più breve e meno incline a sfuggire al controllo”.

Perché i cicli degli agenti fanno esplodere i costi

Un normale turno di chat ha un input e un output. Un ciclo di un agente ha una sequenza di questo tipo:

  1. l'utente pone una domanda,
  2. il modello pianifica,
  3. il modello chiama uno strumento,
  4. lo strumento restituisce dati,
  5. il modello legge i dati,
  6. il modello decide il passo successivo,
  7. si ripete.

Ogni iterazione aggiunge nuovi token al prompt dell'iterazione successiva. Se continui ad aggiungere gli output completi degli strumenti e i ragionamenti precedenti, il prompt cresce più o meno a gradini.

In pratica, questo produce tre moltiplicatori dei costi:

  • Accumulo del contesto: ogni passaggio porta con sé quelli precedenti.
  • Chiamate eccessive agli strumenti: lo stesso strumento viene chiamato con argomenti leggermente diversi.
  • Tentativi ripetuti fuori controllo: il modello continua a “provare ancora una cosa” quando ha già fatto abbastanza.

Un'insidia comune è che lo spreco di token di solito resta invisibile finché non esamini le tracce delle singole esecuzioni. La risposta finale può essere concisa, ma la catena nascosta può essere 10x più grande dell'output visibile all'utente.

Un semplice modello dei costi

Se un ciclo esegue N passaggi, ciascuno con:

  • C token di contesto mantenuto,
  • I token di output degli strumenti reinseriti nel contesto,
  • O token di output del modello,

allora il totale approssimativo è:

total_tokens ≈ N * (C + I + O)

È una stima ottimistica, perché C di solito cresce man mano che il ciclo prosegue. In un agente reale, i turni successivi sono spesso i più costosi.

Le leve di controllo che contano davvero

Ci sono alcuni punti su cui puoi intervenire. Il segreto è combinarli.

ControlloCosa riduceCaso d'uso idealeCompromesso
Limiti ai passaggiCicli fuori controlloQualsiasi agente con strumentiPuò interrompersi troppo presto nei compiti difficili
Riduzione del contestoToken di inputCompiti di lunga durataRischio di perdere informazioni utili dalla cronologia
Sottoagenti meno costosiSpesa per le attività di routineRicerca, estrazione, classificazioneCosti aggiuntivi di coordinamento
Caching dei risultati degli strumentiSpesa per chiamate ripetute agli strumentiFonti stabili, query ripetuteDati obsoleti e invalidazione
Osservabilità della spesaFatture inatteseSistemi in produzioneRichiede lavoro di strumentazione
Condizioni di arresto dei cicliCicli infiniti o quasi infinitiAgenti inaffidabiliOccorre definire cosa sia “sufficientemente buono”

Le configurazioni di produzione più efficaci le utilizzano tutte.

1) Imposta limiti rigorosi ai passaggi

Questa è la soluzione più semplice e più sottovalutata: se non imposti un limite massimo rigido, ti affidi al modello perché si fermi da solo.

Di solito parto da:

  • 3–5 passaggi per compiti circoscritti,
  • 6–8 passaggi per compiti di media complessità,
  • un numero maggiore solo quando c'è un motivo valido.

Un buon limite non è solo una valvola di sicurezza. Impone una migliore scomposizione del compito. Se l'agente ha a disposizione solo quattro mosse, tende a:

  • richiedere prima lo strumento giusto,
  • evitare deviazioni esplorative,
  • e convergere più rapidamente verso una risposta utilizzabile.

Esempio di controllore del ciclo

MAX_STEPS = 5

for step in range(MAX_STEPS):
    action = model.next_action(state)

    if action.type == "final":
        return action.final_answer

    observation = run_tool(action.tool_name, action.arguments)
    state = update_state(state, action, observation)

raise RuntimeError("Agent stopped after step cap")

Un'insidia comune: i limiti ai passaggi devono applicarsi all' intero piano, non a ciascuna sottoprocedura in modo indipendente. Altrimenti sposti l'esplosione dall'agente principale agli assistenti annidati.

2) Riduci il contesto a ogni turno

La maggior parte degli agenti conserva troppa cronologia. Non ha bisogno di tutte le risposte precedenti degli strumenti, soprattutto se una risposta era lunga e contava un solo dettaglio.

In pratica, ho ottenuto i risultati migliori con una politica di memoria a livelli:

  • Conserva integralmente: richiesta dell'utente, obiettivo attuale, decisioni definitive, vincoli irrisolti.
  • Riassumi: ragionamenti precedenti, tentativi su percorsi alternativi, output lunghi degli strumenti.
  • Elimina: ipotesi senza sbocco, risultati duplicati degli strumenti, vecchie bozze intermedie.

Cosa conservare

Un oggetto di stato compatto funziona meglio della riproposizione della trascrizione integrale:

{
  "goal": "Find the failing endpoint and propose a fix",
  "constraints": [
    "No schema changes",
    "Must preserve backward compatibility"
  ],
  "known_facts": [
    "500s started after deploy 1842",
    "Only /v1/search is affected"
  ],
  "open_questions": [
    "Is the new cache layer returning stale payloads?"
  ],
  "step": 3
}

È molto meno costoso che fornire al modello 20 turni di «ragionamento ad alta voce».

Schema pratico per ridurre il contesto

Usa tre buffer:

  • working_set: turno corrente, output degli strumenti, piano attivo.
  • summary_memory: cronologia compressa.
  • archive: tutto ciò che potrebbe servirti per gli audit, ma non per il contesto del prompt.

L’agente vede solo working_set + summary_memory. Quando working_set diventa troppo grande, riassumilo in summary_memory.

L’insidia è la deriva del riepilogo. Se il riepilogo perde informazioni, può cancellare vincoli e indurre l’agente a ripetere gli stessi errori. Preferisco conservare i fatti strutturati separatamente dai riepiloghi in forma libera, così il modello non deve dedurli dal testo.

3) Usa sottoagenti più economici per le attività semplici

Non ogni passaggio merita il tuo modello migliore.

Se l’attività consiste nel:

  • estrarre campi da JSON,
  • classificare un ticket,
  • verificare se un file è cambiato,
  • o generare una breve query di ricerca,

spesso basta un modello più piccolo ed economico. Riserva il modello costoso alla pianificazione, alla sintesi e alla gestione delle ambiguità.

Suddivisione tipica

  • Agente principale: ragiona sull’attività e decide quando fermarsi.
  • Sottoagente: svolge attività circoscritte come ricerca, estrazione o normalizzazione.
  • Verificatore: controlla il formato, la completezza o la presenza di errori evidenti negli output.

Un’architettura pratica:

User
  -> Orchestrator (strong model)
      -> Search agent (cheap model)
      -> Extract agent (cheap model)
      -> Final synthesis (strong model)

Perché funziona

Il modello principale resta concentrato sul flusso di controllo invece di fare tutto da solo. Il sottoagente può essere vincolato tramite il prompt e avere un limite rigido di token.

Esempio di prompt per un sottoagente di ricerca:

Return only:
1. the best search query,
2. 3 likely source categories,
3. no explanation.

Un insieme di requisiti così circoscritto mantiene gli output brevi e prevedibili.

Se la tua piattaforma offre accesso a più modelli a prezzi convenienti, è qui che ne trai vantaggio: un modello potente per l’orchestrazione, uno più economico per le sottoattività ripetitive e nessun motivo per consumare token premium nel parsing di routine.

4) Metti in cache i risultati degli strumenti con criterio

I cicli degli agenti spesso pagano più volte per le stesse informazioni:

  • letture ripetute dei file,
  • interrogazioni ripetute del database,
  • ricerche web ripetute,
  • chiamate ripetute per embedding o recupero di informazioni.

Mettere in cache gli output degli strumenti è una delle modifiche con il maggiore ritorno sull’investimento.

Usa chiavi semantiche per la cache, non il testo grezzo

Una cache basata sul testo grezzo del prompt non trova corrispondenze se la formulazione cambia leggermente. Le chiavi migliori si basano sull’intento normalizzato:

def cache_key(tool_name, args):
    normalized = normalize_args(args)
    return f"{tool_name}:{hash(normalized)}"

Esempio di voce della cache:

{
  "tool": "repo_search",
  "query": "auth middleware rate limit bug",
  "result": {
    "files": ["src/middleware/auth.py", "src/api/routes.py"],
    "ts": 1710001123
  }
}

Quando la cache è più utile

  • Agenti che ispezionano repository,
  • ricerca di documenti,
  • basi di conoscenza stabili,
  • trasformazioni deterministiche,
  • recupero ripetuto di informazioni nei flussi di lavoro con più turni.

Quando la cache può essere dannosa

  • dati che cambiano rapidamente,
  • risultati specifici per l’utente,
  • qualsiasi dato con requisiti di aggiornamento legati al tempo.

L’insidia comune consiste nel mettere in cache gli output degli strumenti senza comunicarne il grado di aggiornamento all’agente. Se il modello crede di aver ricevuto dati in tempo reale quando invece provengono dalla cache, potrebbe prendere decisioni sbagliate. Includi timestamp o intervalli di validità nei metadati degli strumenti.

5) Mostra la spesa nella dashboard

Se monitori solo la latenza e il tasso di successo, ti sfuggirà il vero problema: un successo costoso.

Per ogni esecuzione, devi poter osservare:

  • token di input,
  • token di output,
  • chiamate agli strumenti,
  • latenza degli strumenti,
  • spesa totale,
  • numero di passaggi,
  • motivo dell’arresto.

Schema minimo degli eventi

{
  "run_id": "r_8f2c",
  "step": 4,
  "model": "gpt-5.5",
  "input_tokens": 1842,
  "output_tokens": 221,
  "tool_name": "repo_search",
  "tool_latency_ms": 312,
  "estimated_cost_usd": 0.087,
  "stop_reason": "step_cap"
}

Cosa monitorare nella pratica

  • Token per attività completata con successo: l’indicatore di costo più chiaro.
  • Token per passaggio: rileva la crescita eccessiva dei prompt.
  • Chiamate ripetute agli strumenti: di solito indicano un errore di pianificazione.
  • Distribuzione dei motivi di arresto: se molte esecuzioni terminano perché raggiungono il limite, il tuo agente non pianifica a sufficienza.

Uno dei grafici più utili è quello del costo per tipo di attività. Alcune categorie saranno naturalmente costose. Va bene così. Ciò che devi individuare è l’attività che dovrebbe essere economica ma non lo è.

6) Interrompi tempestivamente i cicli fuori controllo

Un ciclo dovrebbe fermarsi per più motivi del solo «ho raggiunto il limite di passaggi».

Tra le condizioni di arresto utili ci sono:

  • il modello ha prodotto una risposta finale,
  • la stessa chiamata a uno strumento si ripete senza nuove informazioni,
  • la variazione del livello di confidenza o dell’utilità è sotto la soglia,
  • l’attività è risolta secondo un verificatore,
  • il piano non fa più progressi.

Esempio di meccanismo di interruzione del ciclo

seen_calls = set()

for step in range(MAX_STEPS):
    action = model.next_action(state)
    signature = (action.tool_name, canonicalize(action.arguments))

    if signature in seen_calls:
        return fail("repeated tool call with no new information")
    seen_calls.add(signature)

    observation = run_tool(action.tool_name, action.arguments)
    state = update_state(state, action, observation)

    if verifier_says_done(state):
        return finalize(state)

Questo rileva un problema molto comune: il modello «vuole essere utile» e si limita a riformulare la stessa query.

Un’altra protezione utile: proseguire solo se c’è un guadagno di utilità

Se un passaggio non modifica abbastanza lo stato, non proseguire. Può bastare una condizione semplice come:

  • nessun nuovo file trovato,
  • nessuna nuova entità estratta,
  • nessun miglioramento del livello di confidenza nella risposta,
  • nessun nuovo elemento di prova aggiunto.

La metrica esatta dipende dall’attività, ma è essenziale avere una misura del guadagno marginale.

Cosa succede davvero quando ottimizzi bene questo processo

Quando rendi il ciclo più efficiente, l’agente di solito migliora in modi che all’inizio possono passare inosservati:

  • Diventa meno prolisso e più deciso.
  • Richiede prima lo strumento giusto.
  • Produce meno cicli di «sto ancora indagando».
  • Diventa più economico e più veloce, perché meno turni significano meno contesto e meno latenza.

Il compromesso importante è che limiti rigidi e una riduzione aggressiva del contesto possono rendere il sistema fragile nelle attività davvero difficili. Quindi non fingere che l’agente stia «risolvendo» problemi quando in realtà sta solo esaurendo il tempo a disposizione. Rendilo evidente con trasparenza nei log e nei messaggi rivolti agli utenti.

La mia regola pratica: puntare su una competenza entro limiti definiti anziché su un'esplorazione infinita.

Una configurazione pratica per la produzione

Se dovessi mettere in produzione un agente domani, partirei da:

  • MAX_STEPS = 5
  • stato strutturato, anziché riproporre l'intera trascrizione
  • memoria riepilogativa dopo ogni turno
  • sottoagenti economici per ricerca ed estrazione
  • cache dei risultati degli strumenti con metadati sull'aggiornamento
  • registrazione di token e costi per ogni esecuzione
  • rilevatore di chiamate ripetute
  • motivi di arresto espliciti

Questa configurazione non è appariscente, ma è ciò che impedisce alla fattura di crescere più rapidamente del prodotto.

Indicazioni pratiche

  • Limita prima di tutto i passaggi: è la protezione più economica contro i cicli fuori controllo.
  • Riduci drasticamente il contesto e mantieni lo stato strutturato separato dai riepiloghi.
  • Usa sottoagenti più economici per compiti circoscritti, anziché spendere token premium ovunque.
  • Memorizza nella cache gli output riutilizzabili degli strumenti, ma rendi visibile quanto sono aggiornati, così il modello non si fida ciecamente di dati obsoleti.
  • Registra la spesa per esecuzione, per passaggio e per chiamata a uno strumento, così gli aumenti indesiderati dei costi sono subito visibili.
  • Interrompi i cicli in caso di ripetizione, assenza di progressi o completamento verificato, non solo quando le risorse si esauriscono.
  • Progetta per una competenza entro limiti definiti: risultati sufficientemente buoni, rapidi e prevedibili battono sempre soluzioni ingegnose ma costose.
A

AI Prime Tech pubblica questo blog. Gli articoli sono redatti con l'assistenza dell'AI; verifica nella documentazione ufficiale i dettagli specifici della versione, come gli ID dei modelli, i prezzi e i limiti, prima di farvi affidamento.

Ottieni accesso all'API Claude a un costo inferiore

Un'unica chiave API per Claude Opus 5.5, Sonnet 5, Haiku 4.5 e Fable 5.1, oltre a GPT-6 modelli. Pagamento a consumo, senza abbonamento.

Ottieni la tua chiave API →
AI Prime Tech è un gateway API indipendente di terze parti. Claude™ e Anthropic® sono marchi di Anthropic, PBC. Non si intende suggerire alcuna affiliazione o approvazione.