# NiBiS Ingestion Pipeline ## Overview Die NiBiS Ingestion Pipeline verarbeitet Abitur-Erwartungshorizonte aus Niedersachsen und indexiert sie in Qdrant für RAG-basierte Klausurkorrektur. ## Unterstützte Daten ### Verzeichnisse | Verzeichnis | Jahre | Namenskonvention | |-------------|-------|------------------| | `docs/za-download` | 2024, 2025 | `{Jahr}_{Fach}_{niveau}_{Nr}_EWH.pdf` | | `docs/za-download-2` | 2016 | `{Jahr}{Fach}{Niveau}Lehrer/{Jahr}{Fach}{Niveau}A{Nr}L.pdf` | | `docs/za-download-3` | 2017 | `{Jahr}{Fach}{Niveau}Lehrer/{Jahr}{Fach}{Niveau}A{Nr}L.pdf` | ### Dokumenttypen - **EWH** - Erwartungshorizont (Hauptziel) - **Aufgabe** - Prüfungsaufgaben - **Material** - Zusatzmaterialien - **GBU** - Gefährdungsbeurteilung (Chemie/Biologie) - **Bewertungsbogen** - Standardisierte Bewertungsbögen ### Fächer Deutsch, Englisch, Mathematik, Informatik, Biologie, Chemie, Physik, Geschichte, Erdkunde, Kunst, Musik, Sport, Latein, Griechisch, Französisch, Spanisch, Katholische Religion, Evangelische Religion, Werte und Normen, BRC, BVW, Gesundheit-Pflege ## Architektur ``` ┌─────────────────────────────────────────────────────────────────┐ │ NiBiS Ingestion Pipeline │ ├─────────────────────────────────────────────────────────────────┤ │ │ │ 1. ZIP Extraction │ │ └── Entpackt 2024.zip, 2025.zip, etc. │ │ │ │ 2. Document Discovery │ │ ├── Parst alte Namenskonvention (2016/2017) │ │ └── Parst neue Namenskonvention (2024/2025) │ │ │ │ 3. PDF Processing │ │ ├── Text-Extraktion (PyPDF2) │ │ └── Chunking (1000 chars, 200 overlap) │ │ │ │ 4. Embedding Generation │ │ └── OpenAI text-embedding-3-small (1536 dim) │ │ │ │ 5. Qdrant Indexing │ │ └── Collection: bp_nibis_eh │ │ │ └─────────────────────────────────────────────────────────────────┘ ``` ## Verwendung ### Via API (empfohlen) ```bash # 1. Vorschau der verfügbaren Dokumente curl http://localhost:8086/api/v1/admin/nibis/discover # 2. ZIP-Dateien entpacken curl -X POST http://localhost:8086/api/v1/admin/nibis/extract-zips # 3. Ingestion starten curl -X POST http://localhost:8086/api/v1/admin/nibis/ingest \ -H "Content-Type: application/json" \ -d '{"ewh_only": true}' # 4. Status prüfen curl http://localhost:8086/api/v1/admin/nibis/status # 5. Semantische Suche testen curl -X POST http://localhost:8086/api/v1/admin/nibis/search \ -H "Content-Type: application/json" \ -d '{"query": "Analyse literarischer Texte", "subject": "Deutsch", "limit": 5}' ``` ### Via CLI ```bash # Dry-Run (nur analysieren) cd klausur-service/backend python nibis_ingestion.py --dry-run # Vollständige Ingestion python nibis_ingestion.py # Nur bestimmtes Jahr python nibis_ingestion.py --year 2024 # Nur bestimmtes Fach python nibis_ingestion.py --subject Deutsch # Manifest erstellen python nibis_ingestion.py --manifest /tmp/nibis_manifest.json ``` ### Via Shell Script ```bash ./klausur-service/scripts/run_nibis_ingestion.sh --dry-run ./klausur-service/scripts/run_nibis_ingestion.sh --year 2024 --subject Deutsch ``` ## Qdrant Schema ### Collection: `bp_nibis_eh` ```json { "id": "nibis_2024_deutsch_ea_1_abc123_chunk_0", "vector": [1536 dimensions], "payload": { "doc_id": "nibis_2024_deutsch_ea_1_abc123", "chunk_index": 0, "text": "Der Erwartungshorizont...", "year": 2024, "subject": "Deutsch", "niveau": "eA", "task_number": 1, "doc_type": "EWH", "bundesland": "NI", "variant": null, "source": "nibis", "training_allowed": true } } ``` ## API Endpoints | Methode | Endpoint | Beschreibung | |---------|----------|--------------| | GET | `/api/v1/admin/nibis/status` | Ingestion-Status | | POST | `/api/v1/admin/nibis/extract-zips` | ZIP-Dateien entpacken | | GET | `/api/v1/admin/nibis/discover` | Dokumente finden | | POST | `/api/v1/admin/nibis/ingest` | Ingestion starten | | POST | `/api/v1/admin/nibis/search` | Semantische Suche | | GET | `/api/v1/admin/nibis/stats` | Statistiken | | GET | `/api/v1/admin/nibis/collections` | Qdrant Collections | | DELETE | `/api/v1/admin/nibis/collection` | Collection löschen | ## Erweiterung für andere Bundesländer Die Pipeline ist so designed, dass sie leicht erweitert werden kann: ### 1. Neues Bundesland hinzufügen ```python # In nibis_ingestion.py # Bundesland-Code (ISO 3166-2:DE) BUNDESLAND_CODES = { "NI": "Niedersachsen", "BE": "Berlin", "BY": "Bayern", # ... } # Parsing-Funktion für neues Format def parse_filename_berlin(filename: str, file_path: Path) -> Optional[Dict]: # Berlin-spezifische Namenskonvention pass ``` ### 2. Neues Verzeichnis registrieren ```python # docs/za-download-berlin/ hinzufügen ZA_DOWNLOAD_DIRS = [ "za-download", "za-download-2", "za-download-3", "za-download-berlin", # NEU ] ``` ### 3. Dokumenttyp-Erweiterung Für Zeugnisgeneration oder andere Dokumenttypen: ```python DOC_TYPES = { "EWH": "Erwartungshorizont", "ZEUGNIS_VORLAGE": "Zeugnisvorlage", "NOTENSPIEGEL": "Notenspiegel", "BEMERKUNG": "Bemerkungstexte", } ``` ## Rechtliche Hinweise - NiBiS-Daten sind unter den [NiBiS-Nutzungsbedingungen](https://nibis.de) frei nutzbar - `training_allowed: true` - Strukturelles Wissen darf für KI-Training genutzt werden - Für Lehrer-eigene Erwartungshorizonte (BYOEH) gilt: `training_allowed: false` ## Troubleshooting ### Qdrant nicht erreichbar ```bash # Prüfen ob Qdrant läuft curl http://localhost:6333/health # Docker starten docker-compose up -d qdrant ``` ### OpenAI API Fehler ```bash # API Key setzen export OPENAI_API_KEY=sk-... ``` ### PDF-Extraktion fehlgeschlagen Einige PDFs können problematisch sein (gescannte Dokumente ohne OCR). Diese werden übersprungen und im Error-Log protokolliert. ## Performance - ~500-1000 Chunks pro Minute (abhängig von OpenAI API) - ~2-3 GB Qdrant Storage für alle NiBiS-Daten (2016-2025) - Embeddings werden nur einmal generiert (idempotent via Hash)