Non si tratta di velocità. Si tratta di far sì che più agenti con punti di vista diversi discutano su una decisione e raggiungano una conclusione migliore di quella che ciascuno di loro potrebbe raggiungere da solo. Con il codice completo per orchestratore, esperti e unione.
Quando chiedi a un singolo modello di valutare una decisione, ottieni un'unica visione, solitamente media e cauta. Tende ad essere d'accordo, ad appianare, a trovare un equilibrio. Questo è il problema: una decisione importante non può essere valutata da un'unica visione media, deve essere attaccata da diversi lati.
Uno sciame di agenti risolve strutturalmente questo problema. Crei diversi esperti, ognuno con un ruolo e un pregiudizio ben definiti: uno pensa solo ai soldi, un altro solo al rischio tecnico, un terzo solo all'utente. Analizzano una decisione in modo indipendente, raggiungono conclusioni diverse, e poi imponi una riconciliazione di tali conclusioni. Il valore qui non è la velocità, ma il fatto che il disaccordo è incorporato nella struttura. Un singolo agente tende al pensiero di gruppo con se stesso, uno sciame di ruoli no.
Questo articolo mostra come costruire un tale sciame, con codice. Trattiamo tre parti: l'orchestratore che assegna i ruoli, gli esperti che analizzano in modo indipendente e l'unione che li riconcilia in un'unica conclusione.
Architettura: Orchestratore, Esperti, Unione
Uno sciame per l'analisi è composto da tre componenti.
L'orchestratore prende il compito e decide quali ruoli di esperti sono necessari. Per valutare il lancio di un prodotto, questi potrebbero essere un investitore, un ingegnere, un product specialist, un esperto di sicurezza. L'orchestratore non analizza da solo, distribuisce i ruoli.
Gli esperti lavorano in parallelo e in modo indipendente. Ognuno vede la stessa decisione ma attraverso la propria lente. Fondamentalmente, non vedono le conclusioni degli altri, altrimenti subentra il conformismo. L'indipendenza è ciò che produce punti di vista diversi.
L'unione raccoglie le conclusioni degli esperti e le riconcilia: dove sono d'accordo, dove si contraddicono, qual è il verdetto finale su tutti gli angoli. Non si tratta di una media, ma di una sintesi che mantiene il disaccordo come segnale.

Passaggio 1: Il Client di Base
Inizia con un semplice client per il modello. Utilizzo un formato di messaggio compatibile con OpenAI, funziona con la maggior parte dei provider e con Ollama in locale.
1import requests2import json3from concurrent.futures import ThreadPoolExecutor45API = "http://localhost:11434/api/chat" # Ollama, o un endpoint del provider6MODEL = "qwen2.5:32b"78def ask(system, user, temperature=0.7):9 resp = requests.post(API, json={10 "model": MODEL,11 "messages": [12 {"role": "system", "content": system},13 {"role": "user", "content": user},14 ],15 "temperature": temperature,16 "stream": False,17 }, timeout=120)18 resp.raise_for_status()19 return resp.json()["message"]["content"]
Passaggio 2: L'Orchestratore Assegna i Ruoli
L'orchestratore riceve il compito e decide quali esperti sono necessari. Non codificare i ruoli in anticipo, lascia che il modello li scelga per il compito specifico, questo rende lo sciame generico. Richiedi JSON rigoroso per analizzarlo.
1ORCHESTRATOR_SYSTEM = """Sei l'orchestratore di uno sciame analitico.2Per il compito, definisci 3-5 ruoli di esperti che daranno opinioni3MASSIMAMENTE DIVERSE e in conflitto sulla decisione. I ruoli devono4confliggere nei loro interessi, non complementarsi a vicenda.56Per ogni ruolo dai: nome, focus (su cosa si fissa), bias (verso cosa è7drogato, cosa tende a sopravvalutare).89Rispondi SOLO con un array JSON, senza spiegazioni:10[{"name": "...", "focus": "...", "bias": "..."}, ...]11"""1213def plan_roles(task):14 raw = ask(ORCHESTRATOR_SYSTEM, f"Task to analyze:\n{task}",15 temperature=0.9) # temperatura più alta per diversità di ruoli16 # taglia il JSON nel caso il modello abbia aggiunto testo intorno17 start, end = raw.find("["), raw.rfind("]") + 118 return json.loads(raw[start:end])
Manteniamo la temperatura alta qui apposta: vogliamo ruoli diversificati, non ovvi. Il requisito "i ruoli devono confliggere" nel prompt è la chiave, senza di esso il modello dà tre ruoli quasi identici e l'intero senso dello sciame è perso.
Passaggio 3: Gli Esperti Analizzano in Parallelo e Indipendentemente
Ogni esperto riceve il suo ruolo e la stessa decisione. Fondamentalmente: lavorano in parallelo e non vedono le conclusioni degli altri. Il parallelismo qui non è solo per la velocità, garantisce l'indipendenza, un esperto non può fisicamente adattarsi all'opinione di un altro.
1EXPERT_SYSTEM = """Sei un esperto con il ruolo: {name}.2Il tuo focus: {focus}.3Il tuo bias: {bias}. Non combatterlo, è il tuo valore per l'analisi.45Analizza la decisione STRETTAMENTE dalla tua posizione. Non essere equilibrato,6non cercare di tenere conto di altri punti di vista, lo faranno altri esperti.7Il tuo compito è spingere la tua angolazione al limite.89Dai:10- un verdetto dalla tua posizione (a favore / contro / condizionale)11- 2-3 argomenti principali specificamente dalla tua angolazione12- 1 rischio che è più visibile dalla tua posizione e che gli altri si perderanno13Corto e duro, senza fronzoli."""1415def run_expert(role, task):16 system = EXPERT_SYSTEM.format(**role)17 opinion = ask(system, f"Decision to analyze:\n{task}", temperature=0.7)18 return {"role": role["name"], "opinion": opinion}1920def run_swarm(roles, task):21 # lancio parallelo: indipendenza più velocità22 with ThreadPoolExecutor(max_workers=len(roles)) as pool:23 futures = [pool.submit(run_expert, role, task) for role in roles]24 return [f.result() for f in futures]
Nota il prompt dell'esperto: gli proibiamo esplicitamente di essere equilibrato. Questo è controintuitivo, ma è il punto centrale. Se ogni esperto cerca di tenere conto di tutti i lati, ottieni cinque opinioni caute identiche. Forzando ciascuno a spingere la sua angolazione al limite, ottieni uno spettro reale, che l'unione poi riconcilia.
Passaggio 4: L'Unione Riconcilia le Conclusioni
Ora abbiamo diverse opinioni nette e unilaterali. L'unione le raccoglie in un unico verdetto, ma non mediandole. Cerca dove gli esperti sono d'accordo (un forte segnale), dove si contraddicono (una zona di rischio che richiede una decisione) e cosa prevale su cosa.
1MERGE_SYSTEM = """Sei il sintetizzatore di uno sciame analitico. Ti vengono2date le opinioni di diversi esperti con pregiudizi diversi su una decisione.34Il tuo compito NON è di mediarle. Il tuo compito è:51. Accordo: su cosa gli esperti hanno concordato nonostante le diverse6 posizioni. Questo è il segnale più affidabile, evidenzialo.72. Conflitto: dove gli esperti si contraddicono direttamente. Non8 appianarlo, nomina il conflitto esplicitamente e di cosa costa ogni lato.93. Punti ciechi: un rischio nominato da un solo esperto, ma che conta.104. Verdetto finale su tutto: a favore / contro / condizionale, e a quali11 condizioni cambia.1213Scrivi densamente. Mantieni il disaccordo come informazione, non nasconderlo."""1415def merge_opinions(task, opinions):16 block = "\n\n".join(17 f"### Expert: {o['role']}\n{o['opinion']}" for o in opinions18 )19 user = f"Decision:\n{task}\n\nExpert opinions:\n{block}"20 return ask(MERGE_SYSTEM, user, temperature=0.4) # temperatura più bassa per sintesi sobria
Abbassiamo la temperatura nell'unione: se gli esperti devono essere diversificati (T alta), il sintetizzatore deve essere sobrio e coerente (T bassa). L'istruzione chiave qui è "non mediare, mantieni il disaccordo come informazione." Un'unione normale collassa tutto in poltiglia, "da un lato, dall'altro lato." Una buona unione dice chiaramente: qui tutti sono d'accordo, e qui c'è un conflitto e costa questo.
Passaggio 4.5: Un Avvocato del Diavolo Contro i Falsi Accordi
C'è un pericolo silenzioso: a volte gli esperti concordano non perché la decisione sia buona, ma perché tutti guardano nella stessa direzione per inerzia. Questo è un falso accordo, ed è più pericoloso di un conflitto aperto, perché sembra fiducia.
Contro questo aggiungiamo un agente speciale, l'avvocato del diavolo. Il suo unico compito è attaccare il consenso. Vede tutte le opinioni degli esperti ed è obbligato a trovare perché potrebbero essere tutti sbagliati contemporaneamente. Se lo sciame ha votato all'unanimità "a favore," l'avvocato cerca uno scenario in cui è una catastrofe.
1DEVIL_SYSTEM = """Sei l'avvocato del diavolo in uno sciame analitico. Ti2vengono date le opinioni degli esperti. Il tuo unico compito: attaccare il3loro accordo.45Se gli esperti hanno converguto su qualcosa, trova perché potrebbero essere6TUTTI SBAGLIATI CONTEMPORANEAMENTE. Cerca un punto cieco condiviso:7un'ipotesi che tutti hanno accettato senza verificare, uno scenario a cui8nessuno ha pensato perché scomodo.910Non essere educato. Il tuo valore è che dici ciò che il gruppo non vuole11sentire. Dai:12- quale ipotesi condivisa degli esperti è la più pericolosa13- uno scenario in cui l'opinione unanime dello sciame si rivela fatalmente14 sbagliata15- una domanda che il gruppo ha accuratamente evitato16Se non c'è accordo e gli esperti sono veramente in disaccordo, dillo17chiaramente e indica il conflitto irrisolto più acuto."""1819def run_devil(task, opinions):20 block = "\n\n".join(21 f"### {o['role']}\n{o['opinion']}" for o in opinions22 )23 user = f"Decision:\n{task}\n\nSwarm opinions:\n{block}"24 return ask(DEVIL_SYSTEM, user, temperature=0.8)
L'avvocato lavora dopo gli esperti ma prima dell'unione, e il suo attacco va nella sintesi insieme alle opinioni. Il punto è che anche uno sciame unanime ottiene almeno un agente obbligato a cercare una crepa. Questo è economico (una chiamata) e rompe strutturalmente il pensiero di gruppo: il consenso ora deve sopravvivere a un attacco, non solo accadere.
Passaggio 4.6: Un Turno di Dibattito per Affinare il Conflitto
Il primo passaggio degli esperti è indipendente, e questo è giusto per la diversità. Ma dopo che le opinioni sono state raccolte, puoi fare un turno di dibattito: mostra a ogni esperto un riepilogo delle opinioni degli altri e lascia che obietti. Questo affina i conflitti, gli argomenti deboli cadono, quelli forti si consolidano.
1DEBATE_SYSTEM = """Sei l'esperto {name} nel secondo round di analisi.2La tua posizione originale:3{own_opinion}45Ora vedi le opinioni degli altri esperti. Non cedere sotto pressione, ma6non ignorare nemmeno gli argomenti forti. Dai:7- dove un argomento di un altro colpisce genuinamente la tua posizione,8 ammettilo onestamente9- dove mantieni la tua linea e perché la loro obiezione è debole10- se hai cambiato il tuo verdetto dopo il dibattito, e se sì, come11Corto. Questo non è una ripetizione della prima opinione, ma una reazione12agli avversari."""1314def debate_round(roles, task, opinions):15 others_map = {}16 for o in opinions:17 others = "\n\n".join(18 f"### {x['role']}\n{x['opinion']}" for x in opinions if x is not o19 )20 others_map[o["role"]] = others2122 def rebut(o):23 system = DEBATE_SYSTEM.format(name=o["role"], own_opinion=o["opinion"])24 user = (f"Decision:\n{task}\n\n"25 f"Opponents' opinions:\n{others_map[o['role']]}")26 return {"role": o["role"], "opinion": ask(system, user, temperature=0.6)}2728 with ThreadPoolExecutor(max_workers=len(opinions)) as pool:29 return list(pool.map(rebut, opinions))
Anche il turno di dibattito è parallelo: ogni esperto reagisce a tutti gli altri contemporaneamente, ancora una volta senza conformismo in tempo reale. Dopo il dibattito, le opinioni sono di solito più nette: puoi vedere quali posizioni hanno retto sotto il fuoco e quali sono crollate. Sono queste opinioni temprate che entrano nell'unione finale.
Passaggio 5: Mettere Tutto Insieme
1def analyze(task, debate=True):2 print("Orchestrator is picking roles...")3 roles = plan_roles(task)4 for r in roles:5 print(f" - {r['name']}: {r['focus']}")67 print(f"\nLaunching {len(roles)} experts in parallel...")8 opinions = run_swarm(roles, task)9 for o in opinions:10 print(f"\n[{o['role']}]\n{o['opinion']}")1112 # turno di dibattito opzionale: gli esperti reagiscono tra loro13 if debate:14 print("\nDebate round, experts rebut each other...")15 opinions = debate_round(roles, task, opinions)1617 # l'avvocato del diavolo attacca l'accordo dello sciame18 print("\nDevil's advocate looks for a crack in the agreement...")19 devil = run_devil(task, opinions)20 print(f"\n[Devil's advocate]\n{devil}")2122 # l'unione riconcilia le conclusioni più l'attacco dell'avvocato23 print("\nMerge is reconciling the conclusions...")24 opinions_plus = opinions + [{"role": "Devil's advocate", "opinion": devil}]25 verdict = merge_opinions(task, opinions_plus)26 print(f"\n=== FINAL VERDICT ===\n{verdict}")27 return verdict2829if __name__ == "__main__":30 analyze(31 "We want to remove the free tier and make the product fully paid "32 "with a 14-day trial. Should we do it?"33 )
Eseguendo questo, vedrai l'intera pipeline: l'orchestratore sceglie i ruoli, gli esperti tagliano la verità dalle loro angolazioni, discutono tra loro nel turno di dibattito, l'avvocato attacca il loro accordo e l'unione fornisce un verdetto su tutto, incluso l'attacco. Un singolo agente sulla stessa domanda darebbe un vago "dipende dal tuo pubblico," lo sciame fornisce una ripartizione strutturata in cui i conflitti sono espliciti e il consenso è stress-testato.
Cosa Rende Funzionante Questo Sciame
Tre cose separano uno sciame utile da un teatro fatto di agenti.
I ruoli devono confliggere, non complementarsi. Se i tuoi esperti sono "un marketer, un specialista SMM, un content manager," daranno risposte quasi identiche, perché i loro interessi coincidono. Il vero valore è quando gli interessi confliggono: crescita vs sostenibilità, velocità vs qualità, soldi ora vs fiducia dopo. Un conflitto di interessi è ciò che spacca la decisione.
Gli esperti non devono vedersi tra loro. Non appena un esperto vede l'opinione di un altro, inizia il conformismo, si adegua. L'indipendenza non è un dettaglio implementativo, è una condizione di lavoro. Il lancio parallelo la dà gratuitamente.
L'unione non media, preserva il conflitto. Una sintesi errata trasforma cinque opinioni nette in un riassunto senza denti. Una buona sintesi lascia il conflitto visibile, perché il conflitto è l'informazione più preziosa: mostra dove la decisione è genuinamente rischiosa, non dove tutti annuiscono.
Dove Estendere
Questa struttura si estende in direzioni ovvie. Puoi aggiungere un turno di dibattito: dopo la prima unione, mostra agli esperti il riepilogo e lascia che obiettino, il che affina i conflitti. Puoi mettere un giudice su un modello più forte degli esperti per soppesare gli argomenti. Puoi rendere i ruoli permanenti per un tipo ricorrente di decisione, così non li generi ogni volta.
Ma il principio di base rimane: lenti diverse, analisi indipendente, una sintesi che rispetta il disaccordo. Uno sciame è utile per l'analisi non perché ci siano molti agenti, ma perché guardano in modo diverso e non si lasciano scivolare in un denominatore comune. Prendi una decisione che stai rivoltando nella testa da solo in questo momento, e falla passare attraverso un tale sciame. Vedrai angolazioni che non avevi considerato.





