Développer des systèmes multi-agents : quand et comment les utiliser
Alors que les systèmes mono-agent traitent efficacement la plupart des flux de travail d'entreprise, les architectures multi-agents peuvent générer une valeur supplémentaire pour votre organisation. Découvrez quand et comment les utiliser.
Qu'est-ce qu'un système multi-agents ?
Un système multi-agents est une architecture dans laquelle plusieurs instances LLM s'exécutent avec des contextes de conversation distincts, coordonnés par le code. Chaque agent gère une portion distincte d'une tâche — un sous-agent effectue des recherches tandis qu'un orchestrateur planifie, par exemple — ce qui protège le contexte, permet un travail parallèle et autorise une spécialisation qu'un seul agent ne peut pas assumer.
Il existe plusieurs modèles de coordination (essaims d'agents, systèmes basés sur les capacités et architectures de bus de messages), mais cet article se concentre sur le modèle orchestrateur-sous-agent : un modèle hiérarchique dans lequel un agent principal génère et gère des sous-agents spécialisés pour des sous-tâches spécifiques. Ce modèle offre un modèle de coordination simple et constitue un bon point de départ pour les équipes qui débutent dans les systèmes multi-agents. Nous explorerons d'autres schémas en détail dans notre prochain article.
Aujourd'hui, les systèmes multi-agents sont souvent utilisés dans les situations où un seul agent serait plus performant, même si cette analyse continue d'évoluer à mesure que les modèles s'améliorent. Chez Anthropic, nous avons vu des équipes investir des mois dans la création d'architectures multi-agents élaborées, pour découvrir qu'une amélioration des requêtes d'un seul agent permettait d'obtenir des résultats équivalents.
Après avoir créé des systèmes multi-agents et travaillé avec des équipes qui les déploient en production, nous avons identifié trois situations dans lesquelles plusieurs agents surpassent systématiquement un seul agent : lorsque la pollution du contexte dégrade les performances, lorsque les tâches peuvent être exécutées en parallèle et lorsque la spécialisation améliore la sélection des outils ou la concentration sur les tâches. En dehors de ces situations, les coûts de coordination dépassent généralement les avantages.
Dans cet article, nous expliquons comment reconnaître les limites d'un agent unique, identifier les trois scénarios dans lesquels les systèmes multi-agents excellent et éviter les erreurs de mise en œuvre courantes.
Les arguments en faveur du démarrage avec un seul agent
Un seul agent bien conçu et doté d'outils adéquats peut accomplir bien plus que ce à quoi s'attendent de nombreux développeurs.
Les systèmes multi-agents introduisent un surcoût. Chaque agent supplémentaire représente un autre point d'échec potentiel, un autre ensemble de requêtes dont assurer la maintenance et une autre source de comportement inattendu.
Nous avons constaté que certaines équipes mettaient en place des systèmes multi-agents complexes, avec des agents distincts chargés de la planification, de l'exécution, de la révision et de l'itération, pour découvrir qu'elles perdaient le contexte à chaque transfert et qu'elles consacraient plus de jetons à coordonner qu'à exécuter. Lors de nos tests, les implémentations multi-agents utilisent généralement 3 à 10 fois plus de jetons que les approches mono-agent pour les tâches équivalentes. Cette surcharge résulte de la duplication du contexte entre les agents, des messages de coordination entre eux et de la synthèse des résultats pour les transferts.
Un cadre de décision pour les systèmes multi-agents
Les architectures multi-agents apportent une valeur ajoutée lorsqu'elles permettent de surmonter des contraintes spécifiques qu'un seul agent ne peut pas résoudre. Cela signifie que les architectures multi-agents doivent être réservées aux cas où elles offrent des avantages évidents qui justifient le surcoût. L'infrastructure gérée peut également effectuer cela pour vous (voir orchestration multi-agents dans Agents gérés de Claude).
Les modèles ci-dessous représentent les cas où nous observons systématiquement des rendements positifs sur cet investissement.
Protection du contexte
Les grands modèles de langage ont des fenêtres de contexte finies, et la qualité de la réponse peut se dégrader à mesure que le contexte augmente. Lorsque le contexte d'un agent accumule des informations à partir d'une sous-tâche qui n'est pas pertinente pour les sous-tâches suivantes, il y a pollution du contexte. Les sous-agents assurent l'isolation, chacun opérant dans son propre contexte isolé, concentré sur sa tâche spécifique.
Prenons l'exemple d'un agent du support client qui doit récupérer l'historique des commandes tout en diagnostiquant des problèmes techniques. Si chaque recherche de commande ajoute des milliers de jetons au contexte, la capacité de l'agent à raisonner sur le problème technique se dégrade.
L'approche mono-agent :
# Single agent accumulates everything in context
conversation_history = [
{"role": "user", "content": "My order #12345 isn't working"},
{"role": "assistant", "content": "Let me check your order..."},
# Tool result adds 2000+ tokens of order history
{"role": "user", "content": "... (order details, past purchases, shipping info) ..."},
{"role": "assistant", "content": "Now let me diagnose the technical issue..."},
# Context is now polluted with order details the agent doesn't need
]L'agent doit raisonner sur le problème technique tout en conservant plus de 2 000 jetons d'historique de commandes non pertinents dans le contexte, ce qui détourne l'attention et réduit la qualité de la réponse.
L'approche multi-agents :
from anthropic import Anthropic
client = Anthropic()
class OrderLookupAgent:
def lookup_order(self, order_id: str) -> dict:
# Separate agent with its own context
messages = [
{"role": "user", "content": f"Get essential details for order {order_id}"}
]
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=messages,
tools=[get_order_details_tool]
)
# Returns only essential information
return extract_summary(response)
class SupportAgent:
def handle_issue(self, user_message: str):
if needs_order_info(user_message):
order_id = extract_order_id(user_message)
# Get only what's needed, not full history
order_summary = OrderLookupAgent().lookup_order(order_id)
# Inject compact summary, not full context
context = f"Order {order_id}: {order_summary['status']}, purchased {order_summary['date']}"
# Main agent context stays clean
messages = [
{"role": "user", "content": f"{context}\n\nUser issue: {user_message}"}
]
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=messages
)
return responseL'agent de recherche de commandes traite l'historique complet des commandes et en extrait un résumé. L'agent principal ne reçoit que les 50 à 100 jetons dont il a réellement besoin, ce qui permet de garder le contexte ciblé.
L'isolation du contexte est la plus efficace lorsque les sous-tâches génèrent un volume de contexte élevé (plus de 1 000 jetons), mais que la plupart de ces informations ne sont pas pertinentes pour la tâche principale, lorsque la sous-tâche est bien définie avec des critères clairs quant aux informations à extraire, et pour les opérations de recherche ou de récupération qui nécessitent un filtrage avant utilisation.
Parallélisation
L'exécution de plusieurs agents en parallèle vous permet d'explorer un espace de recherche plus vaste qu'un seul agent ne peut couvrir. Ce modèle s'est révélé particulièrement utile pour les tâches de recherche documentaire et de recherche.
L'équipe de recherche d'Anthropic l'a documenté dans comment nous avons construit notre système de recherche multi-agents. Un agent principal analyse une requête et génère plusieurs sous-agents pour étudier différentes facettes en parallèle. Chaque sous-agent effectue indépendamment des recherches, puis renvoie des résultats distillés. La recherche multi-agents a montré des améliorations substantielles de précision par rapport aux approches mono-agent, en permettant l'exploration dans des espaces d'information plus vastes.
L'implémentation de base décompose une question en facettes indépendantes, exécute des sous-agents de manière concurrente, puis synthétise les résultats.
import asyncio
from anthropic import AsyncAnthropic
client = AsyncAnthropic()
async def research_topic(query: str) -> dict:
# Lead agent breaks query into research facets
facets = await lead_agent.decompose_query(query)
# Spawn subagents to research each facet in parallel
tasks = [
research_subagent(facet)
for facet in facets
]
results = await asyncio.gather(*tasks)
# Lead agent synthesizes findings
return await lead_agent.synthesize(results)
async def research_subagent(facet: str) -> dict:
"""Each subagent has its own context window"""
messages = [
{"role": "user", "content": f"Research: {facet}"}
]
response = await client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
messages=messages,
tools=[web_search, read_document]
)
return extract_findings(response)Cette couverture améliorée a un coût. Les systèmes multi-agents consomment généralement 3 à 10 fois plus de jetons que les approches mono-agent pour des tâches équivalentes. En effet, chaque agent a besoin de son propre contexte, les agents doivent échanger des messages pour se coordonner et les résultats doivent être résumés lorsqu'ils sont transmis d'un agent à l'autre. Alors que le parallélisme contribue à réduire le temps total d'exécution par rapport à l'exécution séquentielle de tout le travail, les systèmes multi-agents prennent souvent plus de temps que les systèmes mono-agent, en raison de l'augmentation considérable du volume total de calculs.
Le principal avantage de la parallélisation est l'exhaustivité, et non la vitesse. Lorsque vous devez effectuer des recherches dans un espace d'informations important ou étudier une question complexe sous de nombreux angles, les agents parallèles peuvent couvrir plus de terrain qu'un agent unique travaillant dans les limites de son contexte. Le compromis est une utilisation plus élevée de jetons et souvent un temps d'exécution total plus long en échange de résultats plus complets.
Spécialisation
Différentes tâches nécessitent parfois des ensembles d'outils, des requêtes système ou des domaines d'expertise différents. Plutôt que de fournir un seul agent avec un accès à des dizaines d'outils, les agents spécialisés avec des ensembles d'outils ciblés adaptés à leurs responsabilités peuvent améliorer la fiabilité.
Spécialisation dans les ensembles d'outils
Lorsqu'un agent a accès à un trop grand nombre d'outils, les performances s'en ressentent. Trois signaux indiquent qu'une spécialisation dans les outils serait utile :
- Quantité. Un agent disposant d'un trop grand nombre d'outils (souvent plus de 20) a du mal à choisir celui qui lui convient.
- Confusion dans le domaine. Lorsque les outils couvrent plusieurs domaines non liés (opérations de base de données, appels d'API, opérations sur le système de fichiers), l'agent ne sait pas quel domaine s'applique à une tâche donnée.
- Performances dégradées. L'ajout de nouveaux outils dégrade les performances des tâches existantes, ce qui suggère que l'agent a atteint sa capacité de gestion des outils.
Spécialisation des requêtes système
Différentes tâches nécessitent parfois des personas, des contraintes ou des instructions différentes qui sont en conflit lorsqu'elles sont combinées. Un agent d'assistance client doit faire preuve d'empathie et de patience ; un agent de revue de code doit être précis et critique. Un agent chargé de vérifier la conformité doit suivre des règles rigides ; un agent de brainstorming a besoin de flexibilité créative. Lorsqu'un seul agent doit passer d'un mode de comportement conflictuel à un autre, la séparation en agents spécialisés avec des requêtes système personnalisées produit des résultats plus cohérents.
La performance de chaque agent spécialisé dépend de ses instructions : les mêmes bonnes pratiques d'ingénierie de requêtes qui améliorent les résultats d'un seul agent s'appliquent à la requête système de chaque sous-agent.
Spécialisation dans l'expertise de domaine
Certaines tâches nécessitent un contexte de domaine approfondi qui submergerait un agent généraliste. Un agent d'analyse juridique peut avoir besoin d'un contexte étendu sur la jurisprudence et les cadres réglementaires. Un agent de recherche médicale peut avoir besoin de connaissances spécialisées en méthodologie d'essais cliniques. Plutôt que de charger tout le contexte du domaine dans un seul agent, les agents spécialisés peuvent apporter une expertise ciblée en rapport avec leurs responsabilités spécifiques.
Exemple : intégration multiplateforme. Considérez un système d'intégration où les agents doivent travailler sur les plateformes de CRM, d'automatisation marketing et de messagerie. Chaque plateforme dispose de 10 à 15 points de terminaison d'API pertinents. Un seul agent disposant de plus de 40 outils a souvent du mal à sélectionner correctement, confondant des opérations similaires entre les plateformes. La division en agents spécialisés avec des ensembles d'outils ciblés et des requêtes personnalisées résout les erreurs de sélection.
from anthropic import Anthropic
client = Anthropic()
# Specialized agents with focused toolsets and tailored prompts
class CRMAgent:
"""Handles customer relationship management operations"""
system_prompt = """You are a CRM specialist. You manage contacts,
opportunities, and account records. Always verify record ownership
before updates and maintain data integrity across related records."""
tools = [
crm_get_contacts,
crm_create_opportunity,
# 8-10 CRM-specific tools
]
class MarketingAgent:
"""Handles marketing automation operations"""
system_prompt = """You are a marketing automation specialist. You
manage campaigns, lead scoring, and email sequences. Prioritize
data hygiene and respect contact preferences."""
tools = [
marketing_get_campaigns,
marketing_create_lead,
# 8-10 marketing-specific tools
]
class OrchestratorAgent:
"""Routes requests to specialized agents"""
def execute(self, user_request: str):
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system="""You coordinate platform integrations. Route requests to the appropriate specialist:
- CRM: Contact records, opportunities, accounts, sales pipeline
- Marketing: Campaigns, lead nurturing, email sequences, scoring
- Messaging: Notifications, alerts, team communication""",
messages=[
{"role": "user", "content": user_request}
],
tools=[delegate_to_crm, delegate_to_marketing, delegate_to_messaging]
)
return responseCe modèle reflète une collaboration professionnelle efficace, dans laquelle des spécialistes disposant d'outils adaptés à leurs rôles collaborent plus efficacement que les généralistes qui tentent de maintenir leur expertise dans tous les domaines. Cependant, la spécialisation rend le routage plus complexe. L'orchestrateur doit correctement classer les demandes et déléguer au bon agent, et un mauvais routage entraîne de piètres résultats. Le maintien de plusieurs agents spécialisés augmente également les coûts de maintenance des requêtes. La spécialisation fonctionne mieux lorsque les domaines sont clairement séparables et que les décisions de routage sont sans ambiguïté.
Dépasser les architectures mono-agent
Au-delà du cadre général, certains signaux concrets suggèrent que les modèles mono-agent ont fait leur temps :
Atteindre les limites du contexte.Si un agent utilise régulièrement de grandes quantités de contexte et que les performances se dégradent, la pression liée au contexte pourrait être un facteur limitant. Notez que les progrès récents dans la gestion du contexte (comme le compactage) réduisent cette limitation, ce qui permet à des agents individuels de conserver une mémoire efficace sur des horizons beaucoup plus longs.
Gérer de nombreux outils. Lorsqu'un agent dispose de 15 à 20 outils ou plus, le modèle consacre beaucoup de contexte et d'attention à comprendre ses options. Avant d'adopter une architecture multi-agents, envisagez d'utiliser l'Outil de recherche d'outils, qui permet à Claude de découvrir dynamiquement des outils à la demande plutôt que de charger toutes les définitions dès le départ. Cela peut réduire l'utilisation de jetons jusqu'à 85 % tout en améliorant la précision de la sélection des outils.
Sous-tâches parallélisables. Lorsque les tâches se décomposent naturellement en parties indépendantes (recherche sur plusieurs sources, tests pour plusieurs composants), des sous-agents parallèles peuvent permettre des gains de vitesse considérables.
Ces seuils changeront à mesure que les modèles s'amélioreront. Les limites actuelles représentent des directives pratiques, et non des contraintes fondamentales.
Décomposition centrée sur le contexte
Lorsque vous adoptez une architecture multi-agents, la décision de conception la plus importante est de savoir comment répartir le travail entre les agents. Nous avons observé que les équipes font souvent ce choix de manière incorrecte, ce qui entraîne une surcharge de coordination qui annule les avantages d'une conception multi-agents.
L'idée clé est d'adopter une approche centrée sur le contexte plutôt que sur le problème lors de la décomposition du travail.
Décomposition centrée sur le problème (souvent contre-productive). Diviser par type de travail (un agent écrit des fonctionnalités, un autre écrit des tests, un troisième examine le code) crée une surcharge de coordination constante. Chaque transfert perd son contexte. L'agent chargé de la rédaction de tests ignore pourquoi certaines décisions de mise en œuvre ont été prises, et le réviseur de code ne dispose pas du contexte d'exploration et d'itération.
Décomposition centrée sur le contexte (généralement efficace). Diviser par limites de contexte signifie qu'un agent gérant une fonctionnalité doit également prendre en charge ses tests, car il possède déjà le contexte nécessaire. Le travail ne doit être divisé que lorsque le contexte peut vraiment être isolé.
Ce principe découle de l'observation des modes de défaillance dans les systèmes multi-agents. Lorsque les agents sont répartis par type de problème, ils se livrent à un jeu du « téléphone sans fil », se transmettant des informations d'un à l'autre, avec chaque transfert dégradant la précision. Dans le cadre d'une expérience avec des agents spécialisés par rôle de développement logiciel (planificateur, implémentateur, testeur, réviseur), les sous-agents ont dépensé plus de jetons pour la coordination que pour le travail réel.
Les limites de décomposition efficaces sont les suivantes :
- Chemins de recherche indépendants. L'étude des « tendances du marché en Asie » par rapport aux « tendances du marché en Europe » peut se dérouler en parallèle, sans contexte commun.
- Composants séparés avec des interfaces propres. Avec un contrat API bien défini, le travail frontend et backend peut se dérouler en parallèle.
- Vérification en boîte noire. Un vérificateur dont les seules tâches sont d'exécuter des tests et de rendre compte des résultats n'a pas besoin de contexte d'implémentation.
Les limites de décomposition problématiques sont les suivantes :
- Phases séquentielles d’une même tâche. La planification, la mise en œuvre et les tests de la même fonctionnalité ont trop de contexte en commun.
- Composants étroitement couplés. Les composants qui nécessitent des échanges constants doivent être regroupés au sein d'un même agent.
- Travail nécessitant un état partagé. Les agents qui ont besoin de synchroniser fréquemment leur compréhension doivent rester ensemble.
Le modèle de sous-agent de vérification
Un modèle multi-agents qui fonctionne bien dans tous les domaines est le sous-agent de vérification. Il s'agit d'un agent dédié dont la seule responsabilité est de tester ou de valider le travail de l'agent principal.
Il est intéressant de noter que les modèles d'orchestration plus performants (comme Claude Opus 4.5) sont de plus en plus capables d'évaluer directement le travail des sous-agents sans étape de vérification distincte. Toutefois, les sous-agents de vérification restent utiles lorsque vous utilisez des orchestrateurs moins performants, lorsque la vérification nécessite des outils spécialisés ou lorsque vous souhaitez appliquer des points de contrôle de vérification explicites dans votre flux de travail.
Les sous-agents de vérification réussissent parce qu'ils contournent le problème du jeu du téléphone. La vérification ne nécessitant, par nature, qu'un transfert minimal de contexte, un vérificateur peut tester un système en boîte noire sans avoir besoin de connaître l'historique complet de sa conception.
Implémentation d'un système multi-agents
L'agent principal termine une unité de travail. Avant de poursuivre, il lance un sous-agent de vérification avec l'artéfact à vérifier, des critères de réussite définis et des outils pour effectuer la vérification.
Le vérificateur n'a pas besoin de comprendre pourquoi l'artéfact a été construit tel qu'il l'a été. Il lui suffit de déterminer si l'artéfact répond aux critères spécifiés.
from anthropic import Anthropic
client = Anthropic()
class CodingAgent:
def implement_feature(self, requirements: str) -> dict:
"""Main agent implements the feature"""
messages = [
{"role": "user", "content": f"Implement: {requirements}"}
]
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
messages=messages,
tools=[read_file, write_file, list_directory]
)
return {
"code": response.content,
"files_changed": extract_files(response)
}
class VerificationAgent:
def verify_implementation(self, requirements: str, files_changed: list) -> dict:
"""Separate agent verifies the work"""
messages = [
{"role": "user", "content": f"""
Requirements: {requirements}
Files changed: {files_changed}
Run the test suite and verify:
1. All existing tests pass
2. New functionality works as specified
3. No obvious errors or security issues
You MUST run the complete test suite before marking as passed.
Do not mark as passing after only running a few tests.
Run: pytest --verbose
Only mark as PASSED if ALL tests pass with no failures.
"""}
]
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=4096,
messages=messages,
tools=[run_tests, execute_code, read_file]
)
return {
"passed": extract_pass_fail(response),
"issues": extract_issues(response)
}
def implement_with_verification(requirements: str, max_attempts: int = 3):
for attempt in range(max_attempts):
result = CodingAgent().implement_feature(requirements)
verification = VerificationAgent().verify_implementation(
requirements,
result['files_changed']
)
if verification['passed']:
return result
requirements += f"\n\nPrevious attempt failed: {verification['issues']}"
raise Exception(f"Failed verification after {max_attempts} attempts")Applications de systèmes multi-agents
Les sous-agents de vérification sont efficaces pour :
- Assurance qualité. Exécuter des suites de tests, analyser le code, valider les résultats par rapport aux schémas.
- Contrôle de conformité. Assurer que les documents répondent aux exigences de la politique, vérifier les résultats par rapport aux règles.
- Validation des résultats. Confirmer que le contenu généré répond aux spécifications avant la livraison.
- Vérification factuelle. Demander à un agent distinct de vérifier les affirmations ou les citations dans le contenu généré.
Le problème de la victoire précoce
Le mode d'échec le plus important pour les sous-agents de vérification consiste à marquer les résultats comme ayant réussi sans avoir effectué des tests approfondis. Le vérificateur exécute un ou deux tests, observe leur réussite et déclare la réussite.
Les stratégies d'atténuation incluent :
- Critères concrets. Spécifiez « Exécutez la suite de tests complète et signalez tous les échecs » plutôt que « Assurez-vous que cela fonctionne ».
- Contrôles complets. Demandez au vérificateur de tester plusieurs scénarios et cas extrêmes.
- Tests négatifs. Demandez au vérificateur d'essayer des entrées qui devraient échouer et de vérifier qu'elles échouent effectivement.
- Instructions explicites. L'instruction « Vous DEVEZ exécuter la suite de tests complète avant de marquer la réussite du test » est essentielle. Sans exigences explicites pour une validation complète, les agents de vérification utilisent des raccourcis.
Choisir entre des systèmes mono-agents et multi-agents
Les systèmes multi-agents sont puissants, mais pas universellement appropriés. Avant d'ajouter la complexité de plusieurs agents coordonnés, confirmez que :
- Il existe de véritables contraintes que le système multi-agents résout, telles que les limites de contexte, les opportunités de parallélisation ou le besoin de spécialisation.
- La décomposition dépend du contexte, pas du type de problème. Groupez le travail en fonction du contexte qu'il nécessite, et non en fonction du type de travail.
- Il existe des points de vérification clairs permettant aux sous-agents de valider le travail sans avoir besoin du contexte complet.
Notre conseil ? Commencez par l'approche la plus simple qui fonctionne, et n'ajoutez de la complexité que si les preuves l'étayent.
Voici le premier d'une série d'articles consacrés aux systèmes multi-agents. Pour plus d’informations sur les modèles mono-agent, voir Créer des agents efficaces. Pour les stratégies de gestion du contexte, voir Ingénierie contextuelle efficace pour les agents IA. Pour en savoir plus sur la manière dont nous avons développé notre système de recherche multi-agents, voir Comment nous avons créé notre système de recherche multi-agents.
Remerciements
Rédigé par Cara Phillips, avec les contributions de Paul Chen, Andy Schumeister, Brad Abrams et Theo Chu.