Как научить нейросеть чужому стилю без дообучения - QubStore

Как научить нейросеть чужому стилю без дообучения

Содержание статьи

Агента, который пишет голосом бренда, обычно предлагают получать дообучением: выгрузить архив постов, собрать датасет, арендовать A100 и оставить LoRA учиться на ночь. Я вместо этого написал два навыка для Claude Code / Codex. Вместе они снимают манеру автора с его готовых текстов и переписывают по ней любой нейрослоп в голос этого автора, без обучения, датасета и видеокарты. Водянистый текст, написанный ChatGPT, расходился с манерой одного крупного телеграм-канала по 14 признакам из 31, а после работы навыков осталось 2. Вся работа занимает вечер, а результат переносится на любую модель, потому что правила стиля лежат в промпте, а не в весах.

Работают навыки по очереди. Первый читает выгрузку канала и снимает с неё профиль стиля: скрипт замеряет десятки признаков, от длины фразы и абзаца до частоты тире, эмодзи и обращений к читателю, а модель превращает замеры в правила. Второй навык берёт эти правила и переписывает по ним любой черновик. Профиль снимается один раз и живёт дальше обычным текстовым файлом в git, а текстов по нему пишется сколько угодно.

Мера тоже оттуда. Скрипт считает по каждому признаку не среднее значение, а вилку: нижнюю и верхнюю границу обычного разброса автора. Готовый текст сверяется с этими вилками, и признак, вышедший за край, идёт в счёт как отклонение. Ориентир дают живые посты самого канала: они попадают в собственный профиль с 2-5 отклонениями из 31, так что мои 2 — это попадание, а не подгонка. Корпус я обезличиваю: он принадлежит крупному бренду, а все тексты в примерах сгенерированы и живому каналу не принадлежат.

Почему дообучение здесь лишняя работа

Цену видно по публичным разборам. Автор клона себя на дообученной модели собрал 51 000 примеров из переписки, арендовал A100 на 40 ГБ, потратил 10,5 часа обучения, а результат описал сам как странное поведение и генерацию несвязанного текста. Тем же путём идёт разбор Системного Блока про дообучение под чужую манеру письма. Через API карты не нужны, но 5000 примеров стоят $100-300, а 24 000 около $700, при аренде A100 от 200 ₽ в час.

Упрекать эти разборы неудачей нечестно, они писались при другом выборе моделей. Довод против дообучения держится на механике: оно зашивает манеру в веса конкретной модели, и переход на другую модель обнуляет работу целиком. Профиль стиля остаётся обычным текстом, поэтому файл, который сегодня читает Claude, завтра прочитает GPT. Вторая причина менее очевидная: дообученную модель нельзя показать заказчику изнутри, а за каждым правилом профиля стоит число, посчитанное по текстам самого заказчика.

Почему модель не умеет копировать стиль сама

Модель знает про автора факты, а не приёмы. Ведёт популярный канал, пишет коротко, любит хлёсткие формулировки: этого хватит, чтобы узнать человека в пересказе, и не хватит, чтобы им писать. Приёмы выглядят мелко и незаметно: длина обычной фразы вместе с разбросом этой длины, длинное тире против дефиса с пробелами у того, кто печатает с телефона, кавычки ёлочками или прямые, обращение к читателю или дистанция. Таких мелочей десятки, и ни одну из них модель не считала, поэтому она берёт две-три самые заметные черты и утрирует их до карикатуры.

Это измеряли и не на моём стенде: в работе arXiv:2509.14543 больше 400 живых авторов и свыше 40 000 генераций, а вывод там про усреднённый тон и про то, что рост числа примеров в промпте почти не помогает. Проверяли few-shot, а не дообучение, так что «учёные доказали, что файнтюн не работает» я не утверждаю.

Профиль стиля: два файла и три слоя

Отсюда и вырос профиль. Раз посчитать приёмы автора модель не может, посчитать их нужно за неё и отдать готовыми, в том виде, который она исполняет буквально: не «пиши энергично», а норма с частотой. Такой набор норм я и называю профилем стиля, и лежит он в двух файлах, а внутри у них три слоя, где числа стоят снизу, слова над числами, а инструкции сверху.

Профиль стиля: три слоя. A — замеры, считает скрипт. B — карта голоса, пишет модель. C — правила генерации, читает тот, кто пишет текст

Первый слой — замеры, отдельный файл JSON: ни одного слова про автора, только цифры, посчитанные обычным скриптом без участия нейросети. Он меряет геометрию текста, частоту первого лица и обращений, тире, дефисы в роли тире, кавычки, эмодзи, капслок, латиницу, официальные обороты и оговорки, приводит всё к частоте на 1000 слов и по каждому признаку выдаёт вилку, а не среднее.

Второй слой — карта голоса словами, уже во втором файле. Её пишет модель, прочитав корпус, и отвечает на то, что цифрами не измеряется: в каком регистре говорит автор, как шутит, чем доказывает правоту, как относится к читателю. Здесь работает правило, без которого всё разваливается: каждый пункт опирается либо на число из первого слоя, либо на конкретный кусок корпуса, а если подтверждения нет, модель обязана написать «в текстах не проявлено», иначе получится профиль человека, которого не существует.

Третий слой — правила генерации, там же следом за картой: техническое задание для модели, которая пишет новый текст. С чего начинать, что чем чередовать, какая медиана длины фразы, чем набирать тире, чего не делать никогда. Формулировка «энергичный и авторитетный тон» тут бесполезна, нужна норма с частотой.

Сквозное правило всех трёх слоёв: в профиль идёт приём, а не содержание. Проверяется оно попыткой угадать по готовому профилю, о чём были исходные тексты, и если угадывается, снят пересказ корпуса, а написанное по нему будет выглядеть плагиатом. Под это в профиле отведён отдельный раздел с перечнем того, что притворяется стилем: предметная область, имена и версии, жанровые рамки площадки и высокая доля латиницы, которая растёт и падает вместе с темой.

Разделение на три слоя я не придумал за вечер, оно собрано из работ по переносу стиля и стилометрии, и каждая дала свою часть.

  • From theories on styles to their transfer in text, Troiano и соавторы: иерархия типов стиля и вывод, что стиль и содержание полностью не разделяются. Отсюда в профиле раздел про утечку содержания.

  • Deep Learning for Text Style Transfer: A Survey, Jin и соавторы: стиль как набор контролируемых атрибутов при генерации. Отсюда третий слой, где стиль задаётся нормами, а не описанием.

  • A Survey on Representing Linguistic Style: интерпретируемые признаки по языковым уровням против непрозрачных нейронных представлений. Отсюда первый слой в виде обычных чисел, которые можно прочитать глазами.

  • Analyzing Writing Styles of Bloggers with Different Opinions: прикладная стилометрия блогов, лексические, синтаксические и структурные признаки. Отсюда сам перечень того, что имеет смысл мерить в постах.

Отправной точкой была и вещь попроще: промпт-шаблон «портрет стиля» Антона Вдовиченко, один плоский JSON, где измеримое, интерпретируемое и додуманное лежали вперемешку и заполнялись на глаз. Перечень тем оттуда полезен для карты голоса, а разведение замеров, интерпретации и правил по трём слоям с требованием опоры на число появилось уже как ответ на эту кашу.

Как этим пользоваться

Разбираться в устройстве профиля полезно, а собирать его руками не придётся: замеры считает скрипт, карту голоса и правила пишет модель, от человека нужны три промпта обычными словами. Профиль снимается один раз на автора, дальше по нему пишется сколько угодно текстов. Имя канала в промптах ниже я обезличил.

Первый промпт снимает профиль по штатной выгрузке канала из Telegram Desktop:

Сними профиль стиля по выгрузке export‑channel.json: корпус сохрани как corpus‑channel.md в корне стенда, профиль положи в папку profiles

Корпус агент собирает сам и выбрасывает пересылы: пересланный пост написал другой человек, и его манера иначе достанется автору по ошибке. У меня из 1085 сообщений выгрузки осталось 252 своих поста с текстом, это 191 456 знаков.

Второй промпт пишет текст (в примере ниже — это изменение уже готового текста, но можно тем же способом генерить сразу новый текст в указанном стиле):

Перепиши slop.md голосом канала, результат сохрани в out-channel.md, исходник не меняй, профиль лежит в profiles. Соблюдай профиль целиком

Третий промпт не обязательный, но позволяет фактически проверить результат:

Прогони сверку скриптом навыка, style.py check, против профиля канала из profiles по двум файлам: slop.md и out-channel.md

Что показала сверка

Теперь числа, ради которых всё и затевалось. По умолчанию сверка пропускает признак, который на длине черновика ожидается реже 1,5 раза, и тексты разной длины считаются по разным знаменателям. Я эту экономию отключаю, поэтому оба текста ниже проверены по всем 31 признаку профиля.

Текст

Отклонений от профиля бренда

Исходник от ChatGPT, 316 слов

14 из 31

Переписано по профилю, 1141 знак

2 из 31

Как научить нейросеть чужому стилю без дообучения

Хвост таблицы сверки исходного текста: вне допуска 14 из 31

Так выглядит вывод сверки на исходнике, а так на тексте, написанном по профилю: те же признаки, тот же знаменатель.

Как научить нейросеть чужому стилю без дообучения

Хвост таблицы сверки текста по профилю: вне допуска 2 из 31, длинное тире и эмодзи в диапазоне канала

Приметы нейротекста, которые ничего не значат

У этих чисел есть слабое место, и назову его я сам: сверка считает моим скриптом по моему же профилю, то есть инструмент проверяет собственную работу. Поэтому дальше два взгляда со стороны, которые про профиль ничего не знают: народная примета, по которой нейротекст принято узнавать на глаз, и внешний детектор.

Начну с приметы. Первым признаком машины обычно называют длинное тире. У исходного текста от ChatGPT оно стоит 51,85 раза на 1000 слов при вилке живого канала 24,0-63,16, то есть машинный текст попадает внутрь неё целиком: по главной примете нейротекста живой бренд и нейрослоп неразличимы.

Теперь взгляд второй, машинный. Детектор нейротекста режет текст на сегменты и метит каждый отдельно, а про мой профиль и про то, как текст писался, не знает ничего. Исходник от ChatGPT он разбирает так: 2 сегмента из 2 с признаками генерации.

Как научить нейросеть чужому стилю без дообучения

Вердикт нейродетектора на исходном тексте: большая часть текста вероятно сгенерирована ИИ

А вот тот же текст после переписывания по профилю канала, с эмодзи, капслоком и длинным тире через слово.

Как научить нейросеть чужому стилю без дообучения

Вердикт нейродетектора на тексте по профилю: текст скорее всего написан человеком, HUMAN один сегмент

Вывод отсюда простой: считать длинное тире уликой бессмысленно. Общее правило описывает среднего пишущего, профиль описывает конкретного, и там где они спорят, выигрывает профиль. Инструмент, который вычистил бы у этого канала длинное тире, эмодзи и капслок по общему правилу, срезал бы вместе с ними его фирменную манеру.

Как повторить

Оба навыка открыты и ставятся двумя командами:

/plugin marketplace add vyacheslav-startsev/claude-plugins

/plugin install style-skills@startsev-plugins

Скрипту понадобятся razdel и pymorphy3, около 15 МБ, и ставить их нужно руками: pip install razdel pymorphy3 pymorphy3-dicts-ru. Без них профиль тоже снимется, только без разбора по частям речи и временам глаголов. Дальше остаётся отдать агенту выгрузку и попросить словами снять профиль.

Исходники навыков: https://github.com/vyacheslav-startsev/claude-plugins/tree/main/plugins/style-skills

Повторять это разумнее всего на собственных текстах: снять профиль, прогнать сверку на любом готовом посте и посмотреть на число отклонений. У меня живые авторские тексты дают от 2 до 5 из 31, и мне интересно, какая цифра выйдет у других: напишите её в комментариях.

Ссылка на основную публикацию