kai

Build on Kai, Hanzo's decision model: it answers typed questions about a state with calibrated probabilities over options you name, and generates no text (POST https://api.hanzo.ai/v1/decisions). Load when code needs a bounded judgment over known options, such as classify, route, gate an action, rank candidates, extract by picking one of the values code found, or verify a claim or field against its source, where the alternative is prompting an LLM and parsing its prose; when writing choice, score or noul questions, confidence thresholds or escalation; when calling Kai over HTTP, from the hanzo-kai (Python) or @hanzo/kai (TypeScript) SDK, or through the kai_* MCP tools; or when moving an integration off TypeSafe's Jev.

Kai

Kai decides; it does not write. Send a state (text or JSON) and named questions, and each answer comes back as a probability over options you wrote: which label, whether a statement holds, which level of a scale. No prose, no reasoning, usage.output_tokens is 0. Your code reads the numbers and decides what to do.

Kai is for bounded judgments inside a program. Writing text, open questions, arithmetic and fact lookup belong to code, search or a Zen model.

Docs first

The docs outrank this skill: read the pages a task needs before writing code. llms.txt indexes every page, and each page's markdown is at https://docs.hanzo.ai/llms.mdx/docs/<path>/content.md. The /docs/kai section is new, and some of its pages may not be published yet. Decisions (the wire) and Kai (the model) are live; when a newer page is missing, say so and work from those two.

| Task | Read | |---|---| | The map of the section | overview | | First call: key, curl, Python, TypeScript, MCP | quickstart | | Request, response, limits, errors, price | decisions | | What a typed decision is | concepts | | What to put in state | state | | Choosing and wording questions | questions, then choice, score, noul, structure | | Thresholds and escalation | confidence | | Breaking a feature into decisions | build, patterns, use cases | | Worked recipes | cookbook, route, triage, gate, loop | | Where the model is weak, measured | limits | | SDKs | Python, TypeScript | | This skill and the MCP tools | agents | | Programs, caches, local runtime | programs | | Moving from Jev | migrate from Jev |

Asking

Acting on answers

Calling

HTTP works today:

curl https://api.hanzo.ai/v1/decisions \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "kai",
       "state": {"ticket": "The export button throws a 500 error since this morning."},
       "questions": {"team": {"type": "choice",
         "instructions": "Which team should handle this ticket?",
         "criteria": {"billing": "charges, invoices, refunds",
                      "tech": "bugs, errors, outages",
                      "other": "anything else"}}}}'

Read answers.team.choice, its confidence, and probabilities over every label. Errors: 400 malformed JSON or unknown model, 401 bad key, 402 no plan or balance, 403 publishable key, 422 a malformed question or a state too long, 429 and 529 (wait Retry-After, then retry).

The SDKs and MCP tools are new. If a package or tool is not published where you are, use HTTP. Both SDKs read HANZO_API_KEY.

from hanzo_kai import Kai, Choice  # uv add hanzo-kai

teams = {"billing": "charges, invoices, refunds", "tech": "bugs, errors, outages", "other": "anything else"}
with Kai() as kai:
    d = kai.decide(state={"ticket": "The export button throws a 500 error."},
                   questions={"team": Choice(instructions="Which team should handle this ticket?", criteria=teams)})
print(d.choices["team"].choice)
import { Kai, choice } from "@hanzo/kai"; // npm i @hanzo/kai; server-side only

const teams = { billing: "charges, invoices, refunds", tech: "bugs, errors, outages", other: "anything else" };
const d = await new Kai().decide({
  state: { ticket: "The export button throws a 500 error." },
  questions: { team: choice("Which team should handle this ticket?", teams) },
});
console.log(d.answers.team.choice); // typed "billing" | "tech" | "other"

MCP: the Hanzo MCP tools kai_decide, kai_choice, kai_score and kai_noul.

From Jev

A Jev integration keeps its state, its questions and the shape of its answers, and moves one of two ways:

  1. On TypeSafe's own SDK, change two settings, TYPESAFE_BASE_URL=https://api.hanzo.ai and TYPESAFE_DEFAULT_MODEL=kai, with a Hanzo sk- key in TYPESAFE_API_KEY. Name kai: no Jev model id becomes Kai.
  2. Or switch to hanzo-kai or @hanzo/kai, or call POST https://api.hanzo.ai/v1/decisions with "model": "kai".

Either way, describe every score level (a null level is refused), then re-run the labeled cases on Kai and set thresholds again; Jev's do not carry over.

Price: 50% lower input-token list price ($0.021 vs $0.042 per 1M). On the frozen harness Kai a7 is more accurate than Jev on 11 of 12 suites, and Jev leads jailbreak 0.940 to 0.920 (results). The Jev guide has the field-by-field differences.

Install

npx skills add https://hanzoskills.com/kai.md

With GitHub access to hanzoai/skills: npx skills add hanzoai/skills --skill kai, or in Claude Code claude plugin marketplace add hanzoai/skills, then claude plugin install kai@hanzoai-skills.