Конфигурация

Поставляется с настройками по умолчанию. Сервис идет с готовым файлом config.toml, в котором большинство параметров уже заполнены разумными значениями. Вы можете запустить сервис «из коробки» или изменить конфигурацию под свои задачи.
Как читать эту страницу: у каждого параметра указан тип. Параметры, отмеченные как обязательные, не имеют встроенного значения по умолчанию: без них сервис не запустится. В поставляемом service/config.toml все обязательные поля уже заполнены. Для остальных параметров, если в конфиге значение не задано, используется встроенное значение по умолчанию, указанное на этой странице.
PRO-режим определяется поставляемым исполняемым файлом. Free-версия не поддерживает секцию [pro]; PRO-версия включает ее принудительно. Значение pro.enabled в config.toml игнорируется.
Важно: Все настройки находятся в файле config.toml. Параметры без встроенного значения по умолчанию обязательны и должны быть указаны в конфиге.

[csv] — Параметры CSV-импорта

default_delimiter Option\ ","
Разделитель CSV по умолчанию, используемый командой sku-cli import при запуске с флагом --config config.toml, если не переопределен явно через --delimiter.
  • Обычно "," или ";"
  • Применяется только в CLI; сам сервис CSV не парсит

[server] — Сетевые параметры

bind String "0.0.0.0:8080"
Адрес и порт, на котором сервис слушает запросы.
  • Локальная разработка: "127.0.0.1:8080"
  • Production / Docker: "0.0.0.0:8080"
  • IPv6: "[::1]:8080"
request_timeout_ms u64 обязательный
Максимальное время обработки одного HTTP-запроса (мс), используемое для диагностики. При превышении половины этого значения в лог выводится предупреждение "Slow request". Полноценный HTTP-таймаут с возвратом 504 Gateway Timeout в текущей версии не реализован.
  • Пакетная загрузка (до 500 элементов): 3000-5000 мс
  • Интерактивный поиск: 1000-2000 мс
max_batch_size usize 500
Максимальное количество элементов в одном запросе `/add`, `/find`, `/delete`.
  • Рекомендуется: 100-300 для 1С, до 500 для фоновой синхронизации, 1 000-5 000 для массовой первичной загрузки при мощном CPU/SSD.
  • При превышении вернется 400 Bad Request.
  • Защита от перегрузки CPU и RAM.
  • Большой batch требует большего max_request_body_size_mb и соответствующего client_max_body_size в nginx. Подробные замеры и рекомендации — в разделе Производительность массовой загрузки.
max_request_body_size_mb usize 20
Максимальный размер HTTP-тела запроса (в мегабайтах).
  • Влияет на лимит тела, который накладывает Axum до разбора JSON
  • Должен быть достаточен для max_batch_size с самыми длинными полями (name, supplier, описания и т.п.)
  • При превышении вернется 413 Request Entity Too Large
  • nginx (или другой reverse proxy) должен иметь не меньший client_max_body_size
tokio_worker_threads Option\ автодетект по ядрам CPU
Число worker-потоков Tokio runtime. Задавайте только в окружениях с жесткими лимитами CPU; обычно лучше оставить `null`.
tokio_max_blocking_threads Option\ автодетект
Максимальное число blocking-потоков Tokio. Увеличьте, если /add с большими батчами сталкивается с "blocking pool full".

[site] — Режим работы "Только для сайта" (API Gateway / Frontend Proxy)

enabled bool false
Включить режим read-only "только для сайта". Мутационные эндпоинты отключаются только при комбинации enabled = true и readonly = true. Остаются только чтение: /find, /export, /health, /api/search-config и статика.
readonly bool false
Работает в паре с enabled. Когда enabled = true и readonly = true, все мутации отключены. При enabled = false значение readonly не влияет на доступность мутаций.
Важно: `/find` остается доступен, потому что это поисковый запрос с телом (HTTP POST). Все остальные POST/PUT/DELETE/PAТCH-блокируются.

[license] — Лицензирование PRO

Параметры лицензирования настраиваются при сборке PRO-версии и зависят от вашего лицензионного сервера. Детали конфигурации публичной документации не раскрываются.

[index] — Полнотекстовый индекс

path String обязательный
Путь к директории поискового индекса.
  • Создается автоматически при старте
  • Размещайте на быстром SSD (NVMe предпочтительно)
  • Не используйте NFS, SMB — резкое падение производительности
writer_ram_budget_mb usize обязательный
Объем RAM для буфера записи индекса (МБ).
  • < 100 000 записей: 50-100 МБ
  • 100 000-500 000: 150-250 МБ
  • > 500 000: 300-500 МБ
  • Больше = реже диск I/O, быстрее массовая загрузка
В PRO-сборке можно переопределить это значение через [pro.index].writer_ram_budget_mb. Если [pro.index].writer_ram_budget_mb = 0 (default), используется верхнеуровневый параметр [index].writer_ram_budget_mb.
fuzzy_max_distance u8 обязательный
Максимальное расстояние Левенштейна для нечеткого поиска. Задается явно в конфиге.
  • 0: только точные совпадения (макс. скорость)
  • 1: одна опечатка (рекомендуется для production)
  • 2: две опечатки (+10-15% recall, но в 1.5-2 раза медленнее)
Морфология и падежи. Сервис использует русский стеммер, но пост-фильтрация результатов опирается на fuzzy_max_distance. С типовым значением 1 поиск хорошо ловит отдельные опечатки («блот» → «болт»), но может пропускать разные падежные формы («болтом», «болты»), потому что после стемминга они дают один и тот же корень, а расстояние Левенштейна между исходными формами бывает равно 2.

Если в вашей предметной области важен поиск в разных падежах (например, пользователи вводят «стальным болтом» вместо «стальной болт»), установите fuzzy_max_distance = 2. В наших замерах скорость при этом остается в диапазоне 15–20 мс на 50 000 товаров.
Поисковый индекс не гарантирует стабильную работу при значениях \>2. Не используйте \>2 в production.
auto_recreate_on_schema_mismatch bool false
Автоматически пересоздавать индекс, если его схема не совпадает с ожидаемой (например, после обновления кода или изменения конфигурации).
  • false (по умолчанию): сервис не запустится и сообщит об ошибке SchemaError. Используйте, если потеря индекса недопустима.
  • true: старый индекс переименовывается в ./data/index.bak.<timestamp>, создается новый пустой индекс. Сервис продолжит работу, но данные нужно будет загрузить заново.
Включайте `true` только если у вас есть надежный источник данных для переиндексации (CSV, 1С, API). В противном случае сервис запустится с пустым индексом.

[search] — Алгоритмы предобработки и фильтрации

[search.field_weights] — Веса базовых полей

name f32 1.0
Вес совпадений по названию товара.
code f32 0.8
Вес совпадений по коду товара.
barcode f32 1.0
Вес совпадений по штрихкоду.
art f32 0.6
Вес совпадений по артикулу.
min_token_length usize обязательный
Минимальная длина токена для участия в поиске.
  • 1: включает однобуквенные коды ("М", "А", "Б"), но добавляет шум
  • 2: оптимально для номенклатуры (отсекает предлоги, частицы)
  • 3: максимальная скорость, если нет значимых коротких кодов
max_results usize обязательный
Количество лучших совпадений по умолчанию (если клиент не передал `limit`).
use_stopwords bool обязательный
Включить фильтрацию стоп-слов при индексации и поиске.
  • Критично для точности BM25 и скорости
  • Отсекает высокочастотные слова: "упак", "кор", "ящ", "комплект", "набор"
  • Рекомендуется: true
stopwords_path String обязательный
Путь к файлу стоп-слов (одно слово на строку, без кавычек).
  • Загружается при старте. Если не найден — используется встроенный набор
  • Добавляйте отраслевой шум: "упак", "кор", "ящ", "комплект", "набор"
auto_match_threshold f32 обязательный
Относительный порог "надежности" для автоматического сопоставления (0.0-1.0).
  • Финальный порог вычисляется как max(relative_threshold, max_score × auto_match_threshold), т.е. результат должен быть не хуже доли от максимального скора
  • Рекомендуется: 0.85-0.90 для баланса точности/полноты
  • Много ложных срабатываний → увеличьте до 0.92
  • Ничего не находится → снизьте до 0.75-0.80
use_unified_search bool обязательный
Включить унифицированный поиск по `name + code + barcode + art`.
  • true: оператор может ввести "болт м16 78454" в одно поле — найдется
  • false: поиск только по полю name (быстрее, но менее гибко)
  • Рекомендуется: true для интеграции с 1С/Excel
transliteration_enabled bool false
Исправление опечаток при вводе на неправильной раскладке клавиатуры.
  • "ghbdtn" → "привет"
  • Экспериментальная функция, может давать ложные срабатывания
  • Включайте, если пользователи часто забывают переключить раскладку
transliteration_threshold f32 0.4
Порог уверенности при транслитерации (встроенный default 0.4). Снизьте, если мало срабатывает, повысьте при ложных совпадениях.
relative_score_threshold f32 0.5
Относительный порог скоринга (0.0-1.0).

Результаты с score < (max_score × relative_score_threshold) отфильтровываются.

  • 0.50: мягкая фильтрация (default, оставляет 50% от лучшего)
  • 0.55: баланс точности/полноты (рекомендуется для production)
  • 0.60-0.70: агрессивно, только очень релевантные
Пример: Найдено 3 кандидата: score 2.0, 1.5, 0.8. При пороге 0.55: 2.0×0.55=1.1 → пройдут 2.0 и 1.5, отсеется 0.8.
Взаимодействие с `auto_match_threshold`: Итоговый порог равен max(relative_threshold, max_score × auto_match_threshold). Результат должен превышать оба значения.
enable_critical_token_filtering bool false
Пост-фильтрация по критичным токенам.

Критичные токены — короткие (≤ critical_token_max_length) ИЛИ содержащие цифры.

Захватывает: М16, 42р, XL, 220V, IP67, DIN125 и т.д.

  • Включите для "грязных" баз, где важно точное совпадение по коротким кодам
  • Отключите, если короткие коды встречаются в каждом товаре (теряете полноту)
Взаимодействие: Работает ТОЛЬКО если `enable_critical_token_filtering = true`. Буст через Aho-Corasick включается отдельно через `enable_aho_corasick`.
critical_token_max_length usize 3
Максимальная длина токена, чтобы считаться "критичным".
  • М16 (3 символа) — критичный при значении 4
  • DIN125 (5 символов) — НЕ критичный при значении 4
  • Увеличьте до 5, если у вас есть значимые 5-символьные коды (DIN125, ГОСТ7798)
min_token_match_ratio f32 обязательный
Минимальное покрытие токенами (0.0-1.0).

Доля токенов запроса, которые должны совпасть в результате.

  • 0.5: минимум 50% токенов должны совпасть (рекомендуется)
  • 0.7: строже, 70% токенов (меньше ложных срабатываний)
  • 0.0: отключить фильтрацию (старое поведение)
Пример: Запрос "болт м16 оцинкованный" (3 токена). При пороге 0.5 → минимум 2 токена должны совпасть. "Болт М16 черный" (совпали "болт", "м16") пройдет. "Гайка м16" (совпал только "м16") отсеется.
Взаимодействие: Применяется ДО `relative_score_threshold`. Товары, не набравшие нужное количество совпавших токенов, даже не попадают в ранжирование.
candidate_multiplier usize обязательный
Множитель количества кандидатов для поиска. `limit × candidate_multiplier` — сколько документов будет извлечено из индекса перед финальной сортировкой.
  • Больше → выше точность, но медленнее
  • Меньше → быстрее, но можно пропустить релевантные результаты
  • Рекомендуемый диапазон: 2-5
extended_search_enabled bool false
Включить расширенный поиск по динамическим полям (PRO-only).
  • true: можно искать по supplier, brand, color и т.д.
  • false: динамические поля игнорируются
Взаимодействие: Если `false`, все `[[search.extended_fields]]` игнорируются, даже если они описаны в конфиге.
require_name_for_fuzzy bool true
Ключевой параметр для коммерческого режима!
  • true: для нечеткого поиска обязательно наличие name (режим совместимости, default)
  • false: можно искать ТОЛЬКО по динамическим полям, без указания name (коммерческий режим)
Когда менять: Установите `false`, если хотите искать товары по поставщику, бренду или ТН ВЭД, даже не зная названия. Также включите `enable_attrs_indexing = true` и задайте `[[search.extended_fields]]` в PRO.
absolute_min_score f32 0.01
Абсолютный минимальный скор для фильтрации результатов.

Защита от ситуации, когда все результаты имеют очень низкий score и относительный порог отбрасывает все.

  • Рекомендуемое значение: 0.01-0.05
  • Не меняйте без крайней необходимости
max_boolean_clauses usize 500
Максимальное количество условий в одном поисковом запросе.

Защита от экспоненциального роста запросов при сложных поисках.

  • Рекомендуемое: 300-1000
  • 500 — баланс безопасности и точности
  • При превышении — лишние клаузулы отбрасываются с предупреждением
allow_empty_name bool false
PRO-only. Режим "Справочник/Ключи".
  • Если true и name пустой — позволяет добавить/найти товар без названия, отключая стемминг/эмбеддинги для пустого имени.
  • Документ индексируется только по ID, code, art и т.п.
  • Рекомендация: true для справочников, где название неизвестно при загрузке; false для стандартного каталога.
enable_attrs_indexing bool false
PRO-only. Индексировать ли JSON-атрибуты 1С (attrs) для быстрых фильтров.
  • Включает точный поиск по реквизитам. Требует больше места на диске.
extra_filter_mode string "hard"
Как обрабатывать произвольные поля extra при поиске. Работает только при enable_attrs_indexing = true.
  • "hard" — точный фильтр: в результаты попадают только товары, у которых ВСЕ указанные в запросе extra-поля совпадают точно. Это поведение по умолчанию.
  • "soft" — бустирование: совпадение по extra увеличивает скор товара, но не отсекает товары без совпадения. Регулируется весом search.weights.extra_match_boost.
  • "off" — игнорировать extra при поиске: поля возвращаются в ответе, но не влияют на выборку и ранжирование.
При переходе между режимами переиндексация не требуется: логика применяется на этапе пост-обработки результатов.
enable_deep_1c_parsing bool false
Глубокий парсинг 1С-ссылок (ref, GUID, URI).
  • Автоматически извлекает ID из строк вида "e1cib/data/...?ref=..." или "{GUID} Название".
  • Рекомендация: включайте, если в name часто приходят 1С-ссылки; иначе оставьте false для экономии CPU.
case_sensitive_fields array [\["id"\]]{.param-default}
Поля, точный поиск по которым будет РЕГИСТРОЗАВИСИМЫМ (учет больших/маленьких букв).
  • Обычно используется для артикулов, штрихкодов, внутренних кодов.
  • Влияет только на прямой поиск по полю: query.code, query.art, query.barcode. Например, при case_sensitive_fields = ["code"] запрос code="ABC-123" найдет только ABC-123, а code="abc-123" — нет.
  • Поиск через общее поле name (unified search) остается регистронезависимым: запрос name="abc-123" найдет товар с code="ABC-123".
  • Чтобы регистрозависимость exact-поиска заработала для уже загруженных данных, выполните переиндексацию после изменения этого параметра.
case_sensitive_extra_fields array [\[\]]{.param-default}
PRO-only. Дополнительные поля для регистрозависимого exact-поиска.
  • Поиск по каким дополнительным полям будет РЕГИСТРОЗАВИСИМЫМ при прямом указании в запросе.
  • Как и case_sensitive_fields, не влияет на поиск через общее поле name.
merge_min_segments usize 8
Минимальное число сегментов поискового индекса для автоматического слияния. Меньшее значение дает более компактный индекс, но чаще тратит CPU на слияние.
merge_max_size_bytes u64 100000000 (100 МБ)
Максимальный размер сегмента (в байтах), который еще участвует в merge. `0` = ограничения нет.
search_timeout_ms u64 5000
Не реализовано. Парсится, но на поиск не влияет. Ошибка 408 Request Timeout не возвращается.
index_timeout_ms u64 30000
Не реализовано. Парсится, но на операции записи в индекс не влияет.
embedding_timeout_ms u64 10000
Не реализовано. Парсится, но на работу эмбеддингов не влияет.

[search.weights] — Веса разных типов совпадений

Для чего это нужно: Сервис может найти товар разными способами: точное совпадение, нечеткое (опечатки), совпадение в "сыром" поле. Эти веса говорят сервису, какой способ важнее.
exact_match_weight f32 1.0
Вес точных совпадений. Обычно не меняется — точные совпадения самые надежные.
  • Увеличить (1.2-1.5) → точные совпадения выше в результатах
  • Уменьшить (0.8-0.9) → точные совпадения менее важны
fuzzy_match_weight f32 0.7
Вес нечетких совпадений (с опечатками).
  • Много опечаток → увеличьте до 0.8-0.85
  • Нечеткий поиск часто ошибается → уменьшите до 0.5-0.6
Взаимодействие с `fuzzy_max_distance`: Если `fuzzy_max_distance = 0`, этот вес не применяется (нечеткий поиск отключен).
raw_match_weight f32 0.8
Вес совпадений в "сыром" поле (без приведения к основе).

Пример: запрос "болты" ищет "болты" (точное совпадение), а не "болт" (основа).

Обычно не требует изменения. Стоит между точным (1.0) и нечетким (0.7).
coverage_boost_per_token f32 0.2
Бонус за каждый совпавший токен.

Формула: score × (1.0 + matched_tokens × coverage_boost_per_token)

  • Запрос "болт м16 оцинкованный" (3 слова). Товар содержит все 3 → бонус 3×0.2=+60%
  • 0.1 — слабый бонус, 0.2 — баланс, 0.3 — сильный
Взаимодействие: Применяется ДО `relative_score_threshold`. Высокий бонус может "протащить" товар с низким исходным скором через порог отсечения.
prefix_boost f32 1.15
Бонус, если название товара начинается с токена запроса.
  • Запрос "болт" → "Болт м16" получает бонус
  • "Гайка болт" — не получает (начинается с "гайка")
  • 1.0 — без бонуса, 1.15 — +15%, 1.3 — +30%
type_weight f32 1.0
Множитель к скору при точном совпадении по полю type.
desc_weight f32 0.85
Дополнительные веса для совпадения по полям
  • Поле desc (точное совпадение)
  • Точное совпадение по полю desc получает дополнительный бонус
ref_weight f32 1.0
Множитель к скору при точном совпадении по полю ref.
attrs_exact_weight f32 1.0
Множитель к скору при точном совпадении по JSON-атрибутам (динамическим extra-полям), найденным через search_by_attrs.
attrs_flat_weight f32 0.7
Вес текстового буста через плоские атрибуты
  • Текстовый буст через плоские атрибуты
extra_match_boost f32 0.3
Множитель буста при совпадении по произвольным полям extra в режиме extra_filter_mode = "soft".
  • 0.0 — совпадение по extra не влияет на скор.
  • 0.3-0.5 — мягкое приоритезирование: подходящие товары поднимаются выше, но не вытесняют релевантные по названию.
  • 1.0-2.0 — сильный буст: товары с совпавшими extra могут оказаться на первых местах даже при менее точном совпадении по name.
Этот вес используется только в режиме "soft". В режиме "hard" совпадение по extra является обязательным фильтром, а в режиме "off" поля игнорируются при поиске.

\[search.fuzzy\] — Тонкая настройка нечеткого поиска

short_query_fuzzy_distance u8 3
Расстояние Левенштейна для однотокенных коротких запросов. Применяется только к запросам из одного токена; эффективное расстояние ограничено fuzzy_max_distance + 1.
  • 1: минимальное расширение
  • 2: стандартное (рекомендуется)
  • 3: максимальное (может давать ложные срабатывания)
Побочный эффект: при стандартных значениях fuzzy_max_distance = 1 эффективное расстояние будет 2, т.е. пример "перф" → "перфоратор" (расстояние 5) недостижим. Если много ложных срабатываний — уменьшите до 2.
short_token_max_len usize 4
Максимальная длина токена, считающегося "коротким".
  • 3: "пер" (короткий), "перф" (обычный)
  • 4: "перф" (короткий), "перфо" (обычный)
  • 5: "перфо" (короткий)
Взаимодействие: Токены короче этого порога получают увеличенное расстояние Левенштейна (`short_query_fuzzy_distance`). Длинные токены используют стандартное `fuzzy_max_distance`.
phrase_min_len usize 2
Не реализовано. Порог phrase search захардкожен: точная фраза ищется при наличии двух и более токенов. Значение парсится, но не влияет на поведение.
phrase_boost f32 4.0
Множитель скора для точных фразовых совпадений.
  • 1.0: без буста
  • 2.0: умеренный буст
  • 4.0: сильный буст (рекомендуется)
  • 8.0: экстремальный (только для точных совпадений)
Слишком высокий буст может "задавить" другие релевантные результаты. Рекомендуется 3.0-5.0.

[search.strategy] — Как сервис ищет: быстро или точно

Для чего это нужно: Последовательный поиск — точнее, булевый — быстрее. Эти настройки говорят сервису, когда использовать какой способ.
auto_select_strategy bool true
Автоматически выбирать стратегию поиска.
  • true: короткие запросы (1-3 слова) → последовательный (точнее), длинные (4+) → булевый (быстрее)
  • false: всегда последовательный (максимальная точность)
Рекомендуется `true` для production.
sequential_max_tokens usize 3
Максимальное количество токенов для последовательного поиска.
  • 2: быстрый переход на булевый (меньше точности)
  • 3: сбалансированный (рекомендуется)
  • 5: максимальная точность для длинных запросов (медленнее)

[search.edge_ngram] — Префиксный поиск для коротких запросов

Для чего это нужно: Пользователь ищет "перф", а в базе есть "Перфоратор". Обычный поиск не находит, потому что "перф" сильно короче. N-gram разбивает слова на части и находит даже по короткому началу.
enabled bool true
Включить Edge N-gram поиск.
Важно: При включении размер индекса увеличивается на 30-40%.
min_gram usize 3
Минимальная длина префикса.
  • 2: найдет даже по 2 буквам ("пе" → "перфоратор"), но больше шума
  • 3: оптимально для русского языка (рекомендуется)
  • 4: только по 4 буквам ("перф" → "перфоратор")
max_gram usize 15
Максимальная длина префикса.
  • 5-6: оптимально (баланс)
  • 8-10: точнее, но индекс больше
  • 15: индекс в 2 раза больше
min_query_len usize 2
Запросы короче этого числа ищутся обычным способом. Защита от мусора по 1 букве.
max_query_len usize 6
Только запросы короче этого числа идут через N-gram. Длинные запросы хорошо ищутся обычным поиском.
boost f32 1.5
Буст для результатов, найденных через N-gram. `1.2` — небольшое преимущество, `1.5` — баланс, `2.0` — сильное.
prefix_boost f32 1.2
Дополнительный буст для слов, которые начинаются с искомого токена. "перф" → "Перфоратор" получает буст, "Электроперфоратор" — нет.

[search.extended_fields] — Динамические поля

Для чего это нужно: Разные товары могут иметь разные наборы полей. Обувь — цвет, размер. Холодильники — диагональ, бренд. Вы описываете ВСЕ поля один раз, сервис индексирует только те, которые есть у конкретного товара.
field String
Имя поля (как будет называться в JSON).
weight f32 обязательный
Важность поля при ранжировании. Используется как множитель при точном совпадении по динамическому полю.
  • Для кодов (tnved, артикулы): 0.8-1.0
  • Для названий (бренд, поставщик): 0.5-0.7
  • Для характеристик (цвет, размер): 0.3-0.5
stemmed bool true
Приводить ли слова к основе (стемминг).
  • true: "поставщики" найдет "поставщик"
  • false: только точное совпадение (для кодов и артикулов)
fuzzy bool true
Разрешить нечеткий поиск (опечатки) для этого поля.
  • true: "Ромашка" найдет "Ромашкаа"
  • false: только точное совпадение

[pro] — Профессиональные фичи (Enterprise)

ВСЕ настройки в этой секции работают ТОЛЬКО в PRO-версии. PRO-режим определяется поставляемым исполняемым файлом; параметр pro.enabled в конфиге игнорируется.
enabled bool false
Показывает, активен ли Pro-режим. Значение определяется поставляемым исполняемым файлом и не может быть изменено через конфиг.
cache_enabled bool false
Кэширование результатов поиска. Повторные одинаковые запросы возвращаются мгновенно. Включайте при высокой нагрузке и стабильном запросном потоке.
cache_size usize 1000
Максимум записей в кэше (LRU).
cache_ttl_seconds u64 300
Время жизни кэша (секунды). 300 = 5 минут.
analytics_enabled bool false
Включить аналитику популярных запросов. Данные доступны через `GET /admin/analytics/stats` (PRO).
analytics_max_queries usize 1000
Максимальное количество уникальных запросов в аналитике.
adaptive_pool_enabled bool false
Включить адаптивный пул потоков для ONNX Runtime. Если `false`, используется фиксированный пул на `pool_min_threads`..`pool_max_threads` потоков.
pool_min_threads usize 2
Минимальное число потоков в пуле для ONNX/эмбеддингов.
pool_max_threads usize 16
Максимальное число потоков в пуле. Не устанавливайте значительно выше числа физических ядер.

[pro.index] — Продвинутые настройки индексации (PRO)

writer_ram_budget_mb usize 0
Бюджет RAM для писателя индекса в PRO-режиме (МБ). Если 0 — используется значение из [index].writer_ram_budget_mb. Положительное значение переопределяет верхнеуровневый параметр только в PRO-сборке. При возникновении OOM на индексации установите 0, чтобы вернуться к общему значению.
commit_mode, commit_docs_threshold и commit_timeout_secs пока не реализованы; коммиты идут по стандартной политике поискового индекса.

[pro.cross_codes] — Кросс-коды и аналоги

enabled bool false
Включить поддержку кросс-кодов (группировка аналогов). Требует переиндексации при изменении.
max_group_size usize 30
Максимальное количество аналогов в ответе из одной группы.
  • 10: для быстрых ответов
  • 30: стандарт (рекомендуется)
  • 50-100: для автозапчастей (много аналогов)
include_in_response bool true
Возвращать ли поле `cross_codes` в ответе поиска.
sort_within_group bool true
Сортировать аналоги внутри группы по score.
include_original_in_cross_list bool false
Включать ли исходный документ в список кросс-кодов в ответе.

[pro.search.embedding] — Семантический поиск (векторные эмбеддинги)

Для чего это нужно: Эмбеддинги позволяют искать товары по смыслу, а не по точному совпадению слов. "шуруповерт" найдет "дрель-шуруповерт" и "винтоверт". Требует ONNX модель и достаточно RAM.
active_backend string "bge_m3"
Активный бэкенд эмбеддингов. Возможные значения: `"bge_m3"`, `"e5"`. Бэкенд `"gemini"` не реализован. По умолчанию `"bge_m3"`.
vector_db_path string "./data/vectors.lance"
Путь к векторному хранилищу.
query_cache_enabled bool true
Кэшировать векторы запросов (снижает latency при повторяющихся фразах).

[pro.search.embedding] — Общие настройки эмбеддингов

active_backend — активный бэкенд: "bge_m3" или "e5" (default: "bge_m3"). "gemini" не реализован.
vector_db_path — путь к векторной БД, например "./data/vectors.lance"
vector_store_type — тип хранилища: "lancedb" (default: "lancedb"). Параметр vector_db_type — устаревший синоним, игнорируется.
vector_index_type — тип векторного индекса (default: "auto"). Если не уверены — оставьте "auto".
Доступные значения:
ЗначениеКогда использовать
"auto"По умолчанию. Хранилище само выберет индекс.
"ivf_pq"Большой каталог и ограниченная память.
"ivf_hnsw_sq"Нужна высокая скорость поиска, ресурсов достаточно.
"ivf_hnsw_pq"Компромисс между скоростью и размером индекса.
"ivf_hnsw_flat"Максимальная точность при поиске, но больше места на диске.
"hnsw"Для Qdrant — обычный HNSW-граф. Для встроенного векторного хранилища работает как "ivf_hnsw_sq".

При смене значения старый индекс не перестраивается автоматически. Чтобы применить новый тип, выполните sku-cli embedding clear и снова проиндексируйте товары.

weight_tantivy / weight_embedding — веса полнотекстового поиска и эмбеддингов при гибридном поиске (default: 0.6 / 0.4)
batch_size — размер батча для индексации (default: 64; для bge-m3 рекомендуется 64-100, для e5-small — до 500)
search_limit_multiplier — во сколько раз расширять выборку кандидатов у векторного поиска перед merge (default: 2; рекомендуется 2-5)
indexing_parallelism — параллелизм при индексации векторов (default: 4)
query_cache_enabled — кэшировать векторы запросов (default: true). Параметры query_cache_size и query_cache_ttl_seconds не реализованы; размер и TTL общего кэша задаются через cache_max_size / cache_ttl_seconds.
cache_max_size / cache_ttl_seconds — размер и TTL общего кэша эмбеддингов (default: 1000 / 300)
vector_quantization — квантование векторов (валидация): "f32", "f16", "i8" (default: "f16"). В текущей версии векторное хранилище всегда хранит векторы как Float32; само значение к хранению не применяется.
enable_sparse / sparse_threshold / sparse_rerank_weight — экспериментальная sparse-ветка bge-m3 (default: false / 0.01 / 0.0). В hybrid-режиме прироста точности не дает, по умолчанию выключена.
max_concurrent_inferences — максимальное число параллельных ONNX-сессий (default: 4; для bge-m3 в бенчмарках использовалось 8)
filter_technical_codes — фильтровать артикулы/штрихкоды из текста для эмбеддинга (default: false)
embedding_fuzzy_fallback_enabled — включать fuzzy-fallback для эмбеддингов (default: true). Параметр fs_fuzzy_fallback_enabled не реализован.
lancedb_retry_* / qdrant_retry_* — настройки retry при записи в vector store (default: 3 попытки, задержка 100-2000 мс)
include_fields / exclude_fields — явный белый/черный список полей, включаемых в эмбеддинг
include_extended_fields — включать ли динамические поля в эмбеддинг (default: true)
enable_aho_corasick — использовать Aho-Corasick для быстрой фильтрации технических кодов (default: true). В Free-сборке всегда выключен.
intra_op_threads / inter_op_threads — не реализовано на верхнем уровне. Потоки ONNX Runtime задаются в секции активного бэкенда (bge_m3 или e5).

[pro.search.embedding.bge_m3] — Бэкенд BGE-M3

enabled — включить режим (default: false). Если active_backend = "bge_m3", должен быть true, иначе сервис не запустится.
model_path — путь к ONNX модели, например "./models/bge-m3-int8/model.onnx" (обязательный)
vector_dimension — размерность вектора: 384 / 768 / 1024 (обязательный)
enable_sparse / sparse_threshold / pooling — sparse-ветка и pooling (default: false / 0.01 / ""). Пустая строка в pooling молча преобразуется в "mean".
Pooling — способ получения одного вектора предложения из выхода трансформера:
  • "mean": усреднение векторов всех токенов. Самый стабильный вариант, рекомендуется для E5 и bge-m3.
  • "cls": вектор специального [CLS]-токена. Иногда чуть лучше для классификации, но может быть нестабилен для поиска.
  • "last": вектор последнего токена. Редко используется; может подойти для декодер-подобных моделей.
intra_op_threads / inter_op_threads — потоки ONNX Runtime (default: 0 / 0). Значение 0 означает автовыбор эвристикой ONNX Runtime.
session_pool_size — пул ONNX-сессий (default: 1; увеличьте до 2–4 при высоком concurrency)

[pro.search.embedding.e5] — Бэкенд E5

enabled — включить режим (default: false)
model_path — путь к ONNX модели, например "./models/e5-small-int8/model.onnx" (обязательный)
model_type — "e5-small", "e5-base", "e5-large" (default: "e5-small")
vector_dimension — размерность вектора: 384 / 768 / 1024 (обязательный)
pooling — "mean", "cls", "last" (default: "", молча преобразуется в "mean")
intra_op_threads / inter_op_threads — потоки ONNX Runtime (default: 0 / 0)
session_pool_size — пул ONNX-сессий (default: 1)

[pro.search.embedding.gemini] — Бэкенд Google Gemini

Не реализовано. Бэкенд Gemini отключен в коде. При active_backend = "gemini" сервис молча переключается на bge_m3. Секция сохранена для обратной совместимости, но не влияет на поведение.

[pro.search.embedding.hnsw] — Настройки HNSW индекса

m — количество соседей в HNSW-графе (default: 16). Используется для Qdrant и встроенного векторного хранилища с IVF-HNSW (num_edges).
ef_construction — размер кандидатов при построении графа (default: 200).
ef_search — размер кандидатов на поиске (default: 100). Пока применяется только для Qdrant; встроенное векторное хранилище управляется автоматически.

[pro.search.embedding.lancedb] — Встроенное векторное хранилище

path — путь к векторному хранилищу (default: "./data/vectors.lance").
collection_name — имя таблицы внутри векторного хранилища (default: "embeddings").
quantization — квантование: "f32", "f16", "i8" (default: "f16").

[pro.search.embedding.qdrant] — Qdrant

url / api_key / collection — адрес, ключ и имя коллекции Qdrant
timeout_seconds — таймаут Qdrant (default: 30). Параметр use_grpc не реализован.

[pro.search.embedding.text_config] — Состав текста для эмбеддинга

include_name / name_weight — включать ли name и его вес (default: true / 2)
include_code / include_barcode / include_art — включать ли code, barcode, art (default: false / false / true)
include_extended_fields / include_extended_field_names / exclude_extended_field_names — какие динамические поля включать/исключать
separator — разделитель между частями супер-текста (default: " ")
filter_technical_codes / apply_stopwords — фильтровать технические коды и стоп-слова (default: true / false)
# Пример конфигурации PRO с BGE-M3
[pro.search.embedding]
active_backend = "bge_m3"
vector_db_path = "./data/vectors.lance"
query_cache_enabled = true

[pro.search.embedding.bge_m3]
enabled = true
model_path = "./models/bge-m3-int8/model.onnx"
vector_dimension = 1024
enable_sparse = false
pooling = ""
intra_op_threads = 0
inter_op_threads = 0
session_pool_size = 1

# Пример переключения на E5-small
# [pro.search.embedding.e5]
# enabled = true
# model_path = "./models/e5-small-int8/model.onnx"
# model_type = "e5-small"
# vector_dimension = 384
# pooling = ""
# intra_op_threads = 0
# inter_op_threads = 0
# session_pool_size = 1
Legacy-режим (active_mode = "legacy") удален. Используйте active_backend и секции [pro.search.embedding.bge_m3] или [pro.search.embedding.e5]. Бэкенд Gemini не реализован.

[pro.search.orchestrator] — Оркестратор поиска

fs_enabled bool true
Включить полнотекстовый поиск.
embedding_enabled bool false
Включить семантический поиск (эмбеддинги). Требует валидной ONNX-модели и инициализированного vector DB.
strategy String "fs_only"
Стратегия поиска по умолчанию.
  • "fs_only": только полнотекстовый поиск (быстро, точно, default)
  • "embedding_only": только эмбеддинги (семантический)
  • "hybrid": последовательный гибрид
  • "parallel": параллельный гибрид (максимальная скорость)
Начинайте с `fs_only`; переходите на `hybrid` после проверки качества эмбеддингов.
tantivy_weight / embedding_weight f32 0.6 / 0.4
Веса для гибридного поиска. `score = tantivy_weight × fs_score + embedding_weight × emb_score`.
  • Преимущество полнотекстового поиска: 0.8 / 0.2
  • Сбалансированный (по умолчанию): 0.6 / 0.4
  • Преимущество эмбеддингов: 0.4 / 0.6
score_normalization String "robust"
Метод нормализации скоров перед объединением полнотекстового поиска и эмбеддингов.
  • "min_max": масштабирование на [0,1] по максимуму.
  • "robust": нормализация на 95-й перцентиль, менее чувствительна к выбросам (default).
  • "z_score": центрирование на среднем и деление на std, затем масштабирование z-значений на [0,1].
  • "softmax": экспоненциальное преобразование, сумма скоров после нормализации = 1.
  • "none": не нормализовать, использовать сырые скоры источника.

Режим влияет только на гибридный/параллельный поиск в PRO, когда скоры полнотекстового поиска и эмбеддингов объединяются.

parallel_batch_threshold usize 8
Минимальный размер batch-запроса, при котором оркестратор обрабатывает запросы параллельно. При batch \< threshold работа идет последовательно.

[pro.background] — Фоновая очередь эмбеддингов

Для чего это нужно: Фоновая индексация эмбеддингов ускоряет ответ API в 10-50 раз. Синхронный режим удален; фоновая очередь всегда включена в PRO.
db_path String "./data/embedding_queue.db"
Путь к SQLite базе для очереди.
worker_count usize 2
Количество фоновых воркеров (рекомендуется 2).
batch_size usize 100
Размер батча для чтения задач из очереди перед отправкой в ONNX-модель.
flush_interval_ms u64 5000
Интервал сброса накопленных задач из очереди в worker\'ы (мс).
max_retries u8 3
Сколько раз повторно пытаться выполнить задачу перед перемещением в failed.
lance_write_buffer_size usize 1000
Сколько векторов накапливать перед одной записью в векторное хранилище. Увеличение снижает число версий хранилища, но при медленном потоке worker будет ждать таймаута.
lance_write_flush_timeout_ms u64 5000
Максимальное время хранения векторов в памяти перед принудительным сбросом.
worker_monitor_interval_secs u64 5
Интервал проверки состояния фоновых worker\'ов (сек). 0 = отключить мониторинг.
worker_max_restarts_per_minute usize 10
Максимальное количество автоперезапусков одного worker\'а в минуту. 0 = безлимит.
cleanup_interval_secs u64 3600
Интервал очистки завершенных записей (сек). По умолчанию раз в час.
retention_completed_secs i64 86400
Сколько секунд хранить завершенные задачи. 0 = удалять сразу после обработки. По умолчанию 24 часа.

[pro.plugins.hierarchy] — Иерархические группы (PRO)

enabled bool true
Включить API иерархических деревьев (POST /hierarchy).
default_max_depth usize 5
Максимальная глубина дерева, используемая в API, если не указана явно.
default_limit usize 1000
Лимит узлов в ответе по умолчанию.
include_cross_codes_by_default bool false
Включать кросс-коды в ответы иерархии по умолчанию.

[security] — Безопасность и лимиты

api_keyStringобязательный
API-ключ для аутентификации. Пусто = отключено. Все запросы должны содержать `X-API-Key: значение`.
rate_limit_per_minuteusizeобязательный
Среднее число запросов с одного IP в минуту. 0 = отключено.
rate_limit_burstusizeобязательный
Максимальный burst-размер. 0 = отключено.
rate_limit_window_secsu6460
Окно rate limiter (сек).

[admin] — Администрирование

backup_dirStringобязательный
Каталог для бэкапов индекса.
max_backupsusizeобязательный
Сколько последних бэкапов хранить. `0` — не удалять старые.
optimize_on_startupboolобязательный
Оптимизировать индекс при старте. Может замедлить запуск на больших индексах.

[feedback] — Обратная связь

enabledboolобязательный
Включить сбор обратной связи через `/feedback`.
log_pathStringобязательный
Путь к файлу с записями feedback.
learn_min_token_lenusize3
Минимальная длина токена, который попадает в обучение синонимов.
learn_max_suggestionsusize20
Максимальное число рекомендаций за один вызов `/admin/learn`.
Формат POST /feedback
Endpoint принимает обязательные поля:
  • query_name — исходный запрос пользователя.
  • matched_id_out — ID найденного товара.
  • action — accept, reject или zero_result.

И опциональные поля для улучшенного анализа:

  • product_name, product_art, product_barcode — данные найденного товара.
  • matched_by — поле, по которому произошло совпадение (name, code, art, barcode, attrs).
  • position — позиция товара в выдаче.
  • session_id — ID сессии для анализа реформулировок.
  • expected_id — ID товара, который ожидал увидеть пользователь.

Пример:

{
  "query_name": "болт м10",
  "matched_id_out": "ID-001",
  "action": "accept",
  "product_name": "Болт М10х50 DIN 933",
  "matched_by": "name",
  "position": 1
}
GET /admin/learn — рекомендации
PRO-only. Анализирует `feedback.log` и возвращает массив рекомендаций. Поддерживает фильтр по типу:
curl 'http://localhost:8080/admin/learn?type=synonym'

Типы рекомендаций:

  • synonym — предлагаемые синонимы на основе accept-записей.
  • missing_product — популярные запросы без результатов (zero_result).
  • check_product — товары с высоким reject rate.
  • typo — возможные опечатки и альтернативные написания.

Каждая рекомендация содержит recommendation_type, title, description, confidence (0.0–1.0) и data.

[export] — Экспорт данных

max_rowsusizeобязательный
Максимальное число строк за один запрос экспорта.
default_limitusizeобязательный
Лимит строк по умолчанию, если не задан явно.

[logging] — Логирование

levelStringобязательный
Уровень логирования: `error`, `warn`, `info`, `debug`, `trace`.
console_enabledboolобязательный
Выводить логи в stdout/stderr.
console_formatStringобязательный
Формат консольных логов: `pretty` или `json`. Значение `compact` молча заменяется на `pretty`.
file_enabledboolобязательный
Писать логи в файл.
file_directoryStringобязательный
Каталог для файлов логов.
file_prefixStringобязательный
Префикс имени файла лога.
file_rotate_max_size_mbusizeобязательный
Максимальный размер файла лога в мегабайтах. Если file_rotate_max_size_mb > 0, ротация выполняется по размеру (имеет приоритет над file_rotate_by_age). Если 0 — ротация только по времени.
file_rotate_by_ageStringобязательный
Период ротации, если ротация по размеру отключена (file_rotate_max_size_mb = 0): hourly, daily, weekly.
file_keep_last_nusizeобязательный
Сколько последних ротированных файлов лога оставлять. При 0 старые файлы не удаляются.
file_json_formatboolобязательный
Писать файловые логи в JSON.

[files] — Внешние словари

synonyms_pathStringобязательный
Путь к JSON-файлу синонимов. Файл должен существовать, если используется обучение.