1% ------------------------------------------------------------------------------2\section{Personnaliser : styles, skills, hooks, sous-agents, MCP}3\label{sec:personnaliser}4% ------------------------------------------------------------------------------56\begin{enbref}7Cinq leviers, du plus simple au plus avancé. Les \textbf{styles de sortie} changent la façon dont l'agent vous parle (Explanatory, Learning). Les \textbf{skills} sont des procédures réutilisables que vous appelez par \texttt{/nom}. Les \textbf{hooks} sont des scripts qui s'exécutent à coup sûr à un moment de la boucle. Les \textbf{sous-agents} sont des instances spécialisées (un relecteur, par exemple). Les \textbf{connecteurs MCP} branchent l'agent sur des outils externes. Chaque section donne un exemple complet pour le cours.8\end{enbref}910\subsection{Styles de sortie : apprendre en travaillant}11\label{sec:styles}1213Claude Code offre deux styles pensés pour l'apprentissage, activés par \texttt{/output-style} \parencite{cc_outputstyles}. Le style \textbf{Explanatory} ajoute des encadrés « Insight » qui expliquent chaque choix (pourquoi cette formule, quel compromis). Le style \textbf{Learning} va plus loin : l'agent écrit l'essentiel mais laisse des marqueurs \texttt{TODO(human)} là où \emph{vous} devez écrire le morceau qui compte, puis commente ce que vous avez écrit. Combiné avec un \texttt{CLAUDE.md} de tuteur (exemple~\ref{ex:tuteur}), c'est la façon la plus rentable d'apprendre avec un agent.1415\begin{terminal}[Style Learning à l'œuvre --- TP3, méthode du revenu (extrait)]16\begin{Verbatim}[commandchars=§¡¿]17§tu¡> /output-style learning¿18 §ok¡Output style set to Learning¿1920§tu¡> Monte la feuille Revenu : en-têtes, cellules de source, et laisse-moi les formules.¿2122 §hi¡Edit¿(gabarit_travail.xlsx, Revenu!A1:C20)23 Feuille montée. Trois formules vous reviennent :2425 §hi¡TODO(human)¿ Revenu!C6 — revenu brut effectif : partir du RBP en C4 et retirer la26 vacance dont le taux est en Accueil!D12. Attention à ce que27 le taux soit celui de la SCHL, pas 0 parce que « tout est loué ».28 §hi¡TODO(human)¿ Revenu!C15 — RNE : quelles lignes de C8:C14 sont des dépenses29 d'exploitation ? L'une d'elles n'en est pas une.30 §hi¡TODO(human)¿ Revenu!C18 — valeur par capitalisation directe : RNE et TGA (Accueil!D14).3132§tu¡> J'ai écrit C6 = C4*(1-Accueil!D12) et C15 = C4-SOMME(C8:C14). Vérifie.¿3334 C6 : correct, et la référence à D12 garde la chaîne intacte.35 C15 : deux écarts. (1) Le RNE part du RBE (C6), pas du RBP (C4). (2) C13 contient le36 paiement hypothécaire : c'est du service de la dette, il n'entre pas dans le RNE37 (convention du cours, CLAUDE.md). Je ne corrige pas ; à vous.38\end{Verbatim}39\end{terminal}4041\subsection{Skills et commandes personnalisées}42\label{sec:skills}4344Une \textbf{skill} est un dossier \texttt{.claude/skills/nom/} contenant un fichier \texttt{SKILL.md} : un en-tête (nom, description) et une procédure en langage naturel. Vous l'appelez par \texttt{/nom}, et l'agent peut aussi la charger de lui-même quand la description correspond à la tâche \parencite{cc_skills}. Placée dans \texttt{\textasciitilde/.claude/skills/}, elle est disponible dans tous vos dossiers. L'ancien format, un fichier \texttt{.claude/commands/nom.md} avec \texttt{\$ARGUMENTS}, reste reconnu.4546\begin{fichier}[.claude/skills/verif-chaine/SKILL.md --- une vérification appelée par /verif-chaine]47\begin{Verbatim}[commandchars=§¡¿,numbers=left]48---49§fk¡name¿: verif-chaine50§fk¡description¿: Vérifie qu'un classeur du cours est chaîné par formules et qu'aucune51 valeur n'a remplacé une formule. À utiliser après toute modification d'un .xlsx.52---53§fk¡# Vérification de la chaîne d'un classeur du cours¿5455Argument attendu : le chemin du classeur (par défaut gabarit_travail.xlsx).56571. Lire le classeur avec openpyxl SANS data_only pour voir les formules.582. Lister toute cellule des zones de travail (feuilles Grille, Revenu, Bordereau) qui59 contient un nombre là où les cellules voisines contiennent des formules. Les rapporter60 avec leur adresse ; ne rien corriger.613. Lire Accueil!D9 (valeur de B). Recalculer indépendamment en Python la valeur conclue62 pour B et pour B+1 selon la règle décrite dans CLAUDE.md ou l'énoncé.634. Rapporter, dans un tableau à trois colonnes (B, valeur recalculée, valeur affichée64 dans le classeur), si les deux valeurs de B donnent des résultats différents.655. Terminer par une ligne : « Chaîne : OK » ou « Chaîne : ROMPUE — cellules : … ».66 Ne jamais écrire dans le classeur pendant cette skill.67\end{Verbatim}68\end{fichier}6970\begin{fichier}[.claude/skills/declaration/SKILL.md --- rédige le brouillon de la déclaration d'outils]71\begin{Verbatim}[commandchars=§¡¿,numbers=left]72---73§fk¡name¿: declaration74§fk¡description¿: Prépare le brouillon de la déclaration d'utilisation des outils à partir75 de l'historique de la session (outils, étapes, vérifications). Niveau 3 du cours.76---77Relis toute la conversation courante et produis, en français, les quatre rubriques de la78déclaration du cours :791. Outils utilisés (Claude Code + modèle actif via /status).802. Étapes concernées et nature de l'aide : une ligne par étape, verbe à l'infinitif,81 cellules ou fichiers nommés, en distinguant ce que J'AI écrit de ce que TU as préparé.823. Vérifications effectuées : uniquement celles dont la sortie apparaît dans la session.834. Renseignements personnels soumis : « aucun » sauf preuve du contraire dans la session.84Ne rien inventer ni embellir. Marquer [À COMPLÉTER] ce que la session ne permet pas de dire.85\end{Verbatim}86\end{fichier}8788Après avoir créé ces fichiers, tapez \texttt{/verif-chaine gabarit\_travail.xlsx} ou \texttt{/declaration}. Le tableau~\ref{tab:skills-idees} donne d'autres idées.8990{\small\Needspace{9\baselineskip}91\begin{tabularx}{\textwidth}{L{3.4cm}X}92\caption{Idées de skills pour le cours}\label{tab:skills-idees}\\93\rowcolor{uqoBleu} \hc{Skill} & \hc{Ce qu'elle fait} \\94\endfirsthead95\captionsuite{Idées de skills pour le cours}96\rowcolor{uqoBleu} \hc{Skill} & \hc{Ce qu'elle fait} \\97\endhead98\suitepage{2}99\endfoot100\finTableau101\endlastfoot102\texttt{/verif-chaine} & Test de la chaîne et détection des valeurs collées (ci-dessus). \\103\rowcolor{uqoBgClair}104\texttt{/declaration} & Brouillon de la déclaration d'outils depuis la session (ci-dessus). \\105\texttt{/critique} & Relit un fichier que vous nommez avec les conventions du cours : écarts, sources manquantes, phrases génériques ; ne réécrit rien. \\106\rowcolor{uqoBgClair}107\texttt{/sources} & Vérifie que chaque chiffre d'un document a une entrée dans \texttt{sources.md} avec URL et date. \\108\texttt{/questions} & Génère cinq questions d'application à partir d'un fichier de notes, une à la fois. \\109\rowcolor{uqoBgClair}110\texttt{/sauvegarde} & Copie datée du classeur dans \texttt{sauvegardes/} et commit Git avec message standard. \\111\end{tabularx}112}113114\subsection{Hooks : ce qui doit arriver à coup sûr}115\label{sec:hooks}116117Une règle de \texttt{CLAUDE.md} est \emph{consultative} : le modèle peut l'oublier. Un hook est un script que Claude Code exécute lui-même à un moment précis de la boucle, sans passer par le modèle : avant un outil (\texttt{PreToolUse}), après (\texttt{PostToolUse}), quand vous envoyez une requête (\texttt{UserPromptSubmit}), quand l'agent finit un tour (\texttt{Stop}), au démarrage (\texttt{SessionStart}), avant une compaction (\texttt{PreCompact}) \parencite{cc_hooks}. Le script reçoit la description de l'événement en JSON sur son entrée standard ; s'il se termine avec le code 2, l'action est bloquée et son message est renvoyé au modèle. Deux exemples pour le cours.118119\begin{fichier}[.claude/settings.json --- deux hooks : protéger l'énoncé, revérifier la chaîne après chaque édition]120\begin{Verbatim}[commandchars=§¡¿,numbers=left]121{122 §fk¡"hooks"¿: {123 §fk¡"PreToolUse"¿: [124 { §fk¡"matcher"¿: §fs¡"Edit|Write"¿,125 §fk¡"hooks"¿: [ { §fk¡"type"¿: §fs¡"command"¿, §fk¡"command"¿: §fs¡"python3 .claude/hooks/protege.py"¿ } ] }126 ],127 §fk¡"PostToolUse"¿: [128 { §fk¡"matcher"¿: §fs¡"Edit|Write"¿,129 §fk¡"hooks"¿: [ { §fk¡"type"¿: §fs¡"command"¿,130 §fk¡"command"¿: §fs¡"python3 .claude/hooks/apres_edition.py"¿ } ] }131 ],132 §fk¡"Stop"¿: [133 { §fk¡"hooks"¿: [ { §fk¡"type"¿: §fs¡"command"¿, §fk¡"command"¿: §fs¡"python3 .claude/hooks/journal.py"¿ } ] }134 ]135 }136}137\end{Verbatim}138\end{fichier}139140\begin{fichier}[.claude/hooks/protege.py --- bloque toute écriture dans l'énoncé et le gabarit original]141\begin{Verbatim}[commandchars=§¡¿,numbers=left]142§fk¡import¿ json, sys143evt = json.load(sys.stdin)144chemin = evt.get(§fs¡"tool_input"¿, {}).get(§fs¡"file_path"¿, §fs¡""¿)145proteges = (§fs¡"/enonce/"¿, §fs¡"enonce.pdf"¿, §fs¡"gabarit.xlsx"¿)146§fk¡if¿ any(p §fk¡in¿ chemin §fk¡for¿ p §fk¡in¿ proteges):147 print(§fs¡f"Refusé : {chemin} est protégé (énoncé ou gabarit original). "¿148 §fs¡"Travaille sur gabarit_travail.xlsx."¿, file=sys.stderr)149 sys.exit(2) §fc¡# 2 = bloqué, motif renvoyé au modèle¿150\end{Verbatim}151\end{fichier}152153\begin{fichier}[.claude/hooks/apres\_edition.py --- après chaque édition d'un .xlsx, relance la vérification]154\begin{Verbatim}[commandchars=§¡¿,numbers=left]155§fk¡import¿ json, subprocess, sys156evt = json.load(sys.stdin)157chemin = evt.get(§fs¡"tool_input"¿, {}).get(§fs¡"file_path"¿, §fs¡""¿)158§fk¡if¿ chemin.endswith(§fs¡".xlsx"¿):159 r = subprocess.run([§fs¡"python3"¿, §fs¡"verif_chaine.py"¿, chemin],160 capture_output=True, text=True)161 print(r.stdout) §fc¡# la sortie entre dans le contexte : l'agent la voit¿162 §fk¡if¿ §fs¡"ROMPUE"¿ §fk¡in¿ r.stdout:163 print(§fs¡"Chaîne rompue : corrige avant de continuer."¿, file=sys.stderr)164 sys.exit(2)165\end{Verbatim}166\end{fichier}167168Le troisième hook, \texttt{journal.py}, peut simplement ajouter la date et le résumé du tour dans \texttt{JOURNAL.md} : c'est votre trace pour la déclaration d'outils. La commande \texttt{/hooks} affiche les hooks actifs et permet d'en ajouter sans éditer le JSON.169170\begin{piege}[Un hook est du code qui s'exécute sur votre machine]171Ne copiez jamais un hook trouvé dans un dossier téléchargé sans l'avoir lu. C'est exactement pour cela que Claude Code demande si vous faites confiance à un dossier avant d'y appliquer ses réglages (§\ref{sec:permissions}). Les hooks de ce guide font quelques lignes, lisibles ; gardez-les ainsi.172\end{piege}173174\subsection{Sous-agents : un relecteur qui n'a pas écrit le résultat}175\label{sec:sousagents}176177Un sous-agent est une instance de Claude avec sa propre description, ses propres outils autorisés et son propre contexte, que l'agent principal appelle pour une sous-tâche ; seul un résumé revient \parencite{cc_subagents}. On le définit dans un fichier \texttt{.claude/agents/nom.md} ; la commande \texttt{/agents} en crée et en gère aussi. Le cas le plus utile dans le cours : un relecteur, qui cherche les écarts avec les conventions sans le biais d'avoir produit le résultat.178179\begin{fichier}[.claude/agents/relecteur.md --- sous-agent de relecture, lecture seule]180\begin{Verbatim}[commandchars=§¡¿,numbers=left]181---182§fk¡name¿: relecteur183§fk¡description¿: Relit un classeur, un script ou une section de rapport du cours et184 rapporte UNIQUEMENT les écarts qui affectent la justesse (conventions du cours,185 formules, sources). À utiliser avant toute remise. Ne modifie jamais rien.186§fk¡tools¿: Read, Grep, Glob, Bash187§fk¡model¿: sonnet188---189Tu es un correcteur d'IMM1003 et d'IMM1033. Tu lis CLAUDE.md pour connaître les190conventions du cours, puis le fichier qu'on te désigne.191192Rapporte, par ordre de gravité, seulement ce qui change un résultat ou une note :193- une convention du cours non respectée (avec la ligne, la cellule ou la formule) ;194- une formule dont le résultat dépend d'une valeur collée ;195- un chiffre sans source, ou une source qui ne dit pas ce qu'on lui fait dire ;196- une incohérence entre deux sections (valeur conclue, hypothèse).197198N'énumère pas les questions de style. Si tu ne trouves rien, dis « Aucun écart affectant199la justesse » : un relecteur qui trouve toujours quelque chose n'est pas fiable.200Tu ne modifies aucun fichier et n'exécutes que des commandes de lecture.201\end{Verbatim}202\end{fichier}203204Appel : « Fais relire \texttt{gabarit\_travail.xlsx} par le sous-agent relecteur et montre-moi son rapport tel quel. » Ce qui revient est une affirmation de second degré : vérifiez les écarts signalés dans le fichier avant de corriger.205206\subsection{MCP : brancher l'agent sur d'autres outils}207\label{sec:mcp}208209Le \emph{Model Context Protocol} est le standard ouvert par lequel un agent découvre et appelle des outils externes \parencite{mcp_spec}. Un « serveur MCP » expose une ressource (un dossier, une base de données, un navigateur, un service en ligne) ; Claude Code s'y connecte et ses outils apparaissent à côté de \texttt{Read} ou \texttt{Bash} \parencite{cc_mcp}. Pour un étudiant, deux connecteurs suffisent largement :210211\begin{terminal}[Ajouter deux connecteurs MCP]212\begin{Verbatim}[commandchars=§¡¿]213§co¡# 1. Un dossier de données publiques, en lecture seule, hors du dossier de TP¿214§tu¡$¿ claude mcp add donnees-publiques -- npx -y @modelcontextprotocol/server-filesystem \215 ~/Documents/UQO/donnees_publiques216217§co¡# 2. Un connecteur distant (exemple fictif) ; portée « project » = ce dossier seulement¿218§tu¡$¿ claude mcp add --transport http --scope project docs-cours https://exemple.uqo.ca/mcp219220§tu¡$¿ claude mcp list221§vok¡¿ donnees-publiques stdio npx -y @modelcontextprotocol/server-filesystem …222§vok¡¿ docs-cours http https://exemple.uqo.ca/mcp (projet : .mcp.json)223\end{Verbatim}224\end{terminal}225226Dans la session, \texttt{/mcp} montre l'état des connecteurs et leurs outils ; chaque outil MCP demande votre accord à la première utilisation, comme \texttt{Bash}. Les connecteurs de portée « projet » sont écrits dans un fichier \texttt{.mcp.json} à la racine du dossier, que l'équipe peut partager.227228\begin{alertbox}[Un connecteur a exactement les pouvoirs qu'on lui donne]229Un serveur MCP malveillant ou mal configuré a le même pouvoir que l'agent. N'installez que des connecteurs de sources connues (Anthropic, l'éditeur du service, un dépôt officiel), lisez ce qu'ils exposent avec \texttt{/mcp}, et ne combinez jamais un connecteur qui \emph{écrit vers l'extérieur} avec un dossier qui contient des données personnelles (figure~\ref{fig:trio}). Pour les TP du cours, aucun connecteur n'est nécessaire.230\end{alertbox}231