Модель Jev от TypeSafe (ID: typesafe/jev-1.13) позиционируется как «System One» — инструмент для получения типизированных решений с калиброванными вероятностями, а не генерации текста. В отличие от chat-моделей, Jev возвращает распределение вероятностей по заранее заданным критериям, что позволяет программно маршрутизировать запросы (publish, hold, reject) без парсинга текста. Ниже приведено практическое руководство по интеграции Jev в стек TypeScript для задач модерации контента, например, на маркетплейсе.
01Архитектура: Код против Модели
Ключевой принцип работы с Jev — разделение задач. Код должен обрабатывать детерминированные проверки, а Jev — семантический анализ. Отправлять в модель стоит только то, что требует интерпретации естественного языка.
- Оставьте в коде: Проверка цены в диапазоне, количество фото, длина текста, арифметика (например, «цена ниже средней по категории на 50%»).
- Отдайте Jev: Определение запрещенных товаров (контрафакт, оружие), выявление попыток перевода сделки вне платформы, проверка соответствия категории и описания.
02Структура данных: State и Questions
Запрос к Jev состоит из двух частей: state (контекст, который нужно оценить) и questions (список суждений). State может быть строкой, JSON-объектом или массивом. Для JSON-объектов используйте «field path» (путь к полю в обратных кавычках, например, `listing.description`), чтобы модель точно знала, какой текст анализировать.
Существует три типа вопросов:
- Choice: Выбор одного варианта из списка. Возвращает победителя, вероятности всех вариантов и метрику confidence (уверенность, основанная на форме распределения, а не просто на вероятности победителя).
- Noul: Бинарная проверка истинности утверждения. Возвращает вероятность истинности. Метрика confidence отсутствует, так как вероятность уже выражает уверенность.
- Score: Оценка по упорядоченной шкале. Возвращает средневзвешенное значение, вероятности каждого уровня и легенду.
03Пример интеграции на TypeScript
Рассмотрим задачу модерации объявления на маркетплейсе. Сначала определим типы данных, а затем подготовим запрос к API.
// listing.ts
export const CATEGORIES = {
electronics: 'Phones, laptops, cameras, audio gear, game consoles, and their accessories.',
furniture: 'Tables, chairs, sofas, beds, shelving, and other household furniture.',
clothing: 'Apparel, shoes, bags, and fashion accessories.',
sporting_goods: 'Bikes, fitness equipment, camping gear, and equipment for playing sports.',
toys_and_baby: 'Toys, games, strollers, car seats, cribs, and other children’s items.'
} as const;
export type Category = keyof typeof CATEGORIES;
export const CONDITIONS = ['for_parts', 'fair', 'good', 'like_new', 'new'] as const;
export type Condition = (typeof CONDITIONS)[number];
export type Listing = {
id: string;
title: string;
description: string;
category: Category;
condition: Condition;
priceUsd: number;
photoCount: number;
};При формировании запроса к Jev, определения категорий передаются как текст в state, чтобы модель могла сопоставить объявление с семантическим описанием категории.
// moderation.ts
import { JevClient } from '@typesafe/jev'; // Псевдо-импорт, используйте реальный SDK
async function moderateListing(listing: Listing) {
// 1. Hard rules (код)
if (listing.photoCount < 1 || listing.priceUsd < 0) {
return { status: 'reject', reason: 'Invalid metadata' };
}
// 2. Подготовка State для Jev
const state = {
listing: {
title: listing.title,
description: listing.description,
category: listing.category,
condition: listing.condition,
priceUsd: listing.priceUsd,
// Включаем определения категорий для семантического сравнения
categoryDefinitions: CATEGORIES
}
};
// 3. Формирование вопросов (Questions)
const questions = [
{
name: 'is_prohibited',
type: 'noul',
instructions: 'Is the item a prohibited type (weapon, counterfeit, recalled child seat)?',
criteria: ['true', 'false']
},
{
name: 'off_platform_payment',
type: 'noul',
instructions: 'Does the listing ask the buyer to pay or chat off-platform?',
criteria: ['true', 'false']
},
{
name: 'category_match',
type: 'choice',
instructions: 'Does the item fit the category: `listing.category`?',
criteria: Object.keys(CATEGORIES)
},
{
name: 'condition_score',
type: 'score',
instructions: 'Rate the condition of the item based on description.',
criteria: CONDITIONS // ['for_parts', 'fair', 'good', 'like_new', 'new']
}
];
// 4. Вызов API
const response = await jevClient.evaluate({
model: 'typesafe/jev-1.13',
state: state,
questions: questions
});
// 5. Валидация и Policy
return processJevResponse(response);
}04Настройка порогов уверенности (Confidence Thresholds)
Jev не принимает решений за вас, он предоставляет вероятности. Ваша задача — сравнить их с порогами, откалиброванными на размеченной выборке (labeled sample).
- High Confidence + Match: Автоматический publish.
- Low Confidence / Ambiguous: Hold для ручной модерации.
- High Confidence + Mismatch: Reject.
05Кому подойдёт / что запустится
Данная архитектура подходит для:
- Маркетплейсов: Автоматическая фильтрация запрещенных товаров и нецелевых категорий.
- Тикет-систем: Маршрутизация обращений в зависимости от тональности и темы.
- Гейтинга инструментов: Проверка безопасности запросов к внешним API (agent tool gating).
Для запуска потребуется аккаунт OpenRouter и доступ к модели typesafe/jev-1.13. Локально запустить Jev на стандартных GPU (RTX 3090/4090) сложно из-за специфики архитектуры принятия решений, поэтому облачный API является основным способом использования. Стоимость зависит от токенов, вложенных в state и questions, поэтому оптимизируйте размер контекста, передавая только необходимые поля.
Источник: OpenRouter ↗
