Pattern di orchestrazione, isolamento e conflitti

Un agente che lavora bene è un risultato; cinque agenti che lavorano insieme male è un problema nuovo. Dividere un compito grande fra più esecutori serve solo se il risultato resta integrabile. Prima regola operativa: dire sempre di quale superficie si parla, perché cloud agent, Copilot CLI, Copilot SDK e GitHub Agentic Workflows orchestrano in modo diverso e non ereditano le capacità l’uno dall’altro.

Scegliere un pattern di orchestrazione

Il pattern dominante è orchestrator-worker: un agente padre decompone la richiesta, dispaccia le unità e riconcilia i risultati. Sul Copilot SDK ha un nome e un’API, la fleet mode, avviata con session.rpc.fleet.start() con un prompt opzionale. La sessione padre coordina più sub-agent indipendenti eseguiti in parallelo, e lo stato condiviso di coordinamento è una lista di todos in SQL: ogni voce ha uno status che passa da pending a in_progress a done, oppure blocked, e una tabella todo_deps esprime le dipendenze, così l’orchestratore dispaccia solo le voci davvero pronte. La regola di ownership è secca: ogni sub-agent possiede esattamente un todo per volta.

await session.rpc.fleet.start({ prompt: "one owner per todo" });

Sulla Copilot CLI lo stesso concetto arriva come slash command: /fleet prende un piano di implementazione e lo spezza in task più piccoli e indipendenti eseguiti in parallelo dai subagent, con l’agente principale che fa da orchestrator e gestisce le dipendenze fra i sottotask. Puoi indirizzare un agente specifico con la sintassi @nome-agente.

Un secondo pattern è la specializzazione per ruolo. I custom agents del SDK si definiscono con name e prompt e possono restringere tools, cambiare model e precaricare skills; il runtime li seleziona per intent matching sulla base della description, a meno che non disattivi infer. La documentazione accoppia un researcher in sola lettura con un editor abilitato alla scrittura: la separazione dei permessi diventa parte del disegno.

Il cloud agent non ha una fleet mode. Ogni sessione affronta un task, lavora su un branch alla volta e apre esattamente una pull request per il task assegnato. Il parallelismo lo costruisci tu, assegnando più task e sorvegliandoli dalla agents page, che mostra le sessioni attraverso i tuoi repository.

L’isolamento viene prima del parallelismo

Senza isolamento il parallelismo non è velocità, è collisione: due agenti che scrivono sugli stessi file nella stessa copia di lavoro producono modifiche sovrapposte. Le forme da riconoscere sono quattro.

Un agente per branch: è il modello del cloud agent, che non condivide il branch e chiude il lavoro in una sola pull request.

Un agente per ambiente: il cloud agent gira in un ambiente di sviluppo effimero suo, alimentato da GitHub Actions. Le cloud sandboxes sono ambienti Linux effimeri e isolati ospitati da GitHub; il local sandboxing applica un isolamento a livello di sistema operativo sulla tua macchina, con una policy di filesystem deny-by-default risolta per directory e per comando.

Un agente per sessione: nel SDK puoi dare a ogni utente un server CLI isolato, condividere un server con sessioni separate da session ID unici, oppure condividere la sessione e serializzare gli accessi con il session locking.

Un agente per workflow run: nei GitHub Agentic Workflows il Markdown viene compilato in un workflow di Actions irrigidito (.lock.yml), l’agente gira in un ambiente Actions isolato, in sola lettura per default, e scrive solo attraverso i safe-outputs dichiarati nel frontmatter.

Non confondere i due assi. Una sandbox limita che cosa un agente può toccare di filesystem e rete; non impedisce a due agenti puntati sulla stessa copia di lavoro di modificare lo stesso file. L’isolamento del lavoro si ottiene con unità disgiunte, branch separati o repository separati.

I tre conflitti e come accorgersene prima del merge

Modifiche di codice sovrapposte. La prevenzione sta nel disegno delle unità: la documentazione della fleet mode dice di evitare di assegnare file sovrapposti a worker diversi, a meno che l’agente padre non riconcili i conflitti in modo esplicito, e di non usarla per modifiche strettamente accoppiate in cui i worker si contendono gli stessi file. Quando le parti dipendono l’una dall’altra il pattern giusto è lo stack di pull request: ognuna punta al branch di quella sotto, ogni livello resta una modifica coerente e rivedibile da sola, e i livelli si fondono uno alla volta con il re-targeting automatico.

Lavoro duplicato. Serve un claim, non solo una lista: il sub-agent prende una voce pronta portandola a in_progress prima di lavorarci, e le todo_deps evitano che qualcuno parta su un pezzo non ancora sbloccato. Senza claim, due agenti che leggono la stessa lista fanno due volte la stessa cosa.

Output contraddittori. È il più insidioso perché non rompe il merge, rompe il progetto. La documentazione è esplicita: la fleet mode non elimina la necessità della revisione da parte dell’agente padre, perché worker paralleli possono produrre assunzioni incoerenti che l’orchestratore deve riconciliare. Conviene affiancare una revisione incrociata automatica: GitHub Copilot code review si può configurare per intervenire alla creazione della pull request o a ogni push successivo.

Che cosa ti viene chiesto

Aspettati scenari in cui devi indicare il pattern o il rimedio corretto. L’errore più costoso è l’attribuzione di superficie: la fleet mode è del Copilot SDK, /fleet è della CLI, nessuna delle due appartiene al cloud agent. Il secondo è trattare l’orchestrazione come garanzia di coerenza: unità disgiunte e claim riducono conflitti di file e doppioni, ma solo la revisione intercetta gli output contraddittori.