(Spine Ch. 11.)
“CECILY. I don’t. But that does not affect the wonderful beauty of his answer. GWENDOLEN. True. In matters of grave importance, style, not sincerity is the vital thing.” Oscar Wilde, The Importance of Being Earnest, Act III (1895)
Picture the diff you’d approve without reading. Somebody moved one key in a deploy-gate classifier’s output schema because it made the thing easier to skim in a log viewer. No weight changed. No prompt changed. Same model, same deploys, same evidence, and every JSON blob still parses clean and validates against the schema. Then the NO-GO rate moves, because the shape of the ask is part of the ask. I have sat and stared at a spread like that convinced I was watching a model regression. I was watching my own hands.
Bottom line: Same question, different wrapper, inverted answer. Format is not a wrapper, it’s a steering input. The schema you hand the model changes what it concludes, not only how it presents it. If your evals, your chains, and your agent’s decisions ride on structured output (and after Ch. 8 they do), you’d better know that the shape of the ask bends the answer.
The model doesn’t have a belief drawer and a formatting drawer. There’s one sampling process, and everything in the context, including your keys, your enum order, your “respond in JSON” instruction, conditions it.
The mechanisms, plainly:
1. Keys are semantic primes. "verdict"
vs "assessment" vs "preliminary_thoughts"
don’t just label the slot, they aim retrieval at different genres
(verdicts sound certain, assessments hedge, thoughts wander). You asked
for a label. You also asked for a mood.
2. Enum order is a nudge. First options get picked
more. Call it position bias. I want to be straight with you. That’s my
field read from shipping enums, not a number I can hand you off a paper,
and as far as I could find nobody has published one either, so treat it
as a thing to test on your own stack rather than a law. It’s flagged
that way in the receipts at the bottom. Your
["approve", "reject"] and your
["reject", "approve"] are different instruments that happen
to share a name. I alphabetized an enum once. Just alphabetized it, the
way you tidy a sock drawer. Congratulations to me: I shipped a new
classifier and called it a formatting commit. Pwned by my own sock
drawer.
3. Format changes the reasoning path. Free text lets the model wander into the answer; JSON forces commitment order (keys in sequence, no preamble). The scratchpad IS the cognition (Ch. 18). Change its shape, change the thought. Think of the Numa Numa video in 2004: same Moldovan pop song underneath every version, but the webcam framing, the captions, and the flying-text overlays each made people hear a different thing. The audio never changed. The wrapper did all the work, and that is exactly the trade you are making when you re-key a schema.
4. Strictness trades off against sense. Lock the schema tight (regex, enums, required everything) and the model spends capacity on compliance instead of correctness. Malformed-but-right becomes well-formed-but-wrong. You optimized the parse rate and taxed the truth rate. My proudest schema had a regex on every field and a required flag on every key, and I bragged about the parse rate to anyone who would sit still, a GeoCities page with a spinning hit counter and nothing worth counting. Every response was well-formed. A pile of them were also wrong, which is the most expensive kind of clean.
None of this means structured output is bad. Ch. 8 stands: typed handoffs beat rumor relays. The schema is part of the instrument, and instruments need calibration, not vibes about neutrality.
Here is a real one I can show you, because it is the schema that fact-checked this book. On 2026-09-09 I ran a receipts pass over the manuscript as a five-stage chain (research, fold, unslop, cite-check, patch), each stage typed. The cite-check stage’s schema, verbatim out of the workflow script:
const CHECK = { type:'object', required:['verdicts','unsupported_count'],
properties:{ verdicts:{type:'array', items:{type:'object',
required:['claim','status','reason'], ... }},
unsupported_count:{type:'number'} } }Read that with the chapter’s eyes. The top-level key is
verdicts, not notes, not
observations. Every element is required to carry a
status, so there is no slot for “I did not look.” And the
prose instruction paired with it ends “Default to unsupported when
uncertain.” That schema does not ask a model what it found. It asks a
model to convict. I wrote it that way on purpose for a fact-check, where
I want a hanging judge, and it worked: it stripped a dozen numbers out
of this manuscript that I liked and could not source, including two of
my own. Now imagine I paste that same shape into a deploy gate because
it is sitting right there in my repo and it parses. Same keys, same
required flags, same hanging judge, now voting on whether your release
ships. Nobody changed a model. Somebody copied a schema.
The other half is a shape I believe I have watched and never wrote
the numbers down for, so take it as memory, not measurement. A
deploy-gate classifier. Schema A:
{"verdict": "GO" | "NO-GO", "reasons": [...]}, verdict
first. Schema B:
{"analysis": "...", "verdict": "GO" | "NO-GO"}, analysis
first. Same model, same deploys, same evidence. My read is that A says
NO-GO less often than B, because verdict-first commits before it reasons
and analysis-first talks itself into caution. Do not quote a rate off me
here. I don’t have one, and making one up would turn me into the exact
guy this chapter is warning you about. The fix wasn’t picking the
winning wrapper anyway. It was moving the decision out of the model:
every cited check green means GO, else NO-GO, computed in code. The
model’s JSON became a report, not a ruling.
The loud failure is unparseable output crashing the chain. The quiet failure is worse because it parses cleanly:
You measure the wrapper and ship the number as the model’s capability.
Eval says 94%. I have absolutely put a 94% on a slide and let a room believe it belonged to the model. What passed was a model-plus-wrapper system, and the wrapper did half the work, or smuggled in the bias. Then the schema changes (new hire, new tool, new API version) and capability “regresses” overnight. Nothing about the model changed. The invisible half of the instrument got swapped.
Second quiet failure: standardizing one wrapper everywhere because it tested best once. You’ve now correlated every decision in your system with the same format bias, every check nodding along with every other check like a very agreeable committee. I did this on purpose and wrote it up as a standard, which is teh n00b move dressed in a governance doc.
Do
Don’t
Ch. 8 chained the work in typed handoffs; Ch. 9 dressed the steps in personas. This chapter closes the uncomfortable corollary: the typing itself steers. Next: context, what actually goes in the window, of which prompt-craft is a subset (Ch. 12).
Thesis is Jeremy’s (format steers conclusions), printed as a practitioner claim and nothing more. Research located no published paper or eval writeup that measures the specific claim that changing an output format changes the model’s conclusion, so the four mechanisms above are reasoning, not measurement, and are labeled that way on purpose.
CHECK schema quoted in the worked example is real
and pasted from the receipts workflow script used on this manuscript,
2026-09-09:
~/.claude/projects/-Users-shoemoney-Projects-aibook/6946a9c6-0887-4d7d-881f-ee5fac2b90c3/workflows/scripts/ghostwriter-receipts-wf_f6d9500d-e42.js,
line 15, with the paired instruction “Default to unsupported when
uncertain” on line 24. Trimmed with ... for print; keys,
required list, and types are unedited.