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

    Genehmigungen und Benutzereingaben verarbeiten

    Stellen Sie Claudes Genehmigungsanfragen und Klärungsfragen den Benutzern zur Verfügung und geben Sie deren Entscheidungen an das SDK zurück.

    Was this page helpful?

    • Erkennen Sie, wenn Claude eine Eingabe benötigt
    • Tool-Genehmigungsanfragen verarbeiten
    • Auf Tool-Anfragen reagieren
    • Klärungsfragen verarbeiten
    • Frageformat
    • Antwortformat
    • Vollständiges Beispiel
    • Einschränkungen
    • Andere Möglichkeiten, Benutzereingaben zu erhalten
    • Streaming-Eingabe
    • Benutzerdefinierte Tools
    • Verwandte Ressourcen

    Während Claude an einer Aufgabe arbeitet, muss es manchmal mit Benutzern Rücksprache halten. Es könnte eine Genehmigung benötigen, bevor Dateien gelöscht werden, oder es muss fragen, welche Datenbank für ein neues Projekt verwendet werden soll. Ihre Anwendung muss diese Anfragen den Benutzern anzeigen, damit Claude mit deren Eingabe fortfahren kann.

    Claude fordert Benutzereingaben in zwei Situationen an: wenn es Genehmigung zur Verwendung eines Tools benötigt (wie das Löschen von Dateien oder das Ausführen von Befehlen) und wenn es Klärungsfragen hat (über das Tool AskUserQuestion). Beide lösen Ihren canUseTool-Callback aus, der die Ausführung pausiert, bis Sie eine Antwort zurückgeben. Dies unterscheidet sich von normalen Gesprächsrunden, bei denen Claude fertig ist und auf Ihre nächste Nachricht wartet.

    Bei Klärungsfragen generiert Claude die Fragen und Optionen. Ihre Aufgabe besteht darin, sie den Benutzern zu präsentieren und ihre Auswahl zurückzugeben. Sie können dieser Abfolge keine eigenen Fragen hinzufügen; wenn Sie Benutzer selbst etwas fragen müssen, tun Sie dies separat in Ihrer Anwendungslogik.

    Dieser Leitfaden zeigt Ihnen, wie Sie jeden Anforderungstyp erkennen und angemessen reagieren.

    Erkennen Sie, wenn Claude eine Eingabe benötigt

    Übergeben Sie einen canUseTool-Callback in Ihren Abfrageoptionen. Der Callback wird ausgelöst, wenn Claude eine Benutzereingabe benötigt, und erhält den Tool-Namen und die Eingabe als Argumente:

    async def handle_tool_request(tool_name, input_data, context):
        # Benutzer auffordern und Zulassung oder Ablehnung zurückgeben
        ...
    
    options = ClaudeAgentOptions(can_use_tool=handle_tool_request)

    Der Callback wird in zwei Fällen ausgelöst:

    1. Tool benötigt Genehmigung: Claude möchte ein Tool verwenden, das nicht automatisch durch Berechtigungsregeln oder Modi genehmigt ist. Überprüfen Sie tool_name auf das Tool (z. B. "Bash", "Write").
    2. Claude stellt eine Frage: Claude ruft das Tool AskUserQuestion auf. Überprüfen Sie, ob tool_name == "AskUserQuestion" ist, um es anders zu behandeln. Wenn Sie ein tools-Array angeben, fügen Sie AskUserQuestion ein, damit dies funktioniert. Weitere Informationen finden Sie unter Klärungsfragen verarbeiten.

    Um Tools automatisch zuzulassen oder abzulehnen, ohne Benutzer aufzufordern, verwenden Sie stattdessen Hooks. Hooks werden vor canUseTool ausgeführt und können Anfragen basierend auf Ihrer eigenen Logik zulassen, ablehnen oder ändern. Sie können auch den PermissionRequest-Hook verwenden, um externe Benachrichtigungen (Slack, E-Mail, Push) zu senden, wenn Claude auf eine Genehmigung wartet.

    Tool-Genehmigungsanfragen verarbeiten

    Nachdem Sie einen canUseTool-Callback in Ihren Abfrageoptionen übergeben haben, wird er ausgelöst, wenn Claude ein Tool verwenden möchte, das nicht automatisch genehmigt ist. Ihr Callback erhält zwei Argumente:

    ArgumentBeschreibung
    toolNameDer Name des Tools, das Claude verwenden möchte (z. B. "Bash", "Write", "Edit")
    inputDie Parameter, die Claude an das Tool übergibt. Der Inhalt variiert je nach Tool.

    Das input-Objekt enthält Tool-spezifische Parameter. Häufige Beispiele:

    ToolEingabefelder
    Bashcommand, description, timeout
    Writefile_path, content
    Editfile_path, old_string, new_string
    Readfile_path, offset, limit

    Weitere Informationen zu vollständigen Eingabeschemas finden Sie in der SDK-Referenz: Python | TypeScript.

    Sie können diese Informationen dem Benutzer anzeigen, damit dieser entscheiden kann, ob die Aktion zulässig oder abgelehnt werden soll, und dann die entsprechende Antwort zurückgeben.

    Das folgende Beispiel fordert Claude auf, eine Testdatei zu erstellen und zu löschen. Wenn Claude jeden Vorgang versucht, druckt der Callback die Tool-Anfrage auf dem Terminal aus und fordert zur y/n-Genehmigung auf.

    In Python erfordert can_use_tool den Streaming-Modus und einen PreToolUse-Hook, der {"continue_": True} zurückgibt, um den Stream offen zu halten. Ohne diesen Hook wird der Stream geschlossen, bevor der Berechtigungs-Callback aufgerufen werden kann.

    Dieses Beispiel verwendet einen y/n-Flow, bei dem jede Eingabe außer y als Ablehnung behandelt wird. In der Praxis könnten Sie eine umfangreichere Benutzeroberfläche erstellen, die es Benutzern ermöglicht, die Anfrage zu ändern, Feedback zu geben oder Claude vollständig umzuleiten. Weitere Informationen finden Sie unter Auf Tool-Anfragen reagieren.

    Auf Tool-Anfragen reagieren

    Ihr Callback gibt einen von zwei Antworttypen zurück:

    AntwortPythonTypeScript
    ZulassenPermissionResultAllow(updated_input=...){ behavior: "allow", updatedInput }
    AblehnenPermissionResultDeny(message=...){ behavior: "deny", message }

    Wenn Sie zulassen, übergeben Sie die Tool-Eingabe (original oder geändert). Wenn Sie ablehnen, geben Sie eine Nachricht an, die erklärt, warum. Claude sieht diese Nachricht und kann seinen Ansatz anpassen.

    from claude_agent_sdk.types import PermissionResultAllow, PermissionResultDeny
    
    # Tool-Ausführung zulassen
    return PermissionResultAllow(updated_input=input_data)
    
    # Tool blockieren
    return PermissionResultDeny(message="User rejected this action")

    Über das Zulassen oder Ablehnen hinaus können Sie die Eingabe des Tools ändern oder einen Kontext bereitstellen, der Claude hilft, seinen Ansatz anzupassen:

    • Genehmigen: Lassen Sie das Tool genau wie von Claude angefordert ausgeführt werden
    • Mit Änderungen genehmigen: Ändern Sie die Eingabe vor der Ausführung (z. B. Pfade bereinigen, Einschränkungen hinzufügen)
    • Ablehnen: Blockieren Sie das Tool und teilen Sie Claude mit, warum
    • Alternative vorschlagen: Blockieren Sie, aber leiten Sie Claude zu dem, was der Benutzer stattdessen möchte
    • Vollständig umleiten: Verwenden Sie Streaming-Eingabe, um Claude eine völlig neue Anweisung zu senden

    Klärungsfragen verarbeiten

    Wenn Claude mehr Anleitung zu einer Aufgabe mit mehreren gültigen Ansätzen benötigt, ruft es das Tool AskUserQuestion auf. Dies löst Ihren canUseTool-Callback mit toolName auf AskUserQuestion aus. Die Eingabe enthält Claudes Fragen als Multiple-Choice-Optionen, die Sie dem Benutzer anzeigen und deren Auswahl zurückgeben.

    Klärungsfragen sind besonders häufig im plan-Modus, in dem Claude die Codebasis erkundet und Fragen stellt, bevor er einen Plan vorschlägt. Dies macht den Plan-Modus ideal für interaktive Workflows, bei denen Claude Anforderungen sammeln soll, bevor Änderungen vorgenommen werden.

    Die folgenden Schritte zeigen, wie Sie Klärungsfragen verarbeiten:

    Frageformat

    Die Eingabe enthält Claudes generierte Fragen in einem questions-Array. Jede Frage hat diese Felder:

    FeldBeschreibung
    questionDer vollständige Fragetext zum Anzeigen
    headerKurzes Label für die Frage (max. 12 Zeichen)
    optionsArray von 2-4 Auswahlmöglichkeiten, jeweils mit label und description
    multiSelectWenn true, können Benutzer mehrere Optionen auswählen

    Hier ist ein Beispiel der Struktur, die Sie erhalten:

    {
      "questions": [
        {
          "question": "How should I format the output?",
          "header": "Format",
          "options": [
            { "label": "Summary", "description": "Brief overview of key points" },
            { "label": "Detailed", "description": "Full explanation with examples" }
          ],
          "multiSelect": false
        }
      ]
    }

    Antwortformat

    Geben Sie ein answers-Objekt zurück, das jedes question-Feld der Frage dem label der ausgewählten Option zuordnet:

    FeldBeschreibung
    questionsGeben Sie das ursprüngliche Questions-Array durch (erforderlich für die Tool-Verarbeitung)
    answersObjekt, bei dem Schlüssel Fragetext und Werte ausgewählte Labels sind

    Für Multi-Select-Fragen verbinden Sie mehrere Labels mit ", ". Für freie Texteingabe verwenden Sie den benutzerdefinierten Text des Benutzers direkt.

    {
      "questions": [...],
      "answers": {
        "How should I format the output?": "Summary",
        "Which sections should I include?": "Introduction, Conclusion"
      }
    }

    Unterstützen Sie freie Texteingabe

    Claudes vordefinierte Optionen decken nicht immer das ab, was Benutzer möchten. Um Benutzern zu ermöglichen, ihre eigene Antwort einzugeben:

    • Zeigen Sie nach Claudes Optionen eine zusätzliche Auswahlmöglichkeit "Sonstiges" an, die Texteingabe akzeptiert
    • Verwenden Sie den benutzerdefinierten Text des Benutzers als Antwortwert (nicht das Wort "Sonstiges")

    Weitere Informationen finden Sie im vollständigen Beispiel unten für eine vollständige Implementierung.

    Vollständiges Beispiel

    Claude stellt Klärungsfragen, wenn es Benutzereingaben benötigt, um fortzufahren. Wenn Claude beispielsweise aufgefordert wird, bei der Entscheidung über einen Tech-Stack für eine mobile App zu helfen, könnte es Fragen zu plattformübergreifend vs. nativ, Backend-Vorlieben oder Zielplattformen stellen. Diese Fragen helfen Claude, Entscheidungen zu treffen, die den Vorlieben des Benutzers entsprechen, anstatt zu raten.

    Dieses Beispiel verarbeitet diese Fragen in einer Terminal-Anwendung. Hier ist, was bei jedem Schritt passiert:

    1. Leiten Sie die Anfrage weiter: Der canUseTool-Callback überprüft, ob der Tool-Name "AskUserQuestion" ist, und leitet zu einem dedizierten Handler weiter
    2. Fragen anzeigen: Der Handler durchläuft das questions-Array und druckt jede Frage mit nummerierten Optionen
    3. Eingabe sammeln: Der Benutzer kann eine Nummer eingeben, um eine Option auszuwählen, oder direkt Freitext eingeben (z. B. "jquery", "i don't know")
    4. Antworten zuordnen: Der Code überprüft, ob die Eingabe numerisch ist (verwendet das Label der Option) oder Freitext (verwendet den Text direkt)
    5. An Claude zurückgeben: Die Antwort enthält sowohl das ursprüngliche questions-Array als auch die answers-Zuordnung

    Einschränkungen

    • Subagents: AskUserQuestion ist derzeit nicht in Subagents verfügbar, die über das Task-Tool erzeugt werden
    • Fragenlimits: Jeder AskUserQuestion-Aufruf unterstützt 1-4 Fragen mit jeweils 2-4 Optionen

    Andere Möglichkeiten, Benutzereingaben zu erhalten

    Der canUseTool-Callback und das AskUserQuestion-Tool decken die meisten Genehmigungs- und Klärungsszenarien ab, aber das SDK bietet andere Möglichkeiten, um Eingaben von Benutzern zu erhalten:

    Streaming-Eingabe

    Verwenden Sie Streaming-Eingabe, wenn Sie:

    • Den Agent mitten in der Aufgabe unterbrechen: Senden Sie ein Abbruchsignal oder ändern Sie die Richtung, während Claude arbeitet
    • Zusätzlichen Kontext bereitstellen: Fügen Sie Informationen hinzu, die Claude benötigt, ohne darauf zu warten, dass es fragt
    • Chat-Schnittstellen erstellen: Ermöglichen Sie Benutzern, Folgefragen während langwieriger Operationen zu senden

    Streaming-Eingabe ist ideal für Konversations-UIs, bei denen Benutzer während der Ausführung mit dem Agent interagieren, nicht nur an Genehmigungspunkten.

    Benutzerdefinierte Tools

    Verwenden Sie benutzerdefinierte Tools, wenn Sie:

    • Strukturierte Eingaben sammeln: Erstellen Sie Formulare, Assistenten oder mehrstufige Workflows, die über das Multiple-Choice-Format von AskUserQuestion hinausgehen
    • Externe Genehmigungssysteme integrieren: Verbinden Sie sich mit bestehenden Ticketing-, Workflow- oder Genehmigungsplattformen
    • Domänenspezifische Interaktionen implementieren: Erstellen Sie Tools, die auf die Anforderungen Ihrer Anwendung zugeschnitten sind, wie Code-Review-Schnittstellen oder Bereitstellungs-Checklisten

    Benutzerdefinierte Tools geben Ihnen vollständige Kontrolle über die Interaktion, erfordern aber mehr Implementierungsarbeit als die Verwendung des integrierten canUseTool-Callbacks.

    Verwandte Ressourcen

    • Konfigurieren Sie Berechtigungen: Richten Sie Berechtigungsmodi und -regeln ein
    • Kontrollieren Sie die Ausführung mit Hooks: Führen Sie benutzerdefinierten Code an Schlüsselpunkten im Agent-Lebenszyklus aus
    • TypeScript SDK-Referenz: Vollständige canUseTool-API-Dokumentation
    import asyncio
    
    from claude_agent_sdk import ClaudeAgentOptions, query
    from claude_agent_sdk.types import (
        HookMatcher,
        PermissionResultAllow,
        PermissionResultDeny,
        ToolPermissionContext,
    )
    
    
    async def can_use_tool(
        tool_name: str, input_data: dict, context: ToolPermissionContext
    ) -> PermissionResultAllow | PermissionResultDeny:
        # Tool-Anfrage anzeigen
        print(f"\nTool: {tool_name}")
        if tool_name == "Bash":
            print(f"Command: {input_data.get('command')}")
            if input_data.get("description"):
                print(f"Description: {input_data.get('description')}")
        else:
            print(f"Input: {input_data}")
    
        # Benutzergenehmigung abrufen
        response = input("Allow this action? (y/n): ")
    
        # Zulassung oder Ablehnung basierend auf der Antwort des Benutzers zurückgeben
        if response.lower() == "y":
            # Zulassen: Tool wird mit der ursprünglichen (oder geänderten) Eingabe ausgeführt
            return PermissionResultAllow(updated_input=input_data)
        else:
            # Ablehnen: Tool wird nicht ausgeführt, Claude sieht die Nachricht
            return PermissionResultDeny(message="User denied this action")
    
    
    # Erforderliche Umgehung: Dummy-Hook hält den Stream für can_use_tool offen
    async def dummy_hook(input_data, tool_use_id, context):
        return {"continue_": True}
    
    
    async def prompt_stream():
        yield {
            "type": "user",
            "message": {
                "role": "user",
                "content": "Create a test file in /tmp and then delete it",
            },
        }
    
    
    async def main():
        async for message in query(
            prompt=prompt_stream(),
            options=ClaudeAgentOptions(
                can_use_tool=can_use_tool,
                hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
            ),
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    
    asyncio.run(main())
    1. 1

      Übergeben Sie einen canUseTool-Callback

      Übergeben Sie einen canUseTool-Callback in Ihren Abfrageoptionen. Standardmäßig ist AskUserQuestion verfügbar. Wenn Sie ein tools-Array angeben, um Claudes Fähigkeiten einzuschränken (z. B. einen schreibgeschützten Agent mit nur Read, Glob und Grep), fügen Sie AskUserQuestion in dieses Array ein. Andernfalls kann Claude keine Klärungsfragen stellen:

      async for message in query(
          prompt="Analyze this codebase",
          options=ClaudeAgentOptions(
              # Fügen Sie AskUserQuestion in Ihre Tools-Liste ein
              tools=["Read", "Glob", "Grep", "AskUserQuestion"],
              can_use_tool=can_use_tool,
          ),
      ):
          # ...
    2. 2

      Erkennen Sie AskUserQuestion

      Überprüfen Sie in Ihrem Callback, ob toolName gleich AskUserQuestion ist, um es anders als andere Tools zu verarbeiten:

      async def can_use_tool(tool_name: str, input_data: dict, context):
          if tool_name == "AskUserQuestion":
              # Ihre Implementierung zum Sammeln von Antworten vom Benutzer
              return await handle_clarifying_questions(input_data)
          # Verarbeiten Sie andere Tools normal
          return await prompt_for_approval(tool_name, input_data)
    3. 3

      Analysieren Sie die Frageneingabe

      Die Eingabe enthält Claudes Fragen in einem questions-Array. Jede Frage hat eine question (der anzuzeigende Text), options (die Auswahlmöglichkeiten) und multiSelect (ob mehrere Auswahlen zulässig sind):

      {
        "questions": [
          {
            "question": "How should I format the output?",
            "header": "Format",
            "options": [
              { "label": "Summary", "description": "Brief overview" },
              { "label": "Detailed", "description": "Full explanation" }
            ],
            "multiSelect": false
          },
          {
            "question": "Which sections should I include?",
            "header": "Sections",
            "options": [
              { "label": "Introduction", "description": "Opening context" },
              { "label": "Conclusion", "description": "Final summary" }
            ],
            "multiSelect": true
          }
        ]
      }

      Weitere Informationen finden Sie unter Frageformat.

    4. 4

      Sammeln Sie Antworten vom Benutzer

      Präsentieren Sie die Fragen dem Benutzer und sammeln Sie deren Auswahl. Wie Sie dies tun, hängt von Ihrer Anwendung ab: ein Terminal-Prompt, ein Web-Formular, ein mobiler Dialog usw.

    5. 5

      Geben Sie Antworten an Claude zurück

      Erstellen Sie das answers-Objekt als Datensatz, bei dem jeder Schlüssel der question-Text ist und jeder Wert das label der ausgewählten Option ist:

      Aus dem FrageobjektVerwenden Sie als
      question-Feld (z. B. "How should I format the output?")Schlüssel
      label-Feld der ausgewählten Option (z. B. "Summary")Wert

      Für Multi-Select-Fragen verbinden Sie mehrere Labels mit ", ". Wenn Sie freie Texteingabe unterstützen, verwenden Sie den benutzerdefinierten Text des Benutzers als Wert.

      return PermissionResultAllow(
          updated_input={
              "questions": input_data.get("questions", []),
              "answers": {
                  "How should I format the output?": "Summary",
                  "Which sections should I include?": "Introduction, Conclusion"
              }
          }
      )
    import asyncio
    
    from claude_agent_sdk import ClaudeAgentOptions, query
    from claude_agent_sdk.types import HookMatcher, PermissionResultAllow
    
    
    def parse_response(response: str, options: list) -> str:
        """Analysieren Sie Benutzereingaben als Optionsnummer(n) oder Freitext."""
        try:
            indices = [int(s.strip()) - 1 for s in response.split(",")]
            labels = [options[i]["label"] for i in indices if 0 <= i < len(options)]
            return ", ".join(labels) if labels else response
        except ValueError:
            return response
    
    
    async def handle_ask_user_question(input_data: dict) -> PermissionResultAllow:
        """Zeigen Sie Claudes Fragen an und sammeln Sie Benutzerantworten."""
        answers = {}
    
        for q in input_data.get("questions", []):
            print(f"\n{q['header']}: {q['question']}")
    
            options = q["options"]
            for i, opt in enumerate(options):
                print(f"  {i + 1}. {opt['label']} - {opt['description']}")
            if q.get("multiSelect"):
                print("  (Enter numbers separated by commas, or type your own answer)")
            else:
                print("  (Enter a number, or type your own answer)")
    
            response = input("Your choice: ").strip()
            answers[q["question"]] = parse_response(response, options)
    
        return PermissionResultAllow(
            updated_input={
                "questions": input_data.get("questions", []),
                "answers": answers,
            }
        )
    
    
    async def can_use_tool(tool_name: str, input_data: dict, context) -> PermissionResultAllow:
        # Leiten Sie AskUserQuestion zu unserem Frage-Handler weiter
        if tool_name == "AskUserQuestion":
            return await handle_ask_user_question(input_data)
        # Auto-Genehmigung anderer Tools für dieses Beispiel
        return PermissionResultAllow(updated_input=input_data)
    
    
    async def prompt_stream():
        yield {
            "type": "user",
            "message": {"role": "user", "content": "Help me decide on the tech stack for a new mobile app"},
        }
    
    
    # Erforderliche Umgehung: Dummy-Hook hält den Stream für can_use_tool offen
    async def dummy_hook(input_data, tool_use_id, context):
        return {"continue_": True}
    
    
    async def main():
        async for message in query(
            prompt=prompt_stream(),
            options=ClaudeAgentOptions(
                can_use_tool=can_use_tool,
                hooks={"PreToolUse": [HookMatcher(matcher=None, hooks=[dummy_hook])]},
            ),
        ):
            if hasattr(message, "result"):
                print(message.result)
    
    
    asyncio.run(main())