Loading...
    • Entwicklerleitfaden
    • API-Referenz
    • MCP
    • Ressourcen
    • Versionshinweise
    Search...
    ⌘K
    Erste Schritte
    Einführung in ClaudeSchnelleinstieg
    Modelle & Preise
    ModellübersichtModell auswählenNeuerungen in Claude 4.6MigrationsleitfadenModellabschreibungenPreise
    Mit Claude entwickeln
    FunktionsübersichtMessages API verwendenStop-Gründe verarbeitenBest Practices für Prompts
    Modellfähigkeiten
    Extended ThinkingAdaptive ThinkingAufwandFast Mode (Research Preview)Strukturierte AusgabenZitateStreaming MessagesBatch-VerarbeitungPDF-UnterstützungSuchergebnisseMehrsprachige UnterstützungEmbeddingsVision
    Tools
    ÜbersichtTool-Nutzung implementierenWeb-Such-ToolWeb-Abruf-ToolCode-Ausführungs-ToolMemory-ToolBash-ToolComputer-Use-ToolText-Editor-Tool
    Tool-Infrastruktur
    Tool-SucheProgrammgesteuerte Tool-AufrufeFeingranulares Tool-Streaming
    Kontextverwaltung
    KontextfensterKomprimierungKontextbearbeitungPrompt CachingToken-Zählung
    Dateien & Assets
    Files API
    Agent Skills
    ÜbersichtSchnelleinstiegBest PracticesSkills für UnternehmenSkills mit der API verwenden
    Agent SDK
    ÜbersichtSchnelleinstiegTypeScript SDKTypeScript V2 (Preview)Python SDKMigrationsleitfaden
    Streaming-EingabeAntworten in Echtzeit streamenStop-Gründe verarbeitenBerechtigungen verarbeitenBenutzergenehmigungen und EingabeAusführung mit Hooks steuernSitzungsverwaltungDatei-CheckpointingStrukturierte Ausgaben im SDKAgent SDK hostenKI-Agenten sicher bereitstellenSystem-Prompts ändernMCP im SDKBenutzerdefinierte ToolsSubagents im SDKSlash-Befehle im SDKAgent Skills im SDKKosten und Nutzung verfolgenTodo-ListenPlugins im SDK
    MCP in der API
    MCP-ConnectorRemote MCP-Server
    Claude auf Plattformen von Drittanbietern
    Amazon BedrockMicrosoft FoundryVertex AI
    Prompt Engineering
    ÜbersichtPrompt-GeneratorPrompt-Vorlagen verwendenPrompt-VerbessererKlar und direkt seinBeispiele verwenden (Multishot Prompting)Claude denken lassen (CoT)XML-Tags verwendenClaude eine Rolle geben (System Prompts)Komplexe Prompts verkettenTipps für lange KontexteTipps für Extended Thinking
    Testen & Evaluieren
    Erfolgskriterien definierenTestfälle entwickelnEvaluierungstool verwendenLatenz reduzieren
    Schutzmaßnahmen verstärken
    Halluzinationen reduzierenAusgabekonsistenz erhöhenJailbreaks abschwächenStreaming-AblehnungenPrompt-Lecks reduzierenClaude im Charakter halten
    Verwaltung und Überwachung
    Admin API ÜbersichtDatenspeicherortArbeitsbereicheUsage and Cost APIClaude Code Analytics APIZero Data Retention
    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
    Leitfäden

    Agentverhalten mit Hooks abfangen und steuern

    Agentverhalten an wichtigen Ausführungspunkten mit Hooks abfangen und anpassen

    Hooks ermöglichen es dir, die Agentausführung an wichtigen Punkten abzufangen, um Validierung, Protokollierung, Sicherheitskontrollen oder benutzerdefinierte Logik hinzuzufügen. Mit Hooks kannst du:

    • Gefährliche Operationen blockieren, bevor sie ausgeführt werden, wie destruktive Shell-Befehle oder nicht autorisierter Dateizugriff
    • Protokollieren und überprüfen jeden Tool-Aufruf für Compliance, Debugging oder Analytik
    • Eingaben und Ausgaben transformieren, um Daten zu bereinigen, Anmeldedaten einzufügen oder Dateipfade umzuleiten
    • Menschliche Genehmigung erfordern für sensible Aktionen wie Datenbankschreibvorgänge oder API-Aufrufe
    • Sitzungslebenszyklus verfolgen, um den Status zu verwalten, Ressourcen freizugeben oder Benachrichtigungen zu senden

    Ein Hook hat zwei Teile:

    1. Die Callback-Funktion: die Logik, die ausgeführt wird, wenn der Hook ausgelöst wird
    2. Die Hook-Konfiguration: teilt dem SDK mit, welches Ereignis abgefangen werden soll (wie PreToolUse) und welche Tools übereinstimmen sollen

    Das folgende Beispiel blockiert den Agent daran, .env-Dateien zu ändern. Definiere zunächst einen Callback, der den Dateipfad überprüft, und übergebe ihn dann an query(), um ihn vor jedem Write- oder Edit-Tool-Aufruf auszuführen:

    import asyncio
    from claude_agent_sdk import query, ClaudeAgentOptions, HookMatcher
    
    # Define a hook callback that receives tool call details
    async def protect_env_files(input_data, tool_use_id, context):
        # Extract the file path from the tool's input arguments
        file_path = input_data['tool_input'].get('file_path', '')
        file_name = file_path.split('/')[-1]
    
        # Block the operation if targeting a .env file
        if file_name == '.env':
            return {
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Cannot modify .env files'
                }
            }
    
        # Return empty object to allow the operation
        return {}
    
    async def main():
        async for message in query(
            prompt="Update the database configuration",
            options=ClaudeAgentOptions(
                hooks={
                    # Register the hook for PreToolUse events
                    # The matcher filters to only Write and Edit tool calls
                    'PreToolUse': [HookMatcher(matcher='Write|Edit', hooks=[protect_env_files])]
                }
            )
        ):
            print(message)
    
    asyncio.run(main())

    Dies ist ein PreToolUse-Hook. Er wird vor der Werkzeugausführung ausgeführt und kann Operationen basierend auf deiner Logik blockieren oder zulassen. Der Rest dieses Leitfadens behandelt alle verfügbaren Hooks, ihre Konfigurationsoptionen und Muster für häufige Anwendungsfälle.

    Verfügbare Hooks

    Das SDK bietet Hooks für verschiedene Phasen der Agentausführung. Einige Hooks sind in beiden SDKs verfügbar, während andere nur in TypeScript verfügbar sind, da das Python SDK sie nicht unterstützt.

    Hook-EreignisPython SDKTypeScript SDKWas löst es ausBeispiel-Anwendungsfall
    PreToolUseJaJaTool-Aufrufanforderung (kann blockiert oder geändert werden)Blockiere gefährliche Shell-Befehle
    PostToolUseJaJaWerkzeugausführungsergebnisProtokolliere alle Dateiänderungen im Audit-Trail
    PostToolUseFailureNeinJaWerkzeugausführungsfehlerBehandle oder protokolliere Werkzeugfehler
    UserPromptSubmitJaJaBenutzer-Prompt-EinreichungInjiziere zusätzlichen Kontext in Prompts
    StopJaJaAgent-AusführungsstoppSpeichere den Sitzungsstatus vor dem Beenden
    SubagentStartNeinJaSubagent-InitialisierungVerfolge parallele Task-Spawning
    SubagentStopJaJaSubagent-AbschlussAggregiere Ergebnisse aus parallelen Tasks
    PreCompactJaJaAnforderung zur GesprächskomprimierungArchiviere vollständiges Transkript vor der Zusammenfassung
    PermissionRequestNeinJaGenehmigungsdialog würde angezeigtBenutzerdefinierte Genehmigungsbehandlung
    SessionStartNeinJaSitzungsinitialisierungInitialisiere Protokollierung und Telemetrie
    SessionEndNeinJaSitzungsbeendigungBereinige temporäre Ressourcen
    NotificationNeinJaAgent-StatusmeldungenSende Agent-Statusaktualisierungen an Slack oder PagerDuty

    Häufige Anwendungsfälle

    Hooks sind flexibel genug, um viele verschiedene Szenarien zu handhaben. Hier sind einige der häufigsten Muster, organisiert nach Kategorie.

    Hooks konfigurieren

    Um einen Hook für deinen Agent zu konfigurieren, übergebe den Hook im Parameter options.hooks beim Aufrufen von query():

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

    Die hooks-Option ist ein Wörterbuch (Python) oder Objekt (TypeScript), wobei:

    • Schlüssel Hook-Ereignisnamen sind (z. B. 'PreToolUse', 'PostToolUse', 'Stop')
    • Werte Arrays von Matchern sind, die jeweils ein optionales Filtermuster und deine Callback-Funktionen enthalten

    Deine Hook-Callback-Funktionen erhalten Eingabedaten über das Ereignis und geben eine Antwort zurück, damit der Agent weiß, ob er die Operation zulassen, blockieren oder ändern soll.

    Matcher

    Verwende Matcher, um zu filtern, welche Tools deine Callbacks auslösen:

    OptionTypStandardBeschreibung
    matcherstringundefinedRegex-Muster zum Abgleich von Tool-Namen. Integrierte Tools umfassen Bash, Read, Write, Edit, Glob, Grep, WebFetch, Task und andere. MCP-Tools verwenden das Muster mcp__<server>__<action>.
    hooksHookCallback[]-Erforderlich. Array von Callback-Funktionen, die ausgeführt werden, wenn das Muster übereinstimmt
    timeoutnumber60Timeout in Sekunden; erhöhe für Hooks, die externe API-Aufrufe tätigen

    Verwende das matcher-Muster, um nach Möglichkeit spezifische Tools anzusteuern. Ein Matcher mit 'Bash' wird nur für Bash-Befehle ausgeführt, während das Weglassen des Musters deine Callbacks für jeden Tool-Aufruf ausführt. Beachte, dass Matcher nur nach Tool-Namen filtern, nicht nach Dateipfaden oder anderen Argumenten – um nach Dateipfad zu filtern, überprüfe tool_input.file_path in deinem Callback.

    Matcher gelten nur für Tool-basierte Hooks (PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest). Für Lifecycle-Hooks wie Stop, SessionStart und Notification werden Matcher ignoriert und der Hook wird für alle Ereignisse dieses Typs ausgelöst.

    Tool-Namen entdecken: Überprüfe das tools-Array in der anfänglichen Systemmeldung, wenn deine Sitzung startet, oder füge einen Hook ohne Matcher hinzu, um alle Tool-Aufrufe zu protokollieren.

    MCP-Tool-Benennung: MCP-Tools beginnen immer mit mcp__ gefolgt vom Servernamen und der Aktion: mcp__<server>__<action>. Wenn du beispielsweise einen Server namens playwright konfigurierst, werden seine Tools mcp__playwright__browser_screenshot, mcp__playwright__browser_click usw. benannt. Der Servername stammt aus dem Schlüssel, den du in der mcpServers-Konfiguration verwendest.

    Dieses Beispiel verwendet einen Matcher, um einen Hook nur für dateimodifizierende Tools auszuführen, wenn das PreToolUse-Ereignis ausgelöst wird:

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

    Callback-Funktionseingaben

    Jeder Hook-Callback erhält drei Argumente:

    1. Eingabedaten (dict / HookInput): Ereignisdetails. Siehe Eingabedaten für Felder
    2. Tool-Use-ID (str | None / string | null): Korreliere PreToolUse- und PostToolUse-Ereignisse
    3. Kontext (HookContext): In TypeScript enthält eine signal-Eigenschaft (AbortSignal) zur Stornierung. Übergebe dies an asynchrone Operationen wie fetch(), damit sie automatisch storniert werden, wenn der Hook das Timeout überschreitet. In Python ist dieses Argument für zukünftige Verwendung reserviert.

    Eingabedaten

    Das erste Argument für deinen Hook-Callback enthält Informationen über das Ereignis. Feldnamen sind über SDKs identisch (beide verwenden snake_case).

    Gemeinsame Felder in allen Hook-Typen:

    FeldTypBeschreibung
    hook_event_namestringDer Hook-Typ (PreToolUse, PostToolUse usw.)
    session_idstringAktuelle Sitzungskennung
    transcript_pathstringPfad zum Gesprächstranskript
    cwdstringAktuelles Arbeitsverzeichnis

    Hook-spezifische Felder variieren je nach Hook-Typ. Elemente, die mit TS gekennzeichnet sind, sind nur im TypeScript SDK verfügbar:

    FeldTypBeschreibungHooks
    tool_namestringName des aufgerufenen ToolsPreToolUse, PostToolUse, PostToolUseFailureTS, PermissionRequestTS
    tool_inputobjectAn das Tool übergebene ArgumentePreToolUse, PostToolUse, PostToolUseFailureTS, PermissionRequestTS
    tool_responseanyVon der Werkzeugausführung zurückgegebenes ErgebnisPostToolUse
    errorstringFehlermeldung aus WerkzeugausführungsfehlerPostToolUseFailureTS
    is_interruptbooleanOb der Fehler durch eine Unterbrechung verursacht wurdePostToolUseFailureTS
    promptstringDer Text des Benutzer-PromptsUserPromptSubmit
    stop_hook_activebooleanOb ein Stop-Hook gerade verarbeitet wirdStop, SubagentStop
    agent_idstringEindeutige Kennung für den SubagentSubagentStartTS, SubagentStopTS
    agent_typestringTyp/Rolle des SubagentsSubagentStartTS
    agent_transcript_pathstringPfad zum Gesprächstranskript des SubagentsSubagentStopTS
    triggerstringWas die Komprimierung ausgelöst hat: manual oder autoPreCompact
    custom_instructionsstringBenutzerdefinierte Anweisungen für die KomprimierungPreCompact
    permission_suggestionsarrayVorgeschlagene Genehmigungsaktualisierungen für das ToolPermissionRequestTS
    sourcestringWie die Sitzung gestartet wurde: startup, resume, clear oder compactSessionStartTS
    reasonstringWarum die Sitzung endete: clear, logout, prompt_input_exit, bypass_permissions_disabled oder otherSessionEndTS
    messagestringStatusmeldung vom AgentNotificationTS
    notification_typestringArt der Benachrichtigung: permission_prompt, idle_prompt, auth_success oder elicitation_dialogNotificationTS
    titlestringOptionaler vom Agent festgelegter TitelNotificationTS

    Der folgende Code definiert einen Hook-Callback, der tool_name und tool_input verwendet, um Details zu jedem Tool-Aufruf zu protokollieren:

    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 {}

    Callback-Ausgaben

    Deine Callback-Funktion gibt ein Objekt zurück, das dem SDK mitteilt, wie es fortfahren soll. Gib ein leeres Objekt {} zurück, um die Operation ohne Änderungen zuzulassen. Um die Operation zu blockieren, zu ändern oder Kontext hinzuzufügen, gib ein Objekt mit einem hookSpecificOutput-Feld zurück, das deine Entscheidung enthält.

    Top-Level-Felder (außerhalb von hookSpecificOutput):

    FeldTypBeschreibung
    continuebooleanOb der Agent nach diesem Hook fortfahren soll (Standard: true)
    stopReasonstringMeldung, die angezeigt wird, wenn continue false ist
    suppressOutputbooleanVerstecke stdout aus dem Transkript (Standard: false)
    systemMessagestringMeldung, die in das Gespräch für Claude eingefügt wird

    Felder innerhalb von hookSpecificOutput:

    FeldTypHooksBeschreibung
    hookEventNamestringAlleErforderlich. Verwende input.hook_event_name, um das aktuelle Ereignis abzugleichen
    permissionDecision'allow' | 'deny' | 'ask'PreToolUseSteuert, ob das Tool ausgeführt wird
    permissionDecisionReasonstringPreToolUseErklärung, die Claude für die Entscheidung angezeigt wird
    updatedInputobjectPreToolUseGeänderte Tool-Eingabe (erfordert permissionDecision: 'allow')
    additionalContextstringPreToolUse, PostToolUse, UserPromptSubmit, SessionStartTS, SubagentStartTSKontext, der zum Gespräch hinzugefügt wird

    Dieses Beispiel blockiert Schreibvorgänge in das /etc-Verzeichnis und injiziert eine Systemmeldung, um Claude an sichere Dateipraktiken zu erinnern:

    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 {
                # Top-level field: inject guidance into the conversation
                'systemMessage': 'Remember: system directories like /etc are protected.',
                # hookSpecificOutput: block the operation
                'hookSpecificOutput': {
                    'hookEventName': input_data['hook_event_name'],
                    'permissionDecision': 'deny',
                    'permissionDecisionReason': 'Writing to /etc is not allowed'
                }
            }
        return {}

    Genehmigungsentscheidungsfluss

    Wenn mehrere Hooks oder Genehmigungsregeln gelten, wertet das SDK sie in dieser Reihenfolge aus:

    1. Deny-Regeln werden zuerst überprüft (jede Übereinstimmung = sofortige Ablehnung).
    2. Ask-Regeln werden zweite überprüft.
    3. Allow-Regeln werden dritte überprüft.
    4. Standard auf Ask, wenn nichts übereinstimmt.

    Wenn ein Hook deny zurückgibt, wird die Operation blockiert – andere Hooks, die allow zurückgeben, können dies nicht überschreiben.

    Ein Tool blockieren

    Gib eine Deny-Entscheidung zurück, um die Werkzeugausführung zu verhindern:

    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 {}

    Tool-Eingabe ändern

    Gib aktualisierte Eingabe zurück, um zu ändern, was das Tool erhält:

    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 {}

    Wenn du updatedInput verwendest, musst du auch permissionDecision einschließen. Gib immer ein neues Objekt zurück, anstatt das ursprüngliche tool_input zu mutieren.

    Eine Systemmeldung hinzufügen

    Injiziere Kontext in das Gespräch:

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

    Spezifische Tools automatisch genehmigen

    Umgehe Genehmigungsaufforderungen für vertrauenswürdige Tools. Dies ist nützlich, wenn du möchtest, dass bestimmte Operationen ohne Benutzerbestätigung ausgeführt werden:

    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 {}

    Das permissionDecision-Feld akzeptiert drei Werte: 'allow' (automatisch genehmigen), 'deny' (blockieren) oder 'ask' (zur Bestätigung auffordern).

    Fortgeschrittene Szenarien handhaben

    Diese Muster helfen dir, komplexere Hook-Systeme für komplexe Anwendungsfälle zu erstellen.

    Mehrere Hooks verketten

    Hooks werden in der Reihenfolge ausgeführt, in der sie im Array angezeigt werden. Halte jeden Hook auf eine einzelne Verantwortung konzentriert und verkette mehrere Hooks für komplexe Logik. Dieses Beispiel führt alle vier Hooks für jeden Tool-Aufruf aus (kein Matcher angegeben):

    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                HookMatcher(hooks=[rate_limiter]),        # First: check rate limits
                HookMatcher(hooks=[authorization_check]), # Second: verify permissions
                HookMatcher(hooks=[input_sanitizer]),     # Third: sanitize inputs
                HookMatcher(hooks=[audit_logger])         # Last: log the action
            ]
        }
    )

    Tool-spezifische Matcher mit Regex

    Verwende Regex-Muster, um mehrere Tools abzugleichen:

    options = ClaudeAgentOptions(
        hooks={
            'PreToolUse': [
                # Match file modification tools
                HookMatcher(matcher='Write|Edit|Delete', hooks=[file_security_hook]),
    
                # Match all MCP tools
                HookMatcher(matcher='^mcp__', hooks=[mcp_audit_hook]),
    
                # Match everything (no matcher)
                HookMatcher(hooks=[global_logger])
            ]
        }
    )

    Matcher gleichen nur Tool-Namen ab, nicht Dateipfade oder andere Argumente. Um nach Dateipfad zu filtern, überprüfe tool_input.file_path in deinem Hook-Callback.

    Subagent-Aktivität verfolgen

    Verwende SubagentStop-Hooks, um die Subagent-Fertigstellung zu überwachen. Die tool_use_id hilft, Parent-Agent-Aufrufe mit ihren Subagents zu korrelieren:

    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])]
        }
    )

    Asynchrone Operationen in Hooks

    Hooks können asynchrone Operationen wie HTTP-Anfragen durchführen. Behandle Fehler elegant, indem du Ausnahmen abfängst, anstatt sie zu werfen. In TypeScript übergebe das signal an fetch(), damit die Anfrage storniert wird, wenn der Hook das Timeout überschreitet:

    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 {}

    Benachrichtigungen senden (nur TypeScript)

    Verwende Notification-Hooks, um Statusaktualisierungen vom Agent zu erhalten und sie an externe Dienste wie Slack oder Überwachungs-Dashboards weiterzuleiten:

    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);
    }

    Häufige Probleme beheben

    Dieser Abschnitt behandelt häufige Probleme und deren Lösungen.

    Hook wird nicht ausgelöst

    • Überprüfe, dass der Hook-Ereignisname korrekt und case-sensitiv ist (PreToolUse, nicht preToolUse)
    • Überprüfe, dass dein Matcher-Muster den Tool-Namen genau abgleicht
    • Stelle sicher, dass der Hook unter dem richtigen Ereignistyp in options.hooks ist
    • Für SubagentStop-, Stop-, SessionStart-, SessionEnd- und Notification-Hooks werden Matcher ignoriert. Diese Hooks werden für alle Ereignisse dieses Typs ausgelöst.
    • Hooks werden möglicherweise nicht ausgelöst, wenn der Agent das max_turns-Limit erreicht, da die Sitzung endet, bevor Hooks ausgeführt werden können

    Matcher filtert nicht wie erwartet

    Matcher gleichen nur Tool-Namen ab, nicht Dateipfade oder andere Argumente. Um nach Dateipfad zu filtern, überprüfe tool_input.file_path in deinem 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 {};  // Skip non-markdown files
      // Process markdown files...
    };

    Hook-Timeout

    • Erhöhe den timeout-Wert in der HookMatcher-Konfiguration
    • Verwende das AbortSignal aus dem dritten Callback-Argument, um die Stornierung elegant in TypeScript zu handhaben

    Tool unerwartet blockiert

    • Überprüfe alle PreToolUse-Hooks auf permissionDecision: 'deny'-Rückgaben
    • Füge Protokollierung zu deinen Hooks hinzu, um zu sehen, welche permissionDecisionReason sie zurückgeben
    • Überprüfe, dass Matcher-Muster nicht zu breit sind (ein leerer Matcher gleicht alle Tools ab)

    Geänderte Eingabe nicht angewendet

    • Stelle sicher, dass updatedInput innerhalb von hookSpecificOutput ist, nicht auf der obersten Ebene:

      return {
        hookSpecificOutput: {
          hookEventName: input.hook_event_name,
          permissionDecision: 'allow',
          updatedInput: { command: 'new command' }
        }
      };
    • Du musst auch permissionDecision: 'allow' zurückgeben, damit die Eingabeänderung wirksam wird

    • Schließe hookEventName in hookSpecificOutput ein, um zu identifizieren, welcher Hook-Typ die Ausgabe ist

    Sitzungs-Hooks nicht verfügbar

    SessionStart-, SessionEnd- und Notification-Hooks sind nur im TypeScript SDK verfügbar. Das Python SDK unterstützt diese Ereignisse aufgrund von Setup-Einschränkungen nicht.

    Subagent-Genehmigungsaufforderungen vervielfachen sich

    Beim Spawnen mehrerer Subagents kann jeder einzelne Genehmigungen separat anfordern. Subagents erben nicht automatisch Parent-Agent-Genehmigungen. Um wiederholte Aufforderungen zu vermeiden, verwende PreToolUse-Hooks, um spezifische Tools automatisch zu genehmigen, oder konfiguriere Genehmigungsregeln, die für Subagent-Sitzungen gelten.

    Rekursive Hook-Schleifen mit Subagents

    Ein UserPromptSubmit-Hook, der Subagents spawnt, kann unendliche Schleifen erstellen, wenn diese Subagents denselben Hook auslösen. Um dies zu verhindern:

    • Überprüfe auf einen Subagent-Indikator in der Hook-Eingabe, bevor du spawnt
    • Verwende das parent_tool_use_id-Feld, um zu erkennen, ob du bereits in einem Subagent-Kontext bist
    • Beschränke Hooks, um nur für die Top-Level-Agent-Sitzung ausgeführt zu werden

    systemMessage wird nicht in der Ausgabe angezeigt

    Das systemMessage-Feld fügt Kontext zum Gespräch hinzu, das das Modell sieht, aber es wird möglicherweise nicht in allen SDK-Ausgabemodi angezeigt. Wenn du Hook-Entscheidungen für deine Anwendung anzeigen musst, protokolliere sie separat oder verwende einen dedizierten Ausgabekanal.

    Weitere Informationen

    • Genehmigungen: Steuere, was dein Agent tun kann
    • Benutzerdefinierte Tools: Erstelle Tools, um die Agent-Fähigkeiten zu erweitern
    • TypeScript SDK-Referenz
    • Python SDK-Referenz

    Was this page helpful?

    • Verfügbare Hooks
    • Häufige Anwendungsfälle
    • Hooks konfigurieren
    • Matcher
    • Callback-Funktionseingaben
    • Eingabedaten
    • Callback-Ausgaben
    • Fortgeschrittene Szenarien handhaben
    • Mehrere Hooks verketten
    • Tool-spezifische Matcher mit Regex
    • Subagent-Aktivität verfolgen
    • Asynchrone Operationen in Hooks
    • Benachrichtigungen senden (nur TypeScript)
    • Häufige Probleme beheben
    • Hook wird nicht ausgelöst
    • Matcher filtert nicht wie erwartet
    • Hook-Timeout
    • Tool unerwartet blockiert
    • Geänderte Eingabe nicht angewendet
    • Sitzungs-Hooks nicht verfügbar
    • Subagent-Genehmigungsaufforderungen vervielfachen sich
    • Rekursive Hook-Schleifen mit Subagents
    • systemMessage wird nicht in der Ausgabe angezeigt
    • Weitere Informationen