Leçon 7 — ADK et mesures

Mesurer et décider

9 min de lecture

Le responsable de la plateforme pose trois questions avant de généraliser le harness à d'autres dossiers : « Le parallélisme vaut-il sa complexité ? Combien coûte un dossier ? Faut-il partir sur ADK ou garder notre code ? » Les impressions ne suffisent pas, et une seule exécution non plus : sur ce projet, deux exécutions identiques ont donné 69 et 88 sur 100 à la grille. Cette leçon produit les chiffres, dit ce qu'ils permettent de conclure et ce qu'ils ne permettent pas.

Le mécanisme : un banc d'essai à variables isolées

flowchart LR
  T["Même demande<br/>même corpus, même grille"] --> A["main, parallélisme 4"]
  T --> B["main, parallélisme 1"]
  T --> C["adk, parallélisme 4"]
  T --> D["adk, parallélisme 1"]
  A --> M["mesures.json<br/>durée par phase, appels,<br/>tokens, coût, note"]
  B --> M
  C --> M
  D --> M

Une seule variable change à la fois : l'implémentation, ou le parallélisme. Les consignes, les schémas, les modèles, le budget et la grille sont communs aux deux versions (c'est pour cela qu'ils vivent hors de version_adk.py). La durée est découpée par phase grâce au journal (Journal.phases()) : sans ce découpage, on attribuerait au parallélisme un écart qui vient de la synthèse.

make e2e

Résultat obtenu (2026-10-15)

Deuxième passage de make e2e (le premier, 3 minutes plus tôt, figure dans le tableau de synthèse) :

e2e du 2026-10-15 20:57 — modèle gemini-3.5-flash-lite
main-parallele    39.2 s (plan 5.3 / sous-agents 6.0 / synthèse 27.9)  16 appels  27007 in  9322 out  0.0398 $  qualité 92.5/100
main-sequentiel   45.3 s (plan 5.3 / sous-agents 18.0 / synthèse 22.1)  15 appels  25411 in  7963 out  0.0347 $  qualité 88.3/100
adk-parallele     42.5 s (plan 7.6 / sous-agents 6.2 / synthèse 28.8)  19 appels  32432 in  8707 out  0.0398 $  qualité 88.3/100
adk-sequentiel    48.0 s (plan 6.1 / sous-agents 21.0 / synthèse 20.9)  18 appels  29414 in  8162 out  0.0368 $  qualité 88.3/100

Synthèse des deux passages (moyenne, puis valeurs individuelles) :

ConfigurationDurée totalePhase sous-agents (passage 2)AppelsCoûtQualité
main, parallèle34,9 s (30,6 ; 39,2)6,0 s15 ; 160,036 $92,5 (92,5 ; 92,5)
main, séquentiel43,4 s (41,4 ; 45,3)18,0 s10 ; 150,033 $84,6 (80,8 ; 88,3)
ADK, parallèle35,4 s (28,2 ; 42,5)6,2 s19 ; 190,036 $78,8 (69,2 ; 88,3)
ADK, séquentiel48,0 s (48,0 ; 48,0)21,0 s21 ; 180,038 $86,7 (85,0 ; 88,3)
xychart-beta
  title "Phase des sous-agents, passage 2 (secondes)"
  x-axis ["main par.", "main séq.", "ADK par.", "ADK séq."]
  y-axis "secondes" 0 --> 25
  bar [6.0, 18.0, 6.2, 21.0]

Deux mesures faites pendant la mise au point, avec la version à la main, complètent le tableau (une exécution chacune) :

Variante du planificateur et de la synthèseDuréeCoûtQualité
gemini-3.5-flash-lite partout14,0 s0,024 $65,8
gemini-3.8-flash, réflexion par défaut59,6 s0,045 $80,8
gemini-3.8-flash, réflexion par défaut, consigne sous-agent finale88,3 s0,067 $88,3
gemini-3.8-flash, réflexion LOW, consigne sous-agent finale34,2 s0,033 $92,5

Ce que les chiffres permettent de conclure

  1. Le parallélisme divise par 3 la phase qu'il touche, et seulement elle. 18,0 → 6,0 s à la main, 21,0 → 6,2 s avec ADK. Sur le temps total, le gain n'est plus que de 5,5 à 6,1 s au passage 2, parce que planification et synthèse pèsent de 56 à 86 % de la durée ; au passage 1, il varie de 11 à 20 s, surtout parce que la durée de la synthèse change d'un passage à l'autre. C'est la loi d'Amdahl appliquée aux agents.
  2. Le parallélisme ne change pas le coût. Les mêmes appels sont faits, dans un autre ordre : 0,033 à 0,040 $ dans toutes les configurations.
  3. La qualité ne dépend pas du parallélisme et l'écart entre passages identiques (69,2 contre 88,3 pour ADK parallèle) dépasse tous les écarts entre configurations. Avec deux passages, aucune différence de qualité entre main et ADK n'est démontrée. Pour en affirmer une, il faudrait de l'ordre d'une dizaine de passages par configuration.
  4. ADK consomme plus d'appels pour le même travail : 18 à 21 contre 10 à 16, et de 16 à 27 % de tokens d'entrée en plus (122 % sur le séquentiel du passage 1), sans surcoût visible ici parce que ces appels sont faits par le modèle le moins cher. Sur un volume de dossiers élevé, cet écart se paie.
  5. Le choix du modèle et du niveau de réflexion du rédacteur pèse plus que tout le reste. La réflexion LOW sur gemini-3.8-flash a divisé la durée par 2,6 et le coût par 2 par rapport à la réflexion par défaut, à qualité égale ou meilleure sur cette exécution.

À la main ou ADK

CritèreÀ la mainADK 2.10 Workflow
Code propre à l'orchestration (hors lignes vides et commentaires)172 lignes (orchestrateur.py + sous_agent.py)133 lignes (version_adk.py)
Contrôle de la requête envoyée au modèletotalpartiel : instructions et outil set_model_response ajoutés
Budget et atterrissage forcédans la bouclecallbacks, en modifiant llm_request
Reprise visible tentative par tentativeouioui avec boucle explicite ; non avec RetryConfig
Reprise après interruption (session persistée, humain dans la boucle)à écrirefournie par le moteur de workflow
Ce qui casse à la mise à jourl'API google-genail'API ADK, qui vient de déprécier ses agents de composition

Recommandation. Pour ce harness, gardez la version à la main en production : elle fait environ un quart d'appels en moins, sa trajectoire est entièrement sous votre contrôle, et le gain en lignes d'ADK (une quarantaine) ne compense pas. Passez à ADK Workflow quand vous avez besoin de ce qu'il apporte vraiment : reprise d'un workflow interrompu, étapes d'approbation humaine, déploiement sur l'outillage ADK (interface de développement, évaluation, Agent Engine). Dans les deux cas, gardez hors du framework les consignes, schémas, contrôles et la grille.

Ce qui casse en production

  • Conclure sur une exécution. Ici, une exécution unique aurait « démontré » qu'ADK parallèle est le pire choix (69,2). Parade : au moins quelques passages par configuration, et toujours les valeurs individuelles à côté de la moyenne.
  • Mesurer le temps total seulement. On en conclurait que le parallélisme ne sert presque à rien, alors qu'il divise par 3 sa phase ; l'action utile (réduire la synthèse) resterait invisible. Parade : durée par phase dans le journal.
  • Oublier les prix qui changent. Le prix de gemini-3.8-flash double au 1er janvier 2027 selon la page tarifaire ; les coûts de ce tableau doubleront pour la moitié planification et synthèse. Parade : PRIX_JSON pour surcharger les prix, et un recalcul à partir des tokens enregistrés.
  • Une grille regex prise pour la vérité. Elle détecte « 340 ms » mais pas un dossier qui écrirait « 340 ms » comme latence d'Orvet. Parade : la grille compare les variantes entre elles ; une relecture humaine d'un échantillon reste nécessaire avant de publier un chiffre de qualité absolu.

La règle de décision

Parallélisez quand la phase des sous-agents domine le temps total ; sinon, optimisez d'abord la phase qui domine. Choisissez le modèle et le niveau de réflexion par rôle, et mesurez-les, avant de toucher à l'architecture. Décidez entre framework et code maison sur ce dont vous avez besoin en exploitation (reprise de sessions, approbations, outillage), pas sur le nombre de lignes. Ne publiez une différence de qualité qu'avec plusieurs passages par configuration.

Pratique

Un dossier plus large comptera 12 sous-tâches au lieu de 5, avec la même synthèse. En séquentiel, chaque sous-agent prend environ 4 s. Avec parallélisme 4, quelle est la durée attendue de la phase des sous-agents ?

Sur deux passages, la version à la main obtient 92,5 et 92,5, la version ADK 69,2 et 88,3. Votre manager veut écrire dans le compte rendu « la version à la main produit de meilleurs dossiers ». Que lui répondez-vous ?

Exercice. À partir des tokens mesurés, estimez le coût mensuel de 400 dossiers par mois avec la version à la main en parallèle, avant et après le 1er janvier 2027. Hypothèse : le passage 2 est représentatif. Lisez dans son journal.jsonl la part des appels gemini-3.8-flash.

Voir la solution

Passage 2 : 0,0398 autotal.Lesdeuxappels‘gemini−3.8−flash‘(planetsyntheˋse)totalisent6687tokensenentreˊeet4283ensortie:6687×0,75/106+4283×3,75/106≈0,0050+0,0161=0,0211au total. Les deux appels `gemini-3.8-flash` (plan et synthèse) totalisent 6 687 tokens en entrée et 4 283 en sortie : 6 687 × 0,75 / 10⁶ + 4 283 × 3,75 / 10⁶ ≈ 0,0050 + 0,0161 = 0,0211. Partie sous-agents : 0,0398 − 0,0211 ≈ 0,0187 $.

  • Jusqu'au 31 décembre 2026 : 400 × 0,0398 ≈ 16 $ par mois.
  • À partir du 1er janvier 2027 (prix gemini-3.8-flash doublés) : 400 × (0,0187 + 2 × 0,0211) ≈ 400 × 0,0609 ≈ 24 $ par mois.

Le coût n'est pas le sujet à ce volume ; la durée de la synthèse (20 à 30 s) l'est davantage si le dossier est demandé en direct. Commande pour extraire ces appels : jq 'select(.nom | startswith("appel gemini-3.8"))' sorties/main-parallele/journal.jsonl.

  • Je sais isoler une variable dans un banc d'essai d'agents
  • Je sais lire la durée par phase avant d'optimiser
  • Je sais dire ce que deux passages permettent de conclure, et ce qu'ils ne permettent pas
  • Je sais argumenter le choix entre code maison et ADK Workflow
  • make e2e écrit sorties/comparatif.json ; make clean supprime sorties/