Несколько месяцев назад я начала пробный проект для одной редакции. Хотелось решить довольно бытовую проблему: журналисты тратили слишком много времени не на журналистику, а на обслуживание новостного потока.

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

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

Так появилась новостная панель. Сначала это был небольшой внутренний эксперимент. Сейчас ей пользуется 10 человек, а сама система собирает материалы, помогает готовить новости, ведет их статусы, отслеживает повторы и взаимодействует с CMS. Для одного из сценариев часть новостей уже может проходить путь до сайта автоматически.

Так выглядит вход в редакционную панель сейчас. Первая версия была значительно проще.
Так выглядит вход в редакционную панель сейчас. Первая версия была значительно проще.

По дороге выяснилось, что заставить нейросеть написать четыре абзаца — далеко не самая сложная часть задачи.

Все начиналось с одной ленты

Первая версия должна была просто собрать источники в одном окне. Вместо того чтобы постоянно переключаться между сайтами и другими площадками, редактор открывал панель и видел свежие материалы. Стек я выбрала простой: Python‑сборщики, Flask, SQLite и небольшой VPS на Ubuntu. Сборщики запускались по расписанию через cron, а flock защищал их от случайного параллельного запуска.

В упрощенном виде схема выглядела так:

источники → Python‑сборщики → SQLite → Flask → редактор

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

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

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

Для меня это был первый важный вывод: автоматизация редакции — это не столько генерация текста, сколько управление путем материала. Нейросеть может написать заметку за несколько секунд, но она сама по себе не ответит на гораздо более прозаичный вопрос: «Эту новость уже кто‑нибудь взял?»

Автоматизация редакции — это не столько генерация текста, сколько управление путем материала.

Как я за день потратила $12 на API

AI появился в проекте довольно рано. Первые версии работали с GigaChat, позже я перешла на OpenAI. Со временем менялись и модели внутри панели.

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

Я это поняла довольно наглядно. В один из дней открыла статистику OpenAI и увидела расход около $12.

Стали разбираться. Оказалось, что на массовом потоке работала дорогая модель, а сама обработка новости могла требовать нескольких обращений к API: отдельно система работала с текстом, отдельно — с заголовком и лидом. То, что на одном материале стоит почти незаметных денег, на сотнях запросов быстро превращается в заметную сумму.

После этого я стала выбирать модель не только по качеству текста. Основной поток в итоге перешел на gpt-5.4-mini. По данным внутреннего учета за одну из последующих недель панель сделала 982 завершенных обращения к OpenAI API примерно на $4.

Если более легкая модель нормально справляется с массовой обработкой новостей, нет смысла платить за возможности, которые в этой задаче не используются. Для сложного материала требования могут быть другими. Для обычной новостной обработки — другими. AI постепенно перестал быть для меня одной большой кнопкой и превратился в обычный компонент системы, который нужно подбирать под задачу.

Скриншот с аккаунта оpenai.com
Скриншот с аккаунта оpenai.com

Дубли оказались сложнее, чем я ожидала

С техническими повторами все просто. У материала есть source_id или source_url. Если такая запись уже есть в базе, второй раз добавлять ее не нужно. Эта защита появилась рано и хорошо работала, пока речь шла об одном и том же материале из одного источника. Но в новостях часто бывает иначе: одно событие почти одновременно описывают несколько площадок. У материалов будут разные ссылки, разные заголовки и разный текст, хотя редактор видит в них один инфоповод.

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

И тут обнаружилась обратная проблема. Слишком агрессивная дедупликация тоже мешает.

Например, два заголовка могут содержать одинаковый процент, но относиться к разным компаниям или разным показателям. Формально они похожи, редакционно — это разные новости. На тестах были случаи, когда шаблонные заголовки ошибочно сближали материалы о разных объектах. То есть задача постепенно изменилась. В начале нужно было просто не загружать одну и ту же ссылку дважды. Потом пришлось учить систему различать технический повтор и редакционный дубль.

Полностью передавать такое решение алгоритму я бы до сих пор не стала.

Когда панелью начали пользоваться другие люди

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

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

В какой‑то момент пришлось объединить несколько параллельных сценариев работы в один: материал проходит проверку, из него создается новость, а дальше ее можно отправить в нужное направление. Служебная карточка при этом не исчезает — она остается частью истории материала.

Для пользователя это выглядит как несколько кнопок и статусов. Внутри оказывается важным другое: система должна точно знать, на каком этапе находится конкретная новость и что с ней уже происходило.

Если она ошибается в этом, красивый интерфейс не спасает.

Потом панель стала тормозить

Еще одна проблема проявилась только после того, как накопились данные. Редактор открывал карточку материала, а она загружалась все дольше. В одном холодном замере SQL‑запрос дошел до 23,88 секунды.

К этому моменту в таблице проверок накопилось 299 221 запись. Мы ввели ограничение по сроку хранения ненужной истории: после очистки удалили 59 826 строк, осталось 239 395. Но одной уборкой проблему было не решить. Запрос искал связанную запись по большой таблице без подходящего индекса.

После добавления составного индекса по news_id, event_date и id ситуация изменилась радикально. В повторных замерах сам SQL выполнялся за 0,005–0,038 мс, а HTTP‑запрос — примерно за 5 мс.

После исправления карточка снова стала открываться сразу. Для меня здесь был довольно практичный критерий: если внутренний инструмент заставляет человека ждать по 20 секунд, редактор просто вернется к привычным вкладкам и чатам. Внутренняя система конкурирует не с другими корпоративными системами. Она конкурирует с привычкой открыть браузер, таблицу или мессенджер и сделать все по‑старому.

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

HTTP 200 еще не означает, что новость создана

Один из самых показательных случаев произошел при подключении внешней CMS. Панель отправила готовую новость и получила от сервера HTTP 200. На первый взгляд запрос выполнился успешно. Только самой новости в CMS не появилось. Оказалось, что сервер вернул ту же форму создания материала. Новый ID не появился, потому что заголовок не прошел внутреннее ограничение CMS: он был длиннее 90 символов.

Для HTTP все выглядело нормально. Для редакции результат был нулевым.

После этого пришлось изменить сам принцип проверки. Недостаточно получить успешный код ответа — система должна убедиться, что объект действительно создан. Нужен новый идентификатор или другой однозначный признак успешной публикации, а результат операции должен попасть в журнал.

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

Как я все‑таки разрешила системе публиковать автоматически

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

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

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

Этот этап немного изменил мой первоначальный взгляд на автоматизацию.

Автопубликацию я включила не для всех материалов. У нее есть очередь, лимит, проверка дублей и несколько условий, при которых публикация вообще не запускается. Например, материал пропускается, если система не нашла подходящую фотографию. Мне оказалось комфортнее автоматизировать именно такие проверяемые случаи, а спорные оставлять редактору.

Там, где решение можно описать однозначным правилом, его имеет смысл автоматизировать. Там, где нужно оценить достоверность, контекст, последствия или редакционную ценность, человек пока остается надежнее.

Саму панель я тоже делала с помощью AI

По профессии я редактор. Когда начинался проект, я не садилась писать Flask‑приложение с пустого файла как опытный Python‑разработчик.

Моя часть работы была другой: я знала, как на самом деле проходит новость через редакцию, где люди теряют время и какие действия нельзя выполнять вслепую. Эти требования я описывала AI обычным языком, а затем вместе с ним переводила их в код, команды для сервера, изменения базы и интерфейса.

Задача могла звучать, например, так: после создания новости карточка исходного материала должна остаться, но отправить ту же новость второй раз система не должна. Или: если журналист уже взял материал, коллега должен это увидеть.

Дальше начиналась техническая часть. Я запускала команды, смотрела результат, проверяла систему на реальных материалах и возвращалась с ошибками. Иногда изменение работало сразу. Иногда ломало соседний сценарий и приходилось разбираться дальше.

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

Самая сложная часть — точно определить поведение продукта.

AI может довольно быстро реализовать плохую логику, если ему хорошо объяснить плохую логику. Он не знает редакционный процесс только потому, что умеет писать на Python. Поэтому чем дальше развивалась панель, тем меньше мои задачи были похожи на «напиши мне функцию» и тем чаще начинались с вопроса: «А что должно произойти в этой ситуации с точки зрения редактора?»

Самые полезные функции выглядят скучно

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

Я не проводила исследование и не измеряла экономию времени секундомером, поэтому не хочу придумывать процент роста производительности. Эффект вижу по работе редакции: меньше времени уходит на механическую обработку потока, больше остается на интервью, эксклюзивные материалы, общение со спикерами и работу на мероприятиях.

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

Что я теперь сделала бы иначе

Если бы начинала заново, первым делом нарисовала бы путь одной новости целиком: от появления в источнике до записи в CMS. В первой версии я больше думала о функциях панели, а проблемы возникали как раз на стыках между ними. Еще раньше добавила бы учет расходов API и посмотрела бы на запросы к базе: пока данных мало, обе проблемы почти незаметны

Еще один вывод — автоматизацию лучше добавлять постепенно. Сначала система собирала материалы, потом помогала писать, затем появились статусы, дедупликация, работа с CMS и только потом — автоматическая публикация в одном из сценариев. Каждый следующий шаг появлялся не потому, что его можно технически реализовать, а потому, что предыдущей версии уже не хватало в реальной работе.

Что в итоге оказалось важнее AI

Когда я начинала этот проект, мне казалось, что главное — научить систему хорошо работать с текстом. Через несколько месяцев оказалось, что генерация текста — одна из самых простых частей.

Намного больше времени заняли состояния материалов, защита от повторных действий, контроль результата во внешней CMS, дубли, скорость базы и правила, определяющие, когда автоматизация вообще имеет право действовать самостоятельно.

Если бы я начинала такой проект снова, я сначала нарисовала бы полный путь материала от источника до публикации и только потом выбирала модели и писала код. AI сильно снижает порог входа в разработку подобных внутренних инструментов. Но он не решает главную задачу: понять, как на самом деле должен работать процесс, который ты собираешься автоматизировать.

Комментарии (1)


  1. Void-Cowboy
    30.09.2026 12:49

    вообщем создали генератор нейрослопа на основании других нейрослоповых статей))

    я вот пол года как перешел на новости в chatGPT - у него можно прямо в веб-интерфейсе "запланировать" периодичные действия, вот у меня раз в сутки он собирает валидные данные за последние 24 часа
    тоже относительно намучался с подбором промта что бы давало нормально без воды и само искало актуальное, сравнивало и откидывало непроверенное и тд при этом не игнорируя официальные источники

    как по мне новостные хабы устарели уже, имея выбор люди не будут читать раздутые новости с рекламными вставками когда можно этого не делать
    я скорее поверю что в моду вернутся RSS-ленты или и вовсе "открытый MCP" от новосных агентств что бы пользователи подключали своих агентов для агрегации новостей