180 lines
13 KiB
Markdown
180 lines
13 KiB
Markdown
# План внутреннего интерфейса оценки поисковой выдачи
|
||
|
||
## Цель
|
||
|
||
Создать закрытую лабораторию релевантности: юрист оценивает фактическую выдачу
|
||
нашего 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: она не блокируется браузером, сохраняет
|
||
контекст выдачи и работает на одном экране с оценкой.
|
||
|
||
### Доступность оценки и документа
|
||
|
||
Оценка реализуется нативной группой `radio` внутри `fieldset` с `legend`
|
||
«Оценка результата». У каждого значения есть видимая подпись: «0 —
|
||
нерелевантен», «1 — косвенно полезен», «2 — частично полезен», «3 — прямо
|
||
отвечает». Нельзя передавать смысл оценки только цветом. Все элементы управления
|
||
доступны с клавиатуры, имеют видимый `:focus-visible`; выбранный результат
|
||
обозначается текстом и визуальным состоянием.
|
||
|
||
На узком экране список результатов занимает всю страницу. Кнопка «Открыть
|
||
документ» открывает полноэкранный нативный `<dialog>` с явной кнопкой
|
||
«Закрыть». При закрытии фокус возвращается на исходную кнопку «Открыть
|
||
документ».
|
||
|
||
### Состояния
|
||
|
||
- Во время поиска и сохранения показывается состояние загрузки; повторная
|
||
отправка на это время недоступна. Стабильная пустая область `role="status"`
|
||
в DOM объявляет начало поиска, число результатов и успешное сохранение.
|
||
- Пустая выдача сообщает: «По запросу „…“ ничего не найдено» и предлагает
|
||
«Изменить запрос».
|
||
- Ошибка поиска сообщает причину и предлагает «Повторить поиск»; текст ошибки
|
||
выводится в `role="alert"`.
|
||
- Ошибка сохранения сообщает: «Не удалось сохранить. Проверьте подключение и
|
||
повторите». Черновик остаётся в браузере, текст ошибки выводится в
|
||
`role="alert"`.
|
||
- После сохранения выводится: «Оценка сохранена · № … · дата и время» в
|
||
указанной стабильной области `role="status"`.
|
||
|
||
До сохранения черновик хранится в `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 — не создан
|