Hanzo decision model · 0 output tokens
How to Use Kai
Send a state and typed questions to POST /v1/decisions with model: "kai". Kai answers each question with a probability for every answer it allows, and writes no text.
Questions
Three question types
Name each question; its answer comes back under the same name.
choiceSend criteria: option → description, or a list of options.Get choice, probabilities (one per option, summing to 1), confidence.
scoreSend criteria: the levels, lowest first.Get score (the expected level index), legend, probabilities by level index.
noulSend instructions: a yes/no question.Get noul: P(true). kai-1.3, the default, does not read a noul’s criteria.
Call it
One request, three questions
Every response also carries id, model, usage (output_tokens is 0), routing (the checkpoint that answered: kai-1.3 for the model id kai), state_hash and latency_ms.
curl -sS --fail-with-body https://api.hanzo.ai/v1/decisions \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kai",
"state": "Customer email: Cancel my plan immediately. Your service was down during our product launch.",
"questions": {
"department": {
"type": "choice",
"instructions": "Route ticket to appropriate team",
"criteria": {
"executive_escalations": "high-value customer cancellation threats",
"support": "general technical inquiries",
"billing": "standard invoice updates"
}
},
"urgency": {
"type": "score",
"instructions": "Rate ticket urgency",
"criteria": ["low", "normal", "high", "critical"]
},
"churn_risk": {
"type": "noul",
"instructions": "Is this account at risk of churning?"
}
}
}'# pip install hanzoai
import os
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AiApi
from hanzoai.cloud.models.ai_decisions_request import AiDecisionsRequest
ai = AiApi(ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"])))
decision = ai.post_decisions(AiDecisionsRequest.from_dict({
"model": "kai",
"state": {"ticket_id": 4821, "text": "Can I get an extension on my payment due date?"},
"questions": {
"team": {
"type": "choice",
"instructions": "Which team handles this?",
"criteria": {"billing": "invoices and payments", "support": "technical issues"},
},
"is_churn_risk": {"type": "noul", "instructions": "Is the user churning?"},
},
}))
print(decision.answers["team"].choice, decision.answers["team"].probabilities)
print(decision.answers["is_churn_risk"].noul)// npm install hanzoai
import { AiApi, Configuration } from 'hanzoai'
const ai = new AiApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }))
const { data: decision } = await ai.postDecisions({
aiDecisionsRequest: {
model: 'kai',
state: { pull_request: 104, diff_lines: 480, files: ['auth.ts', 'token.go'] },
questions: {
risk: {
type: 'score',
instructions: 'Rate security risk of code change',
criteria: ['low: documentation or cosmetic', 'medium: internal logic', 'high: security or auth paths'],
},
},
},
})
console.log(decision.answers.risk.score, decision.answers.risk.probabilities)Limits
What a request may hold
ModelThe model id kai answers from kai-1.3, the default. Ask for kai-1.4 by id for the unified version: one encoder and one head, trained on long states. Ask for kai-1.5 by id for the agentic preview: whether a tool fits a request, and whether to call one at all.
QuestionsUp to 100 a request; 101 is refused with 422.
Statekai-1.3, the default, was trained on 1,024 tokens of state beside each question. Up to 32,768 is answered with routing.extrapolated: true and is unreliable: a fact at the end of a 3,982-token state read 0.507. kai-1.4 was trained on long states and marks no read up to 32,768 extrapolated. Past 32,768 the answer is 422 state_too_long.
TimeOne yes/no question takes <1 ms of server time at p50 in production on GPU (0.27 ms cached in process). Every response reports its own latency_ms.
Price$0.021 per million input tokens; output is free. Jev costs $0.042.
Recipes & Blueprints
Composable Decision Recipes
Modular Rust structs and TypeScript workflows that sit inside your pipelines: retail triage, industrial diagnostics, confidence routing, and agent loops.
recipes::retailShelf inventory triage, return fraud checks, and corporate pricing safety guardrails.
recipes::industrialMulti-criteria powertrain trade studies and telemetry equipment readiness gating.
recipes::routingConfidence margin gates that stand on high-certainty decisions and escalate low-confidence queries to Zen.
recipes::zenOpenAI-compatible request builders and SSE stream accumulators for reasoning thought tokens.
recipes::kataAutonomous test-and-repair agent state machine gating code patch generation vs human review.
recipes::genConversational assistant harness managing multi-turn history and Model Context Protocol (MCP) dispatch.
Coming from Jev
Change the URL, the key and the model
Kai takes the request body Jev takes. The same endpoint also serves typesafe/jev-1.13 with a Hanzo key, at Jev’s price.
# Jev on OpenRouter
curl https://openrouter.ai/api/alpha/decisions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "typesafe/jev-1.13", "state": "…", "questions": {…}}'# Kai on Hanzo: the same body
curl https://api.hanzo.ai/v1/decisions \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "kai", "state": "…", "questions": {…}}'