Files
obsidian-vault/personal/projects/psychologist-app/session-design.md
T
2026-05-30 10:03:30 +00:00

11 KiB

title, aliases, created, updated, tags, related
title aliases created updated tags related
Session Design — AI Psychologist App
Дизайн сессии
Session design
архитектура сессий
2026-05-19 2026-05-24
project
app
psychology
ux
architecture
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)

{
  "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" раскрывает новую тему — прерывать или кратко зафиксировать?

Связанные заметки