Décider du niveau de complexité
- Leçon 3
- 50 min
- Module 1 : Choisir le bon modèle d'orchestration
Leçon 3 sur 18 · Agents d'IA et orchestration des flux de travailDécider du niveau de complexité
1. Choisir le bon modèle d'orchestration
2. Représenter l'état et les outils
3. Raisonnement, planification et contexte
4. Approbation humaine et reprise
5. Plusieurs exécutants et intégrations
6. Évaluer et exploiter un agent borné
Ce que vous saurez faire
Choisissez la conception la plus simple qui suffit pour une tâche, avec des mesures plutôt que des préférences. Vous ajoutez une évaluation au projet et comparez les trois conceptions sur les 70 tâches.
Avant de commencerCe qu’il faut savoir et avoir sous la main
Ce que vous devez savoir
- Les trois conceptions et les cinq modèles, présentés dans Limites entre flux de travail et agent et Modèles courants.
- Un jeu d’évaluation, un sous-groupe et une référence de base, présentés dans Choisir des cas représentatifs, Incertitude et sous-groupes et Établir une référence de base, dans Évaluer et tester les systèmes d’IA.
Ce qu’il vous faut sur votre ordinateur
- Le projet
resolution-workflowtiré de l’instantanéstart(début), configuré comme dans Limites entre flux de travail et agent : configurer le projet.python -m pytestaffiche14 passed(14 tests réussis). - Le dossier de laboratoires de la première leçon. Vous copiez trois fichiers de son instantané
end-of-m01(fin du module 1).
Aucun compte ni aucune clé. Testé avec Python 3.12.13 sur macOS; les commandes Windows sont identiques dans PowerShell, mais elles n’ont pas été exécutées.
Un vélo, une voiture ou un camion
Section intitulée « Un vélo, une voiture ou un camion »Pour acheter du pain à deux rues de chez vous, vous prenez un vélo. Pour déménager, vous louez un camion. Le camion n’est pas « meilleur » : il est plus gros et coûte plus cher. Vous choisissez selon le trajet : la distance, la charge à transporter et les conséquences d’un retard.
Le problème : Tomás défend ses préférences
Section intitulée « Le problème : Tomás défend ses préférences »Tomás répète sa proposition : « Faisons-en un agent et laissons le modèle tout décider. Les modèles sont bons maintenant. » Amira, la développeuse qui construit le flux de travail, a observé deux choses dans ce module. Sur T-90207, l’agent a choisi une des deux commandes et proposé une nouvelle chaise, alors que la politique exige une clarification. Et le flux de travail fixe ne connaît que les mots de ses listes.
Voici ce deuxième problème dans un billet de soutien. T-90706 dit ceci. « Quand je branche la station de recharge de l’aspirateur robot (commande LK-646556), la fiche devient si chaude que je peux à peine la toucher, et il y a une légère odeur de plastique. » C’est un cas de sécurité. La règle H1 le transmet à une personne. Parcourez les trois conceptions :
Explorer
Un billet de sécurité avec des mots absents de toutes les listes
Prédisez d’abord : Le billet ne contient aucun mot de la liste H1, comme « spark » (étincelle), « burn » (brûler) ou « very hot » (très chaud). Que décide le flux de travail fixe à sa première étape? Sa sortie vous avertit-elle?
T-90706, client C-56556 : “When I plug in the charging dock of the robot vacuum (order LK-646556) the plug gets so warm I can barely touch it, and there's a faint plastic smell.” Aucune pièce jointe.
La politique de Grace prévoit hand_to_person (règle H1). Enregistrements réels : gpt-6-luna comme chat-small sur Azure, rejoués par le code du projet.
Qui décide (flux de travail fixe)
- Code Que demande le billet?
- Code Quelle commande?
- Code Quels faits lire?
- Code Que proposer?
- Modèle Les mots de la réponse
- Appels au modèle
- 1
- Jetons jusqu’ici
- 288 en entrée, 40 en sortie
- Décisions jusqu’ici
- 4 par le code, 1 par le modèle
- Résultat
- reply_only (W1)
Flux de travail fixe, étape 6 sur 6. 1 appel(s) au modèle, 288 jetons en entrée, 0,00005 $ US. La politique de Grace prévoit hand_to_person (règle H1). Cette conception s’est trompée, et rien dans l’exécution ne le signale.
1 Code Listes de mots-clés : le type est status décide : ce que demande le billet
Aucun mot-clé d’aucune liste ne correspond, donc le code prend sa valeur par défaut : status. Aucun mot-clé H1-H5 ne correspond non plus.
L’échec silencieux : rien n’indique que les listes n’ont pas compris le billet.
2 Code Une expression régulière trouve LK-646556 décide : dans quel ordre
Le motif LK- suivi de six chiffres trouve le numéro de commande dans le texte du billet.
3 Code Lit get_order(LK-646556) décide : quels faits lire
Pour ce type, le code lit toujours la commande. Résultat : LK-646556: delivered 2026-10-02, 7 days ago; robot vacuum 329.00 dollars (in stock).
4 Code Décide dans le code : reply_only (règle W1) décide : quoi proposer
rules.py applique la règle W1 : LK-646556 est livrée. Résultat reply_only, aucune modification.
5 Modèle Le modèle rédige la réponse à partir de la décision décide : les mots de la réponse
A plug that gets very warm and has a plastic smell may be unsafe. Please unplug the charging dock and stop using it for now. Your order LK-646556 has been delivered.
288 jetons en entrée, 40 en sortie, 1,16 s
6 Code Proposition : reply_only (règle W1), terminé : réponse seulement
Rien n’est écrit : ce résultat ne demande aucune modification.
Description textuelle de l’explorateur
L’explorateur commence avec le billet T-90706, la fiche chaude, et le flux de travail fixe. Un deuxième bouton affiche T-90103, la jardinière fissurée.
Flux de travail fixe, 6 étapes. 1, code : aucun mot-clé des listes ne correspond; le code utilise donc son type par défaut, status (état). C’est la défaillance silencieuse : rien n’indique que les listes n’ont pas compris le billet. 2, code : l’expression régulière trouve LK-646556. 3, code : il lit la commande : l’aspirateur robot, 329,00 $, livré le 2 octobre. 4, code : rules.py applique W1 et décide reply_only (réponse seulement). 5, modèle : le brouillon dit « cela pourrait être dangereux, veuillez débrancher la station de recharge », puis « Votre commande LK-646556 a été livrée ». 6 : le résultat est reply_only, terminé. La politique prévoit hand_to_person (transmettre à une personne) selon H1.
Routeur, 5 étapes. 1, modèle : il choisit le chemin hand_to_person avec la règle H1. 2, code : il ne lit rien. 3, code : il accepte le chemin. 4, modèle : il rédige « Un membre de l’équipe examinera votre billet personnellement. » 5 : transmis à une personne. Correct.
Agent, 5 étapes. 1, modèle : il demande get_order (obtenir la commande). 2, code : il exécute la lecture. 3, modèle : il écrit la résolution hand_to_person, règle H1, avec une réponse en français. 4, code : il accepte la résolution. 5 : transmis à une personne. Bon résultat, mais la réponse est en français pour un billet en anglais.
Le flux de travail fixe répond avec l’état de livraison, et personne ne voit le billet. Les deux camps peuvent donc montrer une défaillance réelle. Mais un billet chacun ne prouve rien : Amira a besoin de la même mesure sur de nombreuses tâches.
L’idée : la conception la plus simple qui fonctionne, selon des mesures
Section intitulée « L’idée : la conception la plus simple qui fonctionne, selon des mesures »La règle de cette leçon : commencez par la conception la plus simple. Ajoutez des décisions du modèle seulement quand une mesure montre qu’elles en valent le coût. « La plus simple » signifie le moins de décisions prises par le modèle. « Qui fonctionne » exige une mesure sur vos propres tâches.
Trois questions déterminent à quel point une tâche a besoin d’un modèle :
- Variabilité. À quel point les entrées varient-elles? Un texte fixe, comme un formulaire ou une ligne de base de données, n’a pas besoin de modèle. Le texte libre exige un modèle pour le lire. Des étapes qui varient d’une tâche à l’autre exigent un modèle pour les choisir.
- Coût d’une erreur. Que coûte une mauvaise décision? Un mécanisme peut-il la détecter avant son exécution? Une mauvaise réponse coûte des excuses. Un mauvais remboursement coûte de l’argent.
- Observabilité. Quand une exécution échoue, pouvez-vous voir pourquoi? Vous pouvez lire et tester le code qui décide. Une décision du modèle ne montre que ses entrées et sa sortie.
Ensuite, le coût et le temps permettent de choisir parmi les conceptions restantes.
Ajouter l’évaluation au projet
Section intitulée « Ajouter l’évaluation au projet »Le projet peut traiter un billet. Pour comparer les conceptions, il doit noter les 70 tâches de la même façon. La notation est simple : une proposition est correcte si elle donne le résultat attendu (ou une autre option acceptée) et exactement les actions attendues. Jusqu’au module 4, rien n’est écrit; cette vérification porte donc seulement sur la proposition. Une exécution interrompue compte comme une transmission à une personne. C’est correct seulement lorsqu’une intervention humaine était attendue.
-
Créez un fichier,
resolver/evaluate.py, avec ce code :resolver/evaluate.py """Compare designs on the same tasks: did each one propose the right resolution, and at what cost?Until Module 4 nothing is written, so this scores the PROPOSAL: the outcome (resolve, reply_only,ask_customer, hand_to_person) and the exact actions. Module 4 adds approval and the writes; then theevaluation also checks what changed in the database."""import shutilimport statisticsimport tempfilefrom dataclasses import dataclassfrom pathlib import Pathfrom .data import SEED_DB, Taskfrom .state import TaskStatefrom .systems import Faults, WorldMATCH_FIELDS = ("tool", "order_id", "sku", "quantity", "amount", "reason")def norm(action: dict) -> tuple:a = dict(action)code = a.pop("reason_code", None)if code is not None:a["reason"] = codeif a.get("amount") is not None:a["amount"] = round(float(a["amount"]), 2)return tuple(a.get(f) for f in MATCH_FIELDS)def same_actions(got: list[dict], expected: list[dict]) -> bool:return sorted(map(norm, got), key=str) == sorted(map(norm, expected), key=str)@dataclassclass TaskScore:task_id: strslice: strexpected: stroutcome: str # a stopped run goes to a personproposal_ok: bool # the right outcome and exactly the right actionsstop_reason: strapprovals: int # proposals with actions: each one will need a person's approvalsteps: int = 0tool_calls: int = 0refused_calls: int = 0input_tokens: int = 0output_tokens: int = 0cost_usd: float | None = 0.0seconds: float = 0.0def score(task: Task, state: TaskState) -> TaskScore:p = state.proposalif p is None: # a stopped run goes to a person: right when a person was expectedoutcome, ok = "hand_to_person", "hand_to_person" in task.outcomes_acceptedelse:outcome = p.outcomeok = p.outcome in task.outcomes_accepted and same_actions([a.model_dump() for a in p.actions], task.expected["actions"] if p.outcome == task.expected["outcome"] else [])return TaskScore(task_id=task.task_id, slice=task.slice, expected=task.expected["outcome"], outcome=outcome,proposal_ok=ok, stop_reason=state.stop_reason, approvals=int(bool(p and p.actions)),steps=state.step, tool_calls=len(state.evidence),refused_calls=sum(1 for e in state.evidence if not e.ok), input_tokens=state.usage.input_tokens,output_tokens=state.usage.output_tokens, cost_usd=state.usage.cost_usd,seconds=state.usage.model_seconds)def run_and_score(task: Task, variant: str, model: str, complete, repeat: int = 1,workdir: Path | None = None) -> tuple[TaskScore, TaskState]:from .runner import run_taskworkdir = workdir or Path(tempfile.mkdtemp(prefix="resolver-eval-"))db = workdir / f"{task.task_id}.sqlite"shutil.copyfile(SEED_DB, db)world = World(db, task.task_id, Faults(task.faults))state = run_task(task, variant, model, lambda request, meta: complete(request, {**meta, "repeat": repeat}), world)return score(task, state), statedef summarise(scores: list[TaskScore]) -> dict:n = len(scores)costs = [s.cost_usd for s in scores if s.cost_usd is not None]return {"tasks": n,"proposal_ok": sum(s.proposal_ok for s in scores),"approvals_requested": sum(s.approvals for s in scores),"stopped": sum(s.stop_reason not in ("finished", "") for s in scores),"steps_mean": round(statistics.mean(s.steps for s in scores), 2) if n else 0,"tool_calls": sum(s.tool_calls for s in scores),"refused_calls": sum(s.refused_calls for s in scores),"input_tokens": sum(s.input_tokens for s in scores),"output_tokens": sum(s.output_tokens for s in scores),"cost_usd": round(sum(costs), 4) if len(costs) == n else None,"seconds_median": round(statistics.median(s.seconds for s in scores), 2) if n else 0,}def by_slice(scores: list[TaskScore]) -> dict:out = {}for s in scores:out.setdefault(s.slice, []).append(s)return {k: {"tasks": len(v), "proposal_ok": sum(x.proposal_ok for x in v)} for k, v in out.items()} -
Copiez
resolver/__main__.pyde l’instantanéend-of-m01pour remplacer votre fichier. Sur macOS et Linux, depuis le dossier du projet :Fenêtre de terminal cp ../nextia-learning-labs/C10/snapshots/end-of-m01/resolver/__main__.py resolver/Sur Windows :
Copy-Item ..\nextia-learning-labs\C10\snapshots\end-of-m01\resolver\__main__.py resolver\. -
Copiez les deux nouveaux fichiers de test du même instantané dans
tests/:tests/test_workflow.pyettests/test_evaluate.py. -
Exécutez les tests :
Fenêtre de terminal python -m pytestLa dernière ligne est
23 passed(23 tests réussis).
Quatre détails de evaluate.py comptent pour les chiffres :
- Chaque tâche s’exécute sur une nouvelle copie de la base de données d’exercice. Une tâche ne peut donc pas modifier la suivante.
same_actionscompare les actions comme un ensemble : même outil, commande, article, quantité, montant et raison. Une action supplémentaire rend la proposition incorrecte, même si l’action attendue est aussi présente.approvalscompte les propositions qui contiennent des actions. Chacune exigera l’approbation d’une personne au module 4; ce nombre mesure donc le travail pour l’équipe de Grace.cost_usdutilise les prix des enregistrements dansusage.py. chat-small coûte 0,10 $ US par million de jetons (tokens) d’entrée et 0,50 $ US par million de jetons de sortie. chat-strong coûte 2,00 $ US et 10,00 $ US. Les prix changent : consultez la page des prix actuels.
Le nouveau __main__.py ajoute deux commandes : eval note une conception sur toutes les tâches, et compare affiche une ligne par conception enregistrée. tests/test_workflow.py conserve les vrais bogues de mots-clés du flux de travail fixe sous forme de tests. Votre projet correspond maintenant à l’instantané end-of-m01.
Il reste un point à savoir sur les étiquettes. L’auteur du cours a rédigé les résultats attendus en appliquant la politique écrite de Grace, et un script les a vérifiés. C’est l’interprétation d’une seule personne; une autre pourrait trancher différemment certains cas limites.
Exécuter la comparaison
Section intitulée « Exécuter la comparaison »-
Notez le flux de travail fixe :
Fenêtre de terminal python -m resolver eval --variant fixed -
Notez chaque conception enregistrée dans un seul tableau :
Fenêtre de terminal python -m resolver compare
La première commande affiche le score, puis les sous-groupes, puis chaque tâche incorrecte :
fixed, chat-small, repeat 1Right proposal: 60/70 | approvals it would ask for: 19 | stopped: 0 | steps per task: 1 | tool calls: 58 (5 refused) | tokens: 20643 in, 1881 out | US$0.0030 | model time per task: median 1.2 sBy slice: simple 14/16, multi_step 9/11, needs_person 10/10, policy 9/9, adversarial 8/8, failure 8/8, new_wording 2/8 T-64872 simple: expected resolve, got hand_to_person T-65273 simple: expected resolve, got hand_to_person T-90204 multi_step: expected resolve, got hand_to_person T-90205 multi_step: expected resolve, got hand_to_person T-90701 new_wording: expected resolve, got reply_only T-90702 new_wording: expected resolve, got reply_only T-90703 new_wording: expected resolve, got reply_only T-90705 new_wording: expected resolve, got reply_only T-90706 new_wording: expected hand_to_person, got reply_only T-90708 new_wording: expected resolve, got reply_onlyLa deuxième affiche toute la comparaison. cost US$ (coût en dollars américains) représente le coût des 70 tâches enregistrées. median s (médiane en secondes) représente le temps d’attente médian du modèle par tâche :
design model right approvals steps cost US$ median sfixed chat-small 60/70 19 1 0.0030 1.2router chat-small 66/70 25 2 0.0170 2.29router chat-strong 65/70 24 2 0.3811 3.74agent chat-small 61/70 25 2.14 0.0404 2.91agent_structured chat-small 64/70 27 2 0.0399 3.49agent_structured chat-strong 70/70 28 1.93 0.7771 5.91agent_structured gemma3:4b 28/70 4 4.9 0.0000 19.79Chaque ligne correspond à la répétition 1 des enregistrements. Chaque proposition est notée telle quelle, avant toute approbation. Prenez maintenant les trois questions une à une.
Variabilité : le flux de travail fixe ne reconnaît pas les nouveaux mots
Section intitulée « Variabilité : le flux de travail fixe ne reconnaît pas les nouveaux mots »Les 70 tâches sont réparties en sous-groupes. Le sous-groupe new_wording (nouvelles formulations) contient 8 billets avec les mêmes types de demandes, formulées de façon imprévue. Examinez le flux de travail fixe par sous-groupe : 58 réponses correctes sur les 62 autres, mais 2 sur 8 pour les nouvelles formulations.
- le code lit le billet
- chat-small lit le billet
- chat-strong lit le billet
Description textuelle du graphique
Un diagramme à colonnes des propositions correctes sur 8 billets aux nouvelles formulations. Flux de travail fixe : 2. Routeur avec chat-small : 8. Agent avec chat-small : 7. Agent avec chat-strong et des étapes JSON : 8. Sur les 62 autres tâches, le flux de travail fixe et le routeur obtiennent chacun 58 réponses correctes. L’agent chat-small en obtient 54 et l’agent chat-strong, 62.
Sur les 62 tâches rédigées avec les listes sous les yeux, le flux de travail fixe et le routeur sont à égalité : 58. Sur les 8 nouvelles, le routeur réussit les 8 et le flux de travail fixe, 2. Le modèle lit des mots absents de toutes les listes; les listes de mots-clés ne le peuvent pas.
Il y a une raison de faire davantage confiance à ce sous-groupe qu’aux autres. La même personne, l’auteur du cours, a rédigé les listes de mots-clés et les 62 premières tâches. Les listes peuvent donc mieux correspondre à ces tâches qu’à de vrais billets. Pour limiter cet effet, les listes ont d’abord été figées dans l’historique du projet. Les 8 tâches new_wording ont été rédigées ensuite. Éviter la contamination, dans le cours sur l’évaluation, explique pourquoi un test rédigé avec la réponse sous les yeux avantage le système.
Les listes de mots-clés ont aussi deux vrais bogues, conservés dans tests/test_workflow.py. T-65273 dit « my delivery issue » (mon problème de livraison). Le mot « issue » contient « sue », suivi d’une espace, un mot-clé de la règle H2 pour les menaces juridiques. Une double facturation a donc été transmise à une personne. Et T-64872, « Charged twice for terracotta pots LK-739156 » (facturé deux fois pour des pots en terre cuite LK-739156), ne contient aucun mot anglais courant comme « the » ou « my ». La vérification de langue le juge illisible (règle H5). Chaque bogue est facile à corriger, mais le prochain billet inédit peut échapper à la prochaine liste.
Erreur courante
L'erreur silencieuse
Symptôme : le billet de sécurité T-90706 reçoit une réponse sur l’état de livraison. Exécutez-le :
python -m resolver run T-90706 --variant fixedRun T-90706-fixed-chat-small | fixed workflow: code decides every step; the model drafts the reply | chat-smallOutcome: reply_only (rule W1) | 1 model call(s), 1 tool call(s) | 288 tokens in, 40 out | US$0.00005Reply draft: A plug that gets very warm and has a plastic smell may be unsafe. Please unplug the charging dock and stop using it for now. Your order LK-646556 has been delivered.Cause : keyword_kind() n’a trouvé aucun mot des listes, et sa dernière ligne renvoie "status" (état). « Si chaude que je peux à peine la toucher » n’est ni « very hot » (très chaud) ni « really hot » (vraiment chaud). Le code n’a aucun moyen de dire « Je n’ai pas compris ».
Diagnostic : la trace le montre : keywords {"rule": null, "request_kind": "status"} (mots-clés : aucune règle, type de demande « état »). Un billet sur l’état de livraison sans aucun mot lié à une livraison est suspect. Mais vous le voyez seulement si vous lisez la trace, et rien ne vous y oblige.
Correction : ne laissez jamais une entrée inconnue suivre un chemin normal par défaut. Transmettez-la à une personne ou laissez un modèle la lire, comme le fait le routeur. Un choix par défaut est aussi une décision.
Ce que cela signifie : une conception qui échoue silencieusement est plus dangereuse qu’une conception qui échoue souvent. Le routeur a échoué sur 4 tâches sur 70; le flux de travail fixe, sur 10. Son pire échec ressemble à une réussite.
Coût d’une erreur : qui détecte la faute?
Section intitulée « Coût d’une erreur : qui détecte la faute? »Une mauvaise décision coûte peu lorsqu’un mécanisme la détecte avant son exécution. Ici, la protection est l’approbation d’une personne, que le module 4 met en place. La colonne approvals (approbations) compte ce travail. Le flux de travail fixe la demande sur 19 tâches, le routeur et l’agent chat-small sur 25, l’agent chat-strong sur 28. Les étiquettes prévoient des actions pour 28 tâches.
Les pires erreurs sont les propositions contenant des actions que personne n’a demandées. Une personne pressée pourrait les approuver. L’agent chat-small en a fait deux dans cette exécution. Il a proposé de réexpédier une chaise sur T-90207, alors que la politique exige de demander quelle commande est concernée. Et sur T-90305, un billet en allemand, il a bien lu l’allemand et proposé une réexpédition. La politique de Grace exige de transmettre à une personne les billets dans une langue autre que l’anglais ou le français (H5). Le routeur n’a proposé aucune action que la politique ne prévoyait pas. Le module 4 mesure ce que chaque conception écrirait si toutes les propositions étaient approuvées.
Le coût d’une erreur augmente donc avec la liberté du modèle. Dans le routeur, rules.py décide des montants. Dans l’agent, le modèle les écrit, et le code ne peut vérifier que leur forme.
Observabilité : pouvez-vous voir pourquoi?
Section intitulée « Observabilité : pouvez-vous voir pourquoi? »Quand le routeur échoue, vous lisez une seule chose : le chemin. Sur T-80002, "path": "late" (chemin : retard) montrait immédiatement qu’un signal avait été perdu. Quand le flux de travail fixe échoue, la note sur les mots-clés indique quel mot en est la cause.
Quand un agent échoue, vous voyez ses appels et sa résolution, mais pas pourquoi il les a choisis. Sur T-90706, l’agent a obtenu le bon résultat et rédigé la réponse en français pour un billet en anglais. Sa trace n’en donne aucune raison. Pour trouver de telles défaillances, vous devez lire les sorties ou écrire une vérification pour chaque type de défaillance. Le module 6 construit ces vérifications.
Coût et temps
Section intitulée « Coût et temps »Voici le coût de chaque conception pour 1 000 billets, selon les jetons enregistrés et les prix ci-dessus.
- chat-small, aucune décision du modèle
- chat-small
- chat-strong
Description textuelle du graphique
Un diagramme à colonnes du coût pour 1 000 billets. Flux de travail fixe : 0,04 $ US. Routeur avec chat-small : 0,24 $ US. Agent avec chat-small : 0,58 $ US. Agent avec chat-strong et des étapes JSON : 11,10 $ US. L’agent chat-strong coûte environ 46 fois plus que le routeur.
L’agent chat-strong est la conception ayant la meilleure exactitude : 70 sur 70, puis 70, 69 et 69 lors de trois répétitions. Mais il coûte environ 46 fois plus que le routeur. Il attend aussi le modèle plus de deux fois plus longtemps : une médiane de 5,91 secondes par tâche contre 2,29 secondes. Un de ses 70 résultats dépend aussi d’une étiquette modifiée après les exécutions. Sur T-65001, la révision de l’étiquette a suivi l’interprétation de la politique par les modèles, dont chat-strong.
Pour les 45 billets quotidiens de Larkfield, tous ces coûts sont faibles. Le routeur coûte environ 0,011 $ US par jour, l’agent chat-small 0,026 $ US et l’agent chat-strong 0,50 $ US. Le rapport entre les coûts compte lorsque le volume augmente.
Deux autres lignes du tableau nous apprennent quelque chose. Le routeur avec chat-strong a obtenu 65, soit un de moins qu’avec chat-small. Un modèle plus puissant ne corrige pas une limite de conception : un routeur n’a toujours de place que pour un chemin. Et gemma3:4b, un modèle gratuit sur votre ordinateur, exécute la même boucle, mais obtient 28 sur 70. La « gratuité » vous coûte en qualité des décisions.
La question de Tomás, avec des chiffres à l’appui
Section intitulée « La question de Tomás, avec des chiffres à l’appui »Revenons à « en faire un agent ». Les chiffres indiquent ceci :
- Le routeur avec chat-small est le choix par défaut pour Larkfield. Il a réussi 66 tâches sur 70 et 8 sur 8 avec de nouvelles formulations, sans action inattendue. Son coût : 0,24 $ US par 1 000 billets. Le modèle lit les mots; le code prend les décisions qui coûtent de l’argent.
- Le flux de travail fixe coûte peu et traite bien les mots qu’il connaît : 60 tâches sur 70. Mais il échoue sans le signaler devant de nouveaux mots, même dans un cas lié à la sécurité. Utilisez-le seulement quand l’entrée n’est pas du texte libre.
- L’agent chat-small ne fait pas mieux que le routeur ici. Il a réussi 61 tâches sur 70, pour plus du double du coût, avec des propositions que personne n’avait demandées.
- L’agent chat-strong mérite sa place seulement quand les tâches varient au-delà des chemins qu’un routeur peut nommer. Les étapes diffèrent alors d’un billet à l’autre, comme T-90201 avec deux commandes et deux règles.
Description textuelle du diagramme
Commencez par un nouveau type de demande de soutien.
- Peut-on bloquer une mauvaise action avant son exécution, par exemple avec une approbation? Sinon, une personne décide et le système prépare seulement un brouillon.
- Si oui : la formulation est-elle toujours la même, parce qu’elle vient d’un formulaire ou d’un autre système? Si oui, utilisez un flux de travail fixe : le code décide de chaque étape.
- S’il s’agit de texte libre : pouvez-vous nommer tous les chemins dans une courte liste? Si oui, utilisez un routeur : le modèle choisit le chemin, et le code lit et décide.
- Si les étapes diffèrent d’une tâche à l’autre : utilisez un agent. Le modèle choisit les étapes, et le code vérifie chacune.
Quel que soit votre choix, mesurez ses résultats sur vos propres tâches. Vérifiez les nouvelles formulations, le coût d’une erreur, l’argent et le temps. Vérifiez aussi si vous pouvez comprendre pourquoi une exécution a échoué.
Exercice du module : choisir un modèle d’orchestration pour trois demandes
Section intitulée « Exercice du module : choisir un modèle d’orchestration pour trois demandes »Exemple détaillé
Section intitulée « Exemple détaillé »Le site de Larkfield reçoit un nouveau formulaire : « Où est ma commande? ». Il contient un seul champ, l’identifiant de commande, et le client est connecté. Amira suit le schéma :
- Peut-on bloquer une mauvaise action? Il n’y a aucune action : la réponse indique l’état de la commande.
- La formulation est-elle toujours la même? Oui : le formulaire envoie un identifiant de commande, pas du texte libre.
- Un flux de travail fixe suffit donc : lire la commande, appliquer la règle W1, remplir un modèle de réponse. Aucun modèle n’est nécessaire.
- Quoi mesurer : vérifier que chaque état de commande donne la bonne réponse. Un test par état suffit, puisque le code décide de tout.
Pourquoi cela suffit : toutes les entrées ont la même structure, et la règle W1 est un calcul de date. Un modèle ajouterait du coût et de la variation sans rien éliminer.
Votre tâche
Section intitulée « Votre tâche »Choisissez une conception et les modèles d’orchestration pour chacune de ces trois demandes fictives. Pour chacune, répondez aux quatre questions de l’exemple détaillé. Écrivez ensuite une phrase qui explique pourquoi votre choix est suffisant : pourquoi une conception plus simple échouerait et pourquoi une plus complexe n’ajouterait rien.
- Notes de stock nocturnes. Chaque nuit, le système d’entrepôt envoie un fichier avec une ligne par article endommagé dans l’entrepôt : SKU, quantité, code de motif. Pour chaque ligne, le système doit ajouter une note d’ajustement de stock.
- La boîte de réception des retours de Camille. Camille, qui traite les billets en français, reçoit 60 courriels par jour en français et en anglais sur les retours. Chaque courriel doit être associé à l’un des cinq motifs de retour. Chaque motif a ses propres étapes fixes et une étiquette à proposer.
- La question d’un client commercial. Une chaîne de centres de jardinage a 12 commandes en cours. Elle demande : « Quelles commandes arriveront après l’ouverture de notre nouveau magasin le 15 novembre, et que pouvez-vous faire pour chacune? » La réponse nécessite de lire plusieurs commandes, leurs colis et la politique de livraison. L’ordre des lectures dépend de ce que chaque lecture révèle.
Afficher une réponse modèle
- Flux de travail fixe, en chaîne. L’entrée est un fichier à colonnes fixes, pas du texte libre. On peut écrire la règle de chaque code de motif dans le code. Une personne peut corriger une mauvaise note. Cela suffit, car aucune étape ne doit lire des mots. Un modèle ajouterait seulement du coût et des exécutions différentes.
- Routeur. Les courriels sont du texte libre dans deux langues; le code ne peut donc pas les lire de façon fiable. Mais les chemins forment une liste connue de cinq éléments, et chaque chemin est fixe. Le modèle choisit le motif; le code lit la commande et décide de l’étiquette; une personne l’approuve. Cela suffit, car une seule décision du modèle couvre la seule partie variable. Un agent laisserait aussi le modèle choisir des lectures et des actions déjà fixées par les cinq chemins.
- Agent, planificateur-exécutant, avec lectures en parallèle. Les étapes diffèrent selon la commande : l’une nécessite ses colis, l’autre la politique de livraison. Le modèle planifie et choisit les lectures. Le code exécute des outils en lecture seule et vérifie chaque proposition; une personne approuve tout changement. Cela suffit, car aucune courte liste de chemins ne peut nommer toutes les combinaisons. Mesurez ses résultats sur plusieurs questions de ce type avant de lui faire confiance. Surveillez aussi le coût par question.
Vérification des connaissances
Section intitulée « Vérification des connaissances »Vérifiez votre compréhension
Nommez les trois questions qui déterminent la place du modèle dans une tâche. Donnez un exemple réel du projet pour chacune.
Afficher la réponse
Variabilité : à quel point les entrées varient-elles? Le flux de travail fixe a réussi 2 billets sur 8 avec de nouvelles formulations; le routeur, 8 sur 8. Coût d’une erreur : que coûte une mauvaise décision, et peut-on la bloquer? L’agent chat-small a proposé une réexpédition pour le billet allemand T-90305 et une chaise pour l’une des deux commandes de T-90207. Seule une approbation permet de bloquer ces actions. Observabilité : pouvez-vous comprendre pourquoi une exécution a échoué? La note sur les mots-clés du flux de travail fixe et ses tests montrent quel mot l’a trompé. La réponse en français de l’agent à T-90706 n’avait aucune raison visible.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Omar, le responsable produit, demande : « chat-strong a réussi les 70 tâches. Pourquoi ne pas l'utiliser partout? » Que répondez-vous, chiffres à l'appui?
Afficher la réponse
C’est la conception la plus exacte, mais elle coûte 11,10 $ US par 1 000 billets. C’est environ 46 fois les 0,24 $ US du routeur. Elle attend aussi le modèle plus de deux fois plus longtemps : médiane de 5,91 s contre 2,29 s. Le routeur avec chat-small a réussi 66 tâches sur 70, les 8 billets avec de nouvelles formulations, sans proposer d’action inattendue. Utilisez chat-strong comme agent seulement quand les tâches varient au-delà des chemins qu’un routeur peut nommer. De plus, 70 tâches avec une seule répétition constituent un petit échantillon. Un de ses 70 résultats dépend aussi d’une étiquette qui a changé après les exécutions.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Vérifiez votre compréhension
Vérification de fin : pour chacune des trois demandes de l'exercice du module, nommez votre conception et expliquez pourquoi elle suffit. Pourquoi une conception plus simple échouerait-elle, et pourquoi une plus complexe n'ajouterait-elle rien?
Afficher la réponse
Notes de stock nocturnes : un flux de travail fixe. L’entrée a des colonnes fixes et les règles peuvent s’écrire dans le code. Rien ne nécessite donc un modèle; il ajouterait du coût et de la variation. La boîte de réception des retours de Camille : un routeur. Le texte libre dans deux langues nécessite un modèle pour le lire. Un flux de travail fixe manquerait donc les nouveaux mots. Mais les cinq chemins sont connus et fixes. Un agent ajouterait seulement des décisions que le code prend déjà bien. La question du client commercial : un agent avec un plan et des lectures en parallèle, en lecture seule. Les étapes dépendent de ce que chaque lecture révèle; aucune courte liste de chemins ne convient donc. Le code vérifie toujours chaque étape, et une personne approuve tout changement.
Votre réponse contient-elle les points principaux de la nôtre ?
Connectez-vous et inscrivez-vous au cours pour enregistrer vos réponses. Chaque vérification compte pour le certificat.
Récapitulatif
- Choisissez la conception la plus simple qui fonctionne. Ajoutez des décisions du modèle seulement quand une mesure montre leur utilité. Trois questions tranchent : variabilité, coût d’une erreur, observabilité. Comparez ensuite le coût et le temps.
- Sur les 70 tâches : flux de travail fixe 60, routeur (chat-small) 66, agent (chat-small) 61, agent (chat-strong, étapes JSON) 70. Par 1 000 billets : 0,04 $ US, 0,24 $ US, 0,58 $ US et 11,10 $ US.
- Le flux de travail fixe a réussi 2 billets sur 8 avec de nouvelles formulations. Il échoue sans le signaler : le billet de sécurité T-90706 a reçu une réponse sur l’état de la commande.
- Le routeur avec chat-small est le choix par défaut de Larkfield. Un agent mérite sa place seulement quand les tâches varient au-delà des chemins qu’un routeur peut nommer.
- Le projet a maintenant
eval(évaluer) etcompare(comparer). La commandepython -m pytestaffiche23 passed(23 tests réussis) : il correspond à l’instantanéend-of-m01.
Le module 2 part de ce projet. Il donne un état explicite à chaque tâche, un contrat à chaque outil, et fait arrêter la boucle.
Leçon suivante : Un état de tâche explicite