208 — Workflows — orchestrer plusieurs primitives
Durée estimée : 60 min
Un
skillencapsule un savoir-faire. Unagentincarne un rôle. Un workflow les compose pour résoudre un problème métier de bout en bout.
Pourquoi ce module
Tu sais créer des skills et des agents. Mais un objectif métier réel dépasse presque toujours le périmètre d’une seule primitive. Prenons un exemple concret : à partir d’une issue GitHub, tu veux que Copilot génère une spécification, rédige un plan d’implémentation, puis produise le code correspondant. Aucun skill isolé ni agent unique ne peut couvrir cette chaîne de bout en bout sans devenir un monstre monolithique.
Un workflow résout ce problème en orchestrant plusieurs primitives dans une séquence cohérente. L’idée centrale est simple : un agent racine pilote le flux et délègue chaque étape à un sous-agent spécialisé via runSubagent. Chaque sous-agent a un scope clair, des outils restreints, et une responsabilité unique.
À la fin de ce module, tu sais :
- expliquer ce qu’est un workflow dans l’écosystème Copilot ;
- appliquer le pattern Outside-In : un orchestrateur racine qui délègue à des sous-agents ;
- identifier et éviter l’anti-pattern du super-agent monolithique ;
- décomposer un objectif métier en étapes, puis mapper chaque étape sur une primitive ;
- câbler un workflow complet qui enchaîne trois sous-agents.
Pré-requis
- Module 103 — Skills
- Module 104 — Agents personnalisés
- VS Code avec l’extension GitHub Copilot activée.
- Un dépôt Git avec au moins une issue ouverte sur GitHub.
Concepts clés
Qu’est-ce qu’un workflow ?
Un workflow est une séquence orchestrée de primitives Copilot (instructions, skills, agents) qu’un agent racine coordonne pour atteindre un objectif métier. Le workflow n’est pas un nouveau type de fichier — c’est un pattern d’organisation qui s’exprime dans le corps d’un .agent.md.
L’agent racine ne fait pas le travail lui-même. Il découpe l’objectif en étapes, délègue chaque étape à un sous-agent spécialisé, récupère le résultat, et passe à l’étape suivante. Chaque sous-agent s’exécute dans son propre contexte, avec ses propres outils et contraintes.
flowchart LR
A[Agent orchestrateur] -->|1. specs| B[spec-writer]
A -->|2. plan| C[plan-writer]
A -->|3. code| D[coder]
Le pattern Outside-In
Le terme Outside-In vient de l’idée qu’on part de l’objectif global (l’extérieur) pour descendre vers les tâches unitaires (l’intérieur). L’orchestrateur connaît le quoi — les sous-agents savent le comment.
Ce pattern présente trois avantages :
- Isolation du contexte — chaque sous-agent ne reçoit que les informations nécessaires à sa tâche. Le sous-agent qui rédige les specs n’a pas besoin de voir le code, et inversement.
- Réutilisabilité — un sous-agent
spec-writerpeut servir dans plusieurs workflows différents. Tu le crées une fois, tu le réutilises partout. - Contraintes d’outils par étape — le sous-agent qui rédige les specs n’a pas besoin de
editFiles. Le sous-agent qui code n’a pas besoin degithubRepo. Chaque agent expose uniquement les outils pertinents pour sa tâche.
L’anti-pattern : le super-agent monolithique
Le réflexe naturel quand on découvre les agents est de tout mettre dans un seul fichier .agent.md :
---
name: do-everything
description: "Depuis une issue, génère les specs, le plan, et le code."
tools:
- codebase
- editFiles
- runInTerminal
- githubRepo
- fetch
- runSubagent
---
Tu es un développeur full-stack senior. Quand on te donne une issue :
1. Lis l'issue sur GitHub.
2. Rédige une spécification technique.
3. Crée un plan d'implémentation.
4. Implémente le code.
5. Lance les tests.
6. Rédige le message de commit.
Ce super-agent pose plusieurs problèmes :
- Contexte saturé — toutes les instructions cohabitent dans le même contexte. À l’étape 4, le modèle traîne encore les consignes de rédaction de specs qui ne servent plus.
- Outils trop larges — l’agent a accès à tout, tout le temps. Rien n’empêche l’étape de rédaction de specs de modifier un fichier par accident.
- Débogage difficile — quand le résultat est mauvais, tu ne sais pas quelle étape a déraillé. Tout est mélangé dans une seule conversation.
- Réutilisation impossible — si tu veux réutiliser la logique de rédaction de specs dans un autre workflow, tu dois copier-coller des sections du super-agent.
Décomposer en orchestrateur + sous-agents
La solution consiste à extraire chaque responsabilité dans un agent dédié :
| Étape | Sous-agent | Responsabilité | Outils |
|---|---|---|---|
| 1 | spec-writer |
Lire l’issue et rédiger les specs | githubRepo |
| 2 | plan-writer |
Transformer les specs en plan d’implémentation | codebase |
| 3 | coder |
Implémenter le plan | codebase, editFiles, runInTerminal |
L’orchestrateur n’a qu’un seul outil spécifique : runSubagent. Il coordonne la séquence et transmet le résultat d’un sous-agent au suivant.
La transmission de contexte entre étapes
Un point subtil : chaque sous-agent s’exécute dans une conversation isolée. Il ne voit pas l’historique des étapes précédentes. C’est l’orchestrateur qui fait le pont : il récupère la sortie du sous-agent précédent et la transmet en entrée au sous-agent suivant.
Dans le corps de l’orchestrateur, cela s’exprime en langage naturel :
1. Délègue la rédaction des specs à `spec-writer` en lui transmettant
le contenu de l'issue. Récupère les specs produites.
2. Délègue la rédaction du plan à `plan-writer` en lui transmettant
les specs. Récupère le plan produit.
3. Délègue l'implémentation à `coder` en lui transmettant le plan.
L’orchestrateur joue le rôle de relais. Chaque sous-agent reçoit exactement ce dont il a besoin — ni plus, ni moins.
Alternative : le pattern handoff
Le pattern Outside-In n’est pas la seule façon d’orchestrer un workflow. Le handoff propose une approche différente : au lieu d’un orchestrateur central qui délègue, chaque agent transfère le contrôle au suivant quand il a terminé son travail.
flowchart LR
A[spec-writer] -->|handoff + specs| B[plan-writer]
B -->|handoff + plan| C[coder]
Dans un handoff :
- Il n’y a pas d’orchestrateur central. Chaque agent connaît le suivant dans la chaîne.
- L’agent qui termine son travail passe le relais en transmettant son résultat au suivant.
- Le contexte circule de proche en proche, pas en étoile via un centre.
Le handoff est plus simple à mettre en place pour des chaînes linéaires : A → B → C. Chaque agent a dans ses instructions une consigne du type « quand tu as terminé, délègue à l’agent plan-writer via runSubagent en lui transmettant ton résultat ».
Quand choisir quoi ?
| Critère | Outside-In (orchestrateur) | Handoff (chaîne) |
|---|---|---|
| Topologie | Étoile — un centre coordonne tout | Linéaire — chaque agent connaît le suivant |
| Visibilité | L’orchestrateur voit tout le flux | Chaque agent ne voit que son prédécesseur |
| Branchement conditionnel | Facile — l’orchestrateur décide | Difficile — chaque agent doit gérer la logique |
| Boucle de feedback | L’orchestrateur peut relancer une étape | Il faut remonter la chaîne entière |
| Simplicité | Plus de fichiers à créer | Moins de fichiers, plus autonome |
| Débogage | Centralisé — une seule conversation à inspecter | Distribué — suivre la chaîne d’agent en agent |
Règle simple : si ton workflow est une chaîne linéaire sans branchement ni boucle, le handoff est plus léger. Dès que tu as besoin de branchements conditionnels (« si les tests échouent, relancer le codeur ») ou de boucles de feedback (« le reviewer renvoie au codeur »), l’orchestrateur central est préférable.
Les deux patterns peuvent se combiner : un orchestrateur central pour le flux principal, avec des handoffs entre sous-agents quand deux étapes sont toujours séquentielles.
Démonstration
Étape 1 — Le super-agent monolithique (point de départ)
Voici le fichier unique que tu vas refactorer. Il fait tout dans un seul agent :
<!-- .agents/do-everything.agent.md -->
---
name: do-everything
description: "Depuis une issue GitHub, génère specs + plan + code."
tools:
- codebase
- editFiles
- runInTerminal
- githubRepo
- runSubagent
---
Tu es un développeur senior. Quand on te donne un numéro d'issue :
1. Récupère le contenu de l'issue sur GitHub via `githubRepo`.
2. Rédige une spécification technique en Markdown dans `docs/specs/`.
3. Crée un plan d'implémentation avec les fichiers à créer ou modifier.
4. Implémente le code selon le plan.
5. Lance les tests avec `npm test`.
Étape 2 — Extraire le sous-agent spec-writer
Crée un premier sous-agent dédié à la rédaction de specs :
+ # .agents/spec-writer.agent.md
+
+ ---
+ name: spec-writer
+ description: "Rédige une spécification technique à partir d'une issue GitHub."
+ tools:
+ - githubRepo
+ ---
+
+ Tu es un rédacteur technique. On te transmet le contenu d'une issue
+ GitHub. Ta seule tâche est de produire une spécification technique
+ structurée en Markdown.
+
+ ## Format de sortie
+
+ - Titre reprenant le titre de l'issue.
+ - Section "Contexte" résumant le problème.
+ - Section "Exigences" listant les critères d'acceptation.
+ - Section "Hors périmètre" listant ce qui n'est pas couvert.
+
+ Tu ne modifies aucun fichier. Tu ne crées aucun fichier.
+ Tu retournes uniquement le contenu Markdown de la spec.
Note que cet agent n’a qu’un seul outil : githubRepo. Il ne peut ni écrire de fichiers ni exécuter de commandes.
Étape 3 — Extraire plan-writer et coder
Même logique pour les deux autres sous-agents :
+ # .agents/plan-writer.agent.md
+
+ ---
+ name: plan-writer
+ description: "Transforme une spécification technique en plan d'implémentation."
+ tools:
+ - codebase
+ ---
+
+ Tu es un architecte logiciel. On te transmet une spécification
+ technique. Ta tâche est de produire un plan d'implémentation.
+
+ ## Format de sortie
+
+ Pour chaque fichier à créer ou modifier :
+ - Chemin du fichier.
+ - Description des changements.
+ - Dépendances avec d'autres fichiers.
+
+ Tu ne modifies aucun fichier. Tu retournes uniquement le plan.
+ # .agents/coder.agent.md
+
+ ---
+ name: coder
+ description: "Implémente du code à partir d'un plan d'implémentation."
+ tools:
+ - codebase
+ - editFiles
+ - runInTerminal
+ ---
+
+ Tu es un développeur. On te transmet un plan d'implémentation.
+ Implémente chaque fichier du plan dans l'ordre indiqué.
+
+ ## Contraintes
+
+ - Suis le plan à la lettre. Ne dévie pas du périmètre.
+ - Lance les tests après l'implémentation.
+ - Si un test échoue, corrige et relance.
Étape 4 — Créer l’orchestrateur
Maintenant, remplace le super-agent par un orchestrateur léger :
- # .agents/do-everything.agent.md (supprimé)
+ # .agents/issue-to-code.agent.md
+
+ ---
+ name: issue-to-code
+ description: "Workflow complet : issue GitHub → specs → plan → code."
+ tools:
+ - runSubagent
+ - githubRepo
+ ---
+
+ Tu es un orchestrateur de workflow. Quand on te donne un numéro
+ d'issue GitHub, tu coordonnes trois sous-agents dans l'ordre :
+
+ ## Workflow
+
+ 1. Récupère le contenu de l'issue via `githubRepo`.
+ 2. Délègue la rédaction des specs à l'agent `spec-writer`
+ en lui transmettant le contenu de l'issue.
+ Récupère les specs produites.
+ 3. Délègue la rédaction du plan à l'agent `plan-writer`
+ en lui transmettant les specs.
+ Récupère le plan produit.
+ 4. Délègue l'implémentation à l'agent `coder`
+ en lui transmettant le plan.
+ 5. Résume le travail accompli : specs, plan, fichiers modifiés.
+
+ ## Règles
+
+ - Tu ne modifies jamais de fichier toi-même.
+ - Tu ne codes jamais toi-même.
+ - Si un sous-agent échoue, rapporte l'erreur et arrête le workflow.
La structure finale du dossier .agents/ :
.agents/
issue-to-code.agent.md # orchestrateur
spec-writer.agent.md # sous-agent 1
plan-writer.agent.md # sous-agent 2
coder.agent.md # sous-agent 3
Étape 5 — Tester le workflow
- Ouvre le panneau
chatde VS Code. - Sélectionne le mode
issue-to-codedans le sélecteur en haut. - Envoie : « Traite l’issue #12. »
- Observe la séquence : l’orchestrateur appelle
spec-writer, puisplan-writer, puiscoder. - Vérifie que chaque sous-agent reste dans son périmètre :
spec-writerne modifie pas de fichier,coderne rédige pas de specs.
Exercice ⭐⭐
Énoncé — Construis un workflow complet qui, depuis une issue GitHub, enchaîne : spécification, planification, implémentation.
Étapes guidées :
- Crée trois sous-agents dans
.agents/:spec-writer.agent.md— lit l’issue, produit une spec Markdown. Outils :githubRepouniquement.plan-writer.agent.md— lit la spec, produit un plan. Outils :codebaseuniquement.coder.agent.md— lit le plan, implémente. Outils :codebase,editFiles,runInTerminal.
- Crée un orchestrateur
issue-to-code.agent.mdqui :- Récupère le contenu de l’issue.
- Délègue chaque étape dans l’ordre via
runSubagent. - Transmet la sortie de chaque étape à l’étape suivante.
- Ne modifie jamais de fichier lui-même.
- Ouvre une issue de test dans ton dépôt (ou utilise une issue existante).
- Active l’agent
issue-to-codeet demande-lui de traiter l’issue. - Vérifie que :
spec-writerproduit une spec sans modifier de fichier.plan-writerproduit un plan sans modifier de fichier.coderimplémente le plan et lance les tests.
Critère de réussite : l’orchestrateur enchaîne les trois sous-agents dans l’ordre, chacun reste dans son scope, et le code final correspond à l’issue de départ.
Validation
Tu peux passer au module suivant si :
- Ton dépôt contient un agent orchestrateur et au moins trois sous-agents.
- L’orchestrateur utilise
runSubagentpour déléguer à chaque sous-agent. - Chaque sous-agent a une liste
toolsrestreinte à ce dont il a besoin. - Chaque sous-agent a une responsabilité unique clairement définie dans sa
description. - Tu sais expliquer pourquoi un super-agent monolithique pose problème.
- Le workflow complet enchaîne les trois étapes et produit un résultat cohérent.
Pour aller plus loin
- Module 315 — Tester ses primitives : mesurer objectivement que chaque sous-agent produit le bon résultat avec des
evalbinaires. - Module 311 — Tokens, hallucinations et sobriété LLM : comprendre pourquoi la décomposition en sous-agents réduit la consommation de tokens.
- Module 314 — Autoresearch : appliquer la discipline d’évaluation itérative à chaque sous-agent du workflow.
- Explore les patterns de workflow plus avancés : boucles de feedback (le relecteur renvoie au codeur), branchements conditionnels (si les tests échouent, relancer l’étape 3), parallélisation (specs et plan en parallèle quand ils sont indépendants).