Стоп-слова в текстах от LLM: как их вычистить и не сойти с ума
Я редактирую тексты, которые генерит модель, по работе уже больше двух лет. Сначала просто переписывал руками. Потом начал собирать список фраз, которые всё время вылезают, и научился вычищать их пачкой — частично промптом, частично пост-обработкой. Этот текст — про эти стоп-слова и про то, как от них избавиться.
Откуда берётся "машинный" привкус
Большие языковые модели обучены на огромном количестве учебных, маркетинговых и журналистских текстов. Там одни и те же речевые штампы повторяются миллион раз, и модель воспринимает их как "вежливый, грамотный, образованный" стиль. Когда ты просишь её написать "полезную статью", она по умолчанию вытаскивает эти штампы, потому что в её картине мира это и есть качественный текст.
Проблема в том, что человек так не пишет. Реальный инженер за кофе не говорит коллеге "стоит отметить, что в современных условиях". Он говорит "короче, это ломается на проде". И когда читатель видит первую фразу в техническом блоге, он понимает: это написала модель, можно не вчитываться.
Топ-30 фраз, которые я вычищаю
Каждая из этих фраз — флаг "автор не очень знает, что хочет сказать".
- "Давайте рассмотрим", "давайте разберёмся"
- "Итак," в начале раздела
- "Стоит отметить, что"
- "Важно понимать, что"
- "Как мы видим", "как видим"
- "Таким образом," в выводе
- "В заключение хотелось бы"
- "В современном мире", "в наше время", "в эпоху цифровизации"
- "Революционный", "мощный", "непревзойдённый"
- "Уникальный инструмент", "уникальная возможность"
- "Полный гайд по", "всё, что нужно знать о"
- "Является" ("X является способом...")
- "Позволяет" ("эта функция позволяет вам...")
- "Осуществляет", "осуществляется"
- "Представляет собой"
- "Не за горами", "не секрет"
- "С каждым днём всё больше"
- "Будущее за", "будущее уже здесь"
- "Открывает новые горизонты"
- "Конечно,", "безусловно,", "несомненно" в начале фразы
- "В сегодняшней статье мы", "в этой статье мы рассмотрим"
- "Перед тем как мы погрузимся"
- "Подводя итог"
- "Ключевой особенностью является"
- "Является краеугольным камнем"
- "Стоит на повестке дня"
- "С точки зрения" (когда не нужно)
- "В рамках данного"
- "На сегодняшний день"
- "При помощи" (часто избыточно)
Список не финальный. У каждого редактора свои триггеры — англицизмы, канцелярит, обороты с "является". Веди свой. Пополняется быстро.
Что не работает
Самое наивное решение — попросить модель: "не используй стоп-слова". Не помогает. Модель забывает за два абзаца, особенно в длинных текстах. Я этим переболел.
Второе наивное решение — приложить весь список из 30 фраз в промпт: "никогда не используй: давайте, итак, ...". Это работает чуть лучше, но не идеально. Модель цепляется за слова в кавычках и иногда пишет "Итак" в первом же абзаце, потому что внимание к промпту падает.
Третий вариант — "перепиши, убрав канцеляризмы". Тоже не выручает: модель в этом запросе часто заменяет одни штампы на другие.
Что работает на этапе генерации
Я перешёл на схему "стиль + анти-примеры". В системном промпте описываю не правила, а голос автора и пару контр-примеров.
Ты пишешь от лица инженера с 10 годами в продакшене.
Говоришь как с коллегой за кофе. Не журналист, не маркетолог.
Плохо: "В современном мире разработки стоит отметить..."
Хорошо: "Это ломается на проде каждый раз, когда нагрузка растёт."
Плохо: "Давайте рассмотрим основные преимущества Postgres."
Хорошо: "За что я выбираю Postgres: транзакции, JSONB, экосистема."Это работает заметно лучше списка запретов. Модель видит "плохо" и "хорошо" с одинаковым смыслом, и подхватывает регистр. Главное — не превращать промпт в инструкцию, а оставлять примерами.
Второй приём — задать длину предложений и абзацев. "Короткие предложения, в среднем 8–14 слов. Никаких длинных периодов с тремя запятыми и причастными оборотами". Это режет канцелярит на корню: "является способом, позволяющим обеспечивать..." просто не помещается в короткое предложение.
Пост-обработка регуляркой
Никакой промпт не вытащит 100% случаев. Я использую двухэтапный подход: модель пишет, потом мой скрипт автоматически чистит самое явное.
const replacements: [RegExp, string][] = [
[/^Итак,\s+/gm, ""],
[/^Конечно,\s+/gm, ""],
[/^Безусловно,\s+/gm, ""],
[/^Несомненно,\s+/gm, ""],
[/Стоит отметить, что\s+/g, ""],
[/Важно понимать, что\s+/g, ""],
[/Как мы видим,?\s+/g, ""],
[/Таким образом,\s+/g, ""],
[/В заключение(\s+хотелось\s+бы)?,?\s+/g, ""],
[/Подводя итог,?\s+/g, ""],
[/В современном мире\s+/g, ""],
[/На сегодняшний день\s+/g, "Сегодня "],
[/при помощи\s+/g, "через "],
[/в рамках данного\s+/g, "в этом "],
];
function stripCliches(text: string) {
let out = text;
for (const [re, sub] of replacements) {
out = out.replace(re, sub);
}
return out;
}Этот скрипт у меня живёт в редакторском пайплайне: модель генерит -> stripCliches -> ручная редактура. На длинных текстах экономит примерно 20–30 минут.
Важная деталь: не делай автоматическую замену "является" на "это". Иногда "является" уместно. Лучше подсветить в редакторе, чем подменить молча.
Подсветка "подозрительных" слов
Для ручной редактуры я делаю отчёт-подсветку. Простой Node-скрипт, который находит все вхождения списка слов и выводит их с контекстом.
const suspects = [
"является",
"позволяет",
"осуществля",
"представляет собой",
"стоит отметить",
"в современном",
"уникальн",
"мощн",
"революционн",
"полный гайд",
];
function highlight(text: string) {
const lines = text.split("\n");
lines.forEach((line, i) => {
const lower = line.toLowerCase();
for (const s of suspects) {
if (lower.includes(s)) {
console.log(`L${i + 1}: ${line}`);
break;
}
}
});
}Прохожусь по выводу, решаю по контексту: оставить, переписать, выкинуть. Это сильно быстрее, чем перечитывать весь текст глазами.
Тяжёлые случаи: "является" и "позволяет"
Эти два глагола — главный канцелярит русского технического текста. Модель их обожает.
"X является инструментом для Y" — почти всегда чище звучит как "X — это инструмент для Y" или "X решает задачу Y". Прямое "X — это Y" в русском нормально и не звучит коряво.
"Эта функция позволяет вам сохранить состояние" — почти всегда лучше "Эта функция сохраняет состояние". Слово "позволяет" нужно тогда, когда речь о возможности, которой можно не воспользоваться. В большинстве технических случаев — нет, инструмент просто делает.
Плохо: useState является хуком, который позволяет добавить состояние.
Хорошо: useState — это хук для состояния.
Плохо: middleware осуществляет проверку токена.
Хорошо: middleware проверяет токен.
Плохо: данный подход представляет собой компромисс.
Хорошо: это компромисс.Когда модель "не хочет" говорить нормально
Бывает, что модель упорно сваливается в формальный тон. Признак: ты пишешь "проще, разговорнее", получаешь те же "стоит отметить". В таком случае помогает поменять подход:
- Дать в промпте кусок реального текста автора и сказать "подражай этому стилю". Это сильнее любых правил.
- Снизить температуру до 0.3–0.5. Низкая температура чаще даёт нейтральный, скучный текст; высокая — иногда вытягивает живость.
- Сменить модель. У Sonnet с русским разговорным стилем у меня обычно лучше, чем у Haiku. Lite-модели чаще скатываются в шаблон.
Что в итоге
Чистка LLM-текстов — это не одна задача, а пайплайн. Стиль и анти-примеры в промпте срезают первый слой. Регулярки убирают остаточные мусорные фразы. Подсветка помогает редактору пройти по подозрительным местам глазами и принять решение.
Главное правило: после всей чистки прочитай текст вслух. Если хоть в одной фразе ты чувствуешь "я бы так не сказал" — её нужно переписать. Регулярка эту проверку не заменит, но без регулярки до неё дольше дойдёшь.