A2A Streaming e Task Asincroni per Flussi di Lavoro di Agenti a Lunga Durata

I task A2A di lunga durata superano la durata delle sessioni di chat.

Indice

La maggior parte delle demo di agenti AI si comporta ancora come completamenti di chat con passaggi aggiuntivi: invii un prompt, aspetti qualche secondo e ricevi una risposta in un’unica output.

Il lavoro reale degli agenti spesso non si adatta a questo schema. Ricerche, revisioni del codice, analisi degli acquisti, indagini su incidenti e pianificazione multi-step possono richiedere minuti o ore e potrebbero necessitare di chiarimenti a metà processo, trasmettere risultati parziali in streaming, delegare il lavoro a un altro agente e produrre file anziché una singola risposta testuale. È qui che il modello asincrono del protocollo A2A diventa importante all’interno del più ampio cluster di Sistemi AI, poiché A2A tratta il lavoro di lunga durata come un Task (Compito) con un ciclo di vita, anziché come una risposta HTTP one-shot. I client possono rimanere connessi tramite Server-Sent Events (SSE), eseguire polling dello stato del task o registrare webhook push quando non possono mantenere una connessione aperta.

Ciclo di vita del task asincrono e streaming A2A per flussi di lavoro degli agenti di lunga durata

Questo articolo copre il design operativo per questi flussi di lavoro, includendo quando utilizzare lo streaming rispetto al polling o al push, come input_required si integra nei flussi human-in-the-loop, la gestione degli errori e cosa monitorare in produzione. Per Agent Cards, messaggi, parti e il modello completo dei task, vedi Cos’è il Protocollo A2A? Agent Cards e Tasks Spiegati.

Perché i Task A2A degli Agenti di Lunga Durata Necessitano di Design Asincrono

Il modello mentale sincrono di richiesta/risposta crolla rapidamente una volta che il lavoro degli agenti coinvolge strumenti, deleghe, approvazioni e grandi artefatti. Un task di un agente potrebbe chiamare internamente diversi server MCP, delegare sotto-lavori a un altro agente tramite A2A, attendere l’approvazione umana, generare grandi artefatti in blocchi, fallire a metà e necessitare di un recupero parziale, e accumulare costi di token attraverso diversi passaggi. Le API HTTP possono approssimare questo comportamento con timeout, lavori in background ed endpoint di status ad hoc, ma A2A integra l’identità e lo stato del task nel protocollo, permettendo a client e gateway di ragionare sul lavoro in modo coerente. Per capire come questi livelli si integrano in un assistente di produzione prima di aggiungere confini A2A asincroni, vedi Architettura Assistente AI: LLM, Memoria, Strumenti, Routing, Osservabilità.

Il mio approccio è pratico: non creare un Task per tutto, perché un riepilogo di una riga non ha bisogno di un ciclo di vita. Usa un Task quando il lavoro è stato (ha uno stato), è auditabile, di lunga durata, produce artefatti o potrebbe necessitare di input durante il processo. La regola generale dell’articolo introduttivo rimane valida: le interazioni semplici possono restituire un Messaggio, mentre il lavoro complesso dovrebbe restituire un Task.

Ciclo di Vita dei Task A2A e Transizioni di Stato

Un Task A2A passa attraverso stati che i client possono interrogare in qualsiasi momento. La denominazione esatta varia leggermente tra le implementazioni, ma il modello è stabile tra i server che seguono il protocollo.

stateDiagram-v2 [*] --> submitted submitted --> working working --> input_required input_required --> working working --> completed working --> failed working --> canceled working --> rejected submitted --> rejected input_required --> failed input_required --> canceled completed --> [*] failed --> [*] canceled --> [*] rejected --> [*]

Lo stato submitted (invitato) significa che il client ha inviato il lavoro e l’agente lo ha accettato o messo in coda. In working (in lavorazione), l’agente sta elaborando attivamente, il che può includere chiamate a strumenti, deleghe o streaming di output parziali. Lo stato input_required (input richiesto) indica che l’agente si è fermato perché ha bisogno di più input, chiarimenti o approvazione umana, e non è uno stato di errore. completed (completato) è un successo terminale con artefatti disponibili; failed (fallito) è un errore terminale i cui dettagli e artefatti parziali dipendono dall’implementazione; canceled (cancellato) significa che un client, un gateway o un chiamante autorizzato ha fermato il task; e rejected (rifiutato) significa che l’agente ha rifiutato il task a causa di policy, mancata corrispondenza delle capacità o autenticazione.

Quando input_required mette in pausa rispetto a fallire un flusso di lavoro

Tratta input_required come una pausa deliberata, non come un’eccezione. L’agente ti sta dicendo che non può procedere senza qualcosa da parte tua, che si tratti di un parametro mancante, di una conferma di policy o di un’approvazione di un manager per un’azione ad alto rischio. Un flusso di lavoro fallisce quando il task raggiunge lo stato failed o rejected, o quando un chiamante supera un timeout aspettando un input che non arriva mai, quindi dovresti progettare timeout espliciti per i passaggi umani anziché lasciare che le approvazioni restino in attesa indefinitamente.

Un’approvazione che aspetta tre giorni senza escalation è un flusso di lavoro bloccato, non uno paziente, e i flussi di lavoro bloccati intasano gli store dei task rendendo più difficili da leggere le dashboard di osservabilità.

Chi può cancellare un task A2A

L’autorità di cancellazione dovrebbe essere definita al momento del design piuttosto che discussa durante un incidente. Il client di solito può cancellare i task che ha creato; un gateway può cancellare per conto dei tenant, violazioni di policy o limiti di budget; e un agente upstream (a monte) può cancellare il lavoro delegato quando orchestra tramite A2A se il protocollo e la policy lo consentono. Registra chi ha cancellato e perché, perché nelle catene multi-agente il lavoro orfano è una fonte comune di costi di token inaspettati.

Human-in-the-Loop con gli Stati dei Task input_required

input_required è una delle funzionalità di design di A2A più sottovalutate, e molti team lo trattano come un codice di errore quando in realtà è uno stato di flusso di lavoro di primo livello. In produzione incontrerai casi in cui l’agente dovrebbe fermarsi, come spendere budget per una richiesta ambigua, eseguire un’azione irreversibile, accedere a dati sensibili senza conferma dello scope o delegare a un specialista che necessita di un’intento utente esplicito. Modella queste situazioni come transizioni deliberate a input_required, con un messaggio chiaro che spiega cosa è necessario.

Flussi di approvazione per la delega A2A rischiosa

Quando l’Agente A delega all’Agente B tramite A2A e l’Agente B entra in input_required per l’approvazione umana, tre sistemi devono concordare su cosa succederà dopo. L’agente downstream si ferma ed espone ciò di cui ha bisogno, l’orchestratore o il gateway mostra quella pausa all’utente, e la risposta dell’utente riprende il task tramite un nuovo messaggio. Il confronto A2A vs MCP spiega perché la delega attraverso i confini degli agenti è un problema diverso dall’accesso agli strumenti, e perché la semantica di approvazione appartiene al livello dei task piuttosto che all’interno di una singola chiamata MCP. Non approvare automaticamente in silenzio solo perché l’UX è scomoda, poiché gli errori costosi di solito derivano da scorciatoie di convenienza piuttosto che da modelli mancanti.

Pattern UX per i task A2A in pausa

Attesa bloccante significa che l’interfaccia utente mostra un caricamento o una scheda di approvazione fino a quando il task non esce da input_required, il che funziona bene per passaggi umani brevi. Attesa non bloccante significa che il client registra l’ID del task, permette all’utente di continuare altrove e utilizza il polling o il push per notificare quando l’input è necessario di nuovo, il che è necessario per mobile, approvazioni collegate via email o assistenti multi-tab. Timeout quando gli umani sono lenti significa definire un SLA per ogni passaggio e, dopo N ore, passare a failed o escalare a un’altra coda, perché le attese illimitate intasano gli store dei task e confondono le dashboard di osservabilità.

Come un gateway A2A gestisce input_required

Se gestisci un gateway A2A, decidi se inoltra gli eventi input_required in modo trasparente, aggrega le pause da più agenti downstream in un’unica richiesta all’utente o impone che determinate competenze richiedano sempre approvazione prima di uscire da input_required. L’autenticazione e le policy per le azioni approvate appartengono a un articolo dedicato sulla sicurezza; per ora, assumi che ogni task ripreso debba portare la stessa identità utente e scope della richiesta originale.

Scegliere Sync, Streaming SSE, Polling o Notifiche Push

A2A supporta più modalità di interazione, e la scelta giusta dipende dalle capacità del client e dalle esigenze di latenza, piuttosto che da quale modalità suona più moderna.

Modalità Ideale per Requisiti del client Compromessi
Sync (SendMessage, Task breve) Lavoro veloce, messaggi immediati Client HTTP semplice Timeout su agenti lenti
Streaming SSE Progressi in tempo reale, artefatti incrementali Connessione a lunga durata Proxy, limiti background mobile
Polling (GetTask) Client batch, integrazioni semplici Timer + ID task Latenza maggiore, più richieste
Webhook Push Mobile, serverless, lavori di ore/giorni Ricevitore HTTPS + verifica Complessità asincrona, hardening sicurezza

Leggi prima i flag di capacità della Agent Card

Prima di scegliere una modalità, leggi la Agent Card dell’agente, perché lo streaming richiede capabilities.streaming: true e il supporto per le notifiche push è annunciato separatamente. I client che assumono che ogni agente supporti lo streaming si romperanno contro implementazioni minimali, quindi la negoziazione non è cerimoniale: previene errori di runtime quando un agente specializzato supporta solo controlli di status basati su polling.

Quando usare il polling lato assistente intorno ad A2A

Il runtime del tuo assistente potrebbe avvolgere il polling dei task A2A in un ciclo di scheduler anziché esporre i dettagli del protocollo grezzo all’utente. Questo pattern si sovrappone agli agenti di polling generali, che sono processi in background che si attivano, controllano lo stato e agiscono. Per la pianificazione durevole, l’idempotenza e i pattern di coda al di fuori di A2A specificamente, vedi Agenti di Polling negli Assistenti AI: 11 Pattern di Implementazione. Usa il polling dell’assistente quando orchestri molti task A2A da un unico piano di controllo, e usa lo streaming o il push nativo A2A quando il client si connette direttamente al confine dell’agente.

Streaming A2A con Server-Sent Events (SSE)

SSE è il canale principale in tempo reale di A2A. Il client chiama SendStreamingMessage, apre una connessione HTTP e riceve una risposta text/event-stream fino a quando il task non raggiunge uno stato terminale o interrotto. Il payload di ogni evento ha una struttura JSON-RPC, e i tipi di risultato tipici includono uno snapshot di un Task, un TaskStatusUpdateEvent per transizioni di ciclo di vita e messaggi intermedi dell’agente, e un TaskArtifactUpdateEvent per la consegna di artefatti a blocchi con suggerimenti append e lastChunk per il riassetto.

sequenceDiagram participant Client participant A2A Server Client->>A2A Server: SendStreamingMessage A2A Server-->>Client: HTTP 200 text/event-stream loop Fino a stato terminale o input_required A2A Server-->>Client: TaskStatusUpdateEvent A2A Server-->>Client: TaskArtifactUpdateEvent (opzionale) end A2A Server-->>Client: Chiudi stream Note over Client,A2A Server: In caso di disconnessione prima dello stato terminale,
il client può chiamare SubscribeToTask

Aggiornamenti dei progressi in streaming e artefatti parziali

Lo streaming brilla quando gli utenti dovrebbero vedere il lavoro in corso, che significhi contatori di passaggi (“3 di 7 fonti revisionate”), generazione di testo parziale, blocchi di file incrementali per grandi report, o transizioni di stato da working a input_required senza polling. Progetta l’interfaccia utente intorno ai tipi di evento piuttosto che intorno a un unico blob finale, perché se mostri l’output solo quando arriva completed potresti tanto fare polling.

Interruzioni delle connessioni SSE e rescrizione

Le reti si interrompono, i laptop vanno in stand-by e i load balancer timeout le connessioni SSE, quindi gli stream lunghi necessitano di logica di recupero anziché di assunzioni ottimistiche. A2A fornisce SubscribeToTask così i client possono riconnettersi a uno stream di task in corso, e il tuo SDK client dovrebbe persistere localmente taskId, rilevare la chiusura dello stream prima dello stato terminale, risottoscrivere con backoff e deduplicare gli eventi se il server riproduce stati sovrapposti. Senza logica di rescrizione, i task lunghi sembrano fragili in produzione anche quando il backend dell’agente è sano.

Notifiche Push e Webhook A2A

Il push si adatta a scenari in cui SSE è una cattiva corrispondenza, come app mobile in background, handler serverless o task che girano per ore o giorni. Il client fornisce una PushNotificationConfig con un url (webhook HTTPS lato client), un token opzionale per validare i POST in arrivo e dettagli authentication opzionali per come il server A2A si autentica al webhook. La configurazione può viaggiare insieme alla chiamata iniziale SendMessage o SendStreamingMessage, o essere aggiunta successivamente tramite CreateTaskPushNotificationConfig per un task esistente.

sequenceDiagram participant Client participant A2A Server participant Webhook Client->>A2A Server: SendMessage + PushNotificationConfig A2A Server-->>Client: taskId Note over A2A Server: Il task gira asincronamente A2A Server->>Webhook: POST notifica cambiamento stato Webhook->>A2A Server: GetTask(taskId) A2A Server-->>Webhook: Task aggiornato + artefatti Webhook->>Client: Riprendi flusso di lavoro / notifica utente

Quando si verifica un aggiornamento significativo, il server A2A POST al webhook e il client tipicamente chiama GetTask con il taskId notificato per recuperare il Task completo aggiornato e gli artefatti. Il push è un segnale, non un trasporto completo del payload.

Quando il push batte una connessione SSE aperta

Preferisci il push quando il client non può mantenere SSE (mobile, funzioni edge), quando gli aggiornamenti sono infrequenti e basati su traguardi piuttosto che token per token, o quando vuoi che il server svegli un motore di flusso di lavoro disconnesso. Preferisci SSE quando gli utenti guardano i progressi in diretta, quando gli artefatti vengono trasmessi in molti piccoli blocchi, o quando la latenza inferiore a pochi secondi è importante.

Correlare le notifiche push ai task A2A

Ogni handler push dovrebbe registrare e propagare il taskId, un ID di traccia o correlazione dalla richiesta originale, il tipo di evento o transizione di stato e un timestamp dalla notifica in modo che gli eventi obsoleti possano essere rifiutati. Gli attacchi di replay e le consegne duplicate accadono in produzione, quindi gli handler idempotenti non sono opzionali.

Panoramica sulla sicurezza degli endpoint Push

Il push introduce il rischio SSRF sul server quando client maliziosi registrano URL interni, e il rischio di impersonificazione sul client quando POST falsi arrivano al webhook. Le mitigazioni includono whitelist di URL, verifica della proprietà, JWT firmati con JWKS, controlli del timestamp e validazione del token di configurazione. Il modello di minaccia completo, i layer di identità e i controlli del gateway vivono in Sicurezza Agenti A2A e MCP: Identità, Delega e Audit Trail; fino a quando non l’hai letto, tratta la verifica dei webhook con la stessa serietà dei callback di pagamento.

Pattern di Flusso di Lavoro Asincrono A2A

Invio di task Fire-and-follow

Il client invia un task, riceve immediatamente un ID del task e si disconnette, per poi eseguire polling di GetTask in seguito o attendere il push. Questo è il pattern predefinito per pipeline serverless e batch, ma dovresti persistere l’ID del task in uno storage durevole prima di riconoscere l’utente, perché le invocazioni serverless che dimenticano l’ID perdono il lavoro.

Ripresa di un task dopo input_required

Dopo input_required, l’utente invia un nuovo messaggio sullo stesso task e l’agente torna a working. Progetta i messaggi in modo che il contesto di ripresa sia esplicito, perché “Approvato: procedere con il fornitore X” batte un nudo “sì” quando devi auditare cosa è stato approvato sei ore dopo.

Delega A2A concatenata con artefatti intermedi

Considera un flusso di lavoro di ricerca in cui un orchestratore possiede il Task T1 e delega il recupero, la sintesi e la verifica ad agenti specialisti, ciascuno con il proprio ID del task e artefatti lungo il percorso.

flowchart TD U[Utente] --> O[Task Orchestratore T1] O -->|A2A| R[Agente di Recupero T2] R --> A2[artefatto: fonti grezze] O -->|A2A| S[Agente di Sintesi T3] S --> A3[artefatto: bozza di sintesi] O -->|A2A| V[Agente di Verifica T4] V --> A4[artefatto: report fact-check] O --> F[artefatto finale: memo di raccomandazione]

Ogni salto ha il proprio ID del task e macchina a stati, quindi l’orchestratore dovrebbe trasmettere in streaming o eseguire polling dei task downstream indipendentemente, persistere gli artefatti intermedi prima di iniziare il prossimo salto e fallire in modo elegante se T3 completa ma T4 rifiuta la bozza. Pattern di Orchestrazione Multi-Agente copre la scelta della topologia quando quegli specialisti girano come servizi separati piuttosto che in un unico runtime. Il progresso parziale è prezioso, e una verifica fallita non dovrebbe eliminare una bozza utilizzabile senza un motivo chiaro.

Storage dei task durevole per completamento ritardato

Lo stato del task e gli artefatti dovrebbero sopravvivere ai riavviani del processo. Se il tuo agente gira su Kubernetes, assumi che i pod muoiano a metà task e fai backup dei record dei task e dei blob degli artefatti su uno store che il container dell’agente non possiede in esclusiva.

Gestione degli Errori per Flussi di Lavoro A2A di Lunga Durata

I flussi di lavoro di lunga durata falliscono in modi prevedibili attraverso timeout, retry, artefatti parziali e cancellazione non sicura, e ciascuno necessita di una policy esplicita anziché di una gestione ad hoc nel codice del client.

Budget di timeout per ogni hop e end-to-end

Imposta i timeout su due livelli: un massimo per hop per un task di un agente prima dell’escalation o della cancellazione, e un massimo end-to-end per il flusso di lavoro visibile all’utente. Un agente di recupero che si blocca non dovrebbe bloccare l’intero orchestratore fino a quando il browser dell’utente non scade.

Retry e idempotenza per i task A2A

I retry senza idempotenza duplicano effetti collaterali come doppie addebiti, ticket duplicati ed email ripetute. Usa ID di messaggio client stabili o chiavi di idempotenza dove il protocollo lo permette, e per le mutazioni di business allineati con Idempotenza nei Sistemi Distribuiti che Funziona Davvero. Riprova solo i fallimenti transitori come interruzioni di rete o 503, e non provare a ritentare ciecamente rejected o fallimenti di policy perché amplificherai il costo e infastidirai gli agenti downstream.

Policy di recupero degli artefatti parziali

Quando un task fallisce dopo aver prodotto artefatti parziali, definisci se esponi l’output parziale all’utente con un’etichetta chiara “incompleto”, permetti la ripresa dall’ultimo checkpoint valido o scarti l’output parziale quando potrebbe fuorviare in contesti medici, legali o finanziari.

Cancellazione sicura attraverso catene di delega

Cancella i task downstream quando un utente upstream abortisce, usa un grafico di delega in modo che la cancellazione si propaghi e registra i task cancellati che hanno già incassato costi, perché i team finanziari se ne accorgono.

Osservabilità per Flussi di Lavoro A2A Asincroni

Non puoi debuggare il lavoro asincrono multi-agente a meno che tu non possa tracciarlo attraverso i confini, il che significa correlare identificatori su ogni hop piuttosto che affidarsi a log non strutturati. I campi di correlazione minimi includono un trace ID per ogni flusso di lavoro avviato dall’utente, un task ID per ogni task dell’agente inclusi i figli delegati, un agent ID per la Agent Card o il servizio che ha gestito l’hop, e un parent task ID che collega le catene di delega.

Registra ogni transizione di stato con timestamp, e registra gli eventi di creazione degli artefatti con dimensione e hash anziché necessariamente il contenuto completo quando si applicano policy PII. Attribuisce costo e latenza per hop, perché i flussi di lavoro multi-agente nascondono la spesa di token fino all’arrivo della fattura e le etichette di costo per task rendono rispondibile la domanda “quale specialista è costoso?”. Per metriche, backend di tracing e pattern di strumentazione specifici per LLM, vedi Osservabilità per Sistemi LLM e il più ampio pilastro Osservabilità per capire come questi segnali si integrano in uno stack di telemetria di produzione. Quando un utente chiede “perché l’agente ha fatto quella cosa?”, la tua risposta dovrebbe essere una traccia che copre orchestratore, hop A2A, chiamate agli strumenti MCP e qualsiasi pausa input_required, anziché un’alcata e un grep dei log.

Checklist di Produzione per Streaming e Task Asincroni A2A

Prima di inviare i percorsi A2A di lunga durata alla produzione, verifica le seguenti aree.

Agent Card e capacità

  • capabilities.streaming riflette il supporto SSE effettivo
  • Supporto notifiche push documentato se implementato
  • Le competenze che richiedono approvazione umana documentano il comportamento previsto input_required

Modalità Client

  • Il client SSE gestisce la rescrizione tramite SubscribeToTask
  • L’intervallo di polling fa backoff sotto carico
  • Il webhook Push verifica l’autenticità e rifiuta gli eventi obsoleti

Durabilità

  • Lo stato del task sopravvive ai riavviani del processo dell’agente
  • Artefatti memorizzati al di fuori del filesystem effimero del container
  • Artefatti intermedi disponibili per il recupero parziale

Fallimento e Policy

  • Budget di timeout per hop e end-to-end definiti
  • Retry idempotenti per operazioni mutanti
  • La cancellazione si propaga attraverso gli spigoli di delega

Osservabilità

  • trace ID + task ID + agent ID su ogni hop
  • Transizioni di stato registrate
  • Attribuzione del costo per task o per agente

Test di Carico

  • SSE attraverso il tuo reverse proxy (il buffering rompe gli stream)
  • Task lunghi concorrenti senza memory leak sulle connessioni aperte
  • Gestione dell’inondazione Push senza sovraccarico del webhook

Conclusione

Il valore di A2A si mostra più chiaramente quando il lavoro non si adatta a una singola chiamata API sincrona, perché streaming, task asincroni, notifiche push e stati dei task espliciti sono il modo in cui il protocollo gestisce carichi di lavoro reali degli agenti come ricerca, delega, approvazioni e grandi artefatti senza fingere che tutto si completi in un unico round trip HTTP. Inizia con la modalità più semplice che funziona, aggiungi SSE quando gli utenti hanno bisogno di progressi in tempo reale, aggiungi push quando le connessioni non possono rimanere aperte, tratta input_required come uno strumento di design di primo livello anziché come un fallimento, e strumentalizza ogni hop in modo che i flussi di lavoro asincroni multi-agente non superino la tua capacità di spiegarli.

Domande Frequenti

Quando dovresti usare lo streaming A2A invece del polling? Usa lo streaming quando il client può mantenere una connessione HTTP aperta e hai bisogno di aggiornamenti di progresso a bassa latenza o artefatti incrementali. Usa il polling quando le connessioni sono inaffidabili, i client sono orientati al batch, o hai bisogno solo di controlli di status periodici su task di lunga durata.

Cosa significa input_required in un task A2A? È uno stato di pausa in cui l’agente ha bisogno di più informazioni o approvazione umana. Progetta UX e timeout intorno ad esso esplicitamente anziché trattarlo come un errore.

Come funzionano le notifiche push A2A? Registra una PushNotificationConfig con un webhook HTTPS. Il server POST su aggiornamenti significativi; il client chiama GetTask per recuperare lo stato completo e gli artefatti.

Come dovresti ritentare i task A2A falliti? Ritenta i fallimenti transitori con chiavi di idempotenza, rispetta i budget di timeout e non ritentare ciecamente stati terminali come rejected o fallimenti di policy.

Cosa dovresti registrare per i flussi di lavoro A2A di lunga durata? Correla trace ID, task ID e agent ID attraverso gli hop. Registra transizioni di stato, artefatti, deleghe, approvazioni e costo per passaggio in modo che tu possa ricostruire l’intero flusso di lavoro.

Fonti

Iscriviti

Ricevi nuovi articoli su sistemi, infrastruttura e ingegneria AI.