Перейти к содержанию

Double-embedding в Open WebUI Knowledge Bases

Задача 8 · Разобрано 07.08.2026 · KB-исследование, не баг нашей инфраструктуры

TL;DR

Это не баг, а by design (по заявлению разработчиков Open WebUI).

При загрузке файла в Knowledge Base Open WebUI создаёт две копии эмбеддингов одного и того же контента:

  1. Per-file collection (file-{file.id}) — эмбеддинги для отдельного файла (нужно чтобы файл можно было прикрепить к чату сам по себе)
  2. Knowledge collection ({knowledge.id}) — эмбеддинги того же файла, но в рамках Knowledge Base

Оба вызова идут через process_file в backend/open_webui/routers/retrieval.pyобсуждение #8240.

Что это значит для нас

Наша конфигурация: VECTOR_DB=qdrant, KB на русском, ~24 файла в KB alatyr-infra.

Последствия: - Место в Qdrant × 2 (не критично для нашего объёма ~24 файла) - Токены на эмбеддинг × 2 при первом sync (уже прошли, теперь только UPDATE изменённых) - Retrieval работает корректно — RAG использует Knowledge collection, per-file коллекции используются только когда файл прикреплён напрямую к чату

Прогноз реального overhead: - 24 файла × ~250 chunks × 2 = ~12,000 векторов в Qdrant - Каждый вектор 1024-мерный float32 = 4 KB - Итого: ~48 MB в Qdrant вместо ~24 MB - Ускорение sync (задача 7 batch=32) компенсирует double-embedding по времени

Позиция разработчиков Open WebUI

Из #8240 (декабрь 2024):

Both are required to work. The first call ensures embeddings are created for the file itself, which is essential for the file to be processed and represented properly. The second call to process_file is necessary to associate those embeddings with the knowledge collection in the vector DB.

Removing the first call would break isolated file processing, and skipping the second call would mean the file won't integrate into the relevant knowledge collection.

Был PR #8385 с частичным фиксом (после v0.5.4), но фундаментальная архитектура не изменилась.

Как понять что это именно double-embedding

Логи sync-to-openwebui.sh покажут два вставки для одного файла:

INFO ... Inserted 15 items into collection 'file-abc-123-def-456'
INFO ... Inserted 15 items into collection '7d8e9f10-...' (это ID KB)

Если видишь два Inserted N items подряд с одинаковым N для одного файла — это оно, не наш баг.

Что делать (варианты)

Вариант A: Смириться (рекомендуется)

  • Overhead ~24 MB в Qdrant — незначителен на фоне общих ресурсов ragserver
  • Retrieval работает корректно
  • Ждём когда Open WebUI сделает оптимизацию upstream (issue открыт)

Вариант B: Использовать External Knowledge Source

Open WebUI поддерживает подключение к внешнему Qdrant через настройку External Knowledge Sources (Admin → Settings → Integrations → External Knowledge Sources).

Плюсы: - Мы сами управляем эмбеддингами через sync-to-openwebui.sh в Qdrant напрямую (без API Open WebUI) - Не будет double-embedding — только один вектор на chunk

Минусы: - Нужно переписать sync-to-openwebui.sh — сейчас он использует Open WebUI API /api/v1/files/ + knowledge/{id}/file/add. Придётся ходить в Qdrant напрямую, самим считать эмбеддинги через Ollama API. - Потеряется удобная интеграция с UI Open WebUI (загрузка через drag&drop, статусы sync) - Нужен маппинг полей (content_field, title_field и т.д.) — конфигурация в UI

Оценка: день работы, овчинка не стоит выделки при текущем объёме.

Вариант C: Загружать только через /api/v1/files/ с параметром knowledge_id

По документации:

POST /api/v1/files/ — Upload files. Pass knowledge_id (and optionally directory_id) in the upload metadata to have the backend auto-link and process the file into that knowledge base server-side

Возможно (не проверено!) этот путь делает только один process_file вместо двух. Стоит проверить экспериментально.

Проверка: 1. Загрузить один тестовый файл через POST /api/v1/files/ с knowledge_id в metadata 2. Посмотреть в логах Open WebUI сколько раз вызвался process_file 3. Посмотреть в Qdrant сколько коллекций созданы

Если работает — переписать sync-to-openwebui.sh на этот эндпоинт вместо двух отдельных запросов.

Наше решение

Приняли Вариант A (смириться) на текущий момент. Overhead в ~24 MB Qdrant незначителен.

Follow-up (не срочно): - [ ] Проверить Вариант C на одном тестовом файле (пилот на 15 минут) - [ ] Если работает — обновить sync-to-openwebui.sh, экономия эмбеддинг-токенов ×2

Что мониторить: - Размер qdrant-data volume в docker (docker system df или du -sh /var/lib/docker/volumes/rag-platform_qdrant-data) - Если растёт быстрее чем KB — есть проблема с re-embedding или delete-not-cleaning-vectors (#7181, #14077)

Побочные баги (не наши, но знать надо)

#7181 Delete file doesn't clean vectors: при удалении файла из KB через UI векторы остаются в БД. При повторной загрузке того же файла — ошибка "Duplicate content detected".

  • Наш обход: если удаляешь файл из KB, потом хочешь загрузить снова — сначала посмотри в Qdrant, что коллекция реально удалена. Если нет — удали вручную через Qdrant API.

#20854 Reindex broken: кнопка "Reindex" в UI сломана — падает с "Duplicate content detected".

  • Наш обход: при смене embedding model — удалить KB целиком через UI, потом заново создать через sync-to-openwebui.sh. Убедиться что коллекции в Qdrant очистились до нового ingest.

#14077 Persistent data remnants: при изменении chunk size и "save" без изменений — размер vector_db удваивается (новые chunks добавляются, старые не удаляются).

  • Наш обход: не менять chunk size на существующей KB. Если надо — удалить KB и создать заново.

Ссылки

Changelog

Дата Событие
07.08.2026 Задача 8 разобрана. Root cause: by-design архитектура Open WebUI. Принято решение по варианту A. Follow-up: пилот варианта C на 15 мин.