Как я без опыта программирования создал Telegram‑бота, который уже два года ведёт новостной канал

от автора

Два года назад у меня практически не было опыта программирования. Когда‑то в школе мы немного изучали Pascal, но после этого я не написал ни одного скрипта. Я впервые открыл PyCharm, по ходу работы узнал, что такое API, SSH, виртуальная машина, системная служба и облачные задачи. При этом за несколько месяцев я создал систему, которая собирает новости из турецких источников, переводит и сокращает их, помогает администратору отбирать материалы, готовит полноценные публикации и размещает их в Telegram по расписанию.

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

Летний вечер, с которого всё началось

Это был июль 2024 года. Мне дико хотелось сделать что‑нибудь классное и полезное. В местной Telegram‑группе русскоязычного сообщества города Измир (Турция) я увидел очередной вопрос: откуда люди берут актуальные новости города? Вопрос задавали не впервые, но нормального ответа обычно не находилось. Местные новости существовали в основном на сайтах и в Instagram, да ещё и на турецком языке. Чтобы следить за происходящим, в идеале нужно было знать турецкий язык. Нужно было самостоятельно искать источники, переводить тексты и разбираться, насколько им вообще можно доверять.

В тот вечер я уже лежал в постели, но мысль о том, что можно создать собственный новостной канал, не давала мне покоя. Я вскочил, сел за ноутбук и с нетерпением задал ChatGPT несколько вопросов: можно ли самостоятельно сделать систему, которая будет собирать публикации из турецких источников, переводить их и отправлять в Telegram? Что для этого понадобится? Реально ли всё это создать человеку без опыта программирования? ChatGPT ответил, что технически это возможно, и примерно описал необходимые инструменты. Этого оказалось достаточно. Я с удовлетворением лёг спать, зная, что завтра начну.

Какую проблему я хотел решить

Русскоязычным жителям Измира не хватало удобного источника местных новостей. Актуальная информация появлялась в Instagram и на турецких сайтах, но почти всегда на турецком языке и вне Telegram. Нужно было самостоятельно просматривать разные страницы, переводить тексты и отделять важные новости от десятков проходных публикаций. Была и другая проблема. Существовали русскоязычные Telegram‑каналы о Турции в целом, которые публиковали новости без ссылок на первоисточники. Ты читаешь готовый текст, но не понимаешь, какая его часть взята из реальной публикации, а какая была добавлена или переосмыслена автором канала. Мне хотелось сделать по‑другому:

  • собирать новости из нескольких местных источников;

  • переводить их на русский язык;

  • кратко и понятно передавать суть;

  • сохранять ссылку на оригинальную публикацию;

  • давать читателю возможность самостоятельно проверить источник;

  • по возможности показывать реакцию местных жителей.

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

Это Илон Маск поджигает наши леса лазерами со своих спутников.

Изначально переведённые комментарии публиковались в отдельной Telegram‑группе, но это оказалось неудобно. Новому читателю было сложно попасть в группу и найти обсуждение конкретной публикации. Позже бот начал создавать для комментариев отдельные страницы Telegraph и добавлять ссылки на них к новостям.

Моя исходная точка

До этого проекта у меня не было практического опыта программирования. Последний раз я сталкивался с кодом в школе, когда мы немного изучали Pascal. Я не писал небольших скриптов, не создавал ботов, не работал с API и не поднимал серверы. Я впервые увидел интерфейс PyCharm уже во время разработки. Впервые открыл терминал. Впервые подключался к серверу через SSH. Впервые получал API‑ключи и пытался понять, куда их вставлять. В некоторых ситуациях я буквально делал скриншот незнакомого интерфейса, отправлял его в ChatGPT и спрашивал:

Что мне теперь нажать и какой должен быть следующий шаг?

Но сам масштаб задачи меня почему‑то не пугал. В голове был достаточно ясный образ результата, а путь до него воспринимался как интересный вызов. Возможно, это и было моим главным преимуществом. Я не знал названий инструментов и не понимал архитектуру, но представлял, что должна делать система с точки зрения пользователя.

Первый прототип за две недели

Работа над ботом началась во второй половине июля 2024 года. К 5 августа появился первый рабочий прототип. Он уже мог получать публикации из Instagram через Apify, переводить их с турецкого языка и показывать администратору в Telegram. Первое время ChatGPT писал мне код практически целиком.

На раннем этапе я просил ChatGPT присылать обновлённый код целыми файлами.

На раннем этапе я просил ChatGPT присылать обновлённый код целыми файлами.

Я копировал его в PyCharm, нажимал зелёную кнопку запуска и смотрел, что произойдёт. Если появлялась ошибка, я копировал её обратно в ChatGPT и спрашивал, как исправить. Проверял бота в отдельном тестовом Telegram‑канале. Я не помню точную первую функцию, которая заработала. В памяти осталась скорее картинка: открыт PyCharm, я нажимаю зелёную кнопку запуска, а в тестовом Telegram‑канале появляются сообщения от бота. О чудо! Невероятно! Каждая такая маленькая победа давала энергию для следующей.

Через две недели у меня был не идеальный продукт, а работающий MVP. Он ещё не обладал всей современной функциональностью, но уже подтверждал главное: схема действительно может работать. К концу октября 2024 года сформировалась стабильная версия, по основному устройству уже похожая на нынешнюю систему. Бот автоматически собирал материалы, показывал их администратору, позволял выбирать интересные новости, готовил тексты и публиковал их в Telegram.

Как выглядел первый MVP

Первоначальная схема была довольно простой. Для получения публикаций из Instagram я использовал готовый Instagram Scraper на платформе Apify. При моём объёме бесплатных квот хватает до сих пор. Вместе с публикацией система получала:

  • исходный текст;

  • изображение или видеоролик;

  • дату;

  • ссылку на оригинал;

  • комментарии пользователей.

Затем текст передавался языковой модели, переводился на русский язык и показывался администратору. Для обработки новостей внутри самого бота я сначала использовал Google Gemini. Главная причина была простой: там были бесплатные квоты, которых хватало для проверки идеи. Причём у Gemini Flash доступные лимиты были больше, поэтому она хорошо подходила для массовой предварительной обработки. На этапе MVP мне не требовалась идеальная архитектура. Нужно было понять, способен ли такой процесс вообще работать. Оказалось, что способен.

источник → сбор данных → перевод → Telegram → решение администратора → публикация.

Как ограничения Gemini привели к двухступенчатой обработке

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

На первом этапе использовалась Gemini Flash. У неё было больше бесплатных квот, а качества вполне хватало, чтобы быстро сократить и примерно перевести весь поступивший поток.

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

Только после отбора выбранные материалы передавались Gemini Pro. Она выполняла более качественный перевод, сокращение и рерайт текста для публикации. Получалось примерно так:

  1. быстрая и экономная обработка всего потока;

  2. ручной редакционный отбор;

  3. качественная обработка только нужных материалов.

Двухступенчатая обработка: быстрая модель работает со всем потоком, а более качественная — только с материалами, выбранными администратором.

Двухступенчатая обработка: быстрая модель работает со всем потоком, а более качественная — только с материалами, выбранными администратором.

Изначально это решение появилось из‑за ограничений бесплатного API, но в итоге оказалось архитектурно правильным. Даже после перехода на платные модели нет смысла тратить более дорогую обработку на материалы, которые администратор всё равно отклонит.

Примерно в апреле 2025 года обе ступени были переведены на OpenAI API. Сейчас более лёгкая модель занимается предварительной обработкой и комментариями, а более качественная — финальным переводом, сокращением и созданием заголовков. Переход произошёл по нескольким причинам:

  • бесплатные квоты Gemini начали мешать стабильной работе;

  • подходящую платную конфигурацию Gemini мне нормально настроить не удалось;

  • качество русского перевода не полностью устраивало даже на Pro‑модели;

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

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

Instagram заблокировали — пришлось писать собственный парсер

Через несколько дней после запуска первого варианта системы Instagram заблокировали в Турции. Блокировка продлилась недолго, но хорошо показала слабое место проекта: весь сбор новостей зависел от одной платформы. Поэтому я решил сделать собственный парсер турецкого новостного сайта.

На Apify есть готовые парсеры сайтов, но многие из них платные, и их всё равно пришлось бы настраивать под конкретный сайт. У меня уже был собственный сервер, поэтому возник закономерный вопрос: зачем оплачивать ещё один сервис, если можно разобраться и написать нужный инструмент самостоятельно?

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

Раньше я немного видел инструменты разработчика в браузере, но большая часть происходящего всё равно оставалась тёмным лесом. Я открывал код страницы в инструментах разработчика, копировал отдельные HTML‑блоки и отправлял их ChatGPT. Затем указывал на конкретный текст внутри и спрашивал, какая часть структуры отвечает за нужное содержимое, а какие элементы нужно исключить.

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

Мне нужен инструмент, который найдёт последнюю опубликованную новость, получит её заголовок, текст и изображение, но не захватит рекламные блоки и соседние материалы.

Постепенно из таких запросов появился работающий парсер на Python, Selenium, Chrome и Beautiful Soup. После разблокировки Instagram система стала собирать новости одновременно с сайта и из Instagram‑источников. Сегодня к боту подключены четыре Instagram‑источника через Apify и один новостной сайт.

Когда ChatGPT перестал справляться с кодом целиком

Первые версии проекта были небольшими, поэтому ChatGPT мог написать или переписать код целиком. Но когда файл вырос примерно до 300 строк, начались проблемы. Модель стала терять контекст, удалять уже реализованные функции, путаться в названиях и создавать ошибки в местах, которые до этого работали нормально. Иногда она видела в коде то, чего там вообще не было. Чем длиннее становился наш диалог, тем хуже становились ответы. Поэтому мне приходилось регулярно начинать новые чаты. Постепенно появились отдельные диалоги для разных задач.

Отдельные диалоги с ChatGPT для разных задач.

Отдельные диалоги с ChatGPT для разных задач.

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

Действительно, я допустил ошибку и отрезал не ту руку. Больше такого не повторится, сейчас всё переделаю.

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

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

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

Как я начал понимать код

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

Я не стал профессиональным Python‑разработчиком за четыре месяца. Но код перестал выглядеть как магический текст, который можно только скопировать и запустить. Постепенно я начал сам предлагать направление решения. Я просил ChatGPT описать несколько вариантов архитектуры, сравнивал их и выбирал тот, который казался мне наиболее подходящим. Иногда понимал, что предлагаемое решение не может работать в текущей системе, даже если модель уверенно утверждала обратное.

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

Как проект превратился в небольшую распределённую систему

Изначально основной Telegram‑бот и все парсеры работали на одной виртуальной машине. Пока объём был небольшим, система справлялась. Но примерно через полгода сервер начал тормозить и зависать. Иногда переставал отвечать уже не отдельный парсер, а весь бот. Исследование показало, что серверу не хватает оперативной памяти. Основную нагрузку создавал веб‑парсер, а точнее Selenium, Chromedriver и процессы Chrome. Во время сбора новостей на одной машине одновременно работали:

  • постоянный Python‑процесс Telegram‑бота;

  • Python‑процесс парсера;

  • браузер и его служебные процессы;

  • обработка изображений и видео;

  • другие системные задачи.

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

Поэтому веб‑парсер вместе с Selenium и Chrome был вынесен в Google Cloud Run. Теперь браузер запускается во временном контейнере, собирает новые статьи, сохраняет результат и уничтожается вместе с контейнером. Даже если парсер потребляет много памяти, он больше не может забрать ресурсы у постоянно работающего Telegram‑бота. Сбор Instagram выполняется инфраструктурой Apify. На основном сервере остаётся только лёгкая часть, которая получает готовые результаты через API. Так проект, начинавшийся как один Python‑скрипт, постепенно превратился в небольшую распределённую систему.

Как устроена текущая архитектура

Основной Telegram‑бот постоянно работает на виртуальной машине Google Cloud. Он запускается как системная служба. Если процесс завершается, система автоматически поднимает его заново.

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

Instagram‑часть несколько раз в день обращается к настроенным задачам Apify, получает последние публикации и добавляет их в общий набор новостей.

Веб‑парсер запускается отдельно по расписанию через Cloud Scheduler и Cloud Run. При каждом запуске создаётся временный контейнер с Python, Selenium и браузером. Он получает существующий список материалов, находит новые статьи, извлекает данные и синхронизирует результат с основным сервером. Упрощённо схема выглядит так:

Текущая архитектура: Instagram-источники обрабатываются через Apify, а ресурсоёмкий веб-парсер запускается в Cloud Run. Оба потока сходятся в дневном хранилище, откуда новости получает Telegram-бот.

Текущая архитектура: Instagram‑источники обрабатываются через Apify, а ресурсоёмкий веб‑парсер запускается в Cloud Run. Оба потока сходятся в дневном хранилище, откуда новости получает Telegram‑бот.

Парсеры не отправляют команды основному боту напрямую. Главным механизмом обмена остаются ежедневные JSON‑файлы. Это не самая современная и масштабируемая архитектура, но на текущем объёме она работает стабильно и остаётся достаточно простой для поддержки одним человеком.

Что именно делает бот

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

Первичный отбор: администратор просматривает короткие переводы и отправляет интересные новости на финальную обработку.

Первичный отбор: администратор просматривает короткие переводы и отправляет интересные новости на финальную обработку.

Дальше процесс выглядит так:

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

Редакционный интерфейс внутри Telegram

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

Под каждой краткой новостью находится кнопка подготовки. Нажатие добавляет материал в очередь. После отправки первого сообщения на подготовку появляется отдельное сообщение с кнопкой, которая запускает финальную обработку только выбранных новостей. Готовые посты приходят уже с изображением или видео. Если текст не устраивает, его можно изменить через кнопку редактирования. Медиа пока что заменить нельзя.

Слева: Навигация внутри Telegram. Справа: Готовый предпросмотр после финальной обработки - текст можно изменить или сразу добавить публикацию в очередь.

Слева: Навигация внутри Telegram. Справа: Готовый предпросмотр после финальной обработки — текст можно изменить или сразу добавить публикацию в очередь.

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

Как хранятся данные

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

Кроме JSON используются небольшие SQLite‑базы. Одна хранит запланированные задачи и позволяет восстановить публикации после перезапуска. Другая содержит служебное состояние: идентификаторы сообщений, сохранённые Telegram “file_id”, статусы предпросмотров и данные, необходимые для продолжения работы. Некоторые промежуточные очереди пока находятся только в оперативной памяти. Это один из примеров технического долга, который не мешает текущей эксплуатации, но потребует внимания при дальнейшем масштабировании системы.

Работа с изображениями и видео

В JSON хранятся ссылки на медиа, а не сами файлы. Перед отправкой бот временно скачивает изображение или видео, передаёт его в Telegram и удаляет локальную копию. После первой отправки Telegram возвращает «file_id». Бот сохраняет его и при окончательной публикации может использовать уже загруженную копию, не скачивая медиа повторно. Это особенно полезно для Instagram, где прямые ссылки на изображения и видео могут быть временными.

Если у новости несколько изображений, сейчас используется только первое. Поддержки Telegram‑альбомов в рабочей версии пока нет. Если медиа скачать или отправить не удалось, бот сообщает об этом администратору и позволяет опубликовать только текст.

Промпты как результат реальной эксплуатации

В системе нет одного универсального промпта. Обработка разделена на несколько этапов. Сначала длинный турецкий текст при необходимости сокращается. Затем создаётся предварительный перевод примерно на 200 символов. Он нужен только для первичного отбора. Для выбранной новости используется отдельный промпт финальной обработки. Модель должна:

  • перевести текст на русский язык;

  • сохранить основные факты;

  • не добавлять новую информацию;

  • использовать информационный стиль;

  • разбить текст на короткие абзацы;

  • уложиться в заданный объём;

  • правильно передавать названия районов Измира.

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

Что происходит при ошибках

Каждая внешняя система может временно не ответить: Apify, новостной сайт, OpenAI API, Telegram, Telegraph, сервер. Поэтому на разных этапах предусмотрены повторные попытки. Если отдельный источник не ответил, система старается продолжить работу с остальными. Если не удалось отправить изображение или видео, можно опубликовать текстовую версию. Если основной процесс падает, он автоматически перезапускается, а сохранённые задания восстанавливаются.

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

Как определяется новизна материалов

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

Если источник изменит текст уже опубликованной новости, система, скорее всего, этого не заметит. Если одна и та же история появится одновременно на сайте и в Instagram, она может попасть в подборку дважды. Семантической дедупликации в рабочей версии пока нет. Если сайт изменит HTML‑вёрстку, парсер тоже не адаптируется автоматически. Он зависит от структуры страницы и используемых элементов.

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

Результат за два года

Бот работает около двух лет. При среднем потоке около ста новостей в день система могла обработать за это время порядка 70 тысяч материалов. Это приблизительная оценка, а не точная статистика: в разные дни объём менялся. Обычно публикуется около двадцати новостей в день. К каналу подключены пять источников:

  • четыре Instagram‑аккаунта через Apify;

  • один турецкий новостной сайт.

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

Без бота администратору пришлось бы вручную открыть несколько турецких источников, просмотреть последние материалы и хотя бы примерно перевести каждый из них. После отбора нужно было бы скопировать исходный текст, отдельно скачать изображение или видео, обработать новость в ChatGPT и написать заголовок. Затем оставалось собрать публикацию, добавить ссылку на источник и настроить отложенный постинг. С ботом основной цикл отбора и запуска подготовки занимает у меня около пяти минут.

Функции, от которых пришлось отказаться

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

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

Попытка научить систему предсказывать мой выбор

За время работы накопилась история решений:

  • какие новости я выбирал для публикации;

  • какие не доходили до канала.

Возникла идея использовать эти данные, чтобы система могла заранее оценивать интересность новых материалов и избавить администратора от просмотра всего потока заголовков. В марте‑апреле 2025 года я начал экспериментировать с Qdrant, эмбеддингами и LLM‑предсказаниями.

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

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

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

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

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

  • автоматически отсеивать заведомо неинтересные материалы;

  • показывать администратору сначала самые релевантные новости;

  • заметно сокращать время первичного просмотра;

  • учитывать изменение интересов канала;

  • при необходимости брать на себя практически весь ежедневный процесс.

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

В какой момент я увидел масштаб проделанной работы

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

Сколько разных задач пришлось выполнять.

Сколько разных задач пришлось выполнять.

Именно тогда у меня появилась формулировка, которая лучше всего описывает этот опыт:

Я начинал человеком, который не написал ни одного скрипта, а затем один прошёл путь небольшой продуктовой команды.

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

Что я понял о вайбкодинге

Начать можно без опыта, но не без головы на плечах

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

Уверенный ответ не означает правильный

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

Иногда нужно менять не ответ, а вопрос

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

  • начать новый чат;

  • сократить контекст;

  • изолировать проблему;

  • передать только одну функцию;

  • попросить объяснить причину;

  • запросить несколько вариантов архитектуры;

  • самому предложить гипотезу.

Маленький работающий результат важнее идеальной архитектуры

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

  • ограничения бесплатных моделей привели к двухступенчатой обработке;

  • блокировка Instagram — к собственному веб‑парсеру;

  • нехватка памяти — к переносу тяжёлого парсинга в Cloud Run;

  • накопленная история решений — к эксперименту с рекомендациями.

Вайбкодинг не отменяет ответственность

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

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

Качество работы зависит от собственной вовлечённости

У меня появился ещё один, менее технический вывод. Я заметил, что работа с нейросетью требует примерно такой же вовлечённости, как работа с реальным человеком. Иногда я садился вайбкодить в плохом состоянии: был уставшим, раздражённым или занятым другими мыслями. Казалось бы, это машина — достаточно сформулировать команду, и она должна её выполнить. Нифига. В такие дни работа могла целый день идти коту под хвост. Модель ошибалась, уводила в неправильную сторону, а я только сливал энергию. На следующий день со свежей головой я погружался в задачу — и правильное решение находилось почти сразу.

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

Насколько проще стало сегодня

Сейчас я занимаюсь Lua‑скриптингом и создаю шаблоны и плагины для DaVinci Resolve. Для этой работы я использую Codex с заранее подготовленным проектом, контекстом, документацией и примерами. Разница с моим опытом двухлетней давности огромна. Тогда я вручную копировал куски кода между чатами и пытался не дать ChatGPT забыть, что уже было реализовано. Часто приходилось исправлять ошибки синтаксиса.

Сегодня инструмент может работать с проектом, в котором больше тысячи строк кода, анализировать связанные файлы, изучать примеры, писать и запускать тесты, а также находить недостающую информацию. Одна итерация иногда длится около 45 минут. Но в большинстве случаев я ожидаю, что получившееся решение будет работать примерно так, как я описал, а иногда даже лучше. Это не означает, что теперь можно совсем не думать. Качественный результат по‑прежнему зависит от:

  • подготовленного контекста;

  • ясного описания цели;

  • понимания ограничений;

  • хороших примеров;

  • проверки результата.

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

Это не только бот для новостей Измира

Текущая система работает с турецкими новостями и русскоязычным каналом Измира. Но её основная архитектура не привязана ни к Измиру, ни к турецкому языку. В общем виде она делает следующее:

  1. собирает информацию из выбранных источников;

  2. приводит её к единому формату;

  3. сокращает или переводит;

  4. показывает администратору;

  5. получает редакционное решение;

  6. обрабатывает выбранные материалы по заданным правилам;

  7. добавляет медиа;

  8. публикует по расписанию.

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

Другой пример — экспертный канал. Новые исследования и статьи появляются постоянно, но у специалиста нет времени ежедневно просматривать десятки источников. Система может собирать материалы и помогать превращать их в контент, пока эксперт занимается основной работой. Ещё один очевидный сценарий — локальный информационный канал в другом городе или другой стране. Общая архитектура остаётся прежней, меняются только источники, язык и правила обработки. Telegram‑бот здесь — только интерфейс. С технической точки зрения это конвейер, который превращает постоянный информационный поток в управляемый процесс подготовки контента.

Что бы я сказал себе два года назад

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

Слушай, оно тебе надо?

Через пару лет нейросети станут гораздо сильнее. Контекст станет больше. Инструменты научатся работать с целыми проектами, запускать тесты и самостоятельно искать ошибки. Ты вообще представляешь, сколько времени сейчас на это потратишь? А затем добавил бы:

Но, пройдя всё это, ты ни капли не пожалеешь. Ты станешь сильнее уважать себя и поймёшь, что способен разбираться в задачах, которые раньше казались совершенно чужими.

Человеку, который думает начать сейчас, я бы сказал проще:

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

Два года назад я впервые открыл PyCharm и нажимал зелёную кнопку запуска, почти не понимая, что происходит внутри написанного ChatGPT кода. Сегодня этот код ежедневно собирает десятки новостей, помогает мне вести канал и экономит часы ручной работы.

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

ссылка на оригинал статьи https://habr.com/ru/articles/1064476/