SPB Git

Repository Public Research preview

ch02_anatomie.tex 35.6 KB 449 lines latex

1% ------------------------------------------------------------------------------2\section{Anatomie d'un agent : les mécanismes}3\label{sec:anatomie}4% ------------------------------------------------------------------------------56\begin{enbref}7Le mécanisme complet d'un agent, schéma par schéma : la boucle, les cinq couches, un appel d'outil vu de l'intérieur, la fenêtre de contexte, le flux de permissions, les sous-agents, le protocole MCP, une tâche en séquence, puis les patrons d'orchestration et les modes de défaillance. Comprendre ce chapitre, c'est savoir où et pourquoi un agent se trompe, et comment le tenir.8\end{enbref}910Ce chapitre ouvre le capot. Comprendre le mécanisme n'est pas un luxe de programmeur : c'est ce qui vous permet de prévoir \emph{où} un agent se trompe, \emph{pourquoi} il « oublie » une consigne, et \emph{comment} le tenir en laisse. Tout ce qui suit s'applique à Claude Code, Codex, Cursor, Copilot, Gemini CLI et aux modes Agent d'Excel : les noms changent, l'architecture est la même.1112\subsection{La boucle agentique}13\label{sec:boucle}1415Un agent n'est rien d'autre qu'un modèle de langage placé dans une \textbf{boucle} : à chaque tour, le modèle lit tout le contexte accumulé, décide soit de répondre, soit d'appeler un outil ; le résultat de l'outil est ajouté au contexte, et le tour suivant commence. La boucle s'arrête quand le modèle juge la tâche terminée, ou quand un critère de vérification est satisfait.1617\begin{figure}[!htb]18\centering19\begin{tikzpicture}20  % Vous, à gauche21  \node[blocfonce,text width=2.3cm] (user) at (0,0) {\faIcon{user}\\ Vous\\ {\normalfont\footnotesize objectif,\\ validation}};22  % Fenêtre de contexte : trois blocs empilés dans un conteneur23  \node[bloc,text width=3.3cm] (hist) at (4.7,0) {\faIcon{comments}~Historique\\ {\footnotesize vos messages, ses réponses}};24  \node[bloc,text width=3.3cm,above=0.25cm of hist] (sys) {\faIcon{scroll}~Instructions système\\ {\footnotesize + \texttt{CLAUDE.md} / \texttt{AGENTS.md}}};25  \node[bloc,text width=3.3cm,below=0.25cm of hist] (res) {\faIcon{inbox}~Résultats d'outils\\ {\footnotesize fichiers lus, sorties de commandes}};26  \begin{scope}[on background layer]27    \node[conteneur,fit=(sys)(hist)(res),label={[etiq,anchor=south]north:\textbf{Fenêtre de contexte} (ce que le modèle « voit »)}] (ctx) {};28  \end{scope}29  % Modèle et décision30  \node[blocfonce,text width=2.2cm,fill=uqoViolet,draw=uqoViolet] (llm) at (9.1,0) {\faIcon{brain}\\ Modèle\\ {\normalfont\footnotesize LLM}};31  \node[losange,text width=1.6cm] (dec) at (12.4,0) {Appel\\ d'outil ?};32  % Rangée du bas : garde-fous puis outil ; rangée du haut : réponse finale33  \node[blocrouge,text width=2.9cm] (guard) at (12.4,-2.7) {\faIcon{shield-alt}~Garde-fous\\ {\footnotesize permissions · approbation\\ hooks · bac à sable}};34  \node[blocor,text width=2.7cm] (tool) at (9.1,-2.7) {\faIcon{tools}~Outil\\ {\footnotesize lire · écrire · terminal\\ navigateur · MCP}};35  \node[blocvert,text width=2.7cm] (rep) at (12.4,2.7) {\faIcon{flag-checkered}~Réponse finale\\ {\footnotesize + preuves}};36  % flèches37  \draw[flb] (user.east) -- (hist.west) node[midway,etiq,above] {objectif};38  \draw[flb] (ctx.east) -- (llm.west) node[midway,etiq,above] {lit tout};39  \draw[flb] (llm.east) -- (dec.west);40  \draw[flo] (dec.south) -- (guard.north) node[midway,etiq,right] {oui};41  \draw[flo] (guard.west) -- (tool.east) node[midway,etiq,above] {autorisé};42  \node[etiq,anchor=north,text=uqoRouge,text width=3.6cm,align=center] at ($(guard.south)+(0,-0.08)$) {\faIcon{ban}~refusé : le modèle en est informé et reprend la boucle};43  \draw[flo] (tool.west) -| ($(res.east)+(0.7,0)$) -- (res.east);44  \node[etiq,anchor=north east,align=right,text width=3.2cm] at ($(tool.west)+(-0.15,-0.05)$) {résultat ajouté\\ au contexte \faIcon{redo}};45  \draw[fl] (dec.north) -- (rep.south) node[midway,etiq,right] {non};46  \draw[fl] (rep.north) -- ++(0,0.55) -| (user.north);47  \node[etiq,anchor=south] at (6.2,3.95) {réponse et preuves : vous relisez, vous décidez};48\end{tikzpicture}49\caption{La boucle agentique : le modèle lit tout le contexte, décide, appelle un outil ; le résultat revient dans le contexte}\label{fig:boucle}50\end{figure}5152Trois conséquences pratiques découlent directement de ce schéma.5354\begin{enumerate}[label=\textbf{\arabic*.},leftmargin=2em]55  \item \textbf{Tout ce que l'agent lit entre dans le contexte.} Un fichier de 2\,000 lignes, une sortie de commande verbeuse, une page Web : chacun occupe des jetons et dilue vos consignes. D'où les règles « un dossier par travail » et « scoper les explorations ».56  \item \textbf{Le modèle ne voit que du texte.} Il ne distingue pas structurellement une instruction de vous d'une instruction cachée dans un PDF qu'il vient de lire. C'est la racine de l'injection de requête (§\ref{sec:securite}).57  \item \textbf{La boucle s'arrête quand « ça a l'air fini ».} Sans critère de vérification que l'agent peut exécuter lui-même (un test, une comparaison de totaux), c'est vous qui devenez la boucle de vérification, une erreur à la fois \parencite{claudecode_bestpractices}.58\end{enumerate}5960\subsection{Les cinq couches}6162Il est commode de voir un système agentique comme cinq couches empilées. Les instructions descendent, les observations remontent, et chaque couche peut bloquer ce qui la traverse.6364\begin{figure}[!htb]65\centering66\resizebox{\linewidth}{!}{%67\begin{tikzpicture}[couche/.style={draw=uqoBleu,thick,rounded corners=3pt,text width=11.4cm,minimum height=1.05cm,anchor=north west,align=left,font=\small\sffamily,inner xsep=10pt}]68  \node[couche,fill=uqoBleu,text=white] (c1) at (0,0) {\textbf{\faIcon{user}~1. Vous} \quad intention, choix, validation, responsabilité, signature};69  \node[couche,fill=uqoBleu!25,below=0.15cm of c1.south west,anchor=north west] (c2) {\textbf{\faIcon{cogs}~2. Harnais} (Claude Code, Codex, Cursor, Copilot…) \quad boucle, permissions, hooks, mémoire, compaction, sous-agents};70  \node[couche,fill=uqoViolet!15,draw=uqoViolet,below=0.15cm of c2.south west,anchor=north west] (c3) {\textbf{\faIcon{brain}~3. Modèle} (Claude, GPT, Gemini…) \quad raisonnement, langage, décision d'appeler un outil};71  \node[couche,fill=uqoOr!15,draw=uqoOr!80!black,below=0.15cm of c3.south west,anchor=north west] (c4) {\textbf{\faIcon{tools}~4. Outils} \quad fichiers, terminal, navigateur, exécution de code, connecteurs MCP};72  \node[couche,fill=black!6,draw=uqoGris,below=0.15cm of c4.south west,anchor=north west] (c5) {\textbf{\faIcon{globe}~5. Monde} \quad votre dossier de TP, votre classeur Excel, le Web, les portails de données};73  \draw[flb,line width=1.2pt] ([xshift=0.5cm]c1.south east) -- ([xshift=0.5cm]c5.north east) node[midway,right,etiq,align=left] {instructions\\ descendent};74  \draw[flo,line width=1.2pt] ([xshift=-0.5cm]c5.north west) -- ([xshift=-0.5cm]c1.south west) node[midway,left,etiq,align=right] {observations\\ remontent};75\end{tikzpicture}}76\caption{Les cinq couches d'un système agentique : les instructions descendent, les observations remontent}\label{fig:couches}77\end{figure}7879Retenez la place du \textbf{harnais} (couche 2) : c'est là que vivent tous les garde-fous, et c'est la couche que vous configurez. Le modèle (couche 3) est le même que dans le chatbot ; ce qui rend l'outil « agent », c'est le harnais qui lui donne des outils et une boucle.8081\subsection{Un appel d'outil, concrètement}82\label{sec:toolcall}8384Quand le modèle décide d'agir, il n'exécute rien lui-même : il émet un \textbf{message structuré} (nom de l'outil, arguments) que le harnais intercepte, soumet aux garde-fous, exécute, puis dont il renvoie le résultat sous forme de texte. Voici, simplifié, ce qui circule pendant une étape de l'exemple du chapitre~\ref{sec:agents} :8586\begin{terminal}[Un tour de boucle, vu de l'intérieur (simplifié)]87\begin{Verbatim}[commandchars=§¡¿]88§tu¡[Vous]¿        Lis ventes.csv et décris-moi les colonnes et les valeurs suspectes.89              Ne modifie rien.9091§hi¡[Modèle → harnais]¿   §co¡appel d'outil¿92              { "tool": "Read", "args": { "path": "ventes.csv" } }9394§gris¡[Harnais]¿     vérifie : mode plan ? lecture seule → §ok¡autorisé sans demander¿95              exécute la lecture, tronque à 2 000 lignes, renvoie le texte9697§gris¡[Harnais → modèle]¿   §co¡résultat d'outil¿98              "id,prix,date_vente,sup_hab_pi2,terrain_pi2,age,garage,secteur99               1,612000,2026-03-14,1480,6200,31,1,Aylmer100               2,58900,2026-01-08,1390,5800,28,0,Aylmer    §ko¡← prix suspect (58 900 $)¿101               ..."102103§hi¡[Modèle → harnais]¿   §co¡appel d'outil¿104              { "tool": "Bash", "args": { "command": "python3 -c \"import pandas as pd; …describe()\"" } }105106§gris¡[Harnais]¿     vérifie : commande shell → §ko¡DEMANDE VOTRE APPROBATION¿ (mode manuel)107§tu¡[Vous]¿        approuve108§gris¡[Harnais]¿     exécute dans le bac à sable, renvoie la sortie109110§ok¡[Modèle → vous]¿   §co¡réponse¿111              "Le fichier compte 30 lignes et 8 colonnes. Deux anomalies : la vente 2112               affiche 58 900 $ (probable faute de saisie pour 589 000 $) ; la vente 17113               date de 2023, hors période. Aucune valeur manquante. Je n'ai rien modifié."114\end{Verbatim}115\end{terminal}116117Ce qu'il faut voir : (a) l'agent \emph{demande} l'exécution, le harnais \emph{décide} ; (b) une lecture seule passe sans question en mode plan, une commande shell non ; (c) le résultat revient sous forme de texte que le modèle doit à nouveau interpréter, avec les risques d'erreur que cela suppose ; (d) la « valeur suspecte » repérée est une hypothèse du modèle, pas un fait : c'est à vous de vérifier la vente 2.118119\subsection{La fenêtre de contexte, ressource numéro un}120\label{sec:contexte}121122La documentation de Claude Code le dit sans détour : « la fenêtre de contexte est la ressource la plus importante à gérer », et « la performance se dégrade à mesure qu'elle se remplit » \parencite{claudecode_bestpractices}. Voici à quoi ressemble, typiquement, le contexte après une heure de travail sur un TP sans discipline :123124\begin{figure}[!htb]125\centering126\begin{tikzpicture}127  \def\w{16}128  \def\h{1.05}129  \fill[uqoBleu] (0,0) rectangle (\w*0.04,\h);130  \fill[uqoTeal!70] (\w*0.04,0) rectangle (\w*0.12,\h);131  \fill[uqoOr!70] (\w*0.12,0) rectangle (\w*0.50,\h);132  \fill[uqoOrange!70] (\w*0.50,0) rectangle (\w*0.80,\h);133  \fill[uqoViolet!45] (\w*0.80,0) rectangle (\w*0.93,\h);134  \fill[white] (\w*0.93,0) rectangle (\w,\h);135  \draw[uqoGris,thick] (0,0) rectangle (\w,\h);136  \node[font=\tiny\sffamily\bfseries,text=white,rotate=90] at (\w*0.02,\h/2) {4\,\%};137  \node[font=\tiny\sffamily\bfseries,text=white] at (\w*0.08,\h/2) {8\,\%};138  \node[font=\footnotesize\sffamily\bfseries,text=white] at (\w*0.31,\h/2) {fichiers lus en entier : 38\,\%};139  \node[font=\footnotesize\sffamily\bfseries,text=white] at (\w*0.65,\h/2) {sorties de commandes : 30\,\%};140  \node[font=\tiny\sffamily\bfseries,text=white] at (\w*0.865,\h/2) {échanges 13\,\%};141  \node[font=\tiny\sffamily] at (\w*0.965,\h/2) {libre};142  \node[etiq,anchor=north west,align=left,text width=15.8cm] at (0,-0.12) {\textcolor{uqoBleu}{\rule{6pt}{6pt}} instructions système + \texttt{CLAUDE.md}\quad \textcolor{uqoTeal!70}{\rule{6pt}{6pt}} énoncé du TP\quad \textcolor{uqoOr!70}{\rule{6pt}{6pt}} fichiers lus\quad \textcolor{uqoOrange!70}{\rule{6pt}{6pt}} sorties de commandes\quad \textcolor{uqoViolet!45}{\rule{6pt}{6pt}} conversation};143  \draw[flr,line width=1pt] (\w*0.12,\h+0.18) -- (\w*0.80,\h+0.18) node[midway,above,font=\footnotesize\sffamily\color{uqoRouge},text width=10cm,align=center] {68\,\% de « bruit » : vos consignes du début ne pèsent plus que 4\,\%};144\end{tikzpicture}145\caption{La fenêtre de contexte après une heure de travail sans discipline : les consignes ne pèsent plus que 4\,\%}\label{fig:contexte}146\end{figure}147148Trois mécanismes du harnais luttent contre cette dérive, et trois gestes de votre part les complètent.149150{\small\Needspace{9\baselineskip}151\begin{tabularx}{\textwidth}{E{3.4cm}XX}152\caption{Gérer la fenêtre de contexte : mécanismes du harnais et gestes de l'utilisateur}\label{tab:contexte}\\153\rowcolor{uqoBleu} \hc{Mécanisme} & \hc{Ce que fait le harnais} & \hc{Ce que vous faites} \\154\endfirsthead155\captionsuite{Gérer la fenêtre de contexte : mécanismes du harnais et gestes de l'utilisateur}156\rowcolor{uqoBleu} \hc{Mécanisme} & \hc{Ce que fait le harnais} & \hc{Ce que vous faites} \\157\endhead158\suitepage{3}159\endfoot160\finTableau161\endlastfoot162Compaction & Quand le contexte approche la limite, résume automatiquement l'historique en gardant décisions et fichiers clés (\texttt{/compact} pour le forcer). & Indiquer dans \texttt{CLAUDE.md} ce qui doit survivre au résumé (« toujours conserver la liste des fichiers modifiés et la valeur de $B$ »). \\163\rowcolor{uqoBgClair}164Sous-agents & Délègue une exploration à une instance séparée qui ne rapporte qu'un résumé (§\ref{sec:sousagents}). & Demander « utilise un sous-agent pour explorer X » quand la recherche va lire beaucoup de fichiers. \\165Points de restauration & Chaque requête crée un point de contrôle ; \texttt{/rewind} restaure la conversation, les fichiers, ou les deux. & Essayer une approche, revenir en arrière si elle échoue, au lieu d'accumuler des corrections. \\166\rowcolor{uqoBgClair}167Nouvelle session & \texttt{/clear} vide le contexte. & Après deux corrections infructueuses : recommencer avec une requête qui intègre ce que vous avez appris. \\168\end{tabularx}169}170171\subsection{Le fichier d'instructions et la mémoire}172173Au démarrage de chaque session, le harnais lit le fichier d'instructions du projet (\texttt{CLAUDE.md}, \texttt{AGENTS.md}, \texttt{GEMINI.md}, \texttt{.cursor/rules}) et l'injecte dans le contexte, au même niveau que les instructions système. C'est donc la \textbf{première chose que le modèle lit}, à chaque fois, sans que vous ayez à la répéter. Le format \texttt{AGENTS.md} est un standard ouvert reconnu par Codex, Gemini CLI, Copilot, Cursor, VS Code, Jules et une soixantaine de milliers de projets \parencite{agentsmd}.174175Deux règles de conception, tirées de la documentation officielle \parencite{claudecode_bestpractices} : (1) n'y mettre que ce que l'agent ne peut pas deviner en lisant les fichiers (conventions du cours, cellules à ne pas toucher, sources autorisées) ; (2) le garder court, car « un fichier trop long fait que Claude en ignore la moitié ». L'annexe~\ref{ann:claudemd} donne un modèle complet.176177{\small\Needspace{9\baselineskip}178\begin{tabularx}{\textwidth}{XX}179\caption{Fichier d'instructions : ce qu'il faut y mettre, ce qu'il faut en exclure}\label{tab:claudemd}\\180\rowcolor{uqoBleu} \hc{\faIcon{check}~À inclure} & \hc{\faIcon{times}~À exclure} \\181\endfirsthead182\captionsuite{Fichier d'instructions : ce qu'il faut y mettre, ce qu'il faut en exclure}183\rowcolor{uqoBleu} \hc{\faIcon{check}~À inclure} & \hc{\faIcon{times}~À exclure} \\184\endhead185\suitepage{2}186\endfoot187\finTableau188\endlastfoot189Conventions du cours qui diffèrent des conventions génériques (profit séparé, terrain non déprécié, arrondi au 5\,000\,\$) & Ce que l'agent peut lire lui-même dans l'énoncé ou le classeur \\190\rowcolor{uqoBgClair}191Fichiers à ne jamais écraser ; cellules d'entrée & Descriptions détaillées feuille par feuille \\192Comment vérifier (changer $B$, comparer les totaux) & Tutoriels, longues explications \\193\rowcolor{uqoBgClair}194Interdits absolus (pas de valeurs collées à la place de formules ; pas de Web sans demande) & Évidences (« fais du bon travail ») \\195\end{tabularx}196}197198\subsection{Permissions, bac à sable et hooks : le flux d'une action}199200Chaque action proposée par le modèle traverse une chaîne de décisions avant de toucher votre disque. Les noms varient (Claude Code parle de \emph{permission modes} et de \emph{hooks}, Codex de \emph{approval modes} et de \emph{sandbox}), la logique est identique.201202\begin{figure}[!htb]203\centering204\resizebox{\linewidth}{!}{%205\begin{tikzpicture}[node distance=0.5cm and 0.8cm]206  % Rangée 1 : décisions207  \node[blocfonce,fill=uqoViolet,draw=uqoViolet,text width=2.6cm] (a) {Le modèle propose\\ une action};208  \node[losange,right=of a,text width=1.9cm] (d1) {Mode\\ plan ?};209  \node[losange,right=of d1,text width=2.1cm] (d2) {Règle\\ d'autorisation ?};210  \node[losange,right=of d2,text width=2.1cm] (d3) {Vous\\ approuvez ?};211  \node[blocgris,text width=2.6cm,above=0.6cm of d1] (plan) {Lecture seule :\\ écriture \textbf{refusée}};212  \node[blocrouge,text width=2.6cm,above=0.6cm of d3] (ref) {Action \textbf{bloquée}};213  \node[etiq,above=0.15cm of plan,text width=5.5cm] {le modèle est informé du refus et reprend la boucle};214  \node[etiq,above=0.15cm of ref,text width=4cm] {idem : refus renvoyé au modèle};215  % Rangée 2 : exécution (de droite à gauche)216  \node[blocor,text width=2.5cm,below=1.6cm of d3] (pre) {\faIcon{step-backward}~Hook \emph{avant}\\ {\footnotesize script déterministe :\\ lint, blocage de dossier}};217  \node[bloc,text width=2.5cm,left=of pre] (sb) {\faIcon{box}~Bac à sable\\ {\footnotesize dossier et réseau\\ restreints}};218  \node[blocvert,text width=2.5cm,left=of sb] (exe) {\faIcon{play}~Exécution};219  \node[blocor,text width=2.5cm,left=of exe] (post) {\faIcon{step-forward}~Hook \emph{après}\\ {\footnotesize formatage, journal,\\ vérification auto}};220  \node[blocfonce,fill=uqoViolet,draw=uqoViolet,text width=2.6cm,left=of post] (back) {Résultat renvoyé\\ au modèle};221  % flèches rangée 1222  \draw[fl] (a) -- (d1);223  \draw[fl] (d1) -- (plan) node[midway,etiq,right] {oui, et ça écrit};224  \draw[fl] (d1) -- (d2) node[midway,etiq,above] {non};225  \draw[fl] (d2) -- (d3) node[midway,etiq,above] {aucune};226  \draw[fl] (d3) -- (ref) node[midway,etiq,right] {non};227  % descentes vers rangée 2228  \draw[fl] (d3.south) -- ([xshift=0.5cm]pre.north) node[pos=0.45,etiq,right] {oui};229  \draw[fl] (d2.south) -- ++(0,-0.55) -| ([xshift=-0.5cm]pre.north) node[pos=0.25,etiq,above] {liste d'autorisations : oui};230  % chaîne d'exécution231  \draw[fl] (pre) -- (sb);232  \draw[fl] (sb) -- (exe);233  \draw[fl] (exe) -- (post);234  \draw[fl] (post) -- (back);235  \draw[fl,dashed] (back.north) |- ([yshift=-0.35cm]a.south) -- (a.south) node[pos=0.12,etiq,right] {tour suivant};236\end{tikzpicture}}237\caption{Le flux d'une action : mode plan, règles d'autorisation, approbation, hooks, bac à sable, exécution}\label{fig:permissions}238\end{figure}239240{\small\Needspace{9\baselineskip}241\begin{tabularx}{\textwidth}{E{3.2cm}Xp{4.6cm}}242\caption{Modes de permission et usage recommandé dans le cours}\label{tab:modes}\\243\rowcolor{uqoBleu} \hc{Mode} & \hc{Comportement} & \hc{Usage recommandé dans le cours} \\244\endfirsthead245\captionsuite{Modes de permission et usage recommandé dans le cours}246\rowcolor{uqoBleu} \hc{Mode} & \hc{Comportement} & \hc{Usage recommandé dans le cours} \\247\endhead248\suitepage{3}249\endfoot250\finTableau251\endlastfoot252Plan (lecture seule) & Lit, analyse, propose ; aucune écriture, aucune commande qui modifie. & \textbf{Toujours au début} d'une session ; pour comprendre un gabarit ou un énoncé. \\253\rowcolor{uqoBgClair}254Manuel & Demande votre accord avant chaque écriture ou commande. & \textbf{Par défaut} sur tout travail noté. \\255Liste d'autorisations & Certaines commandes sûres passent sans demander (ex. : lancer un script de vérification). & Acceptable pour des commandes que vous avez déjà lues et comprises. \\256\rowcolor{uqoBgClair}257Automatique & Un classificateur ou une règle approuve la plupart des actions ; vous n'êtes consulté qu'en cas de risque détecté. & \feurouge~\textbf{Jamais} sur un travail noté ni sur des données réelles. \\258\end{tabularx}259}260261Les \textbf{hooks} méritent un mot : contrairement au fichier d'instructions, qui est \emph{consultatif} (le modèle peut l'oublier), un hook est un script qui s'exécute \emph{à coup sûr} à un moment donné de la boucle : avant un outil, après un outil, à la fin d'un tour. « Bloquer toute écriture dans le dossier \texttt{enonce/} » ou « recalculer le classeur et signaler si la valeur conclue a changé après chaque édition » sont des hooks typiques ; l'agent peut les écrire pour vous \parencite{claudecode_bestpractices}. Voici, concrètement, à quoi ressemble le premier dans Claude Code : un fichier de configuration qui déclare le hook, et un script de six lignes qui refuse l'action.262263\begin{fichier}[.claude/settings.json --- déclarer un hook « avant écriture » dans le dossier du TP]264\begin{Verbatim}[commandchars=§¡¿,numbers=left]265{266  §fk¡"hooks"¿: {267    §fk¡"PreToolUse"¿: [268      { §fk¡"matcher"¿: §fs¡"Write|Edit"¿,269        §fk¡"hooks"¿: [ { §fk¡"type"¿: §fs¡"command"¿, §fk¡"command"¿: §fs¡"python3 .claude/protege_enonce.py"¿ } ] }270    ]271  }272}273\end{Verbatim}274\end{fichier}275276\begin{fichier}[.claude/protege\_enonce.py --- le script appelé avant chaque écriture]277\begin{Verbatim}[commandchars=§¡¿,numbers=left]278§fk¡import¿ json, sys279appel = json.load(sys.stdin)                       §fc¡# le harnais transmet l'appel d'outil en JSON¿280chemin = appel.get(§fs¡"tool_input"¿, {}).get(§fs¡"file_path"¿, §fs¡""¿)281§fk¡if¿ §fs¡"/enonce/"¿ §fk¡in¿ chemin §fk¡or¿ chemin.endswith(§fs¡"gabarit.xlsx"¿):282    print(§fs¡"Refusé : l'énoncé et le gabarit original sont protégés."¿, file=sys.stderr)283    sys.exit(2)                                    §fc¡# code 2 = action bloquée, motif renvoyé au modèle¿284\end{Verbatim}285\end{fichier}286287Le point à retenir n'est pas la syntaxe, propre à chaque harnais, mais la nature de la protection : \textbf{déterministe}. Le modèle peut « oublier » une règle du fichier d'instructions ; il ne peut pas contourner un script qui s'exécute avant lui.288289\subsection{Sous-agents et orchestration}290\label{sec:sousagents}291292Un agent moderne peut déléguer une sous-tâche à une instance séparée, avec son propre contexte, ses propres outils autorisés, parfois un modèle différent. Le chef d'orchestre ne reçoit qu'un résumé. C'est puissant pour garder le contexte principal propre, et dangereux si le résumé n'est pas relu.293294\begin{figure}[!htb]295\centering296\begin{tikzpicture}[node distance=0.5cm and 0.5cm]297  \node[blocfonce,text width=3.4cm] (lead) {\faIcon{sitemap}~Agent principal\\ {\normalfont\footnotesize planifie, délègue, assemble}};298  \node[bloc,text width=2.9cm,below left=1.1cm and 1.6cm of lead] (s1) {\faIcon{search}~Sous-agent A\\ {\footnotesize explore les 30 ventes\\ contexte séparé}};299  \node[bloc,text width=2.9cm,below=1.1cm of lead] (s2) {\faIcon{calculator}~Sous-agent B\\ {\footnotesize écrit et exécute\\ le script}};300  \node[bloc,text width=2.9cm,below right=1.1cm and 1.6cm of lead,fill=uqoVert!8,draw=uqoVert] (s3) {\faIcon{user-check}~Sous-agent C\\ {\footnotesize \textbf{relit} le résultat\\ contexte vierge}};301  \draw[flb] (lead) -- (s1);302  \draw[flb] (lead) -- (s2) node[midway,etiq,right,xshift=2pt] {tâche};303  \draw[flb] (lead) -- (s3);304  \draw[flo] (s1.north) to[bend left=25] node[etiq,pos=0.6,left,xshift=-4pt] {résumé} (lead.west);305  \draw[flo] (s3.north) to[bend right=25] node[etiq,pos=0.6,right,xshift=4pt] {verdict} (lead.east);306  \node[etiq,below=0.35cm of s2,text width=12cm] {Le sous-agent C illustre le \textbf{patron rédacteur / relecteur} : une seconde instance, sans le biais d'avoir écrit le résultat, cherche les écarts. La documentation recommande de lui demander « seulement les écarts qui affectent la justesse », sans quoi il en trouvera toujours \parencite{claudecode_bestpractices}.};307\end{tikzpicture}308\caption{Sous-agents et patron rédacteur / relecteur : le chef d'orchestre ne reçoit que des résumés}\label{fig:sousagents}309\end{figure}310311Pour vous, la leçon est double : un sous-agent est un excellent moyen de \textbf{faire vérifier} un classeur ou un calcul par une instance neuve ; mais tout ce que rapporte un sous-agent est une affirmation de second degré, deux fois plus éloignée des faits que la sortie brute d'un outil. Exigez les preuves (valeurs de cellules, sorties de commandes), pas les résumés.312313\subsection{MCP : brancher l'agent sur le monde}314\label{sec:mcp}315316Le \emph{Model Context Protocol} est le connecteur universel des agents : un standard ouvert qui décrit comment un modèle découvre et appelle des outils externes. Lancé par Anthropic en novembre 2024, adopté par OpenAI en avril 2025, par Microsoft en juillet, par AWS en novembre, puis confié à la \emph{Agentic AI Foundation} (Linux Foundation) en décembre 2025, il comptait plus de 10\,000 serveurs publics en mars 2026 \parencite{mcp_adoption,mcp_spec2026}.317318\begin{figure}[!htb]319\centering320\begin{tikzpicture}321  \node[blocfonce,fill=uqoViolet,draw=uqoViolet,text width=3cm,minimum height=1.5cm] (c) at (0,0) {\faIcon{robot}~Agent\\ {\normalfont\footnotesize client MCP}};322  \foreach \a/\txt/\ic in {90/{Classeur Excel\\ \footnotesize lire, écrire des cellules}/file-excel, 30/{Base de ventes\\ \footnotesize requêtes SQL}/database, -30/{Navigateur\\ \footnotesize pages, captures}/globe, -90/{Système de fichiers\\ \footnotesize votre dossier de TP}/folder-open, -150/{Portail de données\\ \footnotesize APCIQ, SCHL, StatCan}/chart-line, 150/{Documents\\ \footnotesize PDF, normes, notes}/file-pdf}{323    \node[bloc,text width=2.9cm,align=center] (s\a) at (\a:4.3cm) {\faIcon{\ic}~\txt};324    \draw[flb,<->] (c) -- (s\a);325  }326  \node[etiq,anchor=north,text width=13cm] at (0,-6.1) {Un serveur MCP par ressource, un seul protocole : chaque client compatible (Claude, Codex, Copilot, Gemini, Cursor) peut s'y brancher.};327\end{tikzpicture}328\caption{Le protocole MCP : un serveur par ressource, un seul protocole pour tous les agents}\label{fig:mcp}329\end{figure}330331Pour l'évaluateur, c'est ce qui permet à un agent de \textbf{lire un classeur Excel cellule par cellule}, d'interroger une base de comparables ou de consulter un portail de données sans copier-coller. Pour l'étudiant, c'est aussi une nouvelle surface de risque : un serveur MCP a exactement les pouvoirs qu'on lui donne, et l'Agence de sécurité nationale américaine a publié en juin 2026 des recommandations de conception sécurisée à son sujet \parencite{nsa_mcp}. N'installez que des connecteurs de sources connues (§\ref{sec:securite}).332333\subsection{Une tâche complète, vue en séquence}334\label{sec:sequence}335336La figure~\ref{fig:sequence} suit une tâche réelle du cours (dégrossir trente ventes comparables, chapitre~\ref{sec:agents}) à travers les trois acteurs : vous, l'agent, les outils. Lisez-la de haut en bas ; les étapes numérotées sont celles de l'exemple guidé.337338\begin{figure}[!htb]339\centering340\resizebox{\linewidth}{!}{%341\begin{tikzpicture}[342  lane/.style={draw=uqoGris!50,dashed},343  msg/.style={-{Latex[length=2mm]},thick},344  act/.style={draw,rounded corners=2pt,font=\footnotesize\sffamily,align=center,inner sep=3pt}345]346  \def\xa{0}\def\xb{5.2}\def\xc{10.4}347  \node[blocfonce,text width=2.4cm] (ha) at (\xa,0) {\faIcon{user}~Vous};348  \node[blocfonce,fill=uqoViolet,draw=uqoViolet,text width=2.4cm] (hb) at (\xb,0) {\faIcon{robot}~Agent};349  \node[blocfonce,fill=uqoOr!80!black,draw=uqoOr!80!black,text width=2.4cm] (hc) at (\xc,0) {\faIcon{tools}~Outils};350  \foreach \x in {\xa,\xb,\xc}{\draw[lane] (\x,-0.5) -- (\x,-13.2);}351  % 1 explorer352  \draw[msg,uqoBleu] (\xa,-1.0) -- (\xb,-1.0) node[midway,above,act,fill=uqoBleu!8] {\etape{1} « Lis ventes.csv, décris, ne modifie rien » (mode plan)};353  \draw[msg,uqoOr!80!black] (\xb,-1.8) -- (\xc,-1.8) node[midway,above,act,fill=uqoOr!10] {Read(ventes.csv)};354  \draw[msg,uqoGris] (\xc,-2.3) -- (\xb,-2.3) node[midway,below,act,fill=black!4] {30 lignes, 8 colonnes};355  \draw[msg,uqoViolet] (\xb,-3.2) -- (\xa,-3.2) node[midway,above,act,fill=uqoViolet!8] {colonnes, 2 anomalies, rien modifié};356  % 2 plan357  \draw[msg,uqoBleu] (\xa,-4.1) -- (\xb,-4.1) node[midway,above,act,fill=uqoBleu!8] {\etape{2} « Propose un plan : \$/pi², médianes par secteur, graphique »};358  \draw[msg,uqoViolet] (\xb,-4.7) -- (\xa,-4.7) node[midway,below,act,fill=uqoViolet!8] {plan en 4 points, à valider};359  % 3 exécuter360  \draw[msg,uqoBleu] (\xa,-5.8) -- (\xb,-5.8) node[midway,above,act,fill=uqoBleu!8] {\etape{3} « D'accord, exécute » (mode manuel)};361  \draw[msg,uqoOr!80!black] (\xb,-6.5) -- (\xc,-6.5) node[midway,above,act,fill=uqoOr!10] {Write(analyse.py)};362  \draw[msg,uqoRouge] (\xb,-7.1) -- (\xa,-7.1) node[midway,below,act,fill=uqoRouge!6] {\faIcon{shield-alt}~demande d'approbation : Bash(python3 analyse.py)};363  \draw[msg,uqoBleu] (\xa,-8.1) -- (\xb,-8.1) node[midway,below,act,fill=uqoBleu!8] {approuvé};364  \draw[msg,uqoOr!80!black] (\xb,-8.7) -- (\xc,-8.7) node[midway,above,act,fill=uqoOr!10] {Bash(python3 analyse.py)};365  \draw[msg,uqoGris] (\xc,-9.2) -- (\xb,-9.2) node[midway,below,act,fill=black!4] {tableau + graphique.png};366  % 4 vérifier367  \draw[msg,uqoBleu] (\xa,-10.7) -- (\xb,-10.7) node[midway,above,act,fill=uqoBleu!8] {\etape{4} « Montre les valeurs des ventes 3, 11, 24 » (je recalcule à la main)};368  \draw[msg,uqoViolet] (\xb,-11.4) -- (\xa,-11.4) node[midway,below,act,fill=uqoViolet!8] {trois lignes, preuves brutes};369  % 5 interpréter370  \node[act,fill=uqoVert!10,draw=uqoVert,text width=4.2cm] at (\xa+0.2,-12.5) {\etape{5} \textbf{Vous} interprétez la tendance, choisissez les comparables, rédigez.};371  \node[act,fill=uqoOr!10,draw=uqoOr!80!black,text width=4.2cm] at (\xc-0.2,-12.5) {\etape{6} Déclaration d'outils : script d'exploration ; sélection et grille faites à la main.};372\end{tikzpicture}}373\caption{Une tâche complète en séquence : vous, l'agent, les outils (dégrossir trente ventes comparables)}\label{fig:sequence}374\end{figure}375376377\subsection{Patrons d'orchestration}378\label{sec:patrons}379380Les harnais combinent un petit nombre de patrons, décrits dans la littérature technique depuis 2023 et visibles dans tous les produits de 2026. Les reconnaître vous permet de choisir le bon mode de travail et d'anticiper le risque associé.381382{\small\Needspace{9\baselineskip}383\begin{tabularx}{\textwidth}{E{3.1cm}Xp{3.6cm}p{3.4cm}}384\caption{Patrons d'orchestration : fonctionnement, où vous les rencontrez, risque propre}\label{tab:patrons}\\385\rowcolor{uqoBleu} \hc{Patron} & \hc{Fonctionnement} & \hc{Où vous le rencontrez} & \hc{Risque propre} \\386\endfirsthead387\captionsuite{Patrons d'orchestration : fonctionnement, où vous les rencontrez, risque propre}388\rowcolor{uqoBleu} \hc{Patron} & \hc{Fonctionnement} & \hc{Où vous le rencontrez} & \hc{Risque propre} \\389\endhead390\suitepage{4}391\endfoot392\finTableau393\endlastfoot394Raisonner puis agir (ReAct) & Alternance serrée d'une pensée courte et d'un appel d'outil ; le résultat nourrit la pensée suivante. & Toute session d'agent ; c'est la boucle de base du §\ref{sec:boucle}. & Enchaîner des actions sans recul ; s'enfermer dans une piste. \\395\rowcolor{uqoBgClair}396Planifier puis exécuter & Un plan complet est produit et validé avant la première action. & Mode plan de Claude Code, mode suggestion de Codex, « plan » de Cursor. & Plan élégant mais fondé sur une mauvaise lecture du problème : d'où l'importance de le relire. \\397Réflexion (évaluer et corriger) & Le résultat est évalué contre un critère, puis corrigé, en boucle. & Tests, \texttt{/goal}, hooks de fin de tour. & Sans critère exécutable, l'« évaluation » est une auto-approbation. \\398\rowcolor{uqoBgClair}399Rédacteur et relecteur & Une seconde instance, sans le biais d'avoir produit le résultat, cherche les écarts. & Sous-agent de revue, \texttt{/code-review}, session B en parallèle. & Le relecteur trouve toujours quelque chose ; ne retenir que ce qui touche la justesse. \\400Orchestrateur et travailleurs & Un agent principal découpe, délègue à des sous-agents, assemble. & Sous-agents, agents en arrière-plan, tâches en nuage. & Résumés de second degré ; coût en jetons ; conflits d'édition. \\401\rowcolor{uqoBgClair}402Humain dans la boucle & Chaque action à risque attend une approbation ; l'humain reste décideur. & Mode manuel, permissions, entretien de vérification du cours. & Fatigue d'approbation : au dixième « oui », on ne lit plus. \\403\end{tabularx}404}405406\subsection{Modes de défaillance et parades}407\label{sec:defaillances}408409Les agents échouent de façons prévisibles. Le tableau relie chaque symptôme à sa cause dans le mécanisme et à la parade qui est à votre portée.410411{\small\Needspace{9\baselineskip}412\begin{tabularx}{\textwidth}{R{3.2cm}XX}413\caption{Modes de défaillance des agents et parades à votre portée}\label{tab:defaillances}\\414\rowcolor{uqoRouge} \hc{Symptôme} & \hc{Cause dans le mécanisme} & \hc{Parade} \\415\endfirsthead416\captionsuite{Modes de défaillance des agents et parades à votre portée}417\rowcolor{uqoRouge} \hc{Symptôme} & \hc{Cause dans le mécanisme} & \hc{Parade} \\418\endhead419\suitepage{3}420\endfoot421\finTableau422\endlastfoot423Répétition, boucle sans progrès & Aucun critère d'arrêt exécutable ; le modèle réessaie la même chose. & Fournir un test ; arrêter (\texttt{Esc}) ; reformuler dans une session neuve. \\424\rowcolor{uqoBgClair}425Zèle excessif & L'objectif est interprété largement ; l'agent « améliore » ce qu'on ne lui a pas demandé. & Scoper la tâche (fichiers, cellules) ; hook qui bloque les dossiers protégés ; relire le diff. \\426Complaisance & Le modèle valide votre erreur parce que vous semblez sûr de vous. & Demander la réfutation (« suppose que j'ai tort ») ; ne jamais annoncer la réponse attendue. \\427\rowcolor{uqoBgClair}428Oubli des consignes & Fenêtre de contexte saturée ; les instructions du début pèsent moins. & \texttt{/clear}, \texttt{/compact} ; remettre les conventions dans \texttt{CLAUDE.md}. \\429Fausse réussite & L'agent affirme « c'est fait » sans preuve ; la boucle s'arrête sur l'apparence. & Exiger la sortie brute (valeurs, commandes) ; test du chaînage. \\430\rowcolor{uqoBgClair}431Mauvaise convention & Le modèle applique la convention générique la plus fréquente dans ses données. & Énoncer la convention du cours dans le fichier d'instructions et la requête. \\432Action détournée & Injection de requête par un contenu lu ; trio dangereux réuni. & Pas de Web ni de données sensibles dans la même session ; connecteurs connus seulement. \\433\rowcolor{uqoBgClair}434Valeurs collées à la place de formules & L'agent optimise le résultat visible, pas la structure du classeur. & Interdit explicite dans \texttt{CLAUDE.md} ; vérifier que $B$ change la valeur conclue. \\435\end{tabularx}436}437438\subsection{L'économie des jetons}439440Chaque tour de boucle renvoie au modèle l'intégralité du contexte. Une session d'une heure sur un TP consomme donc bien plus que la somme de vos messages. Ordre de grandeur pour une session raisonnable : lecture de l'énoncé (8\,000 jetons), lecture du classeur (15\,000), vingt tours d'échange (40\,000), sorties de commandes (25\,000), soit près de 90\,000 jetons d'entrée cumulés à chaque tour en fin de session. Sur un abonnement, cela se traduit par l'atteinte plus rapide des limites d'usage ; à l'usage (API), par un coût qui reste de l'ordre du dollar pour la famille de modèles intermédiaire, mais qui grimpe vite avec les sous-agents et les boucles. Les gestes qui économisent : un dossier léger, des lectures ciblées, \texttt{/clear} entre les tâches, et pas de « investigue tout » sans périmètre.441442\begin{okbox}[Ce que ce chapitre change dans votre pratique]443\begin{itemize}444  \item Vous savez maintenant \textbf{pourquoi} il faut commencer en mode plan (rien n'écrit), scoper ce que l'agent lit (le contexte se remplit), et exiger des preuves (le résumé est une affirmation de second degré).445  \item Vous savez \textbf{où} configurer : le fichier d'instructions pour les conventions, les permissions pour la sécurité, les hooks pour ce qui doit arriver à coup sûr.446  \item Vous savez \textbf{quoi} redouter : un texte non fiable lu par l'agent, un mode automatique sur des données réelles, un connecteur inconnu, et les huit modes de défaillance du §\ref{sec:defaillances}.447\end{itemize}448\end{okbox}449
Files main
Menu

Theme