diff --git a/CHANGELOG.md b/CHANGELOG.md index ae18282..07e4cd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Не выпущено +- Добавлен план внутреннего интерфейса оценки поисковой выдачи юристами. - Завершён Search API v1: стабильные справочники, валидный OpenAPI, безопасная пагинация и проверка актуальных редакций в локальном OpenSearch. - Добавлено безопасное переключение alias на новую версию поискового индекса diff --git a/docs/README.md b/docs/README.md index 1fa1b81..ec297c0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,6 +8,8 @@ MVP, зависимости и спринты. - [Готовность к проектированию frontend](product/frontend-design-readiness-plan.md) — обязательные работы и критерии перехода к frontend. +- [План интерфейса оценки поисковой выдачи](product/search-relevance-review-interface-plan.md) — + внутренний инструмент сбора оценок юристов для настройки OpenSearch. - [Задание по нормализации документов](product/minjust-document-normalization-agent-task.md) — требования и критерии приёмки нормализатора ЦБД Минюста КР. diff --git a/docs/product/search-relevance-review-interface-plan.md b/docs/product/search-relevance-review-interface-plan.md new file mode 100644 index 0000000..a045398 --- /dev/null +++ b/docs/product/search-relevance-review-interface-plan.md @@ -0,0 +1,146 @@ +# План внутреннего интерфейса оценки поисковой выдачи + +## Цель + +Создать закрытую лабораторию релевантности: юрист оценивает фактическую выдачу +нашего OpenSearch по практическим запросам. Цель — улучшать собственное +ранжирование, а не воспроизводить алгоритм сайта Минюста КР. + +ЦБД Минюста используется как официальный источник текста, реквизитов, статуса +и редакции акта. Порядок результатов и оценка их полезности определяются в +нашем сервисе. + +Это внутренний рабочий инструмент, а не публичный frontend MVP. Он не включает +регистрацию, личные кабинеты, публичный дизайн, сложные фильтры или сравнение +редакций. + +## Сценарий юриста + +1. Указать поисковый запрос и язык. +2. Получить первые 10–20 результатов в точном порядке OpenSearch. +3. Увидеть позицию каждого результата: `#1`, `#2` и далее. +4. Открыть выбранный документ по клику на название в правой панели страницы. +5. Поставить каждому просмотренному результату оценку и комментарий. +6. Сохранить снимок выдачи и оценок. +7. Передать накопленные записи на анализ ранжирования. + +## Оценка результата + +| Балл | Значение | +| ---: | --- | +| 0 | Нерелевантен: совпали слова, но акт не отвечает на вопрос. | +| 1 | Косвенно полезен: относится к теме, но прямого ответа нет. | +| 2 | Частично полезен: отвечает не полностью или требует другого акта. | +| 3 | Прямо и достаточно отвечает на запрос. | + +Оценка относится к отдельному документу, а не ко всей выдаче. Результат без +оценки считается непросмотренным, а не нерелевантным. + +## Интерфейс + +Рекомендуемый экран — две панели. + +- Вверху: поле запроса, переключатель RU/KY, выбор числа результатов и кнопка + «Найти». +- Слева: карточки результатов в порядке выдачи. Карточка содержит позицию, + название, тип, статус, дату, номер и фрагмент текста. +- Справа: заголовок, реквизиты, очищенный HTML выбранной редакции и ссылка на + официальный источник. +- В карточке: кнопки оценки `0`, `1`, `2`, `3` и раскрываемое поле + комментария. +- Внизу: имя или псевдоним проверяющего, общий комментарий и кнопка + «Сохранить оценку». + +Правая панель предпочтительнее popup: она не блокируется браузером, сохраняет +контекст выдачи и работает на одном экране с оценкой. + +До сохранения черновик хранится в `localStorage`. После успешного сохранения +интерфейс показывает ID записи и время сохранения. + +## Backend и хранение + +Использовать существующие endpoint: + +- `GET /search` — получить ранжированный список результатов; +- `GET /documents/{code}/editions/{edition}` — получить текст выбранной + редакции. + +Добавить два endpoint: + +- `POST /search-reviews` — валидирует и сохраняет оценку; +- `GET /search-reviews/export` — отдаёт накопленные записи в JSON. + +Для первой версии достаточно отдельной SQLite-базы. Это стандартная библиотека +Python, данные переживают перезапуск и легко выгружаются для анализа. Доступ к +интерфейсу и всем endpoint `search-reviews`, включая экспорт, должен быть +ограничен локальной сетью/VPN или аутентификацией reverse proxy. + +Одна запись представляет один сохранённый поисковый сеанс: + +| Поле | Назначение | +| --- | --- | +| `id`, `created_at` | Идентификатор и время сохранения. | +| `reviewer` | Имя или псевдоним проверяющего. | +| `query`, `language` | Исходный запрос и язык поиска. | +| `index_name`, `algorithm_version` | Версия индекса и алгоритма на момент оценки. | +| `top_result_code` | Код документа в позиции `#1`. | +| `results_json` | Снимок результатов в исходном порядке с оценками и комментариями. | +| `overall_comment` | Общий комментарий к выдаче. | + +В `results_json` для каждого результата сохраняются: `rank`, `document_code`, +`edition_code`, название, реквизиты, фрагмент, оценка и комментарий. Снимок +выдачи обязателен: после изменения алгоритма можно будет восстановить именно +тот результат, который видел юрист. + +## Правила сохранения + +- Запрос не пустой, не длиннее 500 символов. +- Оценка может быть только целым числом от 0 до 3 либо отсутствовать у + непросмотренного результата. +- Комментарии имеют ограничение длины; пользовательские значения не вставляются + в HTML. +- `GET /search` возвращает краткоживущий HMAC-подписанный снимок выдачи: + запрос, язык, индекс, результаты и их позиции. `POST /search-reviews` + принимает этот снимок и только оценки с комментариями. Сервер проверяет + подпись и срок, самостоятельно формирует `results_json` и отклоняет оценки + для отсутствующих либо подменённых позиций и документов. +- Нельзя передавать персональные данные или закрытые материалы в комментариях. + +## Анализ данных + +Экспорт должен содержать исходный JSON-снимок, чтобы его можно было обработать +скриптом или открыть в табличном инструменте. Первый отчёт строит: + +- среднюю оценку для каждой позиции выдачи; +- долю результатов с оценкой `3` в top-1, top-3 и top-10; +- запросы, где нет результатов с оценкой `2` или `3`; +- документы, которые часто получают низкую оценку в первых позициях; +- комментарии для ручного разбора ошибок. + +Сырые оценки не должны автоматически менять веса поиска. Сначала команда +разбирает причины: анализатор, синонимы, статус, отсутствие документа, +неправильная формулировка запроса или юридическая неоднозначность. + +## Этапы реализации + +1. Утвердить шкалу 0–3, обязательность имени проверяющего и правила доступа. +2. Добавить SQLite-хранилище, валидацию, сохранение и JSON-экспорт. +3. Добавить статическую внутреннюю страницу в существующий Python-сервер, без + Next.js и отдельного публичного приложения. +4. Подключить поиск, правую панель документа, черновик и сохранение. +5. Добавить минимальные backend-проверки сохранения, повторного запуска, + экспорта и недопустимых оценок. +6. Провести ручный прогон на десяти русскоязычных практических запросах с + двумя юристами. +7. На собранных записях настроить OpenSearch и повторить тот же набор запросов. + +## Критерий готовности + +Юрист вводит запрос, видит порядок выдачи, открывает документ, выставляет +оценки и комментарии, сохраняет их. Экспорт содержит запрос, язык, документ +на позиции `#1`, полный порядок результатов, оценки, комментарии и версию +индекса. Данные можно сравнить до и после изменения алгоритма. + +--- + +Акылдаш · Telegram-бот v0.2.2 · Backend v0.7.1 · Frontend — не создан