Gran parte di ciò che le persone chiamano agente è in realtà una sequenza fissa di passi con una o due chiamate al modello nel mezzo. Il flusso di controllo è noto in anticipo, ma i team lo affidano comunque al modello, e poi passano settimane a far comportare bene un loop non deterministico. Quando la forma del lavoro è nota, l'orchestratore dovrebbe essere deterministico, e AWS Step Functions è più adatto a quel compito di un loop ad agente scritto a mano. Risolve già retry, timeout, gestione degli errori, parallelismo e approvazione umana, esattamente le cose che un framework ad agenti ti chiede di reimplementare.

Il modo utile di vederla: lascia che sia il modello a prendere le decisioni, non l'idraulica. Usa il modello per i passi che richiedono davvero giudizio, estrarre, classificare, redigere, e lascia che una state machine decida cosa gira, in che ordine, e cosa succede quando un passo fallisce. Non ti serve un LLM per sapere che il passo tre segue il passo due.

L'orchestrazione deterministica è una funzionalità, non un limite

Un loop ad agente fatto in casa mette il modello al comando del flusso di controllo: decide quale tool chiamare, legge il risultato, decide il tool successivo, e così via finché non pensa di aver finito. È il design giusto quando il percorso è genuinamente sconosciuto in fase di scrittura. È il design sbagliato quando il percorso è un workflow che potresti disegnare su una lavagna, perché a quel punto ogni esecuzione può prendere una strada diversa, i retry sono improvvisati, e un fallimento a metà lascia uno stato che devi ricostruire.

Step Functions ribalta la cosa. Dichiari gli stati e le transizioni. Ogni stato che richiede giudizio invoca Bedrock (direttamente o tramite una Lambda), ogni stato che non lo richiede è pura logica. L'esecuzione è riproducibile, ogni transizione è registrata, e la execution history è di per sé una traccia di audit. Per un workflow dalla forma nota, il determinismo è esattamente ciò che vuoi.

Retry e gestione degli errori che non scrivi tu

La maggioranza poco affascinante del lavoro sull'affidabilità degli agenti è la politica di retry. Una chiamata al modello va in throttling, un tool va in timeout, un'API a valle restituisce un 500 transitorio. In un loop fatto a mano scrivi backoff, jitter e gestione per tipo di errore a mano, e di solito la sbagli in modo sottile.

Step Functions rende tutto questo dichiarativo. Ogni stato porta il proprio comportamento di retry e catch:

"InvokeModel": {
  "Type": "Task",
  "Resource": "arn:aws:states:::bedrock:invokeModel",
  "Retry": [{
    "ErrorEquals": ["Bedrock.ThrottlingException"],
    "IntervalSeconds": 2,
    "BackoffRate": 2.0,
    "MaxAttempts": 5
  }],
  "Catch": [{
    "ErrorEquals": ["States.ALL"],
    "Next": "HandleFailure"
  }]
}

Il throttling ottiene backoff esponenziale, qualsiasi altra cosa viene instradata a uno stato di fallimento che controlli tu. Nessun codice di retry, nessuna eccezione persa, e il comportamento è visibile nella definizione invece che sepolto in un loop.

L'human-in-the-loop è uno stato di prima classe

Il punto dove gli agenti fatti a mano fanno più male è mettersi in pausa per un essere umano. Un agente che può spendere denaro, mandare email, o modificare la produzione dovrebbe fermarsi e attendere l'approvazione, e farlo in un processo di lunga durata significa mantenere uno stato da qualche parte mentre una persona impiega ore o giorni a rispondere.

Step Functions ha questo già integrato tramite il callback pattern. Un task avviato con .waitForTaskToken mette in pausa l'esecuzione, emette un token, e non fa nulla finché qualcosa non chiama SendTaskSuccess o SendTaskFailure con quel token. Il workflow può restare in pausa per tutto il tempo che serve all'approvazione senza un processo in esecuzione, e poi riprendere esattamente dal punto in cui si era fermato. Ottieni un gate umano durevole e verificabile senza costruire una coda, uno state store e un meccanismo di ripresa tuoi.

Quando vuoi ancora un vero loop ad agente

Questo non è un argomento contro i loop ad agente, è un argomento per usarli dove si guadagnano il loro posto. Ricorri a un loop guidato dal modello quando il percorso è genuinamente aperto: il modello deve decidere, a runtime, quale dei molti tool usare e in quale ordine, e nessun grafo fisso lo cattura. La ricerca aperta, il debugging libero, e i task in cui il prossimo passo dipende da ciò che ha restituito l'ultimo in modi che non puoi enumerare sono la vera casa del loop ad agente.

La trappola è usare quel pattern per una pipeline a cinque passi con un solo ramo. Se riesci a disegnare il flowchart, codifica il flowchart. Riserva il loop non deterministico al lavoro che è davvero non deterministico.

Il punto chiave

Una gran parte del lavoro con agenti in produzione è orchestrazione deterministica travestita da agente. Per quel lavoro, Step Functions ti dà retry, instradamento degli errori, parallelismo, e uno stato di approvazione umana durevole che altrimenti dovresti costruire e mantenere a mano, più una execution history che funge anche da log di audit. Lascia che il modello faccia le chiamate che richiedono giudizio, e lascia che una state machine possieda il flusso di controllo. L'agente più affidabile è spesso quello in cui il modello decide di meno.

Leggi questo dopo

Per la lettura infrastrutturale e platform dello stesso pattern, inclusi i gate di approvazione sulle operazioni ad alto rischio, le note di campo sul cloud sono su ercan.cloud, e l'hub è su ercanermis.com.