Skip to content
Back to Blog

Decision Model vs Structured Output: Do You Still Need a Decision Model With JSON Schema?

What structured output guarantees, and what it does not

The OpenAI documentation says structured outputs make the model always produce a response matching your JSON Schema: required fields are present and enum values are valid.Source: OpenAI structured outputs · 2026-10-12

That solves format. What it does not guarantee:

  • That the value is right: a valid field is not a correct category.
  • How certain the answer is: you get an enum value but not the model's confidence.
  • Edge cases: the OpenAI documentation also states that a refusal or hitting the max-token limit can produce output that does not match the schema, and you handle that separately.Source: OpenAI structured outputs · 2026-10-12

What a decision model returns

A decision model takes state plus questions in and returns answers and probabilities, without generating text. State is whatever you want judged — text or JSON. There are three question types:

  • Choice: pick one option; returns a probability and confidence per option.
  • Score: rate on an ordered scale; returns a probability for each level.
  • Noul: yes/no; returns P(true).

Source: System One decision primitives · 2026-10-12

New to this kind of model? Start with what is a decision model?.

Field mapping: which parts of your schema can move

Original schema fieldBecomesNotes
`enum` (one of several categories)Source: System One decision primitives · Verified 2026-10-18ChoiceUp to 255 options
`boolean` (yes or no)Source: System One decision primitives · Verified 2026-10-18NoulReturns P(true)
A rating field (e.g. 1–5)Source: System One decision primitives · Verified 2026-10-18ScoreUp to 10 levels
Free text, summaries, extracted names and numbersSource: OpenAI structured outputs · Verified 2026-10-18Stays with structured outputThe answer cannot be listed in advance

The test is simple: can the answer be listed in advance? If it can, a decision model answers it. If it cannot, the large model generates it.

The problem with a "confidence" field

Many schemas add a confidence field and ask the model to report a number from 0 to 1. That number, like every other field, is generated by the model.

A decision model returns probabilities per option: one probability for each option, derived from the model's judgement over those options, not written out as text.

This page compares mechanics only; it does not claim one is more accurate. Either way, thresholds have to be validated on your own labelled data.

Rewrite example: a ticket-classification schema

The original schema has three fields: category (enum), urgent (boolean) and replyDraft (string). The first two become a Choice and a Noul in one decision-model request; the draft stays with the large model.

The code below is illustrative and has not been run.

Before: one JSON Schema

ts// Illustrative code, not tested
const ticketSchema = {
  type: 'object',
  properties: {
    category: { type: 'string', enum: ['billing', 'bug', 'account', 'other'] },
    urgent: { type: 'boolean' },
    replyDraft: { type: 'string' },
  },
  required: ['category', 'urgent', 'replyDraft'],
  additionalProperties: false,
};

After: the decision goes to a decision model, the reply stays with the large model

ts// Illustrative code, not tested
import { choice, booleanQuestion } from '@system-one-ai/core';
import type { EvaluationClient } from '@system-one-ai/core';

const ticketQuestions = {
  category: choice('Choose the category of this support ticket.', {
    billing: 'Payments, invoices, and refunds',
    bug: 'The product is broken or behaves unexpectedly',
    account: 'Login, profile, or permission issues',
    other: 'None of the above',
  }),
  urgent: booleanQuestion('Does this ticket need a response within one hour?'),
};

export async function classifyTicket(client: EvaluationClient, ticket: string) {
  const result = await client.evaluate({ state: { ticket }, questions: ticketQuestions });
  return {
    category: result.answers.category.choice,
    categoryConfidence: result.answers.category.confidence,
    urgentProbability: result.answers.urgent.probability,
  };
}

// The reply draft: generate it with the large model's structured output after the
// category is chosen; the schema then keeps only replyDraft.

For how the client is created, see what is a decision model?. Model IDs come from GET /v1/models; don't copy them by hand.

Combining them: decide first, generate second

  1. Let the decision model decide first: which branch, and whether a person is needed.
  2. High confidence follows the branch; low confidence goes to a person or to the large model.
  3. Inside the branch, generate the content it needs — a reply draft, for example — with structured output.

Set thresholds on your own labelled samples. For more combination patterns, see Jev vs ChatGPT, agent tool routing and using a decision model as the first pass in agent evaluation.

How the cost works

Every 4KB is one block, and anything smaller still counts as one block. Cost = blocks × questions × the model rate.

ModelCredits per question per block
Jev1
Clef Flash3
Clef Omni4
Clef6
Decider1

Source: system-one.dev pricing · 2026-10-12

  • Blocks are counted over the whole request's bytes.
  • More questions in one request multiply the cost by question count. The rewrite above asks 2 questions, so the cost is 2 × blocks × rate.
  • Large models bill per token, a different meter; per-unit prices are not directly comparable. Cost both on your own typical request.

New accounts start with 100 credits, and credits never expire. For how to choose a model, see Jev vs Clef.

Want to try? Run a sample (sign-in required).

Verified 2026-10-12

Frequently asked questions

What is the difference between structured output and a decision model?

Structured output guarantees the generated JSON is valid; a decision model answers only predefined questions and returns a probability per option.

Do I still need a decision model with a JSON Schema?

If you want to act on how certain the answer is, enum, boolean and rating fields can become decision-model questions. If the current setup is good enough, there is no need to change.

Is a `confidence` field generated by the model reliable?

That number is generated by the model. A decision model returns probabilities per option. Either way, validate thresholds on your own labelled data.

Which fields should not move?

Free text, summaries, and extracted names and numbers — anything whose values cannot be listed in advance.

What does a rewritten flow look like?

The decision model picks the category and urgency; the large model then generates the reply draft with structured output, keeping only that field in its schema.