Liquid AI Releases d1: A Decision Model That Returns Calibrated Probabilities With Zero Output Tokens


Liquid AI has released d1, a decision model built for structured choices instead of text generation. You give it context and a set of typed questions. It returns calibrated probabilities across a fixed set of outcomes in a single call, with zero generated tokens. The target is the work many teams still send to general LLMs: classification, ticket routing, scoring, moderation, reranking and LLM-as-judge checks.

Is it deployable? Yes, today, as a hosted API. d1 runs on the Liquid API under the model name d1:free. Liquid’s model library lists it as API only and not trainable, so there are no GGUF, MLX or ONNX weights to self-host.

What is a Decision Model?

A decision model evaluates a situation and returns a typed answer from options you define before the call. It does not write text. In every response, usage.output_tokens is 0. Liquid AI’s migration guide gives a simple rule: if the answer is one of N known options, use a decision model. If the model must compose a new string, keep your LLM.

The 3 Primitives: Noul, Choice and Score

  • Noul is a yes/no question that returns a probability between 0 and 1. In Liquid’s example, ‘Is this message a complaint?’ returned 0.999.
  • Choice picks one option from a named set. It returns the top pick, the full distribution and a confidence value. A double-charge ticket scored 0.9997 on ‘billing.’
  • Score rates input on an ordered rubric and returns a probability-weighted position. Levels are indexed from 0, so a 4-level urgency rubric spans 0 to 3. A production outage scored 2.9995.

You can mix all 3 types in one request. The model evaluates every question against the same state in one round trip.

How a d1 API Call Works

Each request has 3 parts: the model, the state (plain text or a JSON object) and the questions. Calls go to POST https://api.liquid.ai/decisions/v1/systemone. Keys come from console.liquid.ai and start with liquid_. The clients are TypeSafe AI’s typesafe-sdk for Python and @typesafe-ai/sdk for TypeScript.

from typesafe_sdk import TypeSafeClient, Noul

client = TypeSafeClient(api_key=os.environ["LIQUID_API_KEY"],
                        base_url="https://api.liquid.ai")
result = client.system_one(
    model="d1:free",
    state="I have been waiting over three weeks for my order...",
    questions={"is_complaint": Noul(
        instructions="Is this message a complaint from the customer?")},
)
print(result.answers["is_complaint"].noul)  # 0.999

Why Move LLM Classification Calls to d1

The migration guide lists the concrete differences against an LLM with structured output:

  • No billed output tokens: An LLM bills output even for a one-word label.
  • Predictable latency: There is no decoding loop that grows with output length.
  • No schema errors: Answers always match the question type, so malformed JSON and retries go away.
  • Usable uncertainty: You get calibrated probabilities instead of a self-reported number.
  • Fewer round trips: 3 sequential classification calls become 1.

Probabilities make thresholds practical. Liquid’s moderation example blocks above 0.8, allows below 0.2 and sends the middle band to human review. Its routing example falls back to the most capable model tier when router confidence drops below 0.5. Liquid also says repeated evaluations of the same input are more consistent, which reduces verdict flips.

Keep an LLM for summarization, drafting, multi-turn chat, code generation and complex multi-step reasoning.

Demo: Road Decider

Liquid’s road-decider cookbook is a pixel-art survival racer. d1 uses a Choice question to pick left, center or right on every decision tick, about 2 to 5 times per second depending on game speed. The app is vanilla JavaScript on Node.js 18+, with a Vite proxy that keeps the API key server-side. A “Jev vs d1” mode races d1 against TypeSafe’s typesafe/jev-1.13 through OpenRouter. The most useful lesson is about state design. Per-lane summaries with distance to the first obstacle produced more confident decisions than a raw grid of the road.

Interactive Explainer: d1 Step by Step

‘;el.appendChild(d);});setTimeout(function(){var f=el.querySelectorAll(‘.fill’);keys.forEach(function(k,i){f[i].style.width=Math.max(obj[k]*100,0.6)+’%’});},60);post();}
function pills(el,list,cb){el.innerHTML=”;list.forEach(function(x,i){var b=document.createElement(‘span’);b.className=”pill”+(i?”:’ on’);b.textContent=x.name;b.onclick=function(){el.querySelectorAll(‘.pill’).forEach(function(p){p.classList.remove(‘on’)});b.classList.add(‘on’);cb(x)};el.appendChild(b)});cb(list[0]);}
/* tabs */
var runners={};
R.querySelectorAll(‘.tab’).forEach(function(t){t.onclick=function(){R.querySelectorAll(‘.tab’).forEach(function(x){x.classList.remove(‘on’)});R.querySelectorAll(‘.pane’).forEach(function(x){x.classList.remove(‘on’)});t.classList.add(‘on’);$(t.dataset.p).classList.add(‘on’);if(runners[t.dataset.p])runners[t.dataset.p]();setTimeout(post,50)}});
/* p1 race */
var bill={billing:0.9997,account:0.0002,returns:0.00005,shipping:0.00003,technical:0.00002};
var toks=[‘{“‘,’department’,'”:’,’ “‘,’billing’,'”}’];var timer;
function race(){clearInterval(timer);$(‘llmTok’).innerHTML=”;$(‘llmCnt’).textContent=”0″;$(‘llmRes’).textContent=”…”;$(‘d1Res’).textContent=”…”;$(‘d1Bars’).innerHTML=”;$(‘llmParse’).classList.remove(‘run’);var c=$(‘d1Core’);c.classList.remove(‘run’);void c.offsetWidth;c.classList.add(‘run’);
setTimeout(function(){bars($(‘d1Bars’),bill,Object.keys(bill));$(‘d1Res’).textContent=”billing”;},450);
var i=0;timer=setInterval(function(){if(i 0.999′},{name:’Harmful content’,p:0.99,q:’state: “You\’re an absolute idiot… I\’m going to find out where you work.”\nnoul: “Does this user message contain harmful, threatening, or abusive content?”\n=> 0.99′}];
function noulUpd(){var hi=+$(‘hi’).value,lo=+$(‘lo’).value;$(‘hiV’).textContent=hi.toFixed(2);$(‘loV’).textContent=lo.toFixed(2);$(‘wiV’).textContent=np.toFixed(3);
R.querySelector(‘.gauge’).style.setProperty(‘background’,’linear-gradient(90deg,#22c55e 0%,#22c55e ‘+lo*100+’%,#f59e0b ‘+lo*100+’%,#f59e0b ‘+hi*100+’%,#ef4444 ‘+hi*100+’%)’,’important’);
$(‘needle’).style.left=”calc(“+np*100+’% – 1.5px)’;$(‘needleV’).textContent=np.toFixed(3);var a=$(‘noulAct’);
if(np>hi){a.textContent=”block”;a.style.background=’#fde2e2′;a.style.color=”#b42318″}else if(np‘+i+”;$(‘scTicks’).innerHTML=t;$(‘scNeedle’).style.left=”-1.5px”;$(‘scV’).textContent=”0″;
setTimeout(function(){$(‘scNeedle’).style.left=”calc(“+(x.s/mx*100)+’% – 1.5px)’;$(‘scV’).textContent=x.s},80);bars($(‘scBars’),x.p,Object.keys(x.p));$(‘scRes’).textContent=x.s;$(‘scConf’).textContent=x.c;
$(‘scAct’).textContent=x.n===4?(x.s>=2.5?’page on-call’:x.s>=1.5?’escalate’:’standard queue’):’escalate (SLA 4h)’;})}
runners.p4=scInit;
/* p5 road */
var L=[‘left’,’center’,’right’],ROWS=6,ob={},cur=1;ob[‘0-1’]=1;ob[‘2-3′]=1;
function road(){var h=””;for(var r=ROWS-1;r>=0;r–){for(var l=0;l<3;l++){var k=l+’-‘+r;h+=’

‘+(ob[k]?’traffic’:’row ‘+(r+1))+’

‘}}
var first=L.map(function(_,l){for(var r=0;r‘+(l===cur?’YOU’:L[l])+’



Source link

  • Related Posts

    Nebius Opens 2026 Physical AI Awards: Five $150K Compute Credit Prizes

    Once a physical AI product is in the field, the compute problem changes shape. Fleet data starts arriving faster than a team can label it, every retraining cycle has to…

    OpenAI Launches dots: Always-On GPT-6 Astra Agents That Work From Their Own Cloud Computers

    OpenAI just introduced dots at their DevDay today. Dots are persistent AI agents powered by GPT-6 Astra. Each dot gets its own cloud computer and browser. It works across 4,000+…

    Leave a Reply

    Your email address will not be published. Required fields are marked *