Un brief, quatre canaux, des règles
Le problème
Le même brief produit doit devenir quatre textes très différents :
| Canal | Format attendu | Longueur maximale (choix du lab) |
|---|---|---|
| accroche, 3 paragraphes courts, appel à l'action, 3 hashtags | 1 300 caractères | |
| ton chaleureux, quelques emojis, 5 hashtags | 800 caractères | |
| Newsletter | ligne « Objet : », titre, 2 paragraphes, bouton | 1 500 caractères |
| 2 ou 3 phrases, vouvoiement, un lien | 350 caractères |
Et deux règles s'appliquent partout :
- pas de données personnelles : un brief contient souvent un contact presse (« Léa Dupont, lea.dupont@... ») qui ne doit jamais être publié, ni même envoyé au modèle ;
- pas de promesses interdites : « garanti à vie », « 100 % sans risque », « le meilleur du marché » sont des allégations invérifiables, qui exposent la marque à un reproche de pratique commerciale trompeuse.
Pourquoi un sous-agent par canal ?
On pourrait demander les quatre textes en un seul appel. Séparer les canaux apporte trois choses :
- Des consignes courtes et nettes : chaque agent n'a que les règles de son canal ; il ne mélange pas les hashtags Instagram et la ligne « Objet : » de la newsletter.
- Du parallélisme : les quatre appels partent en même temps, la durée totale est celle du plus lent, pas la somme.
- Une modération par canal : si seul le texte Instagram dérape, seul lui est bloqué ; les trois autres restent utilisables.
sequenceDiagram
participant U as "Utilisateur"
participant P as "ParallelAgent"
participant L as "linkedin"
participant W as "whatsapp"
U->>P: "brief produit"
par en parallèle
P->>L: "brief"
L-->>P: "texte_linkedin"
and
P->>W: "brief"
W-->>P: "texte_whatsapp"
end
P-->>U: "état : texte_linkedin, ..., texte_whatsapp"
Vocabulaire ADK :
| Terme | Définition | Dans ce lab |
|---|---|---|
| Sous-agent | agent rattaché à un agent parent par sub_agents=[...] | les 4 rédacteurs |
ParallelAgent | agent de workflow (sans LLM) qui lance tous ses sous-agents en même temps | declinaisons |
output_key | clé de l'état de session où ADK enregistre la réponse finale de l'agent | texte_linkedin... |
| Callback | fonction appelée par ADK à un moment précis du cycle de vie | moderer_entree, moderer_sortie |
Pourquoi un ParallelAgent et non un SequentialAgent ici ?
SequentialAgent sert quand l'étape B lit le résultat de l'étape A. Ici, chaque déclinaison part du même brief : on peut tout lancer en même temps. Le nombre de tokens, lui, est le même.
Où placer la modération ?
ADK propose plusieurs callbacks autour d'un appel au modèle. Deux nous suffisent :
flowchart LR
REQ["Requête construite par ADK"] --> BM{"before_model_callback"}
BM -->|"renvoie None"| LLM["Modèle Gemini"]
BM -->|"renvoie une LlmResponse"| SKIP["Réponse de remplacement : le modèle n'est pas appelé"]
LLM --> AM{"after_model_callback"}
AM -->|"renvoie None"| OUT["Réponse d'origine"]
AM -->|"renvoie une LlmResponse"| REPL["Réponse remplacée"]
| Callback | Quand | Ce qu'il peut faire | Notre usage |
|---|---|---|---|
before_model_callback | juste avant l'appel au modèle | modifier la requête, ou court-circuiter l'appel en renvoyant une réponse | masquer e-mails et téléphones ; refuser un brief qui exige « garanti à vie » |
after_model_callback | juste après la réponse du modèle | remplacer la réponse | bloquer un texte qui contient une promesse interdite ou une donnée personnelle |
Un brief contient le téléphone du contact presse. À quel moment faut-il le retirer pour que Gemini ne le voie jamais ?
after_model_callback agit trop tard : le numéro a déjà été envoyé au modèle. L'instruction ne fait que demander de ne pas le recopier. Seul le masquage avant l'appel garantit que le modèle ne le reçoit pas.
Exercice : choisir le bon point d'accroche
Pour chaque besoin, choisissez before_model_callback, after_model_callback ou « ni l'un ni l'autre » :
- Refuser un brief écrit en anglais.
- Couper un texte WhatsApp trop long.
- Mesurer la durée de chaque appel au modèle.
- Interdire au rédacteur LinkedIn d'appeler un outil de publication.
Voir la solution
- before_model : on inspecte le brief et on renvoie une réponse de refus, sans appeler le modèle.
- after_model : on remplace la réponse par une version coupée (ou mieux, on la bloque et on demande une nouvelle génération : couper au milieu d'une phrase donne un mauvais texte).
- Les deux ensemble :
before_modelnote l'heure dans l'état,after_modelcalcule la durée. - Ni l'un ni l'autre : c'est le rôle de
before_tool_callback(avant l'exécution d'un outil), ou plus simplement de ne pas donner cet outil à l'agent.
Résultat obtenu
Exécution réelle le 2026-10-15 (gemini-3.5-flash) sur brief_produit.md, qui contient un contact presse fictif : extrait du rapport.
## whatsapp (262/350 car., ok)
Découvrez la gourde isotherme en inox Clairo de 500 ml, conçue pour maintenir vos boissons
froides 24 h et chaudes 12 h. Profitez de notre prix de lancement à 29,90 € jusqu'au
30 novembre 2026. Commandez la vôtre parmi 4 couleurs sur https://exemple.fr/produit 💧
## Journal de modération
- linkedin | entrée : masquage | email, telephone
- instagram | entrée : masquage | email, telephone
- newsletter | entrée : masquage | email, telephone
- whatsapp | entrée : masquage | email, telephoneJe sais faire
- Expliquer pourquoi découper une tâche en un sous-agent par canal
- Choisir entre
ParallelAgentetSequentialAgent - Situer
before_model_callbacketafter_model_callbackdans le cycle d'un appel - Dire pourquoi masquer une donnée personnelle avant l'appel au modèle