Русский язык от LLM гарантирует код, а не промпт
В промпте было написано «пиши по-русски». В канал ушли английские заголовки. Разбор того, почему инструкция — не гарантия, и что ставить вместо неё.
В промпте было честно написано: «Пиши по-русски, но названия продуктов оставляй как есть». Модель посчитала заголовок названием — и в канал ушло Introducing Claude Sonnet 5 и Flint: A visualization language….
Промпт был правильный. Он просто ничего не гарантирует.
Что работает вместо инструкции
Три слоя, и все три — код:
- Детектор. Функция
looksRussian(text, original): минимум три кириллические буквы, кириллицы не меньше 35% от латиницы, и текст не является дословной копией исходного заголовка. Латиница внутри допустима — «Anthropic представила Claude Sonnet 5» проходит. - Корректирующий вызов. Не прошло — уходит второй, дешёвый запрос только по проблемным заголовкам, с отдельным системным промптом-переводчиком.
- Отбраковка. Всё ещё не русский — новость выбрасывается. Поэтому кандидатов берём с запасом (
count + 2), и выпуск не худеет.
В отчёт админу пишется «переведено вторым проходом: N» и «отброшено: N» — видно, насколько модель справляется сама.
Побочное открытие: правило ловится регистром
Запретить латиницу нельзя — названия продуктов мы не переводим. Но «Colab CLI» это имя, а «system of record» — английская фраза. Различаются они регистром: каждое латинское слово в русском тексте обязано начинаться с заглавной.
Отсюда родилась проверка isGoodLabel(). «Colab CLI», «Aurora 1.5», «Claude Code в безопасности» — проходят. «Claude в security», «AI coding agents» — нет.
Общее правило
Любое требование к выводу модели — язык, длина, наличие поля, отсутствие ссылок — проверяется кодом после ответа. Промпт снижает вероятность нарушения, но не убирает её. Если нарушение вам дорого обходится, значит, у него должен быть детектор.