Structured Output Beats Clever Parsing
Still regex-parsing JSON out of model text? Stop. Bedrock structured outputs enforce a JSON Schema during decoding, so the response is valid by construction.

If your application still pulls JSON out of model prose with a regex and a retry loop, you are solving a problem Amazon Bedrock now solves at the decoding layer. Structured outputs, generally available on Bedrock since February 2026, constrain the model to a JSON Schema while it generates tokens, so the response conforms to your shape by construction rather than by hope. The regex was never the fix. It was the symptom of asking a model to "please return JSON" and then cleaning up when it did not.
The parsing approach fails in ways that are annoying precisely because they are rare. Ninety-something percent of responses parse. The rest wrap the JSON in a markdown fence, add a friendly sentence before it, trail a comma, or hallucinate a field. Your parser then throws in production, on the input you did not test, at the worst time. Constrained decoding removes that whole failure class because the invalid token is never emitted in the first place.
Three ways to get structure, in order of strength
Prompt-and-pray
You ask for JSON in the system prompt, maybe give an example, and parse the text. This works until it does not. It has no guarantee, no enforcement, and its failure rate is exactly the tail that never shows up in a demo. Every hour spent hardening the parser is an hour spent on a problem the platform can eliminate.
Tool use as a schema
Long before native structured outputs, the reliable trick was to define a tool whose input schema is the shape you want, then read the tool-call arguments instead of the message text. The model fills the tool inputs, and you get a structured object. This is still a good pattern when the same call also needs to actually invoke tools. On Bedrock you can now add strict: true to a tool definition so the tool name and inputs are validated against the schema rather than merely suggested by it.
Native structured outputs
The direct route is to declare the response shape as a JSON Schema and let Bedrock enforce it during generation. It uses JSON Schema Draft 2020-12 and constrained decoding, so the model physically cannot emit a token that would break the schema. On the Converse API the field is outputConfig.textFormat, and the schema needs a name. It is available across Converse, ConverseStream, InvokeModel, and InvokeModelWithResponseStream for Anthropic Claude 4.5 and a set of open-weight models.
// Converse: enforce the shape instead of parsing for it
outputConfig: {
textFormat: {
jsonSchema: {
name: "extraction",
schema: {
type: "object",
properties: {
invoice_id: { type: "string" },
total_cents: { type: "integer" },
currency: { type: "string", enum: ["USD", "EUR", "GBP"] }
},
required: ["invoice_id", "total_cents", "currency"],
additionalProperties: false
}
}
}
}What enforcement buys you
The obvious win is that the output parses. The larger win is what you get to delete: the retry-on-invalid loop, the JSON-repair library, the defensive re-prompt that says "you returned invalid JSON, try again," and the alert that fires when all of that still fails. Each of those was compensating for a probabilistic output. Once the schema is enforced during decoding, the compensation is dead code. Fewer retries also means fewer tokens and lower latency, because you are not paying for a second call to fix the first.
Set additionalProperties: false and mark fields required so the schema is tight. A loose schema that allows extra keys hands back some of the guarantee you just bought, because the model can still attach fields your code does not expect.
Where it does not apply
Structured output is for machine-readable responses: extraction, classification, routing, function arguments, anything a downstream system consumes. It is the wrong tool for prose a human reads, where a rigid schema fights the point. And it constrains shape, not truth. A schema guarantees total_cents is an integer, not that it is the correct integer. Validation of values, ranges, and business rules is still your job. The schema removes the parsing failure mode. It does not remove the need to check that the model got the answer right.
The takeaway
Clever parsing is effort spent working around a guarantee the model never gave you. Bedrock structured outputs move the guarantee into the decoder: declare a JSON Schema, and the response is valid by construction. Use native structured outputs for pure data, tool-use schemas when the same call also acts, and keep value-level validation regardless. Then delete the regex, the repair loop, and the retry. They were scaffolding for a problem you no longer have.
Read this next
- Stop Fine-Tuning. You Need RAG, a Cache, and Better Prompts, on solving format and behavior with prompting and platform features instead of training.
- Streaming Responses Are a UX Decision, Not a Performance One, on why streaming and structured output pull in opposite directions.
For the platform and delivery side of shipping this reliably, the cloud field notes live at ercan.cloud, and the hub is at ercanermis.com.
More from Ercan
Two more sites, same author, different ground.
Cloud, AWS, EKS, Terraform, platform engineering.
Field notes from production systems. EKS, IAM, Terraform at organization scale, observability, cost optimization.
Visit ercan.cloud →The hub. About, consulting, contact.
Personal hub for both writing tracks. Who I am, how the consulting works, how to reach me.
Visit ercanermis.com →