Как Poliscope сделала всю местную политику Германии доступной для поиска на одном сервере с помощью Qdrant

Источник: Qdrant•

Как Poliscope сделала всю местную политику Германии доступной для поиска на одном сервере с помощью Qdrant

Poliscope делает данные о местной политике Германии доступными для поиска в одном месте. В Германии около 11 000 муниципалитетов, и почти каждый из них публикует информацию через информационную систему совета (на немецком — Ratsinformationssystem). Именно там публикуются повестки дня, протоколы,…

Poliscope делает данные о местной политике Германии доступными для поиска в одном месте. В Германии около 11 000 муниципалитетов, и почти каждый из них публикует информацию через информационную систему совета (по-немецки — Ratsinformationssystem). Именно там публикуются повестки дня, протоколы, предложения и документы по планированию. Многие порталы обслуживают сразу несколько муниципалитетов, поэтому около 4800 активных порталов Poliscope охватывают примерно 90% немецких муниципалитетов и 98% населения. Они работают примерно на дюжине программных продуктов, каждый из которых имеет свои особенности и ни один из которых не взаимодействует с другими.

Это тот уровень политики, который люди ощущают наиболее непосредственно: решение о зонировании для ветропарка, строительство новой школы, продолжение движения автобусов. Это также тот уровень, который никто не мог искать. Чтобы узнать, какие советы в Германии обсуждали ветроэнергетику, приходилось открывать порталы по очереди.

Poliscope сканирует их все, выполняет оптическое распознавание символов (OCR) для каждого PDF-файла и объединяет результаты в едином поисковой строке. Первыми клиентами стали разработчики проектов в области возобновляемых источников энергии, которым необходимо знать в тот самый момент, когда совет начинает зонировать новый участок под ветряную или солнечную электростанцию, чтобы первыми выйти на землевладельцев. За ними последовали журналисты, городские планировщики и компании, продающие товары муниципалитетам. Сегодня корпус охватывает около 532 000 заседаний, 5,5 миллиона вопросов повестки дня и 5,6 миллиона документов, причем ежемесячно поступает около 20 000 новых заседаний. В Qdrant это 130 миллионов точек, 117 миллионов из которых — фрагменты документов.

В следующей демоверсии поиск по запросу «Windkraft» (ветроэнергетика) выполняется по всем советам Германии за текущий год, сужается до земли Шлезвиг-Гольштейн и открывает одно заседание совета на том пункте повестки дня, который совпал с запросом.

До Qdrant поиска не существовало

Первая версия Poliscope ничего не искала. Для каждого заседания рассчитывалась оценка релевантности языковой модели для горстки фиксированных тем (ветер и солнце среди них) исключительно на основе названий пунктов повестки дня. Никто не заглядывал внутрь PDF-файлов. Для первых клиентов этого было достаточно, поскольку их волновали только эти темы, но это решение не масштабировалось до «поиска по чему угодно».

Документы — это то место, где кроются настоящие ответы: что было сказано, что было решено, как прошло голосование. Добраться до них означало провести OCR 4,3 ТБ PDF-файлов — от одностраничных уведомлений до 700-страничных файлов планирования со встроенными картами, — а затем развернуть слой извлечения данных, который мог бы хранить более 100 миллионов фрагментов и при этом отвечать за время, которое человек готов ждать.

Почему Poliscope выбрала Qdrant: гибридный поиск, иерархические фильтры и сервер, которым можно владеть самостоятельно

Колья Мартенс (Kolja Martens), соучредитель и технический директор Poliscope, зафиксировал требования к поисковой системе, прежде чем сделать выбор. Сопоставление немецких ключевых слов не подлежало обсуждению: сложные существительные приводят к тому, что чисто семантический поиск пропускает точные термины, поэтому движку требовался плотный и разреженный поиск в рамках одного запроса. Результаты должны были фильтроваться по иерархическому коду региона, поскольку большинство пользователей ищут информацию по одной земле, одному округу или одному городу. Результаты должны были группироваться по заседаниям или предложениям. И весь поисковый стек должен был работать на одной большой машине, которой Poliscope управляла бы самостоятельно.

Последнее требование было связано с юрисдикцией в такой же степени, как и со стоимостью. Poliscope хотела использовать для данных исключительно европейский стек, размещенный на собственном оборудовании, без американских вендоров, удерживающих индекс, и без каких-либо рисков в рамках американского закона CLOUD Act. Суверенитет данных всплывает в собственных продажных беседах Poliscope, и управляемый сервис в регионе американского гиперскалрера не решал эту проблему.

В конце 2025 года Колья оценил Typesense и привычные управляемые векторные решения. Он обнаружил, что Typesense ориентирован на каталоги товаров с защитой от опечаток, а векторный поиск является для него второстепенной функцией. Среди управляемых вариантов группировка результатов поиска либо отсутствовала, либо требовала обходных путей. Он протестировал Qdrant на бесплатном облачном уровне перед покупкой сервера, и в феврале 2026 года Poliscope запустила в продакшн решение на базе открытого кода Qdrant.

Что склонило чашу весов в пользу Qdrant: это профессиональный инструмент. В нем настраивается абсолютно все, а это значит, что можно либо выстрелить себе в ногу, либо создать что-то невероятно быстрое, и мы сделали и то, и другое. При этом он остается простым в использовании, документация хороша, а агенты по написанию кода ориентируются в нем без посторонней помощи.

Что склонило чашу весов в пользу Qdrant: это профессиональный инструмент. В нем настраивается абсолютно все, а это значит, что можно либо выстрелить себе в ногу, либо создать что-то невероятно быстрое, и мы сделали и то, и другое. При этом он остается простым в использовании, документация хороша, а агенты по написанию кода ориентируются в нем без посторонней помощи.

От 20-секундного поиска до менее чем секунды на 130 миллионах точек

Poliscope предоставила первую версию поиска клиентам на раннем этапе, когда уже было проиндексировано около 70 миллионов точек при минимальной настройке. Один поиск занимал до 20 секунд. Ожидание результата во время звонка по продажам было, по словам Кольи, неловким молчанием.

Исправления были получены за счет собственных настроек Qdrant, каждое из которых оценивалось на продакшн-корпусе.

Многоарендная изоляция (tenant partitioning) по землям. Большинство людей ищут в пределах одного региона. В Германии 16 земель, которые Poliscope объединила в 12 арендаторов, используя поддержку многоарендности Qdrant, причем те же 12 групп соответствуют шардам коллекции. Поскольку запрос почти всегда содержит регион, он может отсеять до 80% корпуса до начала векторного поиска.

Префиксный индекс для иерархии регионов. Немецкие административные ID строго иерархичны: ID каждого подмножества начинается с ID родительского объекта. Одно совпадение по префиксу в этом поле, поддержанное ключевым индексом с опцией префикса, покрывает «все внутри этого округа» в рамках одного условия. Это заменило самый медленный фильтр в системе.

В таблице приведены производственные измерения, которыми Poliscope поделилась для обоих изменений.

TurboQuant для индекса и исходных данных. Poliscope начала с 2-битного бинарного квантования Qdrant. 26 сентября 2026 года она переключила индекс в оперативной памяти на 1,5-битный TurboQuant — изменение конфигурации, не потребовавшее повторного приема данных. Двумя днями позже, в Qdrant 1.19, исходные векторы на диске были перенесены с типа float32 на тип данных turbo4, для чего данные были скопированы в новую коллекцию. Место для хранения на сервере подходило к концу, и этот шаг освободил его, одновременно повысив полноту поиска (recall).

В таблице приведены измерения Poliscope до и после каждого шага, причем задержка измерялась только для запроса Qdrant.

Полнота поиска (recall) после шага turbo4 практически не изменилась.

Сегодня выполнение запроса в Qdrant занимает 8,5 мс на перцентиле P50 и 12,5 мс на P95 в бенчмарке Poliscope. При измерении от начала до конца с 29 сентября 2026 года, включая встраивание (embedding) запроса, поиск в Qdrant и реранжирование, поиск занимает в среднем 0,87 секунды, 0,59 секунды на медиане и 2,1 секунды на P95.

Это до сих пор вызывает у меня легкий прилив адреналина: одна поисковая строка — и вы видите каждый совет в стране, который касался вашей темы на прошлой неделе. Мониторинг на муниципальном уровне превратился из практически невозможного в нечто столь же простое, как поиск в Google.

Это до сих пор вызывает у меня легкий трепет: одна поисковая строка — и вы видите каждый совет в стране, который на прошлой неделе затрагивал вашу тему. Мониторинг на муниципальном уровне превратился из практически невыполнимой задачи в нечто столь же простое, как поиск в Google.

Как запрос проходит через Poliscope

Загрузка. Веб-краулеры на выделенном сервере собирают заседания, пункты повесток, предложения и PDF-файлы с порталов в базу данных Poliscope. PDF-файлы проходят через очередь OCR на отдельном GPU-сервере, где модель компьютерного зрения превращает каждую страницу в Markdown. Хук базы данных ставит в очередь задачи BullMQ. Воркер разбивает Markdown на фрагменты, векторизует каждый фрагмент в 1536 измерениях и добавляет или обновляет его в Qdrant, используя встроенный в Qdrant алгоритм BM25 в качестве разреженного вектора с модификатором IDF. Большинство изменений попадают в Qdrant сразу после того, как они появляются в базе данных. Еженедельная задача сверки очищает все остальное.

Запрос. Поиск обслуживает встроенный поиск Poliscope, его сервер протокола контекста модели (MCP), агентов и службы мониторинга. Парсер запросов поддерживает подзапросы OR в гибридном режиме, а также AND, NOT и точные фразы в режиме ключевых слов. Гибридный префетч выполняет BM25 и плотный поиск за один запрос, причем плотная сторона обслуживается из 1.5-битного индекса TurboQuant и пересчитывается по сравнению с оригиналами turbo4 с 3-кратной сверхдискретизацией, после чего объединяет их с помощью слияния оценок на основе распределения (DBSF). Результаты группируются по заседанию или предложению, после чего переранжируются кросс-энкодером Jina (jina-reranker-v2-base-multilingual). Каждое попадание содержит диапазон страниц PDF, поэтому результаты ссылаются непосредственно на нужную страницу исходного документа.

Настройка. Open-source версия Qdrant 1.19 работает как одиночный узел с одной коллекцией из 130 миллионов векторов на 12 шардах на выделенном сервере Hetzner в Германии с 256 ГБ оперативной памяти. База данных и API делят одну и ту же машину.

Маленькая команда, один сервер

Запуск поиска на собственном оборудовании был осознанным выбором для Poliscope. Это позволяет хранить данные клиентов на серверах в Германии под контролем Poliscope и дает возможность команде настраивать систему под то, как пользователи действительно ищут информацию.

Этот контроль вполне осязаем: команда сама решает, какие ядра отвечают на запросы, а какие запускают оптимизатор, и планирует масштабные пакетные загрузки с учетом производственного трафика, а не ограничений провайдера. Обратной стороной является то, что решения, которые управляемый сервис принял бы за вас, ложатся на ваш собственный стол. Структура шардов была одним из таких решений, и Poliscope изменила ее на раннем этапе, создав новую коллекцию параллельно со старой и выполнив переключение.

Ничто из этого не требовало выделенной команды по поиску. Поиск — это лишь часть платформы, где основные усилия разработчиков уходят на более сложную задачу — обеспечение надежного краулинга тысяч порталов. Qdrant должен был вписаться в это без превращения в отдельный проект, и документация сыграла большую роль в том, почему это удалось. Колья ведет разработку с помощью агентов кодирования и сервера MCP с документацией, а документации и исходного кода Qdrant оказалось достаточно, чтобы агенты нашли нужную настройку без посторонней помощи.

Qdrant позволяет нам сделать всю немецкую местную политику доступной для семантического поиска на одном сервере силами лишь небольшой команды. Каждая проблема масштабирования, с которой мы сталкивались, имела для этого рычаг управления, и этот рычаг был хорошо задокументирован.

Qdrant позволяет нам сделать всю немецкую местную политику доступной для семантического поиска на одном сервере силами лишь небольшой команды. Каждая проблема масштабирования, с которой мы сталкивались, имела для этого рычаг управления, и этот рычаг был хорошо задокументирован.

Что дальше: еще десять лет данных и второй узел

Данные Poliscope начинаются с января 2024 года — года основания компании. Сотрудничество с исследовательскими центрами позволит расширить охват до 2016 года, что в несколько раз увеличит объем корпуса. Миграция на TurboQuant освободила ресурс на текущем сервере, и когда рост действительно выведет коллекцию за пределы одной машины, Колья планирует запустить второй узел, разделить данные между ними и уже тогда вернуться к вопросу о выборе между самоуправляемым и управляемым решением.

Что касается поиска, команда начала измерять полноту (recall) для каждого изменения конфигурации, начиная с миграции квантования, и рассматривает возможность использования более коротких плотных векторов, поскольку гибридный поиск с BM25 не давал промахов, о которых им было бы известно при 1536 измерениях.

От практически невыполнимой задачи до поисковой строки

Poliscope начиналась с проблемы мониторинга, которую компании раньше решали, выдавая стажерам список порталов. Теперь она выполняет гибридный поиск по 130 миллионам записей муниципальных архивов Германии, отфильтрованных по арендатору и префиксу региона и сжатых с помощью TurboQuant, на одном сервере, которым владеет и управляет небольшая команда. Поиск по всем советам Германии занимает в среднем 0,87 секунды, и каждый результат ведет обратно на страницу, с которой он был получен.

О чём эта статья

Ещё в разделе «Разработка ПО»

Все →

Ещё от Qdrant