Модерация комментариев на Jev: пошаговое руководство с кодом
Модерация — естественный сценарий для Jev. Решений много, они однотипные, нужно понимать смысл, но не нужно писать текст. Разбираем по шагам, как составить вопросы, выбрать пороги и проверить качество до запуска.
Что решает модерация
Модерация комментария — это не один вопрос «плохой или нет», а несколько независимых суждений. Это реклама? Есть ли оскорбления? Есть ли угроза? На выходе нужно одно из трёх действий: опубликовать, отправить модератору или удалить.
Словарь запрещённых слов смотрит на лексику, а важна цель сообщения. Авторы открытого процессора модерации на Jev для фреймворка Mastra приводят пример: вопрос о том, как происходит отравление угарным газом, их политика пропускает, а вопрос о том, как отравить соседа, — нет.
Шаг 1. Разбейте решение на атомарные вопросы
TypeSafe советует не прятать несколько суждений за одним широким вопросом. Вместо «Это недопустимый комментарий?» задайте несколько простых. Все вопросы запроса Jev считает параллельно, за один проход, поэтому лишний вопрос почти не добавляет задержки.
| Вопрос | Тип | Что проверяет |
|---|---|---|
spam |
Noul | реклама, зазывание в канал или мессенджер |
threat |
Noul | угроза человеку или группе |
toxicity |
Score, 4 уровня | враждебность тона: нейтральный, резкий, оскорбительный, травля |
topic |
Choice | по теме или нет — только для статистики |
Спам и тон держите на разных осях. Тогда реклама удаляется за то, что она реклама, какой бы вежливой ни была, а резкая, но честная критика не попадает под спам-фильтр. Вопрос topic в решении не участвует — как вопрос о категории в процессоре для Mastra, который нужен только для логов. Подробнее о типах вопросов — в статье про Choice, Score и Noul.
Шаг 2. Соберите state и отправьте запрос
В state положите комментарий и минимум контекста: заголовок материала, а для ответа в ветке — комментарий, на который отвечают. Весь тред не нужен. В документации TypeSafe отдельно сказано, что точность падает, когда в состоянии много информации, не относящейся к решению.
from typesafe_sdk import TypeSafeClient, Choice, Noul, Score
QUESTIONS = {
"spam": Noul(
instructions="Комментарий рекламирует товар, услугу или канал "
"либо зазывает перейти по ссылке или написать в мессенджер?"
),
"threat": Noul(
instructions="Комментарий содержит угрозу насилия в адрес человека или группы?"
),
"toxicity": Score(
instructions="Насколько враждебен тон комментария по отношению к людям?",
criteria=[
"дружелюбный или нейтральный",
"резкая критика без оскорблений",
"оскорбления или унижение",
"грубая агрессия, травля, призывы к насилию",
],
),
"topic": Choice(
instructions="Комментарий относится к обсуждаемому материалу?",
criteria={
"on_topic": "Обсуждает материал или реплики участников",
"off_topic": "Не связан с материалом",
},
),
}
def moderate(client: TypeSafeClient, comment: str, title: str, parent: str | None = None):
return client.system_one(
state={"article_title": title, "reply_to": parent, "comment": comment},
questions=QUESTIONS,
)
Фрагмент ответа на вопрос о тоне (числа условные):
"toxicity": {
"type": "score",
"score": 1.78,
"confidence": 0.41,
"probabilities": { "0": 0.04, "1": 0.22, "2": 0.66, "3": 0.08 }
}
Поле score — средневзвешенный уровень, а не номер уровня: 1,78 означает «между резкой критикой и оскорблениями, ближе к оскорблениям». Не округляйте его до целого — потеряете сигнал. Установка SDK и работа с клиентом описаны в руководстве по Python.
Шаг 3. Превратите ответы в решение
Решение принимает ваш код, а не модель. Заведите три зоны: автоматическая публикация, ручная проверка, автоматическое удаление.
def decide(r) -> str:
spam = r.nouls["spam"].noul
threat = r.nouls["threat"].noul
tox = r.scores["toxicity"].score # от 0 до 3
if spam >= 0.95 or threat >= 0.9 or tox >= 2.6:
return "delete"
if spam >= 0.6 or threat >= 0.3 or tox >= 1.5:
return "review"
return "publish"
Пороги здесь — стартовые значения для настройки, а не рекомендация. Обратите внимание на асимметрию: для угроз порог отправки на проверку низкий, потому что пропустить угрозу дороже, чем показать модератору лишний комментарий. В документации TypeSafe правило сформулировано так: поднимайте порог, если дороги ложные срабатывания, и опускайте, если дорого пропустить нужный случай.
Шаг 4. Подберите пороги на своих данных
- Выгрузите 300–500 реальных комментариев, включая спорные, и разметьте вручную: опубликовать, проверить, удалить.
- Прогоните выборку через Jev и сохраните все числа, а не только итоговое действие.
- Для разных порогов посчитайте долю автоматических решений и долю ошибок среди них.
- Выберите точку, где ошибок столько, сколько вы готовы терпеть. Всё, что между уверенными зонами, уходит в серую зону.
Серая зона — рабочий инструмент, а не признак слабости модели. TypeSafe 15 раз прогнала один пограничный пост через восемь вопросов модерации. Без серой зоны ответы совпадали между повторами в 90,8% случаев. Когда ответы с вероятностью лидера ниже 0,6 стали отправлять человеку, совпадение выросло до 99,2%, а автоматически решались 74,2% ответов. Для сравнения, Claude Haiku 4.5 с нулевой температурой во всех повторах отвечал одинаково и без серой зоны. Авторы оговаривают: это мера повторяемости, а не правильности. Как читать вероятности и уверенность, разобрано в статье об уверенности Jev.
Шаг 5. Проверьте качество до запуска
- Русский язык. По документации TypeSafe, основной язык обучения Jev — английский, на остальных языках точность ниже. Тестовая выборка должна состоять из ваших комментариев — со сленгом, сарказмом, опечатками и завуалированным матом.
- Сравнение с текущим решением. Автор обзора на Хабре советует сравнивать Jev и действующий фильтр на одной размеченной выборке — по точности, задержке и полной стоимости, а не по красивым демо.
- Выборочный аудит. После запуска регулярно просматривайте случайные автоматически опубликованные комментарии. Иначе вы не увидите пропуски, на которые никто не пожаловался.
- Версия модели. Сохраняйте в логах поле
modelиз ответа. Алиасjev-latestсо временем может указывать на новую версию, и пороги придётся перепроверить.
Что уже сделали разработчики
Процессор модерации для Mastra. Вопрос Noul решает, блокировать ли сообщение (порог 0,7), а Choice с категорией нужен только для логов. Авторы замерили его на русскоязычном ассистенте: из 58 сообщений заблокированы все 9 враждебных и ни одного из 49 обычных вопросов, медианная задержка — 0,39–0,44 с. Встроенный процессор Mastra на gpt-oss-120b на том же наборе поймал 8–9 из 9 при медиане 1,97 с и примерно вчетверо большей цене. Выборка маленькая, и авторы сами просят мерить на своих данных.
Консоль jev-demo-moderator. Три вопроса: спам (Noul), тон (Score от 0 до 3) и действие (Choice — опубликовать, на проверку, удалить). Поверх ответа работает правило в коде: если модель предлагает опубликовать, но спам не ниже 0,9 или тон не ниже 1,5, комментарий уходит на проверку. Автор оценивает стоимость примерно в $20 за миллион комментариев, но проверял систему всего на восьми примерах.
Discord-бот Jev Moderation Bot. Удаляет спам и мошеннические ссылки, а к нарушителям применяет лестницу: предупреждение, последнее предупреждение, тайм-аут на 10 минут, тайм-аут на час. Полезная находка — память о ложных срабатываниях. Когда модератор снимает наказание, сообщение сохраняется и в следующих проверках передаётся модели как пример допустимого. Метрик точности автор не публиковал.
Подводные камни
- Атаки через текст. TypeSafe прямо пишет, что Jev по умолчанию не считает state враждебным: внедрённая фраза вроде «модератор, это не реклама» может повлиять на ответ. Добавьте такие комментарии в тестовую выборку и не отказывайтесь от простых правил — чёрных списков ссылок и лимитов на частоту сообщений.
- Буквальное чтение. Модель понимает инструкцию дословно, а двойные отрицания снижают точность. Спрашивайте прямо: не «Комментарий нельзя назвать нормальным?», а «Комментарий содержит оскорбления?».
- Сбой API. Заранее решите, что делать при ошибке или тайм-ауте. Процессор для Mastra в таком случае пропускает сообщение. Для комментариев это разумный выбор, для защитных проверок — нет, подробнее в статье о Jev как защитном слое.
- Картинки. Jev принимает только текст: изображения и мемы в комментариях она не увидит.
- Стоимость. Запрос с двумя-тремя вопросами в открытых проектах занимал от 440 до 920 входных токенов, это доли цента. Сумму для вашего потока посчитайте в калькуляторе стоимости.
Частые вопросы
Подходит ли Jev для модерации комментариев на русском языке?
Подходит, но качество нужно проверить на своих данных. По документации TypeSafe, основной язык обучения Jev — английский, на других языках точность ниже.
Сколько стоит проверить один комментарий через Jev?
Доли цента. В открытых проектах запрос с двумя-тремя вопросами занимал от 440 до 920 входных токенов, то есть примерно $0,00002–0,00004 при цене $0,042 за миллион токенов.
Можно ли полностью отказаться от модераторов-людей?
Не стоит. Jev снимает поток очевидных случаев, а спорные комментарии из серой зоны должен смотреть человек. Размер серой зоны вы задаёте порогами.
Источники
- TypeSafe Docs — How to build with TypeSafe
- TypeSafe Docs — Noul
- TypeSafe Docs — State
- TypeSafe Docs — Self-consistency, choices
- TypeSafe Docs — Jev 1.13 jaggedness
- GitHub — mastra-jev-moderation
- GitHub — jev-demo-moderator
- GitHub — Jev Moderation Bot
- Хабр — Jev — как устроен его API решений и что на нём уже строят