Демка · 9 сентября 2026

TenderLens

TenderLens принимает HTML, PDF, XML, JSON и TXT, приводит документы к одному контракту и режет их на стабильные chunks. Индексация идёт через NATS JetStream. bge-m3 в MWS считает embeddings, pgvector ищет близкие фрагменты, а gpt-oss-120b формирует ответ только по найденному контексту и возвращает источники.

История реализации: с 20 августа 2026. Публичный стенд: с 7 сентября 2026. Реальные модели MWS подключены 9 сентября 2026.Версия 6c005b6e10 кадров интерфейса

Опубликованный стенд с реальными моделями MWS, pgvector, NATS и синтетическим корпусом

01 / Задача

Поиск по документам: FastAPI и pgvector

Задача — собрать проверяемый поиск по разнородным тендерным файлам. От исходного документа до ответа остаётся трасса document → chunk → embedding → hit → citation, поэтому результат можно вернуть к конкретному фрагменту.

Сценарий: Поиск и разбор набора документов.

Что делал

  • Нормализация документов, событийная индексация и хранение chunks в PostgreSQL.
  • Search и Ask API с источниками, отдельным no-context ответом и порогом релевантности.
  • MWS-провайдер для embeddings и Chat Completions, проверка deployment IDs и размерности векторов.
  • Публичный стенд с сессионным и общим rate limit. Ключ MWS остаётся на сервере.

02 / Реализация

Что отличает реализацию

Каждый ответ проходит одну трассу: document → chunk → bge-m3 → pgvector → gpt-oss-120b → citation. Повтор события не размножает chunks. Посторонний запрос отсекается до генерации. Корпус синтетический; очередь, индексатор, БД, векторный поиск и обе модели MWS работают реально.

Скриншоты

Экраны, формы, ошибки

Скриншоты, схемы и исходные материалы сохранены на языке оригинала; подписи и описание переведены.

03 / Технологии

Что использовано

Python / FastAPI 36.6%Python parsers / indexing 35.2%JavaScript / HTML / CSS 15%Python / pgvector 9.8%Python / NATS 3.4%

Доли по размеру прикладных файлов Git в закреплённой версии. Каждый файл отнесён к одной подсистеме по правилам scripts/generate-stack-share.mjs; тесты, ассеты, зависимости и generated-файлы исключены. Округление — до 0,1%. Это состав кода, а не уровень владения технологиями.

FastAPI / Pydantic

HTTP-контракты, валидация, Search и Ask.

MWS Model Hub

bge-m3 для embeddings; gpt-oss-120b для ответа по контексту.

NATS JetStream

Доставка событий индексатору и повтор.

PostgreSQL / pgvector

Документы, attachments, chunks и cosine search.

SQLAlchemy / Python

Нормализация, извлечение, chunking и проверка content_hash.

04 / Решения

Как устроен проект

  • Seed отправляет TenderChangedV1 через NATS; индексатор извлекает текст и атомарно заменяет chunks при изменении content_hash.
  • bge-m3 возвращает 1024-компонентные embeddings. Индексатор пишет имя модели рядом с каждым chunk, а PostgreSQL VECTOR(1024) выполняет cosine search.
  • Ask передаёт gpt-oss-120b только найденные фрагменты. Документы в prompt помечены как данные, а не инструкции.
  • Порог 0,40 выбран после замера релевантных и посторонних запросов. Если подходящих chunks нет, generation endpoint не вызывается.
  • Внешний crawler на публичном стенде выключен. Корпус синтетический, очередь, БД, векторный поиск и MWS inference работают реально.
Компоненты опубликованного демо
Компоненты опубликованного демо

05 / Проверка

Сценарии демки

  1. Найдите документ о серверах: первый результат должен содержать гарантию 36 месяцев и метку bge-m3.
  2. Переключитесь на Ask: gpt-oss-120b должен ответить по найденным фрагментам и показать источники.
  3. Выберите «Нет контекста»: при score ниже 0,40 сервис возвращает отказ без вызова модели генерации.
  4. Проверьте состояние корпуса: четыре документа, 16 chunks и ready у каждой записи.

Результаты проверок

  • Опубликованы десять кадров версии 6c005b6: desktop, mobile, Search, Ask, no-context и validation.
  • Четыре ready-документа переиндексированы в 16 векторов bge-m3 размерности 1024.
  • В галерейной browser-проверке 9 сентября 2026 desktop Search занял 298 мс, Ask — 1145 мс, no-context — 115 мс; mobile Search — 137 мс, Ask — 1936 мс. Это одиночные измерения, не benchmark.
  • Для релевантных тестовых запросов top cosine был 0,604–0,927; для двух посторонних — 0,278 и 0,370. Production threshold выставлен 0,40.
  • Текущий снимок двух контейнеров TenderLens: около 121,4 MiB RAM суммарно при простое. Модели выполняются в MWS и не занимают RAM/GPU VPS.
  • На момент снимка 9 сентября 2026 было доступно около 5,05 GiB RAM и 105,7 GiB диска на VPS.

Ограничения

  • Четыре синтетических документа и 16 chunks — небольшой демонстрационный корпус, а не база реальных закупок.
  • Качество модели на независимом наборе не измерялось. Показанные cosine scores описывают только запросы из проверки 9 сентября 2026.
  • Лимит — 5 Search/Ask запросов в минуту на сессию и 12 запросов в минуту на весь процесс. Запросы пользователей не сохраняются.
  • Inference зависит от доступности двух deployment в MWS. При недоступности провайдера readiness становится красным, автоматического перехода на fake нет.
  • Worker health подтверждает соединение при старте; отдельный детектор зависшего вычисления не реализован.

Технические заметки

Модули, API, схема данных, запуск и результаты проверок.

Открыть учебник →Документация →Материалы ↓