From 9b78a5a1bb2820ae16ad59efce085f58e041dc28 Mon Sep 17 00:00:00 2001 From: Maksim Totmin Date: Tue, 23 Jun 2026 10:41:45 +0700 Subject: [PATCH] first commit --- .gitignore | 2 + README.md | 60 ++ see_asserts.json | 2009 ++++++++++++++++++++++++++++++++++++++++++++ smc_asserts.json | 237 ++++++ test_see_models.py | 374 +++++++++ test_smc_models.py | 202 +++++ 6 files changed, 2884 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 see_asserts.json create mode 100644 smc_asserts.json create mode 100644 test_see_models.py create mode 100644 test_smc_models.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a60b85 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +__pycache__/ +*.pyc diff --git a/README.md b/README.md new file mode 100644 index 0000000..02fad36 --- /dev/null +++ b/README.md @@ -0,0 +1,60 @@ +# SEE/SMC Autotests + +Набор тестов для проверки моделей **SEE** (Semantic Entity Extraction) и **SMC** (Short Message Classification) после обновления. + +## Файлы + +| Файл | Назначение | +|------|-----------| +| `test_see_models.py` | Тест всех моделей SEE (entity + classifier) | +| `test_smc_models.py` | Тест всех моделей SMC (classifier) | +| `see_asserts.json` | Ожидаемые проверки для SEE (опционально) | +| `smc_asserts.json` | Ожидаемые проверки для SMC (опционально) | + +## Использование + +### Без проверок (только непустой ответ) + +```bash +python3 test_see_models.py +python3 test_smc_models.py +``` + +### С проверками по asserts + +```bash +python3 test_see_models.py --asserts see_asserts.json +python3 test_smc_models.py --asserts smc_asserts.json +``` + +### Другой сервер + +```bash +python3 test_see_models.py --host 10.101.60.27 --port 6184 +python3 test_smc_models.py --host 10.101.60.27 --port 6181 +``` + +## Формат asserts + +```json +{ + "asserts": [ + { + "model": "fio", + "text": "Иванов Иван Иванович", + "checks": { + "min_found": 1, + "text_contains": "иван", + "confidence_min": 0.3 + } + } + ] +} +``` + +- `model` — имя модели (подстрока для поиска) +- `text` — текст для запроса (опционально) +- `min_found` — минимальное количество найденных сущностей/классов +- `text_contains` — подстрока в тексте/классе первой сущности +- `calculated_contains` — подстрока в `calculated` (только entity) +- `confidence_min` — минимальный confidence diff --git a/see_asserts.json b/see_asserts.json new file mode 100644 index 0000000..a7a2090 --- /dev/null +++ b/see_asserts.json @@ -0,0 +1,2009 @@ +{ + "_format": "Entity/classifier checks для SEE. min_found/min_classes=0 для вариантов.", + "asserts": [ + { + "model": "Начало диалога-planned", + "text": "здравствуйте", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "other_payment-planned", + "text": "мобилизационные выплаты", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап областной~4f2d37c9a020797ba3151b7814303264", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "new_minsoc_subsidii-planned", + "text": "субсидия на жкх", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Да-Нет-Повтор~ffb403fff9f5802d53aac8a5c844af26", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday~4f2d37c9a020797ba3151b7814303264", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Мои талоны~4f2d37c9a020797ba3151b7814303264", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Мои талоны~081406f0904c707cf068a6fbb8f249bb", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "see_grade", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "operatorcheck-planned", + "text": "соедините с оператором", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Отказ от оценки-new", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "service_mfc_see~bf505da3280184027363ec7349c0e6fc", + "text": "хочу получить водительское удостоверение", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания-new", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "offices_mfc_see", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Маткап федеральный~081406f0904c707cf068a6fbb8f249bb", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Количество услуг-planned", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Мои талоны", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Типы граждан-new", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы выплат~4f2d37c9a020797ba3151b7814303264", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filial", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "zags_handler", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "new_minsoc_subsidii-new", + "text": "субсидия на жкх", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы выплат", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Статусы ЕПГУ", + "text": "проверить статус заявления", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "fio2-planned", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап федеральный-planned", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags-planned", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Дни недели", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Повтор-new", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Без уточнения возраста для заграна~4f2d37c9a020797ba3151b7814303264", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Тип загранпаспорта~bf505da3280184027363ec7349c0e6fc", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "yesno-new", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "nsk_fillials-backup", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код-planned", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "yesno-planned", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "new_trud-planned", + "text": "потерял работу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап областной-planned", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Статусы ЕПГУ~4f2d37c9a020797ba3151b7814303264", + "text": "проверить статус заявления", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "new_minsoc_subsidii", + "text": "субсидия на жкх", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Начало диалога~081406f0904c707cf068a6fbb8f249bb", + "text": "здравствуйте", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы граждан-planned", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Без уточнения возраста для заграна", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "nsk_fillials~4f2d37c9a020797ba3151b7814303264", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "end_repeat-new", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "end_repeat", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Заглушка-planned", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Да-Нет-Повтор~4f2d37c9a020797ba3151b7814303264", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Дни недели-planned", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Да-Нет-Повтор~bf505da3280184027363ec7349c0e6fc", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Паспорт-planned", + "text": "хочу получить паспорт", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Пособие по рожд и воспит", + "text": "пособие по рождению", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Паспорт", + "text": "хочу получить паспорт", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Повтор", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Маткап областной-new", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filials_mfc_see-planned", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна-planned", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания~ffb403fff9f5802d53aac8a5c844af26", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап областной", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_date-planned", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date-backup~4f2d37c9a020797ba3151b7814303264", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday-planned", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код~ffb403fff9f5802d53aac8a5c844af26", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2~ffb403fff9f5802d53aac8a5c844af26", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "7" + } + }, + { + "model": "yesno_obzv-planned", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы выплат-new", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы граждан~4f2d37c9a020797ba3151b7814303264", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Отказ от оценки-new~4f2d37c9a020797ba3151b7814303264", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Количество услуг-backup~4f2d37c9a020797ba3151b7814303264", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Отказ от оценки-new~ffb403fff9f5802d53aac8a5c844af26", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств~bf505da3280184027363ec7349c0e6fc", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств-planned", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "new_trud-new", + "text": "потерял работу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Тип загранпаспорта", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "конкретика режим работы~4f2d37c9a020797ba3151b7814303264", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств~081406f0904c707cf068a6fbb8f249bb", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Пособие по рожд и воспит-new", + "text": "пособие по рождению", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "end_repeat-planned", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Без уточнения возраста для заграна~bf505da3280184027363ec7349c0e6fc", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Паспорт-new", + "text": "хочу получить паспорт", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы выплат-planned", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "operatorcheck", + "text": "соедините с оператором", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Да-Нет-Повтор~081406f0904c707cf068a6fbb8f249bb", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "fio2-backup", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "see_grade-planned", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Суперсервис Рождение ребенка", + "text": "рождение ребенка", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "fio2~bf505da3280184027363ec7349c0e6fc", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "mobilizac", + "text": "мобилизационные", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Исключение других ведомств-backup~ffb403fff9f5802d53aac8a5c844af26", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date-backup", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time~bf505da3280184027363ec7349c0e6fc", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filials_mfc_see~bf505da3280184027363ec7349c0e6fc", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Количество услуг~bf505da3280184027363ec7349c0e6fc", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Лаврентьевская карта НСО", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Да-Нет-Повтор", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Типы выплат~ffb403fff9f5802d53aac8a5c844af26", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time~4f2d37c9a020797ba3151b7814303264", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Несогласие клиента~4f2d37c9a020797ba3151b7814303264", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна~4f2d37c9a020797ba3151b7814303264", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Конкретика Фонд ЖКХ~ffb403fff9f5802d53aac8a5c844af26", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Заглушка-backup", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "конкретика режим работы~ffb403fff9f5802d53aac8a5c844af26", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Паспорт~bf505da3280184027363ec7349c0e6fc", + "text": "хочу получить паспорт", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Несогласие клиента-planned", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Начало диалога~4f2d37c9a020797ba3151b7814303264", + "text": "здравствуйте", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Суперсервис Рождение ребенка~ffb403fff9f5802d53aac8a5c844af26", + "text": "рождение ребенка", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "offices_mfc_see-planned", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "fio2", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "иван" + } + }, + { + "model": "Суперсервис Рождение ребенка~4f2d37c9a020797ba3151b7814303264", + "text": "рождение ребенка", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Статусы ЕПГУ~ffb403fff9f5802d53aac8a5c844af26", + "text": "проверить статус заявления", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Да-Нет-Повтор-planned", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код~081406f0904c707cf068a6fbb8f249bb", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы граждан", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Количество услуг", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "matcap_direct-planned", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Несогласие клиента~ffb403fff9f5802d53aac8a5c844af26", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "yesno", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Количество услуг~4f2d37c9a020797ba3151b7814303264", + "text": "сколько у меня талонов", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "offices_mfc_see~bf505da3280184027363ec7349c0e6fc", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Повтор-planned", + "text": "все, до свидания", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "mobilizac-new", + "text": "мобилизационные", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Заглушка", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_date~bf505da3280184027363ec7349c0e6fc", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания~4f2d37c9a020797ba3151b7814303264", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "service_mfc_see~4f2d37c9a020797ba3151b7814303264", + "text": "хочу получить водительское удостоверение", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags_handler-planned", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Несогласие клиента~081406f0904c707cf068a6fbb8f249bb", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания~081406f0904c707cf068a6fbb8f249bb", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания-planned", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2-planned", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Лаврентьевская карта НСО~081406f0904c707cf068a6fbb8f249bb", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "new_trud", + "text": "потерял работу", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Отказ от оценки~081406f0904c707cf068a6fbb8f249bb", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код-new", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Тип загранпаспорта~4f2d37c9a020797ba3151b7814303264", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Начало диалога", + "text": "здравствуйте", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "other_payment", + "text": "мобилизационные выплаты", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "конкретика режим работы-new", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags~ffb403fff9f5802d53aac8a5c844af26", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filial-new", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday~081406f0904c707cf068a6fbb8f249bb", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags-backup~ffb403fff9f5802d53aac8a5c844af26", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filial-planned", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "yesno_obzv", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Да-Нет~ffb403fff9f5802d53aac8a5c844af26", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "конкретика режим работы~bf505da3280184027363ec7349c0e6fc", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "конкретика режим работы~081406f0904c707cf068a6fbb8f249bb", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Статусы ЕПГУ-new~ffb403fff9f5802d53aac8a5c844af26", + "text": "проверить статус заявления", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств~4f2d37c9a020797ba3151b7814303264", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Несогласие клиента~bf505da3280184027363ec7349c0e6fc", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Лаврентьевская карта НСО-new", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": ":" + } + }, + { + "model": "other_payment-new", + "text": "мобилизационные выплаты", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Тип загранпаспорта-new", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2~4f2d37c9a020797ba3151b7814303264", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday~bf505da3280184027363ec7349c0e6fc", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "nsk_fillials", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Маткап федеральный", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_date~4f2d37c9a020797ba3151b7814303264", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Исключение других ведомств~ffb403fff9f5802d53aac8a5c844af26", + "text": "это не относится", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап федеральный~4f2d37c9a020797ba3151b7814303264", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна~bf505da3280184027363ec7349c0e6fc", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап федеральный-new", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Типы выплат~081406f0904c707cf068a6fbb8f249bb", + "text": "я гражданин россии", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Без уточнения возраста для заграна-planned", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Суперсервис Рождение ребенка-planned", + "text": "рождение ребенка", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Да-Нет-Повтор-new", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday~ffb403fff9f5802d53aac8a5c844af26", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Тип загранпаспорта-planned", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Маткап областной~081406f0904c707cf068a6fbb8f249bb", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "weekday", + "text": "в пятницу", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_date", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "2026" + } + }, + { + "model": "Лаврентьевская карта НСО~ffb403fff9f5802d53aac8a5c844af26", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "filials_mfc_see", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "zags_handler-new", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Статусы ЕПГУ-planned", + "text": "проверить статус заявления", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "конкретика режим работы-planned", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "matcap_direct", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Конкретика по УК~ffb403fff9f5802d53aac8a5c844af26", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Лаврентьевская карта НСО~4f2d37c9a020797ba3151b7814303264", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time-planned", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags~4f2d37c9a020797ba3151b7814303264", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна-backup", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Лаврентьевская карта НСО-planned", + "text": "лаврентьевская карта", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "rating_med", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "service_mfc_see-backup", + "text": "хочу получить водительское удостоверение", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "rating_med-planned", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Паспорт~4f2d37c9a020797ba3151b7814303264", + "text": "хочу получить паспорт", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "zags-backup", + "text": "загс центрального района", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2~bf505da3280184027363ec7349c0e6fc", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Вернуться в главное меню~ffb403fff9f5802d53aac8a5c844af26", + "text": "вернуться в главное меню", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "service_mfc_see-planned", + "text": "хочу получить водительское удостоверение", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "yesno_obzv-new", + "text": "да", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "mobilizac-planned", + "text": "мобилизационные", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "matcap_direct-new", + "text": "на улучшение жилищных условий", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Не знаю код~4f2d37c9a020797ba3151b7814303264", + "text": "не знаю код подразделения", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "оценка обслуживания~bf505da3280184027363ec7349c0e6fc", + "text": "пять", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "конкретика режим работы", + "text": "режим работы мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Несогласие клиента", + "text": "я не согласен", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Начало диалога~ffb403fff9f5802d53aac8a5c844af26", + "text": "здравствуйте", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "offices_mfc_see~4f2d37c9a020797ba3151b7814303264", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "service_mfc_see", + "text": "хочу получить водительское удостоверение", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "operatorcheck-new", + "text": "соедините с оператором", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Пособие по рожд и воспит-planned", + "text": "пособие по рождению", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "fio2-planned", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "nsk_fillials-backup", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "date", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "2026" + } + }, + { + "model": "number", + "text": "пятьсот двадцать три", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "523" + } + }, + { + "model": "nsk_fillials~4f2d37c9a020797ba3151b7814303264", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Заглушка-planned", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date-planned", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date-backup~4f2d37c9a020797ba3151b7814303264", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2~ffb403fff9f5802d53aac8a5c844af26", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "7" + } + }, + { + "model": "time", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": ":" + } + }, + { + "model": "fio2-backup", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "7" + } + }, + { + "model": "fio2~bf505da3280184027363ec7349c0e6fc", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date-backup", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time~bf505da3280184027363ec7349c0e6fc", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_time~4f2d37c9a020797ba3151b7814303264", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Возраст заявителя для заграна~4f2d37c9a020797ba3151b7814303264", + "text": "мне 25 лет", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "Заглушка-backup", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "fio2", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "иван" + } + }, + { + "model": "Заглушка", + "text": "тест", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "record_date~bf505da3280184027363ec7349c0e6fc", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "phone2-planned", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_time", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": ":" + } + }, + { + "model": "phone2~4f2d37c9a020797ba3151b7814303264", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "nsk_fillials", + "text": "родники", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "fio", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "иван" + } + }, + { + "model": "record_date~4f2d37c9a020797ba3151b7814303264", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "record_date", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "2026" + } + }, + { + "model": "record_time-planned", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "uuid", + "text": "550e8400-e29b-41d4-a716-446655440000", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "550e" + } + }, + { + "model": "phone2~bf505da3280184027363ec7349c0e6fc", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 0 + } + }, + { + "model": "date", + "text": "на завтра", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "2026" + } + }, + { + "model": "number", + "text": "пятьсот двадцать три", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "523" + } + }, + { + "model": "time", + "text": "в пять часов вечера", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": ":" + } + }, + { + "model": "phone", + "text": "8 913 456 78 90", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "calculated_contains": "7" + } + }, + { + "model": "fio", + "text": "Иванов Иван Иванович", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "иван" + } + }, + { + "model": "uuid", + "text": "550e8400-e29b-41d4-a716-446655440000", + "checks": { + "confidence_min": 0.1, + "min_found": 1, + "text_contains": "550e" + } + } + ] +} \ No newline at end of file diff --git a/smc_asserts.json b/smc_asserts.json new file mode 100644 index 0000000..5b2e552 --- /dev/null +++ b/smc_asserts.json @@ -0,0 +1,237 @@ +{ + "_format": "Массив asserts для SMC. Все модели типа classifier.", + "asserts": [ + { + "model": "МФЦ НСК~bf505da3280184027363ec7349c0e6fc", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК~ffb403fff9f5802d53aac8a5c844af26", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "филиалы 54_МФЦ-backup", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "mfc_test_old-backup", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "тест мфц нск-new", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК-backup~4f2d37c9a020797ba3151b7814303264", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК-backup", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "mfc_test_old", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "ekc_smc", + "text": "записаться в екц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "ekc_smc-backup", + "text": "записаться в екц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "minsoc_20_july", + "text": "какие выплаты от минсоца", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК-backup~081406f0904c707cf068a6fbb8f249bb", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "филиалы 54_МФЦ", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК-backup~ffb403fff9f5802d53aac8a5c844af26", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "ЕКЦ НСК~ffb403fff9f5802d53aac8a5c844af26", + "text": "записаться в екц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "offices_mfc", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "minsoc_20_july-backup", + "text": "какие выплаты от минсоца", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Техническая поддержка", + "text": "не работает компьютер", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Тест~ffb403fff9f5802d53aac8a5c844af26", + "text": "тестовое сообщение", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "филиалы 54_МФЦ~bf505da3280184027363ec7349c0e6fc", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК~4f2d37c9a020797ba3151b7814303264", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ НСК~081406f0904c707cf068a6fbb8f249bb", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "филиалы 54_МФЦ~4f2d37c9a020797ba3151b7814303264", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "ЕКЦ НСК-backup~ffb403fff9f5802d53aac8a5c844af26", + "text": "записаться в екц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ2-new", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "Тест-backup~ffb403fff9f5802d53aac8a5c844af26", + "text": "тестовое сообщение", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "МФЦ1", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + }, + { + "model": "филиалы 54_МФЦ-backup~bf505da3280184027363ec7349c0e6fc", + "text": "хочу записаться в мфц", + "checks": { + "confidence_min": 0.1, + "min_found": 1 + } + } + ] +} \ No newline at end of file diff --git a/test_see_models.py b/test_see_models.py new file mode 100644 index 0000000..f12032b --- /dev/null +++ b/test_see_models.py @@ -0,0 +1,374 @@ +#!/usr/bin/env python3 +"""SEE model autotest — проверяет все загруженные модели после обновления. + +Использование: + python3 test_see_models.py + python3 test_see_models.py --host 10.101.60.26 + python3 test_see_models.py --host 10.101.60.25 --port 6184 + python3 test_see_models.py --asserts see_asserts.json + +Файл ассертов (JSON): + { + "asserts": [ + { + "model": "fio", // подстрока для поиска модели + "type": "entity|classifier", + "text": "Иванов Иван Иванович", // текст для запроса + "checks": { + // для entity: + "min_found": 1, // мин. количество найденных сущностей + "text_contains": "иванов", // подстрока в text первой сущности + "calculated_contains": "Ф:", // подстрока в calculated + "confidence_min": 0.5, // мин. confidence + + // для classifier: + "min_classes": 1, // мин. количество классов + "top_class_contains": "Yes", // подстрока в top классе + "confidence_min": 0.5 // мин. confidence топ-класса + } + } + ] + } + +Возвращает exit code 0 если все модели прошли, иначе 1. +""" + +import argparse +import json +import os +import sys +import unittest +from urllib.parse import quote + +try: + import urllib.request as urlreq + import urllib.error as urlerr +except ImportError: + urlreq = None + +DEFAULT_HOST = "10.101.60.25" +DEFAULT_PORT = 6184 +BASE_PATH = "/see" + +PRETRAINED_TESTS = { + "fio": {"text": "Иванов Иван Иванович", "hint": "ФИО"}, + "phone": {"text": "8 913 456 78 90", "hint": "телефон"}, + "number": {"text": "пятьсот двадцать три", "hint": "число"}, + "date": {"text": "на завтра", "hint": "дата"}, + "uuid": {"text": "550e8400-e29b-41d4-a716-446655440000", "hint": "UUID"}, + "time": {"text": "в пять часов вечера", "hint": "время"}, +} + +HANDLER_TESTS = { + "fio2": {"text": "Иванов Иван Иванович", "type": "entity"}, + "phone2": {"text": "8 913 456 78 90", "type": "entity"}, + "record_date": {"text": "на завтра", "type": "entity"}, + "record_time": {"text": "в пять часов вечера", "type": "entity"}, + "yesno": {"text": "да", "type": "classifier"}, + "yesno_obzv": {"text": "да", "type": "classifier"}, + "weekday": {"text": "в пятницу", "type": "classifier"}, + "end_repeat": {"text": "все, до свидания", "type": "classifier"}, + "operatorcheck": {"text": "соедините с оператором", "type": "classifier"}, + "see_grade": {"text": "пять", "type": "classifier"}, + "other_payment": {"text": "мобилизационные выплаты", "type": "classifier"}, + "mobilizac": {"text": "мобилизационные", "type": "classifier"}, + "matcap_direct": {"text": "на улучшение жилищных условий", "type": "classifier"}, + "new_minsoc_subsidii": {"text": "субсидия на жкх", "type": "classifier"}, + "new_trud": {"text": "потерял работу", "type": "classifier"}, + "rating_med": {"text": "отлично", "type": "classifier"}, + "zags": {"text": "загс центрального района", "type": "classifier"}, + "zags_handler": {"text": "загс на нижегородской", "type": "classifier"}, + "filial": {"text": "в мошковский филиал", "type": "classifier"}, + "offices_mfc_see": {"text": "родники", "type": "classifier"}, + "service_mfc_see": {"text": "хочу получить водительское удостоверение", "type": "classifier"}, + "nsk_fillials": {"text": "в филиал на родниках", "type": "classifier"}, +} + +CUSTOM_MODEL_MATCHES = [ + ("record_date", "на завтра"), + ("record_time", "в пять часов вечера"), + ("fio", "Иванов Иван Иванович"), + ("phone", "8 913 456 78 90"), + ("date", "на завтра"), + ("time", "в пять часов вечера"), + ("uuid", "550e8400-e29b-41d4-a716-446655440000"), + ("number", "пятьсот двадцать три"), + ("filial", "в филиал на родниках"), + ("zags", "загс центрального района"), + ("yesno", "да"), + ("weekday", "в пятницу"), + ("grade", "пять"), + ("obzv", "да"), + ("operator", "соедините с оператором"), + ("repeat", "все, до свидания"), + ("matcap", "на улучшение жилищных условий"), + ("mobilizac", "мобилизационные"), + ("trud", "потерял работу"), + ("subsidii", "субсидия на жкх"), + ("rating", "отлично"), + ("payment", "мобилизационные выплаты"), + ("service_mfc", "хочу получить паспорт"), + ("offices_mfc", "родники"), + ("паспорт", "хочу получить загранпаспорт"), + ("ЕПГУ", "проверить статус заявления на госуслугах"), + ("лаврентьев", "как получить лаврентьевскую карту"), + ("возраст", "мне 25 лет"), + ("загран", "хочу сделать загранпаспорт"), + ("вернуться", "вернуться в главное меню"), + ("не знаю код", "не знаю код подразделения"), + ("оценк", "оцениваю обслуживание на пять"), + ("несогласи", "я не согласен с этим"), + ("начало диалог", "здравствуйте"), + ("пособие", "какое пособие по рождению"), + ("УК", "проблема с управляющей компанией"), +] + +FALLBACK_TEXT = "Здравствуйте, хочу записаться на приём в МФЦ для получения паспорта, запись на завтра" + + +def load_asserts(path): + if not path: + return [] + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + return data.get("asserts", []) + + +class SeeAPI: + def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT): + self.base = f"http://{host}:{port}{BASE_PATH}" + + def get_models(self): + return json.loads(self._request(f"{self.base}/models")) + + def test_entity(self, model_id, text, similarity=70): + encoded = quote(model_id, safe="") + url = f"{self.base}/entities/{encoded}?text={quote(text)}&similarity={similarity}" + return json.loads(self._request(url)) + + def _request(self, url, timeout=15): + try: + with urlreq.urlopen(url, timeout=timeout) as r: + return r.read().decode("utf-8") + except urlerr.HTTPError as e: + raise RuntimeError(f"HTTP {e.code}: {e.read().decode('utf-8')[:200]}") + except urlerr.URLError as e: + raise RuntimeError(f"Connection failed: {e.reason}") + + +class TestSeeModels(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.api = SeeAPI(cls.args.host, cls.args.port) + cls.asserts = load_asserts(cls.args.asserts) + data = cls.api.get_models() + TestSeeModels.models = data + total = len(data["models"]) + len(data["handlers"]) + len(data["pretrained"]) + print(f"\n models: {len(data['models'])}, " + f"handlers: {len(data['handlers'])}, " + f"pretrained: {len(data['pretrained'])}") + if cls.asserts: + print(f" asserts loaded: {len(cls.asserts)}") + if total == 0: + raise unittest.SkipTest("Нет ни одной модели") + + def _find_assert(self, model_id): + for a in self.asserts: + if a["model"] in model_id: + return a + return None + + def _check_assert(self, model_id, result): + a = self._find_assert(model_id) + if not a: + return + checks = a.get("checks", {}) + has_classes = isinstance(result, dict) and "classes" in result + if has_classes: + classes = result.get("classes", []) + if "min_found" in checks: + self.assertGreaterEqual(len(classes), checks["min_found"], + f"{model_id}: expected >= {checks['min_found']} items, got {len(classes)}") + if classes and "text_contains" in checks: + self.assertIn(checks["text_contains"], classes[0].get("class", ""), + f"{model_id}: missing '{checks['text_contains']}'") + if classes and "confidence_min" in checks: + self.assertGreaterEqual(classes[0].get("confidence", 0), checks["confidence_min"], + f"{model_id}: confidence < {checks['confidence_min']}") + else: + entities = [] + for v in result.values(): + if isinstance(v, list): + entities.extend(v) + count = len(entities) + if "min_found" in checks: + self.assertGreaterEqual(count, checks["min_found"], + f"{model_id}: expected >= {checks['min_found']} entities, got {count}") + if count > 0: + first = entities[0] + if "text_contains" in checks: + self.assertIn(checks["text_contains"], first.get("text", ""), + f"{model_id}: text missing '{checks['text_contains']}'") + if "calculated_contains" in checks: + self.assertIn(checks["calculated_contains"], first.get("calculated", ""), + f"{model_id}: calculated missing '{checks['calculated_contains']}'") + if "confidence_min" in checks: + self.assertGreaterEqual(first.get("confidence", 0), checks["confidence_min"], + f"{model_id}: confidence < {checks['confidence_min']}") + + def _text_for_model(self, model_id): + a = self._find_assert(model_id) + if a and "text" in a: + return a["text"] + for substr, text in CUSTOM_MODEL_MATCHES: + if substr in model_id: + return text + return FALLBACK_TEXT + + def _is_empty(self, result): + if not result or result == {}: + return True + return all( + isinstance(v, list) and len(v) == 0 for v in result.values() + ) + + def test_01_list_models(self): + """Получение списка моделей""" + data = self.models + self.assertIn("models", data) + self.assertIn("handlers", data) + self.assertIn("pretrained", data) + + def _fmt_result(self, model_id, result): + print(f" >> {model_id}") + if isinstance(result, dict) and "classes" in result: + for c in result["classes"][:5]: + print(f" class={c.get('class','?')} conf={c.get('confidence',0):.3f}") + if len(result["classes"]) > 5: + print(f" ... ({len(result['classes'])} classes)") + else: + for key, entities in result.items(): + if isinstance(entities, list): + for e in entities[:3]: + text = e.get("text", "?") + calc = e.get("calculated", "?") + conf = e.get("confidence", 0) + print(f" {key}: text='{text}' calc='{calc}' conf={conf:.3f}") + if len(entities) > 3: + print(f" ... ({len(entities)} entities)") + + def test_02_pretrained_models(self): + """Проверка pretrained-моделей""" + errors = [] + for model_id, td in PRETRAINED_TESTS.items(): + if model_id not in self.models.get("pretrained", []): + errors.append(f" {model_id}: нет в списке") + continue + try: + result = self.api.test_entity(model_id, td["text"]) + if self._is_empty(result): + errors.append(f" {model_id}: пустой результат") + else: + self._check_assert(model_id, result) + self._fmt_result(model_id, result) + except AssertionError: + raise + except Exception as e: + errors.append(f" {model_id}: {e}") + if errors: + self.fail("Ошибки pretrained:\n" + "\n".join(errors)) + + def test_03_handler_models(self): + """Проверка handler-моделей""" + errors = [] + handlers = self.models.get("handlers", []) + if not handlers: + self.skipTest("Нет handler моделей") + for model_id in handlers: + text = FALLBACK_TEXT + for key, td in HANDLER_TESTS.items(): + if key in model_id: + text = td["text"] + break + a = self._find_assert(model_id) + if a and "text" in a: + text = a["text"] + try: + result = self.api.test_entity(model_id, text) + if self._is_empty(result): + print(f" [!] {model_id}: пустой результат") + else: + self._check_assert(model_id, result) + self._fmt_result(model_id, result) + except AssertionError: + raise + except Exception as e: + errors.append(f" {model_id}: {e}") + if errors: + self.fail("Ошибки handler:\n" + "\n".join(errors)) + + def test_04_custom_models(self): + """Проверка кастомных моделей""" + errors = [] + models = self.models.get("models", []) + if not models: + self.skipTest("Нет кастомных моделей") + for model_id in models: + text = self._text_for_model(model_id) + try: + result = self.api.test_entity(model_id, text) + if self._is_empty(result): + print(f" [!] {model_id}") + else: + self._check_assert(model_id, result) + self._fmt_result(model_id, result) + except AssertionError: + raise + except Exception as e: + errors.append(f" {model_id}: {e}") + if errors: + self.fail("Ошибки кастомных моделей:\n" + "\n".join(errors)) + + def test_05_handler_pretrained_coverage(self): + """Проверка handler моделей phone/uuid/number/fio""" + errors = [] + handlers = self.models.get("handlers", []) + for htype, td in [("phone", PRETRAINED_TESTS["phone"]), + ("uuid", PRETRAINED_TESTS["uuid"]), + ("number", PRETRAINED_TESTS["number"]), + ("fio", PRETRAINED_TESTS["fio"])]: + matching = [h for h in handlers if htype in h.lower()] + if not matching: + continue + for mid in matching[:2]: + try: + result = self.api.test_entity(mid, td["text"]) + if self._is_empty(result): + print(f" [!] {mid} ({td['hint']})") + else: + self._check_assert(mid, result) + self._fmt_result(mid, result) + except AssertionError: + raise + except Exception as e: + errors.append(f" {mid}: {e}") + if errors: + self.fail("Ошибки handler coverage:\n" + "\n".join(errors)) + + +def main(): + parser = argparse.ArgumentParser(description="SEE model autotest") + parser.add_argument("--host", default=DEFAULT_HOST, help=f"Хост (default: {DEFAULT_HOST})") + parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Порт (default: {DEFAULT_PORT})") + parser.add_argument("--asserts", default=None, help="JSON файл с ассертами") + args = parser.parse_args() + TestSeeModels.args = args + + suite = unittest.TestLoader().loadTestsFromTestCase(TestSeeModels) + runner = unittest.TextTestRunner(verbosity=2) + result = runner.run(suite) + sys.exit(0 if result.wasSuccessful() else 1) + + +if __name__ == "__main__": + main() diff --git a/test_smc_models.py b/test_smc_models.py new file mode 100644 index 0000000..3488d51 --- /dev/null +++ b/test_smc_models.py @@ -0,0 +1,202 @@ +#!/usr/bin/env python3 +"""SMC model autotest — проверяет все загруженные модели классификации после обновления. + +Использование: + python3 test_smc_models.py + python3 test_smc_models.py --host 10.101.60.27 + python3 test_smc_models.py --host 10.101.60.27 --port 6181 + python3 test_smc_models.py --asserts smc_asserts.json + +Файл ассертов (JSON): + { + "asserts": [ + { + "model": "МФЦ НСК", // подстрока для поиска модели + "type": "classifier", + "text": "записаться на приём", // опционально, свой текст + "checks": { + "min_classes": 1, // мин. количество классов + "top_class_contains": "МФЦ", // подстрока в top классе + "confidence_min": 0.5 // мин. confidence топ-класса + } + } + ] + } + +Возвращает exit code 0 если все модели прошли, иначе 1. +""" + +import argparse +import json +import sys +import unittest +from urllib.parse import quote + +try: + import urllib.request as urlreq + import urllib.error as urlerr +except ImportError: + urlreq = None + +DEFAULT_HOST = "10.101.60.27" +DEFAULT_PORT = 6181 +BASE_PATH = "/smc" + +DEFAULT_TEXT = "Здравствуйте, хочу записаться на приём в МФЦ для получения паспорта" + + +def load_asserts(path): + if not path: + return [] + with open(path, "r", encoding="utf-8") as f: + data = json.load(f) + return data.get("asserts", []) + + +class SmcAPI: + def __init__(self, host=DEFAULT_HOST, port=DEFAULT_PORT): + self.base = f"http://{host}:{port}{BASE_PATH}" + + def get_models(self): + return json.loads(self._request(f"{self.base}/models")) + + def classify(self, model_id, text): + encoded = quote(model_id, safe="") + url = f"{self.base}/classify/{encoded}?text={quote(text)}" + return json.loads(self._request(url)) + + def _request(self, url, timeout=30): + try: + with urlreq.urlopen(url, timeout=timeout) as r: + return r.read().decode("utf-8") + except urlerr.HTTPError as e: + raise RuntimeError(f"HTTP {e.code}: {e.read().decode('utf-8')[:200]}") + except urlerr.URLError as e: + raise RuntimeError(f"Connection failed: {e.reason}") + + +class TestSmcModels(unittest.TestCase): + @classmethod + def setUpClass(cls): + cls.api = SmcAPI(cls.args.host, cls.args.port) + cls.asserts = load_asserts(cls.args.asserts) + data = cls.api.get_models() + TestSmcModels.models = data + models = data.get("models", []) + handlers = data.get("handlers", []) + print(f"\n models: {len(models)}, handlers: {len(handlers)}") + if cls.asserts: + print(f" asserts loaded: {len(cls.asserts)}") + if len(models) + len(handlers) == 0: + raise unittest.SkipTest("Нет ни одной модели") + + def _find_assert(self, model_id): + for a in self.asserts: + if a["model"] in model_id: + return a + return None + + def _check_assert(self, model_id, result): + a = self._find_assert(model_id) + if not a: + return + checks = a.get("checks", {}) + classes = result.get("classes", []) + if "min_found" in checks: + self.assertGreaterEqual(len(classes), checks["min_found"], + f"{model_id}: expected >= {checks['min_found']} classes, got {len(classes)}") + if classes and "confidence_min" in checks: + self.assertGreaterEqual(classes[0].get("confidence", 0), checks["confidence_min"], + f"{model_id}: top confidence < {checks['confidence_min']}") + + def test_01_list_models(self): + """Получение списка моделей""" + data = self.models + self.assertIn("models", data) + self.assertIn("handlers", data) + print(f"\n models: {len(data['models'])}") + print(f" handlers: {len(data['handlers'])}") + + def test_02_models(self): + """Классификация через модели""" + errors = [] + models = self.models.get("models", []) + for mid in models: + if not mid: + continue + text = DEFAULT_TEXT + a = self._find_assert(mid) + if a and "text" in a: + text = a["text"] + try: + result = self.api.classify(mid, text) + classes = result.get("classes", []) + if not classes: + print(f" [!] {mid}: пустой результат") + else: + self._check_assert(mid, result) + print(f" >> {mid}") + for c in classes[:5]: + cl = c.get("class", "?") + conf = c.get("confidence", 0) + print(f" class='{cl}' conf={conf:.3f}") + if len(classes) > 5: + print(f" ... ({len(classes)} classes)") + except AssertionError: + raise + except Exception as e: + errors.append(f" {mid}: {e}") + if errors: + self.fail("Ошибки моделей:\n" + "\n".join(errors)) + + def test_03_handlers(self): + """Классификация через handler модели""" + errors = [] + handlers = self.models.get("handlers", []) + if not handlers: + self.skipTest("Нет handler моделей") + for mid in handlers: + if not mid: + continue + text = DEFAULT_TEXT + a = self._find_assert(mid) + if a and "text" in a: + text = a["text"] + try: + result = self.api.classify(mid, text) + classes = result.get("classes", []) + if not classes: + print(f" [!] {mid}: пустой результат") + else: + self._check_assert(mid, result) + print(f" >> {mid}") + for c in classes[:5]: + cl = c.get("class", "?") + conf = c.get("confidence", 0) + print(f" class='{cl}' conf={conf:.3f}") + if len(classes) > 5: + print(f" ... ({len(classes)} classes)") + except AssertionError: + raise + except Exception as e: + errors.append(f" {mid}: {e}") + if errors: + self.fail("Ошибки internal:\n" + "\n".join(errors)) + + +def main(): + parser = argparse.ArgumentParser(description="SMC model autotest") + parser.add_argument("--host", default=DEFAULT_HOST, help=f"Хост (default: {DEFAULT_HOST})") + parser.add_argument("--port", type=int, default=DEFAULT_PORT, help=f"Порт (default: {DEFAULT_PORT})") + parser.add_argument("--asserts", default=None, help="JSON файл с ассертами") + args = parser.parse_args() + TestSmcModels.args = args + + suite = unittest.TestLoader().loadTestsFromTestCase(TestSmcModels) + runner = unittest.TextTestRunner(verbosity=2) + result = runner.run(suite) + sys.exit(0 if result.wasSuccessful() else 1) + + +if __name__ == "__main__": + main()