Relatório de Estado — ArboreoLab Embeddings Worker
Data: 09 de Janeiro de 2026
Atualizado em: 09/01/2026 04:45 (BRT)
Responsável: Engenheiro de Software Sênior
Status: ✅ Operacional (Worker Mac processando clio_ocr)
📊 Resumo Executivo
| Métrica | Valor |
|---|---|
| Localização | /home/arboreolab/Clio/embeddings-worker-interface |
| Deploy Mac | ~/embeddings-worker-deploy |
| Dispositivo | MacBook Air M2 (Apple Silicon) |
| Aceleração | MPS (Metal Performance Shaders) |
| Modelo | paraphrase-multilingual-mpnet-base-v2 (768 dim) |
| Batch Size | 32 (recomendado: até 128) |
| Status | 🔄 Processando clio_ocr (13.104/16.431 = 80%) |
🎯 Objetivo
Gerar embeddings vetoriais para entidades do sistema ArboreoLab, permitindo busca semântica por:
- Nome da entidade (
entity_vector) - Entidade relacionada (
relatedto_entity_name_vector) - Tripla completa (
triple_vector) — ex: "Walter Zanini é amigo de Aracy Amaral"
🏗️ Arquitetura
┌─────────────────────────────────────────────────────────────────────────┐
│ SERVIDOR (srv1) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Node.js Backend │ │
│ │ ou curl (HTTP) │ │
│ └────────────────────────────────┬────────────────────────────────┘ │
│ │ │
│ localhost:9002 (API) │
│ │ │
│ ┌────────────────────────────────┼────────────────────────────────┐ │
│ │ SSH Reverse Tunnel │ SSH Forward Tunnel │ │
│ │ (API: 9002 → 9999) │ (DB: 3306 → 3306) │ │
│ └────────────────────────────────┼────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────────────┼────────────────────────────────┐ │
│ │ MariaDB 11.8.5 │ │ │
│ │ ├── ClioVector │ │ │
│ │ └── GeopoliticasVector │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
SSH Tunnel (porta 22)
│
┌─────────────────────────────────────────────────────────────────────────┐
│ MACOS (MacBook Air M2) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Embeddings Worker (Flask API) │ │
│ │ ├── Port 9999 (local) │ │
│ │ ├── Device: MPS (Metal Performance Shaders) │ │
│ │ ├── Model: paraphrase-multilingual-mpnet-base-v2 │ │
│ │ └── Batch Size: 32 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
📁 Estrutura do Projeto
embeddings-worker-interface/
├── api_server.py # API Flask para controle remoto (usado no servidor)
├── worker.py # Worker standalone (usado no Mac)
├── embedding_generator.py # Gerador de embeddings (sentence-transformers)
├── db_connector.py # Conexão MariaDB (validação aprimorada)
├── config.py # Configuração via .env (suporte a aliases)
├── start_worker.sh # Script de inicialização (túnel + worker)
├── ssh_tunnel.sh # Gerenciador de túnel SSH (forward + reverse)
├── install_mac.sh # Instalador para Mac
├── setup.sh # Setup do ambiente Python (venv)
├── create_deploy_package.sh # Gera tar.gz para distribuição
├── requirements.txt # Dependências Python
├── .env.macos # Template de configuração Mac
├── com.arboreolab.embeddings-worker.plist # LaunchAgent macOS
├── releases/ # Pacotes de deploy gerados
│ └── embeddings-worker-deploy.tar.gz
└── migrations/
├── 001_add_entity_relation_vectors.sql
├── 002_fix_geopoliticas_vector.sql
└── 003_revert_and_consolidate_vector.sql
🔌 API Endpoints
| Método | Endpoint | Descrição |
|---|---|---|
GET | /health | Health check |
GET | /status | Status do worker e estatísticas |
GET | /databases | Lista databases disponíveis (multi-tenant) |
GET | /jobs | Lista jobs pendentes/em execução |
POST | /jobs | Cria novo job de embeddings |
GET | /jobs/{id} | Status de job específico |
Exemplo de Uso
# Listar databases
curl http://localhost:9002/databases
# Iniciar processamento completo
curl -X POST http://localhost:9002/jobs \
-H "Content-Type: application/json" \
-d '{"database": "GeopoliticasVector"}'
# Processar apenas 100 registros (teste)
curl -X POST http://localhost:9003/jobs \
-H "Content-Type: application/json" \
-d '{"database": "GeopoliticasVector", "limit": 100}'
# Monitorar progresso
curl http://localhost:9002/status
📊 Databases e Registros
| Database | Tabela | Total Registros | Status |
|---|---|---|---|
| GeopoliticasVector | clio_entidades_vector | 10.024 | ⏳ Pendente (32 processados em teste) |
| ClioVector | clio_entidades_vector | 20.359 | ⏳ Pendente (dados modelo) |
Colunas Vetoriais em clio_entidades_vector
| Coluna | Tipo | Descrição |
|---|---|---|
entidade_id | INT | FK para clio_entidades.id |
entity_vector | VECTOR(768) | Embedding do nome da entidade |
relatedto_entity_name_vector | VECTOR(768) | Embedding da entidade relacionada |
triple_vector | VECTOR(768) | Embedding da tripla completa |
📊 Status de Processamento (09/01/2026 04:45 BRT)
| Tabela | Total | Processados | Pendentes | Status |
|---|---|---|---|---|
clio_entidades | 97.335 | 97.335 | 0 | ✅ 100% |
clio_entity_relations | 31.649 | 31.649 | 0 | ✅ 100% |
clio_triples | 31.649 | 31.649 | 0 | ✅ 100% |
clio_ocr | 16.431 | 13.104 | 3.327 | 🔄 80% |
clio_ocr_segments | 13.969 | 13.969 | 0 | ✅ 100% |
| TOTAL | 191.033 | 187.706 | 3.327 | 98% |
Worker Ativo
| Worker | Device | Porta | Batch | Status |
|---|---|---|---|---|
| MacBook Air M2 | MPS (Metal) | 9999 | 32 | 🔄 Processando clio_ocr |
| srv1 (Servidor) | CPU | 9003 | 16 | ⏹️ Parado (evitar conflito) |
Performance Observada (Mac)
- Batch size: 32 registros
- Tempo por batch: ~1 segundo (geração + UPDATE)
- Velocidade MPS: até 39 it/s
- ETA para conclusão: ~2-3 minutos
⚙️ Configuração (.env)
# Database (via SSH tunnel)
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=embeddings_worker
DB_PASSWORD=Emb3dd1ngs_W0rk3r_2026!
DB_NAME=GeopoliticasVector
# Model
MODEL_NAME=paraphrase-multilingual-mpnet-base-v2
DEVICE=mps
# API
API_PORT=9999
BATCH_SIZE=32
# SSH Tunnel
SSH_HOST=srv1.arboreolab.com.br
SSH_USER=arboreolab_38g57g0kO0dh
SSH_PORT=22
REMOTE_PORT=9002
SSH_KEY=/Users/douglasromao/.ssh/id_ed25519
🔐 Usuário MariaDB
-- Usuário específico para embeddings worker
CREATE USER 'embeddings_worker'@'localhost' IDENTIFIED BY 'Emb3dd1ngs_W0rk3r_2026!';
CREATE USER 'embeddings_worker'@'127.0.0.1' IDENTIFIED BY 'Emb3dd1ngs_W0rk3r_2026!';
GRANT SELECT, UPDATE ON ClioVector.* TO 'embeddings_worker'@'localhost';
GRANT SELECT, UPDATE ON ClioVector.* TO 'embeddings_worker'@'127.0.0.1';
GRANT SELECT, UPDATE ON GeopoliticasVector.* TO 'embeddings_worker'@'localhost';
GRANT SELECT, UPDATE ON GeopoliticasVector.* TO 'embeddings_worker'@'127.0.0.1';
FLUSH PRIVILEGES;
📈 Processamento Completo (08/01/2026)
Status Final
| Database | Tabela | Total | Processados | Status |
|---|---|---|---|---|
| GeopoliticasVector | clio_entidades (semantic_vector) | 97.335 | 97.335 | ✅ 100% |
| GeopoliticasVector | clio_entity_relations | 31.649 | 31.649 | ✅ 100% |
| GeopoliticasVector | clio_triples | 31.649 | 31.649 | ✅ 100% |
Workers Utilizados
| Worker | Aceleração | Porta | Registros Processados |
|---|---|---|---|
| MacBook Air M2 | MPS (Metal) | 9002 | ~80.000 |
| srv1 (Servidor) | CPU AVX-512 | 9003 | ~80.000 |
Total: ~160.633 embeddings processados em paralelo com coordenação automática.
🧪 Testes de Busca Vetorial (08/01/2026)
Resumo de Performance
| Métrica | Valor | Status |
|---|---|---|
| Queries testadas | 39 | ✅ |
| Tempo médio | 114.98ms | ✅ Bom |
| Throughput (cache) | 2.394 queries/s | ✅ Excelente |
Latência por Tipo de Busca
| Tipo | Queries | Tempo Total | Média |
|---|---|---|---|
| semantic_vector | 27 | 2.220s | 82.25ms |
| relation_vector | 7 | 1.458s | 208.39ms |
| triple_vector | 5 | 0.804s | 160.95ms |
Teste de Carga (100 queries)
| Métrica | Valor |
|---|---|
| Tempo total | 41.77ms |
| Média por query | 0.42ms |
| Throughput | 2.394 queries/segundo |
🔍 Análise de Resiliência a Erros OCR
Variações Corretas (Alta Tolerância) ✅
| Query | Score | Encontrou? |
|---|---|---|
| "Walter Zanini" | 0.954 | ✅ Top 1 |
| "walter zanini" | 0.901 | ✅ Top 1 |
| "WALTER ZANINI" | 0.897 | ✅ Top 1 |
| "Zanini, Walter" | 0.927 | ✅ Top 1 |
| "Prof. Walter Zanini" | 0.972 | ✅ Top 1 |
"Walter Zanini" (aspas) | 1.000 | ✅ Perfeito |
Erros de OCR no Sobrenome (Tolerância Alta) ✅
| Erro | Query | Score | Status |
|---|---|---|---|
| i → 1 | "Walter Zan1ni" | 0.899 | ✅ Encontrou |
| i truncado | "Walter Zanmi" | 0.898 | ✅ Encontrou |
| l → ln | "Walter Zanlni" | 0.913 | ✅ Encontrou |
| letra faltando | "Walter Zanin" | 0.901 | ✅ Encontrou |
Erros de OCR no Primeiro Nome (Tolerância Baixa) ⚠️
| Erro | Query | Score | Status |
|---|---|---|---|
| l → 1 | "Wa1ter Zanini" | 0.800 | ⚠️ Top 5 |
| l → i | "Waiter Zanini" | 0.762 | ❌ Não encontrou |
| l → I | "WaIter Zanini" | 0.794 | ❌ Não encontrou |
Conclusão OCR
- Erros no sobrenome: Bem tolerados pelo modelo
- Erros no primeiro nome: Problemáticos (confunde entidades)
- Acentos incorretos: Degradam significativamente
� Teste Completo de Índices Vetoriais (08/01/2026)
Inventário de Índices
| Índice | Tabela | Coluna | Total Vetores |
|---|---|---|---|
idx_semantic_vector | clio_entidades | semantic_vector | 97.335 |
idx_relation_vec | clio_entity_relations | relation_vector | 31.649 |
idx_triple_vec | clio_triples | triple_vector | 31.649 |
idx_ocr_vec | clio_ocr | ocr_vector | 16.431 |
idx_segment_vec | clio_ocr_segments | segment_vector | 13.969 |
| TOTAL | 191.033 |
Resultados por Índice
1. semantic_vector (97.335 vetores)
| Query | Latência | Score | Top Resultado |
|---|---|---|---|
| "Walter Zanini" | 3.6ms | 0.954 | Walter Zanini |
| "Museu de Arte" | 197.8ms | 0.934 | Museum of Art |
| "Bienal" | 622.5ms | 0.806 | Organizadores da Bienal |
2. relation_vector (31.649 vetores)
| Query | Latência | Score | Top Resultado |
|---|---|---|---|
| "MAC" | 29.9ms | 0.925 | Walter Zanini → MAC |
| "Di Cavalcanti" | 15.6ms | 0.943 | Museu de Arte Moderna de São Paulo → Di Cavalcanti |
3. triple_vector (31.649 vetores)
| Query | Latência | Score | Top Resultado |
|---|---|---|---|
| "Zanini diretor MAC" | 31.9ms | 0.839 | Walter Zanini | diretor de | MAC |
| "artista exposicao" | 35.9ms | 0.817 | artista | entrega trabalhos a | sede da Bienal |
4. ocr_vector (16.431 vetores)
| Query | Latência | Score | Top Resultado |
|---|---|---|---|
| "correspondencia diplomatica" | 16.4ms | 0.716 | DSCN3741.JPG |
| "catalogo exposicao" | 141.2ms | 0.708 | DSCN7371.JPG |
5. segment_vector (13.969 vetores)
| Query | Latência | Score | Top Resultado |
|---|---|---|---|
| "assinatura diretor" | 12.6ms | 0.724 | diretor de |
| "data carta" | 85.2ms | 0.728 | dostcard |
Estatísticas Consolidadas
| Métrica | Valor | Status |
|---|---|---|
| Total de vetores | 191.033 | ✅ |
| Queries testadas | 11 | ✅ |
| Média por query | 108.4ms | ✅ Bom |
| Queries < 500ms | 10/11 (91%) | ✅ |
| Maior latência | 622.5ms (termo genérico) | ⚠️ Aceitável |
Observações
- A query "Bienal" excedeu 500ms (622ms) por ser termo muito genérico que requer cálculo de distância em 97.335 vetores
- Queries específicas como "Walter Zanini" respondem em menos de 5ms
- Índices de relacionamento e triplas mantêm performance consistente (~30ms)
- Índice OCR é adequado para busca em documentos
🏥 Diagnóstico de Saúde
GeopoliticasVector: ✅ SAUDÁVEL
| Critério | Status |
|---|---|
| Embeddings semânticos (97.335) | ✅ |
| Embeddings relacionamentos (31.649) | ✅ |
| Embeddings triplas (31.649) | ✅ |
| Embeddings OCR (16.431) | ✅ |
| Embeddings segmentos (13.969) | ✅ |
| Total vetores indexados | 191.033 |
| Tolerância a variações de case | ✅ |
| Tolerância a erros OCR (sobrenome) | ✅ |
| Performance produção (menos de 500ms) | ✅ 91% |
| Throughput >1k q/s | ✅ |
Veredicto: ✅ Pronto para produção
🚀 Deploy no Mac
Instalação Automática (Recomendado)
O script install_mac.sh (incluído no pacote de deploy) automatiza todo o processo.
# Navegue até o diretório descompactado
cd embeddings-worker-deploy
sudo ./install_mac.sh
Instalação Manual
# 1. Crie o diretório de destino
mkdir -p ~/ArboreoLab
cd ~/ArboreoLab
# 2. Baixe e descompacte o pacote
curl -O https://srv1.arboreolab.com.br/downloads/embeddings-worker-deploy.tar.gz
tar -xzf embeddings-worker-deploy.tar.gz
cd embeddings-worker-deploy
# 3. Configure o ambiente
cp .env.macos .env
echo "Edite o arquivo .env com suas credenciais e configurações"
nano .env
# 4. Execute o setup para criar o ambiente Python
./setup.sh
# 5. Para rodar manualmente (sem serviço de background)
# ./start_worker.sh
Auto-start (Serviço launchd)
O script install_mac.sh faz isso automaticamente. Para fazer manualmente:
# 1. Copie o arquivo de serviço para o local correto
sudo cp com.arboreolab.embeddings-worker.plist /Library/LaunchDaemons/
# 2. Carregue o serviço
sudo launchctl load /Library/LaunchDaemons/com.arboreolab.embeddings-worker.plist
# 3. Inicie o serviço (opcional, RunAtLoad=true já faz isso)
sudo launchctl start com.arboreolab.embeddings-worker
📝 Próximos Passos
- [✅] Processar GeopoliticasVector completo (97.335 + 31.649 + 31.649 registros)
- [✅] Limpar ClioVector (dados removidos, estrutura mantida como referência)
- [✅] Verificar paridade estrutural ClioVector vs GeopoliticasVector
- [✅] Testar todos os 5 índices vetoriais (191.033 vetores validados)
- [🔄] Reprocessar clio_ocr (13.104/16.431 = 80% concluído - Mac processando)
- [✅] Corrigir formato de vetores (
worker.pyatualizado para binário) - [ ] Integrar com motor-rag para busca semântica por entidades
- [ ] Configurar LaunchAgent para auto-start no Mac
🐛 Problemas Resolvidos
| Problema | Causa | Solução |
|---|---|---|
Access denied no MariaDB | Senha com caracteres especiais (backtick, pipe) | Criado usuário embeddings_worker com senha simples |
| Túnel SSH não conectava ao DB | DB_HOST=localhost usa socket, não TCP | Alterado para DB_HOST=127.0.0.1 |
| Worker não iniciava | Script esperava 5s, modelo leva 15s para carregar | Aumentado timeout para 30s |
| Porta em uso | Processo anterior não terminado | Adicionado cleanup no script |
Record has changed (09/01) | Dois workers (Mac + servidor) processando | Parado worker do servidor, Mac processa sozinho |
Vetores clio_ocr zerados (09/01) | Processamento anterior com bug | Reprocessamento via Mac com formato correto |
📚 Referências
- Modelo: sentence-transformers/paraphrase-multilingual-mpnet-base-v2
- MariaDB VECTOR: MariaDB Vector Documentation
- MPS (Apple Silicon): PyTorch MPS Backend