okf-gem · blog
Release · 1.9.0

Uma busca que você troca: okf 1.9.0

RS Rodrigo Serradura · ·7 min de leitura
🇺🇸 Read in English

Até a 1.9.0, a okf buscava no seu bundle de exatamente um jeito. Agora você escolhe a engine, e a escolha vem com um resultado que merece atenção: a nova engine full-text é de 44 a 56 vezes mais rápida por consulta, e vem desligada.

Isso não é um meio-termo defensivo. Uma invocação de CLI constrói um índice, faz uma pergunta e termina, então a vazão que ela comprou é vazão que ela nunca vive para gastar. O que você leva da release é uma escolha que não existia antes: casamento exato que começa na hora, ou casamento ranqueado e tolerante a erro de digitação que você pede pelo nome quando a pergunta vale a espera.

Duas engines, e como você escolhe uma

Trocar a engine não muda o formato do que volta. Duas engines podem discordar completamente sobre quais conceitos casam e ainda entregar linhas com as mesmas chaves na mesma ordem, então um script que lê --json nunca precisa saber qual delas rodou. O que muda é o casamento e o ranqueamento:

scan (padrão)index
casatexto cru, literalmentetokens inteiros e os tokens que eles prefixam
ranqueia porsoma dos pesos de campoBM25+
capacidaderegexpfuzzy, prefix
acha ustomer dentro de customersimnão

A seleção é por capacidade quando a consulta exige uma. --fuzzy exige :fuzzy, então ela vai para o índice sem você nomear uma engine, e esse roteamento não imprime nada: sem nota, sem mudança de cabeçalho, sem chave nova no JSON. --engine NAME escolhe uma diretamente, para o caso em que uma flag de capacidade não dá conta, já que um modelo de casamento não exige nada e portanto nenhuma flag seleciona um.

Errar é um erro de uso que nomeia a engine capaz de fazer o serviço:

$ okf search @okf rate --engine index -e
error: --engine index does not support --regexp (try --engine scan)

$ okf search @okf rate --engine bogus
error: unknown search engine: bogus (available: index, scan)

Uma terceira engine agora pode chegar como uma gem instalada em vez de um fork. O --help lista o que estiver registrado em vez de um par fixo no código, então uma engine de que a okf nunca ouviu falar aparece no texto de ajuda assim que você a instala, e ela precisa passar o mesmo contrato que as duas nativas passam antes de ter permissão para responder qualquer coisa. Nada disso vem junto hoje; a questão é que um backend SQLite ou FTS5 não precisa mais ser escrito por este projeto para existir.

Por que a engine rápida está desligada

Os números por consulta não são apertados. Medido com benchmark-ips no Ruby 4.0.5 contra o bundle @okf real, replicado para corpora maiores, o índice sustenta de 44 a 56 vezes a vazão de consultas do scan, e o múltiplo se mantém quase constante porque as duas abordagens escalam linearmente neste corpus.

Essa é a medida certa para qualquer coisa que indexa uma vez e depois responde por horas, que é o que uma página de grafo ou um servidor rodando fazem.

É a medida errada para um processo que termina. Uma invocação de CLI constrói um índice, faz uma pergunta e morre. De ponta a ponta, com 1.000 conceitos, são 3,00 s contra 0,24 s, com a construção respondendo por cerca de 95% disso. A vantagem de vazão é real e o processo nunca vive o bastante para colher.

Então o padrão não se mexeu, e o tradeoff está escrito no --help em vez de ficar num benchmark que ninguém roda. O mergulho no minifts cobre o port em si, o que o tokenizador custa, e a única mudança arquitetural que faria o caminho rápido virar padrão.

A página do grafo desenha a camada de índices

Todo bundle OKF carrega um index.md autorado por diretório, o mapa da §6. A página do grafo só conseguia mostrá-los dentro do modo árvore de arquivos, onde um nó de pasta fazia as vezes do mapa do diretório.

Show indexes transforma isso numa camada: cada mapa vira um ladrilho ligado por arestas aos conceitos que lista e aos mapas abaixo dele, desenhado sobre qualquer layout que já esteja rodando, então ligá-lo não custa mais o arranjo que você estava lendo. A autoria aparece como forma, sólida onde um autor escreveu um mapa e vazada onde o bundle apenas implica um, então o toggle se lê tanto como curadoria quanto como navegação.

A view de Files mudou de forma na mesma release: a árvore aninha por segmento de caminho, a aba Indexes separada se dissolveu num toggle "Indexes only" sobre essa mesma árvore, e quem lê pela primeira vez agora recebe uma nota dizendo onde está o índice. Essa metade da release tem post próprio, com capturas de tela.

@slug é um alvo, não um caminho

A 1.8.0 trouxe o registry. A 1.9.0 termina de ensinar ao resto do sistema que um nome é um jeito de dizer qual bundle.

O erro cru de não é um diretório agora carrega a gramática:

$ okf lint ./nope
error: ./nope is not a directory or a registry ref
       (@slug names a registered bundle, @ the default; okf registry list)

Essa mensagem é compartilhada por todo verbo, que é a razão de @all ficar de fora: @all pertence só ao search. A agent skill que vem junto fez a mudança correspondente, trocando "Which directory?" por "Which target?", e seus playbooks de consume e search nomeiam @slug nos passos de orientação.

A skill também parou de sondar pela CLI. Ela gastava uma rodada de ferramenta num teste de presença command -v okf antes de toda tarefa. Esse teste morreu: rode o verbo, e trate um "command not found" do shell como o único sinal para instalar. Uma linha começando com error: é a CLI respondendo com um resultado de bundle ou de uso, nunca uma toolchain ausente, então o caso comum agora não paga rodada de guarda nenhuma.

Também nesta release

Atualizando

gem install okf        # or: bundle add okf

Nada nesta release exige mudança num bundle existente, e o comportamento padrão de busca é byte a byte idêntico ao da 1.8.0: mesmos campos, mesmos pesos, mesmo casamento literal. O minifts chega como terceira dependência de runtime, Ruby puro, sem extensão nativa, sem árvore de dependências própria, e com o mesmo piso Ruby 2.4 que as outras duas seguram.

A imagem multi-arch acompanha a release como sempre em ghcr.io/serradura/okf:1.9.0, e toda a superfície acima está no demo ao vivo.

O que fecha o círculo. Quase tudo que você faz com o okf search deve continuar igual, porque continua mesmo. O que mudou é que as duas perguntas que a busca antiga não respondia, "ache isso mesmo eu tendo escrito errado" e "ranqueie direito entre quatro bundles", agora têm uma flag cada, e uma terceira engine não precisa mais ser escrita por este projeto para existir.