diff --git a/SPRINTS.md b/SPRINTS.md index 9ffb001..61caa02 100644 --- a/SPRINTS.md +++ b/SPRINTS.md @@ -43,23 +43,47 @@ ## Спринт 2. Многошаговый диалог с памятью треда ### Цель -Перейти от одиночного `/query` к полноценному диалогу: агент помнит историю, оператор ведёт разговор из 5+ реплик. На тестовой странице добавляется режим «чат», рядом с режимом «одиночный вопрос» из Спринта 1. +Перейти от одиночного `/query` к полноценному диалогу: агент помнит историю, оператор ведёт разговор из 5+ реплик. Текущую страницу отладки (одиночный вопрос) оставляем без изменений, добавляем **вторую отладочную страницу** — «Песочница» со списком всех сохранённых диалогов. ### Статус: ⏳ Запланирован ### Задачи -- [ ] Хранилище диалогов (SQLite): `threads`, `messages` -- [ ] Эндпоинт `POST /chat`: принимает `thread_id`, `text` → возвращает ответ агента + источники + `assembled_prompt` -- [ ] Базовый системный промпт (хардкод для старта): роль, тон клиники, что можно и нельзя -- [ ] Сборка контекста: история треда + RAG-чанки -- [ ] Веб-страница расширена режимом «Песочница»: - - [ ] левая колонка — чат (оператор пишет как пациент, видит ответы агента) + +**Хранилище:** +- [ ] Стек: SQLite + SQLAlchemy 2.0 (async, ORM-стиль) + Alembic для миграций +- [ ] Таблицы: + - `threads` (id, name, user_id nullable, agent_config_id nullable, created_at, updated_at) + - `messages` (id, thread_id FK, role, text, sources_json, assembled_prompt, created_at) + - Колонки `user_id` и `agent_config_id` заводим сразу nullable — под будущие Спринты 3+ (мульти-пользователи, мульти-промпты), чтобы не тащить миграции задним числом +- [ ] Первая миграция Alembic с этими двумя таблицами +- [ ] Все диалоги сохраняются навсегда (никакого авто-удаления) +- [ ] Имя треда генерируется автоматически по первой реплике пациента + дата; оператор может переименовать вручную + +**Эндпоинты:** +- [ ] `POST /chat` — принимает `thread_id` (или создаёт новый если не передан) + `text` → возвращает ответ агента + источники со score + `assembled_prompt` +- [ ] `GET /threads` — список всех диалогов (id, name, created_at, messages_count, превью первой реплики) +- [ ] `GET /threads/{id}` — тред целиком с историей сообщений +- [ ] `PATCH /threads/{id}` — переименовать тред +- [ ] `DELETE /threads/{id}` — удалить тред со всеми сообщениями + +**Сборка ответа:** +- [ ] Базовый системный промпт (хардкод для старта): роль агента, тон клиники, что можно и нельзя +- [ ] Сборка контекста для LLM: системный промпт + история треда + RAG-чанки по последней реплике + +**Веб-интерфейс:** +- [ ] В шапке обеих страниц — ссылки «Отладка» (текущая `/`) / «Песочница» (новая `/sandbox`) +- [ ] Текущий `static/index.html` остаётся без изменений +- [ ] Новая страница `static/sandbox.html` на отдельном маршруте `/sandbox`: + - [ ] левая колонка — список сохранённых диалогов: превью, дата, кнопка «переименовать», кнопка «удалить», кнопка «новый тред» + - [ ] центральная колонка — сам чат (оператор пишет как пациент, видит ответы агента, история подгружается при клике на тред из списка) - [ ] правая колонка — retrieved-чанки со score + собранный промпт по последней реплике - - [ ] кнопка «сбросить тред» ### Критерий готовности - [ ] Оператор может провести диалог из 5+ реплик, агент помнит контекст +- [ ] Все диалоги сохраняются и видны в левой колонке после перезагрузки страницы +- [ ] Оператор может открыть старый диалог, переименовать его, удалить - [ ] В правой колонке видно, что нашёл RAG и что улетело в LLM на последнем шаге +- [ ] Старая страница отладки (`/`) работает как раньше, ничего не сломано --- @@ -143,3 +167,4 @@ - Автосинхронизация wiki - Перевод правил из свободного текста в структурированный список (pattern → instruction) - Мультипользовательский режим (несколько операторов одновременно настраивают) +- Хранение исходных файлов (`./data/uploads/{document_id}.{ext}` + `source_path` в метаданных Chroma) — чтобы переиндексировать без повторной загрузки и показывать оператору оригинал документа