Итерации 1–3 прошли как по рельсам. Итерация 4 убила ветку — и это хорошо

от автора

Третья статья из серии. Предыдущие: манифест до первой строчки кода и итерация 0 — скелет и первый вебхук.

Я обещал публиковать честно: и где всё идёт по плану, и где разбиваешься о реальность. Вот статья про и то, и другое.

Три итерации — ровно. Четвёртая — ветка feat/iter-4 удалена, откат на main. Причина не в технических проблемах. Причина в том, что я наконец честно посмотрел на то, что построил, и понял: модель диалога слабая.

Итерации 1–3: когда спека работает

Каждая итерация — 15–20 минут с агентом, плюс столько же на ревью и документирование.

Итерация 1: Event Core

Контракт событий из vibepp.yaml стал рабочим кодом. Таблица events — append-only: триггер в PostgreSQL запрещает UPDATE и DELETE на уровне базы. Идемпотентность по max_update_id — повторный вебхук от MAX не создаёт дубль answer.given.

Property-based тесты (Vitest + fast-check) на инварианты INV-02, INV-03, INV-04, INV-07. Не «проверил один случай», а «сгенерируй 1000 случайных последовательностей событий и убедись, что инварианты держатся».

Итерация 2: первый вопрос

Управление жизненным циклом диалога. Открытие сессии (session.opened), первый статичный вопрос (question.asked, question_id = core:first), сохранение ответа (answer.given). inferDialogState — чистая функция над массивом событий, без I/O внутри.

Идемпотентность сессии: session.opened:iter2:${max_user_id} — одна сессия на пользователя. Повторный /start не ломает состояние.

Итерация 3: LLM-диалог

После ответа на первый вопрос — цепочка адаптивных вопросов, сгенерированных Claude на основе всех предыдущих ответов сессии. Anthropic как primary, OpenAI как fallback при ошибке или таймауте.

Порядок строгий по инварианту INV-06: llm.called пишется в базу до отправки сообщения пользователю. Если сервис упал между вызовом LLM и ответом — факт вызова сохранён, можно восстановить.

Промпт версионируется: поле prompt_version в llm.called и файл prompts/dialog-next-question.md. input_hash — SHA-256 итогового контента промпта. Через месяц можно воспроизвести, какой именно промпт породил конкретный вопрос.

Итерация 4: убита

Итерация 4 по спеке — «Первая карта»: Stability Engine, классификатор сигналов, CognitiveIdentityMap, BehavioralPatternMap, card.computed.

Что было сделано технически

Классификатор сигналов. После каждого answer.given — отдельная маленькая LLM (OpenAI с коротким таймаутом) анализирует пару «вопрос + ответ» и возвращает массив сигналов: card_type, scale, polarity, weight. При ошибке или таймауте — rule-based fallback. Каждый сигнал пишется как card_signal.received с causation_id = answer_event_id.

Две карты — CognitiveIdentityMap (шкалы source/horizon/tempo: как человек мыслит) и BehavioralPatternMap (шкалы obstacle/locus/energy: как действует под давлением).

Stability Engine. Карта назначается детерминированно (card.computed), когда:

— суммарный вес сигналов ≥ MIN_AGGREGATE_SIGNAL_WEIGHT_FOR_CARD (0.5)

— по каждой шкале есть хотя бы один сигнал с весом ≥ 0.2

— уверенность доминирующего полюса ≥ CARD_CONFIDENCE_THRESHOLD (0.72)

Инвариант INV-03: только детерминированный код решает, готова карта или нет. LLM предлагает сигнал — код принимает решение.

Контекст Layer I в промпте. Вместо полного транскрипта диалога — компактный блок: хвост последних ответов, rollup сигналов по сессии, слабые шкалы, флаг stall. Флаг stall: если за последние 3 ответа суммарный прирост сигналов < 0.15 — модели передаётся инструкция задать более прямой вопрос.

Промпт классификатора вынесен в prompts/signal-classifier-layer1.md и версионируется отдельно.

Почему ветка удалена

Я запустил диалог руками. И понял: это не работает как продукт.

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

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

Нейросеть адаптируется к ответам — этого мало. «Адаптивный вопрос на основе предыдущих ответов» — это ещё не методика. Это механизм. Методика — это другое: как выстроить последовательность, чтобы человек чувствовал движение и открытие, а не допрос.

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

Откатился на main. Удалил ветку.

Что дальше: другая модель диалога

Следующая итерация будет другой по структуре.

Вместо бесконечной цепочки вопросов — короткие тематические опросы по конкретным граням личности. После каждого опроса пользователь получает маленькое зеркало — не «вы набрали X баллов», а живой инсайт о том, что система увидела.

Параллельно с этими диалогами сигналы формируют несколько слоёв:

Архетипы и типы мышления — CognitiveIdentityMap, BehavioralPatternMap и дальше по слоям.

ÆON-профиль — read model поверх event log, который уточняется с каждой сессией.

Book of Consciousness — таймлайн трансформации пользователя: каждая завершённая сессия добавляет запись. Это и есть будущий платный слой: история себя, паттерны во времени, то, что никакой одноразовый тест не даст.

Разница с тем, что было: пользователь получает что-то сразу после сессии, а не «когда накопится». Ценность появляется раньше. Retention строится на том, что каждый возврат добавляет новую грань, а не просто проходит ещё один круг вопросов.

Перед следующей итерацией — проектирование методики. Не промпта, не алгоритма. Именно методики: как устроен короткий опрос, что пользователь видит на выходе, как это складывается в Book of Consciousness.

Эту работу агент не сделает. Реализовать — сделает. Придумать — моя задача.

Следующая статья — когда методика будет готова и ветка откроется снова.

Репозиторий: github.com/Quantum-Insight-Lab/aeon_map_system

Предыдущие статьи: [манифест] [итерация 0]

Было у вас такое: технически всё сделано, но продукт не то? Особенно интересно, как вы обнаруживали это — в ходе разработки или уже на пользователях.

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