Skip to content
Docs

Decision

Ask typed questions about a piece of shared state and get structured answers back. Decision models return choices, scores, and boolean probabilities instead of free-form text, which makes them a fit for classification, routing, rubric-based assessment, and automated verification.

Several questions can be answered in parallel within a single request, against the same state.

To see which decision models AI Gateway supports, use the Decision filter at the AI Gateway Models page.

For a step-by-step setup, see the Decision quickstart.

Through the AI SDK, decisions require ai 7.0.128 or later, or experimental_evaluate on earlier AI SDK 7 releases. Decisions are also available through the HTTP API below and the TypeSafe-compatible API. They are not supported through the OpenAI-compatible, Anthropic-compatible, or Cohere-compatible endpoints.

Decision models were previously called evaluation models. The experimental_evaluate export and gateway.evaluationModel() still work as deprecated aliases with the same request and response shapes.

app/api/decide/route.ts
import { experimental_decide as decide } from 'ai';
 
export async function GET() {
  const result = await decide({
    model: 'typesafe-ai/jev',
    state: 'The support agent issued a full refund to the customer.',
    questions: {
      refunded: {
        type: 'boolean',
        instructions: 'Was a refund issued?',
      },
    },
  });
 
  return Response.json(result.answers);
}

Each key in questions becomes a key in answers:

// result.answers
{
  refunded: { type: 'boolean', probability: 0.99 }
}

Returns a probability between 0 and 1. Supply criteria to define what the true and false cases mean.

const result = await decide({
  model: 'typesafe-ai/jev',
  state: 'The build failed with exit code 1.',
  questions: {
    passed: {
      type: 'boolean',
      instructions: 'Did the build succeed?',
      criteria: {
        true: 'exit code 0',
        false: 'any non-zero exit code',
      },
    },
  },
});
 
// { passed: { type: 'boolean', probability: 0.01 } }

Picks one option from a named set. criteria is a record of option names to descriptions, and the answer carries both the selected choice and the probability of each option.

const result = await decide({
  model: 'typesafe-ai/jev',
  state: 'My card was charged twice for one order.',
  questions: {
    route: {
      type: 'choice',
      instructions: 'Route this support ticket.',
      criteria: {
        billing: 'payment or charge problems',
        shipping: 'delivery problems',
        technical: 'application bugs',
      },
    },
  },
});
 
// {
//   route: {
//     type: 'choice',
//     choice: 'billing',
//     probabilities: { billing: 1, shipping: 0, technical: 0 },
//   },
// }

Rates the state along an ordered scale. criteria is an array of at least two labels, ordered lowest to highest. The answer is an interpolated score plus the probability of each rung.

const result = await decide({
  model: 'typesafe-ai/jev',
  state: 'The PR adds tests, updates docs, and has a clear description.',
  questions: {
    quality: {
      type: 'score',
      instructions: 'Rate the quality of this pull request.',
      criteria: [
        'poor: no tests or docs',
        'fair: partial coverage',
        'good: tests and docs',
        'excellent: tests, docs, and clear rationale',
      ],
    },
  },
});
 
// {
//   quality: {
//     type: 'score',
//     score: 2.97,
//     probabilities: { '0': 0, '1': 0, '2': 0.02, '3': 0.98 },
//   },
// }

Questions of different types can share a single state, and are answered in one round trip.

app/api/triage/route.ts
import { experimental_decide as decide } from 'ai';
 
export async function GET() {
  const result = await decide({
    model: 'typesafe-ai/jev',
    state: 'I cannot log in, and I also want a refund for last month.',
    questions: {
      authIssue: {
        type: 'boolean',
        instructions: 'Is there a login problem?',
      },
      wantsRefund: {
        type: 'boolean',
        instructions: 'Is a refund requested?',
      },
      urgency: {
        type: 'score',
        instructions: 'How urgent is this ticket?',
        criteria: ['low', 'medium', 'high'],
      },
    },
  });
 
  return Response.json(result.answers);
}

Decision fallbacks can rerun a successful decision with another model when a Choice or Score has low confidence, a Boolean probability falls inside an uncertain band, or a compound condition matches. Configure the policy under providerOptions.gateway.models for AI SDK decide, POST /v1/evaluate, or the TypeSafe-compatible API.

Decision fallbacks are opt-in and support one successful-response fallback stage. See Decision Fallbacks for the condition contract, full-request rerun behavior, virtual model configuration, response metadata, and two-stage billing.

state accepts a string, an object, or an array, so you can pass structured records or a message history directly without serializing them yourself.

const result = await decide({
  model: 'typesafe-ai/jev',
  state: {
    order: { id: 'A-1', total: 42.5, status: 'refunded' },
    agent: 'bot-7',
  },
  questions: {
    refunded: {
      type: 'boolean',
      instructions: 'Is the order refunded?',
    },
  },
});

When using an AI Gateway provider instance, specify decision models with gateway.decisionModel(...).

app/api/decide/route.ts
import { experimental_decide as decide } from 'ai';
import { gateway } from '@ai-sdk/gateway';
 
export async function GET() {
  const result = await decide({
    model: gateway.decisionModel('typesafe-ai/jev'),
    state: 'The support agent issued a full refund to the customer.',
    questions: {
      refunded: {
        type: 'boolean',
        instructions: 'Was a refund issued?',
      },
    },
  });
 
  return Response.json(result.answers);
}

If you are not using the AI SDK, post to /v1/evaluate with the same model, state, and questions fields.

decide.sh
curl https://ai-gateway.vercel.sh/v1/evaluate \
  -H "Authorization: Bearer $AI_GATEWAY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe-ai/jev",
    "state": "I was charged twice for my subscription.",
    "questions": {
      "refund": {
        "type": "boolean",
        "instructions": "Is the customer asking for money back?"
      }
    }
  }'

The response reports the model that ran, the answers, token usage, and AI Gateway routing and cost metadata:

{
  "model": "typesafe-ai/jev",
  "answers": { "refund": { "type": "boolean", "probability": 0.98 } },
  "usage": { "inputTokens": 275, "outputTokens": 20 },
  "providerMetadata": {
    "gateway": {
      "routing": {
        "originalModelId": "typesafe-ai/jev",
        "resolvedProvider": "typesafe-ai",
        "canonicalSlug": "typesafe-ai/jev",
        "finalProvider": "typesafe-ai"
      },
      "cost": "0.00001155",
      "marketCost": "0.00001155",
      "surchargeCost": "0",
      "gatewayCost": "0.00001155",
      "generationId": "gen_..."
    }
  }
}

Decision requests work with BYOK. If your team has added a key for the provider, it is used automatically.

/v1/evaluate accepts the same providerOptions as other AI Gateway endpoints, so you can require zero data retention or restrict which providers may serve the request:

{
  "model": "typesafe-ai/jev",
  "state": "...",
  "questions": { "refund": { "type": "boolean", "instructions": "..." } },
  "providerOptions": {
    "gateway": { "zeroDataRetention": true, "only": ["typesafe-ai"] }
  }
}

String entries in providerOptions.gateway.models can name native decision models or language models, and a language model answers through structured output. The array also accepts one conditional decision fallback object. Provider-specific namespaces, such as providerOptions.openai, carry to a matching fallback provider. See Decision Fallbacks for complete requests.

If you already call TypeSafe with its SDK, you don't need to rewrite your requests. Point the client at https://ai-gateway.vercel.sh/typesafe and AI Gateway accepts TypeSafe's own request and response shapes, including noul for Boolean questions. Decision fallbacks work there too.

See TypeSafe API for authentication, supported endpoints, and response headers.

Decision requests report token usage like any other model, and are billed from the model's per-token rates. Check the AI Gateway Models page for the rates on a specific model, since some decision models price input tokens only.

When a decision fallback triggers, both stages are billed and the response usage totals both calls. The stages run sequentially, so the request also includes both model calls' latency. See two-stage usage and latency for details.

const result = await decide({
  model: 'typesafe-ai/jev',
  state: 'The support agent issued a full refund.',
  questions: {
    refunded: { type: 'boolean', instructions: 'Was a refund issued?' },
  },
});
 
console.log(result.usage);
// { inputTokens: 283, outputTokens: 21 }
Last updated October 5, 2026

Was this helpful?

supported.