Loading...
    • Guide du développeur
    • Référence API
    • MCP
    • Ressources
    • Notes de version
    Search...
    ⌘K
    Premiers pas
    Introduction à ClaudeDémarrage rapide
    Modèles et tarification
    Aperçu des modèlesChoisir un modèleNouveautés dans Claude 4.6Guide de migrationDépréciation des modèlesTarification
    Créer avec Claude
    Aperçu des fonctionnalitésUtiliser l'API MessagesGérer les raisons d'arrêtMeilleures pratiques de prompting
    Gestion du contexte
    Fenêtres de contexteCompactionÉdition du contexte
    Capacités
    Mise en cache des promptsRéflexion étendueRéflexion adaptativeEffortStreaming de messagesTraitement par lotsCitationsSupport multilingueComptage des tokensEmbeddingsVisionSupport PDFAPI FilesRésultats de rechercheSorties structurées
    Outils
    AperçuComment implémenter l'utilisation d'outilsStreaming d'outils granulaireOutil BashOutil d'exécution de codeAppel d'outils programmatiqueOutil Computer useOutil Éditeur de texteOutil Web fetchOutil Web searchOutil MémoireOutil Tool search
    Compétences d'agent
    AperçuDémarrage rapideMeilleures pratiquesCompétences pour l'entrepriseUtiliser les compétences avec l'API
    SDK Agent
    AperçuDémarrage rapideSDK TypeScriptTypeScript V2 (aperçu)SDK PythonGuide de migration
    Streaming d'entréeDiffuser les réponses en temps réelGérer les raisons d'arrêtGérer les permissionsApprobations et entrées utilisateurContrôler l'exécution avec des hooksGestion des sessionsSauvegarde de fichiersSorties structurées dans le SDKHéberger le SDK AgentDéployer les agents IA de manière sécuriséeModifier les prompts systèmeMCP dans le SDKOutils personnalisésSous-agents dans le SDKCommandes slash dans le SDKCompétences d'agent dans le SDKSuivi des coûts et de l'utilisationListes de tâchesPlugins dans le SDK
    MCP dans l'API
    Connecteur MCPServeurs MCP distants
    Claude sur les plateformes tierces
    Amazon BedrockMicrosoft FoundryVertex AI
    Ingénierie des prompts
    AperçuGénérateur de promptsUtiliser les modèles de promptsAméliorateur de promptsÊtre clair et directUtiliser des exemples (prompting multi-coups)Laisser Claude réfléchir (CoT)Utiliser les balises XMLDonner un rôle à Claude (prompts système)Enchaîner les prompts complexesConseils pour le contexte longConseils pour la réflexion étendue
    Tester et évaluer
    Définir les critères de succèsDévelopper des cas de testUtiliser l'outil d'évaluationRéduire la latence
    Renforcer les garde-fous
    Réduire les hallucinationsAugmenter la cohérence des résultatsAtténuer les jailbreaksRefus en streamingRéduire les fuites de promptsGarder Claude dans le rôle
    Administration et surveillance
    Aperçu de l'API AdminRésidence des donnéesEspaces de travailAPI d'utilisation et de coûtsAPI Claude Code AnalyticsRétention zéro des données
    Console
    Log in
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...
    Loading...

    Solutions

    • AI agents
    • Code modernization
    • Coding
    • Customer support
    • Education
    • Financial services
    • Government
    • Life sciences

    Partners

    • Amazon Bedrock
    • Google Cloud's Vertex AI

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Company

    • Anthropic
    • Careers
    • Economic Futures
    • Research
    • News
    • Responsible Scaling Policy
    • Security and compliance
    • Transparency

    Learn

    • Blog
    • Catalog
    • Courses
    • Use cases
    • Connectors
    • Customer stories
    • Engineering at Anthropic
    • Events
    • Powered by Claude
    • Service partners
    • Startups program

    Help and security

    • Availability
    • Status
    • Support
    • Discord

    Terms and policies

    • Privacy policy
    • Responsible disclosure policy
    • Terms of service: Commercial
    • Terms of service: Consumer
    • Usage policy
    Guides

    Intercepter et contrôler le comportement des agents avec des hooks

    Intercepter et personnaliser le comportement des agents aux points d'exécution clés avec des hooks

    Les hooks vous permettent d'intercepter l'exécution des agents aux points clés pour ajouter une validation, une journalisation, des contrôles de sécurité ou une logique personnalisée. Avec les hooks, vous pouvez :

    • Bloquer les opérations dangereuses avant leur exécution, comme les commandes shell destructrices ou l'accès non autorisé aux fichiers
    • Journaliser et auditer chaque appel d'outil pour la conformité, le débogage ou l'analyse
    • Transformer les entrées et les sorties pour nettoyer les données, injecter des identifiants ou rediriger les chemins de fichiers
    • Exiger une approbation humaine pour les actions sensibles comme les écritures de base de données ou les appels API
    • Suivre le cycle de vie de la session pour gérer l'état, nettoyer les ressources ou envoyer des notifications

    Un hook a deux parties :

    1. La fonction de rappel : la logique qui s'exécute lorsque le hook se déclenche
    2. La configuration du hook : indique au SDK quel événement accrocher (comme PreToolUse) et quels outils faire correspondre

    L'exemple suivant empêche l'agent de modifier les fichiers .env. Tout d'abord, définissez un rappel qui vérifie le chemin du fichier, puis transmettez-le à query() pour l'exécuter avant tout appel d'outil Write ou Edit :

    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher
    
    # Définir un rappel de hook qui reçoit les détails de l'appel d'outil
    async def protect_env_files(input_data, tool_use_id, context):
        # Extraire le chemin du fichier des arguments d'entrée de l'outil
        file_path = input_data['tool_input'].get('file_path', '')
        file_name = file_path.split('/')[-1]
    
        # Bloquer l'opération si elle cible un fichier .env
        if file_name == '.env':
            return {
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Cannot modify .env files'
                }
            }
    
        # Retourner un objet vide pour autoriser l'opération
        return {}
    
    async def main():
        async for message in query(
            prompt="Update the database configuration",
            options=ClaudeAgentOptions(
                hooks={
                    # Enregistrer le hook pour les événements PreToolUse
                    # Le matcher filtre uniquement les appels d'outils Write et Edit
                    'PreToolUse': [HookMatcher(matcher='Write|Edit', hooks=[protect_env_files])]
                }
            )
        ):
            print(message)
    
    asyncio.run(main())

    Ceci est un hook PreToolUse. Il s'exécute avant l'exécution de l'outil et peut bloquer ou autoriser les opérations en fonction de votre logique. Le reste de ce guide couvre tous les hooks disponibles, leurs options de configuration et les modèles pour les cas d'usage courants.

    Hooks disponibles

    Le SDK fournit des hooks pour différentes étapes de l'exécution des agents. Certains hooks sont disponibles dans les deux SDK, tandis que d'autres sont spécifiques à TypeScript car le SDK Python ne les supporte pas.

    Événement HookSDK PythonSDK TypeScriptCe qui le déclencheCas d'usage exemple
    PreToolUseOuiOuiDemande d'appel d'outil (peut bloquer ou modifier)Bloquer les commandes shell dangereuses
    PostToolUseOuiOuiRésultat de l'exécution de l'outilJournaliser tous les changements de fichiers dans la piste d'audit
    PostToolUseFailureNonOuiÉchec de l'exécution de l'outilGérer ou journaliser les erreurs d'outil
    UserPromptSubmitOuiOuiSoumission du message utilisateurInjecter du contexte supplémentaire dans les messages
    StopOuiOuiArrêt de l'exécution de l'agentEnregistrer l'état de la session avant la sortie
    SubagentStartNonOuiInitialisation du sous-agentSuivre la génération de tâches parallèles
    SubagentStopOuiOuiAchèvement du sous-agentAgréger les résultats des tâches parallèles
    PreCompactOuiOuiDemande de compaction de conversationArchiver la transcription complète avant le résumé
    PermissionRequestNonOuiLa boîte de dialogue de permission s'afficheraitGestion des permissions personnalisée
    SessionStartNonOuiInitialisation de la sessionInitialiser la journalisation et la télémétrie
    SessionEndNonOuiArrêt de la sessionNettoyer les ressources temporaires
    NotificationNonOuiMessages de statut de l'agentEnvoyer les mises à jour de statut de l'agent à Slack ou PagerDuty

    Cas d'usage courants

    Les hooks sont suffisamment flexibles pour gérer de nombreux scénarios différents. Voici certains des modèles les plus courants organisés par catégorie.

    Configurer les hooks

    Pour configurer un hook pour votre agent, transmettez le hook dans le paramètre options.hooks lors de l'appel de query() :

    async for message in query(
        prompt="Your prompt",
        options=ClaudeAgentOptions(
            hooks={
                'PreToolUse': [HookMatcher(matcher='Bash', hooks=[my_callback])]
            }
        )
    ):
        print(message)

    L'option hooks est un dictionnaire (Python) ou un objet (TypeScript) où :

    • Les clés sont les noms des événements de hook (par exemple, 'PreToolUse', 'PostToolUse', 'Stop')
    • Les valeurs sont des tableaux de matchers, chacun contenant un modèle de filtre optionnel et vos fonctions de rappel

    Vos fonctions de rappel de hook reçoivent les données d'entrée sur l'événement et retournent une réponse pour que l'agent sache s'il faut autoriser, bloquer ou modifier l'opération.

    Matchers

    Utilisez les matchers pour filtrer les outils qui déclenchent vos rappels :

    OptionTypeDéfautDescription
    matcherstringundefinedModèle regex pour faire correspondre les noms d'outils. Les outils intégrés incluent Bash, Read, Write, Edit, Glob, Grep, WebFetch, Task, et autres. Les outils MCP utilisent le modèle mcp__<server>__<action>.
    hooksHookCallback[]-Requis. Tableau de fonctions de rappel à exécuter lorsque le modèle correspond
    timeoutnumber60Délai d'expiration en secondes ; augmentez pour les hooks qui effectuent des appels API externes

    Utilisez le modèle matcher pour cibler des outils spécifiques chaque fois que possible. Un matcher avec 'Bash' s'exécute uniquement pour les commandes Bash, tandis que l'omission du modèle exécute vos rappels pour chaque appel d'outil. Notez que les matchers ne filtrent que par nom d'outil, pas par chemins de fichiers ou autres arguments—pour filtrer par chemin de fichier, vérifiez tool_input.file_path à l'intérieur de votre rappel.

    Les matchers ne s'appliquent qu'aux hooks basés sur les outils (PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest). Pour les hooks de cycle de vie comme Stop, SessionStart et Notification, les matchers sont ignorés et le hook se déclenche pour tous les événements de ce type.

    Découvrir les noms d'outils : Vérifiez le tableau tools dans le message système initial lorsque votre session démarre, ou ajoutez un hook sans matcher pour journaliser tous les appels d'outils.

    Nommage des outils MCP : Les outils MCP commencent toujours par mcp__ suivi du nom du serveur et de l'action : mcp__<server>__<action>. Par exemple, si vous configurez un serveur nommé playwright, ses outils seront nommés mcp__playwright__browser_screenshot, mcp__playwright__browser_click, etc. Le nom du serveur provient de la clé que vous utilisez dans la configuration mcpServers.

    Cet exemple utilise un matcher pour exécuter un hook uniquement pour les outils qui modifient les fichiers lorsque l'événement PreToolUse se déclenche :

    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                HookMatcher(matcher='Write|Edit', hooks=[validate_file_path])
            ]
        }
    )

    Entrées de la fonction de rappel

    Chaque rappel de hook reçoit trois arguments :

    1. Données d'entrée (dict / HookInput) : Détails de l'événement. Voir données d'entrée pour les champs
    2. ID d'utilisation d'outil (str | None / string | null) : Corréler les événements PreToolUse et PostToolUse
    3. Contexte (HookContext) : En TypeScript, contient une propriété signal (AbortSignal) pour l'annulation. Transmettez-la aux opérations asynchrones comme fetch() pour qu'elles s'annulent automatiquement si le hook expire. En Python, cet argument est réservé pour une utilisation future.

    Données d'entrée

    Le premier argument de votre rappel de hook contient des informations sur l'événement. Les noms de champs sont identiques dans les SDK (tous utilisent snake_case).

    Champs communs présents dans tous les types de hooks :

    ChampTypeDescription
    hook_event_namestringLe type de hook (PreToolUse, PostToolUse, etc.)
    session_idstringIdentifiant de session actuel
    transcript_pathstringChemin vers la transcription de la conversation
    cwdstringRépertoire de travail actuel

    Champs spécifiques au hook varient selon le type de hook. Les éléments marqués TS ne sont disponibles que dans le SDK TypeScript :

    ChampTypeDescriptionHooks
    tool_namestringNom de l'outil appeléPreToolUse, PostToolUse, PostToolUseFailureTS, PermissionRequestTS
    tool_inputobjectArguments passés à l'outilPreToolUse, PostToolUse, PostToolUseFailureTS, PermissionRequestTS
    tool_responseanyRésultat retourné par l'exécution de l'outilPostToolUse
    errorstringMessage d'erreur de l'échec de l'exécution de l'outilPostToolUseFailureTS
    is_interruptbooleanSi l'échec a été causé par une interruptionPostToolUseFailureTS
    promptstringLe texte du message utilisateurUserPromptSubmit
    stop_hook_activebooleanSi un hook d'arrêt est actuellement en cours de traitementStop, SubagentStop
    agent_idstringIdentifiant unique du sous-agentSubagentStartTS, SubagentStopTS
    agent_typestringType/rôle du sous-agentSubagentStartTS
    agent_transcript_pathstringChemin vers la transcription de conversation du sous-agentSubagentStopTS
    triggerstringCe qui a déclenché la compaction : manual ou autoPreCompact
    custom_instructionsstringInstructions personnalisées fournies pour la compactionPreCompact
    permission_suggestionsarrayMises à jour de permissions suggérées pour l'outilPermissionRequestTS
    sourcestringComment la session a démarré : startup, resume, clear, ou compactSessionStartTS
    reasonstringPourquoi la session s'est terminée : clear, logout, prompt_input_exit, bypass_permissions_disabled, ou otherSessionEndTS
    messagestringMessage de statut de l'agentNotificationTS
    notification_typestringType de notification : permission_prompt, idle_prompt, auth_success, ou elicitation_dialogNotificationTS
    titlestringTitre optionnel défini par l'agentNotificationTS

    Le code ci-dessous définit un rappel de hook qui utilise tool_name et tool_input pour journaliser les détails de chaque appel d'outil :

    async def log_tool_calls(input_data, tool_use_id, context):
        if input_data['hook_event_name'] == 'PreToolUse':
            print(f"Tool: {input_data['tool_name']}")
            print(f"Input: {input_data['tool_input']}")
        return {}

    Sorties du rappel

    Votre fonction de rappel retourne un objet qui indique au SDK comment procéder. Retournez un objet vide {} pour autoriser l'opération sans modifications. Pour bloquer, modifier ou ajouter du contexte à l'opération, retournez un objet avec un champ hookSpecificOutput contenant votre décision.

    Champs de niveau supérieur (en dehors de hookSpecificOutput) :

    ChampTypeDescription
    continuebooleanSi l'agent doit continuer après ce hook (défaut : true)
    stopReasonstringMessage affiché lorsque continue est false
    suppressOutputbooleanMasquer stdout de la transcription (défaut : false)
    systemMessagestringMessage injecté dans la conversation pour que Claude le voie

    Champs à l'intérieur de hookSpecificOutput :

    ChampTypeHooksDescription
    hookEventNamestringTousRequis. Utilisez input.hook_event_name pour correspondre à l'événement actuel
    permissionDecision'allow' | 'deny' | 'ask'PreToolUseContrôle si l'outil s'exécute
    permissionDecisionReasonstringPreToolUseExplication affichée à Claude pour la décision
    updatedInputobjectPreToolUseEntrée d'outil modifiée (nécessite permissionDecision: 'allow')
    additionalContextstringPreToolUse, PostToolUse, UserPromptSubmit, SessionStartTS, SubagentStartTSContexte ajouté à la conversation

    Cet exemple bloque les opérations d'écriture dans le répertoire /etc tout en injectant un message système pour rappeler à Claude les pratiques sûres en matière de fichiers :

    async def block_etc_writes(input_data, tool_use_id, context):
        file_path = input_data['tool_input'].get('file_path', '')
    
        if file_path.startswith('/etc'):
            return {
                # Champ de niveau supérieur : injecter des conseils dans la conversation
                'systemMessage': 'Remember: system directories like /etc are protected.',
                # hookSpecificOutput : bloquer l'opération
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Writing to /etc is not allowed'
                }
            }
        return {}

    Flux de décision de permission

    Lorsque plusieurs hooks ou règles de permission s'appliquent, le SDK les évalue dans cet ordre :

    1. Les règles Deny sont vérifiées en premier (toute correspondance = refus immédiat).
    2. Les règles Ask sont vérifiées en deuxième.
    3. Les règles Allow sont vérifiées en troisième.
    4. Par défaut Ask si rien ne correspond.

    Si un hook retourne deny, l'opération est bloquée—les autres hooks retournant allow ne la remplaceront pas.

    Bloquer un outil

    Retournez une décision de refus pour empêcher l'exécution de l'outil :

    async def block_dangerous_commands(input_data, tool_use_id, context):
        if input_data['hook_event_name'] != 'PreToolUse':
            return {}
    
        command = input_data['tool_input'].get('command', '')
    
        if 'rm -rf /' in command:
            return {
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Dangerous command blocked: rm -rf /'
                }
            }
        return {}

    Modifier l'entrée de l'outil

    Retournez une entrée mise à jour pour modifier ce que l'outil reçoit :

    async def redirect_to_sandbox(input_data, tool_use_id, context):
        if input_data['hook_event_name'] != 'PreToolUse':
            return {}
    
        if input_data['tool_name'] == 'Write':
            original_path = input_data['tool_input'].get('file_path', '')
            return {
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'allow',
                    'updatedInput': {
                        **input_data['tool_input'],
                        'file_path': f'/sandbox{original_path}'
                    }
                }
            }
        return {}

    Lors de l'utilisation de updatedInput, vous devez également inclure permissionDecision. Retournez toujours un nouvel objet plutôt que de muter l'original tool_input.

    Ajouter un message système

    Injecter du contexte dans la conversation :

    async def add_security_reminder(input_data, tool_use_id, context):
        return {
            'systemMessage': 'Remember to follow security best practices.'
        }

    Approuver automatiquement des outils spécifiques

    Contourner les invites de permission pour les outils de confiance. C'est utile lorsque vous souhaitez que certaines opérations s'exécutent sans confirmation de l'utilisateur :

    async def auto_approve_read_only(input_data, tool_use_id, context):
        if input_data['hook_event_name'] != 'PreToolUse':
            return {}
    
        read_only_tools = ['Read', 'Glob', 'Grep', 'LS']
        if input_data['tool_name'] in read_only_tools:
            return {
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'allow',
                    'permissionDecisionReason': 'Read-only tool auto-approved'
                }
            }
        return {}

    Le champ permissionDecision accepte trois valeurs : 'allow' (approbation automatique), 'deny' (bloquer), ou 'ask' (demander une confirmation).

    Gérer les scénarios avancés

    Ces modèles vous aident à construire des systèmes de hooks plus sophistiqués pour les cas d'usage complexes.

    Chaîner plusieurs hooks

    Les hooks s'exécutent dans l'ordre dans lequel ils apparaissent dans le tableau. Gardez chaque hook concentré sur une seule responsabilité et chaînez plusieurs hooks pour une logique complexe. Cet exemple exécute les quatre hooks pour chaque appel d'outil (aucun matcher spécifié) :

    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                HookMatcher(hooks=[rate_limiter]),        # Premier : vérifier les limites de débit
                HookMatcher(hooks=[authorization_check]), # Deuxième : vérifier les permissions
                HookMatcher(hooks=[input_sanitizer]),     # Troisième : nettoyer les entrées
                HookMatcher(hooks=[audit_logger])         # Dernier : journaliser l'action
            ]
        }
    )

    Matchers spécifiques aux outils avec regex

    Utilisez des modèles regex pour faire correspondre plusieurs outils :

    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                # Faire correspondre les outils de modification de fichiers
                HookMatcher(matcher='Write|Edit|Delete', hooks=[file_security_hook]),
    
                # Faire correspondre tous les outils MCP
                HookMatcher(matcher='^mcp__', hooks=[mcp_audit_hook]),
    
                # Faire correspondre tout (aucun matcher)
                HookMatcher(hooks=[global_logger])
            ]
        }
    )

    Les matchers ne correspondent qu'aux noms d'outils, pas aux chemins de fichiers ou autres arguments. Pour filtrer par chemin de fichier, vérifiez tool_input.file_path à l'intérieur de votre rappel de hook.

    Suivi de l'activité des sous-agents

    Utilisez les hooks SubagentStop pour surveiller l'achèvement des sous-agents. Le tool_use_id aide à corréler les appels de l'agent parent avec leurs sous-agents :

    async def subagent_tracker(input_data, tool_use_id, context):
        if input_data['hook_event_name'] == 'SubagentStop':
            print(f"[SUBAGENT] Completed")
            print(f"  Tool use ID: {tool_use_id}")
            print(f"  Stop hook active: {input_data.get('stop_hook_active')}")
        return {}
    
    options = ClaudeAgentOptions(
        hooks={
            'SubagentStop': [HookMatcher(hooks=[subagent_tracker])]
        }
    )

    Opérations asynchrones dans les hooks

    Les hooks peuvent effectuer des opérations asynchrones comme des requêtes HTTP. Gérez les erreurs correctement en capturant les exceptions au lieu de les lever. En TypeScript, transmettez le signal à fetch() pour que la requête s'annule si le hook expire :

    import aiohttp
    from datetime import datetime
    
    async def webhook_notifier(input_data, tool_use_id, context):
        if input_data['hook_event_name'] != 'PostToolUse':
            return {}
    
        try:
            async with aiohttp.ClientSession() as session:
                await session.post(
                    'https://api.example.com/webhook',
                    json={
                        'tool': input_data['tool_name'],
                        'timestamp': datetime.now().isoformat()
                    }
                )
        except Exception as e:
            print(f'Webhook request failed: {e}')
    
        return {}

    Envoyer des notifications (TypeScript uniquement)

    Utilisez les hooks Notification pour recevoir les mises à jour de statut de l'agent et les transférer vers des services externes comme Slack ou des tableaux de bord de surveillance :

    TypeScript
    import { query, HookCallback, NotificationHookInput } from "@anthropic-ai/claude-agent-sdk";
    
    const notificationHandler: HookCallback = async (input, toolUseID, { signal }) => {
      const notification = input as NotificationHookInput;
    
      await fetch('https://hooks.slack.com/services/YOUR/WEBHOOK/URL', {
        method: 'POST',
        body: JSON.stringify({
          text: `Agent status: ${notification.message}`
        }),
        signal
      });
    
      return {};
    };
    
    for await (const message of query({
      prompt: "Analyze this codebase",
      options: {
        hooks: {
          Notification: [{ hooks: [notificationHandler] }]
        }
      }
    })) {
      console.log(message);
    }

    Corriger les problèmes courants

    Cette section couvre les problèmes courants et comment les résoudre.

    Le hook ne se déclenche pas

    • Vérifiez que le nom de l'événement du hook est correct et sensible à la casse (PreToolUse, pas preToolUse)
    • Vérifiez que votre modèle de matcher correspond exactement au nom de l'outil
    • Assurez-vous que le hook se trouve sous le type d'événement correct dans options.hooks
    • Pour les hooks SubagentStop, Stop, SessionStart, SessionEnd et Notification, les matchers sont ignorés. Ces hooks se déclenchent pour tous les événements de ce type.
    • Les hooks peuvent ne pas se déclencher lorsque l'agent atteint la limite max_turns car la session se termine avant que les hooks puissent s'exécuter

    Le matcher ne filtre pas comme prévu

    Les matchers ne correspondent qu'aux noms d'outils, pas aux chemins de fichiers ou autres arguments. Pour filtrer par chemin de fichier, vérifiez tool_input.file_path à l'intérieur de votre hook :

    const myHook: HookCallback = async (input, toolUseID, { signal }) => {
      const preInput = input as PreToolUseHookInput;
      const filePath = preInput.tool_input?.file_path as string;
      if (!filePath?.endsWith('.md')) return {};  // Ignorer les fichiers non-markdown
      // Traiter les fichiers markdown...
    };

    Expiration du hook

    • Augmentez la valeur timeout dans la configuration HookMatcher
    • Utilisez le AbortSignal du troisième argument de rappel pour gérer l'annulation correctement en TypeScript

    Outil bloqué de manière inattendue

    • Vérifiez tous les hooks PreToolUse pour les retours permissionDecision: 'deny'
    • Ajoutez une journalisation à vos hooks pour voir quel permissionDecisionReason ils retournent
    • Vérifiez que les modèles de matcher ne sont pas trop larges (un matcher vide correspond à tous les outils)

    L'entrée modifiée n'est pas appliquée

    • Assurez-vous que updatedInput se trouve à l'intérieur de hookSpecificOutput, pas au niveau supérieur :

      return {
        hookSpecificOutput: {
          hookEventName: input.hook_event_name,
          permissionDecision: 'allow',
          updatedInput: { command: 'new command' }
        }
      };
    • Vous devez également retourner permissionDecision: 'allow' pour que la modification d'entrée prenne effet

    • Incluez hookEventName dans hookSpecificOutput pour identifier le type de hook pour lequel la sortie est destinée

    Les hooks de session ne sont pas disponibles

    Les hooks SessionStart, SessionEnd et Notification ne sont disponibles que dans le SDK TypeScript. Le SDK Python ne supporte pas ces événements en raison de limitations de configuration.

    Les invites de permission des sous-agents se multiplient

    Lors de la génération de plusieurs sous-agents, chacun peut demander des permissions séparément. Les sous-agents n'héritent pas automatiquement des permissions de l'agent parent. Pour éviter les invites répétées, utilisez les hooks PreToolUse pour approuver automatiquement des outils spécifiques, ou configurez des règles de permission qui s'appliquent aux sessions des sous-agents.

    Boucles de hooks récursives avec des sous-agents

    Un hook UserPromptSubmit qui génère des sous-agents peut créer des boucles infinies si ces sous-agents déclenchent le même hook. Pour éviter cela :

    • Vérifiez un indicateur de sous-agent dans l'entrée du hook avant de générer
    • Utilisez le champ parent_tool_use_id pour détecter si vous êtes déjà dans un contexte de sous-agent
    • Limitez les hooks pour qu'ils s'exécutent uniquement pour la session de l'agent de niveau supérieur

    systemMessage n'apparaît pas dans la sortie

    Le champ systemMessage ajoute du contexte à la conversation que le modèle voit, mais il peut ne pas apparaître dans tous les modes de sortie du SDK. Si vous devez exposer les décisions de hook à votre application, journalisez-les séparément ou utilisez un canal de sortie dédié.

    En savoir plus

    • Permissions : contrôler ce que votre agent peut faire
    • Outils personnalisés : construire des outils pour étendre les capacités de l'agent
    • Référence du SDK TypeScript
    • Référence du SDK Python

    Was this page helpful?

    • Hooks disponibles
    • Cas d'usage courants
    • Configurer les hooks
    • Matchers
    • Entrées de la fonction de rappel
    • Données d'entrée
    • Sorties du rappel
    • Gérer les scénarios avancés
    • Chaîner plusieurs hooks
    • Matchers spécifiques aux outils avec regex
    • Suivi de l'activité des sous-agents
    • Opérations asynchrones dans les hooks
    • Envoyer des notifications (TypeScript uniquement)
    • Corriger les problèmes courants
    • Le hook ne se déclenche pas
    • Le matcher ne filtre pas comme prévu
    • Expiration du hook
    • Outil bloqué de manière inattendue
    • L'entrée modifiée n'est pas appliquée
    • Les hooks de session ne sont pas disponibles
    • Les invites de permission des sous-agents se multiplient
    • Boucles de hooks récursives avec des sous-agents
    • systemMessage n'apparaît pas dans la sortie
    • En savoir plus