Wird geladen

Strikte Tool-Nutzung: Schluss mit der Ablehnung eigener Aufrufe

Lektion 210 Min.
Wird geladen

Strikte Tool-Nutzung: Schluss mit der Ablehnung eigener Aufrufe

ZusammenfassungTranskript

Wenn dein Backend einen Tool-Aufruf ablehnt, den Claude selbst erzeugt hat, ist strikte Tool-Nutzung die Lösung. Das Video schaltet sie für ein Tool bei Meridian ein, einem fiktiven Ingenieurbüro, und führt dieselben 100 Anfragen einmal mit deaktivierter und einmal mit aktivierter Funktion aus.

Die Demo in diesem Video wurde im September 2026 aufgezeichnet. Sie lief auf Claude Haiku 4.5 (claude-haiku-4-5). Die Ergebnisse können bei neueren Modellen abweichen.

Claude folgt normalerweise dem input_schema eines Tools, aber standardmäßig wird dies nicht erzwungen. Daher lehnt dein Backend manchmal einen Tool-Aufruf ab, den Claude gemacht hat, weil die Eingabe des Aufrufs eines der folgenden Probleme aufweist:

  • Der String "2" anstelle der Ganzzahl 2
  • Ein fehlendes Pflichtfeld

Strikte Tool-Nutzung behebt dieses Problem. Ein einziges Flag, strict: true, sorgt dafür, dass die von Claude geschriebene Eingabe deinem Schema entspricht.

Bei Meridian verwendet ein Assistent das Tool queue_stamp_request, um Zeichnungssätze für den Stempel eines lizenzierten Ingenieurs in die Warteschlange zu stellen. Meridians Validator ist der Code, der jeden Tool-Aufruf prüft. Mit deaktiviertem Strict lehnt er 79 von 100 Anfragen ab. Mit aktiviertem Strict und dem aus dem Validator generierten Schema lehnt er keine ab.

So funktioniert strikte Tool-Nutzung

Mit strict: true kompiliert die API zunächst dein JSON Schema in eine Grammatik. Eine Grammatik ist eine Reihe von Regeln, die festlegt, welche Tokens an jeder Stelle der Eingabe als Nächstes folgen dürfen. Danach kann Claude bei jeder Auswahl des nächsten Tokens des Tool-Aufrufs nur ein Token auswählen, das die Grammatik zulässt. Dies wird grammatikbeschränktes Sampling genannt.

Das Schema besagt, dass revision eine Ganzzahl ist, und Claude hat bis zu "revision": geschrieben. Ohne Strict können fünf nächste Tokens ausgewählt werden: 3, "3", three, 3.0 und null. Mit strict: true kann nur 3 ausgewählt werden, und die anderen vier sind durchgestrichen.

Mit strict: true können nur Tokens ausgewählt werden, die dein Schema erlaubt, sodass ein Ganzzahlfeld eine Ganzzahl erhält.

Dies ist Meridians Tool-Definition, gekürzt. Strict benötigt zwei ihrer Zeilen: das Flag und eine Einstellung, die das Flag erfordert.

json
{
  "name": "queue_stamp_request",
  "description": "Queues a drawing set for a professional engineer's stamp.",
  "strict": true,
  "input_schema": {
    "type": "object",
    "properties": {
      "drawing_set_id": {"type": "string"},
      "revision": {"type": "integer"}
    },
    "required": ["drawing_set_id", "revision"],
    "additionalProperties": false
  }
}
  • "strict": true ist das Flag. Es steht auf der obersten Ebene, neben name, description und input_schema, außerhalb des Schemas.
  • "additionalProperties": false ist die Einstellung. Sie bedeutet, dass die Eingabe kein Feld enthalten darf, das das Schema nicht benennt, und Strict verlangt sie für jedes Objekt.

Erstelle das Schema aus deinem Validator

Strikte Tool-Nutzung sorgt dafür, dass die von Claude geschriebene Eingabe deinem Schema entspricht, daher muss das Schema das aussagen, was dein Validator aussagt. Wenn du das Schema von Hand schreibst, driften die beiden auseinander. Ein Tool-Aufruf kann dann dem Schema entsprechen und trotzdem abgelehnt werden. Bei Meridian machte ein handgeschriebenes Schema die Lizenznummer zu einem einfachen String ohne Muster. So bestand "PE 46196" das Schema, scheiterte aber am Validator, der PE- und fünf Ziffern verlangt.

Schreibe die Regeln einmal in deinem Validator und generiere das Schema daraus. In Python ist der Validator normalerweise eine Pydantic-Klasse. In TypeScript wird er normalerweise mit Zod geschrieben.

Unten siehst du Meridians Pydantic-Klasse StampRequest mit dem Code, der sie verwendet, sowie das Schema, das StampRequest.model_json_schema() zurückgibt. Jedes # ... steht für nicht gezeigten Code, und das Schema zeigt nur die Lizenznummer.

python
class StampRequest(BaseModel):
    model_config = {"extra": "forbid"}
    # ...
    pe_license_number: str | None = Field(pattern=r"^PE-\d{5}$")
    # ...
stamp_tool = {
    # ...
    "input_schema": StampRequest.model_json_schema(),
    "strict": True,
}
stamp_request = StampRequest.model_validate(call.input)
json
{
  "additionalProperties": false,
  "properties": {
    "pe_license_number": {
      "anyOf": [
        {"pattern": "^PE-\\d{5}$", "type": "string"},
        {"type": "null"}
      ],
      "title": "Pe License Number"
    }
  }
}
  • "extra": "forbid" wird zu "additionalProperties": false, der Einstellung, die Strict erfordert.
  • str | None wird zu anyOf, sodass die Lizenznummer entweder ein String mit diesem pattern oder null ist.
  • model_validate() prüft call.input, die von Claude geschriebene Eingabe, gegen dieselbe Klasse.

Vergleiche die Durchläufe mit deaktiviertem und aktiviertem Strict

Meridians Test sendet 100 Stempelanfragen in einfacher Sprache mit dem Tool queue_stamp_request an Claude Haiku 4.5, und StampRequest validiert jeden Tool-Aufruf. Dieselben 100 Anfragen laufen zweimal: zuerst mit einem handgeschriebenen Schema und deaktiviertem Strict, dann mit dem generierten Schema und aktiviertem Strict.

Spiele beide Durchläufe unten erneut ab.

Wird geladen

Das pattern des Schemas legt fest, welches Format erlaubt ist, und Strict sorgt dafür, dass Claude sich daran hält.

Strict steuert die Form der Eingabe, kann aber keine Tatsache liefern, die die Anfrage nie genannt hat. Von den 100 Anfragen erwähnen 28 nie eine Lizenz. Das generierte Schema erlaubt null für die Lizenznummer, und alle 28 kamen als null zurück.

Grenzen der strikten Tool-Nutzung

Sechs Dinge, die du wissen solltest (Stand Oktober 2026):

  1. Halte geschützte Gesundheitsinformationen (PHI) heraus. Kompilierte Schemas erhalten nicht denselben PHI-Schutz wie Prompts und Antworten, also lass PHI aus Eigenschaftsnamen, enum-Werten, const-Werten und pattern-Ausdrücken heraus.
  2. Grenzwerte (Bounds) werden nicht unterstützt. Eine Anfrage, deren Schema minimum, maximum, minLength oder maxLength verwendet, gibt einen 400-Fehler zurück. Prüfe Grenzwerte in einer Validator-Funktion, etwa Pydantics @field_validator, und gib sie in der Beschreibung des Feldes an.
  3. Limits summieren sich über Tools hinweg. Eine Anfrage kann höchstens 20 strikte Tools enthalten. Über diese Tools hinweg kann sie höchstens 24 optionale Parameter enthalten. Sie kann außerdem höchstens 16 Parameter enthalten, die anyOf oder ein Typ-Array verwenden, was ein nullbares Feld wie str | None erzeugt.
  4. Die Eingabe kann dem Schema trotzdem nicht entsprechen. Das passiert nach einer Ablehnung, wenn eine Antwort bei max_tokens abgeschnitten wird, oder wenn ein enum- oder const-String in anderer Groß-/Kleinschreibung zurückkommt.
  5. Manche Modelle lehnen einen erzwungenen Tool-Aufruf ab. Das Setzen von tool_choice auf any oder tool erzwingt einen Tool-Aufruf. Das gibt bei Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1 und Claude Mythos 5.1 einen 400-Fehler zurück. Lass bei diesen Modellen tool_choice auf auto, seinem Standardwert.
  6. Programmatisches Tool-Calling kann keine strikten Tools verwenden. Beim programmatischen Tool-Calling schreibt Claude Code, der deine Tools aufruft. Lektion 8 behandelt dies.

Wichtige Erkenntnisse

  • strict: true sorgt dafür, dass die Tool-Eingabe deinem Schema entspricht, außer nach einer Ablehnung oder einer abgeschnittenen Antwort, oder wenn sich die Groß-/Kleinschreibung eines enum- oder const-Strings ändert.
  • Generiere das Schema aus deinem Validator, etwa einer Pydantic-Klasse.
  • Halte Grenzwerte aus dem Schema heraus und zähle Tools, optionale Parameter und nullbare Parameter über die gesamte Anfrage hinweg.