36772-vm/ai/LocalAIApi.php
2025-12-08 22:18:04 +00:00

617 lines
24 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// ai/QuestionnaireProcessor.php
// Processes KI-Fit Check questionnaire with AI analysis
require_once __DIR__ . '/LocalAIApi.php';
class QuestionnaireProcessor
{
private array $questionnaireData;
private string $language;
public function __construct(array $questionnaireData, string $language = 'de')
{
$this->questionnaireData = $questionnaireData;
$this->language = $language;
}
/**
* Process the complete questionnaire and generate AI analysis
*/
public function process(): array
{
try {
// Step 1: Generate AI prompt
$prompt = $this->generateAIPrompt();
// Step 2: Call AI service
$aiResponse = $this->callAIService($prompt);
// Step 3: Parse and structure the response
$analysis = $this->parseAIResponse($aiResponse);
// Step 4: Calculate scores and metrics
$analysis['scores'] = $this->calculateScores();
$analysis['metrics'] = $this->calculateMetrics();
$analysis['tools'] = $this->recommendTools();
$analysis['timeline'] = $this->generateTimeline();
return [
'success' => true,
'analysis' => $analysis,
'report_id' => $this->generateReportId(),
'timestamp' => date('Y-m-d H:i:s')
];
} catch (Exception $e) {
return [
'success' => false,
'error' => $e->getMessage(),
'fallback' => $this->generateFallbackAnalysis()
];
}
}
/**
* Generate comprehensive AI prompt based on questionnaire answers
*/
private function generateAIPrompt(): string
{
$answers = $this->questionnaireData;
// System prompt based on language
$systemPrompts = [
'de' => "Du bist ein KI-Beratungsexperte für kleine und mittlere Unternehmen in Deutschland. Analysiere diese KI-Readiness-Bewertung und erstelle eine professionelle, maßgeschneiderte Analyse.",
'en' => "You are an AI consulting expert for small and medium-sized businesses. Analyze this AI readiness assessment and create a professional, tailored analysis.",
'tr' => "Küçük ve orta ölçekli işletmeler için bir AI danışmanlık uzmanısınız. Bu AI hazırlık değerlendirmesini analiz edin ve profesyonel, özelleştirilmiş bir analiz oluşturun."
];
$systemPrompt = $systemPrompts[$this->language] ?? $systemPrompts['de'];
// Build detailed user prompt
$prompt = "Analysiere diese KI-Readiness-Bewertung:\n\n";
// Company Information
$prompt .= "=== UNTERNEHMENSINFORMATIONEN ===\n";
if (!empty($answers['q2'])) {
$prompt .= "Branche: " . $answers['q2'] . "\n";
}
if (!empty($answers['q1'])) {
$sizeMap = [
'1-person' => 'Einzelunternehmer (1 Person)',
'2-5' => 'Kleinstunternehmen (2-5 Mitarbeiter)',
'6-20' => 'Kleinunternehmen (6-20 Mitarbeiter)',
'21-50' => 'Mittelstand (21-50 Mitarbeiter)',
'50plus' => 'Großunternehmen (50+ Mitarbeiter)'
];
$prompt .= "Unternehmensgröße: " . ($sizeMap[$answers['q1']] ?? $answers['q1']) . "\n";
}
// Business Model
if (!empty($answers['q3']) && is_array($answers['q3'])) {
$modelMap = [
'dienstleistung' => 'Dienstleistung',
'handel' => 'Handel',
'coaching' => 'Coaching/Beratung',
'agentur' => 'Agentur',
'ecommerce' => 'E-Commerce',
'produktion' => 'Produktion'
];
$models = array_map(fn($m) => $modelMap[$m] ?? $m, $answers['q3']);
$prompt .= "Geschäftsmodelle: " . implode(', ', $models) . "\n";
}
// Primary Goals
if (!empty($answers['q4'])) {
$goalMap = [
'zeit-sparen' => 'Zeit sparen bei repetitiven Aufgaben',
'kosten-reduzieren' => 'Kosten reduzieren durch Automatisierung',
'wachstum' => 'Wachstum beschleunigen',
'qualität' => 'Qualität verbessern',
'innovation' => 'Innovation vorantreiben'
];
$prompt .= "Primäres KI-Ziel: " . ($goalMap[$answers['q4']] ?? $answers['q4']) . "\n";
}
// AI Importance
if (!empty($answers['q5'])) {
$importance = [
'1' => 'nicht wichtig',
'2' => 'eher unwichtig',
'3' => 'neutral',
'4' => 'wichtig',
'5' => 'sehr wichtig'
];
$prompt .= "KI-Bedeutung: " . ($importance[$answers['q5']] ?? $answers['q5']) . "/5\n";
}
// Time-consuming Tasks
if (!empty($answers['q6']) && is_array($answers['q6'])) {
$taskMap = [
'kundenkommunikation' => 'Kundenkommunikation',
'administrative' => 'Administrative Aufgaben',
'marketing' => 'Marketing/Content',
'buchhaltung' => 'Buchhaltung/Finanzen',
'planung' => 'Planung/Organisation',
'daten' => 'Datenanalyse'
];
$tasks = array_map(fn($t) => $taskMap[$t] ?? $t, $answers['q6']);
$prompt .= "\nZeitintensive Aufgaben:\n- " . implode("\n- ", $tasks) . "\n";
}
// Current Automation
if (!empty($answers['q7'])) {
$prompt .= "\nAktuelle Automatisierung:\n" . $answers['q7'] . "\n";
}
// Weekly Hours on Repetitive Tasks
if (!empty($answers['q8'])) {
$hoursMap = [
'unter-5h' => 'unter 5 Stunden/Woche',
'5-10h' => '5-10 Stunden/Woche',
'11-15h' => '11-15 Stunden/Woche',
'16-20h' => '16-20 Stunden/Woche',
'20plus' => 'über 20 Stunden/Woche'
];
$prompt .= "Repetitive Stunden/Woche: " . ($hoursMap[$answers['q8']] ?? $answers['q8']) . "\n";
}
// Budget
if (!empty($answers['q9'])) {
$budgetMap = [
'unter-50' => 'unter 50€/Monat',
'50-100' => '50-100€/Monat',
'100-300' => '100-300€/Monat',
'300-500' => '300-500€/Monat',
'500plus' => '500€+/Monat'
];
$prompt .= "KI-Budget: " . ($budgetMap[$answers['q9']] ?? $answers['q9']) . "\n";
}
// Technical Affinity
if (!empty($answers['q10'])) {
$affinity = [
'1' => 'sehr schwer',
'2' => 'eher schwer',
'3' => 'neutral',
'4' => 'einfach',
'5' => 'sehr einfach'
];
$prompt .= "Technische Affinität: " . ($affinity[$answers['q10']] ?? $answers['q10']) . "/5\n";
}
// Current AI Tools
if (!empty($answers['q11']) && is_array($answers['q11'])) {
$toolMap = [
'chatgpt' => 'ChatGPT/Sprach-KIs',
'midjourney' => 'Bildgenerierung',
'crm' => 'KI-CRM Tools',
'marketing' => 'KI-Marketing Tools',
'automatisierung' => 'Automatisierungs-Tools',
'keine' => 'Keine KI-Tools'
];
$tools = array_map(fn($t) => $toolMap[$t] ?? $t, $answers['q11']);
$prompt .= "Aktuelle KI-Tools: " . implode(', ', $tools) . "\n";
}
// Biggest Challenge
if (!empty($answers['q12'])) {
$challengeMap = [
'zeit' => 'Zeitmangel',
'wissen' => 'Fehlendes Wissen',
'kosten' => 'Kosten',
'integration' => 'Integration',
'nutzen' => 'Unklarheit über Nutzen'
];
$prompt .= "Größte Herausforderung: " . ($challengeMap[$answers['q12']] ?? $answers['q12']) . "\n";
}
// Implementation Timeline
if (!empty($answers['q13'])) {
$timelineMap = [
'sofort' => 'sofort (innerhalb 1 Monat)',
'kurz' => 'kurzfristig (1-3 Monate)',
'mittel' => 'mittelfristig (3-6 Monate)',
'lang' => 'langfristig (6+ Monate)',
'keine' => 'keine konkreten Pläne'
];
$prompt .= "Umsetzungszeitraum: " . ($timelineMap[$answers['q13']] ?? $answers['q13']) . "\n";
}
$prompt .= "\n=== ANFORDERUNGEN FÜR DIE ANALYSE ===\n";
$prompt .= "Bitte erstelle eine strukturierte Analyse mit folgenden Abschnitten:\n";
$prompt .= "1. KI-Readiness Score (0-100) mit Begründung\n";
$prompt .= "2. Stärken des Unternehmens für KI-Implementierung\n";
$prompt .= "3. Verbesserungsbereiche\n";
$prompt .= "4. Konkrete KI-Anwendungsfälle für dieses Unternehmen\n";
$prompt .= "5. Quick Wins (schnell umsetzbare Maßnahmen)\n";
$prompt .= "6. Strategische Empfehlungen für die nächsten 12 Monate\n";
$prompt .= "7. Geschätzte Zeit- und Kosteneinsparungspotenziale\n\n";
$prompt .= "Antworte in einem professionellen, aber verständlichen Ton. Nutze Überschriften und Aufzählungen für bessere Lesbarkeit.";
return json_encode([
'model' => 'gpt-4',
'input' => [
['role' => 'system', 'content' => $systemPrompt],
['role' => 'user', 'content' => $prompt]
],
'temperature' => 0.7,
'max_tokens' => 3000
]);
}
/**
* Call the AI service using LocalAIApi
*/
private function callAIService(string $prompt): array
{
$payload = json_decode($prompt, true);
// Use LocalAIApi to call the AI service
$response = LocalAIApi::createResponse($payload, [
'poll_interval' => 3,
'poll_timeout' => 60
]);
if (empty($response['success'])) {
throw new Exception('AI service error: ' . ($response['error'] ?? 'Unknown error'));
}
return $response;
}
/**
* Parse AI response into structured format
*/
private function parseAIResponse(array $aiResponse): array
{
$text = LocalAIApi::extractText($aiResponse);
// Try to parse as JSON first
$json = LocalAIApi::decodeJsonFromResponse($aiResponse);
if ($json) {
return $this->parseStructuredJSON($json);
}
// Otherwise, parse the text
return $this->parseTextResponse($text);
}
/**
* Parse structured JSON response
*/
private function parseStructuredJSON(array $json): array
{
return [
'score' => $json['score'] ?? $this->calculateScore(),
'score_explanation' => $json['score_explanation'] ?? '',
'strengths' => $json['strengths'] ?? [],
'improvements' => $json['improvements'] ?? [],
'use_cases' => $json['use_cases'] ?? [],
'quick_wins' => $json['quick_wins'] ?? [],
'recommendations' => $json['recommendations'] ?? [],
'estimated_savings' => $json['estimated_savings'] ?? [],
'full_analysis' => $json
];
}
/**
* Parse text response
*/
private function parseTextResponse(string $text): array
{
// Extract score from text
preg_match('/Score[\s:]*(\d+)/i', $text, $scoreMatches);
$score = isset($scoreMatches[1]) ? (int)$scoreMatches[1] : $this->calculateScore();
// Extract sections (simplified parsing)
$sections = [
'strengths' => $this->extractSection($text, ['Stärken', 'Stärke', 'Vorteile']),
'improvements' => $this->extractSection($text, ['Verbesserung', 'Schwächen', 'Herausforderung']),
'quick_wins' => $this->extractSection($text, ['Quick Wins', 'schnelle Maßnahmen', 'sofort umsetzbar']),
'recommendations' => $this->extractSection($text, ['Empfehlung', 'Maßnahmen', 'Vorschläge'])
];
return [
'score' => $score,
'score_explanation' => $this->extractScoreExplanation($text),
'strengths' => $sections['strengths'],
'improvements' => $sections['improvements'],
'use_cases' => $this->extractUseCases($text),
'quick_wins' => $sections['quick_wins'],
'recommendations' => $sections['recommendations'],
'estimated_savings' => $this->extractSavings($text),
'full_analysis' => $text
];
}
/**
* Calculate readiness score based on answers
*/
private function calculateScore(): int
{
$score = 50; // Base score
// Add points based on answers
if (!empty($this->questionnaireData['q5'])) {
$score += ((int)$this->questionnaireData['q5'] - 3) * 10;
}
if (!empty($this->questionnaireData['q10'])) {
$score += ((int)$this->questionnaireData['q10'] - 3) * 8;
}
if (!empty($this->questionnaireData['q8'])) {
$hoursMap = [
'unter-5h' => -10,
'5-10h' => 0,
'11-15h' => 15,
'16-20h' => 25,
'20plus' => 30
];
$score += $hoursMap[$this->questionnaireData['q8']] ?? 0;
}
if (!empty($this->questionnaireData['q13'])) {
$timelineMap = [
'sofort' => 20,
'kurz' => 15,
'mittel' => 10,
'lang' => 5,
'keine' => 0
];
$score += $timelineMap[$this->questionnaireData['q13']] ?? 0;
}
return max(0, min(100, $score));
}
/**
* Calculate business metrics
*/
private function calculateMetrics(): array
{
$answers = $this->questionnaireData;
// Time saving potential
$hoursMap = [
'unter-5h' => 10,
'5-10h' => 20,
'11-15h' => 30,
'16-20h' => 40,
'20plus' => 50
];
$weeklyHours = $hoursMap[$answers['q8']] ?? 20;
// Cost saving (assuming €50/hour)
$monthlyCostSaving = $weeklyHours * 50 * 4.33;
// Quick wins based on number of time-consuming tasks
$quickWins = !empty($answers['q6']) && is_array($answers['q6'])
? min(count($answers['q6']), 8)
: 3;
return [
'time_saving_weekly' => $weeklyHours . 'h',
'time_saving_monthly' => ($weeklyHours * 4.33) . 'h',
'cost_saving_monthly' => '€' . number_format($monthlyCostSaving, 0, ',', '.'),
'cost_saving_yearly' => '€' . number_format($monthlyCostSaving * 12, 0, ',', '.'),
'quick_wins_count' => $quickWins,
'roi_months' => 6 // Estimated ROI in months
];
}
/**
* Recommend tools based on answers
*/
private function recommendTools(): array
{
$answers = $this->questionnaireData;
$tools = [];
// Always recommend these basics
$tools[] = [
'name' => 'ChatGPT Plus',
'category' => 'Content & Kreativität',
'priority' => 'high',
'description' => 'Für Texterstellung, Ideen & Content',
'price' => '20€/Monat'
];
// Based on business model
if (!empty($answers['q3']) && is_array($answers['q3'])) {
if (in_array('dienstleistung', $answers['q3']) || in_array('coaching', $answers['q3'])) {
$tools[] = [
'name' => 'Calendly',
'category' => 'Terminplanung',
'priority' => 'medium',
'description' => 'Automatisierte Terminbuchung',
'price' => '10€/Monat'
];
}
if (in_array('ecommerce', $answers['q3'])) {
$tools[] = [
'name' => 'Zapier',
'category' => 'Automatisierung',
'priority' => 'high',
'description' => 'App-Integration ohne Code',
'price' => '20€/Monat'
];
}
if (in_array('agentur', $answers['q3']) || in_array('marketing', $answers['q3'])) {
$tools[] = [
'name' => 'Jasper AI',
'category' => 'Content Marketing',
'priority' => 'high',
'description' => 'Professionelle Marketing-Texte',
'price' => '39€/Monat'
];
}
}
// Based on time-consuming tasks
if (!empty($answers['q6']) && is_array($answers['q6'])) {
if (in_array('kundenkommunikation', $answers['q6'])) {
$tools[] = [
'name' => 'Pipedrive',
'category' => 'CRM & Vertrieb',
'priority' => 'high',
'description' => 'Visuelles CRM für den Vertrieb',
'price' => '15€/Monat'
];
}
if (in_array('buchhaltung', $answers['q6'])) {
$tools[] = [
'name' => 'QuickBooks',
'category' => 'Buchhaltung',
'priority' => 'medium',
'description' => 'KI-gestützte Buchhaltung',
'price' => '25€/Monat'
];
}
}
// Based on budget
if (!empty($answers['q9'])) {
if ($answers['q9'] === 'unter-50') {
$tools = array_slice($tools, 0, 2); // Limit to 2 tools for small budget
}
}
return array_slice($tools, 0, 5); // Max 5 tools
}
/**
* Generate implementation timeline
*/
private function generateTimeline(): array
{
$answers = $this->questionnaireData;
if (empty($answers['q13'])) {
return $this->getDefaultTimeline();
}
$timelines = [
'sofort' => [
['month' => 1, 'action' => 'Quick Wins implementieren', 'tools' => ['ChatGPT', 'Calendly']],
['month' => 2, 'action' => 'Kundenkommunikation automatisieren', 'tools' => ['Pipedrive', 'Zapier']],
['month' => 3, 'action' => 'Reporting & Analyse aufbauen', 'tools' => ['Power BI', 'Google Analytics']]
],
'kurz' => [
['month' => 1, 'action' => 'Machbarkeitsstudie', 'tools' => []],
['month' => 2, 'action' => 'Pilotprojekt starten', 'tools' => ['ChatGPT']],
['month' => 3, 'action' => 'Team schulen', 'tools' => []],
['month' => 4, 'action' => 'Erste Prozesse automatisieren', 'tools' => ['Zapier']]
],
'mittel' => [
['month' => 1, 'action' => 'Strategie entwickeln', 'tools' => []],
['month' => 2, 'action' => 'Tools evaluieren', 'tools' => []],
['month' => 3, 'action' => 'Budget planen', 'tools' => []],
['month' => 4, 'action' => 'Pilot starten', 'tools' => []],
['month' => 5, 'action' => 'Erste Ergebnisse analysieren', 'tools' => []],
['month' => 6, 'action' => 'Skalierung planen', 'tools' => []]
],
'lang' => [
['month' => 1, 'action' => 'Informationsphase', 'tools' => []],
['month' => 3, 'action' => 'Anforderungsanalyse', 'tools' => []],
['month' => 6, 'action' => 'Strategieentwicklung', 'tools' => []],
['month' => 9, 'action' => 'Pilotprojekt starten', 'tools' => []],
['month' => 12, 'action' => 'Evaluierung', 'tools' => []]
]
];
return $timelines[$answers['q13']] ?? $this->getDefaultTimeline();
}
private function getDefaultTimeline(): array
{
return [
['month' => 1, 'action' => 'Quick Wins umsetzen', 'tools' => ['ChatGPT']],
['month' => 2, 'action' => 'Prozessanalyse durchführen', 'tools' => []],
['month' => 3, 'action' => 'Erste Automatisierungen', 'tools' => ['Zapier']],
['month' => 6, 'action' => 'Ergebnisse evaluieren', 'tools' => []],
['month' => 12, 'action' => 'KI-Strategie skalieren', 'tools' => []]
];
}
/**
* Helper methods for text parsing
*/
private function extractSection(string $text, array $keywords): array
{
$lines = explode("\n", $text);
$items = [];
$inSection = false;
foreach ($lines as $line) {
$line = trim($line);
// Check if we've entered a section
foreach ($keywords as $keyword) {
if (stripos($line, $keyword) !== false && strlen($line) < 100) {
$inSection = true;
continue 2;
}
}
// Collect items in section
if ($inSection && ($line === '' || stripos($line, '###') !== false)) {
break;
}
if ($inSection && $line !== '' && preg_match('/^[-•\d.]+\s+(.+)$/', $line, $matches)) {
$items[] = $matches[1];
}
}
return array_slice($items, 0, 5);
}
private function extractUseCases(string $text): array
{
// Simple extraction of numbered items
preg_match_all('/\d+\.\s+(.+?)(?=\n\d+\.|\n###|$)/s', $text, $matches);
return $matches[1] ?? ['Kundenkommunikation automatisieren', 'Content-Erstellung optimieren', 'Datenanalyse verbessern'];
}
private function extractSavings(string $text): array
{
preg_match_all('/(\d+[\d.,]*)\s*(?:Stunden|h|€|EUR)/i', $text, $matches);
return $matches[0] ?? ['20-30 Stunden/Woche', '1.000-2.000€/Monat'];
}
private function extractScoreExplanation(string $text): string
{
$lines = explode("\n", $text);
foreach ($lines as $line) {
if (stripos($line, 'Score') !== false || stripos($line, 'Bewertung') !== false) {
return $line;
}
}
return '';
}
private function generateReportId(): string
{
return 'KI-' . date('Ymd-His') . '-' . strtoupper(substr(md5(uniqid()), 0, 6));
}
private function generateFallbackAnalysis(): array
{
return [
'score' => $this->calculateScore(),
'score_explanation' => 'Basierend auf Ihren Antworten berechnet',
'strengths' => ['Bereitschaft zur Veränderung', 'Klares Ziel definiert'],
'improvements' => ['Prozessanalyse benötigt', 'Budgetplanung optimieren'],
'use_cases' => ['Kundenkommunikation automatisieren', 'Content-Erstellung optimieren'],
'quick_wins' => ['ChatGPT für E-Mail-Vorlagen nutzen', 'Automatische Terminbuchung einrichten'],
'recommendations' => ['Mit kleinen Projekten starten', 'Team schulen und einbinden'],
'estimated_savings' => ['20-30 Stunden/Woche', '1.000-2.000€/Monat']
];
}
}
?>