← Интерфейсы и исследования

Дизайн: архитектура «семи агентов» лендинга на базе rodnik-hermes

Статус: проект архитектуры, без изменений в коде и конфигах. Дата: 2026-08-15. Вход: rodnik.bz/1/ (семь персон), rodnik-hermes (ARCHITECTURE.md, docs/profiles.md, docs/vision-hermes.md, docs/routine-catalog.md, паспорта soul/profiles/), rodnik-web (пайплайн, Assist::Suggest, prompt_templates, llm-биллинг). Внутренний документ — на trends не публикуется.


0. Принцип

Лендинг продаёт семь работ; система исполняет их четырьмя механизмами:

МеханизмЧто даётЦена
Профиль (HERMES_HOME: SOUL, config, ключи)личность, свой периметр, своя модельпроцесс + ~22.5k токенов SOUL на вызов
Канал (платформенный вход к gateway)точка доступапочти ноль
Рутина (cron: prompt / гибрид / no_agent)работа по расписаниюпо режиму
Карточка доски (assignee → воркер)разовая работа под ревьюспавн Писаря

Правило заведения профиля (из ревью ролей): другая модель, другой периметр доступа, другой класс входных данных или отдельный поток повторяемой работы. Ни одна из четырёх «новых» персон лендинга (Яна, Вера, Мирон, Игнат) этим критериям не отвечает — профили под них не заводятся. Персона — продуктовый ярлык поверх механизма, а не сущность.

Центральный новый объект дизайна — реестр персон (§2): таблица «персона → механизмы → метрика», которая делает лендинг честным (проценты атрибутируются) и не даёт продуктовой нарезке протечь в архитектуру.


1. Карта: персона → механизм

                        ┌─ Себастьян = Telegram-канал (голос → STT gateway)
                        │
чат директора ──────────┤
Telegram ───────────────┴──► default (Sales Brain) ◄── рутины Яны/Веры/Мирона/Игната
                                    │                       (все кроны — в default-сторе,
                                    │ board_card /           per-profile cron, upstream #4707)
                                    │ board_curate_now
                                    ▼
                         no_agent seed (nba_seed.sh)
                                    │
                                    ▼
                          orchestrator (воркер) ──👤─► карточки человеку
                                    │
                                    🤖 (assignee=scribe)
                                    ▼
                             scribe (воркер) ──► черновик в карточку, на ревью
                                                 (брифы Яны, письма Веры,
                                                  фидбек Мирона — здесь)

отдельный контур:  desktop ──► rodnik-web Assist::Suggest ──► realtime-гейтвей (Лина)
                                (envelope, AssistSession)      быстрая модель, без тулов,
                                                               без памяти, свой bearer

фон (не персоны): rodnik-web pipeline (Whisper → normalize → sales_analysis →
                  classify → ingest OpenViking; amoCRM crm_summary) — детерминированный
                  код, производит сырьё для всех персон

01 · Яна — «брифер к каждому звонку»

Механизм: гибридная рутина в default + 🤖-карточки Писарю. Ежедневная крон-джоба режима «--script без --no-agent»: скрипт детерминированно собирает список сегодняшних звонков/встреч из CRM-проекции (crm_tasks / календарь amoCRM), stdout инжектится в промпт — агент ставит по 🤖-карточке «бриф к звонку <deal>» (идемпотентно brief-<deal_id>-<дата>), диспетчер спавнит Писаря на каждую. Бриф Писарь уже умеет (паспорт: «бриф к звонку — что известно, боли, возражения, цель, следующий шаг»; результат — в карточку, воркспейс scratch).

Почему не «каждому менеджеру по агенту»: бриф — это read-only компиляция CRM + viking_search, никакого своего периметра или модели не требует. Почему гибрид, а не prompt-джоба: список звонков — арифметика; тратить ~22.5k токенов SOUL на «выясни, какие сегодня звонки» — против урока nba_seed.sh.

Доставка: карточка на доске + утренняя сводка «готовы брифы: N» в чат менеджера (когда появится multi-user, см. §4) или РОПу.

02 · Лина — «суфлёр, который не молчит на „дорого“»

Механизм: профиль realtime на отдельном гейтвее — уже спроектирован и работает. Быстрая модель, без инструментов, без памяти, свой порт и свой bearer; речь клиента — враждебный вход, фенсится Context::Envelope со случайной меткой; память диалога живёт в Rails (AssistSession), не на гейтвее; [NO_RESP] — контракт молчания; промпт — prompt_type: assistant из /admin, единственный UNSEEDED-тип.

В дизайне ничего не меняется — Лина фиксируется как эталон «персона = профиль» и как единственная персона со своим SLA на латентность (см. §5).

03 · Вера — «тот, кто не даёт сделке остыть»

Механизм: детерминированный пайплайн + рутина дожима + 👤-карточки. Три части работы Веры уже разложены по правильным домам:

Вера — самая «распределённая» персона: код + рутина + две дорожки доски. Именно поэтому реестр персон (§2) обязателен — иначе её +7% нечем атрибутировать.

04 · Мирон — «уши РОПа на все звонки»

Механизм: пайплайн (100% покрытие) + рутина ротации + дашборды. «100% звонков разобраны» уже даёт пайплайн: каждый звонок проходит calls_analysis, каждая sales-встреча — sales_analysis; это свойство конвейера, не агента. Персона Мирона — надстройка осмысления: рутина №6 каталога («Качество звонков менеджера», среда, менеджеры по кругу, режим РОПа из SOUL) + выход report_publish в rodnik-report + 🤖-карточка «черновик обратной связи» Писарю.

Дизайн-дельта: к ротации добавить еженедельный агрегат «дыры в скрипте» (частотный срез красных флагов по всем звонкам недели → один дашборд) — это обещание лендинга «дыру в скрипте закрыть на этой неделе». Гибридная рутина: SQL-скрипт считает частоты, агент интерпретирует.

05 · Игнат — «методист, который учит систему»

Механизм: пакет из трёх существующих рутин каталога. №2 «Недельный разбор проигранных» (пт 17:00, причины + цитаты из транскриптов), №3 «Когорты won/lost за месяц» (1-е число, + 3 гипотезы с якорями), №7 «Свод возражений» (раз в 2 недели, objections/current.md). Сырьё уже оседает: objections_grouping, CohortDigest → cohorts/<status>/<week>.md в OpenViking.

«Учит систему» в буквальном смысле — компаундинг памяти (этос №7): выводы Игната ингестятся обратно в OpenViking и поднимаются всем остальным персонам через viking_search. Ничего нового заводить не надо — только собрать три рутины под один ярлык в реестре.

06 · Себастьян — «все данные продаж в кармане»

Механизм: канал, не личность. Telegram-бот тенанта — вход к default-гейтвею; голосовые перевариваются STT гейтвея (voice memo transcription — штатная возможность Hermes). Себастьян не имеет своей души, своей модели и своего процента — лендинг это честно оговаривает («доступ, не процент»).

Граница дизайна: пока Telegram-каналом пользуется только ком.директор, ничего не требуется. Как только доступ получают менеджеры — включается дизайн multi-user-brain (§4): OBO-токен в каждом tool-call, owner-RLS в Rails. Себастьян становится триггером этой работы, но не отдельным профилем.

07 · Родник — «второй мозг коммерческого»

Механизм: связка default + orchestrator + scribe — как есть. default (Sales Brain: этос семи статей, режим РОПа, конверт-контракт, навигация по мозгу) — собеседник и исполнитель всех рутин; orchestrator (паспорт «Оркестратор внимания»: 8–12 действий, деньги × риск, две дорожки, дедуп) — доска; scribe (паспорт «Писарь»: одна карточка, результат в карточку, наружу ничего) — руки. На лендинге вся тройка продаётся одним именем «Родник» — и это правильно: оркестратор и писарь — служебные роли, клиенту их видеть незачем.


2. Реестр персон — единственная новая сущность дизайна

Тонкий каталог в rodnik-web (концептуально — YAML/таблица, не новые процессы):

personas:
  yana:
    title: "Яна — брифер к каждому звонку"
    mechanisms:
      routines: [briefs-daily]            # id крон-джоб в default-сторе
      card_keys: ["brief-*"]              # идемпотентные ключи карточек
    metric: "звонков с брифом / всех звонков; конверсия таких звонков"
  lina:
    title: "Лина — суфлёр"
    mechanisms: { profile: realtime, service: Assist::Suggest }
    metric: "подсказок показано / принято; латентность p95"
  vera:
    mechanisms:
      pipeline: [sales_analysis→crm_summary]
      routines: [warm-deals]              # №5 каталога
      card_keys: ["promise-*", "warm-*"]
    metric: "фоллоуапов вовремя; сделок, не остывших >7 дней"
  miron:
    mechanisms: { pipeline: [calls_analysis], routines: [qa-rotation, script-gaps] }
    metric: "покрытие разбора 100%; закрытых дыр скрипта"
  ignat:
    mechanisms: { routines: [weekly-lost, monthly-cohorts, objections-refresh] }
    metric: "гипотез выдано / принято; повторяемость причин lost"
  sebastian:
    mechanisms: { channel: telegram }
    metric: "DAU канала; голосовых запросов"
  rodnik:
    mechanisms: { profiles: [default, orchestrator, scribe], board: true }
    metric: "карточек закрыто (👤/🤖); гипотез проверено"

Что реестр даёт:

  1. 1. Атрибуция процентов. Каждый «+N%» лендинга привязывается к измеримому выходу конкретных рутин/карточек, а не к имени. Без этого пилот на 30 дней не доказуем.
  2. 2. Биллинг по персонам. Дизайн llm-billing уже ведёт учёт по virtual keys и фичам (llm_usage_events, разрезы по фиче/ключу/модели/компании). Виртуальные ключи прокси выравниваются с персонами (<tenant>-assist = Лина, <tenant>-cron = рутины Яны/Веры/Мирона/Игната, <tenant>-chat = Родник/Себастьян) — и «токены пакетами» из прайса лендинга становятся строкой отчёта «сколько сжёг каждый сотрудник».
  3. 3. UI «Команда». Вкладка в rodnik-web рендерит карточки персон из реестра: статус (рутины живы/на паузе — уже есть pause/resume в «Рутинах»), последний выход, расход токенов. Суточный контур лендинга («До звонка → На звонке → После → Качество → Система») — это просто группировка реестра по времени суток.
  4. 4. Защита архитектуры. Новая персона на лендинге = строка реестра, собранная из существующих механизмов. Требование «заведи персоне процесс» проверяется по критерию §0 — и почти всегда отклоняется.

Таблица персона → рутина

Развёртка реестра в плоский вид — то самое соответствие, без которого проценты лендинга не проверить в пилоте. «№» — номера болванок из routine-catalog; Д2/Д4 — дельты из §7; «код» — детерминированный пайплайн rodnik-web, не LLM.

ПерсонаВкладРутина / механизмРасписание (МСК)РежимВыход
Яна+4%Брифы к сегодняшним звонкам (Д2) → 🤖-карточки brief-* Писарю07:30 буднигибридбрифы в карточках доски
Лина+6%Не рутина: realtime-контур Assist::Suggest (профиль realtime)в момент разговорапрофильподсказка на экране / [NO_RESP]
Вера+7%Карточка из разговора: sales_analysis → crm_summary в amoCRMпосле каждой записикодсводка в сделке
Вера″Обещание в задачу: next steps → 👤-карточки promise-* (Д3)после каждой записикод + карточказадача человеку
Вера″№5 «Дожим стынущих сделок» → карточки warm-*вт, чт 10:00promptкарточки + сводка в чат
Мирон+5%Разбор 100% звонков: calls_analysis / sales_analysisкаждый звонок/встречакодартефакт разбора
Мирон″№6 «Качество звонков менеджера» (ротация, режим РОПа)ср 15:00promptдашборд + 🤖 «черновик фидбека»
Мирон″Агрегат «дыры в скрипте» за неделю (Д4)еженедельногибриддашборд частот красных флагов
Игнат+4%№2 «Недельный разбор проигранных»пт 17:00promptдашборд с цитатами
Игнат″№3 «Когорты won/lost за месяц»1-е числоpromptдашборд + 3 гипотезы с якорями
Игнат″№7 «Свод возражений» → objections/current.mdраз в 2 неделиpromptдашборд + обновление среза
СебастьяндоступНе рутина: Telegram-канал к default (голос → STT гейтвея)по запросуканалответ голосом/текстом
Родник+4%№1 «Утренний дайджест дня»08:30 будниpromptсводка в чат КД
Родник″№4 «Подготовка к планёрке»пн 08:00promptдашборд + сводка
Родник″nba_seed.sh → seed Оркестратора → доска → Писарь07:00 пн-сбno_agentдоска следующих действий
Родник″Чат КД + board_curate_now («обнови доску сейчас»)по запросучатответы, карточки

Правило чтения: у персоны с процентом каждая строка — измеримый выход; вклад персоны в пилоте считается по сумме её строк, а не по впечатлению. Лина и Себастьян — единственные строки без крона: первая — профиль со своим SLA на латентность, второй — канал без собственного выхода.


3. Расписание суток (контур лендинга «как это выглядит за день»)

Все LLM-рутины — prompt/гибрид-джобы в default-сторе (единственный тикающий: cron per-profile by design, upstream #4707; bearer /api/jobs и вкладка «Рутины» видят только его). Времена — МСК, конвенция CronSchedule.

ВремяПерсонаДжобаРежим
07:00 пн-сбРодникnba_seed.sh → seed Оркестратораno_agent + script (есть)
07:30 будниЯнабрифы к сегодняшним звонкам → 🤖-карточкигибрид (дизайн)
08:00 пнРодникподготовка к планёрке (№4)prompt (каталог)
08:30 будниРодникутренний дайджест (№1)prompt (каталог)
в течение дняЛинаподсказки на живых разговорахrealtime-контур (есть)
после каждого звонкаВера/Миронпайплайн: разбор, crm_summary, ingestкод (есть)
10:00 вт, чтВерадожим стынущих (№5) → карточкиprompt (каталог)
15:00 срМиронротация качества (№6) → дашборд + фидбекprompt (каталог)
17:00 птИгнатразбор проигранных (№2) → дашбордprompt (каталог)
1-е числоИгнаткогорты won/lost (№3)prompt (каталог)
раз в 2 недИгнатсвод возражений (№7)prompt (каталог)
по запросуСебастьянголос в Telegram → defaultканал (есть)

Обещание лендинга «Не надо открывать Вайбкод и просить. Контур идёт по расписанию отдела» выполняется именно кронами default-стора — потому что фоновые делегации Hermes не переживают рестарт, а no_agent-сиды и prompt-джобы переживают. Это архитектурная причина, по которой персоны «работают сами» через cron+доску, а не через delegate_task из чата.


4. Границы безопасности (без изменений — фиксация соответствия)

Лендинг: «152-ФЗ с первого дня. Данные в РФ. Поручение — до старта разборов». Архитектура это уже держит, дизайн лишь закрепляет соответствие персонам:


5. Экономика и SLA по персонам


6. Что дизайн сознательно НЕ делает

  1. 1. Не заводит профили Яне, Вере, Мирону, Игнату. Ни один не проходит критерий (другая модель / периметр / класс входа / свой поток). Семь профилей вместо четырёх реальных (default, orchestrator, scribe, realtime) означали бы расходящиеся души, умножение SOUL-бюджета и ту самую ошибку «наделал кучу отделов».
  2. 2. Не даёт персонам «выбирать друг друга». Маршрутизация одна — assignee на доске (плюс автоподбор декомпозера по --description профиля). Никакой связи «Яна зовёт Игната»: связь между работами — через память (OpenViking) и доску, не через диалог агентов.
  3. 3. Не переносит запись в CRM на агентов. Этос №6: советует агент, решает человек; в CRM пишет детерминированный пайплайн. «Вера сама всё фиксирует» с лендинга — правда, но фиксирует код по факту записи, а не LLM по своему усмотрению.
  4. 4. Не строит «оркестратора оркестраторов». Иерархия остаётся плоской: seed → Оркестратор → Писарь, глубже не растёт (у Писаря доски-курирования нет — защита от рекурсии зашита в паспорт).
  5. 5. Не делает Себастьяна личностью. Пока у канала нет требования отвечать иначе, чем чат, — это вход, а не роль.

7. Дельты дизайна (что появится, когда дойдёт до реализации)

Свод отличий от текущего состояния — всё в рамках существующих механизмов:

#ДельтаМеханизмПерсона
Д1Реестр персон + вкладка «Команда»каталог в rodnik-web поверх «Рутин» и доскивсе
Д2Рутина «брифы к сегодняшним звонкам»гибридная крон-джоба + 🤖-карточки brief-*Яна
Д3Next steps разбора → 👤-карточки promise-*расширение рутины поверх sales_analysisВера
Д4Агрегат «дыры в скрипте» за неделюгибридная крон-джоба + дашбордМирон
Д5Virtual keys прокси ↔ персоныконфиг LiteLLM + группировка отчётабиллинг
Д6Фолбэк-цепочка + алерт квоты + порядок деградацииконфиг инстанса + мониторингвсе
Д7Рутины №1–№7 каталога как blueprints для провижининга тенантаcron blueprintsЯна/Вера/Мирон/Игнат

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