feat(sprint8b): регрессия ответов веток · general_info + фикс PRAGMA foreign_keys

Параллель к 8a, но проверяем не код intent от роутера, а содержимое ответа
конкретной ветки на одиночную реплику. Старт — general_info, 46 кейсов.

Логика pass/fail (для одного кейса):
- A — RAG-секция: среди retrieved-чанков есть кусок с
  section == expected_doc_section (точное совпадение). Если поле не задано —
  пропускаем.
- B — keywords: обязательные expected_keywords встречаются в predicted_answer
  (case-insensitive). По умолчанию все; поддерживаются keywords_min: N
  и keywords_any: true. Запрещённые expected_must_not — ни одного.
- Pass = A ∧ B. Незаданные поля не проверяются.
- Кэш: (text_hash, branch_config_id) → {answer_text, retrieved_sections}.
  Привязан к версии промпта ветки. Смена версии = пустой кэш = свежий прогон.
  Правка JSONL без изменения text → pass/fail пересчитывается без LLM.

Backend:
- Таблицы eval_branch_runs / eval_branch_run_cases / eval_branch_predictions.
  Миграция m9g1f7e89j56.
- services/eval_branch_run_service.py: загрузка JSONL, фоновый прогон через
  asyncio.create_task, кэш, оценка A+B с поддержкой keywords_min/keywords_any.
- chat_service.run_branch_single_turn — изолированный single-turn без
  роутера и треда (использует существующий config_service + vectorstore + llm).
- API: POST /eval/branch-runs, GET /eval/branch-runs?intent_code=,
  GET /eval/branch-runs/{id}, GET /eval/branch-cases-with-status?intent_code=.

UI (static/regression.html):
- Селектор режима «Роутер / Ветка · general_info». Логика пикера переиспользуется
  (фильтры, диапазон, массовый выбор, счётчик «новые / в кэше»).
- Для режима «Ветка»: фильтр по coverage, колонки секция/coverage, keywords,
  частота, кэш. Drill-down прогона: ожидание, retrieved-секции, причины fail,
  полный ответ ветки.

База кейсов (eval/branch_cases_general_info.jsonl) — от пользователя, 46 кейсов
по схеме {text, intent, coverage, expected_doc_section?, expected_keywords?,
expected_must_not?, keywords_min?, keywords_any?, count?, note?}.

Связанная правка SQLite (нашли при удалении документа в этом спринте):
- db/session.py: connect-listener PRAGMA foreign_keys=ON на каждое подключение.
  Без этого ondelete=CASCADE в SQLite не enforced, и удаление документа
  оставляло подписки в intent_documents висячими (что давало пустой RAG
  и fail регрессии).
- Миграция n0h2g8f9a0k67 — одноразовая чистка существующих висячих подписок.

docs/SPRINTS.md: Спринт 8b →  Закрыт. Diff vs предыдущий прогон для веток
и кнопка «Сбросить кэш регрессии» вынесены в docs/BACKLOG.md.

Также включены обновлённые data/datasets/general_info.md и price_question.md
(рабочий материал оператора), и черновик eval/branch_cases_price_question.jsonl
для следующего захода (8b на price_question).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
AR 15 M4
2026-05-03 01:20:59 +05:00
parent a8f7e68795
commit bb5e3f5eb3
15 changed files with 1228 additions and 109 deletions
+7 -17
View File
@@ -10,8 +10,9 @@ sources:
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/operacionnye-vmeshatelstva/*
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/diagnostika/*
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/kt-issledovanija/*
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/klinika-doktora-pirogova/*
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/klinika-doktora-pirogova/* (исторический источник; филиал закрыт в 2026 году, прайс из активной части датасета убран)
- Ya_wiki_kugn/out/yandex-wiki-catalog/homepage/udalennyjj-kontakt-centr/organizacionnye-voprosy/zapis-k-otonevrologu/blokada/*
- Уточнения от оператора (Кузнецова Н.) — 2026-05-02: закрытие филиала Пирогова в Краснокамске.
note: Цены собраны из выгрузки Yandex Wiki клиники. После запуска подписки этот файл заменит автоматически обновляемый источник. Все суммы — рубли.
---
@@ -59,20 +60,9 @@ note: Цены собраны из выгрузки Yandex Wiki клиники.
- Батарейки для слухового аппарата — 360 руб. за упаковку из 6 шт. (поштучно не продаются).
- Если аппарат куплен в Клинике и сломался: после окончания гарантии — приём у сурдолога; устранимая поломка (замена расходников) — стоимость расходников. Серьёзная поломка — отправка в ремонт, стоимость указывает сервис в счёте.
## Клиника доктора Пирогова (Краснокамск)
## Филиал «Клиника доктора Пирогова» (Краснокамск)
- Семейный врач (Суднева А. Р.): 950 руб. первичный, 750 руб. повторный. Эндоскопия ЛОР-органов на приёме — 500 руб.
- ЛОР-телемедицинский приём: 1700 руб. первичный, 1400 руб. повторный. Включает консультацию ЛОР-врача и видеоэндоскопию.
- Аллерголог-иммунолог (телемед, Антонова Е. В.): 1800 руб. первичный, 1500 руб. повторный.
- ЛОР-приём по ОМС (Гилязова Л. Л., вт/чт 12:00–14:00) — бесплатно, по направлению.
- Дерматолог (Чемякин Е. А.): консультация 1000 руб. + услуги по прайсу.
- Косметолог-эстетист — услуги по прайсу.
- УЗИ — услуги по прайсу. Доплерография при двойне (срок беременности до 30 недель) — ориентировочно 1800 руб.
- ЭКГ — 450 руб., расшифровка/повторный приём — 800 руб.
- Профосмотр — 450 руб. (+390 руб. за аудиометрию, если требуется).
- Промывание серных пробок — 550 руб. за одно ухо.
- Тест на хеликобактер с индикаторными трубками — 500 руб.
- Инъекции в процедурном кабинете: внутримышечная — 150 руб., внутривенная — 300 руб., капельница внутривенная — 500 руб. Курсы: 5 в/м инъекций — 600 руб., 7 — 850 руб., 10 — 1150 руб. 5 в/в инъекций — 1200 руб., 7 — 1700 руб.
Филиал в Краснокамске закрыт в 2026 году. Все услуги, ранее доступные там (приём семейного врача, телемед-приёмы ЛОР и аллерголога, ЛОР по ОМС, дерматолог, косметолог, УЗИ, ЭКГ, профосмотр, инъекции в процедурном кабинете, промывание серных пробок 550 ₽ и т. п.), в сети больше не оказываются. На вопросы о ценах услуг этого филиала — честно сообщить, что филиал закрыт, и предложить услуги пермских филиалов (Цеткин и Газеты Звезда), либо эскалировать оператору.
## Эндоскопическая телемед-консультация ЛОР (онлайн-формат)
@@ -80,7 +70,7 @@ note: Цены собраны из выгрузки Yandex Wiki клиники.
## Стандартные диагностические процедуры
- Эндоскопическая диагностика ЛОР-органов — 900 руб. (в Клинике Пирогова — 500 руб.).
- Эндоскопическая диагностика ЛОР-органов — 900 руб.
- Аудиометрия — 1200 руб.
- Тимпанометрия — 800 руб.
- Аудиологический скрининг (отоакустическая эмиссия) — 800 руб.
@@ -270,7 +260,7 @@ note: Цены собраны из выгрузки Yandex Wiki клиники.
## Что покрыто из выгрузки уверенно
- Цены на приёмы у ЛОР, аллерголога, пульмонолога, отоневролога, сурдолога, врачей Клиники Пирогова, телемед-приёмов.
- Цены на приёмы у ЛОР, аллерголога, пульмонолога, отоневролога, сурдолога, телемед-приёмов.
- Скидка 50% по направлению, цена приёма «со скидкой».
- Полный набор стоимостей операций ЛОР-профиля.
- Анестезия, пребывание в палате, послеоперационное сопровождение.
@@ -287,7 +277,7 @@ note: Цены собраны из выгрузки Yandex Wiki клиники.
- **Справка ФНС / налоговый вычет.** Раздел в вики есть, но в выгрузке отсутствует. Нужен короткий блок: за какой период оформляется, сколько по времени готовится, нужна ли оплата за услугу.
- **СБП.** Уточнить, принимается ли оплата через Систему быстрых платежей или только нал/карта по терминалу.
- **Скидки.** В выгрузке только «50% по направлению на лечебную процедуру». Если есть скидки пенсионерам, многодетным, сотрудникам, постоянным пациентам — отдельно прописать; иначе при вопросе ассистент будет каждый раз говорить «уточню у оператора».
- **Цены по «услугам по прайсу» в Пирогове.** В таблице у дерматолога, косметолога, УЗИ написано «по прайсу» — конкретные цифры в подстраницах есть только частично. Нужно собрать прайсы в одну таблицу.
- **Услуги, бывшие только в Пирогова.** После закрытия филиала из активного датасета убраны: цены семейного врача, телемед-приёма ЛОР/аллерголога, дерматолога, косметолога, УЗИ, ЭКГ, профосмотра, инъекций в процедурном кабинете, промывания серных пробок (550 ₽). Если эти услуги планируется оказывать в пермских филиалах — нужно явно прописать новые прайсы; иначе бот честно отвечает «филиал закрыт» и эскалирует.
- **Расхождение по наркозу для аденотомии.** В разделе «Структура звонка по аденотомии» (скрипты записи) указана стоимость наркоза 16500 руб., а на странице самой аденотомии — 21500 руб. Возможно, это устаревшая цена в одном из источников. Нужно сверить с актуальным прайсом и поправить в вики, иначе ассистент будет давать разные ответы в зависимости от того, какой кусок выгрузки попадёт в контекст.
- **Цена аллерголога-иммунолога повторного приёма (очный).** В выгрузке указана стоимость только первичного очного приёма (2400 руб.). Для пульмонолога и ЛОРа повторный тоже отдельно не зафиксирован.
- **Эндоскопия как самостоятельная диагностика.** На странице эндоскопии есть две цены — 900 руб. и 12100 руб., вторая выглядит как опечатка или комплексный код. В этом файле я взял 900 руб. как основное; стоит сверить с прайсом.