Utilise ce skill quand une tâche dépasse ce qu'un seul contexte peut traiter et bénéficie d'une structure d'agents : couvrir en parallèle (décomposer un large périmètre), gagner en confiance (perspectives indépendantes + vérification adversariale avant de conclure), ou absorber une échelle qu'un contexte ne tient pas (migrations, audits, sweeps). Le tool Workflow exécute un script JavaScript qui orchestre des sous-agents de façon déterministe (boucles, conditions, fan-out) — contrairement à un agent unique piloté par le modèle.
-
Scoper le travail d'abord (inline) — Avant d'orchestrer, découvre la work-list en ligne : liste les fichiers, trouve les cibles, scope le diff. Le hybride est souvent le bon move : scout inline → puis Workflow pour pipeliner sur la liste. Tu n'as pas besoin de connaître la forme avant la tâche, seulement avant l'étape d'orchestration.
-
Choisir la phase — Identifie une seule phase bien scopée par appel : understand (lecteurs parallèles → carte structurée), design (panel de juges sur N approches → synthèse scorée), review (dimensions → find → verify adversarial), research (sweep multi-modal → deep-read → synthèse), migrate (découvrir les sites → transformer chacun en worktree isolé → vérifier). Pour du multi-phase, enchaîne plusieurs workflows et lis chaque résultat avant de décider le suivant.
-
Écrire le bloc meta — Tout script commence par export const meta = {...} en littéral pur (pas de variables, d'appels, de spreads). Champs requis : name, description. Optionnels : whenToUse, phases (un objet par phase() avec title exact). Exemple :
export const meta = {
name: 'review-changes',
description: 'Revue multi-dimension du diff, chaque finding vérifié',
phases: [{ title: 'Review' }, { title: 'Verify' }],
}
-
Préférer pipeline() par défaut — pipeline(items, stage1, stage2, ...) fait passer chaque item par toutes les étapes sans barrière : l'item A peut être en stage 3 pendant que B est en stage 1. Wall-clock = chaîne la plus lente, pas somme-des-plus-lents-par-étape. Chaque callback reçoit (prevResult, originalItem, index).
const results = await pipeline(
DIMENSIONS,
d => agent(d.prompt, {label: `review:${d.key}`, phase: 'Review', schema: FINDINGS}),
review => parallel(review.findings.map(f => () =>
agent(`Vérifie de façon adversariale: ${f.title}`, {phase: 'Verify', schema: VERDICT})
.then(v => ({...f, verdict: v}))))
)
const confirmed = results.flat().filter(Boolean).filter(f => f.verdict?.isReal)
-
N'utiliser parallel() (barrière) que si nécessaire — parallel(thunks) attend TOUS les résultats. Justifié uniquement quand l'étape N a besoin du set complet de l'étape N-1 : dedup/merge global, early-exit sur count zéro, ou prompt qui référence "les autres findings". PAS justifié par "je dois flatten/filter d'abord" (fais-le dans une étape de pipeline) ni "c'est plus propre". Un thunk qui throw → null dans le résultat ; .filter(Boolean) avant usage.
-
Sortie structurée via schema — Sans schema, agent() renvoie son texte final (string). Avec schema (JSON Schema), le sous-agent est forcé d'appeler StructuredOutput et agent() renvoie l'objet validé — pas de parsing, retry automatique sur mismatch. Renvoie null si l'utilisateur skip l'agent → filtrer.
-
Patterns qualité — Compose selon la tâche :
- Adversarial verify : N sceptiques indépendants par finding, chacun promptés pour réfuter ; on tue si majorité réfute.
- Perspective-diverse verify : si un finding peut échouer de plusieurs façons, donne à chaque vérificateur une lentille distincte (correctness, security, perf, repro) plutôt que N réfuteurs identiques.
- Judge panel : N tentatives sous angles différents (MVP-first, risk-first, user-first), scorées par juges parallèles, synthèse du gagnant + greffe des meilleures idées des autres.
- Loop-until-dry : pour de la découverte de taille inconnue (bugs, edge cases), relance des finders jusqu'à K rounds consécutifs sans rien de neuf. Dedup contre
seen (tout ce qui a été vu), PAS contre confirmed — sinon les findings rejetés réapparaissent et ça ne converge jamais.
- Completeness critic : un agent final qui demande "qu'est-ce qui manque — modalité non explorée, claim non vérifié, source non lue ?". Ce qu'il trouve devient le round suivant.
-
Scaler au budget — budget.total (cible de tokens, null si non fixée), budget.spent(), budget.remaining(). Boucle dynamique avec garde sur budget.total (sinon remaining() vaut Infinity et tu cours jusqu'au cap de 1000 agents) :
while (budget.total && budget.remaining() > 50_000) {
const r = await agent("Trouve des bugs.", {schema: BUGS})
bugs.push(...r.bugs)
log(`${bugs.length} trouvés, ${Math.round(budget.remaining()/1000)}k restants`)
}
-
Itérer & resume — Chaque invocation persiste son script sous le dossier de session et renvoie le scriptPath + un runId. Pour itérer : édite le fichier et relance avec {scriptPath}. Pour reprendre après un kill/edit : {scriptPath, resumeFromRunId} — le plus long préfixe inchangé d'appels agent() renvoie en cache instantanément, le premier appel modifié et tout ce qui suit s'exécute en live.
-
Rester dans la boucle — Workflow tourne en arrière-plan et renvoie immédiatement un task ID ; une <task-notification> arrive à la fin. Suis la progression live via /workflows. Pour du travail large, enchaîne plusieurs workflows en séquence — lis chaque résultat avant de décider la phase suivante.