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
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>
213 lines
9.3 KiB
TypeScript
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>
|
|
}
|