Pas de vitesse. Il s'agit de faire en sorte que plusieurs agents avec des points de vue différents débattent d'une seule décision et parviennent à une conclusion meilleure que n'importe lequel d'entre eux seul. Avec le code complet pour l'orchestrateur, les experts et la fusion.
Lorsque vous demandez à un seul modèle d'évaluer une décision, il donne un seul point de vue, généralement moyen et prudent. Il a tendance à être d'accord, à lisser, à trouver un équilibre. C'est le problème : une décision importante ne peut pas être évaluée par un seul point de vue moyen, elle doit être attaquée de différents côtés.
Un essaim d'agents résout cela structurellement. Vous créez plusieurs experts, chacun avec un rôle et un biais bien définis : l'un ne pense qu'à l'argent, un autre qu'au risque technique, un troisième qu'à l'utilisateur. Ils analysent une décision indépendamment, arrivent à des conclusions différentes, puis vous forcez une réconciliation de ces conclusions. La valeur ici n'est pas la vitesse, mais le fait que le désaccord soit intégré dans la structure. Un seul agent tend vers une pensée de groupe avec lui-même, un essaim de rôles ne le fait pas.
Cet article montre comment construire un tel essaim, avec du code. Nous couvrons trois parties : l'orchestrateur qui attribue les rôles, les experts qui analysent indépendamment, et la fusion qui les réconcilie en une seule conclusion.
Architecture : Orchestrateur, Experts, Fusion
Un essaim pour l'analyse comporte trois composants.
L'orchestrateur prend la tâche et décide quels rôles d'experts sont nécessaires. Pour évaluer un lancement de produit, cela pourrait être un investisseur, un ingénieur, un spécialiste produit, un responsable sécurité. L'orchestrateur n'analyse pas lui-même, il distribue les rôles.
Les experts travaillent en parallèle et indépendamment. Chacun voit la même décision mais à travers sa propre lentille. Crucialement, ils ne voient pas les conclusions des autres, sinon la conformité s'installe. L'indépendance est ce qui produit des points de vue différents.
La fusion collecte les conclusions des experts et les réconcilie : là où ils sont d'accord, là où ils se contredisent, quel est le verdict final sous tous les angles. Ce n'est pas une moyenne mais une synthèse qui conserve le désaccord comme signal.

Étape 1 : Le Client de Base
Commencez par un client simple vers le modèle. J'utilise un format de message compatible OpenAI, cela fonctionne avec la plupart des fournisseurs et avec Ollama en local.
1import requests2import json3from concurrent.futures import ThreadPoolExecutor45API = "http://localhost:11434/api/chat" # Ollama, or a provider endpoint6MODEL = "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"]
Étape 2 : L'Orchestrateur Attribue les Rôles
L'orchestrateur reçoit la tâche et décide quels experts sont nécessaires. Ne codez pas les rôles en dur à l'avance, laissez le modèle les choisir pour la tâche spécifique, cela rend l'essaim général. Demandez du JSON strict à analyser.
1ORCHESTRATOR_SYSTEM = """You are the orchestrator of an analytical swarm.2For the task, define 3-5 expert roles that will give maximally DIFFERENT3and conflicting views on the decision. The roles must conflict in their4interests, not complement each other.56For each role give: name, focus (what it fixates on), bias (what it is7biased toward, what it tends to overrate).89Reply ONLY with a JSON array, no explanations:10[{"name": "...", "focus": "...", "bias": "..."}, ...]11"""1213def plan_roles(task):14 raw = ask(ORCHESTRATOR_SYSTEM, f"Task to analyze:\n{task}",15 temperature=0.9) # higher temperature for role diversity16 # cut out the JSON in case the model added text around it17 start, end = raw.find("["), raw.rfind("]") + 118 return json.loads(raw[start:end])
Nous gardons la température élevée ici délibérément : nous voulons des rôles diversifiés, pas évidents. L'exigence "les rôles doivent être en conflit" dans le prompt est la clé, sans elle le modèle donne trois rôles presque identiques et tout l'intérêt de l'essaim est perdu.
Étape 3 : Les Experts Analysent en Parallèle et Indépendamment
Chaque expert reçoit son rôle et la même décision. Crucialement : ils fonctionnent en parallèle et ne voient pas les conclusions des autres. Le parallélisme ici n'est pas seulement pour la vitesse, il garantit l'indépendance, un expert ne peut physiquement pas s'adapter à l'opinion d'un autre.
1EXPERT_SYSTEM = """You are an expert with the role: {name}.2Your focus: {focus}.3Your bias: {bias}. Do not fight it, it is your value to the analysis.45Analyze the decision STRICTLY from your position. Do not be balanced,6do not try to account for other viewpoints, other experts will do that.7Your job is to push your angle to the limit.89Give:10- a verdict from your position (for / against / conditional)11- 2-3 main arguments from your angle specifically12- 1 risk that is most visible from your position and others will miss13Short and hard, no fluff."""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 # parallel launch: independence plus speed22 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]
Notez le prompt de l'expert : nous lui interdisons explicitement d'être équilibré. C'est contre-intuitif, mais c'est tout l'intérêt. Si chaque expert essaie de prendre en compte tous les côtés, vous obtenez cinq avis prudents identiques. En forçant chacun à pousser son angle à la limite, vous obtenez un véritable spectre, que la fusion réconcilie ensuite.
Étape 4 : La Fusion Réconcilie les Conclusions
Nous avons maintenant plusieurs opinions tranchées et unilatérales. La fusion les rassemble en un seul verdict, mais pas par moyenne. Elle cherche là où les experts sont d'accord (un signal fort), là où ils se contredisent (une zone de risque nécessitant une décision), et ce qui l'emporte sur quoi.
1MERGE_SYSTEM = """You are the synthesizer of an analytical swarm. You are2given the opinions of several experts with different biases on one decision.34Your job is NOT to average them. Your job is:51. Agreement: what the experts agreed on despite different positions.6 This is the most reliable signal, highlight it.72. Conflict: where the experts directly contradict. Do not smooth it over,8 name the conflict explicitly and say what each side costs.93. Blind spots: a risk only one expert named, but it matters.104. Final verdict across everything: for / against / conditional, and under11 what conditions it changes.1213Write densely. Keep disagreement as information, do not hide it."""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) # lower temperature for sober synthesis
Nous abaissons la température lors de la fusion : si les experts doivent être diversifiés (température élevée), le synthétiseur doit être sobre et cohérent (température basse). L'instruction clé ici est "ne faites pas de moyenne, gardez le désaccord comme information." Une fusion normale réduit tout en bouillie, "d'un côté, de l'autre côté." Une bonne fusion dit clairement : voici ce sur quoi tout le monde est d'accord, et voici un conflit, et il coûte ceci.
Étape 4.5 : Un Avocat du Diable Contre le Faux Accord
Il y a un danger silencieux : parfois les experts sont d'accord non pas parce que la décision est bonne, mais parce que tout le monde regarde dans la même direction par inertie. C'est un faux accord, et c'est plus dangereux qu'un conflit ouvert, car cela ressemble à de la confiance.
Contre cela, nous ajoutons un agent spécial, l'avocat du diable. Son seul travail est d'attaquer le consensus. Il voit toutes les opinions des experts et est obligé de trouver pourquoi elles pourraient toutes être fausses en même temps. Si l'essaim a voté à l'unanimité "pour", l'avocat cherche un scénario où c'est une catastrophe.
1DEVIL_SYSTEM = """You are the devil's advocate in an analytical swarm. You2are given the experts' opinions. Your only job: attack their agreement.34If the experts converged on something, find why they might ALL be wrong AT5ONCE. Look for a shared blind spot: an assumption everyone accepted without6checking, a scenario no one considered because it is inconvenient.78Do not be polite. Your value is that you say what the group does not want9to hear. Give:10- which shared assumption of the experts is the most dangerous11- a scenario in which the swarm's unanimous opinion turns out fatally wrong12- one question the group carefully avoided13If there is no agreement and the experts genuinely disagree, say so plainly14and point to the sharpest unresolved conflict."""1516def run_devil(task, opinions):17 block = "\n\n".join(18 f"### {o['role']}\n{o['opinion']}" for o in opinions19 )20 user = f"Decision:\n{task}\n\nSwarm opinions:\n{block}"21 return ask(DEVIL_SYSTEM, user, temperature=0.8)
L'avocat tourne après les experts mais avant la fusion, et son attaque est intégrée à la synthèse avec les opinions. L'idée est que même un essaim unanime ait au moins un agent obligé de chercher une faille. C'est peu coûteux (un appel) et cela brise structurellement la pensée de groupe : le consensus doit maintenant survivre à une attaque, pas seulement se produire.
Étape 4.6 : Un Tour de Débat pour Affiner le Conflit
Le premier passage des experts est indépendant, et c'est bien pour la diversité. Mais après avoir collecté les opinions, vous pouvez donner un tour de débat : montrer à chaque expert un résumé des opinions des autres et le laisser objecter. Cela affine les conflits, les arguments faibles tombent, les forts se renforcent.
1DEBATE_SYSTEM = """You are expert {name} in the second round of analysis.2Your original position:3{own_opinion}45Now you see the other experts' opinions. Do not cave under pressure, but6do not ignore strong arguments either. Give:7- where another's argument genuinely hits your position, admit it honestly8- where you hold your line and why their objection is weak9- whether you changed your verdict after the debate, and if so, how10Short. This is not a repeat of the first opinion, but a reaction to opponents."""1112def debate_round(roles, task, opinions):13 others_map = {}14 for o in opinions:15 others = "\n\n".join(16 f"### {x['role']}\n{x['opinion']}" for x in opinions if x is not o17 )18 others_map[o["role"]] = others1920 def rebut(o):21 system = DEBATE_SYSTEM.format(name=o["role"], own_opinion=o["opinion"])22 user = (f"Decision:\n{task}\n\n"23 f"Opponents' opinions:\n{others_map[o['role']]}")24 return {"role": o["role"], "opinion": ask(system, user, temperature=0.6)}2526 with ThreadPoolExecutor(max_workers=len(opinions)) as pool:27 return list(pool.map(rebut, opinions))
Le tour de débat est également parallèle : chaque expert réagit à tous les autres à la fois, encore une fois sans conformité en temps réel. Après le débat, les opinions sont généralement plus tranchées : vous pouvez voir quelles positions ont tenu sous le feu et lesquelles se sont effondrées. Ce sont ces opinions durcies qui entrent dans la fusion finale.
Étape 5 : Tout Rassembler
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 # optional debate round: experts react to each other13 if debate:14 print("\nDebate round, experts rebut each other...")15 opinions = debate_round(roles, task, opinions)1617 # devil's advocate attacks the swarm's agreement18 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 # merge reconciles the conclusions plus the advocate's attack23 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 )
En exécutant cela, vous verrez le pipeline complet : l'orchestrateur choisit les rôles, les experts découpent la vérité selon leurs angles, débattent entre eux lors du tour de débat, l'avocat attaque leur accord, et la fusion livre un verdict sur l'ensemble, y compris l'attaque. Un seul agent sur cette même question donnerait un vague "ça dépend de votre public", l'essaim donne une décomposition structurée où les conflits sont explicites et le consensus est testé sous stress.
Ce Qui Rend Cet Essaim Efficace
Trois choses distinguent un essaim utile d'un théâtre d'agents.
Les rôles doivent être en conflit, pas complémentaires. Si vos experts sont "un marketeur, un spécialiste SMM, un gestionnaire de contenu", ils donneront des réponses presque identiques, car leurs intérêts coïncident. La vraie valeur apparaît lorsque les intérêts sont en conflit : croissance vs durabilité, vitesse vs qualité, argent maintenant vs confiance plus tard. Un conflit d'intérêts est ce qui ouvre la décision.
Les experts ne doivent pas se voir. Dès qu'un expert voit l'opinion d'un autre, la conformité commence, il s'adapte. L'indépendance n'est pas un détail d'implémentation, c'est une condition de fonctionnement. Le lancement parallèle la donne gratuitement.
La fusion ne fait pas la moyenne, elle préserve le conflit. Une mauvaise synthèse transforme cinq opinions tranchées en un résumé sans dent. Une bonne synthèse laisse le conflit visible, car le conflit est l'information la plus précieuse : il montre où la décision est réellement risquée, pas là où tout le monde acquiesce.
Où Étendre
Ce squelette s'étend dans des directions évidentes. Vous pouvez ajouter un tour de débat : après la première fusion, montrez le résumé aux experts et laissez-les objecter, ce qui affine les conflits. Vous pouvez placer un juge sur un modèle plus fort que les experts pour peser les arguments. Vous pouvez rendre les rôles permanents pour un type de décision récurrent, afin de ne pas les générer à chaque fois.
Mais le principe de base reste : des lentilles différentes, une analyse indépendante, une synthèse qui respecte le désaccord. Un essaim est utile pour l'analyse non pas parce qu'il y a beaucoup d'agents, mais parce qu'ils regardent différemment et ne se laissent pas glisser vers un dénominateur commun. Prenez une décision que vous retournez dans votre tête seul en ce moment, et passez-la dans un tel essaim. Vous verrez des angles que vous ne teniez pas.





