# `:vector-index-jvector` — ANN-индекс поверх JVector (Datadog) ## Что это JVM-only реализация `MutableVectorIndexStore` поверх [JVector](https://github.com/jbellis/jvector) — ANN-библиотеки Datadog (HNSW-подобный граф). Самый быстрый бэкенд в проекте для больших датасетов (10K+ записей). Используется как замена brute-force SQLite-индекса, когда размер датасета перерастает ~10K записей или важна latency на search. ## Где используется Standalone-агентом в JVM-режиме, когда нужно эффективное семантическое поисковое хранилище. Прямо сейчас модуль **не подключён** в `:standalone` — это API-готовый компонент, ждущий интеграции. ## Что внутри ```kotlin class JVectorVectorIndexStore( override val dimension: Int, seedEntries: List = emptyList(), ) : MutableVectorIndexStore { data class SeedEntry(val id: String, val embedding: FloatArray, val payload: String?) override suspend fun getSize(): Long override suspend fun add(id: String?, embedding: FloatArray, payload: String?): VectorIndex override suspend fun delete(id: String): Boolean override suspend fun clear(): Long override suspend fun search(embedding: FloatArray, limit: Int): List override fun close() } ``` **Параметры графа** (как в `:memory-vector/JVectorMemoryIndex`): `M=16, efConstruction=100, neighborOverflow=1.2f, alpha=1.2f`. **Thread-safety:** `ReentrantReadWriteLock` — параллельные `search()` ок, `add`/`delete`/`clear` — эксклюзивно. **`delete()`:** убирает id из `idToOrdinal` + помечает ordinal как удалённый в `BitSet`. Это позволяет повторный `add(id)` после `delete` (без этого упал бы с `VectorIndexAlreadyExistsException`). ## Цели сборки Только `jvm()` — JVector публикуется только как JVM-библиотека (нет KMP-таргетов). Для Apple-целей использовать `:vector-index-ksqlite`. ## Persist **НЕ поддерживается** в v1. JVector'у для записи на диск нужна Feature с `INLINE_VECTORS`, которая в JVector 3.x конфигурируется отдельно и нестабильна. Альтернатива — пара `(JVectorVectorIndexStore, KVectorStore)` с persistence embeddings в SQLite и graph-rebuild на старте. Если persist нужен — это будущая работа. ## Как подключить ```kotlin dependencies { implementation("pw.binom.agentik:vector-index-jvector:0.1.0") implementation("pw.binom.agentik:vector-index-api:0.1.0") } val store = JVectorVectorIndexStore(dimension = 768) store.add(id = "doc-1", embedding = embeddingOf("hello"), payload = """{"src":"chat"}""") val top = store.search(embedding = queryEmbedding, limit = 10) ``` ## Тесты ``` ./gradlew :vector-index-jvector:jvmTest ``` Покрывают: explicit/auto id, duplicate throws, delete+idempotency, clear, top-K sort, payload round-trip, limit > size. ## Зависимости - `io.github.jbellis:jvector:3.0.6` - `pw.binom.agentik:vector-index-api` - `kotlinx-coroutines-core` ## Чего здесь НЕТ - Persist (см. выше). - Фильтрации в `search()` — чистый ANN. - Multi-target / native — только JVM. ## Текущий статус Реализация готова, тесты зелёные. Интеграция в `:standalone` отложена до момента, когда понадобится.