curl, терминал, API-ключ провайдера LLM, 3–5 своих текстов-образцов на 1–2 абзаца, файл с исходным «ИИ-текстом»output.txt, в котором 0 совпадений с вашим стоп-листом клише, и повторяемый скрипт для следующих правок
export на $env:ИМЯ="значение".pip: проверьте python3 --version. Если команда не найдена — установите Python из пакетного менеджера вашей ОС.curl: проверьте curl --version. Ожидаемый результат — строка вида curl 8.x.x (номер будет вашим).temperature) сверьте с документацией провайдера — они отличаются.~/style-fix).python3 --version отвечает версиейcurl --version отвечает версиейLLM_API_URL, LLM_API_KEY, LLM_MODEL заданы в текущей сессии~/style-fix и в ней лежит input.txtmkdir -p ~/style-fix/examples && cd ~/style-fix
export LLM_API_URL="https://<ваш-провайдер>/v1/chat/completions"
export LLM_API_KEY="<ваш-ключ>"
export LLM_MODEL="<имя-модели-из-документации>"
printenv LLM_API_URL LLM_MODEL
Почему это работает: стиль модели определяется системным промптом (инструкция роли, которую модель держит весь диалог) и примерами, а не вежливостью просьбы. Переменные окружения держат ключ вне кода — вы не попадёте ключом в git.
Что сделать: создайте три файла: style_guide.md (как писать), banned.md (что запрещено, по одному пункту на строку) и input.txt (текст на переписывание). Скопируйте 3–5 своих образцов в examples/.
Зачем: «пиши естественно» — неизмеримая инструкция. Модель выполняет только измеримые: длина предложения, запрещённые слова, порядок абзацев. Стоп-лист потом проверит скрипт, и вы получите объективный результат, а не ощущение.
Пример: style_guide.md
Ты — редактор технических текстов. Правила:
1. Одно утверждение — одно предложение. Средняя длина — до 20 слов.
2. Каждый абзац начинается с факта, команды или числа. Не с обобщения.
3. Не объясняй, что такое очевидное; объясняй только термины.
4. Активный залог: «скрипт печатает», а не «скриптом печатается».
5. Никаких выводов в конце раздела. Закончил мысль — переходи к следующей.
banned.md — по одному клише на строку:
в современном мире
не секрет, что
играет важную роль
давайте разберёмся
в заключение
стоит отметить
Типовые соответствия для стоп-листа:
| Признак ИИ-текста | Что писать в `banned.md` | Чем заменить |
|---|---|---|
| Обобщённое вступление | `в современном мире` | конкретный факт, дата или команда |
| Оценка без данных | `играет важную роль` | что именно делает объект и с каким параметром |
| Затяжка перед темой | `давайте разберёмся` | сразу шаг или команда |
| Финальная вода | `в заключение` | удалить абзац целиком |
Как проверить: wc -l style_guide.md banned.md examples/*.txt — в выводе по каждому файлу число строк. В banned.md их должно быть не меньше 5, в каждом образце — хотя бы 1 (то есть файл не пустой). Числа будут вашими — важен порядок, а не конкретное значение.

Что сделать: создайте rewrite.py, который читает style_guide.md и banned.md, отправляет их в системном сообщении вместе с input.txt и сохраняет ответ в output.txt.
Зачем: правила в системном сообщении весят больше, чем просьба в пользовательском. Запреты в конце пользовательского текста модель часто «съедает» — проверено на длинных промптах.
import os, json, urllib.request
API_URL = os.environ["LLM_API_URL"]
API_KEY = os.environ["LLM_API_KEY"]
MODEL = os.environ["LLM_MODEL"]
system = open("style_guide.md", encoding="utf-8").read()
banned = open("banned.md", encoding="utf-8").read()
src = open("input.txt", encoding="utf-8").read()
samples = ""
for name in sorted(os.listdir("examples")):
samples += "\n--- Пример моего стиля ---\n" + open(f"examples/{name}", encoding="utf-8").read()
payload = {
"model": MODEL,
"messages": [
{"role": "system", "content": system + samples},
{"role": "user", "content":
"Перепиши текст, сохранив все факты и числа. Запрещённые формулировки:\n"
+ banned + "\n\nТЕКСТ:\n" + src},
],
"temperature": 0.4,
}
req = urllib.request.Request(
API_URL,
data=json.dumps(payload).encode("utf-8"),
headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"},
)
with urllib.request.urlopen(req) as r:
data = json.load(r)
open("output.txt", "w", encoding="utf-8").write(data["choices"][0]["message"]["content"])
print("OK -> output.txt")
Пример запуска:
cd ~/style-fix && python3 rewrite.py
Ожидаемый вывод на экране: OK -> output.txt.
Почему это работает: temperature управляет случайностью выбора слов — чем ниже значение, тем предсказуемее формулировки; точный диапазон и допустимые значения сверьте с документацией провайдера, у части моделей параметр не поддерживается. Примеры в системном сообщении задают ритм фразы, а не только список запретов — модель копирует длину предложений и порядок «факт → пояснение». Если строите ассистента с характером и памятью, пригодятся приёмы из гайда «Как настроить эмпатичного ИИ-ассистента: системные промпты, RAG и TTS» — там разобрана та же логика «роль + правила + примеры».
Как проверить: test -s output.txt && echo OK — печатает OK, значит файл создан и не пуст. Затем head -n 3 output.txt — вы видите начало переписанного текста, а не JSON и не пустую строку.

Что сделать: создайте check_style.py — он ищет в output.txt каждую строку из banned.md без учёта регистра и печатает число совпадений.
Зачем: глазами вы пропустите половину клише, особенно на втором абзаце. Скрипт даёт одно число, по которому видно, помог промпт или нет.
import pathlib
banned = [w.strip().lower() for w in
pathlib.Path("banned.md").read_text(encoding="utf-8").splitlines() if w.strip()]
text = pathlib.Path("output.txt").read_text(encoding="utf-8").lower()
hits = [w for w in banned if w in text]
print(f"совпадений: {len(hits)}", hits if hits else "")
Пример запуска:
cd ~/style-fix && python3 check_style.py
Успех выглядит так: совпадений: 0. Если видите совпадений: 2 ['в современном мире', 'стоит отметить'] — вернитесь в Шаг 2 и перенесите эти два пункта в начало style_guide.md, а не в конец banned.md.
Как проверить: сравните число слов: wc -w input.txt output.txt. Переписанный текст обычно короче исходного — если он вырос вдвое, модель добавила пояснений, которых не просили. Затем прочитайте вслух один абзац: спотыкаетесь на конструкции — правьте style_guide.md, а не текст руками.
Финальный чек-лист приёмки:
совпадений: 0input.txt не потеряноЕсли переписанный текст пойдёт в публичный ассистент, прогоните его через методику «Как проверить LLM-приложение на джейлбрейки» — пользовательский ввод может перебить ваши стилевые правила.
Проблема. Стиль не изменился, хотя стоп-лист отправлен
совпадений: 3 ['в современном мире', 'играет важную роль', 'в заключение']style_guide.md больше 10 пунктов и правила конфликтуют.style_guide.md в виде «Никогда не начинай абзац со слов …», сократите список правил до 5, повторите python3 rewrite.py && python3 check_style.py.Проблема. Скрипт падает сразу после запуска
KeyError: 'LLM_API_KEY'.env, который никто не читает. export действует только в текущей сессии.printenv LLM_API_KEY | wc -c — число должно быть больше 1 (сам ключ не печатайте). Если 0, снова выполните export LLM_API_KEY="<ваш-ключ>" или добавьте строку в ~/.bashrc и откройте новый терминал.Проблема. Ответ не разбирается как JSON
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)LLM_API_URL, редиректа или ошибки авторизации на стороне прокси.json.load вывод print(r.status, data[:300]) и запустите снова. Код 200 — проблема в формате ответа, сверьте путь эндпоинта с документацией; код 401 — ключ, 404 — URL.Рабочая схема — три файла (style_guide.md, banned.md, examples/) плюс два скрипта: один переписывает, второй считает совпадения с стоп-листом. Дальше расширяйте banned.md по мере того, как замечаете новые клише, и держите число правил в промпте в пределах пяти.
Как заставить нейросеть писать проще и без воды?
Задать измеримые правила в системном промпте (длина предложения, активный залог) и список запрещённых формулировок, а результат проверять скриптом по стоп-листу, а не на глаз.
Почему нейросеть пишет одинаково при каждом запросе?
Потому что стиль задан только общей формулировкой вроде «пиши естественно». Добавьте 3–5 своих текстов как примеры в системное сообщение — модель начнёт копировать их ритм и длину фраз.
Сколько примеров текста нужно для few-shot?
Начните с трёх: два коротких абзаца и один длинный. Если стиль всё ещё «плывёт», добавьте четвёртый — но следите, чтобы примеры были однородными по жанру, иначе модель смешает стили.
Можно ли убрать канцелярит постобработкой, без повторного запроса?
Частично: замена по словарю из banned.md убирает штампы, но не меняет структуру фраз. Для структуры нужен повторный запрос с исправленным style_guide.md.