Backup #752
| ID | 752 |
| Dateipfad | /var/www/dev.campus.systemische-tools.de/src/Infrastructure/AI/ContentQualityValidator.php |
| Version | 1 |
| Typ |
modified |
| Größe | 3.8 KB |
| Hash | ad80c333aa1d2c4af1699475d785d31b1fda763f672892edd262c5f89b49e35c |
| Datum | 2025-12-23 08:00:15 |
| Geändert von | claude-code-hook |
| Grund | Claude 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
← Zurück zur Übersicht