Пушкин — AI-newsroom для канала
Третий самостоятельный продукт экосистемы Lyumi (наряду с Люми HSE и Wiki). Своя идентичность, свой голос, свой production pipeline.
27 апреля — собран полный AI-newsroom: research → writer → fact-check → visual → publish. 28 апреля — workflow стабилизировался. Камал = главред + фактчекер (~20 минут ручной правки на пост). Всё остальное — роботы. ~$16/мес на 7 постов в неделю.
Принципы AI-newsroom
Главный урок 27 апреля — правильная постановка задачи:
Не «три модели пишут одно и то же». А «три модели с разными ролями + два слоя верификации + визуальный слой = редакция, где главред принимает решение».
Это разница между «использую ИИ» и «строю систему с ИИ внутри».
Четыре принципа которые работают:
- Ни один компонент не принимает решение в вакууме.
- Sonar basic + Sonar Reasoning Pro + KB enrichment из ChromaDB (28 апреля)
- Haiku reflection + Gemini reflection → cross-validate
-
3 writer-а на важных постах → редактор выбирает
-
Честное «не знаю» > красивый вымысел. Топик-якорь в generate_post: «если данных нет — скажи честно». Reflection ловит фантомы URL и статей ТК РК (28 апреля вынесены в отдельные правила).
-
Бренд = определённый голос + постоянный визуал. Голос Люми зафиксирован в DIGEST_SYSTEM_PROMPT. Визуал 1080×1080 (обложка + cheat-sheet) — во всех постах (28 апреля распространено на /case и все автодрафты по расписанию).
-
Человек на финальном decision. Бот никогда не публикует без кнопки Камала. На 28 апреля — ручная правка ~20 мин/пост и это норма.
Три монстрика экосистемы
Hetzner CPX52 (12vCPU/24GB/160GB)
├─ 🤖 Люми — lyumi-hse-bot — экспертный чат-бот (1-на-1)
├─ 📰 Пушкин — lyumi-pushkin-bot — AI-newsroom для канала (этот)
└─ 📚 Wiki MCP — — память экосистемы
28 апреля: Люми и Пушкин связаны через docker-net `lyumi-net`
+ HTTP API (kb_api.py) — общая база знаний, лёгкий Пушкин.
См. [[lyumi/kb_api_bridge]].
| Продукт | Аудитория | Цель (KPI) | Архитектура |
|---|---|---|---|
| Люми | 1-на-1 чат | Глубина и точность | 167,970 чанков ChromaDB, deep retrieval, photo, slash-команды |
| Пушкин | Канал @LyumiHSEDigest | Охват + лиды | Multi-author ensemble, dual fact-check, visual layer, KB enrichment по HTTP |
| Wiki MCP | Обе модели + Камал | Семантическая память | (в режиме архива, развитие в Q3) |
Архитектура pipeline (28 апреля 2026)
╭─ Стадия 1: Research ───────────────────────╮
│ Haiku → 7 sub-queries с on-topic фильтром │
│ ↓ параллельно ↓ │
│ • 7× Sonar (basic) — широта │
│ • 1× Sonar Reasoning Pro — глубина с CoT │
│ • KB enrichment via HTTP — канон из ChromaDB Люми │
│ → merged raw_content (10-30K символов) │
╰────────────────────────────────────────────╯
╭─ Стадия 2: Writer ────────────────────────╮
│ Opus 4.7 + extended thinking(8000) + topic-якорь │
│ + Hook-правило: 4 паттерна без драмы │
│ + URL-правило: не подменяй название документа │
│ → post (HTML <b>, <i>, <a>) │
╰────────────────────────────────────────────╯
╭─ Стадия 3: Fact-check (параллельно) ─────────────╮
│ • Haiku reflection (12K контекст, ~$0.005) │
│ • Gemini 2.5 Pro reflection (60K контекст, ~$0.02) │
│ → устойчивый JSON-парсер (4 стратегии) │
│ → агрегация, при confidence ≥0.75 правки │
│ → шапка: «🛡⚙ −2 HG» / «🛡✓ HG» / «🛡⚠ ?2 H» │
╰────────────────────────────────────────────╯
╭─ Стадия 4: Polish ─────────────────────────╮
│ • _safe_telegram_html (фантомные теги в entities) │
│ • convert_markdown_to_html │
│ • inject_source_urls │
│ • verify_urls_in_text (HEAD + SSL retry adilet) │
│ → чистит осиротевшие буллеты после битых ссылок │
╰───────────────────────────────────────────╯
╭─ Стадия 5: Visual ─────────────────────────╮
│ ОДИН Haiku-вызов → {title, subtitle, items[3-4]} │
│ • Обложка 1080×1080 (Pillow) │
│ • Cheat-sheet 1080×1080 (Pillow) │
╰───────────────────────────────────────────╯
╭─ Стадия 6: Превью драфта ───────────────────╮
│ 🎨 Обложка (post_type) │
│ 📌 Cheat-sheet (post_type) │
│ 📝 ДРАФТ [id] — Тема: ... 🛡⚙ −2 HG │
│ [✅ С обложкой] [📝 Только текст] │
│ [✏️ Редактировать] [🔄 Перегенерировать] │
│ [❌ Пропустить] │
╰────────────────────────────────────────────╯
╭─ Стадия 7: Публикация (Камал нажимает ✅) ─────╮
│ Канал @LyumiHSEDigest получает 3 сообщения: │
│ 1. Обложка с caption-тизером │
│ 2. Cheat-sheet (без caption) │
│ 3. Полный текст частями │
╰────────────────────────────────────────────╯
Календарь и стоимость
5 обычных постов + 1 субботняя аналитика тройная + 1 воскресный опрос/пасхалка:
| День | Команда | Модель | Цена |
|---|---|---|---|
| Пн | npa | Opus 4.7 | ~$0.50 |
| Вт | trends | Opus 4.7 | ~$0.50 |
| Ср | case | Opus 4.7 | ~$0.50 |
| Чт | trends | Opus 4.7 | ~$0.50 |
| Пт | topic | Opus 4.7 | ~$0.50 |
| Сб | analytics_multi | Opus + Gemini + GPT-5 | ~$1.20 |
| Вс | poll/easter | минимум | ~$0.05 |
| Итого | ~$4/нед ≈ $16/мес |
Что задеплоено по состоянию на 28 апреля
Фаза 0 — 27 апреля (утро)
- Чистый digest_bot.py (Spider/Incident вынесены)
- Разделён image: lyumi-pushkin (200MB) в /opt/lyumi-pushkin/
- Свой Dockerfile + requirements.txt + docker-compose.yml
Фаза 1 — 27 апреля (вечер)
- Brand voice synced с Люми
- Topic drift fix — двухслойный якорь
- Reflection dual-layer (Haiku 12K + Gemini 2.5 Pro 60K)
- Visual layer (обложки + cheat-sheets, 1080×1080)
- Публикация в канал (две кнопки: с обложкой / без)
Фаза 2 — 27 апреля (вечер)
- Sonar Reasoning Pro для deep-research
- /analytics_multi — тройной автор (Opus + Gemini + GPT-5)
Фаза 3 — 28 апреля (стабилизация)
Критические фиксы:
- KB enrichment через HTTP-мост lyumi-net (см. [[lyumi/kb_api_bridge]]). Pushkin зовёт http://lyumi-hse-bot:8000/kb_search и получает канон из ChromaDB Люми.
- Hook-правило в DIGEST_SYSTEM_PROMPT — 4 паттерна (парадокс/цифра/провокация/сцена), без драмы. Запрет «Сегодня разберём...» и восклицаний.
- HTML-санитайзер — _safe_telegram_html (whitelist тегов) + _balance_tags (закрывает повисшие в конце части + экранирует осиротевшие в начале). Закрыты 2 разных бага Парсера Telegram.
- Reflection в /case — был не подключён, исправлено.
- Устойчивый JSON-парсер Reflection — 4 стратегии: clean json.loads → raw_decode → fix unescaped newlines → regex fallback (выцепляет has_issues/confidence/issues даже из битого JSON).
- Картинки везде — /case + все автодрафты по расписанию (npa/trends/case/topic/weekly). Раньше были только в /topic, /analytics, /analytics_multi.
- verify_urls_in_text — удаляет осиротевшие буллеты вида «• Текст —» после битых ссылок.
Антифантомы 28 апреля (факты из реальных постов):
- Фантомная URL-атрибуция. Камал поймал: Люми поставила URL
adilet.zan.kz/rus/docs/V2000021713(реально существует — «Правила скорой мед. помощи»), но подписала его «Правила обучения по БиОТ». URL валидный, verify_urls проходил. Исправлено: - В DIGEST_SYSTEM_PROMPT: запрет подменять название документа к валидному URL
-
В pushkin_reflection: новый пункт 8 в system-промпте fact-checker — «фантомная URL-атрибуция»
-
Ст. 182-184 ТК РК в неверном контексте. Люми регулярно цитировала их в контексте «обучение/инструктаж». Реальность: эти статьи про рабочее время и аттестацию. Исправлено:
- В DIGEST_SYSTEM_PROMPT: явный запрет цитировать эти статьи в контексте обучения
- В pushkin_reflection: новый пункт 9 + сняты из whitelist факт-якорей
Реальная производительность (28 апреля)
- ~20 минут ручной правки на пост — это норма. AI-newsroom не подразумевает 100% автогенерации.
- Reflection метка всегда в шапке: 🛡✓ HG / 🛡⚙ −N HG / 🛡⚠ ?N HG
- Картинки 1080×1080 — одинаковая ширина в Telegram preview
- 195 подписчиков на @LyumiHSEDigest
Боевые проверки итоговые
/caseповеденческая безопасность → Heineken Brazil SafeStart кейс с обложкой «Как снизить травматизм на 70%» и cheat-sheet с 4 критериями. Полный pipeline отработал./topic охрана труда на высоте→ 1.3м, 22 кН, синдром подвешенного состояния. Reflection нашёл 3 проблемы, применил правки./analytics_multi культура безопасности DuPont→ 3 варианта готовых к публикации. GPT-5: «как только метрику превращают в палку, люди оптимизируют палку».
Что ДОЛГОСРОЧНО НЕ закрыто
- Авто-инжектор URL — если Люми вставляет URL без подтверждения названия в raw_content, пост-процессор должен сам снимать его (сейчас только Reflection прокатывается с вердиктом, но если confidence < 0.75 — пост уходит как есть)
- Memory топ-50 успешных постов — собирать views/forwards и использовать топовые как few-shot examples
- Калибровка confidence threshold Reflection — иногда находит проблему но не правит (?N вместо −N)
- Polemics-формат — «непопулярные мнения недели» через промпт. Готовить к 500+ подписчикам.
- Multi-source ingestion (LinkedIn, Reddit r/safety) — отложено до накопления данных по reach
Бизнес-смысл
Канал — лидмагнит к консалтингу, не самоцель.
- Сейчас 195 подписчиков, рост ~9/день
- Если 5% подписчиков → HSE-аудиторы/менеджеры → 1 лид/мес на консалтинг = 200-300K₸
- Цель роста: 500 к Q3, 1000 к Q4 → 2-5 лидов/мес = 0.5-1.5M₸/мес
Критерии «пушкин работает»: - Конверсия «подписался → написал Камалу» ≥5% - Регулярные forwards постов в рабочие чаты - «Кто ведёт LyumiHSEDigest?» — узнают Камала
Файлы и архитектура
/opt/lyumi-pushkin/
├─ Dockerfile # python:3.11-slim + fonts-dejavu + fonts-noto-core
├─ requirements.txt # aiogram + httpx + python-dotenv + apscheduler + Pillow
├─ digest_bot.py # главный файл
├─ digest_retriever.py # HTTP-клиент к Lyumi (28 апреля)
├─ pushkin_reflection.py # dual-layer fact-check + 4-стадийный JSON-парсер
├─ cover_generator.py # обложки 1080×1080 на Pillow
├─ summary_card.py # cheat-sheets 1080×1080
└─ docker-compose.yml # env_file: /opt/lyumi/.env, networks: lyumi-net
image: lyumi-pushkin (~200MB)
container: lyumi-pushkin-bot
networks: lyumi-net (общая с lyumi-hse-bot)
volumes: /opt/lyumi/logs (НЕ привязан к lyumi-chroma — база читается по HTTP)
ENV переменные (в общем /opt/lyumi/.env)
OPENROUTER_API_KEY=...
DIGEST_BOT_TOKEN=...
DIGEST_CHANNEL_ID=@LyumiHSEDigest
DIGEST_ADMIN_ID=...
GEMINI_REFLECTION_MODEL=google/gemini-2.5-pro
GEMINI_WRITER_MODEL=google/gemini-2.5-pro
SONAR_DEEP_MODEL=perplexity/sonar-reasoning-pro
KB_API_URL=http://lyumi-hse-bot:8000 # default в digest_retriever.py
KB_API_TIMEOUT=30 # default
Деплой 28 апреля
# С Мака:
scp digest_bot.py digest_retriever.py pushkin_reflection.py \
cover_generator.py summary_card.py \
root@46.62.238.135:/opt/lyumi-pushkin/
scp kb_api.py bot.py requirements.txt \
root@46.62.238.135:/opt/lyumi/
# На сервере (одноразово):
docker network create lyumi-net
# Обновить оба docker-compose.yml добавив networks: lyumi-net (external: true)
# Пересборка обоих:
cd /opt/lyumi && docker compose up -d --build
cd /opt/lyumi-pushkin && docker compose up -d --build
# Проверка связи:
docker exec lyumi-pushkin-bot python -c \
"import httpx; print(httpx.get('http://lyumi-hse-bot:8000/healthz').json())"
Связанные
- [[lyumi/bot_v3]] — основная Люми
- [[lyumi/kb_api_bridge]] — HTTP-мост ChromaDB Lyumi↔Pushkin
- [[lyumi/cleanup_ru_apr28]] — чистка RU-рудиментов (тот же день)
- [[lyumi/strategy_2026]] — стратегия Lyumi 2026
- Memory
project_pushkin_workflow_stable_apr28— ~20 мин ручной правки норма - Memory
project_pushkin_phase2_apr27— детали Phase 2