When the model invokes a tool, the runtime can:
The second flow is way cheaper than letting the handler receive garbage and deal with it. That's why a tight schema pays double: the model learns the valid values from feedback, and your handler skips checks.
JSON Schema has more tools than people use. The ones you'll use 95% of the time:
| Case | Constraint | Example |
|---|---|---|
| Discrete values | enum | "enum": ["sms", "comms", "email"] |
| Number in range | minimum, maximum | "minimum": 0, "maximum": 100 |
| Integer (not float) | type: "integer" | use instead of "number" for counts |
| String with bounded length | minLength, maxLength | "maxLength": 280 (tweets) |
| String with format | format | "format": "date-time", "format": "email", "format": "uri" |
| String with regex | pattern | "pattern": "^[A-Z]{3}-\\d{4}$" (codes like "BAY-1234") |
| Non-empty array | minItems | "minItems": 1 |
severity, it'll try "high", "alta", "urgent", "critical". With enum, it sticks to the 3 you defined.Cannot read property of undefined.format: date-time that the system actually checks.On the right you have schedule_maintenance empty. Define the 5 parameters with the right constraints. The validator checks each constraint with regex; at the end an llm-judge confirms they don't contradict the use case.
The tighter the schema, the less defensive code in the handler. The schema is the first line of defense.