ChatRAG/Settings/VectorDatabaseSettings.cs
2025-06-15 21:34:47 -03:00

494 lines
16 KiB
C#

namespace ChatRAG.Settings
{
// ============================================================================
// 📁 Configuration/VectorDatabaseSettings.cs
// Settings unificados para todos os providers (MongoDB, Qdrant, etc.)
// ============================================================================
namespace ChatRAG.Configuration
{
/// <summary>
/// Configurações principais do sistema de Vector Database
/// </summary>
public class VectorDatabaseSettings
{
/// <summary>
/// Provider ativo (MongoDB, Qdrant, Pinecone, etc.)
/// </summary>
public string Provider { get; set; } = "MongoDB";
/// <summary>
/// Configurações específicas do MongoDB
/// </summary>
public MongoDbSettings MongoDB { get; set; } = new();
/// <summary>
/// Configurações específicas do Qdrant
/// </summary>
public QdrantSettings Qdrant { get; set; } = new();
/// <summary>
/// Configurações globais de embedding
/// </summary>
public EmbeddingSettings Embedding { get; set; } = new();
/// <summary>
/// Configurações de performance e cache
/// </summary>
public PerformanceSettings Performance { get; set; } = new();
/// <summary>
/// Configurações de logging e monitoramento
/// </summary>
public MonitoringSettings Monitoring { get; set; } = new();
/// <summary>
/// Valida se as configurações estão corretas
/// </summary>
public bool IsValid()
{
if (string.IsNullOrWhiteSpace(Provider))
return false;
return Provider.ToLower() switch
{
"mongodb" => MongoDB.IsValid(),
"qdrant" => Qdrant.IsValid(),
_ => false
};
}
/// <summary>
/// Retorna erros de validação
/// </summary>
public List<string> GetValidationErrors()
{
var errors = new List<string>();
if (string.IsNullOrWhiteSpace(Provider))
errors.Add("Provider é obrigatório");
switch (Provider.ToLower())
{
case "mongodb":
errors.AddRange(MongoDB.GetValidationErrors());
break;
case "qdrant":
errors.AddRange(Qdrant.GetValidationErrors());
break;
default:
errors.Add($"Provider '{Provider}' não é suportado");
break;
}
errors.AddRange(Embedding.GetValidationErrors());
return errors;
}
}
/// <summary>
/// Configurações específicas do MongoDB
/// </summary>
public class MongoDbSettings
{
/// <summary>
/// String de conexão do MongoDB
/// </summary>
public string ConnectionString { get; set; } = string.Empty;
/// <summary>
/// Nome do banco de dados
/// </summary>
public string DatabaseName { get; set; } = string.Empty;
/// <summary>
/// Nome da coleção de textos/documentos
/// </summary>
public string TextCollectionName { get; set; } = "texts";
/// <summary>
/// Nome da coleção de projetos
/// </summary>
public string ProjectCollectionName { get; set; } = "projects";
/// <summary>
/// Nome da coleção de dados de usuário
/// </summary>
public string UserDataName { get; set; } = "users";
/// <summary>
/// Timeout de conexão em segundos
/// </summary>
public int ConnectionTimeoutSeconds { get; set; } = 30;
/// <summary>
/// Timeout de operação em segundos
/// </summary>
public int OperationTimeoutSeconds { get; set; } = 60;
/// <summary>
/// Tamanho máximo do pool de conexões
/// </summary>
public int MaxConnectionPoolSize { get; set; } = 100;
/// <summary>
/// Habilitar índices de busca vetorial
/// </summary>
public bool EnableVectorSearch { get; set; } = true;
/// <summary>
/// Configurações específicas do Atlas Search
/// </summary>
public MongoAtlasSearchSettings AtlasSearch { get; set; } = new();
public bool IsValid()
{
return !string.IsNullOrWhiteSpace(ConnectionString) &&
!string.IsNullOrWhiteSpace(DatabaseName) &&
!string.IsNullOrWhiteSpace(TextCollectionName);
}
public List<string> GetValidationErrors()
{
var errors = new List<string>();
if (string.IsNullOrWhiteSpace(ConnectionString))
errors.Add("MongoDB ConnectionString é obrigatória");
if (string.IsNullOrWhiteSpace(DatabaseName))
errors.Add("MongoDB DatabaseName é obrigatório");
if (string.IsNullOrWhiteSpace(TextCollectionName))
errors.Add("MongoDB TextCollectionName é obrigatório");
if (ConnectionTimeoutSeconds <= 0)
errors.Add("MongoDB ConnectionTimeoutSeconds deve ser maior que 0");
return errors;
}
}
/// <summary>
/// Configurações do MongoDB Atlas Search
/// </summary>
public class MongoAtlasSearchSettings
{
/// <summary>
/// Nome do índice de busca vetorial
/// </summary>
public string VectorIndexName { get; set; } = "vector_index";
/// <summary>
/// Número de candidatos para busca aproximada
/// </summary>
public int NumCandidates { get; set; } = 200;
/// <summary>
/// Limite de resultados do Atlas Search
/// </summary>
public int SearchLimit { get; set; } = 100;
}
/// <summary>
/// Configurações específicas do Qdrant
/// </summary>
public class QdrantSettings
{
/// <summary>
/// Host do servidor Qdrant
/// </summary>
public string Host { get; set; } = "localhost";
/// <summary>
/// Porta do servidor Qdrant (REST API)
/// </summary>
public int Port { get; set; } = 6333;
/// <summary>
/// Porta gRPC (opcional, para performance)
/// </summary>
public int? GrpcPort { get; set; } = 6334;
/// <summary>
/// Chave de API (se autenticação estiver habilitada)
/// </summary>
public string? ApiKey { get; set; }
/// <summary>
/// Usar TLS/SSL
/// </summary>
public bool UseTls { get; set; } = false;
/// <summary>
/// Nome da coleção principal
/// </summary>
public string CollectionName { get; set; } = "documents";
/// <summary>
/// Tamanho do vetor de embedding
/// </summary>
public int VectorSize { get; set; } = 1536; // OpenAI embedding size
/// <summary>
/// Métrica de distância (Cosine, Euclid, Dot, Manhattan)
/// </summary>
public string Distance { get; set; } = "Cosine";
// ========================================
// CONFIGURAÇÕES DE PERFORMANCE
// ========================================
/// <summary>
/// Parâmetro M do algoritmo HNSW (conectividade)
/// Valores típicos: 16-48, maior = melhor recall, mais memória
/// </summary>
public int HnswM { get; set; } = 16;
/// <summary>
/// Parâmetro ef_construct do HNSW (construção do índice)
/// Valores típicos: 100-800, maior = melhor qualidade, mais lento
/// </summary>
public int HnswEfConstruct { get; set; } = 200;
/// <summary>
/// Parâmetro ef do HNSW (busca)
/// Valores típicos: igual ou maior que o número de resultados desejados
/// </summary>
public int HnswEf { get; set; } = 128;
/// <summary>
/// Armazenar vetores em disco (economiza RAM)
/// </summary>
public bool OnDisk { get; set; } = false;
/// <summary>
/// Fator de replicação (para clusters)
/// </summary>
public int ReplicationFactor { get; set; } = 1;
/// <summary>
/// Número de shards (para distribuição)
/// </summary>
public int ShardNumber { get; set; } = 1;
/// <summary>
/// Usar quantização para reduzir uso de memória
/// </summary>
public bool UseQuantization { get; set; } = false;
/// <summary>
/// Configurações de quantização
/// </summary>
public QuantizationSettings Quantization { get; set; } = new();
/// <summary>
/// Timeout de conexão em segundos
/// </summary>
public int ConnectionTimeoutSeconds { get; set; } = 30;
/// <summary>
/// Timeout de operação em segundos
/// </summary>
public int OperationTimeoutSeconds { get; set; } = 60;
/// <summary>
/// URL completa calculada
/// </summary>
public string GetConnectionUrl()
{
var protocol = UseTls ? "https" : "http";
return $"{protocol}://{Host}:{Port}";
}
public bool IsValid()
{
return !string.IsNullOrWhiteSpace(Host) &&
Port > 0 &&
!string.IsNullOrWhiteSpace(CollectionName) &&
VectorSize > 0;
}
public List<string> GetValidationErrors()
{
var errors = new List<string>();
if (string.IsNullOrWhiteSpace(Host))
errors.Add("Qdrant Host é obrigatório");
if (Port <= 0)
errors.Add("Qdrant Port deve ser maior que 0");
if (string.IsNullOrWhiteSpace(CollectionName))
errors.Add("Qdrant CollectionName é obrigatório");
if (VectorSize <= 0)
errors.Add("Qdrant VectorSize deve ser maior que 0");
if (HnswM <= 0)
errors.Add("Qdrant HnswM deve ser maior que 0");
if (HnswEfConstruct <= 0)
errors.Add("Qdrant HnswEfConstruct deve ser maior que 0");
var validDistances = new[] { "Cosine", "Euclid", "Dot", "Manhattan" };
if (!validDistances.Contains(Distance))
errors.Add($"Qdrant Distance deve ser um de: {string.Join(", ", validDistances)}");
return errors;
}
}
/// <summary>
/// Configurações de quantização para Qdrant
/// </summary>
public class QuantizationSettings
{
/// <summary>
/// Tipo de quantização (scalar, product, binary)
/// </summary>
public string Type { get; set; } = "scalar";
/// <summary>
/// Quantil para quantização scalar
/// </summary>
public double Quantile { get; set; } = 0.99;
/// <summary>
/// Sempre usar RAM para quantização
/// </summary>
public bool AlwaysRam { get; set; } = false;
}
/// <summary>
/// Configurações globais de embedding
/// </summary>
public class EmbeddingSettings
{
/// <summary>
/// Provider de embedding (OpenAI, Ollama, Azure, etc.)
/// </summary>
public string Provider { get; set; } = "OpenAI";
/// <summary>
/// Modelo de embedding
/// </summary>
public string Model { get; set; } = "text-embedding-ada-002";
/// <summary>
/// Tamanho esperado do embedding
/// </summary>
public int ExpectedSize { get; set; } = 1536;
/// <summary>
/// Batch size para processamento em lote
/// </summary>
public int BatchSize { get; set; } = 100;
/// <summary>
/// Cache de embeddings em memória
/// </summary>
public bool EnableCache { get; set; } = true;
/// <summary>
/// TTL do cache em minutos
/// </summary>
public int CacheTtlMinutes { get; set; } = 60;
public List<string> GetValidationErrors()
{
var errors = new List<string>();
if (ExpectedSize <= 0)
errors.Add("Embedding ExpectedSize deve ser maior que 0");
if (BatchSize <= 0)
errors.Add("Embedding BatchSize deve ser maior que 0");
return errors;
}
}
/// <summary>
/// Configurações de performance e otimização
/// </summary>
public class PerformanceSettings
{
/// <summary>
/// Habilitar paralelização em operações de lote
/// </summary>
public bool EnableParallelization { get; set; } = true;
/// <summary>
/// Número máximo de threads paralelas
/// </summary>
public int MaxParallelism { get; set; } = Environment.ProcessorCount;
/// <summary>
/// Tamanho do batch para operações em lote
/// </summary>
public int BatchSize { get; set; } = 100;
/// <summary>
/// Timeout padrão para operações em segundos
/// </summary>
public int DefaultTimeoutSeconds { get; set; } = 30;
/// <summary>
/// Habilitar retry automático
/// </summary>
public bool EnableRetry { get; set; } = true;
/// <summary>
/// Número máximo de tentativas
/// </summary>
public int MaxRetryAttempts { get; set; } = 3;
/// <summary>
/// Delay entre tentativas em segundos
/// </summary>
public int RetryDelaySeconds { get; set; } = 2;
}
/// <summary>
/// Configurações de monitoramento e logging
/// </summary>
public class MonitoringSettings
{
/// <summary>
/// Habilitar logging detalhado
/// </summary>
public bool EnableDetailedLogging { get; set; } = false;
/// <summary>
/// Logar tempos de operação
/// </summary>
public bool LogOperationTimes { get; set; } = true;
/// <summary>
/// Threshold para log de operações lentas (ms)
/// </summary>
public int SlowOperationThresholdMs { get; set; } = 1000;
/// <summary>
/// Habilitar métricas de performance
/// </summary>
public bool EnableMetrics { get; set; } = true;
/// <summary>
/// Intervalo de coleta de métricas em segundos
/// </summary>
public int MetricsIntervalSeconds { get; set; } = 60;
/// <summary>
/// Habilitar health checks
/// </summary>
public bool EnableHealthChecks { get; set; } = true;
/// <summary>
/// Intervalo de health check em segundos
/// </summary>
public int HealthCheckIntervalSeconds { get; set; } = 30;
}
}
}