Skip to content

JMFTS

JMFTS is a retrieval appliance. It combines matryoshka embeddings, ColBERT-style late interaction, and BM25 into one hybrid search over PostgreSQL with pgvector.

Three read paths over one tree, fused by rankA document tree at the top left: a root marked parent id null with three children typed transcript, wiki colon arxiv and tau colon conversation, and one grandchild typed tau colon message. A dashed bracket encloses the tau conversation subtree and is labelled parent id, subtree scope. To the right, a panel headed POST slash search slash hybrid lists the request body — parent id, weights of vector 0.60 against bm25 0.40, usetype, limit, rerank and rerank method — and a short line ties its parent id field back to the bracketed subtree. An arrow runs from the tree down into a stack of three hatched, doubled-outline slabs that is the whole store: documents with its 768-dimension embed vector on an HNSW index, search term postings with search term stats, and token embeddings with embed 256 on an IVFFlat index. Legs leave the first two slabs into boxes labelled vector and bm25, and both land on one red bar. The bar is annotated weight over sixty plus rank and marked fused by rank, no similarity survives. A single arrow leaves the bar into a box labelled hybrid, one ranking. Below that the flow forks into an optional second stage: maxsim, fed both by the ranking above and by a long leg from the token embeddings slab, and cross encoder, fed only from above because it reads no table. Both merge into a SearchResponse box holding results, total and latency ms.jmftsone tree, many usetypesparent_id: nulltranscriptwiki:arxivtau:conversationtau:messageparent_idsubtree scopePOST /search/hybrid{"parent_id": "<subtree root>","weights": {"vector": 0.60, "bm25": 0.40},"usetype": "transcript","limit": 20,"rerank": true,"rerank_method": "cross_encoder"}the tree is one tabledocuments768-dim embed · HNSWsearch_term_postings+ search_term_statstoken_embeddingsembed_256 · IVFFlatpostgres + pgvectorJMFTS_TOKEN_EMBED_DIMS[256] populated · 384/512 reservedvectorcosine similaritybm25k1 1.2 · b 0.75weight/(60+rank)fused by rankno similarity surviveshybridone ranking?rerank=truemaxsimreuses token_embeddingsno model to loadcross_encoderJMFTS_RERANKER_MODELreads no tableSearchResponseresults[] · total · latency_ms
One documents table holds the corpus as a tree, so scoping a search is naming a parent rather than standing up a second index. Three read paths come off that one store: the 768-dim document vector, the BM25 postings, and the per-token vectors late interaction needs. Hybrid fuses the first two, and it fuses them by rank — each leg contributes weight/(60+rank), so what comes back is an ordering, not a similarity, and a relevant query and a nonsense one measured the same five scores. Threshold on vector instead. Late interaction arrives as the optional second stage, where the two rerank methods differ by prerequisite rather than by quality: maxsim reads tokens you already stored, cross_encoder loads a model and reads no table.

Where to start

The four categories below are a crosswalk, not a sequence. Pick the cell you are actually in.

Acquisition
Application
Action

Tutorials

Action × Acquisition

A guided build that teaches the concepts as you go. Start at the quickstart and keep going.

Cookbook

Action × Application

Recipes for one specific job, for someone who already knows the basics and wants the steps without the narration.

Cognition

DevOps Manual

Cognition × Acquisition

How the system is deployed and operated, and why it is shaped that way. Read this before you run it in anger.

Reference

Cognition × Application

API surface, config, schemas, invariants. Built for search and lookup, not for reading start to finish.