mirror of
https://github.com/hanzoai/papers.git
synced 2026-10-22 17:20:17 +00:00
Kai: typed decisions under deterministic policy, and its results against public benchmarks
Hanzo CI/CD / test (linux-amd64) (push) Skipped
Hanzo CI/CD / test (linux-arm64) (push) Skipped
Hanzo CI/CD / test-advisory (push) Skipped
Build LaTeX Papers / build-pdfs (push) Failing after 1m10s
ci / papers (push) Failing after 1m26s
Hanzo CI/CD / test-amd64 (push) Successful in 4m30s
Hanzo CI/CD / cicd (push) Successful in 7m25s
CI/CD / cicd (push) Successful in 12m0s
Hanzo CI/CD / test (linux-amd64) (push) Skipped
Hanzo CI/CD / test (linux-arm64) (push) Skipped
Hanzo CI/CD / test-advisory (push) Skipped
Build LaTeX Papers / build-pdfs (push) Failing after 1m10s
ci / papers (push) Failing after 1m26s
Hanzo CI/CD / test-amd64 (push) Successful in 4m30s
Hanzo CI/CD / cicd (push) Successful in 7m25s
CI/CD / cicd (push) Successful in 12m0s
This commit is contained in:
@@ -144,6 +144,7 @@ Auto-generated catalogue of research papers. Regenerate: `scripts/gen-index.sh`
|
||||
| `hanzo-webhooks` | `hanzo-webhooks/hanzo-webhooks.tex` |
|
||||
| `hanzod-attested-compute` | `hanzod-attested-compute.tex` |
|
||||
| `hip-0302-replicate` | `hip-0302-replicate/hip-0302-replicate.tex` |
|
||||
| `kai` | `kai/kai.tex` |
|
||||
| `lightspeed-dex` | `lightspeed-dex/lightspeed-dex.tex` |
|
||||
| `locomo-subject-scope` | `locomo-subject-scope/main.tex` |
|
||||
| `mechanism` | `mechanism/mechanism.tex` |
|
||||
@@ -245,4 +246,4 @@ Auto-generated catalogue of research papers. Regenerate: `scripts/gen-index.sh`
|
||||
| `zen4-thinking_whitepaper` | `zen/zen4-thinking_whitepaper.tex` |
|
||||
| `zen4-ultra_whitepaper` | `zen/zen4-ultra_whitepaper.tex` |
|
||||
|
||||
**Total**: 242 papers
|
||||
**Total**: 243 papers
|
||||
|
||||
BIN
Binary file not shown.
+85
@@ -0,0 +1,85 @@
|
||||
% Kai: typed decisions under deterministic policy. Results.
|
||||
\documentclass[11pt]{article}
|
||||
\usepackage{../shared/hanzocover}
|
||||
\usepackage[utf8]{inputenc}
|
||||
\usepackage[T1]{fontenc}
|
||||
\usepackage{lmodern}
|
||||
\usepackage{amsmath, amssymb}
|
||||
\usepackage{booktabs}
|
||||
\usepackage{array}
|
||||
\usepackage{tabularx}
|
||||
\usepackage{xcolor}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{microtype}
|
||||
\usepackage{listings}
|
||||
\input{../shared/lstlang}
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{colorlinks=true,linkcolor=black,citecolor=blue!50!black,urlcolor=blue!50!black}
|
||||
\setlength{\emergencystretch}{3em}
|
||||
\setlist{itemsep=2pt,topsep=3pt}
|
||||
|
||||
\newcommand{\op}[1]{\texttt{#1}}
|
||||
\newcommand{\best}[1]{\textbf{#1}}
|
||||
|
||||
\lstdefinestyle{wire}{basicstyle=\ttfamily\footnotesize,breaklines=true,
|
||||
columns=fullflexible,keepspaces=true,frame=single,framerule=0.3pt,
|
||||
rulecolor=\color{gray!50},xleftmargin=0.5em,xrightmargin=0.5em}
|
||||
|
||||
\title{Kai: Typed Decisions under Deterministic Policy}
|
||||
\author{
|
||||
Hanzo AI Research\thanks{Corresponding author: [email protected]} \\
|
||||
\textit{Hanzo Industries Inc (Techstars '17)} \\
|
||||
San Francisco, California \\
|
||||
\texttt{https://hanzo.ai}
|
||||
}
|
||||
\date{2026-10-22}
|
||||
|
||||
\setcounter{tocdepth}{1}
|
||||
\begin{document}
|
||||
|
||||
\hanzocoverpage
|
||||
\title{Kai: Typed Decisions under Deterministic Policy\\[0.35em]
|
||||
{\large Results of a decision model and the policy that authorizes its actions}}
|
||||
\maketitle
|
||||
|
||||
\begin{abstract}
|
||||
\noindent
|
||||
Kai is a decision model. A caller states a question, the answers it admits and
|
||||
the evidence; Kai returns a calibrated probability over exactly those answers:
|
||||
one label of a choice, a yes or a no, or a level of a score. It writes no text.
|
||||
A deterministic policy, Nio, holds authority over action: the model recommends,
|
||||
the policy authorizes, and a model verdict can only make a policy verdict
|
||||
stricter. Kai serves \op{POST /v1/decisions} at \texttt{api.hanzo.ai} on CPUs,
|
||||
with answers that agree across CPU families to $2\times10^{-5}$. On a frozen
|
||||
harness of twelve decision tasks Kai averages 0.857 against 0.780 for Jev, a
|
||||
hosted decision model, and 0.675 for Laya, an open one, winning seven tasks and
|
||||
trailing on four. It keeps its accuracy as label sets grow from 4 to 150
|
||||
options; its long-context release reads facts planted in states of up to
|
||||
31,000 tokens at 0.73 to 0.80, where a model trained on short states reads at
|
||||
chance; and on Mind2Web its element accuracy is above the published
|
||||
Flan-T5-Base and GPT-4 baselines at a cost of \$0.00004 a step. Its typed grounding of action consequences, read once on a
|
||||
sealed suite of 14,832 scenes, is right on 99.94\% of the scenes it grounds,
|
||||
and every scene whose harm has no exact count escalates to a person. We report
|
||||
where Kai trails as plainly: it beats neither Jev nor Clef on a public decision
|
||||
index, it trails on sealed transfer suites, it catches fewer jailbreaks than Jev
|
||||
at fewer false alarms, and without the policy it does not weigh the stakes of a
|
||||
trolley problem.
|
||||
\end{abstract}
|
||||
|
||||
\tableofcontents
|
||||
\newpage
|
||||
|
||||
\input{sections/01-introduction}
|
||||
\input{sections/02-interface}
|
||||
\input{sections/03-evaluation}
|
||||
\input{sections/04-results}
|
||||
\input{sections/05-limits}
|
||||
\input{sections/06-conclusion}
|
||||
|
||||
\bibliographystyle{plain}
|
||||
\bibliography{references}
|
||||
|
||||
\appendix
|
||||
\input{sections/a1-wire}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,71 @@
|
||||
@misc{openrouterdecisions,
|
||||
author = {{OpenRouter}},
|
||||
title = {Decisions {API} (alpha): \texttt{POST /api/alpha/decisions}},
|
||||
howpublished = {\url{https://openrouter.ai}},
|
||||
year = {2026},
|
||||
note = {Accessed 2026-09-24}
|
||||
}
|
||||
|
||||
@misc{laya,
|
||||
author = {{Convai Innovations}},
|
||||
title = {Laya: a multilingual, non-autoregressive decision engine},
|
||||
howpublished = {\url{https://huggingface.co/convaiinnovations/laya}},
|
||||
year = {2026},
|
||||
note = {Version 0.3.20, Apache-2.0}
|
||||
}
|
||||
|
||||
@inproceedings{zhang2015agnews,
|
||||
author = {Zhang, Xiang and Zhao, Junbo and LeCun, Yann},
|
||||
title = {Character-level Convolutional Networks for Text Classification},
|
||||
booktitle = {Advances in Neural Information Processing Systems},
|
||||
year = {2015}
|
||||
}
|
||||
|
||||
@inproceedings{saravia2018carer,
|
||||
author = {Saravia, Elvis and Liu, Hsien-Chi Toby and Huang, Yen-Hao and Wu, Junlin and Chen, Yi-Shin},
|
||||
title = {{CARER}: Contextualized Affect Representations for Emotion Recognition},
|
||||
booktitle = {Proceedings of the 2018 Conference on Empirical Methods in Natural Language Processing},
|
||||
year = {2018}
|
||||
}
|
||||
|
||||
@inproceedings{casanueva2020banking77,
|
||||
author = {Casanueva, I{\~n}igo and Tem{\v{c}}inas, Tadas and Gerz, Daniela and Henderson, Matthew and Vuli{\'c}, Ivan},
|
||||
title = {Efficient Intent Detection with Dual Sentence Encoders},
|
||||
booktitle = {Proceedings of the 2nd Workshop on Natural Language Processing for Conversational {AI}},
|
||||
year = {2020}
|
||||
}
|
||||
|
||||
@inproceedings{larson2019clinc,
|
||||
author = {Larson, Stefan and Mahendran, Anish and Peper, Joseph J. and Clarke, Christopher and Lee, Andrew and Hill, Parker and Kummerfeld, Jonathan K. and Leach, Kevin and Laurenzano, Michael A. and Tang, Lingjia and Mars, Jason},
|
||||
title = {An Evaluation Dataset for Intent Classification and Out-of-Scope Prediction},
|
||||
booktitle = {Proceedings of the 2019 Conference on Empirical Methods in Natural Language Processing},
|
||||
year = {2019}
|
||||
}
|
||||
|
||||
@inproceedings{lin2023toxicchat,
|
||||
author = {Lin, Zi and Wang, Zihan and Tong, Yongqi and Wang, Yangkun and Guo, Yuxin and Wang, Yujia and Shang, Jingbo},
|
||||
title = {{ToxicChat}: Unveiling Hidden Challenges of Toxicity Detection in Real-World User-{AI} Conversation},
|
||||
booktitle = {Findings of the Association for Computational Linguistics: EMNLP 2023},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{fitzgerald2023massive,
|
||||
author = {FitzGerald, Jack and Hench, Christopher and Peris, Charith and others},
|
||||
title = {{MASSIVE}: A 1M-Example Multilingual Natural Language Understanding Dataset with 51 Typologically-Diverse Languages},
|
||||
booktitle = {Proceedings of the 61st Annual Meeting of the Association for Computational Linguistics},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{deng2023mind2web,
|
||||
author = {Deng, Xiang and Gu, Yu and Zheng, Boyuan and Chen, Shijie and Stevens, Samuel and Wang, Boshi and Sun, Huan and Su, Yu},
|
||||
title = {{Mind2Web}: Towards a Generalist Agent for the Web},
|
||||
booktitle = {Advances in Neural Information Processing Systems},
|
||||
year = {2023}
|
||||
}
|
||||
|
||||
@inproceedings{zhan2024injecagent,
|
||||
author = {Zhan, Qiusi and Liang, Zhixiang and Ying, Zifan and Kang, Daniel},
|
||||
title = {{InjecAgent}: Benchmarking Indirect Prompt Injections in Tool-Integrated Large Language Model Agents},
|
||||
booktitle = {Findings of the Association for Computational Linguistics: ACL 2024},
|
||||
year = {2024}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
\section{Introduction}
|
||||
\label{sec:intro}
|
||||
|
||||
Most decisions a system takes are typed. A ticket goes to one of ten queues, a
|
||||
message is or is not phishing, a request is urgent on a scale of three, an
|
||||
action is allowed, asked about or denied. A generative model can answer each of
|
||||
these by writing text, but the text must then be parsed, its probability is not
|
||||
the probability of the decision, and the same question asked twice can come
|
||||
back in two forms. Kai answers the decision itself. Given a state and a set of
|
||||
typed questions, it returns for each question a probability over exactly the
|
||||
answers the caller declared.
|
||||
|
||||
A model's answer is not an authorization. Kai's decisions that lead to action
|
||||
pass through Nio, a deterministic policy that holds authority over what is
|
||||
done: the model recommends, the policy authorizes, and a model verdict joined
|
||||
with a policy verdict on \emph{allow} $<$ \emph{ask} $<$ \emph{deny} can only
|
||||
make it stricter. Where a decision turns on consequences, Kai reads the
|
||||
consequences into typed state and Nio decides from that state alone; where the
|
||||
evidence does not establish them, the decision goes to a person.
|
||||
|
||||
This paper reports what Kai achieves against public benchmarks and the models
|
||||
they are usually read with. Section~\ref{sec:interface} states the interface.
|
||||
Section~\ref{sec:evaluation} gives the evaluation protocol and the baselines.
|
||||
Section~\ref{sec:results} gives the results, where Kai leads and where it
|
||||
trails, and Section~\ref{sec:limits} what they do not show.
|
||||
@@ -0,0 +1,35 @@
|
||||
\section{The interface}
|
||||
\label{sec:interface}
|
||||
|
||||
A request holds a state (text or JSON), between 1 and 100 questions and,
|
||||
optionally, a policy. A question is one of three types:
|
||||
\begin{itemize}[leftmargin=1.5em]
|
||||
\item a \emph{choice} over two or more labels, answered by a probability for
|
||||
each label;
|
||||
\item a \emph{yes/no} question, answered by the probability of yes;
|
||||
\item a \emph{score} over one or more ordered levels, answered by a
|
||||
probability for each level and its expected level.
|
||||
\end{itemize}
|
||||
Every answer is a distribution over the declared answers and nothing else, so
|
||||
it is read without parsing and compared without a judge. Unknown keys,
|
||||
repeated keys and malformed questions are refused with the path of the fault.
|
||||
Appendix~\ref{app:wire} shows a request of each kind.
|
||||
|
||||
\paragraph{Policy.} A request may carry a policy instead of leaving the
|
||||
decision to the model. Under the harm policy each course of an action names
|
||||
the people it would harm, either stated by the caller or read by Kai as typed
|
||||
answers to registered questions (what lies on the path, and how many people).
|
||||
Nio takes the course that harms fewest, keeps the default course on a tie, and
|
||||
escalates to a person when any count is unknown, inexact or read below the
|
||||
policy's confidence floor of 0.9. A yes/no answer the policy governs is set by
|
||||
the rule, never by the model, and whatever acts on a verdict passes one gate
|
||||
that refuses any action the verdict does not take. A verdict is advice to a
|
||||
person or to a system that checks it again; Kai's decisions are not used to
|
||||
actuate physical systems.
|
||||
|
||||
\paragraph{Serving.} Kai runs on CPUs in full precision. Two CPU families, an
|
||||
arm64 host and an x86-64 host, give the same answers to $2\times10^{-5}$ on
|
||||
every probability and the same policy outcome on every request measured
|
||||
(Section~\ref{sec:serving}), so an answer read in evaluation is the answer
|
||||
production serves. A request is answered the same way whatever else is
|
||||
queued.
|
||||
@@ -0,0 +1,25 @@
|
||||
\section{Evaluation}
|
||||
\label{sec:evaluation}
|
||||
|
||||
\paragraph{Protocol.} Every number is a kept run read through the same path
|
||||
production serves, \op{kai serve} on a CPU, unless a table says otherwise. A
|
||||
benchmark's test items never enter training: every item of every benchmark in
|
||||
this paper, its normalized text and its near duplicates are held out of every
|
||||
training set by an exact and near-duplicate barrier. A sealed suite is written
|
||||
and hashed before the model it measures is frozen, read once, and spent after
|
||||
its read. Comparisons are paired on the same items: accuracy by McNemar's exact
|
||||
test, other statistics by a paired bootstrap, with Holm's correction over a
|
||||
table's family of tests. Intervals are 95\%.
|
||||
|
||||
\paragraph{Baselines.} \emph{Jev} 1.13 is a hosted decision model served
|
||||
through OpenRouter's Decisions API~\cite{openrouterdecisions}; its numbers are
|
||||
its own answers to the same requests, recorded once. \emph{Laya} is an open
|
||||
decision model~\cite{laya}, run from its released weights. \emph{Clef}'s and
|
||||
\emph{Von}'s numbers are as their authors recorded them on the same suites.
|
||||
Where a public paper reports a baseline, we cite it and say so.
|
||||
|
||||
\paragraph{Releases.} Kai is one model line served under one endpoint. A table
|
||||
reports the release that was read on it: the production model, its
|
||||
long-context release, or the production base with a task head added for one
|
||||
benchmark. A task head reads the base's own pass of a request and changes no
|
||||
other answer.
|
||||
@@ -0,0 +1,260 @@
|
||||
\section{Results}
|
||||
\label{sec:results}
|
||||
|
||||
\subsection{Decision tasks}
|
||||
\label{sec:harness}
|
||||
|
||||
The frozen decision harness asks 11,099 questions over 9,499 states drawn from
|
||||
twelve tasks: news topics~\cite{zhang2015agnews}, emotions~\cite{saravia2018carer},
|
||||
banking intents~\cite{casanueva2020banking77}, support triage, spam, phishing,
|
||||
jailbreaks~\cite{lin2023toxicchat}, toxicity, retrieval relevance, routing,
|
||||
typed decisions, and intents in 51 languages~\cite{fitzgerald2023massive}.
|
||||
Table~\ref{tab:harness} gives accuracy. Kai averages 0.857 against Jev's 0.780
|
||||
and Laya's 0.675. Against the better of the two baselines, within 0.005 a tie,
|
||||
Kai wins seven tasks, ties one and trails on four.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lccc}
|
||||
\toprule
|
||||
task & Kai & Laya & Jev \\
|
||||
\midrule
|
||||
AG News & 0.943 & \best{0.950} & 0.860 \\
|
||||
DAIR emotion & \best{0.935} & 0.595 & 0.603 \\
|
||||
Banking77 & \best{0.907} & 0.425 & 0.835 \\
|
||||
support triage & 0.443 & \best{0.502}$^\dagger$ & 0.365 \\
|
||||
email spam & 0.998 & 0.998 & 0.978 \\
|
||||
phishing & \best{0.990} & 0.983$^\dagger$ & 0.900 \\
|
||||
jailbreak & 0.920 & 0.705 & \best{0.940} \\
|
||||
toxicity & \best{0.802} & 0.530 & 0.662 \\
|
||||
RAG relevance & \best{0.675} & 0.625 & 0.620 \\
|
||||
routing & \best{1.000} & 0.639 & 0.977 \\
|
||||
typed decisions & 0.759 & \best{0.766} & 0.736 \\
|
||||
MASSIVE, 51 languages, macro & \best{0.909} & 0.382 & 0.890 \\
|
||||
\midrule
|
||||
mean of the twelve & \best{0.857} & 0.675 & 0.780 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{The frozen decision harness, accuracy. Kai is the production base;
|
||||
its yes/no rows were read on the base's own yes/no answer, and on 951 held-out
|
||||
items of those tasks the production model reads 0.883 against Jev's 0.875.
|
||||
$^\dagger$Laya's support-triage and phishing items are drawn from data its
|
||||
builder marks as trained on.}
|
||||
\label{tab:harness}
|
||||
\end{table}
|
||||
|
||||
\subsection{Many labels, and labels never seen}
|
||||
\label{sec:labels}
|
||||
|
||||
A decision often has more than a handful of answers. Table~\ref{tab:card}
|
||||
reads accuracy as the label set grows, from four labels to Banking77's 77 and
|
||||
CLINC150's 150~\cite{casanueva2020banking77,larson2019clinc}. Kai holds 0.908
|
||||
at 77 and 150 labels, ahead of Jev up to 77 and behind it at 150. On a public
|
||||
zero-shot pilot, 100 items a dataset with Jev's own request shape, Kai reads AG
|
||||
News at 0.940 and emotions at 0.750 against Jev's published 0.910 and 0.480,
|
||||
and Banking77 with 72 sentence-long labels at 0.810 against 0.870; 35 of the
|
||||
pilot's 300 items also appear in the harness.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lcccc}
|
||||
\toprule
|
||||
labels & 4 & 16 & 77 & 150 \\
|
||||
\midrule
|
||||
Kai & \best{0.968} & \best{0.935} & \best{0.908} & 0.908 \\
|
||||
Jev & 0.905 & 0.853 & 0.843 & \best{0.940} \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Accuracy as the label set grows (400 questions a cell; 77 is
|
||||
Banking77, 150 is CLINC150).}
|
||||
\label{tab:card}
|
||||
\end{table}
|
||||
|
||||
\subsection{Long states}
|
||||
\label{sec:long}
|
||||
|
||||
A planted-fact task hides one fact at a swept position in real text of a given
|
||||
length, with decoys in 60\% of states, and asks a choice, a score or a yes/no
|
||||
question about it: 120 states a cell, chance about 0.33. Kai's long-context
|
||||
release reads it through the served CPU path (Table~\ref{tab:long}). A model of
|
||||
the same size trained on states of up to 1,024 tokens reads at chance from the
|
||||
first cell.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lccccc}
|
||||
\toprule
|
||||
state length (tokens) & 900 & 4,000 & 8,000 & 16,000 & 31,000 \\
|
||||
\midrule
|
||||
Kai, long-context release & 0.800 & 0.758 & 0.733 & 0.792 & 0.733 \\
|
||||
the same base trained to 1,024 tokens & 0.333 & 0.308 & 0.375 & 0.350 & 0.300 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Planted-fact accuracy by state length. The long-context release is
|
||||
read on an x86-64 CPU; the short base was read on a GPU.}
|
||||
\label{tab:long}
|
||||
\end{table}
|
||||
|
||||
\subsection{Web agents}
|
||||
\label{sec:web}
|
||||
|
||||
Mind2Web~\cite{deng2023mind2web} asks, at each step of a real website task,
|
||||
which of the page's candidate elements to act on and how. Kai answers each step
|
||||
as a choice over the 50 candidates the benchmark's ranker supplies, with a task
|
||||
head trained on Mind2Web's training split. Table~\ref{tab:web} reads its element
|
||||
accuracy and step success on the three test splits. Kai's element accuracy is
|
||||
above the published Flan-T5-Base and GPT-4 numbers on every split and below
|
||||
Flan-T5-XL's. Kai writes no text, so a step that types a value cannot count as
|
||||
a full success, which holds its step success below Flan-T5-Base's. On the same
|
||||
300-step samples, Claude Haiku 5.5 and Claude Opus 5.5 given the same candidates
|
||||
read 47.3 / 43.3 / 50.0 and 59.7 / 58.0 / 60.7 element accuracy against Kai's
|
||||
51.3 / 41.3 / 40.7, at \$0.0003 and \$0.011 a step against Kai's \$0.00004.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lcccccc}
|
||||
\toprule
|
||||
& \multicolumn{3}{c}{element accuracy} & \multicolumn{3}{c}{step success} \\
|
||||
\cmidrule(lr){2-4}\cmidrule(lr){5-7}
|
||||
& task & website & domain & task & website & domain \\
|
||||
\midrule
|
||||
Kai, with a task head & 48.8 & 41.5 & 39.1 & 37.5 & 28.6 & 29.2 \\
|
||||
Flan-T5-Base (published) & 43.6 & 32.1 & 33.9 & 41.0 & 29.5 & 31.6 \\
|
||||
Flan-T5-XL (published) & \best{55.1} & \best{42.0} & \best{42.1} & \best{52.0} & \best{38.9} & \best{39.6} \\
|
||||
GPT-4, 50 tasks (published) & 41.6 & 35.8 & 37.1 & 36.2 & 30.1 & 26.4 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Mind2Web cross-task, cross-website and cross-domain splits, percent.
|
||||
Kai's cross-domain split is its first 2,000 steps.}
|
||||
\label{tab:web}
|
||||
\end{table}
|
||||
|
||||
\subsection{Tools}
|
||||
\label{sec:tools}
|
||||
|
||||
An agent must pick the right tool for a request, and know when no tool fits.
|
||||
On held-out lists of candidate tools drawn from public tool-use datasets and
|
||||
Hanzo's own catalog, 5,658 ranked cases, Kai's agentic release ranks the right
|
||||
tool with nDCG@10 0.894 [0.889, 0.898] and puts it first on 0.758 [0.747,
|
||||
0.769] of cases, against BM25's 0.781 and 0.541. Asked whether to call a tool
|
||||
at all, it calls on 0.122 [0.087, 0.168] of the cases where none applies while
|
||||
keeping 0.919 of the cases where one does.
|
||||
|
||||
\subsection{Safety}
|
||||
\label{sec:safety}
|
||||
|
||||
Table~\ref{tab:safety} reads the production model on two sets. On
|
||||
InjecAgent~\cite{zhan2024injecagent}, instructions planted in a tool's output
|
||||
for an agent its user never gave, Kai catches 55\% of the attacks at 2.4\%
|
||||
false alarms. On a pool of 1,163 real jailbreak and injection attacks and
|
||||
1,006 human-written benign prompts, Jev ranks attacks better and catches far
|
||||
more of them at 0.5; Kai raises under a third of Jev's false alarms.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lcc}
|
||||
\toprule
|
||||
& Kai & Jev \\
|
||||
\midrule
|
||||
InjecAgent: attacks caught, of 250 & 138 & -- \\
|
||||
InjecAgent: benign flagged, of 207 & 5 & -- \\
|
||||
real attacks: AUROC & 0.725 & \best{0.896} \\
|
||||
real attacks: caught at 0.5 & 26.9\% & \best{77.4\%} \\
|
||||
human-written benign: flagged at 0.5 & \best{3.6\%} & 13.0\% \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Safety reads of the production model.}
|
||||
\label{tab:safety}
|
||||
\end{table}
|
||||
|
||||
\subsection{Consequences under policy}
|
||||
\label{sec:grounding}
|
||||
|
||||
Under the harm policy, Kai reads for each course of an action what lies on its
|
||||
path and how many people, and Nio decides. This grounding was qualified once, on
|
||||
a sealed suite of 14,832 generated scenes in two settings no candidate had
|
||||
trained on, at the policy's floor of 0.9 (Table~\ref{tab:ground}). 5,680 of the
|
||||
scenes state a harm with no exact count (a crowd past the numerals, a hedged
|
||||
count, infrastructure others depend on, a vague harm) and must escalate; the
|
||||
rest must ground. Of the scenes it grounded Kai was right on 99.94\%, with 5
|
||||
wrong courses in 14,832 scenes, and it grounded 2 of the 5,680 it should not
|
||||
have. On 9,600 further scenes built only of unusable evidence (two possible
|
||||
counts, ranges, corrupted figures, crowds, hedges and dependent infrastructure)
|
||||
it grounded none. One person read the same whether described as a stranger, an
|
||||
employee, a chief executive or the system's own developer, on 480 of 480
|
||||
variants, and a server that keeps someone alive escalated on 400 of 400 scenes
|
||||
where an isolated server read as property.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lr}
|
||||
\toprule
|
||||
scenes & 14,832 \\
|
||||
grounded (both courses read at the floor) & 60.8\% \\
|
||||
right, of the grounded & 99.94\% \\
|
||||
wrong courses, of all scenes & 5 (0.03\%) \\
|
||||
grounded where the harm has no exact count & 2 of 5,680 \\
|
||||
unusable-evidence scenes grounded & 0 of 9,600 \\
|
||||
one person read alike across four roles & 480 of 480 \\
|
||||
life-support infrastructure escalated & 400 of 400 \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{The sealed qualification of the production model's typed grounding,
|
||||
at the floor of 0.9.}
|
||||
\label{tab:ground}
|
||||
\end{table}
|
||||
|
||||
On a public trolley-problem benchmark of 5,240 setups, Kai's own yes/no answer
|
||||
does not weigh the stakes: it pulls the lever in 650 of the 672 setups where
|
||||
pulling kills more than it saves, against Jev's 69 and GPT-6 Luna's 143. Asked
|
||||
through the harm policy instead, Kai takes such a dominated course in 17 of
|
||||
the 672 and escalates to a person wherever a count is not established, 2,291 of
|
||||
the 5,240 setups.
|
||||
|
||||
\subsection{Serving}
|
||||
\label{sec:serving}
|
||||
|
||||
The production model serves on CPUs in full precision. Its release was read on
|
||||
an arm64 host and an x86-64 host before it rolled (Table~\ref{tab:serving}),
|
||||
then canaried through the public API: every answer matched the x86-64
|
||||
reference to $1.5\times10^{-6}$.
|
||||
|
||||
\begin{table}[t]
|
||||
\centering
|
||||
\small
|
||||
\begin{tabular}{lr}
|
||||
\toprule
|
||||
yes/no answers across CPU families: largest difference & $1.8\times10^{-5}$ \\
|
||||
yes/no answers across CPU families: decisions that differ & 0 of 955 \\
|
||||
typed policy requests across CPU families: outcomes that differ & 0 of 400 \\
|
||||
production canary: answers within $1.5\times10^{-6}$ & 16 of 16 \\
|
||||
production request of two questions: server time, median & 209 ms \\
|
||||
yes/no request, x86-64, four threads: median / 95th / 99th & 172 / 1,122 / 1,570 ms \\
|
||||
policy request of seven questions, x86-64: median & 947 ms \\
|
||||
peak resident memory of a server & 3.31 GB \\
|
||||
\bottomrule
|
||||
\end{tabular}
|
||||
\caption{Serving the production model.}
|
||||
\label{tab:serving}
|
||||
\end{table}
|
||||
|
||||
\subsection{Where Kai trails}
|
||||
\label{sec:trails}
|
||||
|
||||
On a public decision index of 38 benchmarks, Kai beats neither Jev nor Clef on
|
||||
any of the 32 rows it was read on. By area, Kai, Jev and Clef read arts 0.35,
|
||||
0.61 and 0.63; knowledge 0.24, 0.66 and 0.66; language 0.38, 0.81 and 0.83;
|
||||
retrieval 0.51, 0.72 and 0.79; tools 0.14, 0.77 and 0.83. The knowledge and
|
||||
language rows ask what a compact decision model does not hold, and Hanzo answers them
|
||||
with its generative models instead. On sealed transfer suites of decision tasks
|
||||
Kai never trained toward, its pooled accuracy is 0.440 against Laya's 0.576 and
|
||||
Von's 0.646 and 0.711; the hardest tier, long policies and multi-hop
|
||||
reasoning, is at chance for every model. On jailbreaks Jev catches far more at
|
||||
0.5 (Table~\ref{tab:safety}), and on the trolley benchmark Kai's own answer
|
||||
does not read the stakes (Section~\ref{sec:grounding}).
|
||||
@@ -0,0 +1,23 @@
|
||||
\section{Limits}
|
||||
\label{sec:limits}
|
||||
|
||||
\paragraph{Advice, not actuation.} A policy verdict is advice to a person or to
|
||||
a system that checks it again. Kai's grounding was qualified on generated
|
||||
scenes in settings it had not seen, not on incidents in the field, and its own
|
||||
yes/no answer does not weigh stakes; Kai is not used to actuate physical
|
||||
systems, and a consequential action stays with a person when the evidence does
|
||||
not establish its counts.
|
||||
|
||||
\paragraph{Counts.} The production policy reads counts from 0 to 100 and
|
||||
escalates anything past them or stated inexactly. Reading an exact count of
|
||||
any size, bound to the right course, from the model alone is the next release's
|
||||
work; no suite reported here measures it.
|
||||
|
||||
\paragraph{Breadth.} Kai decides; it does not reason through knowledge-heavy or
|
||||
multi-hop tasks, where it trails generative models (Section~\ref{sec:trails}).
|
||||
Its transfer to decision tasks unlike its training is below the best open
|
||||
model's, and its jailbreak recall is below Jev's.
|
||||
|
||||
\paragraph{Samples.} Some reads are small: 100 items a dataset in the zero-shot
|
||||
pilot, 300 steps a split for the hosted comparison on Mind2Web, 254 cases where
|
||||
no tool applies. Their intervals, not their points, are the claim.
|
||||
@@ -0,0 +1,13 @@
|
||||
\section{Conclusion}
|
||||
\label{sec:conclusion}
|
||||
|
||||
Kai answers decisions as distributions over declared answers, and Nio, a
|
||||
deterministic policy, alone authorizes action. On a frozen harness of twelve
|
||||
decision tasks Kai leads a hosted and an open decision model on average; it
|
||||
scales to large label sets, reads long states in its long-context release,
|
||||
picks web elements and tools at a fraction of a generative model's cost, and
|
||||
grounds the consequences of an action with an error rate of 0.03\% of scenes
|
||||
while escalating every harm it cannot count. It trails on broad knowledge, on
|
||||
transfer to unlike tasks and on jailbreak recall, and these numbers say so.
|
||||
Kai serves at \texttt{api.hanzo.ai}, with the same answers on every CPU family
|
||||
it runs on.
|
||||
@@ -0,0 +1,77 @@
|
||||
\section{The wire}
|
||||
\label{app:wire}
|
||||
|
||||
A request with one question of each type. The state is invented for this
|
||||
example.
|
||||
|
||||
\begin{lstlisting}[style=wire]
|
||||
{
|
||||
"model": "kai",
|
||||
"state": "Hi, we were billed twice for March. Please refund the duplicate today or we will cancel our plan.",
|
||||
"questions": {
|
||||
"department": {
|
||||
"type": "choice",
|
||||
"instructions": "Which department should handle this?",
|
||||
"criteria": {
|
||||
"billing": "invoices, payments, refunds",
|
||||
"technical": "bugs, outages, system errors",
|
||||
"other": "everything else"
|
||||
}
|
||||
},
|
||||
"urgency": {
|
||||
"type": "score",
|
||||
"instructions": "How urgent is this?",
|
||||
"criteria": ["not urgent", "soon", "blocking"]
|
||||
},
|
||||
"churn_risk": {
|
||||
"type": "boolean",
|
||||
"instructions": "Does the user threaten to cancel or leave?"
|
||||
}
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The answer to \op{department} carries \op{choice}, \op{probabilities} over the
|
||||
three labels, \op{confidence} and \op{answer\_confidence} (its top probability); \op{urgency} carries the expected level \op{score}, a legend and
|
||||
the same summaries; \op{churn\_risk} carries its probability alone. The
|
||||
\op{routing} object names the model that answered and its weights' SHA-256.
|
||||
|
||||
A typed harm request. The scene is invented for this example and belongs to no
|
||||
suite. The four typed questions carry the registered wordings; the policy names
|
||||
them for the two courses and governs the yes/no question \op{act}.
|
||||
|
||||
\begin{lstlisting}[style=wire]
|
||||
{
|
||||
"model": "kai",
|
||||
"state": "You control the brake of a gantry rolling along a greenhouse aisle. If nothing is done it reaches the potting bench, where 3 people are working. If you throw the brake it stops in the empty seed store.",
|
||||
"questions": {
|
||||
"default.kind": {"type": "choice", "instructions": "What lies on the path taken if nothing is done?",
|
||||
"criteria": ["people", "nobody", "asset", "unquantified", "infrastructure"]},
|
||||
"default.count": {"type": "choice", "instructions": "How many people lie on the path taken if nothing is done?",
|
||||
"criteria": ["0", "1", "2", "...", "100", "more"]},
|
||||
"action.kind": {"type": "choice", "instructions": "What lies on the path taken if the act is taken?",
|
||||
"criteria": ["people", "nobody", "asset", "unquantified", "infrastructure"]},
|
||||
"action.count": {"type": "choice", "instructions": "How many people lie on the path taken if the act is taken?",
|
||||
"criteria": ["0", "1", "2", "...", "100", "more"]},
|
||||
"act": {"type": "boolean", "instructions": "Should the brake be thrown?"}
|
||||
},
|
||||
"policy": {
|
||||
"profile": "nio/harm@1",
|
||||
"default": "leave",
|
||||
"courses": {
|
||||
"leave": {"people": {"kind": "default.kind", "count": "default.count"}},
|
||||
"throw": {"people": {"kind": "action.kind", "count": "action.count"}}
|
||||
},
|
||||
"answers": {"act": "throw"}
|
||||
}
|
||||
}
|
||||
\end{lstlisting}
|
||||
|
||||
The count labels are written out in full in a real request (\op{"0"} to
|
||||
\op{"100"}, then \op{"more"}); the listing abbreviates them. The response's
|
||||
\op{policy} object holds the profile, the course taken or none, its basis
|
||||
(\op{fewest}, \op{default}, \op{unknown} or \op{tied}), whether it escalates,
|
||||
the reading of each course (kind, its probability, count, its probability,
|
||||
people, and why), and the questions it governs. The answer to \op{act} is set
|
||||
by the rule, not by the model: 1 or 0 with probability of acting 1, or 0.5 with
|
||||
probability of acting 0 under escalation.
|
||||
Reference in New Issue
Block a user