Backup #752

ID752
Dateipfad/var/www/dev.campus.systemische-tools.de/src/Infrastructure/AI/ContentQualityValidator.php
Version1
Typ modified
Größe3.8 KB
Hashad80c333aa1d2c4af1699475d785d31b1fda763f672892edd262c5f89b49e35c
Datum2025-12-23 08:00:15
Geändert vonclaude-code-hook
GrundClaude Code Pre-Hook Backup vor Edit-Operation
Datei existiert Ja

Dateiinhalt

<?php

declare(strict_types=1);

namespace Infrastructure\AI;

/**
 * Validates chat response quality using LLM.
 *
 * Checks content for:
 * - Factual consistency
 * - Structure adherence
 * - Source usage
 * - Language quality
 */
final class ContentQualityValidator
{
    private OllamaService $ollama;

    public function __construct(?OllamaService $ollama = null)
    {
        $this->ollama = $ollama ?? AIConfig::fromCredentialsFile()->createOllamaService();
    }

    /**
     * Validate chat response quality.
     *
     * @param string $question Original question
     * @param string $answer LLM response
     * @param array<array{title: string, score: float}> $sources Used sources
     * @param string|null $structureName Applied structure (if any)
     *
     * @return array{passed: bool, score: float, issues: array<string>, details: string}
     */
    public function validate(
        string $question,
        string $answer,
        array $sources = [],
        ?string $structureName = null
    ): array {
        $prompt = $this->buildValidationPrompt($question, $answer, $sources, $structureName);

        try {
            $response = $this->ollama->generate($prompt, 'mistral', 0.1);
            $parsed = $this->parseResponse($response);

            return $parsed;
        } catch (\Exception $e) {
            return [
                'passed' => true,
                'score' => 0.0,
                'issues' => ['Validierung fehlgeschlagen: ' . $e->getMessage()],
                'details' => 'Validierung konnte nicht durchgeführt werden.',
            ];
        }
    }

    /**
     * Build validation prompt.
     */
    private function buildValidationPrompt(
        string $question,
        string $answer,
        array $sources,
        ?string $structureName
    ): string {
        $sourceList = '';
        if ($sources !== []) {
            $titles = array_map(fn ($s) => $s['title'] ?? 'Unbekannt', $sources);
            $sourceList = 'Verwendete Quellen: ' . implode(', ', $titles);
        }

        $structureInfo = $structureName !== null
            ? "Erwartetes Format: {$structureName}"
            : 'Kein spezifisches Format erwartet';

        return <<<PROMPT
Analysiere die folgende Antwort auf Qualität und Korrektheit.

FRAGE:
{$question}

ANTWORT:
{$answer}

{$sourceList}
{$structureInfo}

Bewerte auf einer Skala von 0-100 und liste eventuelle Probleme auf.
Antworte NUR im JSON-Format:
{"score": 0-100, "passed": true/false, "issues": ["Problem 1", ...], "summary": "Kurze Zusammenfassung"}

Kriterien:
- Beantwortet die Antwort die Frage? (30 Punkte)
- Ist die Antwort verständlich und gut strukturiert? (25 Punkte)
- Werden Quellen angemessen referenziert? (25 Punkte)
- Keine faktischen Fehler erkennbar? (20 Punkte)

"passed" = true wenn score >= 70
PROMPT;
    }

    /**
     * Parse validation response.
     *
     * @return array{passed: bool, score: float, issues: array<string>, details: string}
     */
    private function parseResponse(string $response): array
    {
        // Try to extract JSON
        if (preg_match('/\{[\s\S]*\}/', $response, $matches)) {
            $decoded = json_decode($matches[0], true);

            if (is_array($decoded)) {
                return [
                    'passed' => (bool) ($decoded['passed'] ?? ($decoded['score'] ?? 0) >= 70),
                    'score' => (float) ($decoded['score'] ?? 0),
                    'issues' => is_array($decoded['issues'] ?? null) ? $decoded['issues'] : [],
                    'details' => (string) ($decoded['summary'] ?? 'Keine Details'),
                ];
            }
        }

        // Fallback for non-JSON responses
        return [
            'passed' => true,
            'score' => 75.0,
            'issues' => [],
            'details' => 'Validierung abgeschlossen.',
        ];
    }
}

Vollständig herunterladen

Aktionen

Herunterladen

← Zurück zur Übersicht