Symbolic Index for LLM Knowledge — нейро-символическая поисковая архитектура.

Поиск на 64-битных целых числах. Не нужны векторная БД, ANN-граф или модель эмбеддингов.

Репозиторий GitHub

Ключевой тезис

Поиск никогда не был сложной задачей — он был симптомом неструктурированных данных. Если присвоить 64-битную структуру в момент записи, симптом исчезает.

results = index[(index & mask) == pattern]

Поиск по 100 миллионам сущностей Wikidata в 1,3 ГБ памяти менее чем за секунду. Один Python (NumPy) побеждает оптимизированные векторные БД на C++/Rust — победа архитектуры.

Почему не векторные эмбеддинги?

Векторные эмбеддинги уничтожают структуру.

"Суворов — русский полководец эпохи Екатерины II"
 → Человек сразу понимает: русский, военный, XVIII век

Модель эмбеддингов:
 [0.234, -0.891, 0.445, ..., 0.112] (384 измерения float)
 → Структура уничтожена. Невозможно прочитать, person это или location.

Чтобы восстановить уничтоженную структуру:
 ANN-граф (HNSW, IVF-PQ), cross-encoder, reranker, фильтр метаданных...

SILK сохраняет структуру.

SIDX: [Human / military / europe / early_modern]
 → Структура жива в битах. Её можно прочитать.
 → Восстанавливать не нужно. Потому что она не была уничтожена.

Суть — в инверсии порядка.

Традиционно: сначала записать → потом структурировать (индексация)
SILK: структурировать при записи → поиск бесплатен

Битовая раскладка SIDX

SIDX следует спецификации Entity Node грамматики GEUL.

[prefix 7 | mode 3 | entity_type 6 | attrs 48]
 MSB(63)                                  LSB(0)
ПолеБитыРазмерОписание
prefix63-577Заголовок протокола GEUL (фиксированный 0001001, игнорируется при поиске)
mode56-543Режим квантизации/числа (зарегистрированная сущность=0, определённый, универсальный, экзистенциальный и т.д. — 8 режимов)
entity_type53-48664 верхнеуровневых типа (Human=0 ~ Election=62, неклассифицированный=63)
attrs47-048Кодирование атрибутов по типу (определяется кодбуком)

Диапазон поиска: entity_type 6 бит + attrs 48 бит = 54 бита. QID не входит в SIDX и хранится в отдельном массиве.

attrs 48 бит — схема по типам

Human(0):       subclass 5 | occupation 6 | country 8 | era 4 | decade 4 | gender 2 | notability 3 | ...
Star(12):       constellation 7 | spectral_type 4 | luminosity 3 | magnitude 4 | ra_zone 4 | dec_zone 4 | ...
Settlement(28): country 8 | admin_level 4 | admin_code 8 | lat_zone 4 | lon_zone 4 | population 4 | ...
Organization(44): country 8 | org_type 4 | legal_form 6 | industry 8 | era 4 | size 4 | ...
Film(51):       country 8 | year 7 | genre 6 | language 8 | color 2 | duration 4 | ...

Сейчас определена битовая раскладка атрибутов для 5 типов. Остальные кодируются только по entity_type.

Архитектура

В SILK два конвейера: кодирование (при записи) и поиск (при запросе). Оба работают по одному принципу: символическое удерживает структуру, LLM обрабатывает смысл.

Конвейер кодирования (при записи)
┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│  Тегирование │──►│  Проверка    │──►│ Кодирование  │
│  LLM         │   │  VALID       │   │ по кодбуку   │
│  документ →  │   │ допустимые   │   │ JSON → SIDX  │
│  JSON        │   │ значения     │   │ (сборка бит) │
│  (семант.    │   │ проверка     │   │              │
│   классиф.)  │   │ согласован.  │   │              │
│              │   │ галлюц.→откл.│   │              │
└──────────────┘   └──────────────┘   └──────────────┘
   LLM тегирует     код проверяет    кодирование по кодбуку
Конвейер поиска (при запросе)
┌──────────────┐   ┌──────────────┐   ┌──────────────┐
│  Интерпретация│──►│ Фильтр      │──►│  Решение LLM │
│  запроса     │   │ bit AND      │   │ только        │
│  поиск по    │   │  NumPy SIMD  │   │ кандидаты    │
│  кодбуку     │   │100M → десятки│   │ десятки →    │
│  + помощь LLM│   │              │   │ ответ        │
└──────────────┘   └──────────────┘   └──────────────┘
   извлечение       широкая          точное
   смысла           фильтрация       решение

Ключевая стратегия: широкая фильтрация через bit AND по SIDX без потерь, затем LLM решает только по немногим кандидатам.

Каждый делает то, что умеет лучше всего:
 Человек: проектирование структуры (кодбук)
 LLM:  семантическая классификация (тегирование) + семантическое решение (поиск)
 Код: проверка правил (VALID) + сборка битов
 CPU:  массовое сравнение (NumPy SIMD)

Кодирование: тегирование LLM → проверка VALID

LLM читает документ и тегирует в JSON. VALID выполняет механическую проверку по кодбуку. Значения, отсутствующие в кодбуке, нарушения согласованности между типами и нарушения ограничений физически не могут попасть в индекс.

Тегирование LLM: {"type": "Human", "occupation": "military", "country": "russia"}
VALID:    occupation="military" ∈ кодбук? ✓  country="russia" ∈ кодбук? ✓
          Human с полем constellation? ✗ отклонён
Кодирование: "military"→6 бит, "russia"→8 бит из кодбука → сборка битов → SIDX uint64

LLM может галлюцинировать. Но VALID играет роль привратника, поэтому вероятность загрязнения индекса равна нулю. Только JSON, прошедший VALID, кодируется в 64-битное целое SIDX по кодбуку.

Поиск: широкая фильтрация, LLM сужает

1. Извлечение смысла запроса   поиск по кодбуку 80% / помощь LLM 20%
2. Сборка битовой маски        детерминированно — алгоритм
3. bit AND через NumPy         детерминированно — полный скан 100M за 20мс
4. Финальное решение LLM       только немногие кандидаты — точное семантическое решение

80% поиска — структурные запросы

"Суворов"       → Q484523 exact match. bit AND. Готово.
"новости Samsung" → org/company + doc_meta/news. bit AND. Готово.
"саммит Байден-Си" → Q6279 ∩ Q15031 ∩ meeting. Пересечение. Готово.
Структурные запросы (80%): bit AND в SILK достаточно. LLM не нужен.
Семантические запросы (15%): SILK сужает кандидатов → LLM решает по 5-10 случаям.
Генеративные запросы  (5%): SILK определяет документ → LLM генерирует.

Multi-SIDX

Один документ/событие несёт несколько SIDX.

Новостная статья "Встреча глав Samsung, NVIDIA и Hyundai":

SIDX[0]: [Human / business / east_asia ]  Ли Джэён
SIDX[1]: [Org   / company / east_asia ]  Samsung
SIDX[2]: [Human / business / n_america]  Дженсен Хуанг
SIDX[3]: [Org   / company / n_america]  NVIDIA
SIDX[4]: [Human / business / east_asia ]  Чон Ый Сон
SIDX[5]: [Org   / company / east_asia ]  Hyundai
SIDX[6]: [Event / meeting / east_asia ]  встреча

Всё — одинаковые 64-битные SIDX. Один индекс. Один bit AND для поиска. Поле entity_type различает сущности (Human, Org) и события (Event).

Структура индекса

sidx_array = np.array([...], dtype=np.uint64)  # 108.8M × 8B = 870MB
qid_array  = np.array([...], dtype=np.uint32)  # 108.8M × 4B = 435MB
# Всего ~1.3GB памяти
Построение индекса:
 Elasticsearch: токенизация → анализ → обратный индекс → слияние сегментов
 Pinecone:      эмбеддинг → HNSW-граф → кластеризация
 SILK:          sort

Никаких структур данных. Один отсортированный массив.

Сравнение с векторными БД

SILKВекторная БД
Размер индекса (1 трлн записей)12TB1,5PB (в 125 раз)
Построение индексаsortHNSW — дни
Холодный стартоткрыл файл — готовопостроение графа — часы
Разделённый сканвозможен (результат идентичен)невозможен (граф разрывается)
Сложные условияпересечение (точно)сжатие в один вектор (приблизительно)
Результатыточные (множественные операции)приблизительные (ранжирование по сходству)
РевизияJSON (белый ящик)невозможна (чёрный ящик)
bit AND не зависит от порядка, без состояния, допускает агрегацию.
Векторная БД: весь граф должен быть в памяти. Разделение = разрушение.
SILK:    режь где угодно — работает. Разделение = только медленнее. Результат идентичен.

Конвейер ревизии

Векторные эмбеддинги — чёрный ящик, ревизия невозможна. SIDX — это JSON, ревизия возможна.

Этап 1 — тегирование малой LLM    Llama 8B / GPT-4o-mini. Точность 85-90%.
Этап 2 — механическая проверка VALID  допустимые значения, согласованность, ограничения. Стоимость $0.
Этап 3 — ревизия большой LLM      только confidence=low. Точность 99%+.

VALID — привратник: галлюцинации за пределами допустимых значений кодбука физически не могут попасть в индекс.

Лицензия

MIT — Репозиторий GitHub