# Coordination multi-agent Quand vous avez plusieurs agents LLM travaillant sur des tâches liées, Synapse fournit la couche de coordination — mémoire partagée, affectation de tâches et chat asynchrone. ## Schémas ### Schéma 1 : Mind partagé (source unique de vérité) Tous les agents partagent une Mind Key. Ils lisent/écrivent le même magasin de mémoire. ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Agent A │ │ Agent B │ │ Agent C │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ └─────────────┼─────────────┘ ▼ ┌──────────────┐ │ Shared Mind │ │ (one key) │ └──────────────┘ ``` **Cas d'usage :** petite équipe d'agents travaillant sur un projet. **Configuration :** ```bash # Tous les agents utilisent la même Mind Key export SYNAPSE_MIND_KEY=mk_shared_key... ``` **Coordination via tâches :** ```python # L'agent A crée une tâche create_task("Review PR #42", priority="high") # L'agent B la récupère tasks = list_tasks(status="pending") if tasks: task = tasks[0] update_task(task["id"], status="in_progress") # ... do work ... update_task(task["id"], status="done") ``` ### Schéma 2 : Minds spécialisés (contextes isolés) Chaque agent a son propre mind. Ils communiquent via un mind de « coordination » partagé. ``` ┌──────────┐ ┌──────────┐ ┌──────────┐ │ Coder │ │ Reviewer │ │ Deployer │ │ Agent │ │ Agent │ │ Agent │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ ▼ ▼ ▼ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ Mind C │ │ Mind R │ │ Mind D │ └─────────┘ └─────────┘ └─────────┘ │ │ │ └─────────────┼─────────────┘ ▼ ┌──────────────────┐ │ Coordination Mind│ │ (shared) │ └──────────────────┘ ``` **Cas d'usage :** agents avec différentes spécialités (codage, revue, déploiement). **Configuration :** ```bash # Agent codeur SYNAPSE_MIND_KEY=mk_coder... MCP_TRANSPORT=stdio npx synapse-mcp-api@latest # Agent relecteur SYNAPSE_MIND_KEY=mk_reviewer... MCP_TRANSPORT=stdio npx synapse-mcp-api@latest # Agent déploiement SYNAPSE_MIND_KEY=mk_deployer... MCP_TRANSPORT=stdio npx synapse-mcp-api@latest ``` **Coordination via mind partagé :** ```python # Le codeur stocke « prêt pour relecture » COORDINATION_KEY = "mk_coordination..." requests.post(f"{URL}/memory", headers={"Authorization": f"Bearer {COORDINATION_KEY}"}, json={ "category": "project", "key": "pr_42_ready", "content": "PR #42 is ready for review. Branch: feature/docs-system", "tags": ["review", "pr-42"], "priority": "high" }) # Le relecteur récupère les demandes de revue r = requests.get(f"{URL}/memory/search?q=ready+for+review", headers={"Authorization": f"Bearer {COORDINATION_KEY}"}) ``` ### Schéma 3 : hub-and-spoke (orchestrateur) Un agent orchestrateur central affecte des tâches à des agents travailleurs. ``` ┌──────────────┐ │ Orchestrator │ │ Agent │ └──────┬───────┘ │ ┌──────────┼──────────┐ ▼ ▼ ▼ ┌──────┐ ┌──────┐ ┌──────┐ │Worker│ │Worker│ │Worker│ │ A │ │ B │ │ C │ └──────┘ └──────┘ └──────┘ ``` **Cas d'usage :** workflows complexes avec travail parallèle. **Implémentation :** ```python # Orchestrateur class Orchestrator: def assign_task(self, worker_id, task_description): # Stocker la tâche dans le mind du travailleur (ou mind de coordination partagé) create_task(task_description, priority="high") # Notifier le travailleur via chat reply(f"@{worker_id}: New task — {task_description}") def check_progress(self): tasks = list_tasks(status="in_progress") for t in tasks: print(f"{t['title']}: {t['status']}") # Les travailleurs pollinent les tâches affectées class Worker: def run(self): while True: tasks = list_tasks(status="pending") for t in tasks: if assigned_to_me(t): update_task(t["id"], status="in_progress") result = do_work(t) update_task(t["id"], status="done") reply(f"Completed: {t['title']}") time.sleep(60) ``` ## Coordination via chat Les agents peuvent communiquer via le système de chat : ```python # L'agent A envoie à l'agent B reply("@agent-b: Can you review my PR?") # L'agent B polline et répond for msg in poll_messages(): if "@agent-b" in msg["content"]: reply(f"@agent-a: Sure, looking at it now.") ``` > [!NOTE] > Les messages de chat sont marqués par rôle. Définissez role=agent pour les messages > agent-à-agent, role=human pour humain-à-agent. ## Coordination via variables Utilisez des variables pour une coordination légère (verrous, drapeaux) : ```python # Acquérir un verrou def acquire_lock(name): r = requests.post(f"{URL}/var", headers={"Authorization": f"Bearer {KEY}"}, json={"key": f"lock_{name}", "value": "acquired"}) return True def release_lock(name): requests.delete(f"{URL}/var/lock_{name}", headers={"Authorization": f"Bearer {KEY}"}) # Utilisation if acquire_lock("deploy"): try: deploy_to_production() finally: release_lock("deploy") ``` ## Bonnes pratiques > [!TIP] > - **Utilisez des minds séparés pour des préoccupations séparées** — ne mélangez pas mémoire de codeur et de relecteur > - **Taguez les agents dans le chat** — `@agent-name` pour une adresse claire > - **Utilisez des tâches pour l'affectation de travail** — pas le chat (le chat est pour la discussion) > - **Implémentez l'idempotence** — les agents peuvent réessayer des opérations échouées > - **Journalisez tout** — stockez les décisions en mémoire pour l'auditabilité ## Prochaines étapes - [Agent LLM persistant](/docs/guides/persistent-llm-agent) - [Cookbook LLM](/docs/llm-cookbook/session-start-pattern) - [Automatisation par webhooks](/docs/guides/webhook-automation)