Dark theme
WELCOME TO QQUANTUM

Let Qubi show you around.

Choose how you’d like to explore.

Don’t agreeGo to yourOS instead ↗

Both choices allow Google Analytics, so we can see which pages help.

Sound is your choice. Essential cookies keep the site working. Continuing either way also allows Google Analytics (visits and pages viewed).

Read our Terms, Privacy and Cookies.

Change your choices anytime from the footer.

Getting Qubi ready.
Technology

Structured outputs,
not just valid JSON.

Constrained decoding made structured output reliable, and that reliability is narrower than it sounds. The schema settles the shape of the response. Whether the values in it are true is still a question only your validation and your evaluation set can answer.

  • Schemas · tools · grammars
  • The layer production runs on
All Technology & Model Stack →
Pixel illustration for Structured Outputs & Tool Calling: irregular shapes fitting a checked output template.

The mechanism under everything

Almost no production AI system consumes free text. A support agent emits an intent, a confidence and a set of arguments; a document pipeline emits fields; an orchestration layer emits which tool to call and with what. The model's paragraph is for the human at the end, if there is one — the part the software acts on is a structured object.

That makes structured output the least discussed and most load-bearing part of the stack. It is also where a system quietly becomes fragile: a parser wrapped in a try block, a regular expression pulling JSON out of a markdown fence, a retry loop that fires a few times an hour and nobody looks at. All of that was necessary once. It is not any more, and removing it is usually the cheapest reliability win available on an existing system.

The reason is a change in mechanism rather than a change in model quality. Asking a model nicely for JSON is a prompt. Constraining its decoder so that no token producing invalid JSON can be sampled is an engineering guarantee about syntax, and it is the difference between hoping and knowing — about the shape, and only about the shape.

Three things that get conflated

01

JSON mode

An instruction to the model, sometimes with a flag, that the response should be JSON. It usually is. It may still be JSON of a different shape than you expected: a missing field, an extra one, a number where you wanted a string, the whole object nested inside a wrapper key. Better than asking in the prompt, and not a guarantee about your schema.
02

Constrained decoding

The schema is compiled into a grammar or state machine, and at each step the sampler is masked so only tokens that can continue a valid document are available. Invalid output is not corrected after the fact — it is unreachable. This is what “structured outputs” means when a provider offers it as a distinct feature, and it is what makes the parse step disappear from your code.
03

Tool calling

The same machinery pointed at a different purpose. You describe the functions available, each with a parameter schema; the model returns a name and a validated argument object rather than prose; your code executes it and feeds the result back. Tool calling is structured output with a dispatch step attached, which is why the two share every failure mode.

What the grammar actually buys you

This is the distinction worth being pedantic about, because a great deal of production incident time is spent on the right-hand column by teams who believed the left-hand one had covered it.

Compare your options
Constrained decoding is a syntactic guarantee, not a semantic one. A schema-valid object full of confidently invented values is the characteristic failure of a system that stopped at the left-hand column — and it is harder to spot than a parse error, because nothing throws.
Criterion Constrained decoding Still your job
Output parses as JSON Yes No
Required fields are present Yes No
Types match the schema Yes No
Enum values are members of the enum Yes No
The value is factually right No Yes
The identifier refers to a record that exists No Yes
The date is inside a plausible range No Yes
The amount matches the source document No Yes
The tool is the right tool for this request No Yes
The caller is permitted to invoke it No Yes

There is a second-order effect worth knowing about: a grammar can only mask tokens, so a model pushed into a shape it does not want to produce will fill the shape anyway. If your schema requires a customer_id and the source text contains none, a constrained decoder cannot emit “there isn't one” unless you gave it a way to say so. It will emit a plausible-looking identifier instead. Most invented-value bugs we see are this bug, and the fix is in the schema rather than in the prompt.

Designing a schema the model can fill

01

Flat beats deeply nested

Every level of nesting is another place for the model to lose track of which object it is currently inside. Three levels is usually the point where extraction quality starts to slide. Prefer a flat object with compound field names, and where a hierarchy is genuinely necessary, consider two calls over one deep schema.
02

Enums beat free text

Any field with a bounded set of answers should be an enum, not a string. It removes a whole class of downstream normalisation — priority as “high”, “High”, “HIGH” and “urgent” — and the constraint is enforced by the decoder rather than by a mapping table you maintain. Where the set is large but known, the enum still beats validating a string afterwards.
03

Give it a way to say nothing

The most important field in most extraction schemas is the one that lets the model decline: a nullable value, a found boolean, an enum member called not_stated. Without it a required field is an instruction to invent. With it, “not present in this document” becomes a first-class answer you can measure the rate of.
04

Required means required

Mark a field optional only where its absence is meaningful. Long lists of optional fields produce sparse objects and hide whether the model failed to find something or simply skipped it. Nullable-and-required is almost always the better encoding than optional, because it forces an explicit answer either way.
05

Field names are prompt

invoice_total_including_vat extracts better than amount, and a description on the field beats a paragraph in the system prompt explaining what amount means. The schema is read by the model as part of the context; write it for that reader as well as for the type checker.
06

Ask for the evidence

A source_quote or page field alongside each extracted value costs a few tokens and changes what verification is possible: a reviewer can check the citation rather than re-reading the document, and an automated check can confirm the quoted span actually appears in the source. Grounding the output in something checkable is worth more than any confidence score the model reports about itself.
schemas/invoice_line.json JSON
{
                  "type": "object",
                  "additionalProperties": false,
                  "required": ["supplier_name", "invoice_total", "currency", "confidence", "source_quote"],
                  "properties": {
                    "supplier_name": {
                      "type": ["string", "null"],
                      "description": "Exactly as printed on the document. Null if no supplier is named."
                    },
                    "invoice_total": {
                      "type": ["number", "null"],
                      "description": "Total including tax. Null if the document states no total."
                    },
                    "currency": {
                      "type": ["string", "null"],
                      "enum": ["EUR", "GBP", "USD", "CHF", null],
                      "description": "Null when the document shows an amount with no currency mark."
                    },
                    "confidence": {
                      "type": "string",
                      "enum": ["clear", "ambiguous", "not_found"],
                      "description": "Route anything that is not clear to review."
                    },
                    "source_quote": {
                      "type": ["string", "null"],
                      "description": "Verbatim span the total was read from, for verification."
                    }
                  }
                }
The two design decisions that matter are both visible here: every uncertain field can be null, and the extracted total carries the span it came from so a check can verify it against the document rather than trusting it.

Tool calling in practice

A tool call is the point where a language model stops producing text and starts causing effects, which makes the validation step between the two the most consequential twenty lines in the system. The model proposes; your code decides.

THE TOOL CALL LOOP
  1. 01
    Request

    user or trigger

  2. 02
    Tool schemas

    only what this caller may use

  3. 03
    Model

    name + argument object

  4. 04
    Validate

    schema, then business rules

  5. 05 · Branch / escalation
    Rejected

    error back to the model

  6. 06
    Authorise

    as the end user, not the service

  7. 07
    Execute

    and log the arguments

Lower box = a rejected call returned as a typed errorMarker = one tool invocation
The authorisation step is deliberately after validation and before execution, and it authorises the human the request came from rather than the process making the call. A model that has been talked into asking for something it should not have is stopped here, not by the prompt.
  • Tool choice.

    Providers generally let you force a call, forbid one, or require a specific tool. Use it. A classification step that must return one of four tools should not be allowed to answer in prose, and a final summarisation turn should not be allowed to call anything. Leaving the decision open on every turn is how an agent ends up in a loop calling the same lookup nine times.
  • Parallel calls.

    Where a model can request several independent tools at once, take it — three lookups that could run concurrently are three round trips otherwise, and on a latency-sensitive path that is the whole budget. The constraint is that the calls must genuinely be independent; anything where the second call's arguments depend on the first result has to stay sequential, and a model will occasionally propose otherwise.
  • Errors are context, not exceptions.

    When a call fails, the useful move is usually to return the error to the model as a tool result in terms it can act on — “no customer with that reference; try searching by name” — rather than throwing. Models recover from a well-worded error surprisingly often. They recover from a stack trace never, and a raw exception message is also a place internal detail leaks into a context window.
  • Retries need a budget and a change.

    Retrying the identical call with the identical context usually produces the identical result. A retry should alter something — the temperature, the error hint, the sub-task — and there should be a hard cap, after which the system escalates rather than continuing. Unbounded self-correction loops are the most expensive failure mode in this whole area, because they fail slowly and bill the entire time.
  • Cardinality is a limit, not a suggestion.

    Recognition quality degrades as the tool list grows; a model choosing between forty tools makes worse choices than one choosing between six. Where a system genuinely needs many capabilities, route first — a cheap classifier selecting a small tool set — rather than presenting everything on every turn.

A schema is an interface, so version it

Once anything downstream consumes the object, the schema is a published contract with the same compatibility rules as any API. Adding an optional field is safe. Adding a required one, tightening an enum, renaming a field or changing a type is a breaking change, and doing it in place breaks every consumer at once.

Two practices make this cheap. Keep the schema in version control as its own artefact rather than inline in a prompt string, so a diff is reviewable and a change is attributable. And treat a schema change as a change that must pass the evaluation set — enum edits in particular shift model behaviour in ways nobody predicts, because the enum members are part of the context the model reasons in. A schema change with no eval run behind it is a deploy with no test behind it.

The same argument applies to the tool definitions. A renamed parameter, a reworded description, a reordered enum: all of them alter what the model sees, and all of them belong on the same review path as the code that executes the call.

Questions

Questions about Structured Outputs & Tool Calling.

Does constrained decoding hurt output quality?

It can, and the effect depends on how far the schema is from what the model would naturally produce. A schema that fights the model — forcing a rigid order, demanding a field the input does not support, denying any way to express uncertainty — costs accuracy even though every response is valid. The practical test is to run the same task with and without the constraint against your evaluation set. Where a gap appears, it is nearly always the schema that needs redesigning rather than the constraint that needs removing.

Should we ask the model for a confidence score?

A numeric self-reported confidence is weakly informative at best and tends to cluster in a narrow band regardless of whether the answer is right. A small enum — clear, ambiguous, not found — is more useful, because the categories are actionable routing decisions rather than a number somebody has to threshold. Better still are external signals: whether the quoted span exists in the source, whether a lookup confirms the identifier, whether two independent extractions agree.

Can we use structured outputs with a self-hosted model?

Yes. Grammar-constrained sampling is implemented in the common open-source inference servers, so schema enforcement is available without a hosted provider, and it is one of the areas where self-hosting gives you more control rather than less. Smaller models benefit from it disproportionately: much of their apparent unreliability at structured tasks is formatting failure rather than reasoning failure, and constraining the decoder removes that layer entirely.

How do we test this?

The same way as anything else: a set of real inputs with the correct object for each, scored field by field rather than on whole-object equality. Field-level scoring is the part teams skip, and it is what tells you that the pipeline is fine except that dates are wrong 8% of the time. Include inputs where the correct answer is null or not_found, since a set made only of clean documents cannot detect the invention failure mode at all.

Is this the same thing as MCP?

They operate at different levels. Structured output and tool calling are the model-side mechanism: how a model is made to emit a validated argument object. The Model Context Protocol is a transport and capability-description standard for connecting a model to tool servers over a common interface. You can use tool calling with no MCP at all, and an MCP server is ultimately exposing tools that a model calls this way.

Still parsing JSON
out of a code fence?

Bring the schema and a hundred real inputs. Field-level scoring usually finds the bug in an afternoon.

30-minute technical call · no deck

Shipped & in build

Real work. Check it yourself.

What we built, what stage it is at, and a link to the live thing wherever there is one.

The updated yourOS homepage: Roxy’s open ring surrounded by bento cards for calls, voice, translation, building, design, apps and more.
The yourOS homepage on a phone, with its compact navigation, welcome film button and bento cards.
youros.tech — the homepage bento hero
Our own · coming soon

yourOS

yourOS is an operating system with an AI at its heart. You talk to it like a person, out loud or typed. It makes your calls, plans your days and works on your projects with a crew of agents, on your own private server. Our own product, built from the first commit; the waitlist is open.

What we built
  • Operating system
  • Roxy
  • Agent crew
  • Voice calls
  • App store
  • Website
Meet yourOS →
The Sonora homepage on desktop: a full-bleed dune landscape behind the headline “Transform Your Life with Sound”, with App Store and Google Play download buttons.
The Sonora homepage on a mobile viewport, showing the same hero reflowed to a single column.
sonora.com — homepage, 1440×900
Live · iOS · Android

Sonora

Website, backend and app assets for Sonora, a free AI sound-therapy app on iOS and Android published by Cognitive AI.

What we built
  • Website
  • Backend
  • App assets
Read the case study →
The updated Podswap homepage on desktop: “Grow on Instagram and TikTok for free, with real engagement from creators your size”, beside a tilted wall of exchange, tool and guide cards on a violet gradient.
The updated Podswap homepage on a phone, with its floating navigation, Instagram and TikTok engagement headline and tilted tool cards.
podswap.app — homepage, 1440×900
Five platforms

Podswap

Brand, website, prototype, apps on five platforms, the AI backend and the algorithm-intelligence pipeline for Podswap, a social growth engine that runs without a human in the loop.

What we built
  • Brand
  • Website
  • Prototype
  • Apps on five platforms
  • AI backend
  • Algorithm pipeline
Read the case study →
The unOpen.AI homepage introducing Roxy, a private AI assistant that remembers who you are.
The unOpen.AI homepage on a mobile viewport.
unopen.ai — homepage, 1440×900
Prototype · closed beta

unOpen.AI

In closed beta: Roxy, a private AI assistant with permanent memory running on infrastructure the user owns. Brand, site, product, backend and conversational design.

What we built
  • Brand
  • Site
  • Product
  • Backend
  • Conversational design
Read the case study →
coherence.com on desktop, headed "Intelligence that moves in phase with people".
coherence.com on a mobile viewport, reflowed to a single column.
coherence.com — homepage, 1440×900
Live

Coherence

Live at coherence.com: brand identity generated with AI agents we directed, the motion system and website for the group behind Sonora, AboutAI, WakeUp and MudShadows. Agent work remains in build.

What we built
  • Brand identity
  • Motion system
  • Live website
  • Agent work — in build
Read the case study →
The new Domain Booth homepage on desktop: the headline “Premium Domains. Serious Buyers. Proven Results.” beside the animated DB monogram.
The new Domain Booth homepage on a phone, reflowed to a single column.
Our build of the Domain Booth homepage — 1440×900
Live

Domain Booth

Live at domainbooth.com for DomainBooth, a premium domain brokerage: a new animated mark, every page redesigned and rebuilt with designed mobile layouts, and a custom CMS for its sales record, featured names, press and enquiries.

What we built
  • Animated mark
  • Every page redesigned
  • Designed mobile layouts
  • Custom CMS
Read the case study →
Who we have built for

Twenty-one years. Names you know.

Apps, platforms and campaigns for these teams, long before the AI work. Every one is written up on the work page — what we did, and where our part ended.

See all of our work →
  • BBC Good Food logo
  • Charities Aid Foundation logo
  • GAME logo
  • NatWest logo
  • Next logo
  • NSPCC logo
  • Tesco logo
  • Worldpay logo
  • Samsung logo
  • Sony logo
  • Land Rover logo
  • UAP Limited logo
  • Netflix logo
  • Amazon Prime Video logo
  • Mercedes-Benz dealerships logo
  • San Miguel logo
  • Biovene Barcelona logo
  • Seventy7 logo
  • Littlewoods logo
  • Smile logo
  • The Co-operative Bank logo