Что означает каждое поле
Запрос определяет форматы вопросов и ответов. Ответ возвращает результат для каждого из них. Вот поля JSON, используемые в примере.
Поля запроса
model- Идентификатор модели. В примере зафиксирована версия Jev 1.13, поэтому используемая версия указана явно.
state- Текст или структурированные данные для оценки, например сообщение службы поддержки.
questions- Набор решений с заданными именами. Эти же имена используются в поле answers ответа.
<question_id>- Имя, например action или urgency; ответ использует то же имя.
type- Формат ответа: choice выбирает вариант, score оценивает по упорядоченной шкале, а noul отвечает на вопрос «да/нет».
instructions- Конкретное суждение, которое вы хотите, чтобы модель вынесла.
criteria- Допустимые варианты Choice, уровни шкалы Score или значение false и true для Noul.
Поля ответа
answers- Один результат на вопрос, возвращаемый под тем же именем.
choice- Ключ варианта, выбранного полем choice: вариант с наибольшей вероятностью.
probabilities- Вероятность каждого варианта выбора; сумма этих значений равна 1.
confidence- Отдельный показатель уверенности, рассчитанный по распределению вероятностей; это не вероятность выбранного варианта.
score- Позиция на упорядоченной шкале с учётом вероятностей; она может лежать между двумя уровнями.
legend- Соответствие числовых позиций Score заданным вами уровням и их описаниям.
noul- Число от 0 (нет) до 1 (да) для ответа на вопрос «да/нет».
Один контекст и три независимых вопроса: Choice, Score и Probability. Каждый запуск расходует одну попытку из дневного лимита. Ответ правильного формата всё равно может быть ошибочным. Тестируйте репрезентативные случаи и задавайте пороги маршрутизации для своего процесса.
LangChain · PythonJev в контуре управления агентом LangChain
Контур управляет вызовами модели и инструментов. В точке принятия решения Jev анализирует сообщение, планируемый вызов инструмента или состояние агента и возвращает типизированный ответ. Следующий шаг определяет ваш код; открытые задачи остаются за чат-моделью.
ModelRouterMiddlewarebefore_agent → wrap_model_callПеред запуском классифицируйте последнее сообщение пользователя, выберите модель и используйте её на протяжении всего запуска. Выбор, вероятности и уверенность остаются доступны в состоянии агента.
AutoModeMiddlewarewrap_tool_callПроверяйте выбранный вызов инструмента до выполнения. Если Jev обнаружит риск или недостаточные полномочия, промежуточный обработчик заблокирует вызов и вернёт ToolMessage с ошибкой. Запроса на одобрение человеком не будет.
TypeSafeClassifierChoice · Score · NoulСвои проверки можно добавить в пользовательский промежуточный обработчик: передавайте сообщения или состояние агента в TypeSafeClassifier и используйте Choice, Score или Noul для ветвления кода либо передачи сомнительных случаев на проверку.
LangChain · Python · ModelRouterMiddleware
# pip install "langchain-typesafe[experimental]" langchain-openai
# Set TYPESAFE_API_KEY and OPENAI_API_KEY on your server.
from langchain.agents import create_agent
from langchain_typesafe.experimental.middleware import (
ModelChoice, ModelRouterMiddleware,
)
router = ModelRouterMiddleware(
choices={
"fast": ModelChoice(
model="openai:gpt-5.6-terra",
criteria="Simple lookups and extraction.",
),
"powerful": ModelChoice(
model="openai:gpt-6-astra",
criteria="Complex reasoning and high-stakes decisions.",
),
},
instructions="Choose the least costly model that can do the task safely.",
)
agent = create_agent("openai:gpt-5.6-terra", middleware=[router])
result = agent.invoke({"messages": [{"role": "user", "content": "Summarize this log."}]})
print(result["model_route"].choice)
TypeScript на стороне сервера
TypeScript · fetch// Run on your server. Keep the API key out of browser code.
const apiKey = process.env.OPENROUTER_API_KEY;
if (!apiKey) throw new Error("Set OPENROUTER_API_KEY");
const response = await fetch("https://openrouter.ai/api/alpha/decisions", {
method: "POST",
headers: {
Authorization: "Bearer " + apiKey,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "typesafe/jev-1.13",
state: {input: "A customer reports a duplicate charge."},
questions: {
team: {
type: "choice",
instructions: "Which team should handle this?",
criteria: {
billing: "Payments and refunds",
technical: "Bugs and integrations"
}
},
urgency: {
type: "score",
instructions: "How urgent is the issue?",
criteria: ["Can wait", "Needs attention today", "Immediate action"]
},
escalate: {
type: "noul",
instructions: "Should a human review this first?",
criteria: {false: "No review needed", true: "Review before acting"}
}
}
})
});
if (!response.ok) throw new Error("Decision request failed");
const {answers} = await response.json();
console.log(answers.team.choice, answers.urgency.score, answers.escalate.noul);