System One API (Decisions API): что это и как работает
System One API (Decisions API) — это эндпоинт, который отправляет модели не запрос на генерацию текста, а состояние и набор типизированных вопросов, и получает обратно готовые ответы с вероятностями: да или нет, один из вариантов, оценку по шкале.
Обычная языковая модель пишет ответ токенами, а приложение потом пытается вытащить из этого текста решение. Модели класса decisions устроены иначе: они читают входные данные за один проход и возвращают вероятность для каждого допустимого ответа, не генерируя ни одного токена.
Откуда взялось название
Деление на две системы мышления — из психологии: быстрые интуитивные суждения и медленное рассуждение. В ИИ так стали называть два класса моделей. System Two — привычные генеративные модели, которые рассуждают и пишут связный текст. System One — модели, которые быстро выдают структурированное решение и на этом заканчивают.
Термин закрепила TypeSafe: в её документации System One описан как класс моделей, а Jev — первая модель этого класса. Liquid AI свои модели того же назначения называет просто decision models. В RouterAI оба названия обозначают одно и то же — эндпоинт, на который можно отправить decisions-модель.
Как это работает
Запрос состоит из двух частей. В state лежит то, что нужно оценить: строка, объект или массив, а модели с поддержкой изображений принимают ещё и картинки. В questions — именованные вопросы с типом и инструкцией. Имя вопроса придумывает разработчик: модель его не видит, ответ придёт под этим же ключом.
{
"model": "liquid/d1.1",
"state": "Клиент пишет, что деньги списались дважды.",
"questions": {
"refund_requested": {
"type": "noul",
"instructions": "Клиент прямо просит вернуть деньги?"
}
}
}
Типы вопросов:
| Тип | Что спрашиваем | Что приходит в ответе |
|---|---|---|
noul |
Да или нет? | вероятность «да» от 0 до 1 |
choice |
Какой вариант из списка? | победивший вариант, probabilities по всем вариантам, confidence
|
score |
Где на шкале? | положение на шкале, probabilities по уровням, confidence
|
box |
Где объект на изображении? | координаты рамки и confidence
|
У choice варианты задаются объектом «ключ — описание», у score — массивом уровней от 2 до 10. Все вопросы к одному state уходят одним запросом и обрабатываются параллельно, поэтому добавление вопросов почти не увеличивает время ответа.
Ответ приходит в поле answers, по ключу на каждый вопрос:
{
"answers": {
"is_urgent": { "type": "noul", "noul": 0.997 },
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.55,
"probabilities": { "billing": 0.697, "technical": 0.298, "sales": 0.005 }
},
"frustration": {
"type": "score",
"score": 0.59,
"confidence": 0.36,
"probabilities": { "0": 0.418, "1": 0.575, "2": 0.007 },
"legend": { "0": "Спокоен, просто описывает ситуацию", "1": "Раздражён, но вежлив", "2": "Очень зол, резкие выражения" }
}
},
"usage": { "input_tokens": 224, "output_tokens": 0 }
}
Два поля стоит читать вместе со значением. confidence показывает, насколько модель уверена в победителе — низкое значение означает, что варианты близки. probabilities показывает, как распределились голоса: в примере выше биллинг выиграл, но техническая команда получила почти 30%, и такое обращение разумно отправить обоим адресатам.
Чем отличается от Chat Completions
| Chat Completions | System One (Decisions) | |
|---|---|---|
| Вход | массив сообщений |
state и questions
|
| Выход | текст, который надо разобрать | типизированные значения и вероятности |
| Откуда вероятность | из вероятностей токенов, нередко после повторного вызова | из модели напрямую, калибрована под варианты |
| Токены на выходе | оплачиваются | не генерируются, output_tokens равен нулю |
| Ответ вне списка вариантов | возможен | невозможен: выбор только из ваших вариантов |
| Форма ответа | свободная | одна из заранее заданных |
Главное практическое отличие — предсказуемость. Текстовый ответ может не совпасть со схемой, а decisions-модель физически не может ответить тем, чего нет в списке. Ответ сразу ложится в if, порог или сортировку, и разбирать его регуляркой не нужно.
Вторая разница — цена и скорость. Тарифицируются только входные токены, выход бесплатен. Liquid AI на своей странице d1 приводит 200–300 мс на текстовое решение.
Есть и ограничение: decisions-модель нельзя вызвать через Chat Completions — запрос вернёт ошибку.
Модели в RouterAI
В каталоге RouterAI 29 карточек моделей с выходом decisions (считая алиас ~typesafe/jev-latest). Цены — в рублях за 1 млн входных токенов, по данным каталога.
| Модель | id | Контекст | Цена за 1 млн входных токенов | Для чего |
|---|---|---|---|---|
| Joey 1 | baseten/joey-1 |
16K | 1,06 ₽ | самый дешёвый вариант для массовых проверок |
| Clef Flash | cloudflare/clef-flash |
24K | 1,91 ₽ | быстрая классификация текста и изображений |
| d1.1 | liquid/d1.1 |
64K | 2,12 ₽ | универсальный вариант: текст и картинки, понятная документация |
| Reflex | morph/reflex |
64K | 4,46 ₽ | повторные вопросы по одному состоянию благодаря кэшу |
| Jev 1.14 | typesafe/jev-1.14 |
256K | 4,46 ₽ | длинные документы, все типы вопросов включая box
|
Разброс по цене внутри класса доходит до четырёх раз, поэтому модель выборки стоит подбирать под задачу, а не брать первую из списка. Чем крупнее модель и длиннее контекст, тем выше цена за токен.
Пример запроса
Эндпоинт: POST https://routerai.ru/api/v1/decisions. Синоним — /api/v1/systemone, он работает так же и возвращает тот же ответ. Модель, state и questions обязательны: без любого из них RouterAI ответит 400, не обращаясь к провайдеру.
import requests
resp = requests.post(
"https://routerai.ru/api/v1/decisions",
headers={"Authorization": "Bearer sk-xxxxxxxxxxxxxxxx"},
json={
"model": "liquid/d1.1",
"state": "Здравствуйте! Третий день не могу подключить оплату на сайте — платежи клиентов не проходят, мы теряем заказы. Помогите, пожалуйста, срочно.",
"questions": {
"is_urgent": {
"type": "noul",
"instructions": "Клиент сообщает о срочной проблеме?",
},
"department": {
"type": "choice",
"instructions": "Какая команда должна заняться обращением?",
"criteria": {
"billing": "Платежи, счета, возвраты, подписки",
"technical": "Ошибки, сбои, интеграции, настройка",
"sales": "Тарифы, покупка, вопросы до оплаты",
},
},
"frustration": {
"type": "score",
"instructions": "Насколько раздражён клиент?",
"criteria": [
"Спокоен, просто описывает ситуацию",
"Раздражён, но вежлив",
"Очень зол, резкие выражения",
],
},
},
},
)
answers = resp.json()["answers"]
if answers["is_urgent"]["noul"] > 0.8:
ticket.priority = "high"
route(answers["department"]["choice"])
Тот же запрос через curl:
curl -X POST "https://routerai.ru/api/v1/decisions" \
-H "Authorization: Bearer $ROUTERAI_API_KEY" \
-H "Content-Type: application/json" \
-d @request.json
На живом запросе с liquid/d1.1 та же фраза дала is_urgent 0,997, department — billing с вероятностью около 0,70 и frustration 0,59. Вероятности от прогона к прогону немного меняются, поэтому пороги подбирайте на своих данных.
Где применяется
- Маршрутизация запросов. Вопросы «какая это область?», «насколько сложная задача?» — и простые запросы уходят дешёвой модели, сложные — сильной. Логика выбора описана в статье про маршрутизацию ИИ-запросов.
-
Классификация. Тема обращения, отдел, язык, тип документа — задача
choiceс закрытым списком. - Guardrails. Проверка входящих и исходящих сообщений на инъекцию промпта, персональные данные, вредный запрос. Проверка стоит доли копейки рядом с вызовом модели, поэтому её можно ставить на каждое сообщение — см. Guardrails в ИИ.
- Выбор действия в агенте. Когда агенту нужно решить, какой инструмент вызвать дальше, он получает список инструментов и возвращает один вариант — без текстовых рассуждений. Обвязку, в которой такой вызов живёт, разбирает статья про Agent Harness.
Связь с RouterAI
RouterAI отдаёт decisions-модели через тот же ключ и тот же баланс, что и Chat Completions: работа из России без VPN, оплата в рублях, отдельный аккаунт провайдера не нужен. Эндпоинт один, а модели — из общего каталога, где у каждой карточки указаны контекст и цена.
Полезное свойство каталога: если модель поддерживает только текст, а не изображения, это видно по характеристикам карточки ещё до запроса. Алиас ~typesafe/jev-latest всегда указывает на актуальную версию Jev, а в ответе поле model содержит датированный снимок, который обслужил запрос, — его стоит логировать, если вы подбирали пороги под конкретную версию.
Ограничения
- Модель отвечает только вариантами из вашего списка: если ни один не подходит, она всё равно выберет ближайший. Для
choiceдобавляйте вариант «ничего из перечисленного». -
noul— не шкала: значение около 0,5 означает «модель не может решить», а не «средний уровень». Для уровня используйтеscore. - Ограничения запроса: 32 000 токенов на
stateи самый длинный вопрос, 64 000 токенов наstateвместе со всеми вопросами, до 255 вариантов в одномchoice. - Некоторые модели на входе принимают
stateлюбой длины, но фактически читают только начало — например, серии Clef на Workers AI обрезают текст примерно до первых 2K токенов. - Модель не объясняет решение. Если нужна причина отказа, спросите её отдельным вопросом
choiceс вариантами причин.
Что почитать
- Jev: решения вместо текста — основной гайд RouterAI по decisions-эндпоинту
-
Как задавать вопросы — типы вопросов,
state, картинки - Рецепты и ограничения — готовые схемы и лимиты
- System One — документация TypeSafe о классе моделей
- Introducing d1 — как устроена модель d1 от Liquid AI
- clef-flash на Workers AI — описание одной из моделей Cloudflare