Перейти к содержанию

Пушкин — AI-newsroom для канала

Третий самостоятельный продукт экосистемы Lyumi (наряду с Люми HSE и Wiki). Своя идентичность, свой голос, свой production pipeline.

27 апреля — собран полный AI-newsroom: research → writer → fact-check → visual → publish. 28 апреля — workflow стабилизировался. Камал = главред + фактчекер (~20 минут ручной правки на пост). Всё остальное — роботы. ~$16/мес на 7 постов в неделю.

Принципы AI-newsroom

Главный урок 27 апреля — правильная постановка задачи:

Не «три модели пишут одно и то же». А «три модели с разными ролями + два слоя верификации + визуальный слой = редакция, где главред принимает решение».

Это разница между «использую ИИ» и «строю систему с ИИ внутри».

Четыре принципа которые работают:

  1. Ни один компонент не принимает решение в вакууме.
  2. Sonar basic + Sonar Reasoning Pro + KB enrichment из ChromaDB (28 апреля)
  3. Haiku reflection + Gemini reflection → cross-validate
  4. 3 writer-а на важных постах → редактор выбирает

  5. Честное «не знаю» > красивый вымысел. Топик-якорь в generate_post: «если данных нет — скажи честно». Reflection ловит фантомы URL и статей ТК РК (28 апреля вынесены в отдельные правила).

  6. Бренд = определённый голос + постоянный визуал. Голос Люми зафиксирован в DIGEST_SYSTEM_PROMPT. Визуал 1080×1080 (обложка + cheat-sheet) — во всех постах (28 апреля распространено на /case и все автодрафты по расписанию).

  7. Человек на финальном 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 апреля (факты из реальных постов):

  1. Фантомная URL-атрибуция. Камал поймал: Люми поставила URL adilet.zan.kz/rus/docs/V2000021713 (реально существует — «Правила скорой мед. помощи»), но подписала его «Правила обучения по БиОТ». URL валидный, verify_urls проходил. Исправлено:
  2. В DIGEST_SYSTEM_PROMPT: запрет подменять название документа к валидному URL
  3. В pushkin_reflection: новый пункт 8 в system-промпте fact-checker — «фантомная URL-атрибуция»

  4. Ст. 182-184 ТК РК в неверном контексте. Люми регулярно цитировала их в контексте «обучение/инструктаж». Реальность: эти статьи про рабочее время и аттестацию. Исправлено:

  5. В DIGEST_SYSTEM_PROMPT: явный запрет цитировать эти статьи в контексте обучения
  6. В 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: «как только метрику превращают в палку, люди оптимизируют палку».

Что ДОЛГОСРОЧНО НЕ закрыто

  1. Авто-инжектор URL — если Люми вставляет URL без подтверждения названия в raw_content, пост-процессор должен сам снимать его (сейчас только Reflection прокатывается с вердиктом, но если confidence < 0.75 — пост уходит как есть)
  2. Memory топ-50 успешных постов — собирать views/forwards и использовать топовые как few-shot examples
  3. Калибровка confidence threshold Reflection — иногда находит проблему но не правит (?N вместо −N)
  4. Polemics-формат — «непопулярные мнения недели» через промпт. Готовить к 500+ подписчикам.
  5. 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