--- title: "Session Design — AI Psychologist App" aliases: - "Дизайн сессии" - "Session design" - "архитектура сессий" created: '2026-05-19' updated: '2026-05-24' tags: - project - app - psychology - ux - architecture related: - "[[personal/projects/psychologist-app/overview]]" - "[[personal/projects/psychologist-app/character-design]]" - "[[personal/projects/psychologist-app/onboarding-ux]]" --- # Session Design — AI Psychologist App > Детальный дизайн сессии: UX-флоу, механика вопросов, открытие/закрытие. > Связан с: [[overview]] (раздел 5-6 — базовая структура и архитектура ботов) --- ## 1. Механика вопросов (Question Delivery) ### Pipeline вопросов ``` Бот 2 (Analyst / "Психолог") → генерирует 1-2 вопроса в 3-м лице ("пользователь избегает...") ↓ Бот 1 (Narrator / "Посредник") → переформулирует в 1-е лицо ("ты избегаешь?") → на выходе: структурированный массив вопросов для UI ↓ UI алгоритм (не агент!) → показывает вопросы по одному в карточках → ждёт ответа → следующий ``` **Ключевой принцип**: раздача вопросов — детерминированный алгоритм, не LLM-вызов. Агент генерирует батч вопросов один раз → посредник переформулирует → UI сам управляет порядком. ### Структура данных от агента (JSON для UI) ```json { "questions": [ { "id": 1, "text": "Ты замечаешь, что откладываешь этот разговор?", "type": "open" }, { "id": 2, "text": "Что происходит внутри когда думаешь об этом?", "type": "open" } ], "answered": [], "session_id": "2026-05-19" } ``` ### Завершение батча вопросов → подбивка Когда все вопросы в батче отвечены, UI передаёт агенту нумерованную подбивку: ``` 1. [вопрос] → [ответ пользователя] 2. [вопрос] → [ответ пользователя] ``` Это входные данные для следующей итерации диалога (следующий батч вопросов или инсайт). --- ## 2. Открытие сессии ### Структура intro 1. **Персонаж-активация** (анимация, 1-2 сек) — без текста, пауза перед словами 2. **Короткое введение** (1-2 предложения максимум): - Что происходит сегодня в целом (настроение агента, не диагноз) - Без "Давай начнём с..." — сразу к делу 3. **"Крючки-активаторы"** из прошлых бесед: - 1-2 элемента из profile.md / последних сессий - Формат: карточка-напоминание ("В прошлый раз ты говорил о...") - **Не перегружать**: максимум 2 крючка, не перечислять всю историю - Если нет прошлых сессий — пропустить этот блок 4. **Переход к теме** — либо предложение агента, либо выбор пользователя ### Prompt агента для intro Агент (Analyst) при старте сессии получает: - `profile.md` — текущий профиль - `sessions/[last 1-2].md` — последние сессии - Задача: сформировать intro + max 2 крючка, без перечисления всего --- ## 3. Закрытие сессии ### Последовательность закрытия (3 этапа) #### Этап 1 — Психолог обновляет документы (backend, не видно пользователю) После завершения диалогового флоу Analyst: - Пишет `sessions/YYYY-MM-DD.md` — запись сессии - Обновляет `profile.md` — новые паттерны/наблюдения - Формирует structured summary для Посредника #### Этап 2 — Посредник: человечный итог (видно пользователю) Посредник в режиме "простого AI-агента" — без аналитики, без психолого-языка: - Тёплая, живая фраза от себя (не "подводя итог...") - Примерный тон: "И от себя — это больше чем ничего. Ты на верном пути." - **Не повторять** то что уже сказал психолог - **Не хвалить** избыточно — anti-sycophancy принцип сохраняется - Сказать когда следующая сессия: "До встречи в четверг" (из расписания пользователя) #### Этап 3 — "One last thing" + завершение - Агент задаёт открытый вопрос с вольным промптом: "Хочешь что-то добавить?" - **Визуально**: маленький текстовый input, **не акцентная** кнопка "Завершить" - Этот экран не предполагает продолжения полноценной сессии - Если пользователь что-то написал → агент может добавить это в заметки сессии, ответить коротко - Если нажал "Завершить" без ввода → сессия закрывается ### Сценарий сдвига расписания Если в "one last thing" (или на любом этапе закрытия) пользователь упоминает сдвиг даты/времени: - Детектируется ключевыми словами (перенести, следующий раз, не смогу в четверг, и т.д.) - Запускается **сценарий планировщика** (отдельный флоу) - Беседа переходит в режим планировщика и **завершается в нём** (не возвращается в сессионный флоу) - Результат: обновлённое расписание, подтверждение новой даты --- ## 4. Флоу сессии целиком ``` ОТКРЫТИЕ ├── Анимация персонажа (1-2 сек) ├── Intro: 1-2 предложения + max 2 крючка из истории └── Выбор темы (пользователь или AI предлагает) ДИАЛОГ ├── Analyst генерирует 1-2 вопроса (3-е лицо) ├── Narrator переформулирует → JSON карточек (1-е лицо) ├── UI раздаёт по одному ├── Пользователь отвечает → нумерованная подбивка └── Следующий батч / инсайт ИНСАЙТ ├── Analyst кристаллизует наблюдение (3-е лицо) └── Narrator переформулирует для пользователя (1-е лицо) ЗАКРЫТИЕ ├── [backend] Analyst пишет session summary, обновляет profile.md ├── Посредник: тёплая фраза + дата следующей сессии ├── "One last thing" (вольный промпт, неакцентное завершение) │ ├── Написал что-то → агент добавляет в заметки, отвечает коротко │ ├── Упомянул перенос → сценарий планировщика │ └── Завершить (кнопка) → сессия закрыта ``` --- ## 5. State Persistence & Session Recovery ### Сохранение стейта на каждом шаге Каждый шаг сессии сохраняется немедленно — не в конце: ``` step_state { session_id: "2026-05-19", user_id: "...", phase: "dialogue", // intro | questionnaire | dialogue | insight | closing current_question_idx: 2, answered: [ {q: "...", a: "..."}, ... ], last_activity_ts: 1747612800 } ``` При следующем открытии приложения — автоматически восстанавливается точка, где пользователь остановился. Не начинает с начала. ### Заброшенная сессия (пользователь пропал посередине) **Триггер**: last_activity_ts > 20 часов, сессия не завершена. **Действие (backend cron)**: 1. Принудительно **завершить сессию** — агент пишет partial summary на основе того, что успело ответить 2. Обновить `profile.md` — даже неполные данные полезны 3. Пометить сессию как `completed_partial` **Уведомление**: на следующий день **примерно в то же время** (± 30 мин от last_activity_ts предыдущих сессий) — push: > "Мы не успели закончить в прошлый раз. Вернёмся?" **Retention protocol** (Stage 2): при N пропущенных сессиях подряд — запускается отдельный флоу "возвращение пользователя" с мягким реактивационным сообщением. Детали — в будущем документе. --- ## 6. Открытые вопросы - [ ] Как именно Narrator детектирует что вопросы в 3-м лице и нужно переформулировать? Prompt rule или регекс-паттерн? - [ ] Сценарий планировщика — отдельный агент или встроен в посредника? - [ ] Как хранить расписание сессий: отдельный `schedule.md` в профиле? - [ ] Что если "one last thing" раскрывает новую тему — прерывать или кратко зафиксировать? ## Связанные заметки - [[personal/projects/psychologist-app/overview]] - [[personal/projects/psychologist-app/character-design]] - [[personal/projects/psychologist-app/onboarding-ux]]