Construindo um Sistema Multi-Agente Claude Code com TEI + Qdrant
TL;DR
Vetorizei código com TEI (Text Embeddings Inference), armazenei no Qdrant e construí um sistema onde 9 agentes Claude Code buscam código em vez de lê-lo.
1. Por Que Construí Isso
Limitações do Claude Code
O Claude Code é poderoso, mas quando precisa entender a base de código geral, ele abre e lê arquivos um por um.
Read src/auth.ts → 200 linhas consumidas
Read src/middleware.ts → 150 linhas consumidas
Read src/utils/token.ts → 100 linhas consumidas
...Existem casos inevitáveis onde toda a base de código precisa ser lida, como revisões de qualidade de código ou auditorias de segurança, e o consumo é significativo.
Imaginei que agentes lidando com revisões de código ou verificações de segurança poderiam entender o código sem a ferramenta Read, reduzindo custos de token. Então eu tentei.
2. Arquitetura
| Camada | Componentes |
|---|---|
| Claude Code | 9 agentes (Morpheus, Neo, Seraph, ...) |
| MCP Protocol (stdio) | |
| mcp-code-rag | Binário Rust. Ponte de indexação/busca |
| HTTP / gRPC | |
| TEI (e5-base) | Conversão de Texto para vetor |
| Qdrant | Armazenamento de vetores + busca por similaridade |
Componentes
| Componente | Função | Localização |
|---|---|---|
| mcp-code-rag | Servidor MCP. Lida com requisições de indexação/busca | Local (binário Rust) |
| TEI (e5-base) | Conversão de Texto para vetor de 768 dimensões | Docker |
| Qdrant | Armazenamento de vetores + busca por similaridade de cosseno | Docker |
| Agentes Claude Code | Buscam via ferramentas MCP ao explorar código | Local |
3. Por Que Esta Stack
O objetivo não era encontrar o modelo de embedding mais recente ou a combinação ideal. O objetivo era testar se um pipeline RAG realmente funciona em um NAS sem GPU. Então escolhi uma stack leve e fácil de auto-hospedar.
TEI + e5-base
- TEI — Servidor oficial de embedding da Hugging Face. Um comando Docker e está implantado
- e5-base — 768 dimensões. Prático o suficiente com ~50ms/query na CPU
- Suporta busca assimétrica com prefixos
query:/passage:, o que é vantajoso para combinar queries curtas com chunks de código longos
Por Que o Servidor MCP É Escrito em Rust
- Binário único — Implante com um executável. Zero dependências de runtime
- Memória — ~15MB de memória residente. Servidores Python são 200MB+
- Claude Code MCP — JSON-RPC baseado em stdio. serde + tokio do Rust é ideal
- Comunicação externa — Tratamento assíncrono de HTTP + gRPC
4. Fluxos Principais
4.1 Indexação (Código para Vetores)
Diretório do projeto
│
▼
[walkdir] Percorrer arquivos (profundidade máx: 10)
│
▼
[filter] 52 diretórios + 60 extensões excluídas
(node_modules, target, .git, imagens, binários...)
│
▼
[incremental check] Comparar tempos de modificação de arquivos
→ Processar apenas arquivos alterados
│
▼
[chunk] Dividir em unidades de 1500 caracteres (sobreposição de 300 caracteres)
│
▼
[TEI] Cada chunk → "passage: {content}" → vetor de 768 dimensões
│
▼
[Qdrant] Upsert baseado em UUID v5 (lotes de 100)
Collection: "code-rag-{project_name}"Por que chunking de 1500 caracteres?
- Muito grande → precisão da busca cai (ruído)
- Muito pequeno → uma única função se divide em múltiplos chunks, perdendo contexto
- 1500 caracteres + sobreposição de 300 caracteres → previne divisão em limites de funções
4.2 Exemplo de Busca — Agente de Code Review
[code_review_agent] Iniciar auditoria de segurança
│
▼
search_codebase("lógica de autenticação", project_name="my-app")
│
▼
Resultados da busca recebidos (Top 10, apenas similaridade >= 0.5):
│
▼
search_codebase("geração de query SQL", project_name="my-app")
│
▼
search_codebase("validação de entrada do usuário", project_name="my-app")
│
▼
Gerar relatório de segurança a partir dos snippets de código coletadosResultado: 0 Reads, 3 buscas para completar o relatório. Analisa vulnerabilidades de segurança em toda a base de código sem abrir um único arquivo.
4.3 Auto-Indexação
Agente: search_codebase("tratamento de erro", project_name="blog")
│
▼
[Verificação de Collection] "my-app" existe?
│
├─ Não → Disparar auto-indexação → Buscar após indexação completar
│
└─ Sim → Buscar imediatamenteAgentes não precisam chamar indexação diretamente. O índice é criado automaticamente na primeira busca.
5. Números do Mundo Real
| Métrica | Valor |
|---|---|
| Velocidade de embedding TEI | ~50ms/query (CPU) |
| Indexação (1000 arquivos) | ~3 min (incremental: apenas arquivos alterados) |
| Resposta de busca | ~200ms (cache miss), ~5ms (cache hit) |
| Memória do mcp-code-rag | ~15MB |
| Dimensões do vetor | 768 (e5-base) |
| TTL do Cache | 5 min |
| Máx de arquivos indexáveis | 5.000 |
| Tamanho do chunk | 1.500 caracteres (sobreposição de 300 caracteres) |
6. Ferramentas MCP
mcp-code-rag fornece 2 ferramentas MCP para o Claude Code.
| Ferramenta | Descrição |
|---|---|
| search_codebase | Busca código com queries em linguagem natural. Passe um nome de projeto para trocar automaticamente de collection + auto-indexar se ainda não indexado |
| refresh_index | Indexar manualmente especificando um caminho de projeto. Incremental — processa apenas arquivos alterados |
Ao impor uma regra de que agentes chamem search_codebase primeiro ao explorar código, você pode prevenir o desperdício de tokens de percorrer arquivos com a ferramenta Read.
Pontos Fortes
- Indexe uma vez, busque instantaneamente depois — Indexação é lenta apenas na primeira vez; execuções subsequentes são incrementais e processam apenas arquivos alterados. A busca em si leva ~200ms
- Zero consumo de token — Nenhum arquivo é aberto com Read, então a janela de contexto não é gasta em buscas
- Exploração de código via linguagem natural — Encontre código relevante imediatamente com queries como "tratamento de autenticação" ou "queries SQL"
- Forte para tarefas de toda a base de código — Bem adequado para análise ampla de padrões como auditorias de segurança e code reviews
Limitações
Busca semântica precisa como "O tratamento de erro está implementado corretamente?" é insuficiente apenas com similaridade de vetores. Para tais casos, você precisa de um modelo Rerank, ou uma abordagem híbrida combinando busca por palavras-chave (BM25) com busca vetorial.
| Caso de Uso | Sistema Atual | Precisa de Adição |
|---|---|---|
| Entender estrutura geral do código | Adequado | — |
| Scanning de padrões de segurança | Adequado | — |
| Busca de lógica precisa | Insuficiente | Rerank, busca híbrida |
| Rastreamento de tratamento de erro | Insuficiente | Rerank + análise AST |
7. Começando
Pré-requisitos
- Ambiente Docker (para rodar Qdrant, TEI)
- Rust (para compilar mcp-code-rag)
- Claude Code (plano Pro)
Uma vez que tudo esteja instalado e o servidor MCP esteja registrado no Claude Code, ele busca apenas o código que você precisa via busca semântica — com zero desperdício de token.
Log
- • 2026-01-29: create