Что мы храним
Раз в сутки программа обходит все страницы Wiki.js РосОсмотра (публичный раздел
public/*, 41 страница) и сохраняет их как обычные markdown-файлы на сервере —
по одному файлу на страницу. Это и есть «корпус» (вкладка «Распарсенные страницы»). Зачем
отдельный слой между вики и поиском: так можно посмотреть содержимое глазами,
переиндексировать без повторной выгрузки из вики и видеть, что реально изменилось между
стадиями.
Как текст режется на кусочки (чанки)
Поиск ищет не по целой странице, а по маленьким кусочкам — «чанкам». Каждый чанк — это один
раздел страницы (между заголовками H1–H3). Например, страница «Статусная модель» распадается
на чанки «Статусная модель > Переходы», «Статусная модель > Переходы > Из Экспертизы»
и так далее — вкладка «Индекс» показывает эти кусочки, если раскрыть строку страницы. Таблицы
специально не режутся посреди строк — иначе теряется смысл. У каждого чанка есть «хлебные
крошки» (heading_path) — путь по заголовкам, чтобы было видно, откуда кусочек,
даже если сам текст короткий.
Что такое эмбеддинг и векторный поиск
Компьютер не понимает смысл слов напрямую — но есть модель (bge-m3), которая превращает любой текст в список из 1024 чисел («вектор»). Тексты, близкие по смыслу, получают близкие наборы чисел — даже если в них нет ни одного общего слова. Например, вопрос «что значит термин CS?» и чанк «CS — команда сопровождения клиентов» окажутся рядом, хотя слово «термин» в ответе не встречается. Векторный поиск — это просто «найти чанки, чей вектор ближе всего к вектору вопроса».
Что такое полнотекстовый поиск (FTS)
Вторая «нога» поиска работает совсем иначе — как встроенный в Postgres аналог Ctrl+F, только умнее (учитывает окончания слов). Она ищет точные слова и термины. Это важно там, где вектор может «смазать» точность — например, короткие аббревиатуры или редкие термины, где важно точное совпадение, а не общий смысл.
Как две ноги объединяются в один список (RRF)
У каждой ноги — свой список из 20 кандидатов с местами (1-е, 2-е, 3-е…). Итоговый рейтинг
считается просто: чем выше место чанка в обеих ногах, тем выше его итоговый балл. Например: чанк
А занял 1-е место у вектора и 3-е у FTS → высокий итоговый балл. Чанк Б есть только у вектора (у
FTS его вообще нет среди 20 кандидатов) → балл ниже. Именно это видно в Playground: у каждого
результата — FTS #3 / вектор #1, а прочерк у ноги значит, что она
вообще не нашла чанк среди своих 20 кандидатов.
Чего здесь нет (пока)
Дашборд не пишет ответ клиенту — он только показывает, что происходит внутри поиска: какие чанки нашлись и почему. Черновик ответа (с помощью Claude) — отдельная, ещё не сделанная задача (E6.2). Поэтому в Playground нет кнопки «сформировать ответ» — только сырые результаты поиска с источниками.