Files
RAG_helper/prompts/intents/new_booking/steps/book.md
T
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

3.6 KiB

Шаг «Подтверждение и контакт» (book)

Задача: одной репликой проговорить план («записываю к {specialist}») и в той же реплике запросить телефон + имя. Это последний шаг до закрытия.

Скрипт

  1. Подтверждение плана — одна короткая фраза с использованием уже собранных слотов:

    • Взрослый, есть жалоба: «Хорошо, записываю к {specialist} — на приёме врач уделит внимание тому, что вас беспокоит ({reason}).»
    • Взрослый, без жалобы (пациент сразу пришёл записываться): «Хорошо, записываю к {specialist}.»
    • Ребёнок: «Хорошо, записываю ребёнка к {specialist}.» Если из истории сообщений известно имя ребёнка — упомяни его естественно.
  2. Запрос контакта — в той же реплике, без отдельного шага:

    • «Чтобы администратор связался и подтвердил время — напишите, пожалуйста, ваш номер телефона и как к вам обращаться.»
    • Если пациент уже называл имя (есть в истории сообщений) — не переспрашивай, проси только телефон: «Чтобы администратор связался — напишите номер телефона.»
    • При записи ребёнка — phone это телефон родителя (того, кто пишет), и обращайся к нему: «как к вам обращаться?» Если legal_rep_phone уже собран на qualify — используй его и не спрашивай повторно.
  3. При получении контакта — закрывающая фраза + state_after: close:

    • «Спасибо. Передаю заявку администратору, он свяжется с вами по номеру {phone}.»

Что зафиксировать в слотах

  • phone — контактный телефон пациента (или родителя при is_child).
  • name — обращение к собеседнику (если ещё не было собрано).
  • confirmedtrue после получения телефона (это и есть «подтверждение»).

Особые случаи

  • Пациент хочет поправить специалиста / повод перед тем, как назвать телефон → state_after: qualify.
  • Пациент отказался дать телефон («только в чате», «не дам номер») — мягко объясни: «Без номера администратор не сможет подтвердить запись. Если не готовы — могу передать заявку оператору, и он свяжется иначе». При повторном отказе → [INTENT_CHANGE: escalate_human].

Переход:

  • Получены phonename, если ещё не было) → state_after: close, slots_updated: {"confirmed": true, "phone": "...", "name": "..."}.
  • Пациент возвращается к выбору специалиста / повода → state_after: qualify.