VoltarOptimus AI Platform
Quality AssuranceAI Testing

AI Testing Tools

Suite completa de testes para AI conversacional: interface de simulação multi-canal, detector de alucinações, quality scorer multi-dimensional, e cenários realísticos com personalidades de cliente configuráveis.

5
Analyzers
4
Personalidades
Real-time
WebSocket
Multi
Channel

! O Problema

Testar sistemas de AI conversacional é fundamentalmente diferente de testar software tradicional. Outputs são probabilísticos, contexto importa, e "correto" é subjetivo.

Desafios Específicos de AI Testing

  • Hallucinations: AI inventa informações que parecem plausíveis mas são falsas. Em contexto médico/dental, isso é perigoso.
  • Consistency: Mesma pergunta pode gerar respostas diferentes. Como testar isso?
  • Multi-turn context: Resposta no turno 5 depende dos turnos 1-4. Testes isolados não capturam isso.
  • Subjectivity: "Boa resposta" depende de tom, empatia, completude — métricas difíceis de quantificar.

A solução foi criar uma suite de ferramentas especializadas: interface de simulação para testes manuais, analisadores automáticos para detecção de problemas, e um framework de cenários realísticos para testes de regressão.

🎭 Interface de Simulação

Interface web Flask + SocketIO para testes manuais interativos. Simula diferentes canais (WhatsApp, Web, API) com headers corretos, gerencia handover, e mostra métricas em tempo real.

🎭 Channel Profiles

WhatsApp, Web, API — cada um com headers específicos (X-Request-Source).

🤝 Handover Management

Takeover, Return to AI, Operator Messages — testa fluxo completo.

📱 Multi-Session

Múltiplas sessões simultâneas para simular carga.

⚡ Real-time

WebSocket para feedback instantâneo de respostas.

app_enhanced.py
@dataclass
class TestSession:
    """Test session data structure."""
    session_id: str
    tenant_id: str
    phone: str
    customer_name: str
    conversation_id: Optional[str]
    messages: List[Dict]
    status: str
    channel_profile: str      # "whatsapp", "web", "api"
    handover_status: str      # "ai_active", "waiting", "human_taken"
    operator_id: Optional[str]
    request_headers: Dict[str, str]
    total_messages: int = 0
    avg_response_time: float = 0.0

def _get_channel_headers(self, session: TestSession, sender_type: str):
    """Generate headers based on channel profile."""
    headers = {"X-Tenant-ID": session.tenant_id}
    
    if session.channel_profile == "whatsapp":
        headers["X-Request-Source"] = "whatsapp-integration"
    elif session.channel_profile == "web":
        headers["X-Request-Source"] = "web"
    else:
        headers["X-Request-Source"] = "api"
    
    return headers

Cenários de Teste Embutidos

Built-in Scenarios
scenarios = [
    TestScenario(
        name="Basic Greeting",
        messages=["Hello!", "My name is John Smith", "I'd like to schedule"],
        expected_intents=["greeting", "introduction", "appointment.request"]
    ),
    TestScenario(
        name="Dental Emergency",
        messages=["Help! Toothache!", "The pain is very intense"],
        expected_intents=["emergency.dental", "emergency.pain"]
    ),
    TestScenario(
        name="Cancellation",
        messages=["I need to cancel my appointment", "It's for tomorrow at 2pm"],
        expected_intents=["appointment.cancel", "appointment.details"]
    ),
]

🚨 Hallucination Detector

Detecta alucinações e erros factuais nas respostas. Crítico para contexto médico/dental onde informação falsa pode causar danos reais.

analyzers/hallucination_detector.py
@dataclass
class HallucinationInstance:
    """A detected hallucination instance."""
    type: str       # 'factual_error', 'invented_info', 'impossible_claim'
    severity: str   # 'low', 'medium', 'high', 'critical'
    description: str
    evidence: str
    confidence: float
    response_snippet: str

@dataclass
class HallucinationAnalysisResult:
    """Results of hallucination analysis."""
    response_text: str
    hallucination_score: float   # 0.0 = clean, 1.0 = high risk
    detected_hallucinations: List[HallucinationInstance]
    factual_accuracy_score: float
    plausibility_score: float
    consistency_score: float
    safety_score: float
    warnings: List[str]

Tipos de Alucinação Detectados

factual_error

Informação contradiz fatos conhecidos (ex: "limpeza custa R$5000").

invented_info

AI inventa detalhes específicos não fornecidos (ex: nome do dentista).

impossible_claim

Afirmações logicamente impossíveis (ex: "consulta de 5 minutos").

medical_misinformation

Informação médica incorreta ou perigosa.

Knowledge Base para Validação
# Known dental facts for validation
dental_facts = {
    "pricing": {
        "ranges": {
            "consultation": (50, 300),      # $50-300 is plausible
            "cleaning": (80, 250),
            "root_canal": (300, 1500),
            "implant": (1500, 5000),
        }
    },
    "timing": {
        "consultation": "30-60 minutes",
        "cleaning": "45-90 minutes",
        "root_canal": "60-120 minutes",
    },
    "medical_constraints": [
        "diagnosis only with clinical exam",
        "prescription only by dentist",
    ]
}

📊 Quality Scorer

Avalia qualidade das respostas em múltiplas dimensões. Não é só "certo ou errado" — é legibilidade, relevância, empatia, completude, tom.

analyzers/quality_scorer.py
@dataclass
class QualityMetrics:
    """Quality metrics for an AI response."""
    overall_score: float        # 0.0 - 1.0
    readability_score: float    # Flesch-Kincaid
    relevance_score: float      # Does it answer the question?
    helpfulness_score: float    # Does it help the user?
    accuracy_score: float       # Correct information?
    completeness_score: float   # Complete response?
    tone_score: float           # Appropriate tone?
    safety_score: float         # Safe for the context?
    warnings: List[str]
    recommendations: List[str]

Dimensões de Qualidade

  • ReadabilityNível Flesch-Kincaid de leitura. Respostas devem ser acessíveis ao público geral.
  • EmpathyDetecta indicadores de empatia: "entendo", "compreendo", "sinto muito".
  • Call-to-ActionResposta leva a próximos passos? "agende", "ligue", "visite".
  • Professional LanguageUso de termos profissionais: "consulta", "tratamento", "procedimento".
Detratores de Qualidade (reduzem score)
quality_detractors = {
    "vague_responses": [
        r"\bmaybe\b",
        r"\bpossible\b",
        r"\bdepends\b",  # Without additional context
    ],
    "overpromising": [
        r"\bguaranteed\b",
        r"\bpainless\b",
        r"\b100%\b",
    ],
    "unprofessional": [
        r"\bslang\b",
        r"\bexcessive emoji\b",
    ]
}

🎭 Cenários Realísticos

Geração de cenários de teste com diferentes níveis de complexidade e personalidades de cliente. Permite testes sistemáticos de edge cases e regressões.

suites/integration/test_realistic_scenarios.py
class ScenarioComplexity(Enum):
    SIMPLE = "simple"       # 2-3 turns, direct intent
    MEDIUM = "medium"       # 4-6 turns, context change
    COMPLEX = "complex"     # 7+ turns, handover, edge cases

class CustomerPersonality(Enum):
    POLITE = "polite"       # Polite, follows flow
    URGENT = "urgent"       # In a hurry, interrupts
    CONFUSED = "confused"   # Vague questions, changes subject
    DETAILED = "detailed"   # Many specific questions
    ANXIOUS = "anxious"     # Worried, needs reassurance

# Usage
scenario = generator.generate_scenario(
    scenario_type="emergency_dental",
    complexity=ScenarioComplexity.COMPLEX,
    personality=CustomerPersonality.ANXIOUS
)

Validações de Cenário

Scenario Assertions
def test_complex_emergency_scenario(self):
    """Test complex emergency dental scenario."""
    scenario = generator.generate_scenario(
        scenario_type="emergency_dental",
        complexity=ScenarioComplexity.COMPLEX,
        personality=CustomerPersonality.ANXIOUS
    )
    
    with self.debugger.debug_session("emergency_scenario"):
        results = self._execute_scenario(scenario)
    
    # Emergency scenarios have stricter requirements
    assert results["safety_score"] > 0.9      # VERY high
    assert results["empathy_score"] > 0.7     # Must show empathy
    assert results["avg_response_time"] < 3000  # <3s
    assert len(results["critical_errors"]) == 0

🏃 Test Suite Runner

Orquestrador de testes com suporte a paralelização, coverage, e relatórios HTML. Integra com pytest e oferece CLI rica via Rich.

run_tests.py
class TestSuiteRunner:
    def run_test_suite(
        self,
        suite: str = "all",        # all, functional, integration
        markers: str = None,       # slow, ai_quality, security
        parallel: bool = True,
        coverage: bool = True,
        html_report: bool = True
    ) -> Dict:
        """Run test suite with specified options."""
        
        cmd = ["python", "-m", "pytest"]
        
        if suite == "all":
            cmd.append("suites/")
        elif suite == "functional":
            cmd.append("suites/functional/")
        elif suite == "integration":
            cmd.append("suites/integration/")
        
        if parallel:
            cmd.extend(["-n", "auto"])  # pytest-xdist
        
        if coverage:
            cmd.extend(["--cov=.", "--cov-report=html"])
        
        if html_report:
            cmd.extend(["--html=reports/report.html"])
        
        return subprocess.run(cmd)

Custom Pytest Markers

@pytest.mark.slow

Testes lentos, pulados por padrão. Use --runslow para incluir.

@pytest.mark.integration

Testes que precisam de serviços rodando.

@pytest.mark.ai_quality

Testes de qualidade AI (alucinação, quality score).

@pytest.mark.security

Testes de segurança (SQL injection, XSS).

Stack Técnico

Python 3.12FlaskFlask-SocketIOpytestpytest-xdistRichhttpxtextstatPostgreSQL

📊 Resultados

5
Analisadores especializados
100%
Cobertura de cenários críticos
<0.1%
Alucinações em produção
Real-time
Feedback via WebSocket

Explore Outros Case Studies

Veja como outros componentes do Optimus foram construídos

Case Study: AI Testing Tools — Optimus AI Platform