O que Gemma Embed Search faz?
Recupere arquivos locais pelo significado. Um único espaço de embeddings guarda imagens, áudio e texto, de modo que uma consulta digitada retorna as fotos, clipes ou documentos que correspondem a ela. O modelo é executado no hardware do usuário por meio de um servidor local; nada é enviado para lugar nenhum.
scripts/embed_search.py faz quatro coisas: doctor verifica o servidor, init salva a
conexão, index incorpora arquivos em um cache, e search os classifica em relação a uma consulta.
Configuração local
As configurações ficam em config.json, nunca neste arquivo:
- Linux e macOS:
~/.config/gemma-embed-search/config.json - Windows:
%USERPROFILE%\.config\gemma-embed-search\config.json
Leia esse arquivo primeiro. Se ele contiver url e model, todos os comandos subsequentes funcionam sem
as flags de conexão e você pode pular a Etapa 2.
Se estiver faltando ou incompleto, peça ao usuário a URL do servidor e a pasta a ser indexada, execute
doctor para listar os modelos que o servidor realmente oferece e depois execute init para escrever o arquivo.
init faz merge, então adicionar uma configuração de cada vez é seguro. Nunca adivinhe um nome de modelo.
Copiar config.example.json desta pasta para aquele caminho e editá-lo faz o mesmo trabalho
que init, para um usuário que prefere editar o arquivo diretamente. Adicione "api_key" lá apenas se
o servidor precisar de uma.
Nunca salve configurações dentro da própria pasta da habilidade. Atualizar a habilidade substitui todos os arquivos nela, e qualquer coisa escrita ali será perdida.
Checklist de configuração
Progresso:
- Etapa 1: Confirme o servidor e escolha um nome de modelo (
doctor) - Etapa 2: Salve a conexão (
init) - Etapa 3: Indexe um piloto de 20 arquivos e verifique uma consulta
- Etapa 4: Indexe a pasta inteira
- Etapa 5: Responda à consulta real do usuário, com
--htmlpara que ele possa ver os resultados
Pule a Etapa 2 se config.json já tiver url e model.
Execute o script com uv run scripts/embed_search.py (instala o Pillow a partir dos metadados
inline do script) ou python3 scripts/embed_search.py se o Pillow já estiver importável.
Etapa 1 — encontre o servidor e o nome do modelo. Nunca adivinhe o nome do modelo; leia-o do servidor.
uv run scripts/embed_search.py --url http://127.0.0.1:1235 doctor
doctor imprime os modelos que o servidor oferece e testa um embedding. Se o usuário ainda não
iniciou um servidor, leia references/setup.md e dê a eles o comando
para o modelo deles.
Etapa 2 — salve para que chamadas posteriores não precisem de flags. Passe --api-key apenas se o servidor
exigir uma; ela é escrita no arquivo de configuração com modo 0600. Passe --root em qualquer comando
posterior para trabalhar em uma pasta diferente sem alterar o que foi salvo.
uv run scripts/embed_search.py --url http://127.0.0.1:1235 --model <nome-do-doctor> init --root <pasta>
uv run scripts/embed_search.py index --limit 20
Etapa 3 — piloto antes da execução longa. A indexação é a etapa cara: aproximadamente 0,25 s por imagem em uma GPU de desktop, então 10.000 arquivos são cerca de 40 minutos. Indexe 20 arquivos, execute uma consulta, e confirme se os resultados parecem corretos antes de se comprometer com a passagem completa.
Etapa 4 — índice completo. Reexecutar index apenas incorpora arquivos novos ou alterados, então uma
execução interrompida é retomada automaticamente.
uv run scripts/embed_search.py index
Etapa 5 — busca.
uv run scripts/embed_search.py search "um labrador preto na praia" --top 20 --html hits.html
Livro de receitas de consultas
| Intenção | Comando |
|---|---|
| Busca semântica simples | search "um mercado noturno lotado" |
| Duas facetas que devem ser verdadeiras | search "uma mulher" --must "a cor amarela" |
| Sinônimos para que uma frase não domine | search "uma mulher" --also "uma garota" --also "retrato feminino" |
| Encontrar toda imagem contendo X | search "personagens com cabelo ruivo" --top 60 --html hits.html |
| Sujeito mais restrição real de cor | search "uma mulher" --color yellow --min-color 0.05 |
| Quadros quase monocromáticos ou escuros | search "qualquer imagem" --max-color blue --modality image |
| Apenas um tipo de arquivo | search "sons de sirene" --modality audio |
| Legível por máquina para trabalho posterior | search "..." --json --top 50 |
| Mais rápido, pontuação ligeiramente menos precisa | search "..." --dims 256 |
--also calcula a média dos vetores de paráfrase em uma única consulta. --must mantém a pontuação da
faceta mais fraca, que é como você expressa AND. Use --also para sinônimos e --must para
condições independentes.
Lendo a saída
A saída simples é pontuação [modalidade] caminho, melhores primeiro. Execuções com cor inserem a proporção de pixels
após a pontuação. --json emite {"query", "index", "total", "filtered_out", "results": [{"rank", "score", "color", "modality", "path"}]} na saída padrão; todo o progresso vai para o stderr,
então a saída padrão sempre pode ser canalizada diretamente para jq.
As pontuações de cosseno desta família de modelos ficam entre aproximadamente 0,3 e 0,8. O número absoluto significa pouco; a diferença entre acertos e erros importa. Se o topo da lista estiver errado, a consulta está errada — reformule-a em vez de confiar na classificação. Nunca apresente uma lista longa como igualmente boa: indique onde os resultados confiantes param e os palpites começam.
Uma lista curta não é a resposta completa. Cada arquivo indexado recebe uma pontuação, então o total na
saída conta todo o corpus e nunca informa quantos resultados são plausíveis. Encontre o
precipício — o ponto onde as pontuações param de cair abruptamente. Se a lista que você mostrou terminar antes
dele, diga que os resultados foram truncados e ofereça uma execução mais longa: um --top maior custa apenas mais uma
folha de contatos, não outra indexação. Respeite um número que o usuário nomear e ainda declare o corte que você
aplicou. Nunca afirme "não há nenhum" sem uma lista ampliada, --top 100 ou mais, que alguém
tenha realmente examinado.
Para revisão visual, sempre ofereça --html: ele escreve uma folha de contatos de miniaturas com
pontuações e nomes de arquivo que o usuário pode abrir em um navegador. Um --html simples escreve hits.html
no diretório de trabalho; --html ARQUIVO define o caminho. As miniaturas são incorporadas como base64, então
a folha é autocontida e viaja sozinha. A folha incorpora miniaturas reais dos arquivos correspondentes,
então trate-a como uma cópia dessa parte da biblioteca: mantenha-a fora do controle de versão e fora de qualquer coisa que você
encaminhe. Elas têm 512 px de largura por padrão; aumente
--thumb-width para inspeção detalhada.
Pegadinhas
- Uma palavra de cor dentro do texto da consulta é uma dica suave, não um filtro.
"uma mulher com tema amarelo"classifica uma mulher com jaqueta laranja em primeiro lugar. Use--color yellow --min-color 0.05para uma restrição real; ela é calculada a partir dos pixels, não do modelo. - Uma palavra de estilo também é uma dica suave, e mais fraca.
"uma mulher fotorrealista com cabelo ruivo"classifica uma ilustração a tinta de uma mulher ruiva em primeiro lugar, porque os substantivos do sujeito superam o estilo. Mova o estilo para--mustpara que seja pontuado como sua própria faceta e fixe o atributo visual com--color. Nenhum dos dois é um filtro verdadeiro:--mustpega o mínimo entre as facetas, então forçar muito em uma troca a outra. - Vários sujeitos em um quadro se misturam em um único vetor, então o quadro pontua pior em uma consulta de
sujeito único do que um quadro dedicado àquele sujeito: um retrato de uma mulher ruiva ao lado de um
homem pode ficar bem abaixo em uma busca por
"mulher com cabelo ruivo"enquanto está no topo de"personagens com cabelo ruivo". Sinônimos da mesma ideia singular não ajudam; a forma plural ou coletiva sim. Aumente--topquando a pergunta for "encontrar tudo que contém X". --colorprecisa que o índice tenha estatísticas de cor, que só oindexcalcula. Um índice construído com uma versão antiga informa 0.0 para tudo: reindexe com--forcese o filtro de cor excluir silenciosamente todos os arquivos.- Índice e consulta devem usar o mesmo modelo. Trocar
--modelmistura silenciosamente vetores incompatíveis; reindexe com--forceapós qualquer alteração de modelo e anote o modelo emstats. - O servidor deve executar o modelo de embedding com pooling médio e seu projetor de visão
(
--mmproj) carregado. Sem o projetor, as requisições de imagem falham ou retornam um vetor que ignora a imagem.doctorprova que o texto funciona; execute uma consulta de imagem para provar a visão. - As imagens são recodificadas para JPEG com o lado maior em 1536 antes de serem enviadas. A recodificação é
necessária, não cosmética: servidores comumente rejeitam WebP, 16 bits ou arquivos com rótulo incorreto,
e o Pillow lê esses em vez disso. O modelo não tem limite de pixels — o servidor reamostra cada imagem
para um orçamento fixo de tokens de visão — então
--resizetroca o tamanho do upload pela fidelidade, não pela correção. Números medidos e detalhes estão em references/setup.md. - Formatos HEIC e raw de câmera não são lidos a menos que o Pillow tenha sido construído com o plugin. O
script registra
skip <arquivo>: cannot identify image filee continua; verifiqueskipped_errorsno resumo da indexação em vez de assumir cobertura total. searchem uma pasta que nunca foi indexada sai com código 4 e uma mensagem. Não trate uma lista de resultados vazia como "sem correspondências" até que a contagem do índice emstatspareça correta.- O áudio é limitado pelo contexto do servidor: cerca de 5,5 minutos por clipe a 25 tokens por segundo. Arquivos mais longos falham como um erro de requisição, não como uma correspondência ruim.
- As pontuações não são comparáveis entre corpora ou entre quantizações. Nunca prometa um
limite; ajuste
--min-colore--topcom base no que o usuário vê.
Referência do script
doctor Verifica o servidor, lista modelos, testa um embedding
init [--root DIR] Salva url, modelo, chave e raiz padrão no arquivo de configuração
index --root DIR Incorpora arquivos novos e alterados (incremental, retomável)
[--modality auto|image|audio|text] [--include '*.png,sub/*.jpg']
[--exclude-dir node_modules,.git] [--limit N] [--batch 16] [--resize 1536]
[--force] [--compact]
search "consulta" Classifica arquivos indexados; imprime pontuação, modalidade, caminho
[--also P]... [--must P]... [--color NOME --min-color F | --max-color F]
[--modality image] [--dims 512|256|128] [--top 20] [--offset 0]
[--json] [--html [ARQUIVO]] [--thumb-width 512]
stats Contagem de entradas, mistura de modalidades, modelo, tamanho do índice
Códigos de saída: 0 sucesso, 2 erro de uso, 3 servidor inacessível ou autenticação rejeitada,
4 índice ausente, 5 nada a fazer, 6 erro do servidor durante a execução. Execute
scripts/embed_search.py <comando> --help para documentação completa das flags.
A resolução de configuração é flag > ambiente (EMBED_SEARCH_URL, EMBED_SEARCH_MODEL,
EMBED_SEARCH_API_KEY, EMBED_SEARCH_ROOT) > arquivo de configuração em
~/.config/gemma-embed-search/config.json. O índice padrão é
~/.cache/gemma-embed-search/<pasta>-<hash>.jsonl, um registro JSON por arquivo, então é
seguro manter vários índices para pastas diferentes.
Mais detalhes
- references/setup.md — iniciando um servidor, requisitos de modelo e flags, o que
doctorsignifica - references/query-guide.md — construção de consultas, lógica de facetas, limites de cor, ajuste com base em resultados reais
- references/errors.md — todo código de saída e a correção para cada modo de falha