API Jev — справочник на русском
У Jev один рабочий метод: POST /v1/systemone. Вы отправляете состояние и типизированные вопросы, а получаете ответы с вероятностями. Здесь собрано всё для интеграции без SDK, сверенное с документацией TypeSafe.
Эндпоинт и авторизация
Все решения Jev идут через один эндпоинт:
POST https://api.typesafe.ai/v1/systemone
Authorization: Bearer <API_KEY>
Content-Type: application/json
Ключ создаётся в консоли TypeSafe (console.typesafe.ai) и передаётся в заголовке Authorization после слова Bearer. Доступ к консоли пока выдают по листу ожидания. Как туда попасть, рассказано в статье о доступе к Jev.
Храните ключ в переменной окружения, например TYPESAFE_API_KEY, и вызывайте API только с сервера: ключ из браузерного кода увидит любой посетитель страницы. Официальные SDK для Python и JavaScript читают ключ из этой переменной сами.
Минимальный рабочий запрос:
curl -X POST https://api.typesafe.ai/v1/systemone \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "jev-latest",
"state": "Третий день не проходят выплаты, клиенты жалуются.",
"questions": {
"is_urgent": { "type": "noul", "instructions": "Обращение срочное?" }
}
}'
Кроме основного метода есть служебный GET /v1/models. Он возвращает имена моделей, доступные вашему аккаунту, с описанием и датой выпуска.
Тело запроса
| Поле | Тип | Обязательное | Что передавать |
|---|---|---|---|
model |
string | да | Имя модели или алиас, например jev-latest |
state |
string, object или array | да | Что оценивать: текст, JSON-запись, переписку, состояние программы |
questions |
object | да | Словарь вопросов: ключ выбираете вы, значение описывает вопрос |
state — то, что модель оценивает. Для одного сообщения хватит строки, но в большинстве задач TypeSafe советует объект с понятными именами полей: ticket, order, refund_policy. Тогда вопрос может сослаться на нужную часть через путь в обратных кавычках, как в примере ниже. Модель принимает только текст, поэтому изображения, аудио и видео нужно заранее превратить в текст или структурированные поля. Как собирать состояние, разобрано в статье о state в Jev.
questions — словарь, где ключ (is_urgent, department) нужен только вашему коду: ответ вернётся под тем же ключом. Модель ключ не видит. Полный вопрос всегда пишите в instructions, даже если имя кажется говорящим.
Поля вопроса
| Поле | Noul | Choice | Score |
|---|---|---|---|
type |
"noul" |
"choice" |
"score" |
instructions |
обязательно | обязательно | обязательно |
criteria |
необязательно, объект с ключами true и false |
обязательно, словарь «вариант → описание или null», до 255 вариантов | обязательно, упорядоченный массив уровней, от 2 до 10 |
instructions и описания в criteria принимают строку, объект или массив. Объект пригодится, когда вопросу нужны данные, например запись из базы, с которой сравнивается state: вопрос кладут в одно поле, данные в другие. Чем три типа отличаются и как выбрать нужный, описано в статье о Choice, Score и Noul.
Пример с тремя типами вопросов:
{
"model": "jev-latest",
"state": {
"ticket": {
"subject": "Двойное списание",
"body": "С карты дважды списали оплату заказа. Верните деньги как можно скорее."
}
},
"questions": {
"refund_requested": {
"type": "noul",
"instructions": "Клиент в `ticket.body` просит вернуть деньги?",
"criteria": {
"true": "Прямо просит вернуть или компенсировать оплату",
"false": "Только сообщает о проблеме или задаёт вопрос"
}
},
"department": {
"type": "choice",
"instructions": "Какой отдел должен ответить на обращение?",
"criteria": {
"billing": "Оплата, списания, возвраты, счета",
"tech": "Ошибки, сбои, настройка",
"other": null
}
},
"urgency": {
"type": "score",
"instructions": "Насколько срочно нужно ответить?",
"criteria": ["Может подождать неделю", "Ответить в течение дня", "Ответить в течение часа"]
}
}
}
Что здесь происходит:
refund_requested— Noul с необязательнымиcriteria. Они уточняют, что считать «да», когда граница тонкая. Для большинства Noul хватает одной формулировки.department— Choice. Модель видит и названия вариантов, и описания, аnullставят там, где название понятно без пояснений. Вариантotherстрахует от обращений, которые не подходят ни одному отделу.urgency— Score. Уровни идут от меньшего к большему, номер уровня равен его позиции в массиве, отсчёт с нуля.
Тело ответа
{
"model": "jev-1.13.0",
"answers": {
"refund_requested": { "type": "noul", "noul": 0.93 },
"department": {
"type": "choice",
"choice": "billing",
"probabilities": { "billing": 0.9, "tech": 0.06, "other": 0.04 },
"confidence": 0.84
},
"urgency": {
"type": "score",
"score": 1.3,
"legend": {
"0": "Может подождать неделю",
"1": "Ответить в течение дня",
"2": "Ответить в течение часа"
},
"probabilities": { "0": 0.05, "1": 0.6, "2": 0.35 },
"confidence": 0.41
}
},
"usage": { "input_tokens": 452, "output_tokens": 38 }
}
Числа в примере условные: они показывают форму ответа, а не реальный вывод модели.
На верхнем уровне три поля. model сообщает версию, которая ответила, даже если в запросе стоял алиас; логируйте её рядом с ответом. В answers лежат ответы под теми же ключами, что и вопросы. В usage — входные и выходные токены, платите вы только за входные.
| Тип | Поле | Что означает |
|---|---|---|
| noul | noul |
Вероятность ответа «да», от 0 до 1. Отдельного confidence нет |
| choice | choice |
Вариант с наибольшей вероятностью |
| choice | probabilities |
Вероятность каждого варианта, в сумме 1 |
| choice, score | confidence |
Насколько распределение сосредоточено на одном ответе, от 0 до 1 |
| score | score |
Позиция на шкале: номера уровней, умноженные на их вероятности и сложенные |
| score | legend |
Номер уровня и его описание из запроса |
| score | probabilities |
Вероятность каждого уровня, ключи — номера уровней в виде строк |
Чаще всего сбивает с толку score. Это не номер победившего уровня, а средневзвешенная позиция, поэтому значение бывает дробным: в примере 0 × 0,05 + 1 × 0,6 + 2 × 0,35 = 1,3. Если коду нужен один уровень, округлите. Если сравниваете шкалы разной длины, поделите score на номер верхнего уровня, то есть на число уровней минус один.
Одно и то же значение 1,0 получится и при всей вероятности на уровне 1, и при половине на уровнях 0 и 2. Поэтому в спорных случаях смотрите probabilities и confidence. Как ставить пороги по уверенности, рассказано в статье об уверенности Jev.
Модели и версии
Имя в model |
Куда указывает | Когда использовать |
|---|---|---|
jev-latest |
jev-1.13.0 |
Последний стабильный релиз, значение по умолчанию в SDK |
jev-preview |
jev-1.13.0 |
Последний релиз, включая предварительные; сейчас совпадает с jev-latest |
jev-1.13.0 |
— | Зафиксированная версия |
Алиас переезжает на новую версию без изменений на вашей стороне, и распределения вероятностей могут сдвинуться. Если вы подбирали пороги уверенности на конкретной версии, указывайте её явно и переходите на новую по своему графику.
Лимиты
- 64 000 токенов на запрос:
stateи все вопросы вместе; - 32 000 токенов на
stateвместе с самым длинным вопросом; - 1200 запросов в минуту и 250 000 токенов в секунду, при превышении любого лимита приходит ошибка 429;
- до 255 вариантов в Choice, от 2 до 10 уровней в Score;
- только текст: строка, JSON-объект или массив.
TypeSafe предупреждает, что лимиты сейчас меняются динамически из-за спроса, а повышенные доступны на корпоративных тарифах. Основной язык обучения — английский. Другие языки модель обрабатывает, но хуже, поэтому вопросы на русском проверяйте на своих данных.
Оплачиваются только входные токены. По данным Polza.AI, к каждому запросу добавляется около 280 служебных токенов, а state оплачивается один раз на запрос. Поэтому несколько вопросов выгоднее отправлять одним запросом; этот приём подробно разобран в статье о speculative fan-out.
Коды ошибок
| Код | Причина | Что делать |
|---|---|---|
| 401 | Нет ключа или он неверный | Проверьте заголовок Authorization и то, что ключ выдан той площадкой, куда уходит запрос |
| 422 | Тело не прошло валидацию | Прочитайте тело ответа: в нём указано проблемное поле |
| 429 | Превышен лимит запросов или токенов | Повторите с экспоненциальной задержкой |
| 529 | TypeSafe временно перегружена | Повторите с экспоненциальной задержкой |
Ошибки приходят со стандартными HTTP-кодами и JSON-телом, где описано, что пошло не так. На 429 и 529 не повторяйте запрос сразу. Удваивайте паузу между попытками и добавляйте случайный разброс, чтобы параллельные воркеры не стучались в API одновременно. SDK TypeSafe делают это сами и учитывают заголовок retry-after, если он пришёл.
Запрос не пройдёт валидацию, если нарушена схема из таблиц выше. Проверьте, что:
- в прямом HTTP-запросе есть поле
model(SDK подставляютjev-latestсами); criteriaу Score передан массивом, а не объектом с номерами уровней;- у Choice есть
criteria, а у Score не меньше двух уровней; - в
typeстоит ровноnoul,choiceилиscore.
Разбор типичных ошибок и готовые схемы повторов — в статье об ошибках API Jev.
Совместимые площадки
Тот же формат запроса принимают агрегаторы. Меняются адрес, ключ и иногда имя модели:
| Площадка | Адрес | Модель |
|---|---|---|
| TypeSafe | https://api.typesafe.ai/v1/systemone |
jev-latest |
| OpenRouter | https://openrouter.ai/api/v1/systemone |
typesafe/jev-1.13 или jev-latest |
| Polza.AI | https://polza.ai/api/v1/systemone |
typesafe/jev |
| Vercel AI Gateway | базовый адрес для SDK https://ai-gateway.vercel.sh/typesafe |
typesafe-ai/jev |
Площадки добавляют в ответ свои поля: OpenRouter возвращает id, provider и usage.cost, Polza.AI — стоимость в рублях в usage.cost_rub. Работать через них можно, пока вы ждёте прямого доступа к TypeSafe: ключ выдают сразу после регистрации.
Частые вопросы
Какой эндпоинт у API Jev?
POST https://api.typesafe.ai/v1/systemone с ключом в заголовке Authorization. У OpenRouter и Polza.AI путь тот же, меняются домен, ключ и имя модели.
Какую модель указывать в поле model?
jev-latest — алиас последнего стабильного релиза, сейчас это jev-1.13.0. Если вы подбирали пороги под конкретную версию, указывайте jev-1.13.0 явно.
Сколько токенов можно отправить в одном запросе?
До 64 тысяч на весь запрос. Отдельно действует лимит 32 тысячи на state вместе с самым длинным вопросом.
Сколько вариантов может быть в Choice и уровней в Score?
До 255 вариантов в одном Choice и от 2 до 10 уровней в Score.
Почему score в ответе дробный?
Это позиция на шкале, взвешенная по вероятностям уровней, а не номер победившего уровня. Если коду нужен один уровень, округлите значение.
Что делать при ошибке 429 или 529?
Повторить запрос с экспоненциальной задержкой. Официальные SDK делают это автоматически.