Claude Haiku фильтрует 30 RSS-лент, Opus пишет посты, а я только нажимаю кнопку

Откройте любой новостной канал в Telegram. Что там? Война, кризис, очередной скандал, «учёные предупреждают о катастрофе». Закрываешь — и настроение на нуле.

Я подумал: а что если сделать канал, где только хорошие новости? Не мотивационные цитаты, не «позитивное мышление» — а реальные научные открытия, медицинские прорывы, технологии, которые делают жизнь лучше. Факты, от которых хочется сказать «ого, круто».

Проблема в том, что вручную это тяжело. Нужно каждый день мониторить десятки источников, отбирать подходящие новости, переписывать их живым языком, подбирать картинки, публиковать в нужное время. Это 2-3 часа в день — фактически работа SMM-менеджера.

Тогда я задал себе вопрос: а что если это автоматизировать? Не полностью — я хочу контролировать, что уходит в канал. Но чтобы бот делал 90% рутины, а мне оставалось только нажать «Опубликовать» или «Другую».

Так появился @GoodN3wsChannel — и бот, который его обслуживает. Весь код — на Python, AI — на Claude API от Anthropic, хостинг — Railway за $5/мес. Общие расходы на AI — меньше 5$ в месяц.

Дальше расскажу, как это устроено внутри.

Архитектура

Стек: Python 3.11, python-telegram-bot, Anthropic SDK, SQLite, APScheduler, Railway.

Источники: 30 RSS-лент — Nature, Science Daily, NASA, MIT News, DeepMind Blog, Medical Xpress, New Scientist, Quanta Magazine и другие. 6 русскоязычных (N+1, Naked Science, Хабр) + 24 англоязычных.

Почему Claude, а не GPT? Три причины. Во-первых, стоимость — об этом ниже. Во-вторых, качество русского текста у Claude заметно лучше. В-третьих, у Anthropic API есть встроенный web_search tool — пригодился для фичи с еженедельным ресёрчем.

Двухмодельная стратегия: Haiku фильтрует, Opus пишет

Это главный архитектурный инсайт, который сэкономил мне деньги: не все задачи требуют дорогой модели.

В проекте две модели Claude работают в связке:

Claude Haiku 4.5 ($1/M input, $5/M output) — быстрая и дешёвая. Решает простые задачи:

  • Выбрать 1 лучшую статью из 24 кандидатов (вернуть JSON с индексом)

  • Проверить качество поста перед публикацией (ответить «OK» или «REJECT»)

Claude Opus 4.6 ($15/M input, $75/M output) — дорогая, но пишет на порядок лучше. Решает творческие задачи:

  • Написать пост живым языком по строгой структуре

  • Переписать пост другими словами, с другой зацепки

  • Написать глубокий ресёрч с веб-поиском

Вот как выглядит промпт для фильтрации (Haiku):


Из списка ниже выбери ровно 1 статью — самую интересную и позитивную.
Критерии отбора (по приоритету):

Научное открытие, прорыв, рекорд, «впервые в истории»
Польза для здоровья, медицинский прогресс
Космос, новые технологии, AI (позитивный угол)

Верни ТОЛЬКО валидный JSON: {"selected": [4]}

А вот ключевая часть промпта для написания поста (Opus):


СТРУКТУРА КАЖДОГО ПОСТА (строго):
1. Одно тематическое эмодзи (🧬 🚀 💊 🤖 ⚡ 🌱 🔬 🧠)
2. Первое предложение — зацепка: удивительный факт или вопрос
3. Второе предложение — что именно произошло
4. Третье предложение — почему это важно для обычных людей
5. Пустая строка
6. Вопрос к читателям (бинарный — да/нет через реакции)
   ❤️ — да / верю / изменит
   💔 — нет / сомневаюсь

Результат — пост выглядит так:

🧠 А что если тревога — это не слабость, а просто химия?

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

Думаете, таблетка от тревоги без побочек реально появится?
❤️ — верю, скоро будет
💔 — сомневаюсь

Три предложения + вопрос с реакциями. Коротко, по делу, вовлекает.

Грабли, на которые я наступил

Самое интересное — это баги, которые не предусмотришь заранее. Вот четыре, которые реально сломали мне бота.

Баг 1: Бесконечный цикл из двух новостей

Симптом: нажимаю кнопку «Другую» — бот показывает новую новость. Нажимаю ещё раз — возвращается предыдущая. И так по кругу: новость A → новость B → новость A → новость B…

Причина: бот не помнил, какие новости я уже отклонил. Он просто заново собирал кандидатов из тех же RSS-лент — и те же статьи возвращались.

Фикс: добавил таблицу skipped в SQLite. Каждая отклонённая статья сохраняется по URL (SHA256-хеш). При следующем сборе кандидатов — пропускается:


# collector.py
if not url or is_seen(url) or is_skipped(url):
    continue  # Уже публиковали или отклоняли — пропускаем

Данные хранятся 30 дней, потом автоматически чистятся.

Баг 2: Утренний пост без модерации

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

Причина: автопайплайн по расписанию (8:00, 14:00, 20:00) публиковал напрямую в канал, минуя модерацию. Качество проверял Haiku — но это не замена человеческому контролю.

Фикс: переделал пайплайн полностью. Теперь автопост не публикуется — он отправляет мне превью в личку с кнопками «Одобрить» / «Отклонить» и ждёт 30 минут:


# bot.py — ключевой паттерн
event = asyncio.Event()
_pending_auto[session_id] = event
Отправляем превью всем админам
for admin_id in admin_ids:
await bot.send_message(admin_id, preview, reply_markup=keyboard)
Ждём нажатие кнопки или таймаут
try:
await asyncio.wait_for(event.wait(), timeout=30 * 60)
except asyncio.TimeoutError:
# Не ответили — НЕ публикуем
mark_skipped(article["link"], article["title"])

Паттерн с asyncio.Event — элегантное решение без поллинга. Админ нажимает кнопку → callback вызывает event.set() → pipeline продолжает выполнение.

Баг 3: Два поста за один запуск

Симптом: в канал улетело два поста с разницей в 3 секунды.

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

Фикс: два уровня защиты:


# 1. Pipeline lock — не запустится дважды одновременно
PIPELINE_LOCK = asyncio.Lock()
2. max_instances=1 в планировщике
scheduler.add_job(run_pipeline, ..., max_instances=1)

Плюс return после первой успешной публикации — строго 1 пост за запуск.

Баг 4: Битые картинки

Симптом: бот находит og:image у статьи, но Telegram не может её загрузить — и весь пост не отправляется.

Фикс: graceful degradation. Если send_photo падает — ловим исключение и отправляем текстом:


try:
    await bot.send_photo(chat_id, photo=image_url, caption=text)
except Exception:
    # Картинка битая — публикуем без неё
    await bot.send_message(chat_id, text=text)

Плюс добавил возможность вручную прикрепить фото: отправляешь картинку боту во время модерации — он подхватывает её вместо og:image.

Фича: еженедельный ресёрч с веб-поиском

Помимо ежедневных коротких постов, раз в неделю я публикую глубокий разбор одной темы. Формат — «🔎 ГЛУБЖЕ: тема».

Чтобы не тратить на это 2 часа, я добавил команду /research:


/research влияние сна на память

Бот делает следующее:

  1. Claude Opus получает web_search tool и ищет реальные исследования по теме

  2. Находит 3-5 публикаций с реальными URL

  3. Пишет пост со структурой: зацепка → «Что известно» → «Почему это важно» → «Что я думаю» → открытый вопрос

  4. Ссылки на исследования оформляет как кликабельные фразы

Технически это multi-turn conversation с Anthropic API:


web_search_tool = {
    "type": "web_search_20250305",
    "name": "web_search",
    "max_uses": 5,
}
for _ in range(max_turns):
resp = client.messages.create(
model="claude-opus-4-6",
tools=[web_search_tool],
messages=messages,
)
if resp.stop_reason == "end_turn":
    # Финальный текст готов
    return extract_text(resp)

if resp.stop_reason == "tool_use":
    # Claude запросил ещё один поиск — передаём результат
    messages.append({"role": "assistant", "content": resp.content})
    # ... обработка tool_result

Claude сам решает, сколько раз искать и по каким запросам. Результат — пост с реальными ссылками на исследования, которые можно проверить.

Экономика: $20 в месяц на всё

Вот реальная разбивка расходов за месяц при 3 постах в день + 1 ресёрч в неделю:

Компонент

Стоимость

Claude Haiku (фильтрация + проверка)

$0.39

Claude Opus (посты + ресёрч + переписывание)

$14.22

Web Search (~20 запросов)

$0.20

Railway (хостинг)

$5.00

Итого

~$20/мес

93% расходов на AI — это Opus. Если перейти на Sonnet (3/15 за миллион токенов), расход падает до ~$7/мес, но качество текста будет чуть ниже.

Когда это окупится?

Если ввести рекламу (2-4 рекламных поста в месяц):

Подписчики

Цена за рекламный пост

Доход/мес

Прибыль

1 000

$5–15

$10–30

Около нуля

3 000

$20–50

$60–150

+$40–130

5 000

$40–100

$160–400

+$140–380

10 000

$100–250

$400–1000

+$380–980

Точка безубыточности — около 1 500 подписчиков при 2 рекламных постах в месяц. Расходы на инфраструктуру минимальны — основная инвестиция это время на рост аудитории.

Для сравнения: SMM-менеджер на аналогичную работу (3 поста/день, подбор новостей, написание, публикация) стоил бы 30 000–50 000 рублей в месяц. Бот делает то же самое за $20.

Что дальше

Канал работает, бот стабилен. Вот что планирую добавить:

  • Вечерний дайджест — одно сообщение со сводкой за день

  • Аналитика по реакциям — какие темы заходят лучше, подкручивать фильтрацию

  • Тематические дни — понедельник космос, среда медицина, пятница AI

  • Дедупликация по смыслу — одну новость часто публикуют 5 разных СМИ с разными URL

Канал: @GoodN3wsChannel

Если устали от плохих новостей — заходите. Там только наука, прорывы и поводы для оптимизма.

Буду рад вопросам в комментариях — расскажу подробнее про любой аспект.