Obsidian MCP + recuperação híbrida: referência de 2026
# Conecte o Obsidian ao Claude e a outros agentes via MCP: configuração do servidor, recuperação híbrida com BM25 + vetores e indexação de um vault com 16.894 arquivos — com configurações funcionais.
Obsidian não é um aplicativo de anotações. É um corpus markdown em texto simples, com prioridade local e estruturado em grafo, que vira um reservatório de contexto para IA quando você adiciona infraestrutura de recuperação. 16.894 arquivos. 49.746 chunks. Consultas em 23 ms. Zero chamadas API. Um arquivo SQLite de 83 MB. Este guia cobre o sistema completo: da arquitetura do cofre à recuperação híbrida, da integração com MCP aos fluxos de trabalho operacionais.
Principais conclusões
Engenharia de contexto, não anotações. O valor de um vault do Obsidian para IA não está nas próprias notas, mas na camada de recuperação que as torna consultáveis. Um vault com 16.000 arquivos sem recuperação é um banco de dados apenas para escrita. Um vault com 200 arquivos, busca hybrid e integração com MCP é uma base de conhecimento para IA. A infraestrutura de recuperação é o produto. As notas são a matéria-prima.
A recuperação hybrid supera a busca puramente por palavras-chave ou puramente semântica. O BM25 encontra identificadores exatos e nomes de funções. A busca vetorial encontra sinônimos e correspondências conceituais em terminologias diferentes. A Reciprocal Rank Fusion (RRF) combina ambas sem exigir calibração de pontuação. Nenhum método isolado cobre os dois modos de falha. Pesquisas sobre o ranking de passagens do MS MARCO confirmam o padrão: a recuperação hybrid supera de forma consistente cada método usado isoladamente.3 O aprofundamento sobre o recuperador hybrid aborda a matemática do RRF, exemplos práticos com números reais, análise dos modos de falha e uma calculadora interativa de fusão.
O MCP oferece às ferramentas de IA acesso direto ao vault. Os servidores do Model Context Protocol (MCP) expõem o recuperador como uma ferramenta que Claude Code, Codex CLI, Cursor e outras ferramentas de IA podem chamar diretamente. O agente consulta o vault, recebe resultados ranqueados com atribuição da fonte e usa o contexto sem carregar arquivos inteiros. O servidor MCP é uma camada fina em torno do mecanismo de recuperação.
Local-first significa custos zero de API e privacidade total. Toda a stack é executada em uma única máquina: SQLite para armazenamento, Model2Vec para embeddings, FTS5 para busca por palavras-chave, sqlite-vec para KNN vetorial. Sem serviços em nuvem, chamadas de API ou dependência de rede. Notas pessoais nunca saem da máquina. A re-incorporação completa dos 49.746 chunks custaria aproximadamente US$ 0,30 pelos preços de API da OpenAI, mas os custos reais são latência, exposição da privacidade e dependência de rede para um sistema que deveria funcionar offline.4
A indexação incremental mantém o sistema atualizado em menos de 10 segundos. A comparação do horário de modificação dos arquivos detecta alterações. Apenas arquivos modificados passam novamente por chunking e geração de embeddings. Uma reindexação completa leva cerca de quatro minutos em hardware Apple M-series. Atualizações incrementais nas edições de um dia típico são executadas em menos de dez segundos. O sistema se mantém atualizado sem intervenção manual.
A arquitetura escala de 200 a mais de 20.000 notas. O mesmo design de três camadas (entrada, recuperação, integração) funciona em qualquer tamanho de vault. Comece com busca apenas por BM25 em um vault pequeno. Adicione busca vetorial quando colisões de palavras-chave se tornarem um problema. Adicione fusão RRF quando precisar de correspondências exatas e semânticas. Cada camada é útil de forma independente e pode ser removida de forma independente.
Como usar este guia
Este guia aborda o sistema completo. Seu ponto de partida depende de onde você está:
| Você é… | Comece aqui | Depois explore |
|---|---|---|
| Novo no Obsidian + IA | Por que usar o Obsidian para infraestrutura de IA, Configuração do Obsidian MCP | Arquitetura do vault, Arquitetura do servidor MCP |
| Já tem um vault e quer acesso por IA | Arquitetura do servidor MCP, Integração com Claude Code | Modelos de embedding, Busca de texto completo |
| Criando um sistema de recuperação | O pipeline completo de recuperação, Reciprocal Rank Fusion | Ajuste de desempenho, Solução de problemas |
| Contexto de equipe ou empresa | Framework de decisão, Padrões de grafo de conhecimento | Receitas de fluxo de trabalho para desenvolvedores, Guia de migração |
As seções marcadas como Contrato incluem detalhes de implementação, blocos de configuração e modos de falha. As seções marcadas como Narrativa se concentram em conceitos, decisões de arquitetura e no raciocínio por trás das escolhas de design. As seções marcadas como Receita apresentam fluxos de trabalho passo a passo.
Por que usar o Obsidian para infraestrutura de IA
A tese deste guia: os vaults do Obsidian são o melhor substrato para bases de conhecimento pessoais de IA porque são local-first, em texto simples, estruturados como grafos, e o usuário controla cada camada da stack.
O que o Obsidian oferece à IA que as alternativas não oferecem
Arquivos markdown em texto simples. Cada nota é um arquivo .md no seu sistema de arquivos. Sem formato proprietário, exportação de banco de dados ou API necessário para ler o conteúdo. Qualquer ferramenta que lê arquivos pode ler seu vault. grep, ripgrep, o pathlib do Python, SQLite FTS5 — todos funcionam diretamente nos arquivos de origem. Ao criar um sistema de recuperação, você está indexando arquivos, não respostas de API. O índice está sempre consistente com a origem porque a origem é o sistema de arquivos.
Arquitetura local-first. O vault fica na sua máquina. Sem servidor, dependência de sincronização em nuvem, limites de taxa de API ou termos de serviço que regulem como você processa seu próprio conteúdo. Você pode gerar embeddings, indexar, dividir em chunks e pesquisar suas notas sem qualquer serviço externo. Isso importa para a infraestrutura de IA porque o pipeline de recuperação é executado na velocidade permitida pelo seu disco, não na velocidade de resposta de um endpoint de API. Também importa para a privacidade: notas pessoais que contêm credenciais, dados de saúde, informações financeiras e reflexões privadas nunca saem da sua máquina.
Estrutura de grafo por meio de wiki-links. A sintaxe [[wiki-link]] do Obsidian cria um grafo direcionado entre notas. Uma nota sobre a implementação de OAuth se vincula a notas sobre rotação de tokens, gerenciamento de sessões e segurança de API. A estrutura de grafo codifica relações entre conceitos selecionadas por humanos. Embeddings vetoriais capturam similaridade semântica, mas wiki-links capturam conexões intencionais que o autor fez enquanto refletia sobre o tema. O grafo é um sinal que os embeddings não conseguem replicar.
Ecossistema de plugins. O Obsidian tem mais de 2.500 plugins da comunidade (a contagem ultrapassou 2.500 em março de 2026, acima de mais de 1.800 em meados de 2025). O Dataview consulta seu vault como um banco de dados. O Templater gera notas a partir de templates com lógica de JavaScript. A integração com Git sincroniza seu vault com um repositório. O Linter impõe consistência de formatação. O plugin nativo Bases (introduzido na v1.9.10) adiciona visualizações semelhantes a bancos de dados — tabelas, galerias, calendários e quadros kanban — sobre arquivos do vault, usando propriedades de frontmatter como campos e salvas como arquivos .base.15 Esses plugins adicionam estrutura ao vault sem alterar o formato subjacente de texto simples. O sistema de recuperação indexa a saída desses plugins, não os plugins em si.
Mais de 5 milhões de usuários. O Obsidian tem uma grande comunidade ativa que produz templates, fluxos de trabalho, plugins e documentação. Quando você encontra um problema de organização do vault ou configuração de plugin, alguém provavelmente já documentou uma solução. A comunidade também produz ferramentas adjacentes ao Obsidian: servidores MCP, scripts de indexação, pipelines de publicação e wrappers de API.
O que apenas um sistema de arquivos não oferece
Um diretório de arquivos markdown tem a vantagem do texto simples, mas não tem três coisas que o Obsidian adiciona:
-
Links bidirecionais. O Obsidian rastreia backlinks automaticamente. Quando você cria um link da Nota A para a Nota B, a Nota B mostra que a Nota A faz referência a ela. O painel de grafo visualiza agrupamentos de conexões. Essa percepção bidirecional é metadado que um sistema de arquivos bruto não fornece.
-
Visualização ao vivo com renderização de plugins. Consultas do Dataview, diagramas Mermaid e blocos de callout são renderizados em tempo real. A experiência de escrita é mais rica do que em um editor de texto, enquanto o formato de armazenamento permanece em texto simples. Você escreve e organiza em um ambiente rico; o sistema de recuperação indexa o markdown bruto.
-
Infraestrutura da comunidade. Descoberta de plugins, marketplace de temas, serviço de sincronização (opcional), serviço de publicação (opcional) e um ecossistema de documentação. Você pode reproduzir qualquer recurso individual com ferramentas independentes, mas o Obsidian os reúne em um fluxo de trabalho coeso.
O que o Obsidian NÃO faz (e o que você cria)
O Obsidian não inclui infraestrutura de recuperação. Ele tem busca básica (texto completo, nome de arquivo, tag), mas não tem pipeline de embeddings, busca vetorial, ranking por fusão, servidor MCP, filtragem de credenciais, estratégia de chunking ou hooks de integração para ferramentas externas de IA. Este guia aborda a infraestrutura que você cria sobre o Obsidian. O vault é o substrato. O pipeline de recuperação, o servidor MCP e os hooks de integração são a infraestrutura.
A arquitetura descrita aqui é markdown-first, não exclusiva do Obsidian. Se você usa Logseq, Foam, Dendron ou um diretório simples de arquivos markdown, o pipeline de recuperação funciona de forma idêntica. O chunker lê arquivos .md. O embedder processa strings de texto. O indexador grava no SQLite. Nenhum desses componentes depende de recursos específicos do Obsidian. A contribuição do Obsidian é o ambiente de escrita e organização que produz os arquivos markdown indexados pelo recuperador.
Configuração do Obsidian MCP
Model Context Protocol (MCP) é a interface padrão que dá ao Claude Code, Codex CLI, Cursor e outras ferramentas de IA acesso direto a um vault do Obsidian. Esta seção conecta um vault a uma ferramenta de IA em cinco minutos. Você instalará o Obsidian, criará um vault, instalará um servidor MCP e executará sua primeira consulta. O início rápido usa um servidor MCP da comunidade para resultados imediatos. As seções posteriores abordam a criação de um pipeline de recuperação personalizado para uso em produção.
Pré-requisitos
- macOS, Linux ou Windows
- Node.js 18+ (para o servidor MCP)
- Obsidian 1.12+ (para a integração com CLI; 1.13.7 é a versão pública atual para desktop – as versões estável e beta convergiram, a linha 1.13 saiu do Catalyst em 30 de julho de 2026; versões anteriores funcionam em configurações somente com MCP)
- Claude Code, Codex CLI ou Cursor instalado
Etapa 1: criar um vault
Baixe o Obsidian em obsidian.md e crie um novo vault. Escolha um local de que você se lembrará — o servidor MCP precisa do caminho absoluto.
# Example vault location
~/Documents/knowledge-base/
Adicione algumas notas para dar algo com que o recuperador possa trabalhar. Mesmo 10 a 20 notas já bastam para ver resultados. Cada nota deve ser um arquivo .md com um título significativo e pelo menos um parágrafo de conteúdo.
Etapa 2: instalar um servidor MCP
Vários servidores MCP da comunidade fornecem acesso imediato ao vault. O ecossistema cresceu significativamente entre 2025 e 2026. Um destaque é o MCPVault (npm @bitbonsai/mcpvault, repositório bitbonsai/mcpvault), agora na v0.15.0 (verificado no npm em 14 de agosto de 2026) — um projeto separado de MarkusPfundstein/mcp-obsidian abaixo, não uma renomeação dele. A v0.11.0 (março de 2026) adicionou list_all_tags para analisar frontmatter e hashtags com contagens, melhorou o tratamento de pastas com pontos e incluiu suporte a .base/.canvas. Vale adotar a sequência de três patches lançados no mesmo dia, em 23 de julho de 2026: a v0.12.3 adiciona uma ferramenta wiki_link que resolve as formas [[Document Name]], [[Name|Display]], [[Name\|Display]] com escape de tabela e #fragment, retornando o conteúdo da nota junto com o caminho resolvido e alternativas ambíguas — a primitiva de recuperação que permite que um agente siga o próprio grafo de links do vault, em vez de pesquisá-lo novamente — e exclui .trash/ de todas as ferramentas por meio do filtro de caminhos padrão; a v0.12.4 estende wiki_link a links com caminho qualificado, como [[folder/Note]]; a v0.12.2 impede que patch_note corrompa inserções que contêm padrões de substituição $ e normaliza caminhos que carregam acidentalmente o prefixo do vault. Dois avisos de severidade média (GHSA-9c83-rr99-vfwj e GHSA-j99q-93c9-h869) foram divulgados contra a lista de negação de diretórios restritos do filtro de caminhos; ambos foram corrigidos bem antes da linha 0.12, nas versões 0.11.4 e 0.11.5, portanto qualquer versão 0.12.x está livre deles.13
Mudança de abril de 2026 — Obsidian CLI como ponte preferida: o Obsidian 1.12.0 introduziu o CLI de primeira classe, e o instalador público 1.12.7 (23 de março de 2026) incluiu o binário independente + TUI + melhorias no arquivo de socket que facilitaram a instalação e a execução de fluxos de trabalho no terminal.16 A linha 1.13 chegou ao canal público como 1.13.4 em 30 de julho de 2026 — uma versão de configurações/imagens/segurança de URI, sem novos recursos de IA ou automação além da superfície do CLI 1.12.x (veja a linha do changelog para saber o que ela altera).2526 As ferramentas da comunidade estão migrando ativamente do plugin Local REST API (que alimentava
mcp-obsidian) para a integração baseada em CLI, pois ela é mais rápida e estável. O repositórioMarkusPfundstein/mcp-obsidiancontinua mantido — commits até maio de 2026 adicionaram ferramentas comosearch_by_tageget_frontmatter— embora não publique releases com tags (instale a partir de um commit fixado). Ele continua baseado em Local REST API; para novas configurações, a ponte CLI costuma ser mais rápida e estável, portanto prefira-a ou as alternativas mais novas da comunidade listadas abaixo.20 Consulte a seção “Obsidian CLI para fluxos de trabalho com IA” mais adiante neste guia para ver a configuração recomendada.
| Servidor | Autor | Transporte | Exige plugin | Recurso principal |
|---|---|---|---|---|
obsidian-mcp (npm obsidian-mcp) |
StevenStavrakis | STDIO | Não | Leve, baseado em arquivos |
| mcp-obsidian | MarkusPfundstein | STDIO | Local REST API | CRUD completo do vault via REST, além de search_by_tag/get_frontmatter — mantido ativamente (commits até maio de 2026); sem releases com tags, fixe um commit20 |
| obsidian-mcp-tools | jacksteamdev | STDIO | Sim (plugin) | Pesquisa semântica + Templater |
| obsidian-claude-code-mcp | iansinnott | WebSocket | Sim (plugin) | Descoberta automática para Claude Code |
obsidian-mcp-server (npm obsidian-mcp-server) |
cyanheads | STDIO | Local REST API | Tags, gerenciamento de frontmatter — configurado por OBSIDIAN_API_KEY/OBSIDIAN_BASE_URL, não por flags de CLI |
| Hybrid Search MCP | comunidade | STDIO | Não | Servidor MCP de pesquisa BM25 + semântica + CLI. Mantido pela comunidade; verifique commits recentes antes de adotá-lo. |
Para o início rápido, a opção mais simples é um servidor baseado em arquivos que lê arquivos .md diretamente. Atenção à colisão de nomes no npm: o servidor baseado em arquivos é o npm obsidian-mcp (StevenStavrakis); o npm obsidian-mcp-server é o servidor da cyanheads, baseado em REST-API, que precisa do plugin Local REST API e de uma chave API — uma confusão comum que deixa leitores com um servidor que não consegue iniciar:
npm install -g obsidian-mcp
Etapa 3: configurar sua ferramenta de IA
Claude Code — registre o servidor com claude mcp add (Claude Code armazena servidores MCP em ~/.claude.json no escopo do usuário ou em .mcp.json de um projeto — não em ~/.claude/settings.json, que ignora silenciosamente um bloco mcpServers):
# User scope (all your projects)
claude mcp add obsidian -s user -- npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/your/vault
# Or project scope, shared with the repo (writes .mcp.json)
claude mcp add obsidian -s project -- npx -y obsidian-mcp@2 serve --vault notes=/absolute/path/to/your/vault
Codex CLI — adicione a ~/.codex/config.toml:
[mcp_servers.obsidian]
command = "npx"
args = ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/your/vault"]
Cursor — adicione a .cursor/mcp.json:
{
"mcpServers": {
"obsidian": {
"command": "npx",
"args": ["-y", "obsidian-mcp@2", "serve", "--vault", "notes=/absolute/path/to/your/vault"]
}
}
}
Etapa 4: executar sua primeira consulta
Abra sua ferramenta de IA e faça uma pergunta que as notas do seu vault possam responder:
Search my Obsidian vault for notes about [topic you wrote about]
A ferramenta de IA chama o servidor MCP, que pesquisa seu vault e retorna conteúdo correspondente. Você deve ver resultados com caminhos de arquivo e trechos relevantes.
O que Claude pode fazer depois de conectado
Os nomes exatos das ferramentas variam conforme o servidor, mas a superfície principal de recursos é consistente entre as implementações:
| Recurso | Ferramenta típica | O que o agente faz com ele |
|---|---|---|
| Pesquisar o vault | obsidian_search / search |
Encontra notas que correspondem a uma consulta e retorna trechos classificados com caminhos de arquivo e atribuição de fonte |
| Ler uma nota completa | obsidian_read_note / read_note |
Obtém o conteúdo completo da nota quando um trecho de pesquisa não é suficiente |
| Listar e navegar | obsidian_list_notes / list_notes |
Explora notas por pasta, tag ou intervalo de datas quando não há uma consulta específica |
| Obter contexto formatado | obsidian_get_context |
Retorna um bloco de contexto estruturado por tópico, dimensionado para um orçamento de tokens e pronto para ser inserido na conversa |
Na prática: Claude responde a perguntas com base nas suas notas e atribuição de fontes, traz decisões anteriores e material de referência para sessões de programação e explora a estrutura do vault sem carregar arquivos inteiros no contexto. Alguns servidores da comunidade também expõem operações de escrita (criação, acréscimo, gerenciamento de tags e frontmatter); o servidor personalizado criado mais adiante neste guia é deliberadamente somente leitura, com a criação de notas feita por hooks.
Aprofundamentos: Arquitetura do servidor MCP para o design de ferramentas e permissões, Integração com Claude Code para hooks e o padrão de ponte, Integração com Codex CLI e Cursor e outras ferramentas para outros agentes.
O que você acabou de criar
Você conectou uma base de conhecimento local a uma ferramenta de IA por meio de um protocolo padrão. O servidor MCP lê os arquivos do seu vault, realiza uma pesquisa básica e retorna resultados. Esta é a versão mínima viável.
O que este início rápido NÃO oferece: - Recuperação hybrid (pesquisa BM25 + vetorial + fusão RRF) - Pesquisa semântica baseada em embeddings - Filtragem de credenciais - Indexação incremental - Injeção automática de contexto baseada em hooks
O restante deste guia aborda a criação de cada um desses recursos. O início rápido comprova o conceito. O pipeline completo oferece recuperação com qualidade de produção.
Obsidian CLI para fluxos de trabalho de AI
O Obsidian 1.12 (fevereiro de 2026) introduziu uma interface de linha de comando integrada que abre uma nova superfície de integração para fluxos de trabalho de AI; ela continua atual até a versão 1.13.7 (a linha 1.13 chegou ao canal público em 30 de julho de 2026; não houve novos recursos do CLI desde então).162526 O CLI funciona como um controle remoto para a GUI do Obsidian — o Obsidian precisa estar em execução (ou será iniciado automaticamente no primeiro comando). Ative-o em Settings > General > Command line interface.
Por que o CLI importa para a infraestrutura de AI
O CLI oferece acesso programático a operações nativas do Obsidian que antes exigiam a GUI ou APIs de plugins. Para fluxos de trabalho de AI, os principais recursos são:
- Pesquisa em scripts e hooks.
obsidian search "query"eobsidian search:context "query"executam pesquisas no vault a partir de qualquer script de shell, hook ou pipeline de automação. A variantesearch:contextretorna linhas correspondentes com o contexto ao redor, o que é útil para inserir resultados em prompts de AI. - Automação de notas diárias.
obsidian dailyabre ou cria a nota diária de hoje. Combinado com scripts de shell, isso permite fluxos de briefing diário automatizados — um hook pode acrescentar resumos gerados por AI à nota diária. - Criação de notas baseada em templates.
obsidian template listeobsidian template creategeram notas a partir de templates do Templater ou do núcleo, permitindo que agentes de AI criem entradas estruturadas no vault sem escrever diretamente em arquivos markdown. - Gerenciamento de propriedades.
obsidian property seteobsidian property getleem e gravam propriedades de frontmatter, permitindo atualizações de metadados por scripts sem analisar YAML. - Controle de plugins.
obsidian plugin enable/disable/listgerencia plugins programaticamente, o que é útil para alternar plugins de indexação durante operações em lote. - Gerenciamento de tarefas.
obsidian task list/add/completeoferece acesso estruturado a tarefas, útil para agentes de AI que gerenciam itens de trabalho no vault.
CLI vs MCP para acesso de AI
Os servidores CLI e MCP têm funções diferentes e são complementares, não concorrentes:
| Aspecto | Obsidian CLI | Servidor MCP |
|---|---|---|
| Chamador | Scripts de shell, hooks, tarefas cron | Agentes de AI (Claude Code, Codex, Cursor) |
| Protocolo | Processo POSIX (stdin/stdout/stderr) | MCP (JSON-RPC por STDIO ou HTTP) |
| Ponto forte | Operações nativas do Obsidian (templates, plugins, propriedades) | Recuperação personalizada (embeddings, BM25, fusão RRF) |
| Limitação | Sem pesquisa vetorial, sem pipeline de embeddings | Sem acesso a operações internas do Obsidian |
| Melhor para | Scripts de automação, pipelines de entrada, ações de hooks | Consultas de agentes de AI em tempo real durante sessões |
Recomendação: Use o CLI para automação de entrada (criação de notas, gerenciamento de propriedades, execução de pesquisa nativa do Obsidian) e o MCP para recuperação (pesquisa hybrid com embeddings). Um hook UserPromptSubmit pode chamar obsidian search:context como uma pré-verificação rápida antes de executar a recuperação hybrid mais pesada (eventos de hook com escopo de ferramenta não podem injetar conteúdo — seu stdout nunca chega ao modelo).
Exemplo: hook de entrada com CLI
#!/bin/bash
# Hook: append today's signals to daily note via CLI
DATE=$(date +%Y-%m-%d)
SUMMARY="$1"
obsidian daily # ensure daily note exists
obsidian file append "Daily Notes/${DATE}.md" "## AI Summary\n${SUMMARY}"
Plugins de agentes do Obsidian
Uma categoria crescente de plugins do Obsidian incorpora agentes de programação com AI diretamente na UI do vault, oferecendo uma alternativa à configuração de servidor MCP externo. Esses plugins executam o agente de AI na barra lateral do Obsidian, em vez de se conectarem a partir de uma ferramenta externa.
Claudian
Claudian incorpora o Claude Code como colaborador de AI no vault. O diretório do vault torna-se o diretório de trabalho do Claude, concedendo a ele recursos agênticos completos: leitura/gravação de arquivos, pesquisa, comandos Bash e fluxos de trabalho em várias etapas.17
Principais recursos para a infraestrutura de AI:
- Prompts com reconhecimento de contexto. Anexa automaticamente a nota em foco, oferece suporte a menções de arquivo @notename, exclusão baseada em tags e seleção do editor como contexto.
- Suporte a visão. Analise imagens por arrastar e soltar, colar ou caminho de arquivo — útil para processar capturas de tela e diagramas armazenados no vault.
- Comandos de barra. Crie templates de prompt reutilizáveis acionados por /command, permitindo operações padronizadas no vault.
- Modos de permissão. Modos YOLO (aprovação automática), Safe (aprovar cada ação) e Plan (somente planejamento), com uma lista de bloqueio de segurança e confinamento ao vault.
Agent Client
Agent Client reúne Claude Code, Codex CLI e Gemini CLI em uma barra lateral unificada do Obsidian por meio do Agent Client Protocol (ACP).18
Principais recursos:
- Alternância entre vários agentes. Converse com Claude Code, Codex ou Gemini CLI no mesmo painel, alternando entre agentes conforme necessário.
- Menções a notas. Use @notename para incluir o conteúdo de notas nos prompts, de forma semelhante ao Claudian, mas sem depender de um agente específico.
- Execução de shell. Execute comandos de terminal inline no chat — scripts de build, comandos git ou qualquer operação de terminal sem sair da conversa.
- Aprovação de ações. Controle detalhado sobre leituras de arquivos, edições e execuções de comandos.
Quando usar plugins de agentes vs MCP externo
| Cenário | Plugin de agente | MCP externo |
|---|---|---|
| Escrever e editar notas do vault com assistência de AI | Melhor — o agente vê o contexto do editor | Funciona, mas sem reconhecimento do editor |
| Desenvolvimento de código em vários repositórios | Limitado — restrito ao vault | Melhor — restrito ao projeto, com sistema de arquivos completo |
| Recuperação em um corpus grande e indexado | Apenas pesquisa básica | Pipeline completo de recuperação hybrid |
| Perguntas e respostas rápidas sobre o vault durante sessões de anotações | Ideal — sem troca de contexto | Exige alternar para o terminal |
Recomendação: Use plugins de agentes para fluxos de trabalho centrados no vault (escrever, organizar e resumir notas). Use servidores MCP externos para fluxos de desenvolvimento em que o agente de AI precisa do pipeline completo de recuperação e de acesso a codebases fora do vault. As duas abordagens podem coexistir — execute o Claudian dentro do Obsidian para trabalhar com notas e o Claude Code com MCP externamente para desenvolvimento.
Estrutura de decisão: Obsidian vs alternativas
Nem todo caso de uso precisa do Obsidian. Esta seção mapeia quando o Obsidian é o substrato certo, quando é exagero e quando outra opção se encaixa melhor.
Árvore de decisão
START: What is your primary content type?
│
├─ Structured data (tables, records, schemas)
│ → Use a database. SQLite, PostgreSQL, or a spreadsheet.
│ → Obsidian is for prose, not tabular data.
│
├─ Ephemeral context (current project, temporary notes)
│ → Use CLAUDE.md / AGENTS.md in the project repo.
│ → These travel with the code and reset per project.
│
├─ Team wiki (shared documentation, onboarding)
│ → Evaluate Notion, Confluence, or a shared git repo.
│ → Obsidian vaults are personal-first. Team sync is possible
│ but not native.
│
└─ Growing personal knowledge corpus
│
├─ < 50 notes
│ → A folder of markdown files + grep is sufficient.
│ → Obsidian adds value mainly through the link graph,
│ which needs density to be useful.
│
├─ 50 - 500 notes
│ → Obsidian adds value. Wiki-links create a navigable graph.
│ → BM25-only search (FTS5) is sufficient at this scale.
│ → Skip vector search and RRF until keyword collisions appear.
│
├─ 500 - 5,000 notes
│ → Full hybrid retrieval becomes valuable. Keyword collisions
│ increase. Semantic search catches queries that BM25 misses.
│ → Add vector search + RRF fusion at this scale.
│
└─ 5,000+ notes
→ Full pipeline is essential. BM25-only returns too much noise.
→ Credential filtering becomes critical (more notes = more
accidentally pasted secrets).
→ Incremental indexing matters (full reindex takes minutes).
→ MCP integration pays dividends on every AI interaction.
Matriz de comparação
| Critério | Obsidian | Notion | Apple Notes | Sistema de arquivos simples | CLAUDE.md |
|---|---|---|---|---|---|
| Local-first | Sim | Não (cloud) | Parcial (iCloud) | Sim | Sim |
| Texto puro | Sim (markdown) | Não (blocos) | Não (proprietário) | Sim | Sim |
| Estrutura de grafo | Sim (wiki-links) | Parcial (menções) | Não | Não | Não |
| Indexável por AI | Acesso direto a arquivos | API obrigatório | Exportação obrigatória | Acesso direto a arquivos | Já no contexto |
| Ecossistema de plugins | Mais de 2.500 plugins | Integrações | Nenhum | N/A | N/A |
| Funciona offline | Completo | Cache somente leitura | Parcial | Completo | Completo |
| Escala para mais de 10 mil notas | Sim | Sim (com API) | Degrada | Sim | Não (arquivo único) |
| Custo | Grátis (core) | US$ 10/mês ou mais | Grátis | Grátis | Grátis |
Quando Obsidian é exagero
- Contexto de um único projeto. Se a AI só precisa de contexto sobre o codebase atual, coloque isso em
CLAUDE.md,AGENTS.mdou na documentação em nível de projeto. Esses arquivos acompanham o repositório e são carregados automaticamente. - Dados estruturados. Se o conteúdo é composto por tabelas, registros ou schemas, use um banco de dados. As notas do Obsidian são orientadas a prosa. Dataview consegue consultar campos de frontmatter, mas um banco de dados real lida melhor com consultas estruturadas.
- Pesquisa temporária. Se as notas serão descartadas depois que o projeto acabar, uma pasta de rascunho com arquivos markdown é mais simples. Não crie infraestrutura de retrieval para conteúdo efêmero.
Quando Obsidian é a escolha certa
- Conhecimento acumulado ao longo de meses ou anos. O valor se acumula conforme o corpus cresce. Um vault com 200 notas consultado diariamente por seis meses entrega mais valor do que um vault com 5.000 notas consultado uma única vez.
- Vários domínios em um único corpus. Um vault com notas sobre programação, arquitetura, segurança, design e projetos pessoais se beneficia de retrieval entre domínios que um
CLAUDE.mdespecífico de projeto não consegue oferecer. - Conteúdo sensível à privacidade. Local-first significa que o pipeline de retrieval nunca envia conteúdo para serviços externos. O vault contém tudo o que você coloca nele, inclusive conteúdo que você não enviaria para um serviço de cloud.
Modelo mental: três camadas
O sistema tem três camadas que operam de forma independente, mas se potencializam quando combinadas. Cada camada tem uma preocupação diferente e um modo de falha diferente.
┌─────────────────────────────────────────────────────┐
│ INTEGRATION LAYER │
│ MCP servers, hooks, skills, context injection │
│ Concern: delivering context to AI tools │
│ Failure: wrong context, too much context, stale │
└──────────────────────┬──────────────────────────────┘
│ query + ranked results
┌──────────────────────┴──────────────────────────────┐
│ RETRIEVAL LAYER │
│ BM25, vector KNN, RRF fusion, token budget │
│ Concern: finding the right content for any query │
│ Failure: wrong ranking, missed results, slow queries │
└──────────────────────┬──────────────────────────────┘
│ chunked, embedded, indexed
┌──────────────────────┴──────────────────────────────┐
│ INTAKE LAYER │
│ Note creation, signal triage, vault organization │
│ Concern: what enters the vault and how it's stored │
│ Failure: noise, duplicates, missing structure │
└─────────────────────────────────────────────────────┘
Intake determina o que entra no vault. Sem curadoria, o vault acumula ruído: screenshots de tweets, artigos copiados e colados sem anotação, ideias pela metade sem contexto. A camada de intake é responsável pelo controle de qualidade no ponto de entrada. Um pipeline de pontuação, uma convenção de tags ou um processo de revisão manual — qualquer mecanismo que garanta que o vault contenha conteúdo que vale recuperar.
Retrieval torna o vault consultável. Este é o motor: dividir notas em unidades de busca com chunking, transformar chunks em embeddings no espaço vetorial, indexar para busca por palavras-chave e busca semântica, combinar resultados com RRF. A camada de retrieval transforma uma pasta de arquivos em uma knowledge base consultável. Sem essa camada, o vault pode ser navegado por exploração manual e busca básica, mas não fica programaticamente acessível para ferramentas de AI.
Integração conecta a camada de retrieval às ferramentas de AI. Um servidor MCP expõe retrieval como uma ferramenta chamável. Hooks injetam contexto automaticamente. Skills capturam novo conhecimento de volta no vault. A camada de integração é a interface entre a knowledge base e os agentes de AI que a consomem.
As camadas são desacopladas por design. O pipeline de pontuação de intake não sabe nada sobre embeddings. O retriever não sabe nada sobre regras de roteamento de sinais. O servidor MCP não sabe nada sobre como as notas foram criadas. Esse desacoplamento permite que você melhore qualquer camada de forma independente. Substitua o modelo de embeddings sem alterar o pipeline de intake. Adicione uma nova capacidade MCP sem modificar o retriever. Altere as heurísticas de pontuação de sinais sem tocar no índice.
Arquitetura do vault para consumo por AI
Um vault otimizado para recuperação por AI segue convenções diferentes de um vault otimizado para navegação pessoal. Esta seção aborda a estrutura de pastas, o schema das notas, as convenções de frontmatter e os padrões específicos que melhoram a qualidade da recuperação.
Estrutura de pastas
Use prefixos numéricos para pastas de nível superior para criar uma hierarquia organizacional previsível. Os números não indicam prioridade — eles agrupam domínios relacionados e tornam a estrutura fácil de escanear.
vault/
├── 00-inbox/ # Unsorted captures, pending triage
├── 01-projects/ # Active project notes
├── 02-areas/ # Ongoing areas of responsibility
├── 03-resources/ # Reference material by topic
│ ├── programming/
│ ├── security/
│ ├── ai-engineering/
│ ├── design/
│ └── devops/
├── 04-archive/ # Completed projects, old references
├── 05-signals/ # Scored signal intake
│ ├── ai-tooling/
│ ├── security/
│ ├── systems/
│ └── ...12 domain folders
├── 06-daily/ # Daily notes (if used)
├── 07-templates/ # Note templates (excluded from index)
├── 08-attachments/ # Images, PDFs (excluded from index)
├── .obsidian/ # Obsidian config (excluded from index)
└── .indexignore # Paths to exclude from retrieval index
Pastas que devem ser indexadas: Tudo que contém prosa em markdown — projetos, áreas, recursos, sinais, notas diárias.
Pastas que devem ser excluídas da indexação: Templates (eles contêm variáveis de placeholder, não conteúdo), anexos (arquivos binários), configuração do Obsidian e qualquer pasta com conteúdo sensível que você não quer no índice de recuperação.
O arquivo .indexignore
Crie um arquivo .indexignore na raiz do vault para excluir caminhos explicitamente do índice de recuperação. A sintaxe corresponde à do .gitignore:
# Obsidian internal
.obsidian/
# Templates contain placeholders, not content
07-templates/
# Binary attachments
08-attachments/
# Personal health/medical notes
02-areas/health/
# Financial records
02-areas/finance/personal/
# Career documents (resumes, salary data)
02-areas/career/private/
O indexador lê esse arquivo antes de escanear e ignora completamente os caminhos correspondentes. Arquivos em caminhos excluídos nunca passam por chunking, nunca recebem embeddings e nunca aparecem nos resultados de busca.
Schema das notas
Toda nota deve ter frontmatter YAML. O recuperador usa campos de frontmatter para filtragem e enriquecimento de contexto:
---
title: "OAuth Token Rotation Patterns"
type: note # note | signal | project | moc | daily
domain: security # primary domain for routing
tags:
- authentication
- oauth
- token-management
created: 2026-01-15
updated: 2026-02-28
source: "" # URL if captured from external source
status: active # active | archived | draft
---
Campos obrigatórios para recuperação:
title— Usado na exibição dos resultados de busca e no contexto de heading para BM25type— Permite consultas filtradas por tipo (“mostre apenas MOCs” ou “apenas sinais”)tags— Indexado no contexto de heading do FTS5 com peso 0,3, fornecendo correspondências de palavra-chave mesmo quando o corpo usa terminologia diferente
Campos opcionais, mas valiosos:
domain— Permite consultas com escopo por domínio (“busque apenas notas de segurança”)source— Atribuição para conteúdo capturado; o recuperador pode incluir URLs de origem nos resultadosstatus— Permite excluir notas arquivadas ou em rascunho da busca ativa
Convenções de chunking
O recuperador divide o conteúdo em chunks nos limites de headings H2 (##). Isso significa que a estrutura das suas notas afeta diretamente a granularidade da recuperação:
Bom para recuperação:
## Token Rotation Strategy
The rotation interval depends on the threat model...
## Implementation with refresh_token
The OAuth 2.0 refresh token flow requires...
## Error Handling: Expired Tokens
When a token expires mid-request...
Três seções H2 produzem três chunks pesquisáveis de forma independente. Cada chunk tem contexto suficiente para que o embedding capture seu significado. Uma consulta sobre “expired token handling” corresponde especificamente ao terceiro chunk.
Ruim para recuperação:
# OAuth Notes
Token rotation depends on threat model. The OAuth 2.0 refresh
token flow requires storing the refresh token securely. When a
token expires mid-request, the client should retry after refresh.
The rotation interval is typically 15-30 minutes for access tokens
and 7-30 days for refresh tokens...
Uma seção longa sem headings H2 produz um único chunk grande. O embedding faz uma média entre todos os tópicos da seção. Uma consulta sobre qualquer subtópico corresponde igualmente à nota inteira.
Regra prática: Se uma seção cobre mais de um conceito, divida-a em subseções H2. O chunker cuida do resto.
O que não colocar nas notas
Conteúdo que degrada a qualidade da recuperação:
- Copiar e colar artigos inteiros sem anotação. O recuperador indexa as palavras-chave do artigo original, diluindo seu vault com conteúdo que você não escreveu. Em vez disso, adicione um resumo, extraia os pontos principais ou crie um link para a URL de origem.
- Screenshots sem descrição em texto. O recuperador indexa texto em markdown. Uma imagem sem alt text ou descrição ao redor fica invisível tanto para BM25 quanto para busca vetorial.
- Strings de credenciais. Chaves API, tokens, senhas, strings de conexão. Mesmo com filtragem de credenciais, a abordagem mais segura é nunca colar secrets nas notas. Em vez disso, referencie-os pelo nome (“o token Cloudflare API em
~/.env”). - Conteúdo gerado automaticamente sem curadoria. Se uma ferramenta gera uma nota (transcrição de reunião, destaques do Readwise, importação de RSS), revise e anote antes que ela entre no vault permanente. Importações automáticas sem curadoria adicionam volume sem acrescentar valor recuperável.
Ecossistema de plugins para workflows de AI
Plugins do Obsidian que melhoram a qualidade do vault para recuperação por AI se dividem em três categorias: estruturais (impõem consistência), consulta (expõem metadados) e sync (mantêm o vault atualizado).
Plugins essenciais
Dataview. Consulta seu vault como um banco de dados usando campos de frontmatter. Crie índices dinâmicos: “todas as notas marcadas com security atualizadas nos últimos 30 dias” ou “todas as notas de projeto com status active.” O Dataview não ajuda diretamente na recuperação, mas ajuda você a identificar lacunas na cobertura do seu vault e encontrar notas que precisam ser atualizadas.
TABLE type, domain, updated
FROM "03-resources"
WHERE status = "active"
SORT updated DESC
LIMIT 20
Templater. Cria notas a partir de templates com campos dinâmicos. Garanta que toda nova nota comece com o frontmatter correto usando um template que preenche previamente os campos created, type e domain. Um frontmatter consistente melhora a filtragem de recuperação.
<%* /* New Resource Note Template */ %>
---
title: "<% tp.file.cursor() %>"
type: note
domain: <% tp.system.suggester(["programming", "security", "ai-engineering", "design", "devops"], ["programming", "security", "ai-engineering", "design", "devops"]) %>
tags: []
created: <% tp.date.now("YYYY-MM-DD") %>
updated: <% tp.date.now("YYYY-MM-DD") %>
source: ""
status: active
---
## Key Points
## Details
## References
Linter. Impõe regras de formatação em todo o vault. Uma hierarquia de títulos consistente (H1 para título, H2 para seções, H3 para subseções) garante que o chunker produza resultados previsíveis. Regras do Linter que importam para recuperação:
- Incremento de títulos: impor níveis de título sequenciais (sem pular de H1 para H3)
- Título YAML: corresponder ao nome do arquivo
- Espaços finais: remover (evita artefatos de tokenização do FTS5)
- Linhas em branco consecutivas: limitar a 1 (chunks mais limpos)
Git integration. Controle de versão para o seu vault. Acompanhe alterações ao longo do tempo, sincronize entre máquinas e recupere exclusões acidentais. O Git também fornece dados de mtime que o indexador usa para detecção incremental de alterações.
Plugins que ajudam a indexação
Smart Connections. Um plugin do Obsidian que oferece busca semântica com AI dentro do próprio Obsidian. O Smart Connections v4 cria embeddings locais por padrão — depois que seu vault é indexado, conexões semânticas e consultas funcionam totalmente offline, sem chamadas API.11 v4.5.0 (5 de maio de 2026) torna as conexões de rodapé parte do Smart Connections Core, então toda instalação pode mostrar conexões de notas relacionadas no rodapé sem abrir um painel lateral. Versões recentes da v4 também adicionaram visualizações em grafo para listas de conexões, locais de dock configuráveis, melhor recuperação de block-embedding após execuções de indexação interrompidas e “Substrate”, um ambiente entre plugins que permite que Smart Connections, Smart Chat e Smart Composer compartilhem estado.21 Embora o sistema de recuperação deste guia seja externo ao Obsidian (executado como um pipeline Python), o Smart Connections é útil para explorar relações semânticas enquanto você escreve. Os dois sistemas indexam o mesmo conteúdo, mas atendem a casos de uso diferentes: Smart Connections para descoberta dentro do editor, o recuperador externo para integração com ferramentas de AI via MCP.
Plugins AI-native lançados em abril de 2026. Uma onda de novos plugins da comunidade mira diretamente o workflow Claude Code / Codex / Gemini-CLI:
| Plugin | Lançado | O que faz |
|---|---|---|
| Cortex | 4 de abril | Agente de vault impulsionado por Claude Code — trata o vault como um workspace de agente, não apenas como um repositório de notas |
| VaultSearch | 7 de abril | Busca hybrid local-first: BM25 + semântica + fuzzy (sobreposição direta com a stack de recuperação deste guia) |
| LLM Wiki | 9 de abril | Transforme seu vault em uma base de conhecimento consultável de forma privada |
| Drift | 11 de abril | Visualizador de diffs no estilo VS Code para edição do Obsidian com AI; posicionado para workflows Claude Code |
| EngramQuest | 11 de abril | Gera desafios de memória a partir de notas; inclui “AI Skills” para Claude Code / Gemini CLI / Cursor |
| Hybrid Search MCP | Março (ainda novo) | Servidor MCP + CLI com BM25 + busca semântica — criado especificamente para assistentes de AI |
Trate isso como uma área emergente — vários desses plugins provavelmente serão consolidados ou absorvidos pelo Smart Connections / núcleo do Obsidian nos próximos trimestres. Se você está escolhendo um hoje, VaultSearch e Hybrid Search MCP são os mais próximos, em filosofia, do recuperador externo deste guia.
Nota sobre Dataview: O Dataview (o plugin de consulta antigo do Obsidian) lançou a versão 0.5.70 pela última vez em abril de 2025 e está efetivamente parado desde então. Para novos trabalhos, o recurso integrado Bases do Obsidian (1.9+) é o sucessor implícito e o caminho recomendado.
Metadata Menu. Oferece edição estruturada de frontmatter com autocomplete para valores de campos. Reduz erros de digitação nos campos type, domain e tags. Metadados consistentes melhoram a precisão da filtragem de recuperação.
Plugins que prejudicam a indexação
Excalidraw. Armazena desenhos como JSON incorporado em arquivos markdown. O JSON é markdown sintaticamente válido, mas produz lixo quando dividido em chunks e incorporado. Exclua arquivos do Excalidraw do índice via .indexignore ou filtre por extensão de arquivo.
Kanban. Armazena o estado do quadro como markdown com formatação especial. O formato foi projetado para renderização de Kanban, não para recuperação de prosa. O chunker produz fragmentos de títulos de cartões e metadados que não geram bons embeddings. Exclua quadros Kanban do índice.
Calendar. Cria notas diárias com conteúdo mínimo (geralmente apenas um cabeçalho de data). Notas vazias ou quase vazias produzem chunks de baixa qualidade. Se você usa notas diárias, escreva conteúdo substancial nelas ou exclua a pasta de notas diárias do índice.
Configuração de plugins que importa
File recovery → Enabled. Protege contra exclusão acidental de notas. Não está diretamente relacionado à recuperação, mas é essencial para uma base de conhecimento da qual você depende.
Strict line breaks → Disabled. Quebras de linha padrão do Markdown (linha em branco dupla para parágrafo) produzem chunks mais limpos do que o modo strict do Obsidian (linha nova única para <br>).
Default new file location → Designated folder. Direcione novos arquivos para 00-inbox/ para que notas sem categoria não poluam pastas de domínio. A inbox é uma área de preparação; os arquivos passam para pastas de domínio após triagem.
Wiki-link format → Shortest path when possible. Alvos de link mais curtos são mais fáceis para o recuperador resolver ao indexar a estrutura de links.
Modelos de embeddings: escolha e configuração
O modelo de embeddings converte chunks de texto em vetores numéricos para busca semântica. A escolha do modelo determina a qualidade da recuperação, o tamanho do índice, a velocidade de geração dos embeddings e as dependências em runtime. Esta seção explica por que o potion-base-8M da Model2Vec é a escolha padrão e quando escolher alternativas.
Por que Model2Vec potion-base-8M
Modelo: minishlab/potion-base-8M
Parâmetros: 7,6 milhões
Dimensões: 256
Tamanho: ~30 MB
Dependências: model2vec (somente numpy, sem PyTorch)
Inferência: somente CPU, embeddings estáticos de palavras (sem camadas de atenção)
Model2Vec destila o conhecimento de um sentence transformer em embeddings estáticos de tokens. Em vez de executar camadas de atenção sobre a entrada (como BERT, MiniLM e outros modelos transformer fazem), Model2Vec produz vetores por meio de uma média ponderada de embeddings de tokens pré-computados.5 A consequência prática: a velocidade de geração dos embeddings é 50-500x maior que a de modelos baseados em transformers, porque não há computação sequencial.
Na página atual de resultados da Model2Vec, potion-base-8M atinge cerca de 92% da pontuação all-task do all-MiniLM-L6-v2 (51,32 vs 55,80), mantendo-se ordens de grandeza mais rápido.6 A diferença restante de qualidade é o trade-off pelas vantagens de velocidade e simplicidade. Para chunks curtos de markdown (em média 200-400 palavras em um vault típico), a diferença de qualidade é menos perceptível do que em documentos mais longos, porque os dois modelos convergem para representações semelhantes em textos curtos e focados.
Configuração
# embedder.py
DEFAULT_MODEL = "minishlab/potion-base-8M"
EMBEDDING_DIM = 256
class Model2VecEmbedder:
def __init__(self, model_name=DEFAULT_MODEL):
self._model_name = model_name
self._model = None
def _ensure_model(self):
if self._model is not None:
return
_activate_venv() # Add isolated venv to sys.path
from model2vec import StaticModel
self._model = StaticModel.from_pretrained(self._model_name)
def embed_batch(self, texts):
self._ensure_model()
vecs = self._model.encode(texts)
return [v.tolist() for v in vecs]
Carregamento lazy. O modelo é carregado no primeiro uso, não no momento da importação. Importar o módulo do embedder não tem custo quando o retriever opera no modo de fallback somente BM25 (por exemplo, quando a venv de embeddings não está instalada).
Ambiente virtual isolado. O modelo roda em uma venv dedicada (por exemplo, ~/.claude/venvs/memory/) para evitar conflitos de dependências com o restante da toolchain. A função _activate_venv() adiciona o site-packages da venv ao sys.path em runtime.
# Create isolated venv
python3 -m venv ~/.claude/venvs/memory
~/.claude/venvs/memory/bin/pip install model2vec
Processamento em lotes. O embedder processa textos em lotes de 64 para amortizar o overhead da Model2Vec. O indexador envia chunks para embed_batch() em vez de gerar o embedding de um chunk por vez.
Quando escolher alternativas
| Modelo | Dim | Tamanho | Velocidade | Qualidade (MTEB) | Melhor para |
|---|---|---|---|---|---|
| potion-base-8M | 256 | 30 MB | 500x | 51,32 | Padrão: local, rápido, sem GPU |
| potion-base-32M | 256 | 120 MB | 400x | 52,83 | Mais qualidade, ainda estático |
| potion-retrieval-32M | 256 | 120 MB | 400x | 35,06 (retrieval) | Estático otimizado para recuperação |
| potion-multilingual-128M | 256 | ~500 MB | 300x | — | Vaults multilíngues (101 idiomas) |
| all-MiniLM-L6-v2 | 384 | 80 MB | 1x | 55,80 | Mais qualidade, ainda local |
| nomic-embed-text-v1.5 | 768 | 270 MB | 0,5x | 62,28 | Melhor qualidade local |
| text-embedding-3-small | 1536 | API | N/A | 62,30 | Baseado em API, maior qualidade |
Escolha potion-base-32M quando você quiser melhor qualidade do que potion-base-8M sem sair da família de embeddings estáticos. Ele usa um vocabulário maior destilado de baai/bge-base-en-v1.5, alcançando uma pontuação all-task de 52,83 (cerca de 3% acima do potion-base-8M), mantendo a mesma saída de 256 dimensões e dependência somente de numpy.8 O arquivo do modelo 4x maior aumenta o uso de memória, mas a velocidade de geração de embeddings continua ordens de grandeza mais rápida que a de modelos transformer.
Escolha potion-retrieval-32M quando seu caso de uso principal for recuperação (que é o caso da busca no vault). Esta variante é ajustada a partir do potion-base-32M especificamente para tarefas de retrieval, com pontuação de 35,06 na tabela de benchmark de retrieval da Model2Vec contra 32,67 do potion-base-32M.8 O trade-off é que ele é otimizado para recuperação, não para qualidade de embeddings de uso geral.
Escolha potion-multilingual-128M quando seu vault contiver notas em vários idiomas. Lançado em maio de 2025, este modelo de 101 idiomas é o modelo de embeddings estáticos com melhor desempenho para tarefas multilíngues, gerando embeddings para qualquer texto em qualquer idioma e mantendo a mesma dependência somente de numpy dos outros modelos potion.12 O arquivo maior do modelo (~500 MB) é o trade-off pela capacidade multilíngue. Use isso quando você tiver notas em japonês, chinês, alemão ou outros idiomas além do inglês junto com conteúdo em inglês.
Escolha all-MiniLM-L6-v2 quando a qualidade da recuperação for mais importante que a velocidade e você tiver PyTorch instalado. Os vetores de 384 dimensões aumentam o tamanho do banco de dados SQLite em ~50% em comparação com vetores de 256 dimensões. A velocidade de geração dos embeddings cai de <1 minuto para ~10 minutos em uma reindexação completa de 15.000 arquivos em hardware M-series.
Escolha nomic-embed-text-v1.5 quando você precisar da melhor qualidade possível de recuperação local e aceitar uma indexação mais lenta. Os vetores de 768 dimensões aproximadamente triplicam o tamanho do banco de dados. Requer PyTorch e uma CPU moderna ou GPU.
Escolha text-embedding-3-small quando latência de rede e privacidade forem trade-offs aceitáveis. O API produz os embeddings de maior qualidade, mas introduz uma dependência de cloud, custo por token (US$ 0,02/milhão de tokens) e envia seu conteúdo para os servidores da OpenAI.
Fique com potion-base-8M em todos os outros casos. A vantagem de velocidade é crítica para indexação iterativa (reindexar durante o desenvolvimento), a dependência somente de numpy evita a complexidade de instalação do PyTorch, e os vetores de 256 dimensões mantêm o banco de dados compacto.
Quantização e redução de dimensionalidade
Model2Vec v0.5.0+ oferece suporte ao carregamento de modelos com precisão e dimensões reduzidas.8 Isso é útil para deploy em hardware limitado ou para reduzir o tamanho do banco de dados sem trocar de modelo:
from model2vec import StaticModel
# Load with int8 quantization (25% of original size)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", quantize=True)
# Load with reduced dimensions (e.g., 128 instead of 256)
model = StaticModel.from_pretrained("minishlab/potion-base-8M", dimensionality=128)
Modelos quantizados mantêm qualidade de recuperação quase idêntica com uma fração do uso de memória. A redução de dimensionalidade segue uma truncagem no estilo Matryoshka — as primeiras N dimensões carregam a maior parte das informações. Reduzir de 256 para 128 dimensões corta pela metade o armazenamento dos vetores, com perda mínima de qualidade para recuperação de textos curtos.
Model2Vec v0.8.x atualiza os internos de tokenizer/persistência, descontinua o suporte a Python 3.9 e atualiza os resultados publicados para as tabelas MTEB mais recentes. Fixe a versão ou teste model2vec antes de atualizar um indexador de produção, porque upgrades da biblioteca podem alterar caminhos de carregamento de modelos mesmo quando o nome do modelo de embeddings permanece igual.10
Fine-tuning para embeddings específicos do vault
Model2Vec v0.4.0+ oferece suporte ao treinamento de modelos de classificação personalizados sobre embeddings estáticos, v0.7.0 adiciona quantização de vocabulário e pooling configurável para destilação, e v0.8.x refatora o comportamento de tokenizer e persistência.10 Isso é relevante para vaults com vocabulário especializado (notas médicas, referências jurídicas, jargão específico de domínio), em que os modelos potion padrão podem não capturar nuances semânticas:
from model2vec import StaticModel
from model2vec.train import train_model
# Fine-tune on vault-specific data
model = StaticModel.from_pretrained("minishlab/potion-base-8M")
trained_model = train_model(model, train_texts, train_labels)
trained_model.save_pretrained("./vault-embeddings")
Para a maioria dos vaults, o potion-base-8M padrão produz qualidade de recuperação suficiente. Fine-tuning só vale a pena quando a recuperação deixa de encontrar de forma consistente conexões específicas do domínio que um modelo de uso geral não consegue capturar.
Rastreamento de hash do modelo
O indexador armazena um hash derivado do nome do modelo e do tamanho do vocabulário. Se você alterar o modelo de embeddings, o indexador detecta a incompatibilidade na próxima execução incremental e dispara automaticamente uma reindexação completa.
def _compute_model_hash(self):
"""Hash model name + vocab size for compatibility tracking."""
key = f"{self._model_name}:{self._model.vocab_size}"
return hashlib.sha256(key.encode()).hexdigest()[:16]
Isso evita misturar vetores de modelos diferentes no mesmo banco de dados, o que produziria pontuações sem sentido de cosine similarity.
Modos de falha
Falha no download do modelo. A primeira execução baixa o modelo do Hugging Face. Se o download falhar (problema de rede, firewall corporativo), o retriever usa fallback para o modo somente BM25. O modelo fica em cache local depois do primeiro download.
Incompatibilidade de dimensões. Se você trocar de modelo sem limpar o banco de dados, os vetores armazenados terão uma dimensão diferente dos novos embeddings. O indexador detecta isso por meio do hash do modelo e dispara uma reindexação completa. Se a verificação de hash falhar (modelo personalizado sem hash adequado), sqlite-vec gerará erro em consultas KNN com dimensões incompatíveis.
Pressão de memória em vaults grandes. Gerar embeddings para mais de 50.000 chunks em um único lote pode consumir muita memória. O indexador processa em lotes de 64 para limitar o pico de uso de memória. Se a memória ainda for um problema, reduza o tamanho do lote.
Pesquisa de texto completo com FTS5
A extensão FTS5 do SQLite oferece pesquisa de texto completo com ranqueamento BM25. FTS5 é o componente de pesquisa por palavra-chave do pipeline de recuperação hybrid. Esta seção aborda a configuração do FTS5, quando o BM25 se destaca e seus modos de falha específicos.
Tabela virtual FTS5
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text,
section,
heading_context,
content=chunks,
content_rowid=id
);
Modo de sincronização de conteúdo. O parâmetro content=chunks informa ao FTS5 para referenciar a tabela chunks diretamente, em vez de armazenar uma cópia duplicada do texto. Isso reduz pela metade o requisito de armazenamento, mas significa que o FTS5 precisa ser sincronizado manualmente quando chunks são inseridos, atualizados ou excluídos.
Colunas. Três colunas são indexadas:
- chunk_text — O conteúdo principal de cada chunk (peso BM25: 1,0)
- section — O texto do cabeçalho H2 (peso BM25: 0,5)
- heading_context — Título da nota, tags e metadados (peso BM25: 0,3)
Ranqueamento BM25
O BM25 ranqueia documentos por frequência de termos, frequência inversa de documentos e normalização do tamanho do documento. A função auxiliar bm25() no FTS5 aceita pesos por coluna:
SELECT
c.id, c.file_path, c.section, c.chunk_text,
bm25(chunks_fts, 1.0, 0.5, 0.3) AS score
FROM chunks_fts
JOIN chunks c ON chunks_fts.rowid = c.id
WHERE chunks_fts MATCH ?
ORDER BY score
LIMIT 30;
Os pesos das colunas (1,0, 0,5, 0,3) significam:
- Uma correspondência de palavra-chave em chunk_text contribui mais para a pontuação
- Uma correspondência em section (cabeçalho) contribui metade disso
- Uma correspondência em heading_context (título, tags) contribui 30% disso
Esses pesos são ajustáveis. Se o seu vault tiver cabeçalhos descritivos que preveem fortemente a qualidade do conteúdo, aumente o peso de section. Se suas tags forem abrangentes e precisas, aumente o peso de heading_context.
Quando o BM25 vence
O BM25 se destaca em consultas que contêm identificadores exatos:
- Nomes de funções:
_rrf_fuse,embed_batch,get_stale_files - flags de CLI:
--incremental,--vault,--model - Chaves de configuração:
bm25_weight,max_tokens,batch_size - Mensagens de erro:
SQLITE_LOCKED,ConnectionRefusedError - Termos técnicos específicos:
PostToolUse,PreToolUse,AGENTS.md
Para essas consultas, o BM25 encontra a correspondência exata imediatamente. A pesquisa vetorial retornaria conteúdo semanticamente relacionado, mas poderia ranquear a correspondência exata abaixo de uma discussão conceitual.
Quando o BM25 falha
O BM25 falha em consultas que usam terminologia diferente do conteúdo armazenado:
- Consulta: “como lidar com falhas de autenticação” → O vault contém notas sobre “recuperação de erro de login” e “tratamento de expiração de sessão”. O BM25 não encontra correspondência porque as palavras-chave são diferentes.
- Consulta: “qual é a melhor forma de gerenciar estado” → O vault contém notas sobre “padrões de Redux store” e “context providers”. O BM25 não encontra porque “gerenciamento de estado” é expresso por nomes de tecnologias específicas.
O BM25 também falha com colisão de palavras-chave em escala. Em um vault com 15.000 arquivos, uma pesquisa por “configuração” corresponde a centenas de notas porque quase toda nota de projeto menciona configuração. Os resultados estão tecnicamente corretos, mas são praticamente inúteis — o ranqueamento não consegue determinar qual nota de “configuração” é relevante para a consulta atual.
Tokenizer do FTS5
O FTS5 usa o tokenizer unicode61 por padrão, que lida com texto ASCII e Unicode. Para vaults com conteúdo CJK (chinês, japonês, coreano) significativo, considere o tokenizer trigram:
-- For CJK-heavy vaults
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text, section, heading_context,
content=chunks, content_rowid=id,
tokenize='trigram'
);
O tokenizer padrão unicode61 divide o texto nos limites das palavras, o que funciona mal para idiomas sem espaços entre palavras. O tokenizer trigram divide a cada três caracteres, permitindo correspondência por substring ao custo do tamanho do índice (aproximadamente 3x maior).
Manutenção
O FTS5 exige sincronização explícita quando a tabela chunks subjacente muda:
# After inserting chunks
cursor.execute("""
INSERT INTO chunks_fts(chunks_fts)
VALUES('rebuild')
""")
O comando rebuild reconstrói o índice FTS5 a partir da tabela de conteúdo. Execute-o após inserções em massa (reindexação completa), mas não após atualizações incrementais individuais — para essas, use INSERT INTO chunks_fts(rowid, chunk_text, section, heading_context) para sincronizar linhas individuais.
Pesquisa vetorial com sqlite-vec
A extensão sqlite-vec traz a busca vetorial KNN (K-Nearest Neighbors) para o SQLite. Esta seção cobre a configuração do sqlite-vec, o pipeline de embedding da nota até o vetor pesquisável e os padrões específicos de consulta.
Tabela virtual sqlite-vec
CREATE VIRTUAL TABLE chunk_vecs USING vec0(
id INTEGER PRIMARY KEY,
embedding float[256]
);
O módulo vec0 armazena vetores float de 256 dimensões como dados binários compactados. A coluna id mapeia 1:1 para a tabela chunks, permitindo joins entre resultados vetoriais e metadados de chunks.
Pipeline de embedding
O pipeline vai da nota até o vetor pesquisável:
Note (.md file)
→ Chunker: split at H2 boundaries
→ Chunks (30-2000 chars each)
→ Credential filter: scrub secrets
→ Embedder: Model2Vec encode
→ Vectors (256-dim float arrays)
→ sqlite-vec: store as packed binary
→ Ready for KNN queries
Serialização vetorial
O módulo struct do Python serializa vetores float para armazenamento no sqlite-vec:
import struct
def _serialize_vector(vec):
"""Pack float list into binary for sqlite-vec."""
return struct.pack(f"{len(vec)}f", *vec)
def _deserialize_vector(blob, dim=256):
"""Unpack binary blob to float list."""
return list(struct.unpack(f"{dim}f", blob))
Consulta KNN
Uma consulta de busca vetorial gera um embedding da consulta de entrada e depois encontra os K chunks mais próximos por distância de cosseno:
def _vector_search(self, query_text, limit=30):
query_vec = self.embedder.embed_batch([query_text])[0]
packed = _serialize_vector(query_vec)
results = self.db.execute("""
SELECT
cv.id,
cv.distance,
c.file_path,
c.section,
c.chunk_text
FROM chunk_vecs cv
JOIN chunks c ON cv.id = c.id
WHERE embedding MATCH ?
AND k = ?
ORDER BY distance
""", [packed, limit]).fetchall()
return results
O operador MATCH no sqlite-vec executa busca aproximada de vizinhos mais próximos. O parâmetro k controla quantos resultados retornar. A coluna distance contém a distância de cosseno (0 = idêntico, 2 = oposto).
Paginação KNN com restrições de distância
A partir do sqlite-vec v0.1.7, consultas KNN têm suporte a restrições WHERE distance < ?, permitindo paginação baseada em cursor em grandes conjuntos de resultados sem reescanear páginas anteriores.14 As versões estáveis posteriores v0.1.8 e v0.1.9 são releases de empacotamento e correções de bugs de DELETE, não releases com novo modelo de consulta, então a v0.1.7 continua sendo o limite de recurso para esse padrão de paginação.23
No horizonte, a linha v0.1.10-alpha (31 de março a 18 de maio de 2026) é a primeira a levar o sqlite-vec além do KNN de força bruta: ela introduz tipos de índice de vizinho mais próximo aproximado — rescore, um índice experimental ivf (inverted-file) que não vem habilitado por padrão, e um índice DiskANN baseado em disco para cofres grandes demais para manter vetores residentes em memória.23 Isso mudaria a história de escalabilidade para cofres muito grandes, mas a linha 0.1.10 ainda está em pré-release (alpha) — trate a indexação ANN como experimental e continue construindo sobre o caminho KNN de força bruta estável da v0.1.9 para cofres de produção até que uma versão estável 0.1.10 seja lançada.
def _paginated_vector_search(self, query_vec, page_size=20, max_distance=None):
"""Paginate through KNN results using distance constraints."""
packed = _serialize_vector(query_vec)
constraint = f"AND distance < {max_distance}" if max_distance else ""
results = self.db.execute(f"""
SELECT cv.id, cv.distance, c.file_path, c.chunk_text
FROM chunk_vecs cv
JOIN chunks c ON cv.id = c.id
WHERE embedding MATCH ?
AND k = ?
{constraint}
ORDER BY distance
""", [packed, page_size]).fetchall()
# Use last result's distance as cursor for next page
next_cursor = results[-1][1] if results else None
return results, next_cursor
Isso substitui o padrão anterior de buscar um k grande e fatiar no Python, reduzindo o uso de memória em consultas exploratórias sobre cofres grandes.
Suporte a DELETE em tabelas vec0
O sqlite-vec v0.1.7 adicionou suporte nativo a DELETE para tabelas virtuais vec0, e a v0.1.9 corrigiu um caminho de erro de DELETE envolvendo colunas de texto de metadados com mais de 12 caracteres.1423 Antes, remover vetores exigia descartar e recriar a tabela. Agora, o caminho de remoção de arquivos do indexador pode excluir vetores diretamente:
# Before v0.1.7: required workaround (drop + recreate, or mark as inactive)
# After v0.1.7: direct DELETE works
db.execute("DELETE FROM chunk_vecs WHERE id = ?", [chunk_id])
Isso simplifica a reindexação incremental quando notas são excluídas ou movidas. O indexador não precisa mais manter uma tabela paralela de “IDs ativos” nem rebuilds em lote.
Quando a busca vetorial vence
A busca vetorial se destaca em consultas nas quais o conceito importa mais do que as palavras específicas:
- Consulta: “como lidar com falhas de autenticação” → Encontra notas sobre “recuperação de erro de login” (mesmo espaço semântico, palavras-chave diferentes)
- Consulta: “quais padrões existem para caching” → Encontra notas sobre “memoization”, “estratégias de Redis TTL” e “HTTP cache headers” (conceitos relacionados, terminologia diversa)
- Consulta: “abordagens para testar código assíncrono” → Encontra notas sobre “fixtures pytest-asyncio”, “mock event loops” e “async test patterns” (mesmo conceito expresso por detalhes de implementação)
Quando a busca vetorial falha
A busca vetorial tem dificuldade com identificadores exatos:
- Consulta:
_rrf_fuse→ Retorna notas sobre “fusion algorithms” e “rank merging”, mas pode ranquear a definição real da função abaixo de discussões conceituais - Consulta:
PostToolUse→ Retorna notas sobre “tool lifecycle hooks” e “post-execution handlers” em vez do nome específico do hook
A busca vetorial também tem dificuldade com dados estruturados. Arquivos de configuração JSON, blocos YAML e snippets de código produzem embeddings que capturam padrões estruturais em vez de significado semântico. Um arquivo JSON com "review": true gera um embedding diferente de uma discussão em prosa sobre code review.
Degradação suave
Se o sqlite-vec não carregar (extensão ausente, plataforma incompatível, biblioteca corrompida), o retriever faz fallback para busca apenas com BM25:
class VectorIndex:
def __init__(self, db_path):
self.db = sqlite3.connect(db_path)
self._vec_available = False
try:
self.db.enable_load_extension(True)
self.db.load_extension("vec0")
self._vec_available = True
except Exception:
pass # BM25-only mode
@property
def vec_available(self):
return self._vec_available
O retriever verifica vec_available antes de tentar consultas vetoriais. Quando desabilitado, todas as buscas usam apenas BM25, e a etapa de fusão RRF é ignorada.
Reciprocal Rank Fusion (RRF)
RRF combina duas listas ranqueadas sem exigir calibração de pontuação. Esta seção aborda o algoritmo, um rastreamento de consulta trabalhado, o ajuste do parâmetro k e por que RRF foi escolhido em vez de alternativas. Para uma calculadora interativa com ranks editáveis, presets de cenário e um explorador visual de arquitetura, veja o mergulho aprofundado no hybrid retriever.
O algoritmo
RRF atribui a cada documento uma pontuação baseada apenas na sua posição de rank em cada lista:
score(d) = Σ (weight_i / (k + rank_i))
Onde:
- k é uma constante de suavização (60, seguindo Cormack et al.3)
- rank_i é o rank do documento, baseado em 1, na lista de resultados i
- weight_i é um multiplicador opcional por lista (padrão 1.0)
Documentos que ficam bem ranqueados em várias listas recebem pontuações fusionadas mais altas. Documentos que aparecem em apenas uma lista recebem uma pontuação dessa única fonte.
Por que RRF em vez de alternativas
Combinação linear ponderada exige calibrar pontuações BM25 contra distâncias de cosine similarity. As pontuações BM25 não têm limite superior e escalam com o tamanho do corpus. As distâncias de cosine similarity são limitadas a [0, 2]. Combiná-las exige normalização, e os parâmetros de normalização dependem do dataset. RRF usa apenas posições de rank, que são sempre números inteiros começando em 1, independentemente do método de pontuação.
Modelos de fusão aprendidos exigem dados de treinamento rotulados — pares de relevância entre consulta e documento. Para uma base de conhecimento pessoal, esses dados de treinamento não existem. Você precisaria julgar manualmente centenas de pares consulta-documento para treinar um modelo útil. RRF funciona sem nenhum dado de treinamento.
Métodos de votação Condorcet (Borda count, Schulze method) são teoricamente elegantes, mas mais complexos de implementar e ajustar. O artigo original de RRF demonstrou que RRF supera métodos Condorcet em dados de avaliação TREC.3
Fusão na prática
Consulta: “how does the review aggregator handle disagreements”
BM25 ranqueia review-aggregator.py na posição 3 (correspondências exatas de palavras-chave em “review,” “aggregator,” “disagreements”), mas coloca dois arquivos de configuração acima (eles correspondem a “review” com mais destaque). A busca vetorial ranqueia o mesmo chunk na posição 1 (correspondência semântica em resolução de conflitos). Após a fusão por RRF:
| Chunk | BM25 | Vec | Pontuação fusionada |
|---|---|---|---|
| review-aggregator.py “Disagreement Resolution” | #3 | #1 | 0.0323 |
| code-review-patterns.md “Multi-Reviewer” | #4 | #2 | 0.0317 |
| deliberation-config.json “Review Weights” | #1 | — | 0.0164 |
Chunks que ficam bem ranqueados em ambas as listas sobem para o topo. Chunks que aparecem em apenas uma lista recebem uma pontuação de fonte única e ficam abaixo dos resultados ranqueados em duas listas. A lógica real de resolução de desacordos vence porque os dois métodos a encontraram — BM25 por palavras-chave, busca vetorial por semântica.
Para o rastreamento completo passo a passo com a matemática de RRF por rank, experimente diferentes valores de k na calculadora interativa de RRF.
Implementação
RRF_K = 60
def _rrf_fuse(self, bm25_results, vec_results,
bm25_weight=1.0, vec_weight=1.0):
"""Fuse BM25 and vector results using Reciprocal Rank Fusion."""
scores = {}
for rank, r in enumerate(bm25_results, start=1):
cid = r["id"]
if cid not in scores:
scores[cid] = {
"rrf_score": 0.0,
"file_path": r["file_path"],
"section": r["section"],
"chunk_text": r["chunk_text"],
"bm25_rank": None,
"vec_rank": None,
}
scores[cid]["rrf_score"] += bm25_weight / (self._rrf_k + rank)
scores[cid]["bm25_rank"] = rank
for rank, r in enumerate(vec_results, start=1):
cid = r["id"]
if cid not in scores:
scores[cid] = {
"rrf_score": 0.0,
"file_path": r["file_path"],
"section": r["section"],
"chunk_text": r["chunk_text"],
"bm25_rank": None,
"vec_rank": None,
}
scores[cid]["rrf_score"] += vec_weight / (self._rrf_k + rank)
scores[cid]["vec_rank"] = rank
fused = sorted(
scores.values(),
key=lambda x: x["rrf_score"],
reverse=True,
)
return fused
Ajustando k
A constante k controla quanto peso é dado aos resultados mais bem ranqueados em relação aos resultados de rank mais baixo:
- k mais baixo (por exemplo, 10): Os resultados no topo dominam. Rank 1 pontua 1/11 = 0,091, rank 10 pontua 1/20 = 0,050 (diferença de 1,8x). Bom quando você confia que os rankers individuais acertam o resultado principal.
- k padrão (60): Equilibrado. Rank 1 pontua 1/61 = 0,0164, rank 10 pontua 1/70 = 0,0143 (diferença de 1,15x). As diferenças de rank são comprimidas, dando mais peso a aparecer em várias listas.
- k mais alto (por exemplo, 200): Aparecer nas duas listas importa muito mais do que a posição de rank. Rank 1 pontua 1/201, rank 10 pontua 1/210 — quase idêntico. Use quando os rankers individuais produzem rankings ruidosos, mas a concordância entre listas é confiável.
Comece com k=60. O artigo original de RRF encontrou esse valor robusto em diversos datasets TREC. Ajuste apenas depois de medir casos de falha na sua própria distribuição de consultas.
Desempate
Quando dois chunks têm pontuações RRF idênticas (raro, mas possível com o mesmo rank em uma lista e sem aparecer na outra), desfaça empates assim:
- Prefira chunks que aparecem nas duas listas em vez de chunks que aparecem em apenas uma
- Entre chunks nas duas listas, prefira aquele com o menor rank combinado
- Entre chunks em apenas uma lista, prefira aquele com o menor rank nessa lista
O pipeline completo de retrieval
Esta seção acompanha uma consulta da entrada à saída por todo o pipeline: busca BM25, busca vetorial, fusão RRF, truncamento por orçamento de tokens e montagem do contexto.
Fluxo de ponta a ponta
User query: "PostToolUse hook for context compression"
│
├─ BM25 Search (FTS5)
│ → MATCH "PostToolUse hook context compression"
│ → Top 30 results ranked by BM25 score
│ → 12ms
│
├─ Vector Search (sqlite-vec)
│ → Embed query with Model2Vec
│ → KNN k=30 on chunk_vecs
│ → Top 30 results ranked by cosine distance
│ → 8ms
│
└─ RRF Fusion
→ Merge 60 candidates (may overlap)
→ Score by rank position
→ Top 10 results
→ 3ms
│
└─ Token Budget
→ Truncate to max_tokens (default 4000)
→ Estimate at 4 chars per token
→ Return results with metadata
→ <1ms
Latência total: ~23ms para um banco de dados com 49.746 chunks em hardware Apple M3 Pro.
A API de search
class HybridRetriever:
def search(self, query, limit=10, max_tokens=4000,
bm25_weight=1.0, vec_weight=1.0):
"""
Search the vault using hybrid BM25 + vector retrieval.
Args:
query: Search query text
limit: Maximum results to return
max_tokens: Token budget for total result text
bm25_weight: Weight for BM25 results in RRF
vec_weight: Weight for vector results in RRF
Returns:
List of SearchResult with file_path, section,
chunk_text, rrf_score, bm25_rank, vec_rank
"""
# BM25 search
bm25_results = self._bm25_search(query, limit=30)
# Vector search (if available)
if self.index.vec_available:
vec_results = self._vector_search(query, limit=30)
fused = self._rrf_fuse(
bm25_results, vec_results,
bm25_weight, vec_weight,
)
else:
fused = bm25_results # BM25-only fallback
# Token budget truncation
results = []
token_count = 0
for r in fused[:limit]:
chunk_tokens = len(r["chunk_text"]) // 4
if token_count + chunk_tokens > max_tokens:
break
results.append(r)
token_count += chunk_tokens
return results
Truncamento por orçamento de tokens
O parâmetro max_tokens impede que o retriever retorne mais contexto do que a ferramenta de AI consegue usar. A estimativa usa 4 caracteres por token (uma aproximação razoável para prosa em inglês). Os resultados são truncados de forma gulosa: adiciona resultados na ordem do ranking até o orçamento acabar.
Essa é uma estratégia conservadora. Uma abordagem mais sofisticada consideraria as pontuações de qualidade de cada resultado e preferiria resultados mais curtos e de maior qualidade em vez de resultados mais longos e de menor qualidade. A abordagem gulosa é mais simples e funciona bem na prática porque o ranking RRF já ordena os resultados por relevância.
Esquema do banco de dados (completo)
-- Chunk content and metadata
CREATE TABLE chunks (
id INTEGER PRIMARY KEY,
file_path TEXT NOT NULL,
section TEXT NOT NULL,
chunk_text TEXT NOT NULL,
heading_context TEXT DEFAULT '',
mtime_ns INTEGER NOT NULL,
embedded_at REAL NOT NULL
);
CREATE INDEX idx_chunks_file ON chunks(file_path);
CREATE INDEX idx_chunks_mtime ON chunks(mtime_ns);
-- FTS5 for BM25 search (content-synced to chunks table)
CREATE VIRTUAL TABLE chunks_fts USING fts5(
chunk_text, section, heading_context,
content=chunks, content_rowid=id
);
-- sqlite-vec for vector KNN search
CREATE VIRTUAL TABLE chunk_vecs USING vec0(
id INTEGER PRIMARY KEY,
embedding float[256]
);
-- Model metadata for compatibility tracking
CREATE TABLE model_meta (
key TEXT PRIMARY KEY,
value TEXT
);
Caminho de degradação gradual
Full pipeline: BM25 + Vector + RRF → Best results
No sqlite-vec: BM25 only → Good results (no semantic)
No model download: BM25 only → Good results (no semantic)
No FTS5: Vector only → Decent results (no keyword)
No database: Error → Prompt user to run indexer
O retriever verifica os recursos disponíveis na inicialização e adapta sua estratégia de consulta. Um componente ausente reduz a qualidade, mas não causa erros. A única falha crítica é a ausência do arquivo do banco de dados.
Estatísticas de produção
Medido em um vault com 16.894 arquivos, 49.746 chunks, banco de dados SQLite de 83 MB, Apple M3 Pro:
| Métrica | Valor |
|---|---|
| Total de arquivos | 16.894 |
| Total de chunks | 49.746 |
| Tamanho do banco de dados | 83 MB |
| Latência de consulta BM25 (p50) | 12ms |
| Latência de consulta vetorial (p50) | 8ms |
| Latência da fusão RRF | 3ms |
| Latência de search de ponta a ponta (p50) | 23ms |
| Tempo de reindexação completa | ~4 minutos |
| Tempo de reindexação incremental | <10 segundos |
| Modelo de embedding | potion-base-8M (256-dim) |
| Pool de candidatos BM25 | 30 |
| Pool de candidatos vetoriais | 30 |
| Limite padrão de resultados | 10 |
| Orçamento padrão de tokens | 4.000 tokens |
Hashing de conteúdo e detecção de alterações
O indexador precisa saber quais arquivos mudaram desde a última execução do índice. Esta seção cobre o mecanismo de detecção de alterações e a estratégia de hashing.
Comparação de horário de modificação do arquivo
O indexador armazena mtime_ns (horário de modificação do arquivo em nanossegundos) para cada chunk na tabela chunks. Em uma execução incremental, o indexador:
- Examina o vault em busca de todos os arquivos
.mdnas pastas permitidas - Lê o
mtime_nsde cada arquivo a partir do sistema de arquivos - Compara com o
mtime_nsarmazenado no banco de dados - Identifica três categorias:
- Arquivos novos: o path existe no sistema de arquivos, mas não no banco de dados
- Arquivos alterados: o path existe nos dois, mas o
mtime_nsé diferente - Arquivos excluídos: o path existe no banco de dados, mas não no sistema de arquivos
def get_stale_files(self, vault_mtimes):
"""Find files whose mtime changed or are new."""
stored = dict(self.db.execute(
"SELECT DISTINCT file_path, mtime_ns FROM chunks"
).fetchall())
stale = []
for path, mtime in vault_mtimes.items():
if path not in stored or stored[path] != mtime:
stale.append(path)
return stale
def get_deleted_files(self, vault_paths):
"""Find files in database that no longer exist in vault."""
stored_paths = set(r[0] for r in self.db.execute(
"SELECT DISTINCT file_path FROM chunks"
).fetchall())
return stored_paths - set(vault_paths)
Por que mtime, não hash de conteúdo
O hashing de conteúdo (SHA-256 do conteúdo do arquivo) seria mais confiável do que a comparação por mtime — ele detectaria casos em que um arquivo foi tocado sem alteração (por exemplo, um git checkout restaurando o mtime original). Porém, o hashing exige ler todos os arquivos em cada execução incremental. Para 16.894 arquivos, ler o conteúdo dos arquivos leva de 2 a 3 segundos. Ler mtimes do sistema de arquivos leva <100ms.
O trade-off: a comparação por mtime ocasionalmente dispara a reindexação desnecessária de arquivos inalterados (falsos positivos), mas nunca deixa de detectar alterações reais. Falsos positivos custam algumas chamadas extras de embedding por execução. A diferença de velocidade (100ms vs 3 segundos) torna o mtime a escolha pragmática para um sistema que roda em cada interação com AI.
Como lidar com exclusões
Quando um arquivo é excluído do vault, o indexador remove todos os seus chunks do banco de dados:
def remove_file(self, file_path):
"""Remove all chunks and vectors for a file."""
chunk_ids = [r[0] for r in self.db.execute(
"SELECT id FROM chunks WHERE file_path = ?",
[file_path],
).fetchall()]
for cid in chunk_ids:
self.db.execute(
"DELETE FROM chunk_vecs WHERE id = ?", [cid]
)
self.db.execute(
"DELETE FROM chunks WHERE file_path = ?",
[file_path],
)
A instrução DELETE FROM chunk_vecs funciona nativamente a partir do sqlite-vec v0.1.7, com uma correção de bug na v0.1.9 para operações DELETE em tabelas vec0 com colunas de texto de metadados mais longas.1423 Versões anteriores exigiam workarounds (remover e recriar a tabela virtual, ou manter um conjunto externo de “IDs ativos”). Se você estiver usando uma versão anterior à 0.1.9, atualize antes de depender de exclusões diretas em esquemas com muitos metadados.
Tabelas FTS5 com sincronização de conteúdo exigem exclusão explícita via INSERT INTO chunks_fts(chunks_fts, rowid, ...) VALUES('delete', ?, ...) para cada linha removida. O indexador lida com isso como parte do processo de remoção de arquivos.
Reindex incremental vs completo
O indexador oferece suporte a dois modos: incremental (rápido, para uso diário) e completo (lento, ocasional). Esta seção explica quando usar cada um, as garantias de idempotência e a recuperação de corrupção.
Reindex incremental
Quando usar: Indexação diária depois de editar notas. É o modo padrão.
O que ele faz: 1. Varre o vault em busca de alterações de arquivos (comparação de mtime) 2. Exclui chunks de arquivos removidos 3. Refaz o chunking e os embeddings dos arquivos alterados 4. Insere novos chunks para arquivos novos 5. Sincroniza o índice FTS5
Duração típica: <10 segundos para as edições de um dia em um vault com 16.000 arquivos.
python index_vault.py --incremental
Reindex completo
Quando usar: - Depois de alterar o modelo de embedding (incompatibilidade de hash do modelo detectada) - Depois de uma migração de schema (novas colunas, índices alterados) - Depois de corrupção do banco de dados (falha na verificação de integridade) - Quando a indexação incremental produz resultados inesperados
O que ele faz: 1. Remove todos os dados existentes (chunks, vetores, entradas FTS5) 2. Varre o vault inteiro 3. Faz o chunking de todos os arquivos 4. Gera embeddings de todos os chunks 5. Cria o índice FTS5 do zero
Duração típica: ~4 minutos para 16.894 arquivos no Apple M3 Pro.
python index_vault.py --full
Idempotência
Ambos os modos são idempotentes: executar o mesmo comando duas vezes produz o mesmo resultado. O indexador exclui os chunks existentes de um arquivo antes de inserir novos, então repetir a indexação incremental em um banco de dados já atualizado produz zero alterações. Repetir a indexação completa produz um banco de dados idêntico.
Recuperação de corrupção
Se o banco de dados SQLite for corrompido (queda de energia durante a escrita, erro de disco, processo encerrado no meio de uma transação):
# Check integrity
sqlite3 vectors.db "PRAGMA integrity_check;"
# If corruption detected, full reindex rebuilds from source files
python index_vault.py --full
A fonte da verdade sempre são os arquivos do vault, não o banco de dados. O banco de dados é um artefato derivado que pode ser reconstruído a qualquer momento. Esta é uma propriedade crítica do design: você nunca precisa fazer backup do banco de dados.
A flag --incremental
Quando o indexador roda com --incremental:
- Verificação do hash do modelo. Compara o hash do modelo armazenado com o modelo atual. Se for diferente, muda automaticamente para o modo de reindex completo e avisa o usuário.
- Varredura de arquivos. Percorre as pastas permitidas, coleta caminhos de arquivos e mtimes.
- Detecção de alterações. Compara com os dados armazenados.
- Processamento em lote. Refaz o chunking e os embeddings dos arquivos alterados em lotes de 64.
- Relatório de progresso. Imprime a contagem de arquivos processados e o tempo decorrido.
- Encerramento controlado. Trata SIGINT concluindo o arquivo atual antes de parar.
Filtragem de credenciais e limites de dados
Notas pessoais contêm segredos: chaves API, bearer tokens, strings de conexão de banco de dados, chaves privadas coladas durante sessões de debugging. O filtro de credenciais impede que isso entre no índice de retrieval.
O problema
Uma nota sobre debugging de uma integração OAuth pode conter:
The token was: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
I used this curl command:
curl -H "Authorization: Bearer sk-ant-api03-abc123..."
Sem filtragem, tanto o JWT quanto a chave API seriam divididos em chunks, transformados em embeddings e armazenados no banco de dados. Uma busca por “authentication” retornaria o chunk contendo segredos reais. Pior, se o retriever enviar resultados para uma ferramenta de AI por meio de MCP, os segredos aparecem na janela de contexto da AI e, potencialmente, nos logs da ferramenta.
Filtragem baseada em padrões
O filtro de credenciais roda em cada chunk antes do armazenamento, fazendo correspondência com 25 padrões específicos de fornecedores, além de padrões genéricos:
Padrões específicos de fornecedores:
| Padrão | Exemplo | Regex |
|---|---|---|
| Chave API da OpenAI | sk-... |
sk-[a-zA-Z0-9_-]{20,} |
| Chave API da Anthropic | sk-ant-api03-... |
sk-ant-api\d{2}-[a-zA-Z0-9_-]{20,} |
| PAT do GitHub | ghp_... |
gh[ps]_[a-zA-Z0-9]{36,} |
| AWS Access Key | AKIA... |
AKIA[0-9A-Z]{16} |
| Chave Stripe | sk_live_... |
[sr]k_(live\|test)_[a-zA-Z0-9]{24,} |
| Token Cloudflare | ... |
Vários padrões |
Padrões genéricos:
| Padrão | Detecção |
|---|---|
| JWT tokens | eyJ[a-zA-Z0-9_-]+\.eyJ[a-zA-Z0-9_-]+ |
| Bearer tokens | Bearer\s+[a-zA-Z0-9_\-\.]+ |
| Chaves privadas | -----BEGIN (RSA\|EC\|OPENSSH) PRIVATE KEY----- |
| base64 de alta entropia | Strings com entropia >4,5 bits/caractere, 40+ caracteres |
| Atribuições de senha | password\s*[:=]\s*["'][^"']+["'] |
Implementação do filtro
def clean_content(text):
"""Scrub credentials from text before indexing."""
result = ScanResult(is_clean=True, match_count=0, patterns=[])
for pattern in CREDENTIAL_PATTERNS:
matches = pattern.regex.findall(text)
if matches:
text = pattern.regex.sub(
f"[REDACTED:{pattern.name}]", text
)
result.is_clean = False
result.match_count += len(matches)
result.patterns.append(pattern.name)
return text, result
Principais escolhas de design:
-
Filtrar antes do embedding. O texto limpo é o que recebe o embedding. A representação vetorial nunca codifica padrões de credenciais. Uma consulta por “chave API” retorna notas que discutem gerenciamento de chaves API, não notas que contêm chaves reais.
-
Substituir, não remover. O token
[REDACTED:pattern-name]preserva o contexto semântico do texto ao redor. O embedding captura que “algo parecido com uma credencial estava aqui” sem codificar a credencial em si. -
Registrar padrões, não valores. O filtro registra quais padrões corresponderam (por exemplo, “Scrubbed 2 credential(s) from oauth-debug.md [jwt, bearer-token]”), mas nunca registra o valor da credencial.
Exclusão baseada em caminho
O arquivo .indexignore oferece exclusão granular ampla por caminho. O filtro de credenciais oferece limpeza granular fina dentro dos arquivos indexados. Ambos são necessários:
.indexignorepara pastas inteiras que você sabe que contêm conteúdo sensível (notas de saúde, registros financeiros, documentos de carreira)- Filtro de credenciais para segredos acidentalmente incorporados em conteúdo que, de outra forma, poderia ser indexado
Classificação de dados
Para vaults com conteúdo diverso, considere classificar as notas por sensibilidade:
| Nível | Exemplos | Indexar? | Filtrar? |
|---|---|---|---|
| Público | Rascunhos de blog, notas técnicas | Sim | Sim |
| Interno | Planos de projeto, decisões de arquitetura | Sim | Sim |
| Sensível | Dados salariais, registros de saúde | Não (.indexignore) | N/A |
| Restrito | Credenciais, chaves privadas | Não (.indexignore) | N/A |
Arquitetura do servidor MCP
Os servidores do Model Context Protocol (MCP) expõem o retriever como uma ferramenta que os agentes de IA podem chamar. Esta seção aborda o design do servidor, a superfície de capacidades e os limites de permissão.
Escolha do protocolo: STDIO vs HTTP
O MCP oferece suporte a dois modos de transporte:
STDIO — A ferramenta de IA inicia o servidor MCP como um processo filho e se comunica por stdin/stdout. Este é o modo padrão para ferramentas locais. Claude Code, Codex CLI e Cursor oferecem suporte a servidores MCP via STDIO.
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/path/to/vault",
"DB_PATH": "/path/to/vectors.db"
}
}
}
}
HTTP — O servidor MCP é executado como um serviço HTTP independente. Útil para acesso remoto, configurações com vários clientes ou configurações de equipe em que o vault está em um servidor compartilhado.
{
"mcpServers": {
"obsidian": {
"url": "http://localhost:3333/mcp"
}
}
}
Recomendação: Use STDIO para vaults pessoais. É mais simples, mais seguro (sem exposição à rede), e o ciclo de vida do servidor é gerenciado pela ferramenta de IA. Use HTTP somente quando várias ferramentas ou várias máquinas precisarem de acesso simultâneo ao mesmo vault.
Evolução da especificação MCP. A especificação MCP de junho de 2025 adicionou autorização OAuth 2.1, saídas estruturadas de ferramentas (esquemas de retorno tipados) e elicitação (prompts ao usuário iniciados pelo servidor). A versão de novembro de 2025 trouxe o Streamable HTTP como modo de transporte de primeira classe, descoberta de URL
.well-knownpara navegação automática pelas capacidades do servidor, anotações estruturadas de ferramentas que declaram se uma ferramenta é somente leitura ou mutável, e um sistema de padronização de níveis SDK.79 A próxima revisão agora é concreta: a especificação de 2026-07-28 entrou em Release Candidate em 21 de maio de 2026 — a maior revisão do MCP desde o lançamento. Suas principais mudanças são um núcleo de protocolo sem estado (o handshakeinitializee o cabeçalhoMcp-Session-Idforam removidos, portanto os servidores não rastreiam mais o estado da sessão por conexão), Apps do MCP (os servidores podem retornar HTML renderizado no servidor, exibido em iframes sandboxed do cliente), Tasks deixando o núcleo experimental e se tornando uma extensão oficial (tasks/get,tasks/update,tasks/cancelpara operações de longa duração), autorização OAuth 2.0 / OIDC reforçada e uma política de ciclo de vida de descontinuação de recursos de 12 meses. Ela foi lançada conforme o cronograma como a revisão de 28 de julho de 2026 — agora a especificação atual (verificada em 14 de agosto de 2026).24 Para servidores de vaults pessoais, STDIO continua sendo o caminho mais simples, e o núcleo sem estado torna os servidores STDIO para um único usuário ainda mais enxutos. O transporte Streamable HTTP, a descoberta.well-knowne os Apps do MCP beneficiam principalmente implantações HTTP empresariais com roteamento multilocatário e balanceamento de carga. Acompanhe o roadmap do MCP para atualizações que afetem sua escolha de transporte.
Design de capacidades
O servidor MCP deve expor um conjunto mínimo de ferramentas:
search — A ferramenta principal. Executa a recuperação hybrid e retorna resultados classificados.
{
"name": "obsidian_search",
"description": "Search the Obsidian vault using hybrid BM25 + vector retrieval",
"parameters": {
"query": { "type": "string", "description": "Search query" },
"limit": { "type": "integer", "default": 5 },
"max_tokens": { "type": "integer", "default": 2000 }
}
}
read_note — Lê o conteúdo completo de uma nota específica pelo caminho. Útil quando o agente quer ver o contexto completo de um resultado de busca.
{
"name": "obsidian_read_note",
"description": "Read the full content of a note by file path",
"parameters": {
"file_path": { "type": "string", "description": "Relative path within vault" }
}
}
list_notes — Lista notas que correspondem a um filtro (por pasta, tag, tipo ou intervalo de datas). Útil para exploração quando o agente não tem uma consulta específica.
{
"name": "obsidian_list_notes",
"description": "List notes matching filters",
"parameters": {
"folder": { "type": "string", "description": "Folder path within vault" },
"tag": { "type": "string", "description": "Tag to filter by" },
"limit": { "type": "integer", "default": 20 }
}
}
get_context — Uma ferramenta de conveniência que executa uma busca e formata os resultados como um bloco de contexto adequado para inserção em uma conversa.
{
"name": "obsidian_get_context",
"description": "Get formatted context from vault for a topic",
"parameters": {
"topic": { "type": "string", "description": "Topic to get context for" },
"max_tokens": { "type": "integer", "default": 2000 }
}
}
Limites de permissão
O servidor MCP deve impor limites rigorosos:
-
Somente leitura. O servidor lê o vault e o banco de dados do índice. Ele não cria, modifica nem exclui notas. As operações de escrita (captura de novas notas) são tratadas por hooks ou skills separados, não pelo servidor MCP.
-
Restrito ao vault. O servidor lê apenas arquivos dentro do caminho configurado do vault. Tentativas de path traversal (
../../etc/passwd) devem ser rejeitadas. -
Saída com credenciais filtradas. Mesmo que o banco de dados contenha conteúdo pré-filtrado, aplique filtragem de credenciais na saída como uma medida de defesa em profundidade.
-
Respostas limitadas por tokens. Aplique
max_tokensem todas as respostas das ferramentas para evitar que a ferramenta de IA receba blocos de contexto excessivamente grandes.
Tratamento de erros
As ferramentas do MCP devem retornar mensagens de erro estruturadas que ajudem a ferramenta de IA a se recuperar:
def search(self, query, limit=5, max_tokens=2000):
if not self.db_path.exists():
return {
"error": "Index database not found. Run the indexer first.",
"suggestion": "python index_vault.py --full"
}
results = self.retriever.search(query, limit, max_tokens)
if not results:
return {
"results": [],
"message": f"No results found for '{query}'. Try broader terms."
}
return {
"results": [
{
"file_path": r["file_path"],
"section": r["section"],
"text": r["chunk_text"],
"score": round(r["rrf_score"], 4),
}
for r in results
],
"count": len(results),
"query": query,
}
Integração com Claude Code
Claude Code é o principal consumidor do sistema de recuperação do Obsidian. Esta seção aborda a configuração do MCP, a integração de hooks e o padrão obsidian_bridge.py.
Configuração do MCP
Registre o servidor personalizado com claude mcp add (o escopo de usuário grava em ~/.claude.json; -s project grava um .mcp.json compartilhável — ~/.claude/settings.json não é uma superfície de configuração do MCP):
claude mcp add obsidian -s user \
-e VAULT_PATH=/absolute/path/to/vault \
-e DB_PATH=/absolute/path/to/vectors.db \
-- python /path/to/obsidian_mcp.py
A entrada equivalente em .mcp.json, caso você prefira escrevê-la manualmente:
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/absolute/path/to/vault",
"DB_PATH": "/absolute/path/to/vectors.db"
}
}
}
}
Depois de adicionar a configuração, reinicie o Claude Code. O servidor MCP será iniciado como um processo filho. Verifique se ele está em execução:
> What tools do you have from the obsidian MCP server?
Claude Code deve listar as ferramentas disponíveis (obsidian_search, obsidian_read_note etc.).
Integração de hooks
Hooks estendem o comportamento do Claude Code em pontos definidos do ciclo de vida. Dois hooks são relevantes para a integração com o Obsidian:
Os hooks são registrados nas configurações (~/.claude/settings.json, sob a chave hooks, com um nome de evento e matcher) e recebem um payload JSON no stdin — não há um diretório de hooks que o Claude Code descubra automaticamente, e os detalhes da ferramenta nunca chegam como argumentos $1/$2.
Hook UserPromptSubmit — consulta o vault quando você envia um prompt e injeta contexto relevante (o stdout desse evento é adicionado à conversa):
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [{ "type": "command", "command": "/path/to/obsidian-context.sh" }]
}
]
}
}
#!/bin/bash
# obsidian-context.sh — read the JSON payload from stdin
PROMPT=$(jq -r '.prompt // empty')
[ -z "$PROMPT" ] && exit 0
CONTEXT=$(python /path/to/retriever.py search "$PROMPT" --limit 3 --max-tokens 1500)
if [ -n "$CONTEXT" ]; then
printf 'Relevant vault context:\n%s\n' "$CONTEXT" # stdout -> added as context
fi
Hook PostToolUse — captura saídas significativas de ferramentas de volta para o vault para recuperação futura (registrado com um matcher para que seja acionado apenas para as ferramentas que importam):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|Bash",
"hooks": [{ "type": "command", "command": "/path/to/capture-insight.sh" }]
}
]
}
}
#!/bin/bash
# capture-insight.sh — tool name and response arrive as stdin JSON
PAYLOAD=$(cat)
TOOL_NAME=$(printf '%s' "$PAYLOAD" | jq -r '.tool_name')
OUTPUT=$(printf '%s' "$PAYLOAD" | jq -r '.tool_response // "" | tostring')
if [ ${#OUTPUT} -gt 500 ]; then
python /path/to/capture.py --text "$OUTPUT" --source "claude-code-$TOOL_NAME"
fi
O padrão obsidian_bridge.py
Um módulo bridge fornece uma Python API que hooks e skills podem chamar:
# obsidian_bridge.py
from retriever import HybridRetriever
_retriever = None
def get_retriever():
global _retriever
if _retriever is None:
_retriever = HybridRetriever(
db_path="/path/to/vectors.db",
vault_path="/path/to/vault",
)
return _retriever
def search_vault(query, limit=5, max_tokens=2000):
"""Search vault and return formatted context."""
retriever = get_retriever()
results = retriever.search(query, limit, max_tokens)
if not results:
return ""
lines = ["## Vault Context\n"]
for r in results:
lines.append(f"**{r['file_path']}** — {r['section']}")
lines.append(f"> {r['chunk_text'][:500]}")
lines.append("")
return "\n".join(lines)
A skill /capture
Uma skill do Claude Code para capturar insights de volta no vault:
/capture "OAuth token rotation requires both access and refresh token invalidation"
--domain security
--tags oauth,tokens
A skill cria uma nova nota em 00-inbox/ com o frontmatter correto e aciona uma reindexação incremental para que a nova nota possa ser pesquisada imediatamente.
Padrões de comandos personalizados
As skills do Claude Code podem encapsular operações do vault em comandos nomeados. Profissionais criaram bibliotecas de comandos específicos para Obsidian que tratam o vault tanto como fonte de leitura quanto como destino de escrita.
Varredura de sinais. Um comando /scan-intel consulta fontes externas, pontua descobertas em relação a interesses pessoais de pesquisa e grava sinais qualificados como notas no vault com frontmatter:
/scan-intel --topics "agent infrastructure, security" --lookback 7d
O comando busca informações em fontes configuradas (arXiv, HN, RSS), aplica um modelo de pontuação (relevância, capacidade de gerar ação, profundidade, autoridade) e grava os sinais aprovados em pastas do vault específicas por tópico. O vault se torna o consumidor downstream de um pipeline automatizado de inteligência.
Diário de bordo. Um comando /captains-log agrega a atividade diária do git em todos os repositórios, grava uma entrada estruturada de diário no vault e inclui decisões tomadas, percepções e tópicos em aberto:
/captains-log
O comando coleta o histórico de commits do GitHub, agrupa por repositório e formata como uma entrada narrativa de diário. Com o tempo, os registros diários criam um histórico pesquisável do que foi entregue e por quê.
Captura no Obsidian. Um comando /obsidian-capture recebe um insight da sessão atual do Claude Code e o grava diretamente no vault com os metadados corretos:
/obsidian-capture "SAST gates in agent loops increase security degradation"
--folder AI-Tools --tags security,agents
O padrão se estende a qualquer operação no vault: criar MOCs, atualizar notas de status de projetos, vincular sinais relacionados ou gerar resumos semanais a partir de registros diários acumulados.
Exemplos da comunidade. Profissionais estão publicando suas bibliotecas de comandos. Um desenvolvedor compartilhou 22 comandos personalizados para Obsidian + Claude Code que abrangem revisões diárias, planejamento de projetos, captura de pesquisas e fluxos de trabalho de conteúdo.1 Outro criou uma skill “Visual Explainer” que gera notas com diagramas no vault a partir da análise de código.2 Os comandos variam, mas a arquitetura é consistente: skills do Claude Code como interface, notas do vault como camada de armazenamento e infraestrutura de recuperação como mecanismo de consulta.
Gerenciamento da janela de contexto
A integração deve considerar a janela de contexto do Claude Code:
- Limite o contexto injetado a 1.500-2.000 tokens por consulta. Mais do que isso compete com a memória de trabalho do agente.
- Inclua atribuição da fonte. Sempre inclua o caminho do arquivo e o título da seção para que o agente possa consultar a fonte.
- Trunque o texto dos chunks. Chunks longos devem ser truncados com
..., em vez de omitidos por completo. Os primeiros 300-500 caracteres normalmente contêm as informações principais. - Não injete em todos os prompts. A injeção é executada por
UserPromptSubmit(o evento cujo stdout chega ao modelo), portanto, gerencie o orçamento nela: pule prompts conversacionais curtos, injete apenas quando o prompt mencionar código, arquivos ou decisões anteriores e limite o bloco injetado. Eventos restritos a ferramentas, como PreToolUse, podem bloquear ou registrar, mas o stdout deles nunca chega ao modelo.
Integração do Codex CLI
O Codex CLI se conecta a servidores MCP por meio de config.toml. O padrão de integração difere do Claude Code na sintaxe de configuração e na entrega de instruções.
Configuração do MCP
Adicione a ~/.codex/config.toml (o Codex lê $CODEX_HOME/config.toml; instruções no nível do projeto pertencem a AGENTS.md, não a um arquivo de configuração do projeto):
[mcp_servers.obsidian]
command = "python"
args = ["/path/to/obsidian_mcp.py"]
[mcp_servers.obsidian.env]
VAULT_PATH = "/absolute/path/to/vault"
DB_PATH = "/absolute/path/to/vectors.db"
Padrões de AGENTS.md
O Codex CLI lê AGENTS.md para instruções no nível do projeto. Inclua orientações para pesquisar o vault:
## Available Tools
### Obsidian Vault (MCP: obsidian)
Use the `obsidian_search` tool to find relevant context from the knowledge base.
Search the vault when you need:
- Background on a concept or pattern
- Prior decisions or rationale
- Reference material for implementation
Example queries:
- "authentication patterns in FastAPI"
- "how does the review aggregator work"
- "sqlite-vec configuration"
Diferenças em relação ao Claude Code
| Recurso | Claude Code | Codex CLI |
|---|---|---|
| Configuração do MCP | claude mcp add → ~/.claude.json / .mcp.json do projeto |
~/.codex/config.toml |
| Hooks | Registrados nas configurações, 31 eventos de ciclo de vida, JSON no stdin | Compatível (superfície estável; seu próprio conjunto de eventos) |
| Skills | ~/.claude/skills/ |
~/.codex/skills/ (estável) |
| Arquivo de instruções | CLAUDE.md |
AGENTS.md |
| Superfície de permissões | Modos: Manual / acceptEdits / auto (padrão no Pro/Max/Team desde 14 de agosto de 2026) / plan / bypassPermissions | Política de aprovação untrusted / on-request / never × sandbox read-only / workspace-write / danger-full-access (--full-auto removido na v0.147.0) |
Diferença principal: ambas as ferramentas agora oferecem suporte a hooks e skills; o que difere é o formato. O Codex combina uma política de aprovação com um modo de sandbox no nível do sistema operacional, em vez dos modos de permissão do Claude Code, e seus eventos de hook são diferentes — adapte o padrão (consulte o vault antes de trabalhar, capture depois), não a configuração. AGENTS.md continua sendo o lugar certo para instruções persistentes de pesquisar-primeiro-no-vault no Codex.
Cursor e outras ferramentas
Cursor e outras ferramentas de IA compatíveis com MCP podem se conectar ao mesmo servidor MCP do Obsidian. Esta seção aborda a configuração de ferramentas comuns.
Cursor
Adicione a .cursor/mcp.json na raiz do seu projeto:
{
"mcpServers": {
"obsidian": {
"command": "python",
"args": ["/path/to/obsidian_mcp.py"],
"env": {
"VAULT_PATH": "/absolute/path/to/vault",
"DB_PATH": "/absolute/path/to/vectors.db"
}
}
}
}
O arquivo .cursorrules do Cursor pode incluir instruções para usar o vault:
When working on implementation tasks, search the Obsidian vault
for relevant context before writing code. Use the obsidian_search
tool with descriptive queries about the concept you're implementing.
Matriz de compatibilidade
| Ferramenta | Suporte a MCP | Transporte | Local da configuração |
|---|---|---|---|
| Claude Code | Completo | STDIO | claude mcp add → ~/.claude.json / .mcp.json do projeto |
| Codex CLI | Completo | STDIO | ~/.codex/config.toml |
| Cursor | Completo | STDIO | .cursor/mcp.json |
| Windsurf | Completo | STDIO | ~/.codeium/windsurf/mcp_config.json |
| Continue.dev | Completo | STDIO + HTTP | ~/.continue/config.yaml (mcpServers) |
| Zed | Completo (servidores de contexto) | STDIO | settings.json (context_servers) |
| Claudian (plugin do Obsidian) | N/D (incorporado) | Claude Code CLI | Configurações do plugin do Obsidian |
| Agent Client (plugin do Obsidian) | N/D (incorporado) | ACP | Configurações do plugin do Obsidian |
Alternativa para ferramentas sem MCP
Para ferramentas que não oferecem suporte a MCP, o recuperador pode ser encapsulado como um CLI:
# Search from command line
python retriever_cli.py search "query text" --limit 5
# Output formatted for copy-paste into any tool
python retriever_cli.py context "query text" --format markdown
O CLI produz texto estruturado que pode ser colado manualmente na entrada de qualquer ferramenta de IA. Isso é menos elegante do que a integração com MCP, mas funciona universalmente.
Cache de prompts a partir de notas estruturadas
Notas estruturadas no vault podem servir como blocos de contexto reutilizáveis que reduzem o uso de tokens nas interações com IA. Esta seção aborda o design de chaves de cache e o gerenciamento do orçamento de tokens.
O padrão
Em vez de buscar contexto em cada interação, crie antecipadamente blocos de contexto a partir de notas bem estruturadas do vault e armazene-os em cache:
# cache_keys.py
CONTEXT_BLOCKS = {
"auth-patterns": {
"vault_query": "authentication patterns implementation",
"max_tokens": 1500,
"ttl_hours": 24, # Rebuild daily
},
"api-conventions": {
"vault_query": "API design conventions REST patterns",
"max_tokens": 1000,
"ttl_hours": 168, # Rebuild weekly
},
"project-architecture": {
"vault_query": "current project architecture decisions",
"max_tokens": 2000,
"ttl_hours": 12, # Rebuild twice daily
},
}
Invalidação do cache
A invalidação do cache se baseia em dois sinais:
- Expiração do TTL. Cada bloco de contexto tem um tempo de vida. Quando o TTL expira, o bloco é reconstruído consultando novamente o vault.
- Detecção de mudanças no vault. Quando o indexador detecta mudanças em arquivos que contribuíram para um bloco de contexto armazenado em cache, o bloco é invalidado imediatamente.
Gerenciamento do orçamento de tokens
Uma sessão começa com um orçamento total de contexto. Os blocos em cache consomem parte desse orçamento:
Total context budget: 8,000 tokens
├─ System prompt: 1,500 tokens
├─ Cached blocks: 3,000 tokens (pre-loaded)
├─ Dynamic search: 2,000 tokens (on-demand)
└─ Conversation: 1,500 tokens (remaining)
Os blocos em cache são carregados no início da sessão. Os resultados de buscas dinâmicas preenchem o orçamento restante por consulta. Essa abordagem híbrida oferece ao agente uma base de contexto frequentemente necessária, preservando o orçamento para consultas específicas.
Uso de tokens antes/depois
Sem cache: Cada consulta relevante aciona uma busca no vault, retornando 1.500-2.000 tokens de contexto. Em 10 consultas em uma sessão, o agente consome 15.000-20.000 tokens de contexto do vault.
Com cache: Três blocos de contexto pré-criados consomem 4.500 tokens no total. Buscas adicionais acrescentam 1.500-2.000 tokens por consulta única. Em 10 consultas, das quais 6 são atendidas por blocos em cache, o agente consome 4.500 + (4 * 1.500) = 10.500 tokens — aproximadamente metade do uso sem cache.
Captura de resumos comprimidos de saídas detalhadas
As saídas de ferramentas podem ser detalhadas: stack traces, listagens de arquivos e resultados de testes. Um hook não consegue reduzir o que o modelo vê — quando PostToolUse é acionado, a saída completa já está na janela de contexto, e nada que um hook imprima a substitui. O que um hook pode fazer é gravar um resumo comprimido no vault, para que sessões futuras recuperem o veredito em duas linhas em vez de executar novamente ou reler o original de 5.000 tokens. Trate isso como um padrão de captura para memória entre sessões, não como uma forma de economizar contexto durante a sessão (nela, os recursos reais são /compact, prompts com escopo definido e solicitar saídas menos detalhadas).
O problema
Uma chamada à ferramenta Bash que executa testes pode retornar:
PASSED tests/test_auth.py::test_login_success
PASSED tests/test_auth.py::test_login_failure
PASSED tests/test_auth.py::test_token_refresh
PASSED tests/test_auth.py::test_session_expiry
... (200 more lines)
FAILED tests/test_api.py::test_rate_limit_exceeded
A saída completa tem 5.000 tokens, mas o sinal está em 2 linhas: 200 aprovados, 1 com falha.
Implementação do hook
Registrado em PostToolUse com um matcher Bash (registrado nas configurações, JSON via stdin — consulte Integração de hooks acima):
#!/bin/bash
# summarize-and-capture.sh — write a compressed summary to the vault
PAYLOAD=$(cat)
OUTPUT=$(printf '%s' "$PAYLOAD" | jq -r '.tool_response // "" | tostring')
# Only summarize large outputs
[ ${#OUTPUT} -lt 2000 ] && exit 0
if printf '%s' "$OUTPUT" | grep -q "PASSED\|FAILED"; then
PASSED=$(printf '%s' "$OUTPUT" | grep -c "PASSED")
FAILED=$(printf '%s' "$OUTPUT" | grep -c "FAILED")
SUMMARY="Tests: $PASSED passed, $FAILED failed"
[ "$FAILED" -gt 0 ] && SUMMARY="$SUMMARY
$(printf '%s' "$OUTPUT" | grep 'FAILED')"
python /path/to/capture.py --text "$SUMMARY" --source "test-run-summary"
fi
exit 0
Cada invocação do hook é um processo novo, portanto não é necessária uma proteção contra recursão — as próprias gravações de um hook não o acionam novamente, e variáveis exportadas nunca sobrevivem até a próxima invocação.
Heurísticas de compressão
| Tipo de saída | Detecção | Estratégia de compressão |
|---|---|---|
| Resultados de testes | Palavras-chave PASSED / FAILED |
Conta aprovações/falhas, mostra apenas as falhas |
| Listagens de arquivos | ls ou find no comando |
Trunca para as primeiras 20 entradas + contagem |
| Stack traces | Palavra-chave Traceback |
Mantém o primeiro e o último frame + mensagem de erro |
| Status do Git | modified: / new file: |
Resume contagens por status |
| Saída de build | warning: / error: |
Remove linhas informativas, mantém avisos/erros |
Pipeline de entrada e triagem de sinais
A camada de entrada determina o que entra no vault. Sem curadoria, o vault acumula ruído. Esta seção aborda o pipeline de pontuação que direciona sinais para pastas de domínio.
Fontes
Os sinais vêm de vários canais:
- Feeds RSS: Blogs técnicos, avisos de segurança, notas de lançamento
- Favoritos via Web Clipper: A extensão oficial Obsidian Web Clipper (Chrome, Firefox, Safari) é o caminho de entrada com maior fidelidade para captura no navegador. O ciclo de lançamentos de abril de 2026 a tornou significativamente mais útil para fluxos de trabalho com IA:22
- 1.4.0 (9 de abr.): Interface interativa de transcrições do YouTube — fixe o vídeo, navegue pela transcrição, role automaticamente e destaque a posição atual. Além de um padrão “Open in Reader” que envia uma captura com um clique diretamente para o modo Reader.
- 1.5.0–1.5.1 (15 de abr.): Visualizador de destaques — navegue e pesquise destaques capturados em todo o vault. Transição de entrada gradual para o Reader. Reprodução/pausa do YouTube mais fluida. A versão 1.5.1 corrigiu uma regressão na compilação do webpack.
- 1.6.0–1.6.2 (21–23 de abr.): Reformulação da UX do marcador de texto com suporte para dispositivos móveis. Defuddle 0.18 adiciona extratores específicos para LinkedIn, Threads, Bluesky, Discourse e Medium. A versão 1.6.2 corrige uma regressão da área de transferência no modo incorporado do Safari. Configure templates por domínio de origem para que transcrições do YouTube, READMEs de GitHub e artigos longos cheguem cada um a uma nota com nome apropriado e o frontmatter correto para o pipeline de pontuação abaixo.
- Newsletters: Trechos importantes de newsletters por e-mail
- Captura manual: Notas escritas durante leituras, conversas ou pesquisas
- Saída de ferramentas: Saídas relevantes de ferramentas de IA capturadas por meio de hooks
- Extensão de Compartilhamento do iOS: O app iOS do Obsidian (atualizado no início de 2026) inclui uma Extensão de Compartilhamento que salva conteúdo do Safari, redes sociais e outros apps diretamente no vault sem abrir o Obsidian; a linha 1.13 adiciona destinos configuráveis na Folha de Compartilhamento com variáveis de template — incluindo
url, para que uma página capturada registre automaticamente seu link de origem no frontmatter.19 Isso cria um caminho de entrada móvel sem atrito — compartilhe um artigo pelo Safari e ele chega como uma nota no vault pronta para ser pontuada. - Obsidian CLI: Scripts de shell e hooks podem criar notas via
obsidian file createou acrescentar conteúdo a notas existentes viaobsidian file append, permitindo pipelines automatizados de entrada no desktop.
Dimensões de pontuação
Cada sinal recebe uma pontuação em quatro dimensões (de 0,0 a 1,0 cada):
| Dimensão | Pergunta | Pontuação baixa (0,0-0,3) | Pontuação alta (0,7-1,0) |
|---|---|---|---|
| Relevância | Isso se relaciona aos meus domínios ativos? | Tangencial, fora do escopo | Diretamente relevante para o trabalho ativo |
| Aplicabilidade | Posso usar esta informação? | Teoria pura, sem aplicação | Técnica ou padrão específico que posso aplicar |
| Profundidade | Quão substancial é o conteúdo? | Manchetes, resumo superficial | Análise detalhada com exemplos |
| Autoridade | Quão confiável é a fonte? | Blog anônimo, não verificado | Fonte primária, revisada por pares, especialista reconhecido |
Pontuação composta e direcionamento
composite = (relevance * 0.35) + (actionability * 0.25) +
(depth * 0.25) + (authority * 0.15)
| Faixa de pontuação | Ação |
|---|---|
| 0.55+ | Direcionar automaticamente para a pasta de domínio |
| 0.40 - 0.55 | Colocar na fila para revisão manual |
| < 0.40 | Descartar (não armazenar) |
Direcionamento por domínio
Sinais com pontuação acima de 0.55 são direcionados a uma de 12 pastas de domínio com base em correspondência de palavras-chave e classificação de tópicos:
05-signals/
├── ai-tooling/ # Claude, LLMs, AI development tools
├── security/ # Vulnerabilities, auth, cryptography
├── systems/ # Architecture, distributed systems
├── programming/ # Languages, patterns, algorithms
├── web/ # Frontend, backends, APIs
├── data/ # Databases, data engineering
├── devops/ # CI/CD, containers, infrastructure
├── design/ # UI/UX, product design
├── mobile/ # iOS, Android, cross-platform
├── career/ # Industry trends, hiring, growth
├── research/ # Academic papers, whitepapers
└── other/ # Signals that don't fit a domain
Estatísticas de produção
Ao longo de 14 meses de operação:
| Métrica | Valor |
|---|---|
| Total de sinais processados | 7,771 |
| Direcionados automaticamente (>0.55) | 4,832 (62%) |
| Na fila para revisão (0.40-0.55) | 1,543 (20%) |
| Descartados (<0.40) | 1,396 (18%) |
| Pastas de domínio ativas | 12 |
| Média de sinais por dia | ~18 |
Padrões de grafo de conhecimento
O grafo de wiki-links do Obsidian codifica relações entre notas. Esta seção aborda a semântica dos links, o percurso do grafo para expansão de contexto e antipadrões que degradam a qualidade do grafo.
Semântica de backlinks
Cada wiki-link cria uma aresta direcionada no grafo. O Obsidian rastreia links diretos e backlinks:
- Link direto: A nota A contém
[[Note B]]→ A cria um link para B - Backlink: A nota B mostra que a nota A faz referência a ela
O grafo codifica diferentes tipos de relações, dependendo do contexto:
| Padrão de link | Semântica | Exemplo |
|---|---|---|
| Link embutido | “Está relacionado a” | “Veja [[OAuth Token Rotation]] para mais detalhes” |
| Link de cabeçalho | “Tem subtópico” | ”## Related\n- [[Token Rotation]]\n- [[Session Management]]” |
| Link semelhante a tag | “É categorizado como” | ”[[type/reference]]” |
| Link de MOC | “Faz parte de” | Uma nota Map of Content que lista notas relacionadas |
Maps of Content (MOCs)
MOCs são notas de índice que organizam notas relacionadas em uma estrutura navegável:
---
title: "Authentication & Security MOC"
type: moc
domain: security
---
## Core Concepts
- [[OAuth 2.0 Overview]]
- [[JWT Token Anatomy]]
- [[Session Management Patterns]]
## Implementation Patterns
- [[OAuth Token Rotation]]
- [[Refresh Token Security]]
- [[PKCE Flow Implementation]]
## Failure Modes
- [[Token Expiry Handling]]
- [[Session Fixation Prevention]]
- [[CSRF Defense Strategies]]
Os MOCs beneficiam a recuperação de duas formas:
- Correspondência direta. Uma busca por “authentication overview” encontra o próprio MOC, fornecendo ao agente uma lista curada de notas relacionadas.
- Expansão de contexto. Depois de encontrar uma nota específica, o recuperador pode verificar se a nota aparece em algum MOC e incluir a estrutura do MOC nos resultados, oferecendo ao agente um mapa do tópico mais amplo.
Percurso do grafo para expansão de contexto
Uma melhoria futura para o recuperador: depois de encontrar os principais resultados, expanda o contexto seguindo links:
def expand_context(results, depth=1):
"""Follow wiki-links from top results to find related context."""
expanded = set()
for result in results:
# Parse wiki-links from chunk text
links = extract_wiki_links(result["chunk_text"])
for link_target in links:
# Resolve link to file path
target_path = resolve_wiki_link(link_target)
if target_path and target_path not in expanded:
expanded.add(target_path)
# Include target's most relevant chunk
target_chunks = get_chunks_for_file(target_path)
# ... rank and include best chunk
return results + list(expanded_results)
Isso não está implementado no recuperador atual, mas representa uma extensão natural da estrutura do grafo.
Antipadrões
Clusters órfãos. Grupos de notas que se vinculam entre si, mas não têm conexões com o restante do vault. O painel de grafo no Obsidian torna esses grupos visíveis como ilhas desconectadas. Clusters órfãos indicam MOCs ausentes ou links entre domínios ausentes.
Proliferação de tags. Usar tags de forma inconsistente ou criar tags detalhadas demais. Um vault com 500 tags únicas em 5.000 notas tem, em média, 1 nota a cada 10 tags — as tags não são úteis para filtragem. Consolide em 20 a 50 tags de alto nível que correspondam às suas pastas de domínio.
Notas com muitos links e pouco conteúdo. Notas compostas inteiramente de wiki-links, sem prosa. Essas notas são mal indexadas porque o chunker não tem texto para transformar em embeddings. Adicione pelo menos um parágrafo de contexto explicando por que as notas vinculadas estão relacionadas.
Links bidirecionais para tudo. Nem toda referência precisa ser um wiki-link. Mencionar “OAuth” de passagem não exige [[OAuth 2.0 Overview]]. Reserve wiki-links para relações intencionais e navegáveis, nas quais clicar no link forneceria um contexto útil.
Receitas de fluxo de trabalho para desenvolvedores
Fluxos de trabalho práticos que combinam recuperação do vault com tarefas diárias de desenvolvimento.
Carregamento de contexto pela manhã
Comece o dia carregando o contexto relevante:
Search my vault for notes about [current project] updated in the last week
O retriever retorna notas recentes sobre seu projeto ativo, oferecendo uma rápida recapitulação de onde você parou. Mais eficaz do que reler as mensagens de commit de ontem.
Captura de pesquisa durante o código
Ao implementar um recurso, capture insights sem sair do editor:
/capture "FastAPI dependency injection with async generators requires yield,
not return. The generator is the dependency lifecycle."
--domain programming
--tags fastapi,dependency-injection
O insight capturado é indexado imediatamente e fica disponível para recuperação futura. Ao longo dos meses, essas microcapturas criam um corpus de conhecimento específico de implementação.
Início de projeto
Ao começar um novo projeto ou recurso:
- Pesquise no vault: “O que eu sei sobre [tecnologia/padrão]?”
- Revise os 5 principais resultados em busca de decisões anteriores e gotchas
- Verifique se existe um MOC para o domínio; se não existir, crie um
- Pesquise modos de falha: “problemas com [tecnologia]”
Debugging com pesquisa no vault
Ao encontrar um erro ou comportamento inesperado:
Search my vault for [error message or symptom]
Notas anteriores de debugging muitas vezes contêm a causa raiz e a correção. Isso é especialmente valioso para problemas recorrentes entre projetos — o vault lembra o que você esquece.
Preparação para code review
Antes de revisar um PR:
Search my vault for patterns and conventions about [module being changed]
O vault retorna decisões anteriores, restrições arquiteturais e padrões de código relevantes para o código em revisão. A revisão é informada por conhecimento institucional, não apenas pelo diff.
Ajuste de performance
Esta seção cobre estratégias de otimização para diferentes tamanhos de vault e padrões de uso.
Gerenciamento do tamanho do índice
| Tamanho do vault | Chunks | Tamanho do DB | Reindexação completa | Incremental |
|---|---|---|---|---|
| 500 notas | ~1.500 | 3 MB | 15 segundos | <1 segundo |
| 2.000 notas | ~6.000 | 12 MB | 45 segundos | 2 segundos |
| 5.000 notas | ~15.000 | 30 MB | 2 minutos | 4 segundos |
| 15.000 notas | ~50.000 | 83 MB | 4 minutos | <10 segundos |
| 50.000 notas | ~150.000 | 250 MB | 15 minutos | 30 segundos |
Com 50.000+ notas, considere: - Aumentar o tamanho do lote de 64 para 128 para gerar embeddings mais rápido - Usar o modo WAL (padrão) para acesso concorrente - Executar a reindexação completa fora dos horários de pico
Otimização de consulta
Modo WAL. O modo Write-Ahead Logging do SQLite permite leituras concorrentes enquanto o indexador escreve:
db.execute("PRAGMA journal_mode=WAL")
Isso é essencial quando o servidor MCP lida com consultas enquanto o indexador executa uma atualização incremental.
Pooling de conexões. O servidor MCP deve reutilizar conexões com o banco de dados em vez de abrir uma nova conexão por consulta. Uma única conexão de longa duração com modo WAL oferece suporte a leituras concorrentes.
# MCP server initialization
db = sqlite3.connect(DB_PATH, check_same_thread=False)
db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA mmap_size=268435456") # 256 MB mmap
I/O mapeado em memória. O pragma mmap_size informa ao SQLite para usar I/O mapeado em memória para o arquivo de banco de dados. Para um banco de dados de 83 MB, mapear o arquivo inteiro na memória elimina a maioria das leituras em disco.
Otimização de FTS5. Após uma reindexação completa, execute:
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');
Isso mescla os segmentos internos de b-tree do FTS5, reduzindo a latência de consulta para pesquisas posteriores.
Benchmarks de escala
Medido em Apple M3 Pro, 36 GB de RAM, SSD NVMe:
| Operação | 500 notas | 5K notas | 15K notas | 50K notas |
|---|---|---|---|---|
| Consulta BM25 | 2ms | 5ms | 12ms | 25ms |
| Consulta vetorial | 1ms | 3ms | 8ms | 20ms |
| Fusão RRF | <1ms | <1ms | 3ms | 5ms |
| Pesquisa completa | 3ms | 8ms | 23ms | 50ms |
Todos os benchmarks incluem acesso ao banco de dados, execução da consulta e formatação dos resultados. A latência de rede para comunicação MCP STDIO adiciona 1-2ms.
Solução de problemas
Desvio do índice
Sintoma: A pesquisa retorna resultados desatualizados ou não encontra notas adicionadas recentemente.
Causa: O indexador incremental não foi executado após adicionar notas, ou o mtime de um arquivo não foi atualizado (por exemplo, sincronizado de outra máquina com timestamps preservados).
Correção: Execute uma reindexação completa: python index_vault.py --full
Troca do modelo de embeddings
Sintoma: Depois de alterar o modelo de embeddings, a pesquisa vetorial retorna resultados sem sentido.
Causa: Vetores antigos (do modelo anterior) estão sendo comparados com novos vetores de consulta. As dimensões ou a semântica do espaço vetorial são incompatíveis.
Correção: O indexador deve detectar a incompatibilidade de hash do modelo e acionar automaticamente uma reindexação completa. Se isso não acontecer, limpe manualmente o banco de dados e reindexe:
rm vectors.db
python index_vault.py --full
Manutenção do FTS5
Sintoma: Consultas FTS5 retornam resultados incorretos ou incompletos após muitas atualizações incrementais.
Causa: Segmentos internos do FTS5 podem ficar fragmentados depois de muitas atualizações pequenas.
Correção: Reconstrua e otimize:
INSERT INTO chunks_fts(chunks_fts) VALUES('rebuild');
INSERT INTO chunks_fts(chunks_fts) VALUES('optimize');
Timeout do MCP
Sintoma: A ferramenta de AI informa que o servidor MCP atingiu timeout.
Causa: A primeira consulta aciona o carregamento do modelo (inicialização preguiçosa), que leva 2-5 segundos. O timeout padrão de MCP da ferramenta de AI pode ser menor.
Correção: Faça o pré-aquecimento do modelo na inicialização do servidor:
# In MCP server initialization
retriever = HybridRetriever(db_path, vault_path)
retriever.search("warmup", limit=1) # Trigger model load
Locks de arquivo do SQLite
Sintoma: Erros SQLITE_BUSY ou SQLITE_LOCKED.
Causa: Vários processos escrevendo no banco de dados ao mesmo tempo. O modo WAL permite leituras concorrentes, mas apenas um escritor.
Correção: Garanta que apenas um processo (o indexador) escreva no banco de dados. O servidor MCP e os hooks devem apenas ler. Se você precisar de escritas concorrentes, use o modo WAL e defina um timeout de ocupado:
db.execute("PRAGMA busy_timeout=5000") # Wait up to 5 seconds
sqlite-vec não carrega
Sintoma: A pesquisa vetorial está desativada; o retriever roda em modo somente BM25.
Causa: A extensão sqlite-vec não está instalada, não foi encontrada no caminho da biblioteca ou é incompatível com a versão do SQLite.
Correção:
# Install via pip
pip install sqlite-vec
# Or compile from source
git clone https://github.com/asg017/sqlite-vec
cd sqlite-vec && make
Verifique se a extensão carrega:
import sqlite3
db = sqlite3.connect(":memory:")
db.enable_load_extension(True)
db.load_extension("vec0")
print("sqlite-vec loaded successfully")
Problemas de memória em vault grande
Sintoma: Erros de falta de memória durante a reindexação completa de um vault grande (50.000+ notas).
Causa: O tamanho do lote de embeddings é grande demais, ou todo o conteúdo dos arquivos está sendo carregado na memória simultaneamente.
Correção: Reduza o tamanho do lote e processe os arquivos incrementalmente:
BATCH_SIZE = 32 # Reduce from 64
Também garanta que o indexador processe os arquivos um de cada vez (lendo, fazendo chunking e gerando embeddings de cada arquivo antes de passar para o próximo), em vez de carregar todos os arquivos na memória.
Guia de migração
Do Apple Notes
- Exporte o Apple Notes usando a opção “Export All” (macOS) ou use uma ferramenta de migração como
apple-notes-liberator - Converta as exportações HTML para markdown usando
markdownifyoupandoc - Mova os arquivos convertidos para a pasta
00-inbox/do seu vault - Revise e adicione frontmatter a cada nota
- Mova as notas para as pastas de domínio apropriadas
Do Notion
- Exporte do Notion: Settings → Export → Markdown & CSV
- Descompacte a exportação na pasta
00-inbox/do seu vault - Corrija artefatos de markdown específicos do Notion:
- O Notion usa
- [ ]para checklists — isso é markdown padrão - O Notion inclui tabelas de propriedades como HTML — converta para frontmatter YAML
- O Notion incorpora imagens como caminhos relativos — copie as imagens para sua pasta de anexos
- Adicione frontmatter padrão (
type,domain,tags) - Substitua links de páginas do Notion por wiki-links do Obsidian
Do Google Docs
- Use o Google Takeout para exportar todos os documentos
- Converta arquivos
.docxpara markdown:pandoc -f docx -t markdown input.docx -o output.md - Converta em lote:
for f in *.docx; do pandoc -f docx -t markdown "$f" -o "${f%.docx}.md"; done - Mova para o vault, adicione frontmatter e organize em pastas
De markdown puro (sem Obsidian)
Se você já tem um diretório de arquivos markdown:
- Abra o diretório como um vault do Obsidian (Obsidian → Open Vault → Open folder)
- Adicione
.obsidian/ao.gitignorese o diretório tiver controle de versão - Crie templates de frontmatter e aplique aos arquivos existentes
- Comece a conectar notas com
[[wiki-links]]conforme você lê e organiza - Execute o indexador imediatamente — o sistema de recuperação funciona desde o primeiro dia
De outro sistema de recuperação
Se você está migrando de um sistema diferente de embeddings/pesquisa:
- Não tente migrar vetores. Modelos diferentes produzem espaços vetoriais incompatíveis. Execute uma reindexação completa com o novo modelo.
- Migre o conteúdo, não o índice. Os arquivos do vault são a fonte da verdade. O índice é um artefato derivado.
- Verifique após a migração. Execute 10-20 consultas cujas respostas você já conhece e confira se os resultados correspondem às suas expectativas.
Registro de alterações
| Data | Alteração | Fonte |
|---|---|---|
| 2026-08-14 | Primeira auditoria holística de gate — leitura do avaliador do guia completo; R1 marcou 8,29 com três achados CRITICAL e cinco MAJOR, todos corrigidos nesta linha. Os CRITICALs prejudicavam o leitor: o início rápido instalava o npm obsidian-mcp-server como “a opção baseada em arquivos mais simples” — esse pacote é o servidor baseado em REST-API da cyanheads (precisa do plugin Local REST API + OBSIDIAN_API_KEY; sem flag --vault), enquanto o servidor baseado em arquivos é o npm obsidian-mcp (StevenStavrakis) — a tabela de servidores trazia a mesma colisão de nomes e ambos foram corrigidos com nomes npm explícitos; ambos os blocos de configuração de Claude Code MCP ensinavam mcpServers em ~/.claude/settings.json, que o Claude Code ignora silenciosamente — reescritos para claude mcp add (escopo de usuário → ~/.claude.json) com uma variante de escopo de projeto em .mcp.json, e a célula da matriz de compatibilidade corrigida; os exemplos de hook usavam argumentos posicionais $1/$2 e um diretório de descoberta automática ~/.claude/hooks/pre-tool-use/ — uma interface que o Claude Code nunca teve — reescritos como hooks registrados nas configurações lendo stdin JSON via jq (a injeção de contexto foi movida para UserPromptSubmit, cuja saída stdout é realmente adicionada ao contexto), e a premissa da seção “PostToolUse context compression” (um hook reduzindo o que o modelo vê) é impossível — reformulada como capturar um resumo comprimido no vault para reutilização entre sessões, com a proteção de recursão desnecessária removida (cada invocação de hook é um processo novo). MAJORs: 1.13.4 → 1.13.7 (verificado no manifesto, versões estável e beta convergiram); a nota de especificação de MCP de 2026-07-28 ainda dizia “a especificação final chega em 28 de julho” dezessete dias após ela ter chegado como revisão Current (passada para o passado; 9 reescrita como histórica, apontando para 24); a comparação com Codex ensinava os modos de aprovação removidos suggest/auto-edit/full-auto e “hooks/skills não são suportados” — ambas são superfícies estáveis do Codex desde meados de 2026, tabela e parágrafo reconstruídos (a célula de CC agora nomeia os modos de permissão reais, incluindo o padrão automático de 14 de agosto); linhas da matriz de Zed/Continue/Windsurf atualizadas. Menores: a variante de projeto .codex/config.toml removida (somente $CODEX_HOME), mcpvault 0.12.4 → 0.15.0, âncoras expiradas de “em” tornadas não relativas, e a prometida incorporação da variável url da Folha de Compartilhamento do iOS 1.13 chegou à seção de intake. A verificação R2 confirmou os reparos, mas encontrou resíduos em suas bordas, corrigidos em uma segunda passada: os blocos de Codex/Cursor do início rápido ainda invocavam o binário em colisão (agora npx -y obsidian-mcp@2 serve nas três ferramentas, correspondendo à sintaxe v2 do pacote instalado), uma frase sobre PreToolUse-injeta-contexto sobreviveu abaixo da seção de hooks reescrita (as orientações de injeção agora passam consistentemente por UserPromptSubmit), e quatro linhas curtas (parêntese sem fechamento, referência obsoleta a 1.13.4, a versão de 13, a frase restante de roadmap de 9). |
24 26 |
| 2026-08-07 | Obsidian 1.13 chegou ao canal público: 1.13.4 promovida em 30 de julho de 2026 (verificado no manifesto: desktop-releases.json latestVersion 1.13.4, beta.latestVersion 1.13.6). As três referências no corpo a “o canal público permanece em 1.12.7” foram atualizadas. O que a linha 1.13 entrega, agora que está amplamente disponível: uma reformulação das configurações (janela separada, busca por nome/descrição, navegação por teclado + Vim), um visualizador de imagens em tela cheia com navegação por arquivo e controles de redimensionamento no Live Preview, Bookmarks pesquisáveis, multisseleção no Sync e — o mais relevante para o público deste guia — segurança de URI do Obsidian: ações de obsidian:// agora exigem uma caixa de diálogo de confirmação, a menos que estejam na lista de permissões. A automação deste guia passa por MCP e pelo CLI, que não são afetados, mas qualquer fluxo que controle o Obsidian via URIs (Shortcuts, scripts, outros iniciadores) agora precisa adicionar suas ações à lista de permissões uma vez, ou solicitará confirmação sempre. Para desenvolvedores: um novo API de Configurações com guia de migração, uma alteração incompatível em --callout-color (exige cores CSS válidas, não mais trigêmeos RGB — temas e snippets precisam ser atualizados), Electron 43.1.1 e atualizações de CodeMirror e Mermaid 11.13.0. Sem alterações em AI, MCP ou CLI. O acompanhamento do Catalyst passa para 1.13.6. |
26 |
| 2026-07-27 | Varredura de lançamentos + uma correção de aviso. MCPVault passou de 0.12.1 → 0.12.4 em três patches no mesmo dia em 23 de julho, todos perdidos pela varredura de 22 de julho porque chegaram no dia seguinte. v0.12.3 adiciona uma ferramenta wiki_link — resolve [[Document Name]], [[Name\|Display]], formas escapadas em tabela e #fragment, retornando conteúdo mais o caminho resolvido e alternativas ambíguas — e exclui .trash/ de todas as ferramentas pelo filtro de caminhos padrão; v0.12.4 estende isso a links [[folder/Note]] qualificados por caminho; v0.12.2 corrige patch_note corrompendo inserções de padrões com $, normaliza caminhos com prefixo do vault e elimina achados de alta gravidade do npm audit. A seção do servidor MCP e [^24] agora descrevem os três. Correção: a linha de 2026-07-07 dizia que v0.12.1 estava “com dois avisos de gravidade média sobre filtro de caminhos”. Não estava. O Advisory API de GitHub indica um intervalo vulnerável de < 0.11.5 para GHSA-9c83-rr99-vfwj e < 0.11.4 para GHSA-j99q-93c9-h869 — ambos corrigidos antes de a linha 0.12 ser aberta, então 0.12.1 já estava livre quando aquela linha foi escrita. O corpo e a nota de rodapé agora indicam as primeiras versões corrigidas, em vez de deixar “execute uma versão atual” sugerir uma exposição em aberto. Também: Obsidian 1.13.4 desktop + mobile (27 de julho) é acesso antecipado do Catalyst; o manifesto desktop-releases.json ainda informa latestVersion 1.12.7 com beta.latestVersion 1.13.4, então o canal público não mudou e as referências de versão aqui permanecem. O conteúdo é de UX (exibição de nome de arquivo no lightbox, alinhamento e padding de imagem no Live Preview, uma condição de corrida ao salvar arquivo travado, layout de configurações), sem alteração em AI, MCP ou CLI. |
13 26 |
| 2026-07-22 | Varredura de lançamentos, sem mudanças de fluxo. Obsidian 1.13.3 desktop + mobile (21 de julho) é apenas acesso antecipado do Catalyst — o canal público, verificado no manifesto, permanece em 1.12.7; o conteúdo é de UX (lightbox/zoom de imagem incorporada, correção de altura de linha no Live Preview, teclas de seta no File Recovery, correção de paneType de URI unique), sem alterações em AI/MCP/CLI. O acompanhamento do Catalyst sobe 1.13.2 → 1.13.3. Nota: 1.13.3 foi publicado mais tarde em 21 de julho, após o encerramento da varredura daquele dia — o “sem novos lançamentos” da linha anterior estava correto quando foi escrito. Web Clipper 1.7.1 (22 de julho, lançamento de GitHub): Importar destaques, variáveis de modelo Interpreter {{model}}/{{modelId}}/{{modelProvider}}, predefinições de provedores atualizadas, Defuddle 0.19.2, correções do Interpreter para modelos recentes de Anthropic, chaves API nativas do Gemini, tratamento de DeepSeek e Azure OpenAI; as disponibilizações nas lojas podem atrasar em relação à data de GitHub. Sem notícias oficiais do servidor MCP; a especificação stateless ainda estava prevista para 28 de julho. |
26 |
| 2026-07-21 | Correção de precisão: o canal público de desktop é 1.12.7, não 1.13.1. A entrada de 2026-06-10 (e referências no corpo desde então) tratava 1.13.1 como lançamento do canal público; a página de changelog de 1.13.1 está marcada como Early access, e o manifesto oficial de atualização automática (obsidianmd/obsidian-releases, desktop-releases.json) lista latestVersion público 1.12.7 com 1.13.2 no canal beta — toda a linha 1.13.x é exclusiva do Catalyst. Referências no corpo e 26 corrigidas. A varredura de lançamentos de 2026-07-17 → 2026-07-21 não encontrou novos lançamentos: o core permanece em 1.13.2 Catalyst, Clipper 1.7.0, sem notícias oficiais do servidor MCP, e a especificação stateless de MCP ainda estava prevista para 28 de julho. | 26 |
| 2026-07-17 | Varredura de lançamentos, sem mudanças de fluxo. Obsidian 1.13.2 (14 de julho) é apenas acesso antecipado do Catalyst — o canal público permanece em 1.13.1, então as referências de versão aqui continuam atuais; seu único item relacionado ao guia é uma nova variável url no modelo da Folha de Compartilhamento do iOS (insere o link compartilhado na nota), que será incorporada à seção do caminho de captura quando 1.13.2 chegar ao público. Web Clipper 1.7.0 (16 de junho, descoberto anteriormente): atualização para Defuddle 0.19.0, {{content}} agora preserva marcadores ==highlight==, e os destaques persistem entre a página ativa e a visualização Reader. Nenhum servidor MCP oficial do Obsidian ou integração de AI foi anunciado; o lançamento stateless da especificação MCP continuava agendado para 28 de julho. Verificado em obsidian.md/changelog, lançamentos de github.com/obsidianmd/obsidian-clipper e blog.modelcontextprotocol.io. |
|
| 2026-07-07 | Correções de precisão. MCPVault esclarecido como projeto próprio (npm @bitbonsai/mcpvault, repo bitbonsai/mcpvault), agora v0.12.1, com dois avisos de gravidade média sobre filtro de caminhos (GHSA-9c83-rr99-vfwj, GHSA-j99q-93c9-h869) — o link [^24] anterior apontava para o repo errado (MarkusPfundstein/mcp-obsidian). Corrigido o status de MarkusPfundstein/mcp-obsidian: ele é mantido ativamente (commits até 15 de maio de 2026, adicionando search_by_tag/get_frontmatter), não “inativo desde junho de 2025”; ele ainda não disponibiliza lançamentos com tag. Verificado no histórico de commits de GitHub, nos Security Advisories de GitHub e no npm. |
|
| 2026-07-06 | Reestruturação editorial para facilitar a encontrabilidade: renomeado “Quick Start: First AI-Connected Vault” para Configuração do Obsidian MCP (âncora #obsidian-mcp-setup) e adicionado um resumo de capacidades “O que Claude pode fazer depois de conectado” (buscar, ler, listar, contexto formatado; limite somente leitura com escritas tratadas por hooks), consolidado da seção de Arquitetura do Servidor MCP. Sem fatos novos; links internos atualizados. |
|
| 2026-06-10 | Atualização de versões. Obsidian 1.13.1 desktop chegou ao canal público (9 de junho de 2026) — uma atualização de UX de configurações + CodeMirror sobre 1.13.0, sem grande alteração de AI/automação. Referências a versões atuais no corpo passaram de 1.13.0 para 1.13.1 (pública, 9 de junho de 2026). | 26 |
| 2026-06-09 | Atualização do ecossistema. A especificação MCP de 2026-07-28 entrou em Release Candidate (anunciada em 21 de maio de 2026) — a maior revisão de MCP desde o lançamento: núcleo de protocolo stateless (remove o handshake initialize e Mcp-Session-Id), Apps MCP (HTML renderizados no servidor em iframes sandboxed), Tasks passando do núcleo experimental para uma extensão oficial, endurecimento de OAuth 2.0/OIDC e uma política de ciclo de descontinuação de 12 meses (especificação final em 28 de julho de 2026); substituiu o enquadramento especulativo de roadmap “provisoriamente em meados de 2026” na nota de Evolução da Especificação MCP pelo RC concreto. sqlite-vec v0.1.10-alpha (31 de mar. – 18 de maio de 2026) adiciona tipos de índice approximate-nearest-neighbor (rescore, ivf experimental, DiskANN baseado em disco) além do KNN por força bruta — marcado como no horizonte/experimental, pois a linha 0.1.10 ainda é pré-lançamento. Obsidian 1.13.0 desktop (acesso antecipado, 28 de maio de 2026) atualizado como versão atual nas referências do corpo; é um lançamento de UX/segurança/ferramentas de desenvolvimento, sem novos recursos de AI/automação. |
24 23 25 |
| 2026-06-08 | Verificação de manutenção. Model2Vec v0.8.2 (29 de maio de 2026) lançado: uma versão de manutenção que adiciona uma opção de pesos congelados para treinamento, além de correções para tokens de múltiplas palavras, uma refatoração do treinamento e correções no tratamento de pesos não quantizados; nota de rodapé atualizada. Nada mais novo que a base existente: a versão mais recente do Obsidian continua 1.13.0 (28 de maio, já documentada abaixo), sqlite-vec estável continua v0.1.9 (v0.1.10 ainda alpha), e a especificação MCP continua sendo a revisão de 2025-11-25. Sem mudança no corpo além da nota de versão do Model2Vec. | 10 |
| 2026-05-28 | Obsidian 1.13.0 desktop + 1.13.0 mobile (acesso antecipado do Catalyst) lançados. Desktop: painel de Configurações reformulado que abre em sua própria janela com busca integrada e navegação por teclado; URIs do Obsidian agora exibem uma caixa de diálogo de confirmação antes de disparar ações; novo aviso antes de carregar recursos HTML de unidades de rede; Search adicionado à visualização Bookmarks; tratamento aprimorado de imagens no editor; melhorias em File Explorer / Properties / Sync; inúmeras correções para desenvolvedores-API e bugs. Mobile: nova Folha de Compartilhamento do iOS com locais de destino configuráveis; reordenação de abas pelo alternador de abas; gestos de pressionar e segurar em tablets para redimensionar divisões e barras laterais fixadas; Bases ganha um item de menu para redimensionar colunas em visualizações de tabela; correções de bugs no iOS e na busca. Implicações para fluxos de AI: a caixa de diálogo de confirmação em URIs do Obsidian adiciona uma barreira deliberada às integrações MCP/agente orientadas por URI; o menu de redimensionamento de colunas do Bases torna o Bases mais utilizável como índice de entrada do vault que agentes consultam; o destino configurável da Folha de Compartilhamento do iOS torna mais rápido conectar o caminho de captura do iPhone (já documentado como o intake principal) aos pipelines Claude/Codex. | |
| 2026-05-06 | Atualização de vigência com fontes verificadas: Smart Connections v4.5.0 moveu conexões do rodapé para o Core; lançamentos estáveis sqlite-vec v0.1.8/v0.1.9 atualizaram o empacotamento e o comportamento de DELETE; Model2Vec v0.8.x atualizou internals de tokenizer/persistência e tabelas de benchmark; corrigida a cronologia de CLI do Obsidian de “1.12.7 introduziu CLI” para “1.12.0 introduziu CLI, 1.12.7 melhorou o empacotamento de instalação/runtime.” | |
| 2026-04-27 | Ciclo de abril do Web Clipper: 1.4.0 (UI interativa de transcrição do YouTube + padrão Abrir no Reader), 1.5.0 (visualizador de Highlights), 1.6.0 (reformulação de UX do Highlighter + extratores de fonte Defuddle 0.18 para LinkedIn/Threads/Bluesky/Discourse/Medium), 1.6.1 + 1.6.2 (correções para Reader e Safari). Reenquadrado o Web Clipper como o caminho principal de intake pelo navegador para fluxos de AI, em vez de uma menção passageira a favoritos. Nenhum lançamento de Obsidian desktop, Sync ou Bases na janela. | |
| 2026-04-16 | Smart Connections v4.3.0 (visualização de grafo, dock configurável, recuperação de block-embedding, env entre plugins do Substrate). Documentada a onda de plugins nativos de AI de abril de 2026 (Cortex, VaultSearch, LLM Wiki, Drift, EngramQuest, Hybrid Search MCP). Sinalizado MarkusPfundstein/mcp-obsidian como em modo de manutenção (último commit em junho de 2025). Dataview inativo; Bases é o sucessor para novos trabalhos. Obsidian CLI 1.12.7 continua sendo a ponte preferida para assistentes de AI. |
|
| 2026-04-01 | Adicionada a seção Obsidian CLI (comandos v1.12 para fluxos de AI). Adicionada a seção de plugins de agente (Claudian, Agent Client). Documentado o plugin core Bases para organização do vault. Atualizada a contagem de plugins para 2.500+. Adicionada a Extensão de Compartilhamento do iOS como fonte de intake. Atualizada a matriz de compatibilidade com plugins de agente incorporados. | |
| 2026-03-30 | MCPVault v0.11.0: ferramenta list_all_tags, suporte a .base/.canvas, renomeado para @bitbonsai/mcpvault. Obsidian Desktop v1.12.7 inclui o binário CLI para interações mais rápidas no terminal. |
|
| 2026-03-23 | Documentado sqlite-vec v0.1.7 estável: suporte a DELETE para tabelas vec0, restrições de distância KNN para paginação. Índice approximate nearest neighbor DiskANN anunciado para lançamento futuro. | |
| 2026-03-07 | Adicionado potion-multilingual-128M (101 idiomas, maio de 2025) à comparação de modelos de embeddings. sqlite-vec em v0.1.7-alpha.10 (correções de CI/CD, sem alterações de recursos). Especificação MCP e técnicas de recuperação confirmadas como atuais. | |
| 2026-03-03 | Atualizada a evolução da especificação MCP (nov. de 2025 entregue: Streamable HTTP, .well-known, anotações de ferramentas). Adicionados fine-tuning do Model2Vec e suporte a tokenizer BPE/Unigram. Adicionada tabela de comparação de servidores MCP da comunidade. Atualizado Smart Connections para v4. | |
| 2026-03-02 | Adicionados potion-base-32M e potion-retrieval-32M à comparação de modelos. Adicionada seção de quantização/redução de dimensionalidade. Adicionada nota de evolução da especificação MCP. | |
| 2026-03-01 | Lançamento inicial |
Referências
-
Internet Vin, “22 commands I use with Obsidian and Claude Code,” March 2026, x.com/internetvin/status/2026461256677245131. ↩
-
Nicopreme, skill de agente “Visual Explainer” com comandos de barra, x.com/nicopreme/status/2023495040258261460. ↩
-
Cormack, G.V., Clarke, C.L.A. e Buettcher, S. Reciprocal Rank Fusion supera Condorcet e métodos individuais de aprendizado de ranking. SIGIR, 2009. Apresenta RRF com k=60 como um método sem parâmetros para combinar listas classificadas. ↩↩↩
-
Preços de Embeddings da OpenAI. text-embedding-3-small: US$ 0,02 por milhão de tokens. Custo estimado do vault por reindexação completa: ~US$ 0,30. ↩
-
van Dongen, T. et al. Model2Vec: transforme qualquer Sentence Transformer em um modelo pequeno e rápido. arXiv, 2025. Descreve a abordagem de destilação que produz embeddings estáticos a partir de sentence transformers. ↩
-
Cartão do modelo potion-base-8M e resultados do Model2Vec. As tabelas publicadas atuais informam potion-base-8M com 51.32 Avg (All) / 51.08 Avg (MTEB), em comparação com all-MiniLM-L6-v2 com 55.80 Avg (All) / 55.93 Avg (MTEB), ou aproximadamente 92% de retenção na pontuação de todas as tarefas. ↩
-
Especificação do Model Context Protocol. O padrão MCP para conectar ferramentas de IA a fontes de dados. ↩
-
Modelos Potion do Model2Vec, potion-base-32M e potion-retrieval-32M. Os cartões de modelo atuais informam potion-base-32M com 52.83 Avg (All) e potion-retrieval-32M com 35.06 na tabela de retrieval. ↩↩↩
-
Atualização sobre o próximo lançamento do protocolo MCP. Histórico: o lançamento de novembro de 2025 trouxe o transporte Streamable HTTP, descoberta de URL
.well-known, anotações estruturadas de ferramentas e padronização de níveis SDK. O ciclo de lançamento apresentado foi concluído com a revisão de 28 de julho de 2026 — a especificação atual (consulte 24). ↩↩↩ -
Lançamentos do Model2Vec. v0.4.0 (fev. de 2025): suporte a treinamento/fine-tuning. v0.5.0 (abr. de 2025): reescrita do backend, quantização, redução de dimensionalidade. v0.7.0 (out. de 2025): quantização de vocabulário, suporte a tokenizadores BPE/Unigram. v0.8.0/v0.8.1 (mar. de 2026): refatorações de tokenizador e persistência, descontinuação do Python 3.9, atualizações dos resultados do MTEB V2 e compatibilidade com caminhos do Windows. v0.8.2 (29 de maio de 2026): uma versão de manutenção que adiciona uma opção de pesos congelados para treinamento, além de correções para tokens de múltiplas palavras, uma refatoração de treinamento e correções no tratamento de pesos não quantizados. ↩↩↩
-
Smart Connections para Obsidian. Smart Connections v4: embeddings de IA local-first, busca semântica funciona offline após a indexação inicial. ↩
-
potion-multilingual-128M. Minish Lab, maio de 2025. Modelo de embeddings estáticos para 101 idiomas, com o melhor desempenho entre embeddings estáticos multilíngues. Mesma dependência apenas de numpy dos outros modelos potion. ↩
-
MCPVault —
bitbonsai/mcpvault. npm@bitbonsai/mcpvault, versão mais recente v0.15.0 (publicada em 2026-08-09); a sequência 0.12.2–0.12.4 foi lançada em 2026-07-23 (0.12.2 às 09:51, 0.12.4 às 10:10 — 0.12.3 aparece no changelog do repositório entre elas, mas nunca foi publicada no npm); um projeto distinto deMarkusPfundstein/mcp-obsidian, não uma renomeação dele. v0.11.0 (março de 2026) adicionou a ferramentalist_all_tagspara examinar frontmatter e hashtags com contagens, melhorou o tratamento de pastas com pontos e adicionou suporte a arquivos.base/.canvas. O conteúdo de 0.12.2–0.12.4 vem do CHANGELOG.md do repositório, que é o único registro de lançamento — o endpoint de releases do GitHub para este repositório retorna uma lista vazia, portanto os horários de publicação no npm e o changelog são as fontes principais. 0.12.2:patch_noteinserenewStringliteralmente em vez de expandir$',$&,$`,$$(issue #149 / PR #153); caminhos absolutos prefixados pelo vault ou no estilo~/foram normalizados para relativos ao vault (issue #122 / PR #151); descobertas de alta severidade do npm audit foram eliminadas por atualizações apenas do lockfile (PR #154). 0.12.3: nova ferramentawiki_link(PR #101) e.trash/excluída de todas as ferramentas pelo filtro de caminhos padrão. 0.12.4:wiki_linkresolve links com caminho qualificado, como[[folder/Note]], pelo caminho completo relativo ao vault, em vez do basename. Dois avisos de segurança de severidade média do GitHub afetam seu filtro de caminhos: GHSA-9c83-rr99-vfwj (diretórios restritos negados apenas na raiz do vault, não nos aninhados) e GHSA-j99q-93c9-h869 (bypass da lista de negação por equivalência de maiúsculas/minúsculas e ponto/espaço à direita). Conforme o API do aviso do GitHub, seus intervalos vulneráveis são< 0.11.5e< 0.11.4, com as primeiras versões corrigidas 0.11.5 e 0.11.4, respectivamente — ambas anteriores à 0.12.0, portanto todas as versões 0.12.x, incluindo a 0.12.1, já estão corrigidas. Intervalos dos avisos e timestamps do npm reverificados em 2026-08-14. ↩↩↩ -
Lançamento do sqlite-vec v0.1.7. 17 de março de 2026. Lançamento estável: suporte a DELETE para tabelas virtuais vec0, restrições de distância KNN para paginação, melhorias nos testes de fuzzing. A indexação aproximada de vizinhos mais próximos DiskANN foi anunciada para um lançamento futuro. ↩↩↩
-
Introdução ao Bases. Plugin principal do Obsidian introduzido na v1.9.10. Visualizações semelhantes a bancos de dados (tabelas, galerias, calendários, quadros kanban) sobre arquivos do vault usando propriedades do frontmatter como campos. Arquivos salvos no formato
.base. ↩ -
Changelog do Obsidian Desktop v1.12.0 e Changelog do Obsidian Desktop v1.12.7. A v1.12.0 introduziu o CLI para automação do vault baseada em terminal; a v1.12.7 melhorou o empacotamento de instalação/runtime com um binário independente, TUI e comportamento de arquivo de socket. Consulte também a documentação do CLI. ↩↩
-
Claudian. Plugin do Obsidian que incorpora Claude Code como um colaborador de IA no vault. Oferece chat na barra lateral, prompts com reconhecimento de contexto, suporte a visão, comandos slash e modos de permissão. ↩
-
Agent Client. Plugin do Obsidian que oferece uma interface unificada para Claude Code, Codex CLI e Gemini CLI por meio do Agent Client Protocol (ACP). Oferece suporte a menções de notas, execução de shell e aprovação de ações. ↩
-
Changelog do Obsidian iOS. As atualizações do início de 2026 incluem uma Share Extension para salvar conteúdo de outros apps diretamente no vault, correções nos widgets de Daily Note e Bookmark e melhorias na atualização do widget View Note. ↩
-
MarkusPfundstein/mcp-obsidian. Mantido ativamente — commits até 15 de maio de 2026, com trabalhos recentes adicionando ferramentas como
search_by_tageget_frontmatter, além de cobertura de testes ampliada (verificado em relação ao histórico de commits do repositório e atools.py). Ainda não disponibiliza releases com tags, portanto instale a partir de um commit fixado. Baseado em Local-REST-API; discussões no fórum (abril de 2026) relatam migração da comunidade para a ponte CLI do Obsidian de primeira classe (1.12.x) em novas configurações, mas mcp-obsidian continua sendo uma opção funcional e atualizada para implantações REST-API existentes. ↩↩ -
Lançamento do Smart Connections v4.5.0. 5 de maio de 2026. As conexões no rodapé se tornaram um recurso Core; os lançamentos recentes da v4 também incluem visualizações em grafo para listas de conexões, locais configuráveis do painel de conexões, recuperação aprimorada de block-embedding, estado entre plugins do Substrate, correções de fallback de transformer e redução de cálculos duplicados de conexões. ↩
-
releases de obsidianmd/obsidian-clipper — fonte primária para o mapeamento entre versão e recursos do Web Clipper. Ciclo de abril de 2026: 1.4.0 (9 de abr., UI de transcrição do YouTube + Open in Reader como padrão), 1.5.0 (15 de abr., visualizador de Highlights + fade-in do Reader), 1.5.1 (15 de abr., correção de compilação do webpack), 1.6.0 (21 de abr., UX do Highlighter + Defuddle 0.18 com extratores para LinkedIn/Threads/Bluesky/Discourse/Medium), 1.6.1 (22 de abr., correções no outline do Reader + busca em highlights), 1.6.2 (23 de abr., correção da área de transferência do modo incorporado do Safari). Listado também na loja Mozilla Add-ons e na Chrome Web Store. ↩
-
sqlite-vec v0.1.8, sqlite-vec v0.1.9, sqlite-vec v0.1.10-alpha.3 e sqlite-vec v0.1.10-alpha.4. A v0.1.8 corrigiu o empacotamento do npm; a v0.1.9 corrigiu um bug de DELETE para colunas de texto de metadados com mais de 12 caracteres; a v0.1.10-alpha.3 adiciona suporte adequado a
INSERT OR REPLACE INTO; a v0.1.10-alpha.4 (18 de maio de 2026) corrige a falha deALTER TABLE RENAMEem tabelasvec0que usam os novos recursos ivf/diskann e um bug de limpeza de instruções armazenadas em cache no DiskANN. A linha 0.1.10 continua em pré-lançamento. ↩↩↩↩↩ -
Candidato a lançamento da especificação MCP de 2026-07-28. Anunciada em 21 de maio de 2026; a especificação final foi lançada em 28 de julho de 2026. A maior revisão do MCP desde o lançamento: núcleo de protocolo sem estado (remove o handshake
initializee o cabeçalhoMcp-Session-Id), Apps do MCP (HTML renderizada no servidor em iframes de cliente em sandbox), Tasks deixando o núcleo experimental para se tornar uma extensão oficial (tasks/get,tasks/update,tasks/cancel), fortalecimento da autorização OAuth 2.0 / OIDC e uma política de ciclo de vida de descontinuação de recursos de 12 meses. ↩↩↩↩↩ -
Changelog do Obsidian Desktop v1.13.0. Acesso antecipado, 28 de maio de 2026. Lançamento de UX/segurança/ferramentas para desenvolvedores: painel Settings reformulado, que abre em sua própria janela com busca e navegação por teclado; diálogos de confirmação antes da execução de URIs do Obsidian; um novo API de Settings para desenvolvedores de plugins; e uma correção do CLI para instalações flatpak. Nenhuma grande capacidade nova de IA/automação além da superfície do CLI 1.12.x. ↩↩↩
-
Changelog do Obsidian. O Obsidian 1.13.1 para desktop foi lançado em 9 de junho de 2026 como um lançamento de acesso antecipado do Catalyst — um refinamento de UX das configurações e uma atualização do CodeMirror em relação à 1.13.0, sem nova capacidade de IA/automação. A própria página do changelog da 1.13.1 está identificada como “Early access”, e o manifesto oficial de atualização automática (obsidianmd/obsidian-releases, desktop-releases.json) lista
latestVersionpúblico 1.12.7, com 1.13.2 no canal beta; verificado em 2026-07-21. Reverificado em 2026-07-27: o manifesto ainda informalatestVersion1.12.7, combeta.latestVersionagora em 1.13.4. O feed Atom emobsidian.md/changelog.xmlidentifica cada entrada 1.13.x — 1.13.1 a 1.13.4 — como “(Early access)”; a entrada mais recente intitulada “(Public)” continua sendo 1.12.7, datada de 2026-03-23, correspondendo à lista de releases do GitHub deobsidian-releases. Reverificado em 2026-08-07: o manifesto agora informalatestVersion1.13.4 (promoção pública em 30 de julho de 2026), combeta.latestVersion1.13.6 — a linha 1.13 está amplamente disponível, e as linhas históricas acima descrevem com precisão o período exclusivo do Catalyst conforme as respectivas datas. Reverificado em 2026-08-14: o manifesto informalatestVersion1.13.7, combeta.latestVersion1.13.7 — estável e beta convergiram. ↩↩↩↩↩↩↩↩↩