Files
breakpilot-lehrer/admin-lehrer/app/(admin)/ai/rag-pipeline/_components/ArchitectureTab.tsx
Benjamin Admin 9ba420fa91
Some checks failed
CI / go-lint (push) Has been skipped
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / test-go-school (push) Successful in 42s
CI / test-go-edu-search (push) Successful in 34s
CI / test-python-klausur (push) Failing after 2m51s
CI / test-python-agent-core (push) Successful in 21s
CI / test-nodejs-website (push) Successful in 29s
Fix: Remove broken getKlausurApiUrl and clean up empty lines
sed replacement left orphaned hostname references in story page
and empty lines in getApiBase functions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-24 16:02:04 +02:00

213 lines
9.3 KiB
TypeScript

'use client'
export function ArchitectureTab() {
return (
<div className="space-y-8">
{/* What is this module */}
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg border border-gray-200 dark:border-gray-700 p-6">
<h2 className="text-xl font-bold text-gray-900 dark:text-white mb-4">
Was macht dieses Modul?
</h2>
<div className="prose dark:prose-invert max-w-none">
<p className="text-gray-600 dark:text-gray-400">
Das <strong>RAG-Indexierungs-Modul</strong> verarbeitet Dokumente und macht sie fuer die KI-gestuetzte Suche verfuegbar.
Es handelt sich <strong>nicht</strong> um klassisches Machine-Learning-Training, sondern um:
</p>
<ul className="mt-4 space-y-2 text-gray-600 dark:text-gray-400">
<li className="flex items-start gap-2">
<span className="text-blue-500 mt-1">1.</span>
<span><strong>Dokumentenextraktion:</strong> PDFs und Bilder werden per OCR in Text umgewandelt</span>
</li>
<li className="flex items-start gap-2">
<span className="text-blue-500 mt-1">2.</span>
<span><strong>Chunking:</strong> Lange Texte werden in suchbare Abschnitte (1000 Zeichen) aufgeteilt</span>
</li>
<li className="flex items-start gap-2">
<span className="text-blue-500 mt-1">3.</span>
<span><strong>Embedding:</strong> Jeder Chunk wird in einen Vektor (1536 Dimensionen) umgewandelt</span>
</li>
<li className="flex items-start gap-2">
<span className="text-blue-500 mt-1">4.</span>
<span><strong>Indexierung:</strong> Vektoren werden in Qdrant gespeichert fuer semantische Suche</span>
</li>
</ul>
</div>
</div>
{/* Architecture Diagram */}
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg border border-gray-200 dark:border-gray-700 p-6">
<h2 className="text-xl font-bold text-gray-900 dark:text-white mb-6">
Technische Architektur
</h2>
{/* Visual Pipeline */}
<div className="relative">
{/* Data Sources Row */}
<div className="grid grid-cols-4 gap-4 mb-8">
<SourceCard icon="📄" title="NiBiS PDFs" subtitle="Erwartungshorizonte" color="blue" />
<SourceCard icon="📤" title="Uploads" subtitle="Eigene EH" color="green" />
<SourceCard icon="⚖️" title="Rechtskorpus" subtitle="DSGVO, AI Act" color="purple" />
<SourceCard icon="📚" title="Schulordnungen" subtitle="Bundeslaender" color="orange" />
</div>
<ArrowDown />
{/* Processing Layer */}
<div className="bg-gray-50 dark:bg-gray-900 rounded-xl p-6 mb-8">
<h3 className="text-sm font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-4">
Verarbeitungs-Pipeline
</h3>
<div className="flex items-center justify-between gap-4">
<PipelineStep icon="🔍" title="OCR" subtitle="Text-Extraktion" />
<ArrowRight />
<PipelineStep icon="✂️" title="Chunking" subtitle="1000 Zeichen" />
<ArrowRight />
<PipelineStep icon="🧮" title="Embedding" subtitle="1536-dim Vektor" />
<ArrowRight />
<PipelineStep icon="💾" title="Speichern" subtitle="Qdrant" />
</div>
</div>
<ArrowDown />
{/* Storage Layer */}
<div className="bg-gradient-to-r from-indigo-50 to-purple-50 dark:from-indigo-900/20 dark:to-purple-900/20 rounded-xl p-6 mb-8 border-2 border-indigo-200 dark:border-indigo-800">
<h3 className="text-sm font-semibold text-indigo-600 dark:text-indigo-400 uppercase tracking-wide mb-4">
Vektor-Datenbank (Qdrant)
</h3>
<div className="grid grid-cols-3 gap-4">
<CollectionCard collection="bp_nibis_eh" label="Offizielle EH" />
<CollectionCard collection="bp_eh" label="Benutzer EH" />
<CollectionCard collection="bp_legal_corpus" label="Rechtskorpus" />
</div>
</div>
<ArrowDown />
{/* Usage Layer */}
<div className="grid grid-cols-2 gap-4">
<div className="p-4 bg-emerald-50 dark:bg-emerald-900/20 rounded-xl border-2 border-emerald-200 dark:border-emerald-800">
<h4 className="font-medium text-emerald-700 dark:text-emerald-400 mb-2">Semantische Suche</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
Fragen werden in Vektoren umgewandelt und aehnliche Dokumente gefunden
</p>
</div>
<div className="p-4 bg-amber-50 dark:bg-amber-900/20 rounded-xl border-2 border-amber-200 dark:border-amber-800">
<h4 className="font-medium text-amber-700 dark:text-amber-400 mb-2">RAG-Antworten</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
LLM generiert Antworten basierend auf gefundenen Dokumenten
</p>
</div>
</div>
</div>
</div>
{/* Technical Details */}
<div className="bg-white dark:bg-gray-800 rounded-2xl shadow-lg border border-gray-200 dark:border-gray-700 p-6">
<h2 className="text-xl font-bold text-gray-900 dark:text-white mb-4">
Technische Details
</h2>
<div className="grid grid-cols-2 gap-6">
<div>
<h3 className="font-medium text-gray-900 dark:text-white mb-3">Embedding-Service</h3>
<table className="w-full text-sm">
<tbody className="divide-y divide-gray-200 dark:divide-gray-700">
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Modell</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">text-embedding-3-small</td>
</tr>
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Dimensionen</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">1536</td>
</tr>
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Port</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">8087</td>
</tr>
</tbody>
</table>
</div>
<div>
<h3 className="font-medium text-gray-900 dark:text-white mb-3">Chunk-Konfiguration</h3>
<table className="w-full text-sm">
<tbody className="divide-y divide-gray-200 dark:divide-gray-700">
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Chunk-Groesse</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">1000 Zeichen</td>
</tr>
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Ueberlappung</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">200 Zeichen</td>
</tr>
<tr>
<td className="py-2 text-gray-500 dark:text-gray-400">Distanzmetrik</td>
<td className="py-2 font-mono text-gray-900 dark:text-white">COSINE</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
)
}
// --- Internal helper components ---
function SourceCard({ icon, title, subtitle, color }: {
icon: string
title: string
subtitle: string
color: string
}) {
const colorClasses: Record<string, string> = {
blue: 'bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800',
green: 'bg-green-50 dark:bg-green-900/20 border-green-200 dark:border-green-800',
purple: 'bg-purple-50 dark:bg-purple-900/20 border-purple-200 dark:border-purple-800',
orange: 'bg-orange-50 dark:bg-orange-900/20 border-orange-200 dark:border-orange-800',
}
return (
<div className={`p-4 rounded-xl border-2 text-center ${colorClasses[color]}`}>
<div className="text-3xl mb-2">{icon}</div>
<div className="font-medium text-gray-900 dark:text-white">{title}</div>
<div className="text-xs text-gray-500">{subtitle}</div>
</div>
)
}
function PipelineStep({ icon, title, subtitle }: {
icon: string
title: string
subtitle: string
}) {
return (
<div className="flex-1 p-4 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 text-center">
<div className="text-2xl mb-1">{icon}</div>
<div className="font-medium text-sm">{title}</div>
<div className="text-xs text-gray-500">{subtitle}</div>
</div>
)
}
function CollectionCard({ collection, label }: { collection: string; label: string }) {
return (
<div className="p-3 bg-white dark:bg-gray-800 rounded-lg text-center">
<div className="font-mono text-xs text-gray-500">{collection}</div>
<div className="font-medium text-gray-900 dark:text-white">{label}</div>
</div>
)
}
function ArrowDown() {
return (
<div className="flex justify-center mb-4">
<div className="text-4xl text-gray-400"></div>
</div>
)
}
function ArrowRight() {
return <div className="text-2xl text-gray-400"></div>
}