Uma consulta ao diretório.
Uma varredura contígua.
A busca vetorial filtrada é geralmente um scatter-gather por um índice que nada sabe sobre seu filtro. O Telys controla o layout físico: na chave de partição, vizinhos-mais-próximos-onde-chave-igual-a-x é uma consulta O(1) ao diretório mais uma varredura sequencial de um bloco contíguo. Esta página percorre o runtime em produção hoje e, em seguida, a arquitetura para a qual ele está convergindo — rotulada como spec.
A engine controla onde cada vetor reside.
Uma collection declara partition_by na criação, e o layout segue a chave. O segmento base é clusterizado por partição — cada chave mapeia para uma fatia contígua — e escritas recentes ficam ao lado em um delta mutável com formato Arrow.
Clusterizado por partição
Vetores armazenados ordenados por chave de partição, de modo que cada partição é um bloco contíguo. Uma consulta com escopo lê uma sequência contínua de memória, não linhas dispersas por um índice.
O(1) chave → fatia
Um diretório mapeia cada valor de partição ao seu (offset, length) no segmento base. Resolver o filtro é uma consulta ao dicionário, não uma travessia de índice.
Escritas com formato Arrow
add e upsert acrescentam aqui, cada linha marcada com um LSN de escrita monotônico. O delta é consultável imediatamente e se une à fatia base por um único caminho de varredura.
O que uma consulta com escopo executa.
col.search(qvec, where={"tenant_id": "acme"}, top_k=10)
O filtro nomeia a chave de partição com a qual a collection foi criada.
Consulta O(1): o valor da partição resolve para (offset, length) no segmento base. Sem geração de candidatos, sem ponto de entrada em grafo.
Pontuação exata SIMD sobre um bloco sequencial. O recall neste caminho é 1,0 — é uma varredura, não uma aproximação. Os valores medidos de p50/p95 para esta etapa são publicados na página de benchmarks, cada um vinculado ao seu gate de recall e rig.
Linhas com a mesma chave no delta em formato Arrow são pontuadas pelo mesmo caminho. Uma escrita fica visível para a próxima consulta imediatamente.
Hits filtrados pelo LSN do snapshot: versões tombstoned e supersedidas nunca emergem. Top-k retorna com o payload do explain anexado.
Partições superdimensionadas seguem um fork declarado: build_ivf posiciona um IVF por partição sobre qualquer partição acima do limiar de linhas, e as consultas são roteadas por ele com um rerank exato — calibrado contra um piso de recall e nomeado no plano.
Todo resultado nomeia seu plano.
explain=True retorna o plano físico que a consulta efetivamente executou. Na chave de partição, você obtém o scan de fatia contígua. Partições superdimensionadas declaram o fork IVF. Filtros fora da chave recaem em scatter-gather — e o payload explica o motivo.
hits = col.search(qvec, where={"tenant_id": "acme"}, top_k=10, explain=True)
hits["explain"]["plan"]
# on the partition key → "PartitionSliceExactF32" # one contiguous slice, exact, recall 1.0
# oversized partition → "PartitionIVFRerankF32" # per-partition IVF + exact rerank
# off-key filter → "ScatterGatherExact" # fallback — and it says why:
hits["explain"]["fallback_reason"]
# "path is not the physical partition key"Nada é sobrescrito. Versões são supersedidas.
O modelo de escrita é MVCC append-only. upsert grava uma nova versão de um id lógico e marca a anterior como supersedida; delete posiciona um tombstone em um LSN de exclusão; snapshot() fixa uma visão de leitura consistente; compact() incorpora o delta à base e descarta o que nenhum snapshot pode ver.
col.upsert(vectors, ids=ids, metadata=metadata) # a new version; the prior one is superseded col.delete(["doc-41"]) # tombstone at a delete LSN — no in-place erase lsn = col.snapshot() # pin a consistent read view at an LSN col.compact() # fold delta into base; drop superseded rows col.build_ivf(min_rows=20000, target_recall=0.98)
| Chamada | O que faz |
|---|---|
| adicionar / add_texts | Insere novas linhas. Ids duplicados são rejeitados — uma segunda linha física para um id lógico exige upsert, por design. |
| inserção / upsert_texts | Grava uma nova versão de um id lógico; a versão anterior é supersedida, nunca sobrescrita no lugar. |
| buscar / search_text | Top-k filtrado. explain=True anexa o plano físico ao resultado. |
| delete | Aplica tombstone em linhas lógicas em um LSN de exclusão. |
| compact | Incorpora o delta ao segmento base; descarta versões tombstoned e supersedidas. |
| build_ivf | Constrói IVF por partição sobre partições acima do limiar de linhas, calibrado a um piso de recall. |
| snapshot | Retorna um LSN que fixa uma visão de leitura consistente. |
| save / stats | Persiste a coleção em disco; reporta contagens de linhas, partições e informações de layout. |
Tudo abaixo é especificação, não referência de API publicada. É o substrato para o qual o runtime está convergindo. A interface voltada ao SDK está congelada, de modo que a troca subjacente é invisível para os chamadores.
Um planner. Um IR plano. Um executor.
Três front ends convergem para um único planner, que emite uma representação intermediária física plana, executada por um executor vetorizado Mojo diretamente sobre buffers Arrow.
O modelo de memória (remember · recall · as_of), a API de consulta (point_get · scan · search · hybrid_search) e o fabric. Um contrato de entrada único; nenhum engine por API.
Planejamento lógico e físico em um único lugar. A seletividade é estimada a partir de estatísticas de segmento; o plano é explícito e retornado com o resultado.
Um array plano de operadores vinculados por slots inteiros. O registrador entre operadores é um row set — um bitmap, row-ids ordenados ou um vetor de seleção.
Execução vetorizada sobre buffers Arrow e arrays de candidatos FAISS. O hot path SIMD permanece fora do Python; páginas Parquet comprimidas são decodificadas em scratch buffers primeiro.
A camada de mutação
Um write-ahead log para durabilidade e ordenação, e um delta mutável em formato Arrow para visibilidade imediata — a camada de tabela que o Parquet não oferece por conta própria.
Selados, imutáveis
Segmentos colunares comprimidos e duráveis. Estatísticas de rodapé orientam a poda de segmentos e row-groups; arquivos selados nunca são mutados.
FAISS ANN
Índices FAISS por segmento, vinculados ao checksum e à versão do segmento, mapeados como somente leitura com tempo de vida atrelado ao snapshot de leitura.
Poda e léxico
Zone maps, bloom filters e bitmaps para poda; um sidecar BM25 para recuperação esparsa e fusão de scores.
SCAN FILTER PROJECT POINT_GET RANGE_GET AGGREGATE TOP_K HASH_JOIN HASH_GROUP_BY SORT ANN_SEARCH SPARSE_SEARCH FUSE RERANK MATERIALIZE
WAL primeiro. Visível imediatamente. Selado em segundo plano.
Frames append-only com checksums e LSNs monotônicos. A recuperação repete registros após o último LSN selado e trunca no primeiro checksum inválido.
A escrita chega ao delta mutável e fica consultável imediatamente — segmentos selados e delta se unem por um único caminho de scan.
Ultrapassado um limite de tamanho, linhas ou idade, o delta é ordenado e gravado como um segmento Parquet com seu .vidx e sidecars, depois publicado por uma troca atômica de manifesto.
Mesclagens em segundo plano unem segmentos pequenos, descartam linhas com tombstone e reconstroem os sidecars — com orçamento controlado, para que implantações on-device permaneçam silenciosas.
Segmentos selados nunca são mutados. Uma leitura fixa (snapshot de manifesto, LSN); escritores selam novos segmentos e trocam o manifesto sem perturbar leitores em andamento. A coleta de lixo aguarda o snapshot ativo mais antigo.
O filtro escolhe o plano, não o contrário.
ANN filtrado é planejamento adaptativo por seletividade: o planejador estima quantas linhas sobrevivem ao filtro a partir das estatísticas de segmento e então escolhe a estratégia mais barata que mantém o contrato de recall.
Prefilter → exato
Prefilter escalar ou bitmap primeiro, depois pontuação SIMD exata sobre os sobreviventes. Abaixo de um limite de linhas, o ANN é ignorado por completo — varredura exata, recall 1.0.
Travessia com allow-bitmap
A travessia ANN carrega um allow-bitmap, de modo que o índice só expõe linhas admitidas pelo filtro.
ANN → pós-filtro
ANN primeiro com over-fetch adaptativo, depois post-filter. O filtro remove pouco, então a geração de candidatos lidera.
Verificações de correção precedem qualquer número de desempenho.
O runtime entregue é verificado por suítes de paridade executadas contra ambas as implementações do motor, e toda consulta pode nomear o plano físico que utilizou. Esta é a ordem de operações aqui: verificações de correção primeiro, medição depois.
Benchmarks são publicados sob um contrato de imparcialidade — recall equivalente, hardware equivalente, resultados separados por transporte, vitória / empate / derrota reportados. Os primeiros resultados medidos estão agora disponíveis na página de benchmarks, cada número acompanhado de suas condições completas: hardware, conjunto de dados, dimensão, seletividade, recall e transporte. Todo multiplicador permanece uma hipótese fora das condições declaradas ao seu lado.