Relatório: Motor RAG Multi-Signal Scoring v2
Data: 09/01/2026
Autor: Engenheiro de Software Sênior
Status: ✅ IMPLEMENTADO E VALIDADO
1. Resumo Executivo
Implementação completa do Multi-Signal Scoring v2 no Motor RAG (fregeRAG), integrando os 5 índices vetoriais do GeopoliticasVector para busca semântica híbrida com alta precisão e performance.
Resultados Principais
| Métrica | Antes | Depois | Melhoria |
|---|---|---|---|
| Performance | 57.7s | 788ms | -98.6% |
| Precisão | Docs MAC ausentes | MAC no Top 2 | ✅ |
| Robustez | - | 83% queries aprovadas | ✅ |
2. Arquitetura Multi-Signal Scoring v2
2.1 Fluxo de Processamento
Query do Usuário
│
▼
┌──────────────────┐
│ Gerar Embedding │ (~60ms)
└────────┬─────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ DETECÇÃO DE ENTIDADES │
├──────────────────────────────────────────────────────┤
│ 1. Match Exato (n-grams → clio_entidades) │
│ 2. Busca Semântica (idx_semantic_vector) │
│ 3. Busca por Relacionamentos (idx_triple_vec) │
└────────┬─────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ POOL DE CANDIDATOS │
├──────────────────────────────────────────────────────┤
│ • Busca Vetorial Docs (idx_ocr_vec) → 100 docs │
│ • Busca Vetorial Segmentos (idx_segment_vec) → 100 │
│ • Entity Boosting → +50 docs com entidades │
└────────┬─────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────┐
│ SCORING (5 SINAIS) │
├──────────────────────────────────────────────────────┤
│ Score = W_DOC×S_doc + W_SEG×S_segment + W_ENT×S_ent │
│ + W_TRI×S_triple + W_TXT×S_text │
└────────┬─────────────────────────────────────────────┘
│
▼
Ranking Final
2.2 Sinais e Pesos
| Sinal | Peso | Descrição | Fonte |
|---|---|---|---|
| S_doc | 0.25 | Similaridade documento inteiro | clio_ocr.ocr_vector |
| S_segment | 0.30 | Similaridade melhor parágrafo | clio_ocr_segments.segment_vector |
| S_ent | 0.20 | Cobertura de entidades | clio_entidades.inFileID |
| S_triple | 0.15 | Similaridade relações | clio_triples.triple_vector |
| S_text | 0.10 | Match palavras-chave | Full-text em content_markdown |
2.3 Entity Boosting
Problema resolvido: Documentos contendo entidades da query (ex: "MAC") tinham baixa similaridade vetorial (~0.65) comparado a documentos genéricos (~0.75), ficando fora do pool de candidatos.
Solução: Quando entidades são detectadas na query, seus documentos associados (inFileID) são adicionados ao pool de candidatos independentemente do score vetorial.
# Fluxo Entity Boosting
1. Detectar entidades na query (ex: "MAC" → 19 documentos)
2. Buscar metadados desses documentos
3. Adicionar ao pool de candidatos (mesmo se não estavam no top 100 vetorial)
4. S_ent = entidades_matched / total_entidades_query
3. Otimizações de Performance
3.1 Problemas Identificados (Profiling)
| Função | Tempo Original | Causa |
|---|---|---|
_semantic_search_entities | 36.5s | GROUP BY + VEC_DISTANCE em 97k registros |
_batch_search_triples | 18s | GROUP BY em toda tabela sem filtro |
_semantic_search_relationships | 12.6s | HAVING + duplo VEC_DISTANCE |
_detect_entities_in_query | 1.4s | 15 queries SQL separadas |
_batch_search_segments | 1.1s | GROUP BY + VEC_DISTANCE |
3.2 Soluções Aplicadas
| Função | Otimização | Tempo Final |
|---|---|---|
_semantic_search_entities | ORDER BY VEC_DISTANCE (usa índice), agrupa em Python | 16ms |
_batch_search_triples | ORDER BY + LIMIT 200, mapeia em Python | 138ms |
_semantic_search_relationships | ORDER BY direto, remove HAVING | 105ms |
_detect_entities_in_query | Uma query com IN() em vez de N queries | 102ms |
_batch_search_segments | ORDER BY + LIMIT 300, agrupa em Python | 184ms |
3.3 Resultado de Performance
ANTES: 72,728ms (profiling inicial)
DEPOIS: 855ms (profiling final)
Melhoria: -98.8%
4. Correções de Funcionalidade
4.1 S_segment Fallback
Problema: Documentos sem segmentos processados recebiam S_segment=0, perdendo 30% do score.
Solução: Fallback para S_doc quando S_segment=0:
S_segment = segment_scores.get(workflow_id, 0.0)
if S_segment == 0.0 and S_doc > 0:
S_segment = S_doc # Fallback
4.2 S_ent Diluição
Problema: Entidades semânticas/relacionamentos diluíam o denominador de S_ent.
Solução: Calcular S_ent baseado apenas em entidades com match exato:
exact_entities = [e for e in query_entities if e.get('source') != 'semantic']
S_ent = len(matched_entities) / len(exact_entities)
5. Validação
5.1 Query Principal
Query: "Diretor do MAC na década de 70"
| Rank | Documento | Score | Observação |
|---|---|---|---|
| 1 | FMAC_USP_0014_003_carta_oficio_138_11031978.jpg | 0.59 | Carta de Walter Zanini (MAC) |
| 2 | FMAC_USP_0054_001_Carta_Zanini_09011969.jpg | 0.59 | Carta de Zanini sobre Bienal |
| 3 | FMAC_USP_0014_003_report_1p.jpg | 0.55 | Report do MAC-USP |
5.2 Bateria de Testes
| Query | Tempo | Status |
|---|---|---|
| Diretor do MAC na década de 70 | 843ms | ✅ |
| Walter Zanini | 1188ms | ✅ |
| Bienal de São Paulo | 1081ms | ✅ |
| correspondência sobre exposição de arte contemporânea | 1534ms | ⚠️ |
| documento de 1970 | 2583ms | ✅ |
| Julio Plaza artista | 1813ms | ✅ |
Taxa de Aprovação: 83% (5/6 queries)
6. Arquivos Modificados
6.1 Core
| Arquivo | Alterações |
|---|---|
motorRag/services/tenant_search_engine.py | Multi-Signal v2, Entity Boosting, otimizações |
6.2 Funções Modificadas
search_documents_v2()- Orquestração dos 5 sinais_detect_entities_in_query()- Query única com IN()_semantic_search_entities()- ORDER BY com índice vetorial_semantic_search_relationships_from_triples()- Otimização de query_batch_search_triples()- ORDER BY + mapeamento Python_batch_search_segments()- ORDER BY + mapeamento Python_calculate_multi_signal_score_v2()- Fallbacks S_segment e S_ent_get_entity_documents()- Nova função para Entity Boosting_fetch_documents_by_ids()- Nova função para Entity Boosting
6.3 Scripts de Teste
| Script | Propósito |
|---|---|
test_multisignal_search.py | Teste principal da query MAC |
test_profiling.py | Profiling de performance |
test_robustness.py | Validação com múltiplas queries |
test_entity_boosting.py | Diagnóstico do Entity Boosting |
test_mac_scores.py | Debug de scores MAC |
test_sent_debug.py | Debug de S_ent |
7. Índices Vetoriais Utilizados
| Índice | Tabela | Registros | Latência Média |
|---|---|---|---|
idx_semantic_vector | clio_entidades | 97,335 | ~100ms |
idx_relation_vec | clio_relacoes | 31,649 | ~50ms |
idx_triple_vec | clio_triples | 31,649 | ~100ms |
idx_ocr_vec | clio_ocr | 16,431 | ~50ms |
idx_segment_vec | clio_ocr_segments | 13,969 | ~180ms |
8. Próximos Passos
- Testar no Frontend - Validar integração via interface Vue.js
- Monitoramento - Adicionar métricas de latência no PM2
- Cache de Embeddings - Considerar cache Redis para queries frequentes
- Ajuste de Pesos - Fine-tuning baseado em feedback de usuários
9. Integração Frontend (NOVA)
9.1 Arquitetura de Integração
Frontend Vue.js Node.js Backend Motor RAG
┌─────────────────┐ ┌─────────────────┐ ┌─────────────┐
│ SearchSection │ POST │ /api/fregerag/ │ POST │ /api/ │
│ .vue │ ──────────► │ search_v2 │ ─────────►│ fregerag/ │
│ │ │ │ │ search_v2 │
│ fregerag.ts │◄────────────│ (proxy) │◄──────────│ │
│ searchV2() │ JSON │ │ JSON │ │
└─────────────────┘ └─────────────────┘ └─────────────┘
9.2 Arquivos Modificados
| Arquivo | Descrição |
|---|---|
Clio/node/backend/routes/ai/fregeRAGRoute.js | Novo endpoint /search_v2 |
Clio/iface-backend-vuejs/src/api/fregerag.ts | searchEntitiesV2() + interfaces TypeScript |
Clio/iface-backend-vuejs/src/views/ai/fregerag/components/SearchSection.vue | Toggle v1/v2 + UI para breakdown |
9.3 Validação Frontend (09/01/2026 04:01)
Logs do Node.js confirmam operação correta:
🔍 [v2] Busca: "quem era o diretor do MAC USP nos anos 1970" | Tenant: GeopoliticasVector
✅ [v2] FastAPI [GeopoliticasVector] retornou: 20 docs, 11 entidades detectadas na query
🔍 [v2] Busca: "cor como linguagem exposição" | Tenant: GeopoliticasVector
✅ [v2] FastAPI [GeopoliticasVector] retornou: 20 docs, 8 entidades detectadas na query
🔍 [v2] Busca: "Quando foi a bienal que norte americanos boicotaram o brasil" | Tenant: GeopoliticasVector
✅ [v2] FastAPI [GeopoliticasVector] retornou: 20 docs, 10 entidades detectadas na query
9.4 Funcionalidades da UI v2
- Toggle v1/v2: Usuário pode escolher entre busca legacy e Multi-Signal
- Threshold ajustável: Slider de 0.10 a 0.50
- Top K configurável: 10, 20 ou 50 resultados
- Score Breakdown: Visualização dos 5 sinais (S_doc, S_seg, S_ent, S_tri, S_txt)
- Entidades detectadas: Badge mostrando entidades encontradas na query
10. Dependências
- MariaDB 11.8.5 com suporte a VECTOR(768)
- Python 3.12
- sentence-transformers (paraphrase-multilingual-mpnet-base-v2)
- mysql-connector-python
- FastAPI
11. Comandos Úteis
# Testar busca Multi-Signal
cd /home/arboreolab/estudos/1_funcionais/fregeRAG_v1
source /home/arboreolab/estudos/.venv/bin/activate
python3 test_multisignal_search.py
# Profiling de performance
python3 test_profiling.py
# Validação de robustez
python3 test_robustness.py
# Reiniciar Motor RAG
pm2 restart motor-rag
# Reiniciar Node.js Backend
pm2 restart node-backend-Arboreolab
Assinatura: Engenheiro de Software Sênior ArboreoLab
Revisão: v1.1 (Integração Frontend)
Status: ✅ PRODUÇÃO