Active development · measured on six regression suites

The embedded
search engine for structured records

Records with textual fields (color, material, behavior, condition) deserve better than substring matching or one monolithic vector. PrismDB gives each field its own retrieval strategy and fuses the results, like light through a prism.

Your records say "midnight navy"; your users search "blue". PrismDB learns that at write time: no synonym lists, no per-query LLM. Queries are pure retrieval, ~5ms, deterministic. One Rust binary.

+3 over the production substring baseline on Argus-faithful (37/50 vs 34/50) −8 against the same baseline on Argus v2, 25 dimensions (34/50 vs 42/50)
~5ms warm query zero manual synonyms all six suites, and where the gate costs recall →
"blue leather shoes" LEARNED · NLI color: blue → navy ✓ BM25 material: leather DENSE style: shoes ≈ sneaker ✓
The problem

Structured records with textual fields are everywhere. No search engine handles them well.

Product catalogs, analytics records, IoT anomaly logs, legal documents: each record is a set of independent dimensions, each holding a brief factual description. Existing engines force a bad choice on all of them:

1

Monolithic embeddings

Vector databases encode the entire record as one point. Dimensions cancel each other: a query for "green jacket" competes with "pacing nervously" in the same vector space.

2

Lexical ceiling

Full-text search handles stemming but cannot bridge semantic gaps. "distressed" never finds "sitting on floor holding head".

3

Fuzzy where it must be exact

An enum that should only ever match exactly and a free-text behavior description that must match loosely get the same treatment. No database lets a field choose its own retrieval strategy, so one of the two is always wrong.

4

Query-time expansion tax

Bridging vocabulary at query time (LLM rewriting, on-the-fly synonyms) makes every search slow, costly, and non-deterministic. Curated synonym lists rot. Nobody closes the gap at write time.

Vocabulary expansion

Your records say "midnight navy". Your users search "blue".

PrismDB closes the vocabulary gap at write time through a cost ladder of seven expansion tiers. Each gap is closed by the cheapest tier that closes it: modifiers, NLI sense resolution, ConceptNet parents, synonym edges, lexicon projection, enum aliases, and enum projection cover vocabulary the corpus never contains.

Every tier proposes; none of them decides. A candidate enters the index only if a DeBERTa-v3 MNLI cross-encoder judges that the record's own value entails it, above a fixed 0.70 cutoff. The verdict is cached per unique pair, including the refusals, so a second graduation judges zero pairs it has already seen.

No curated synonym lists. No domain configuration. All inference at write time, cached per unique value. Queries are pure retrieval: the query path runs no generative inference at all. The cost ladder is a comparison rule, not a prohibition: every tier is considered, the cheapest one that works is used.

"midnight navy"
+ "blue" NLI sense
"full-grain cowhide"
+ "leather" ConceptNet
"ultralight slip-on runner"
+ "shoe" NLI sense
"lingering near exit"
+ "loiter" synonym
"fidgeting constantly"
+ "nervous" projection
"PERSON_GENDER_MALE"
+ "male, man" enum alias

Real expansions learned on the public regression datasets. None of these pairs is hardcoded anywhere in the engine.

What the judge refused
"midnight navy"
"red" below cutoff
"pocket square"
"bag" below cutoff
"minimalist topcoat"
"sweatshirt" below cutoff

A tier proposed each of these; the judge declined. The refusals are cached with the same key as the acceptances, so the ladder never pays to re-litigate them.

Capabilities

The intelligence lives in the storage layer

Per-dimension retrieval

Each field gets its own lens (exact, BM25 sparse, or dense vector) in its own semantic space. No monolithic embeddings, no dimension dilution.

Cross-dimension coherence

Results must hold across the dimensions your query actually touched: a precision mechanism monolithic vector search cannot express.

Cost-ladder vocabulary expansion

Seven tiers: modifiers, NLI sense resolution, ConceptNet parents, synonym edges, lexicon projection, enum aliases, enum projection. Each gap closed by the cheapest tier that closes it, and every candidate gated by an NLI cross-encoder before it enters the index. All at write time, cached per pair.

Query decomposition + rewrites

Multi-term queries are split and routed per dimension by IDF + embedding routing. Spell correction, compound splitting, and term merging handle messy input.

Built-in embeddings

BGE-M3 dense (1024d) + NLI judge (DeBERTa-v3) for write-time expansion. Backends: CPU ONNX, NVIDIA GPU, or Apple-GPU MLX sidecar, auto-detected and spawned by the binary. No external services.

Unified in-process engine

One embedded engine (qdrant-edge) holds per-dimension BM25 sparse and dense 1024d vectors with native RRF fusion, one collection per dimension rather than one per corpus. Everything above it is PrismDB: query decomposition and routing, the write-time expansion ladder, the cross-dimension gate, and the temporal axis. Deployment is a single binary.

Temporal axis

Point-in-time, range, and trajectory queries over timestamped streams. Track who was where, when, and in what sequence. Built into the query engine.

Graduation lifecycle

Seal a segment, learn vocabulary from the new data, reindex, and open the next segment. Incremental cost: re-graduation of known vocabulary judges zero pairs.

On the roadmap
Cross-dimension gate at scale
keep true matches when a query routes across many dimensions
Query-log learning
expand vocabulary from real usage patterns
Public benchmark
STaRK-Amazon subset with local baselines on the same data
Client SDKs
Python, Rust, Go; the HTTP API is the stable surface today
Architecture

Single binary, zero external dependencies

A Rust workspace of focused crates. The unified storage engine (qdrant-edge), embedding and NLI models (CPU ONNX, NVIDIA GPU, or Apple-GPU MLX, auto-detected), and SQLite ship in one binary. Deployment is ./prismdb. Like SQLite, it embeds where your data lives.

prismdb-server HTTP API · IDF routing · cross-dim filter prismdb-planner Query Plan · Lens Select prismdb-optimizer Stats analysis (offline) prismdb-cli serve · prefill prismdb-semantic BGE-M3 dense · NLI DeBERTa-v3 · ConceptNet · lexicon prismdb-storage · unified engine (qdrant-edge, in-process) BM25 sparse / dimension Dense 1024d / dimension SQLite · stats + caches prismdb-core
Use cases

Built for records described in words

Wherever a pipeline (often an LLM) produces structured records with free-text fields, the vocabulary it writes never matches the vocabulary people search. That gap is PrismDB's home turf: attribute-decomposed queries over structured records.

Video Analytics Pipelines

appearance clothing activity context
Q "green jacket"
"olive windbreaker zipped to the collar"

Product Catalogs

material color style condition
Q "blue leather shoes"
"midnight navy genuine Italian leather minimalist low-top sneaker"

Legal Discovery

parties topics clauses obligations
Q "indemnity clause limiting liability"
"hold harmless provision capping damages"

IoT / Industrial

anomaly type component severity
Q "overheating in motor 3"
"thermal runaway trend on unit 3 bearing assembly"

Same color, same dimension: each query term routes to its field and matches vocabulary learned at write time.

Quick start

One binary. One HTTP API.

No cluster, no external services. Embeddings run in-process (CPU) or on the local GPU via an auto-spawned sidecar. Declare your dimensions, insert records as plain text, search. Client SDKs (Python, Rust, Go) are on the roadmap; the HTTP API is the stable surface today.

Serve + declare dimensions
terminal
$ prismdb serve --port 6340 --data-dir ./data

$ curl -X POST localhost:6340/api/v1/collections \
    -d '{
      "name": "products",
      "dimensions": [
        {"name": "category", "type": "exact"},
        {"name": "material", "type": "semantic"},
        {"name": "color",    "type": "semantic"},
        {"name": "style",    "type": "semantic"}
      ]
    }'
Search · the prism decomposes automatically
terminal
$ curl -X POST localhost:6340/api/v1/collections/products/search \
    -d '{"query": "blue leather shoes", "limit": 10}'

{
  "results": [{
    "id": "SKU-001",
    "score": 0.94,
    "facts": {
      "color": "midnight navy",      ← matched "blue"
      "material": "Italian leather",
      "style": "low-top sneaker"   ← matched "shoes"
    },
    "matched_dimensions": ["color", "material", "style"]
  }]
}
Status

Not released. Measured, and still moving.

PrismDB is in active development and is not publicly available. The engine runs, the six regression suites are re-measured on every routing change, and the boundaries it has not crossed yet are written down next to the ones it has.

If you work on retrieval over structured records, the interesting conversation is not the feature list: it is where the cross-dimension gate trades recall for precision, what the NLI cutoff refuses, and which of these tiers survives contact with a corpus shaped like yours.