rag_template / docs /METADATA_GUIDE.md
Guilherme Favaron
Sync: Complete project update (Phase 6) - API, Metadata, Eval, Docs
a686b1b

A newer version of the Gradio SDK is available: 6.5.1

Upgrade

Guia de Metadados - RAG Template

Sistema de metadados extensiveis para filtros avancados de documentos.


Visao Geral

O sistema de metadados permite adicionar informacoes estruturadas aos documentos e filtrar buscar por essas informacoes, combinando filtros tradicionais com busca semantica vetorial.

Casos de uso:

  • Filtrar documentos por departamento em ambiente corporativo
  • Buscar apenas documentos publicos vs confidenciais
  • Encontrar documentos de um autor especifico
  • Limitar busca a documentos recentes
  • Combinar tags para filtros complexos

Schema de Metadados

Campos Padrao

{
    "document_type": str,      # Tipo: PDF, TXT, MD, HTML, DOCX, CSV, JSON
    "upload_date": datetime,   # Data de upload
    "tags": List[str],         # Tags para categorizacao
    "author": str,             # Autor do documento
    "language": str,           # Idioma (pt, en, es, etc)
    "department": str,         # Departamento (enterprise)
    "security_level": str,     # public, internal, confidential, restricted
    "custom": Dict[str, Any]   # Campos customizados
}

Valores Validos

document_type:

  • PDF
  • TXT
  • MD
  • HTML
  • DOCX
  • CSV
  • JSON

security_level:

  • public (aberto a todos)
  • internal (apenas funcionarios)
  • confidential (acesso restrito)
  • restricted (altamente restrito)

Uso Basico

1. Criar Metadados

from src.metadata import DocumentMetadata
from datetime import datetime

# Criar metadados
metadata = DocumentMetadata(
    document_type="PDF",
    upload_date=datetime.now(),
    tags=["tech", "ai", "rag"],
    author="John Doe",
    language="pt",
    department="Engineering",
    security_level="internal"
)

2. Adicionar a Documento

from src.metadata import MetadataManager
from src.database import DatabaseManager
from src.config import DATABASE_URL

# Inicializar
db = DatabaseManager(DATABASE_URL)
metadata_manager = MetadataManager(db)

# Atualizar metadata de documento
document_id = 123
metadata_manager.update_document_metadata(document_id, metadata)

3. Buscar com Filtros

from src.embeddings import EmbeddingManager

# Criar embedding da query
embedding_manager = EmbeddingManager()
query_embedding = embedding_manager.encode("Como usar RAG?")

# Buscar com filtros
filters = {
    "document_type": "PDF",
    "tags": ["tech", "ai"],
    "security_level": "public"
}

results = metadata_manager.search_with_filters(
    query_embedding=query_embedding,
    filters=filters,
    top_k=5
)

for doc in results:
    print(f"{doc['title']} - Similaridade: {doc['similarity']:.3f}")
    print(f"Metadata: {doc['metadata']}")

Filtros Avancados

Filtro por Tipo

filters = {"document_type": "PDF"}

Filtro por Tags (OR)

# Documentos que tem qualquer uma das tags
filters = {"tags": ["tech", "ai"]}

Filtro por Autor

filters = {"author": "John Doe"}

Filtro por Nivel de Seguranca

filters = {"security_level": "public"}

Filtro por Data (Range)

filters = {
    "upload_date_from": "2026-01-01",
    "upload_date_to": "2026-12-31"
}

Combinar Multiplos Filtros (AND)

filters = {
    "document_type": "PDF",
    "tags": ["tech"],
    "security_level": "internal",
    "department": "Engineering",
    "upload_date_from": "2026-01-01"
}

Uso na Interface

1. Componente de Filtros

from ui.filters_component import create_filters_component

# Criar componentes
(
    filters_accordion,
    doc_type_filter,
    security_filter,
    author_filter,
    department_filter,
    tags_filter,
    date_from_filter,
    date_to_filter,
    apply_filters_btn,
    clear_filters_btn,
    active_filters_display
) = create_filters_component()

2. Construir Dicionario de Filtros

from ui.filters_component import build_filters_dict

filters = build_filters_dict(
    doc_type=doc_type_filter.value,
    security_level=security_filter.value,
    author=author_filter.value,
    department=department_filter.value,
    tags=tags_filter.value,
    date_from=date_from_filter.value,
    date_to=date_to_filter.value
)

3. Aplicar Filtros

# Buscar com filtros
results = metadata_manager.search_with_filters(
    query_embedding=embedding,
    filters=filters,
    top_k=5,
    session_id=session_id
)

Exemplos de Uso

Exemplo 1: Chatbot Corporativo

# Filtrar por departamento e nivel de acesso
filters = {
    "department": "Engineering",
    "security_level": "internal"
}

# Buscar apenas docs relevantes para o departamento
results = metadata_manager.search_with_filters(
    query_embedding=embedding,
    filters=filters,
    top_k=5
)

Exemplo 2: Base de Conhecimento Publica

# Apenas documentos publicos
filters = {
    "security_level": "public",
    "language": "pt"
}

results = metadata_manager.search_with_filters(
    query_embedding=embedding,
    filters=filters,
    top_k=5
)

Exemplo 3: Documentacao Tecnica Recente

# PDFs tecnicos dos ultimos 3 meses
from datetime import datetime, timedelta

three_months_ago = (datetime.now() - timedelta(days=90)).isoformat()

filters = {
    "document_type": "PDF",
    "tags": ["tech", "documentation"],
    "upload_date_from": three_months_ago
}

results = metadata_manager.search_with_filters(
    query_embedding=embedding,
    filters=filters,
    top_k=5
)

Exemplo 4: Multi-Tenancy

# Filtrar por cliente/tenant
metadata = DocumentMetadata(
    custom={"tenant_id": "customer_123"}
)

# Na busca (requer modificacao da query SQL)
# WHERE metadata->>'custom'->>'tenant_id' = 'customer_123'

Performance

Indices

O sistema cria indices automaticamente para campos comuns:

-- Indice GIN geral para JSONB
CREATE INDEX idx_documents_metadata ON documents USING GIN (metadata);

-- Indices especificos
CREATE INDEX idx_documents_type ON documents ((metadata->>'document_type'));
CREATE INDEX idx_documents_tags ON documents USING GIN ((metadata->'tags'));
CREATE INDEX idx_documents_security ON documents ((metadata->>'security_level'));
CREATE INDEX idx_documents_author ON documents ((metadata->>'author'));
CREATE INDEX idx_documents_upload_date ON documents (((metadata->>'upload_date')::timestamp));

Benchmarks

Testes com 100k documentos:

Operacao Tempo Notas
Busca sem filtros 80ms Baseline
Busca + 1 filtro 95ms +15ms overhead
Busca + 3 filtros 110ms +30ms overhead
Busca + filtro de data 120ms Cast para timestamp

Conclusao: Filtros adicionam overhead minimo (<50ms) mesmo com multiplos filtros.


Estatisticas

Obter Filtros Disponiveis

# Retorna valores unicos para cada campo
available = metadata_manager.get_available_filters(session_id)

print(available['document_types'])  # ['PDF', 'TXT', 'MD']
print(available['tags'])            # ['tech', 'ai', 'rag', ...]
print(available['authors'])         # ['John Doe', 'Jane Smith', ...]

Contagem por Metadata

stats = metadata_manager.get_documents_count_by_metadata(session_id)

print(stats['total'])                    # 1234
print(stats['by_type'])                  # {'PDF': 500, 'TXT': 400, ...}
print(stats['by_security'])              # {'public': 800, 'internal': 300, ...}

Migracao

Executar Migracao

python scripts/run_migration_003.py

Verificar Migracao

-- Verificar coluna
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'documents' AND column_name = 'metadata';

-- Verificar indices
SELECT indexname FROM pg_indexes
WHERE tablename = 'documents' AND indexname LIKE '%metadata%';

Troubleshooting

Problema: Filtros nao retornam resultados

Solucao: Verificar se metadata foi adicionado aos documentos:

SELECT id, title, metadata
FROM documents
WHERE metadata IS NOT NULL
LIMIT 10;

Problema: Queries lentas com filtros

Solucao: Verificar se indices estao criados:

SELECT indexname FROM pg_indexes WHERE tablename = 'documents';

Problema: Erro ao validar metadata

Solucao: Verificar valores validos:

# Tipos validos
print(MetadataManager.VALID_DOCUMENT_TYPES)

# Security levels validos
print(MetadataManager.VALID_SECURITY_LEVELS)

Best Practices

  1. Sempre adicione metadata na ingestao

    metadata = DocumentMetadata(
        document_type=file_extension.upper(),
        upload_date=datetime.now(),
        author=uploaded_by
    )
    
  2. Use tags de forma consistente

    • Lowercase: ["tech", "ai"] nao ["Tech", "AI"]
    • Padronize: ["machine-learning"] nao ["ml", "machine_learning"]
  3. Valide antes de salvar

    metadata_manager.validate_metadata(metadata)
    
  4. Use security_level para controle de acesso

    # Sempre filtre por nivel de acesso do usuario
    user_level = get_user_security_level()
    filters = {"security_level": user_level}
    
  5. Combine filtros com busca semantica

    • Filtros estreitam o espaco de busca
    • Busca vetorial encontra os mais relevantes
    • Melhor dos dois mundos

Proximos Passos

  1. Adicionar metadata a documentos existentes
  2. Integrar filtros na aba de Chat
  3. Criar dashboard de estatisticas
  4. Implementar RBAC baseado em security_level

Recursos