Structured Output Patterns: Tool-Forcing and Schema Constraints
CoreHandle Claude's output defensively · Difficulty 2/5
Explanation
Getting Machine-Readable Output
When you need machine-readable results, request JSON against a schema. Options include tool use / tool-forcing -- define a tool whose input schema is your target output shape and require Claude to call it -- and structured-output features. Prefilling the assistant turn (e.g., with {) can nudge the model toward JSON-only responses by removing room for a conversational preamble.
Prefilling, Concretely
Prefilling means seeding the start of Claude's response yourself, before the model generates anything. Normally the assistant turn is empty and the model writes the whole thing, including whatever conversational preamble it chooses ("Sure, here's the JSON you asked for:"). Prefilling supplies the first character(s) of that turn yourself -- most commonly a single { -- which biases the response strongly toward continuing as a JSON object, because the model is now completing an already-started JSON structure rather than deciding from scratch whether to add a preamble first.
Before/after, conceptually:
# Before -- no prefill: the model decides how the response starts
messages = [
{"role": "user", "content": "Extract the name and email as JSON."}
]
# Response might start: "Sure! Here's the extracted data:\n{...}"
# After -- prefilled: the assistant turn already starts with "{"
messages = [
{"role": "user", "content": "Extract the name and email as JSON."},
{"role": "assistant", "content": "{"}
]
# Response continues the object directly, with much less room for preambleThis is a partial-robustness technique, not a structural guarantee: it makes a JSON-only response likely, but nothing forces the model to keep the object well-formed or to avoid ever breaking out of it. That's why tool-forcing against a schema remains the stronger mechanism when you need an actual guarantee, and prefilling is the lighter-weight nudge you reach for when a full schema/tool setup is more than the task needs.
Why Not Just Ask Nicely
Asking politely for JSON and hoping for compliance is the weakest approach: it has no structural guarantee behind it. Schema-plus-tool-forcing constrains what the model can produce; a plain request only asks for it.
Common exam traps
- Believing that lowering temperature to 0 alone guarantees valid, parseable JSON. Temperature affects sampling randomness, not schema compliance -- schema constraints and tool-forcing are the reliable mechanism, not temperature.
- Treating prefilling as equivalent in strength to tool-forcing/schema constraints -- prefilling nudges the output distribution toward JSON; it does not structurally guarantee it the way a schema-constrained tool call does.
Key Takeaways
- Request JSON against an explicit schema when output must be machine-readable
- Tool use/tool-forcing (a tool whose input schema is the target shape) is a strong mechanism for structured output
- Prefilling the assistant turn (e.g. with `{`) can nudge JSON-only responses
- Lowering temperature to 0 does not guarantee valid JSON; schema plus tool-forcing is the robust pattern
Glossary Terms
A technique where you begin Claude's response by adding a partial assistant turn before the API call. Claude continues from that starting point, allowing precise control over response format, structure, and starting content. Useful for forcing JSON or specific syntax.
Guaranteed formatted output (typically JSON) from Claude. The most reliable method is to define a schema as a tool and set tool_choice to force its use — Claude's tool_use blocks are always valid JSON. Alternatively, use --output-format json with --json-schema in Claude Code CLI.
API parameter controlling how Claude selects tools. 'auto' (default): Claude decides whether to use tools. 'any': Claude must use at least one tool. 'none': Claude cannot use tools. '{type: tool, name: X}': Claude must use the specific named tool. Used to force structured output via a schema tool.
Related Concepts