Module: Pikuri::VectorDb::Backend
- Defined in:
- lib/pikuri/vector_db/backend.rb,
lib/pikuri/vector_db/backend/chroma.rb,
lib/pikuri/vector_db/backend/qdrant.rb,
lib/pikuri/vector_db/backend/result.rb,
lib/pikuri/vector_db/backend/in_memory.rb
Overview
Namespace for vector-store backends. Three ship: InMemory (pure-Ruby
cosine, RAM-only — the audit-friendly educational default, pairs with
Server::InMemory); Qdrant (the recommended persistent option — see
pikuri-vectordb/DESIGN.md for the survey — pairs with Server::Qdrant);
and Chroma (the alternative persistent option, pairs with
Server::Chroma).
Backend protocol
Duck-typed, like pikuri's other seams (+Confirmer+, Filesystem,
Sandbox) — no base class. Every backend implements, so the Indexer and
Tools::Search consume them interchangeably:
#upsert(chunks:, vectors:)— insert-or-replace bychunk.id; parallel equal-length arrays,ArgumentErroron empty/mismatch, returnsnil.#query(vector:, top_k:)— top-k nearest by cosine, descendingArray<Result>(empty when the store is);ArgumentErrorontop_k<= 0.#delete_all— empty the store (nuke-and-reload reindex);nil.#count— stored chunk count,Integer.#delete_by_source(source)— scoped counterpart to#delete_all; no-op when absent;nil.#replace_source(source:, chunks:, vectors:)— delete-by-source then upsert as one op (the incremental-reindex unit); atomic on InMemory, two HTTP calls elsewhere (see each backend).nil.#sources_with_hashes—Hash{String => String, nil}, each indexedsource→ content hash; the boot-sweep reference Indexer#reconcile_plan diffs against disk. Inherently O(sources) (removal detection needs the whole set), so once-per-boot, never per-request.#source_indexed?(source)—Boolean; the scoped counterpart for Tools::Read's membership gate, distinct so a hot path never fetches the full manifest to test one key.
The last four exist for incremental reindex + auto-watch; nuke-and-reload uses only the first four.
Vector-dim contract
The first #upsert establishes the vector dim for the backend's lifetime;
later +#upsert+/+#query+ must match or raise ArgumentError — an embedder
swap mid-session would otherwise silently corrupt the index.