AR 15 M4 60f8a7b398 feat(sprint7.6): оптимизация воронки new_booking до 4 шагов (вариант 2)
Воронка сжата с 6 шагов до 4: intro → qualify → book → close.
Спецификация: docs/OPTIMIZATION_CONVERSION_v1.md.
Цель: сравнимая с конкурентом (NEXTBOT/Александра) конверсия — ≤3 реплик
бота до запроса телефона, содержательный ответ на жалобу в первом
осмысленном сообщении.

Промпты шагов:
- intro.md — переписан. Приветствие + открытый вопрос «что беспокоит?».
  Имя НЕ спрашиваем (слот name со шага снят), оно собирается на book
  вместе с телефоном. Если пациент сразу написал жалобу — не зацикливаемся,
  переходим в qualify.
- qualify.md — переписан. Обязательный 5-пунктовый шаблон ответа на жалобу:
  эмпатия (одна фраза) → 2-3 ЛОР-гипотезы из RAG-выдержек («может быть
  связано с») → специалист → услуга/цена («при необходимости назначит») →
  бинарный CTA «записать?». Если в выдержках нет гипотез/цен — пункт
  пропускается, не сочиняем. Если жалоба не описана (пациент сразу
  «хочу записаться к ЛОРу») — пропускаем гипотезу/услугу, оставляем
  эмпатию-формальность + специалист + CTA.
  Три особые ситуации сохранены: ребёнок (require_legal_rep), конкретный
  врач (waitlist_flag), первичная жалоба на слух (needs_surgologist_first).
- book.md — переписан. Одной репликой: подтверждение плана с
  использованием {specialist}/{reason} + запрос телефона + имени (если
  ещё не было в истории). При is_child=true — обращение к родителю,
  legal_rep_phone используется, если уже собран.
- present.md — DEPRECATED. Файл оставлен в репо на случай отката
  (вариант 1 спецификации). Внутри — заглушка «попал по ошибке —
  выходи на book».
- close.md и offer_time.md не тронуты (offer_time станет актуален с
  реальным календарём).

allowed_next в SEED_INTENT_STEPS:
- intro: [intro, qualify] (без изменений)
- qualify: [qualify, book] (раньше: [qualify, present])
- present: [book] (изоляция; раньше: [present, qualify, offer_time])
- offer_time: [offer_time, book] (deprecated, без изменений)
- book: [book, qualify, close] (раньше: [book, qualify, offer_time, close])
- close: [close] (без изменений)

migrate_new_booking_allowed_next_v2(session) — одноразовая миграция в
services/intent_step_service.py. При старте для каждого шага
new_booking сравнивает текущий allowed_next_json с дореформенным
значением (_PRE_SPRINT_7_6_ALLOWED_NEXT). Если совпадает — обновляет
на новое из SEED. Если оператор правил вручную — пропускает,
warning в лог. Идемпотентна (на повторных запусках ничего не делает).
Подключена в main.py lifespan после ensure_seed_guards.

Защитное условие require_legal_rep на qualify сохранено. Теперь блокирует
переход qualify → book (раньше qualify → present). Логика та же:
при is_child=true и пустых legal_rep_name/legal_rep_phone валидатор
отклоняет переход.

eval/MANUAL_CASES.md — markdown-чеклист для ручных прогонов:
- §A: 5 конверсионных кейсов (храп+уши, боль в горле, тугоухость,
  насморк >месяца, звон в ушах) с чеклистом 5 пунктов на первый ответ
  и проверкой ≤3 реплик до телефона.
- §B: регрессия 8 ручных сценариев из блока H Спринта 6b со ссылками
  на docs/examples/*_v2.md.

SPRINTS.md: Спринт 7.6 →  Закрыт по коду. Применение промптов в БД
и ручная регрессия — за оператором (через UI «Настройки → Шаги»
для каждого из 4 шагов new_booking).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 21:04:09 +05:00

Chat Agent for Patients (RAG) — инструмент настройки

RAG-ядро + веб-инструмент для настройки пациентского чат-агента: загрузка wiki, редактирование промпта и правил, прогон сценариев.

Подключение реальных каналов (чат в мобильном приложении, бот в МАКС) делает другой разработчик — этот проект отдаёт ему готовое RAG-ядро и API плюс согласованную конфигурацию (системный промпт, правила, снапшот базы знаний).


Статус

🟢 Active — Спринты 1–2 и доработки (2.5) закрыты, идём на Спринт 3.

Что уже работает:

  • RAG-ядро: FastAPI + ChromaDB + intfloat/multilingual-e5-large + DeepSeek.
  • Загрузка документов (.md, .txt, .pdf, .docx), чанкинг с чисткой markdown-мусора (навигационные блоки, инлайн-ссылки), просмотр чанков с эмбеддингами.
  • Многошаговый диалог с памятью треда (SQLAlchemy 2.0 async + Alembic + SQLite). История хранится навсегда.
  • Переиндексация без повторной загрузки файла: сохранённый raw_text → новый чанкер.
  • Две отладочные страницы: «Отладка» (одиночный вопрос, база знаний) и «Песочница» (чат с агентом, список тредов, переименование, удаление).
  • Markdown-рендер ответов ассистента в «Песочнице».
  • Системный промпт вынесен в prompts/system_prompt.md — правится без кода.

Цель проекта

  • Поднять RAG по wiki операторов и API диалога с агентом.
  • Дать операторам веб-инструмент, в котором они в процессе настройки:
    • загружают документы wiki (постепенно, по мере готовности — не пакетно);
    • редактируют системный промпт и правила поведения агента;
    • играют роль пациента в тестовом чате и смотрят, что отвечает агент;
    • сохраняют проработанные диалоги как сценарии и перегоняют их после изменения настроек.
  • Сама интеграция с реальными каналами (приложение, МАКС) — вне скоупа этого проекта.

Что не входит в скоуп

  • Реальная интеграция с чатом в мобильном приложении (work-pcs-pt-mobile).
  • Реальная интеграция с ботом в МАКС (work-pcs-pt-bots).
  • Очередь и UI оператора для живого переключения с агента на человека.
  • Мультипользовательская прод-эксплуатация.

Всё это — задача смежного разработчика, который будет использовать API этого сервиса.


Архитектура (черновик)

┌──────────────────────────────────┐      ┌──────────────────────┐
│  Web UI настройки (один экран)   │      │                      │
│  ┌────────────┐  ┌────────────┐  │      │   RAG (wiki)         │
│  │ База знаний│  │ Промпт +   │──┼─────▶│   ChromaDB + E5      │
│  │ (upload)   │  │ правила    │  │      └──────────────────────┘
│  └────────────┘  └────────────┘  │      ┌──────────────────────┐
│  ┌────────────┐  ┌────────────┐  │─────▶│   DeepSeek LLM API   │
│  │ Песочница  │  │ Сценарии   │  │      └──────────────────────┘
│  │ (чат)      │  │ (сохран.)  │  │
│  └────────────┘  └────────────┘  │
└──────────────────────────────────┘
              │
              ▼
       Chat Agent API (FastAPI)
       (тот же API, что потом получит
        внешний разработчик для каналов)

Ключевая идея: веб-инструмент — это единственный клиент агента на время настройки. Когда конфигурация «устаканивается», её снапшот отдаётся внешнему разработчику вместе с документированным API.


Технологический стек (предварительно)

Слой Технология Назначение
API FastAPI (Python 3.113.12) HTTP-эндпоинты агента и настройки
Vector DB ChromaDB База эмбеддингов wiki
Embeddings intfloat/multilingual-e5-large Русскоязычные эмбеддинги
LLM DeepSeek API Диалоговая модель
Хранилище конфигов и сценариев SQLite Промпты, правила, сценарии
Веб-UI Vanilla JS / лёгкий фреймворк Одностраничное приложение настройки
Контейнеризация Docker Изолированный запуск

База опыта — work-pcs-dr-cdss (RAG-сервис для врачей). Переиспользуем паттерн сервисов embeddings.py / vectorstore.py / document_processor.py / llm_client.py.


План (спринты)

См. docs/SPRINTS.md. Архитектурные документы и разобранные примеры — в docs/architecture/ и docs/examples/.


Запуск

Требования

  • Python 3.12
  • Ключ DeepSeek API

Установка

python3.12 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env   # и вписать DEEPSEEK_API_KEY

Старт

.venv/bin/python -m uvicorn main:app --host 0.0.0.0 --port 8003

Миграции Alembic применяются автоматически на старте. Первая загрузка embedding-модели E5-large занимает ~15–20 секунд.

Вручную накатить миграции

.venv/bin/alembic upgrade head

Создать новую миграцию после изменения моделей

.venv/bin/alembic revision --autogenerate -m "описание изменений"
.venv/bin/alembic upgrade head

Использование

Веб-страницы

  • http://localhost:8003/Отладка: загрузка документов, просмотр чанков со scores и эмбеддингами, одиночный тест-вопрос с 3-колоночным ответом (чанки / промпт / ответ LLM).
  • http://localhost:8003/sandbox.htmlПесочница: чат с агентом. Слева список сохранённых диалогов, в центре сам чат, справа отладка последнего ответа (найденные чанки + собранный промпт).

API

Метод Путь Назначение
GET /health Статус, кол-во документов и чанков, модель эмбеддингов
POST /documents/upload Загрузить файл (.md, .txt, .pdf, .docx), сохраняет raw_text в SQLite и чанки в Chroma
GET /documents Список документов
GET /documents/{id}/chunks Чанки документа + их эмбеддинги
DELETE /documents/{id} Удалить документ (из Chroma и SQLite)
POST /documents/{id}/reindex Переразметить документ с актуальными правилами чанкера
POST /documents/reindex-all Переразметить всю базу
POST /query Одиночный вопрос (Отладка)
POST /chat Отправить реплику в тред (создаёт тред, если thread_id не передан)
GET /threads Список всех диалогов
GET /threads/{id} Тред целиком с историей
PATCH /threads/{id} Переименовать
DELETE /threads/{id} Удалить тред со всеми сообщениями

Правка системного промпта

prompts/system_prompt.md — читается при старте сервиса. После правки — рестарт.


Структура

.
├── README.md                       # этот файл
├── docs/                           # проектная документация (см. ниже)
├── config.py                       # настройки (Pydantic BaseSettings)
├── main.py                         # FastAPI app, lifespan, авто-миграции
├── alembic.ini                     # конфиг Alembic
├── migrations/                     # миграции БД
├── prompts/
│   └── system_prompt.md            # системный промпт (правится без кода)
├── db/
│   ├── base.py                     # DeclarativeBase
│   ├── session.py                  # async engine + sessionmaker
│   └── models/
│       ├── thread.py               # диалоги
│       ├── message.py              # сообщения
│       └── document.py             # raw_text документов для reindex
├── models/                         # Pydantic-модели API
│   ├── requests.py
│   └── responses.py
├── routers/
│   ├── health.py
│   ├── documents.py                # upload / list / chunks / delete / reindex
│   ├── query.py                    # /query (одиночный вопрос)
│   ├── chat.py                     # /chat (диалог с памятью)
│   └── threads.py                  # CRUD тредов
├── services/
│   ├── embeddings.py               # E5-large
│   ├── vectorstore.py              # ChromaDB
│   ├── document_processor.py       # парсер + чанкер
│   ├── text_cleanup.py             # чистка markdown-мусора
│   ├── document_service.py         # SQLite-слой для raw_text
│   ├── llm_client.py               # DeepSeek
│   ├── rag_pipeline.py             # /query pipeline
│   └── chat_service.py             # диалоги: создание треда, сборка контекста
├── static/
│   ├── index.html                  # страница «Отладка»
│   └── sandbox.html                # страница «Песочница»
└── data/
    ├── chroma/                     # векторная БД (gitignored)
    └── sqlite/                     # реляционная БД (gitignored)

Документация (docs/)

docs/
├── SPRINTS.md                                  # план и статус спринтов
├── architecture/
│   ├── GRAPH_ARCHITECTURE_v1.md                # черновик при развороте 2026-04-23
│   ├── GRAPH_ARCHITECTURE_v2.md                # уточнения 2026-04-24
│   └── GRAPH_ARCHITECTURE_v3.md                # текущая (билингв. термины + ссылки на примеры)
└── examples/
    ├── 01_basic_booking.md                     # happy path записи (линейный)
    ├── 02_price_during_booking.md              # soft-insertion vs. hard-handoff
    └── 03_child_patient_guard.md               # guard в шаге qualify (запись ребёнка)

Связанные проекты

  • work-pcs-dr-cdss — RAG для врачей, источник технических паттернов.
  • work-pcs-pt-mobile — мобильное приложение пациента (канал подключит другой разработчик).
  • work-pcs-pt-bots — пациентские боты МАКС (канал подключит другой разработчик).
S
Description
No description provided
Readme 722 KiB
Languages
Python 59%
HTML 40.8%
Mako 0.1%