52b46bc53e
Спринт 6c — терминология и сверка документации с реальным кодом:
- Словарь терминов в static/docs.html: «маршрутизатор» вместо «роутер»,
«защитное условие» вместо «guard», «пошаговая ветка» вместо «многошаговая».
Разделены концепты «намерение» (intent) и «ветка» (branch) с пометкой,
что в коде они хранятся как одна сущность 1:1.
- Песочница: «Решение маршрутизатора» виден всегда (зелёный/жёлтый),
счётчик переключений «N из 3» отдельной плашкой, бейджи под словарь.
- Настройки: «Условия перехода» → «Защитные условия (guards, JSON)».
- GRAPH_ARCHITECTURE_v4.md: имена полей thread_state и слоты приведены
к реальной БД (db/models/thread_state.py) и таксономии промптов шагов
(prompts/intents/new_booking/steps/). Ссылки на *_v2 примеры. На v3
поставлена шапка «устарело».
- 4 примера переписаны как *_v2: реальные current_intent_code/
current_step_code/slots_json, реальные allowed_next без двойных переходов,
реальная таксономия слотов name/reason/specialist/preferred_time/confirmed.
Удалены вымышленные CRM tool calls и слоты, которых нет в коде.
- static/example.html — параметризованная страница с навигацией между
4 примерами; роут GET /api/docs/examples/{name} в main.py отдаёт
markdown без дублирования файлов.
- Редактирование документов в Отладке: GET/PUT /documents/{id}/raw,
textarea с переразметкой и обновлением Chroma при сохранении.
Спринт 7, часть A — мульти-RAG через подписку ветка↔документы:
- Миграция: таблица intent_documents (M:N), модель IntentDocument,
индекс по document_id для обратного поиска.
- API: GET/PUT /intents/{code}/documents и GET/PUT /documents/{id}/intents
с PUT-семантикой «полный список», атомарно. Сервис
services/intent_document_service.py.
- Retrieval-фильтр в chat_service: подтягивает document_ids активной
ветки и передаёт в vectorstore.query(). Дефолт пустой подписки —
document_ids=[] (= 0 чанков), не «вся коллекция»: пустая подписка
означает «ветка не настроена», подмешивать случайное хуже, чем
ничего. vectorstore.query() различает None (нет фильтра) и [] (0).
- UI Настроек: блок «Документы базы знаний» в правом сайдбаре,
всегда видим независимо от вкладки, сортировка по имени, счётчик
«N из M», PUT при сохранении.
- UI Отладки: третья кнопка «привязка» рядом с «удалить» —
раскрывашка со списком веток (галочки), быстрая привязка прямо
на странице загрузки.
- Песочница: блок «Срез RAG» с подпиской/найдено, ворнинг при пустой
подписке. Поле rag_subscription в QueryResponse и ChatResponse.
- Системный промпт страницы Отладки переехал в обычную ветку _debug
(«Страница отладки»). Удалён prompts/system_prompt.md и логика
DEFAULT_SYSTEM_PROMPT в llm_client. routers/query.py подтягивает
активный конфиг ветки _debug и её подписки. Дефолт пустой подписки
для _debug — None (вся коллекция), не [] как для пациентских — чтобы
Отладка работала «из коробки». На странице Отладки info-bar показывает
активную версию и счётчик подписок, ссылка → Настройки.
- Тест-блок «Тест-вопрос» в центре Настроек: расширил /query
параметрами intent_code (default _debug), system_prompt (override
для теста черновика из textarea), disable_rag (для _router).
Редактор промпта обёрнут в <details open> — можно свернуть до
одной строки. Под ним — три колонки результата (RAG / промпт /
ответ). Для _router показывается подсказка про отсутствие RAG.
Документы:
- data/datasets/*.md — наработки по 6 веткам (рабочие материалы оператора).
- docs/BRANCH_MAP_AND_PROMPTS_v1.md, docs/OPTIMIZATION_CONVERSION_v1.md,
docs/guides/state_machine_and_slots.md.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
181 lines
24 KiB
Markdown
181 lines
24 KiB
Markdown
---
|
||
intent: reschedule
|
||
title: Перенос и отмена записи (датасет для ветки reschedule)
|
||
purpose: |
|
||
Источник для РАГа в ветке reschedule. Контент рассчитан на ситуацию, когда у пациента уже есть существующая запись и он хочет её перенести или отменить. Бот не делает реального действия в Полимеде — он собирает данные и передаёт администратору.
|
||
sources_wiki:
|
||
- homepage/udalennyjj-kontakt-centr/shablony-otvetov-na-soobshhenija-pacientov.md
|
||
- homepage/sluzhba-administratorov/polimed/perepiska-s-pacientami-v-whatsapp-wa-cherez-polime/perepiska-po-zapisi-na-segodnja-zelenyjj-kvadratik.md
|
||
- homepage/sluzhba-administratorov/polimed/rabota-s-listom-ozhidanija.md
|
||
- homepage/sluzhba-administratorov/poleznye-materialy-administratora/kommunikacii/rabota-s-koll-centrom.md
|
||
- homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/operacionnye-vmeshatelstva/organizacionnye-voprosy.md
|
||
note: |
|
||
Файл собран только из официальной выгрузки Yandex Wiki клиники. Прежние «временные» сводные документы
|
||
(skripty-vozrazhenija-chavo-obshhijj-spravochnik.md, vrachi-kliniki-polnaja-informacija.md)
|
||
для этой ветки не являются источником.
|
||
В вики не нашлись явные правила «за сколько часов до приёма можно перенести/отменить» и нет упоминаний
|
||
штрафов или неустойки за неявку — это пометки в раздел «Что нужно дополнить».
|
||
---
|
||
|
||
# Перенос и отмена записи
|
||
|
||
## Когда срабатывает эта ветка
|
||
|
||
Триггеры, которые бот узнаёт как реплики ветки `reschedule`:
|
||
|
||
- «я сегодня не смогу подойти», «не получится прийти на приём», «не смогу быть в назначенное время»;
|
||
- «перенесите запись на другой день», «можно перенести на вечер?»;
|
||
- «отмените мой визит на завтра», «снимите запись», «удалите запись»;
|
||
- «мне отменили приём, что делать?» — это особый подвид (отмена со стороны клиники, см. ниже).
|
||
|
||
Ключевой признак: пациент говорит, что **не придёт** или хочет **поменять время** — значит запись уже была сделана ранее. Если пациент хочет записаться впервые или на новый приём, это `new_booking`.
|
||
|
||
## Что бот должен собрать у пациента
|
||
|
||
Минимальный набор данных, чтобы администратор мог найти и обработать запись:
|
||
|
||
- ФИО пациента, на кого оформлена запись (особенно если пишет родственник).
|
||
- Дата и время текущей записи.
|
||
- Врач или специальность (если пациент помнит).
|
||
- Что хочет — отменить или перенести.
|
||
- Если хочет перенести — желаемый интервал нового времени: «утро / день / вечер», «будни / выходные», конкретные дни. **Конкретные слоты бот не подтверждает** — реальный календарь к ветке не подключён.
|
||
- Контактный телефон для подтверждения, если он отличается от номера, с которого пишет пациент.
|
||
|
||
Если пациент изначально написал кратко («не приду сегодня»), нужно мягко уточнить хотя бы ФИО и время — без этого администратор не найдёт запись в Полимеде.
|
||
|
||
## Базовое поведение бота
|
||
|
||
1. Извинение за неудобство одной короткой фразой («Понимаю, планы меняются»).
|
||
2. Уточнение, какую именно запись надо изменить.
|
||
3. Уточнение — отмена или перенос.
|
||
4. Если перенос — желаемый интервал нового времени.
|
||
5. Финал: «Сейчас уточню расписание у администратора и вернусь с вариантами» (или «Передам ваш запрос администратору, он свяжется с вами для уточнения нового времени»).
|
||
|
||
Бот не называет конкретные новые даты и часы как доступные. Реальный календарь подключается отдельно, а до этого формулировка только обещающая.
|
||
|
||
## Готовые формулировки для отмены
|
||
|
||
Из шаблонов вики, минимально подогнанные под чат-формат:
|
||
|
||
- «Информацию получили, спасибо, что сообщили. Запись отменена. Если хотите подобрать другое удобное время — напишите, я передам администратору».
|
||
- «Запись на приём отменили. Чтобы перенести на другую дату и время — напишите желаемый интервал, и я передам администратору».
|
||
- «Запись на приём удалена. Хотели бы перенести её на другой день?» (после ответа «нет» на напоминание о приёме).
|
||
|
||
Главное в формулировке — благодарность за то, что предупредили (а не просто «не пришёл»), и предложение перенести.
|
||
|
||
## Готовые формулировки для переноса
|
||
|
||
- «Хорошо, перенесу — подскажите желаемый день и время, чтобы я передал администратору. Конкретное время он подтвердит сам».
|
||
- «Понял, передам администратору, что нужен перенос с {старая_дата} на {желаемый_интервал}. Он свяжется с вами в течение дня и подтвердит новое время».
|
||
- Если пациент не определился с новым временем: «Без проблем, давайте сделаем так — отменим текущий приём, а когда захотите подобрать новое время, напишите сюда. Я передам администратору».
|
||
|
||
Стандартная фраза-резерв (пока нет интеграции с календарём): «Сейчас уточню у администратора и вернусь с вариантами».
|
||
|
||
## Особые ситуации
|
||
|
||
### Отмена со стороны клиники (пациенту отменили приём)
|
||
|
||
Триггеры: «мне отменили приём», «врач отменил смену», «клиника прислала, что приёма не будет».
|
||
|
||
Ситуация: смена врача отменилась по объективной причине. Из вики, шаблон-уведомление: «По объективным причинам рабочая смена у доктора отменена. Приносим извинения и предлагаем перенести приём на другое удобное время. Свяжитесь с нами по телефону (342) 207-03-03 для уточнения новой даты».
|
||
|
||
Поведение бота: подтвердить факт, извиниться от лица клиники, предложить перенести. Если пациент раздражён — `[INTENT_CHANGE: escalate_human]` с `reason=angry` или `explicit_request`.
|
||
|
||
### Пациент заболел перед операцией
|
||
|
||
Триггеры: «мне завтра операция, но я заболел», «температура перед операцией».
|
||
|
||
Поведение бота: подтвердить, что в этой ситуации операция переносится. Цитата из вики: «Доктор решение о проведении операции принимает после осмотра ребёнка перед операцией. Необходимо подойти, сообщить доктору жалобы. Он посмотрит, если пациент болен, перенесёт операцию, назначит лечение».
|
||
|
||
То есть пациент всё равно приезжает в день операции — врач осматривает и решает. Если пациент хочет отменить заранее (за день, за два) — это уже `escalate_human` с `reason=surgery`, потому что отмена операции — не рутинный перенос, тут участвует и хирург, и анестезиолог, и предоперационная подготовка.
|
||
|
||
### Опоздание на текущий приём
|
||
|
||
Триггеры: «я опаздываю на 10 минут», «застрял в пробке, успею к 16:00 вместо 15:30».
|
||
|
||
В вики прямого правила «допустимое опоздание» нет. Поведение бота: поблагодарить за предупреждение, передать в чат администраторам, чтобы держали место. Если опоздание серьёзное (>20–30 минут) и непонятно, успевает ли пациент — мягко предупредить, что администратор может предложить перенос на другое время. Если пациент уверенно говорит «доеду» — фиксируем как «опоздание, держим запись».
|
||
|
||
Технически это пограничный случай между `reschedule` и обычным служебным сообщением. Если бот видит фразу «опоздаю», по умолчанию остаётся в `reschedule` — администратор всё равно решает, держать запись или переносить.
|
||
|
||
### Запрос на перенос к конкретному врачу с ограниченным расписанием
|
||
|
||
Триггеры: упоминание Ворончихиной Н. В., сурдологов, врача в отпуске.
|
||
|
||
Из вики: запись к Ворончихиной Н. В. ведётся **только через лист ожидания**; сурдологов записывают надолго вперёд, есть лист ожидания «вдруг освободится». Если пациент хочет перенести приём у такого врача на более раннюю дату — честно сказать: «Запись к {врач} ведётся через лист ожидания. Я передам администратору, он внесёт вас в лист и свяжется, когда появится подходящее окно».
|
||
|
||
Особый случай — Лебединская Е. А.: запись и переносы ведёт только её личный ассистент Медведева Н. В. Бот в этом случае собирает данные и передаёт.
|
||
|
||
### Перенос приёма по ДМС
|
||
|
||
Триггеры: «у меня запись по ДМС, нужно перенести».
|
||
|
||
Логика: сама запись в системе переносится администратором как обычно. Особенность — гарантийное письмо страховой может иметь срок действия. Из вики: в гарантийном письме указан срок (для Адониса — 30 дней с даты исходящего), и если новая дата не укладывается, пациенту нужно запросить новое гарантийное письмо в страховой. Бот в чате об этом мягко предупреждает: «При переносе по ДМС обратите внимание — у гарантийного письма страховой есть срок действия. Если новая дата за пределами срока, нужно будет запросить у страховой новое письмо. Администратор уточнит детали при подтверждении переноса».
|
||
|
||
### Пациент хочет перенести, но фактически рассказывает про другую жалобу или запись
|
||
|
||
Триггеры: «не пойду к ЛОРу — лучше запишите к сурдологу», «отмените приём, и хочу записаться к аллергологу».
|
||
|
||
Это уже `new_booking` — `[INTENT_CHANGE: new_booking]`. Старую запись можно зафиксировать слотом «отменить» в реплике перед переключением, но всю сборку нового приёма ведёт ветка `new_booking`.
|
||
|
||
## Когда переключать в другие ветки
|
||
|
||
- Острая боль, кровотечение, высокая температура → `[INTENT_CHANGE: escalate_human]` с `reason=acute_pain`. Перенос подождёт — пациента сначала надо вывести из острой ситуации.
|
||
- Упоминание операции, наркоза, стационара → `[INTENT_CHANGE: escalate_human]` с `reason=surgery`. Касается и записи на операцию, и переноса операции.
|
||
- Пациент явно злится из-за отмены/переноса (включая отмену со стороны клиники) → `[INTENT_CHANGE: escalate_human]` с `reason=angry`.
|
||
- Пациент спрашивает «вернёте ли деньги», «штраф за неявку» → `[INTENT_CHANGE: price_question]` (там должен быть отдельный блок про возвраты, см. датасет `price_question.md`).
|
||
- Пациент решил записаться на новый приём, не связанный со старым → `[INTENT_CHANGE: new_booking]`.
|
||
|
||
## Чего бот НЕ делает в этой ветке
|
||
|
||
- Не подтверждает конкретные новые слоты («во вторник в 14:00») как доступные. Расписание уточняет администратор.
|
||
- Не отменяет реальную запись в Полимеде. Бот собирает данные и передаёт в чат «Администраторы». Реальное действие — на стороне человека.
|
||
- Не озвучивает штрафов, неустойки за неявку. В вики таких правил нет, см. раздел «Что нужно дополнить».
|
||
- Не обсуждает медицинскую тему — если пациент по ходу переноса жалуется на симптомы, это не повод уходить в `medical_question`. Жалоба фиксируется только если она объясняет причину переноса (например, «перенесите, у меня температура» — это не диагноз, это причина).
|
||
- Не переадресует на конкретный внутренний добавочный — пациенту озвучивается только основной номер клиники: 8 (342) 207-03-03 (КУГН), 8 (342) 200-02-03 (Г. Звезда), 8 (342) 207-03-00 (Пирогов).
|
||
|
||
## Контекст: как клиника обычно узнаёт об отмене
|
||
|
||
Это нужно боту скорее как фон, чтобы понимать поведение пациентов:
|
||
|
||
- За 4 часа до приёма пациент получает автоматическое напоминание в WhatsApp (утренние приёмы — с вечера). В Полимеде у администратора это отображается «зелёным квадратиком».
|
||
- Пациент отвечает «да» (придёт) или «нет» (отменяет).
|
||
- При «нет» запись в системе удаляется, пациенту предлагают перенести.
|
||
- Если пациент пишет «перенести», это уже не автоматическая отмена — оператор перезванивает по телефону.
|
||
|
||
Поэтому, когда бот отвечает на отмену, имеет смысл предлагать перенос сразу — это типовой сценарий «нет → давайте на другой день».
|
||
|
||
## Связанные практики (для контекста)
|
||
|
||
- **Лист ожидания** — отдельная сущность в Полимеде. Пациента вносят, если: запись к врачу полная, врач в отпуске, к врачу записывают только через лист ожидания (Ворончихина Н. В., сурдологи). Бот в ветке `reschedule` упоминает лист ожидания, только когда пациент явно хочет на конкретного врача с ограниченным расписанием. В обычном переносе про лист ожидания не говорим — это создаёт лишнее ощущение «у вас всё плохо со слотами».
|
||
- **Заявка операторам** — внутренний механизм у администраторов. Бот в чате воспроизводит этот механизм неявно: собирает в реплику пациента всю информацию, которая нужна по шаблону «ФИО, какой врач, со скольки до скольки, что делать с освободившимся временем». Сам пациент эту структуру не видит — для него это обычный диалог.
|
||
|
||
## Что нужно дополнить вручную в вики
|
||
|
||
В выгрузке вики не нашлись и должны быть явно прописаны:
|
||
|
||
- **Граница «за сколько часов до приёма можно перенести / отменить без последствий».** Сейчас бот отвечает обтекаемо. Если в клинике де-факто есть правило (например, «за 24 часа») — его нужно прописать в вики и в этот датасет.
|
||
- **Штрафы / удержание депозита за неявку.** Явных правил нет. Если для отдельных случаев (операции, дорогие диагностики) есть условия удержания части предоплаты при поздней отмене — описать.
|
||
- **Возврат предоплаты за операцию при отмене.** Сценарий «пациент внёс предоплату или организация перевела по 3-стороннему договору, а операция отменилась» — в вики есть только описание прихода денег, нет описания возврата.
|
||
- **Регламент «сколько раз пациент может перенести подряд».** В реальности бывают пациенты, которые переносят 3+ раза. Если есть внутренний регламент (например, «третий перенос подряд = в лист ожидания»), пропишите.
|
||
- **Опоздание.** Есть ли допустимый порог («15 минут — держим запись, больше — переносим»)? В вики не нашёл.
|
||
- **Отмена приёма, оплаченного по подарочному сертификату.** Сертификаты есть, но что с ними при переносе/отмене — не описано.
|
||
- **Перенос приёма за ребёнка с другого законного представителя.** Стандартная история «приёмы ребёнка переносит мама, но в день приёма пришёл папа, а сейчас пишет бабушка». Нужны правила, кто и как может вносить изменения.
|
||
|
||
## Что НЕ должно попадать в датасет ветки `reschedule` (но есть в вики)
|
||
|
||
- Внутренние операционные подробности Полимеда (как именно администратор удаляет запись «минусом», как создаётся лист ожидания, как ставится статус «придёт»). Это для администраторов, не для пациентов.
|
||
- Внутренние добавочные номера сотрудников и врачей.
|
||
- Логины и пароли.
|
||
- Полные операторские скрипты записи (`skript-zapisi-...`) — структура «6 этапов» не для бота, у бота — лаконичный диалог.
|
||
- Цены (попадают в `price_question`).
|
||
- Адреса, режим работы, контакты в подробном виде (попадают в `general_info`).
|
||
|
||
## Источники и приоритет
|
||
|
||
При расхождении инструкций операторов из вики и логики бота — приоритет у бота:
|
||
|
||
- Бот не должен симулировать поведение человека-администратора (звонок пациенту, удаление в Полимеде, открытие чата). Бот действует асинхронно: пациент пишет в чат, бот собирает данные и обещает связь.
|
||
- Если в скрипте оператора написано «оператор перезванивает по телефону для переноса» — бот эту фразу адаптирует в «администратор свяжется с вами в течение дня и подтвердит новое время».
|
||
|
||
Прежние сводные документы (`skripty-vozrazhenija-chavo-obshhijj-spravochnik.md`, `vrachi-kliniki-polnaja-informacija.md`) для этой ветки не источник. После подключения подписки на живую вики они должны быть полностью отвязаны от индекса ветки `reschedule`.
|