221 lines
11 KiB
Markdown
221 lines
11 KiB
Markdown
---
|
||
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]]
|