This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
BreakPilot Dev 19855efacc
Some checks failed
Tests / Go Tests (push) Has been cancelled
Tests / Python Tests (push) Has been cancelled
Tests / Integration Tests (push) Has been cancelled
Tests / Go Lint (push) Has been cancelled
Tests / Python Lint (push) Has been cancelled
Tests / Security Scan (push) Has been cancelled
Tests / All Checks Passed (push) Has been cancelled
Security Scanning / Secret Scanning (push) Has been cancelled
Security Scanning / Dependency Vulnerability Scan (push) Has been cancelled
Security Scanning / Go Security Scan (push) Has been cancelled
Security Scanning / Python Security Scan (push) Has been cancelled
Security Scanning / Node.js Security Scan (push) Has been cancelled
Security Scanning / Docker Image Security (push) Has been cancelled
Security Scanning / Security Summary (push) Has been cancelled
CI/CD Pipeline / Go Tests (push) Has been cancelled
CI/CD Pipeline / Python Tests (push) Has been cancelled
CI/CD Pipeline / Website Tests (push) Has been cancelled
CI/CD Pipeline / Linting (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Docker Build & Push (push) Has been cancelled
CI/CD Pipeline / Integration Tests (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / CI Summary (push) Has been cancelled
ci/woodpecker/manual/build-ci-image Pipeline was successful
ci/woodpecker/manual/main Pipeline failed
feat: BreakPilot PWA - Full codebase (clean push without large binaries)
All services: admin-v2, studio-v2, website, ai-compliance-sdk,
consent-service, klausur-service, voice-service, and infrastructure.
Large PDFs and compiled binaries excluded via .gitignore.
2026-02-11 13:25:58 +01:00
..

edu-search-service

Spezialisierter Suchdienst für deutsche Bildungsinhalte - eine Alternative zu Tavily, optimiert für den deutschen Bildungssektor.

Übersicht

Der edu-search-service crawlt, extrahiert und indiziert Bildungsinhalte von deutschen Bildungsquellen (Kultusministerien, Bildungsserver, wissenschaftliche Studien, etc.) und stellt eine Such-API bereit.

Features

  • BM25 Keyword-Suche mit German Analyzer (OpenSearch)
  • Semantic Search mit Embeddings (OpenAI oder Ollama)
  • Hybrid Search kombiniert BM25 + Vektor-Ähnlichkeit
  • Automatisches Tagging für Dokumenttyp, Fächer, Schulstufe, Bundesland
  • Trust-Score basierend auf Domain-Reputation und Content-Qualität
  • Rate-Limited Crawler mit robots.txt Respekt
  • Admin API für Seed-Verwaltung und Crawl-Steuerung

Architektur

┌─────────────────────────────────────────────────────────────────────┐
│                        edu-search-service                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│   ┌─────────┐    ┌───────────┐    ┌────────┐    ┌─────────┐       │
│   │ Crawler │───▶│ Extractor │───▶│ Tagger │───▶│ Indexer │       │
│   └─────────┘    └───────────┘    └────────┘    └─────────┘       │
│        │                                              │             │
│        ▼                                              ▼             │
│   ┌─────────┐                                  ┌────────────┐      │
│   │  Seeds  │                                  │ OpenSearch │      │
│   └─────────┘                                  └────────────┘      │
│                                                      │             │
│                     ┌────────────┐                   │             │
│                     │ Search API │◀──────────────────┘             │
│                     └────────────┘                                 │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Komponenten

Crawler (internal/crawler/)

  • Rate-Limited HTTP Client (Standard: 0.2 req/sec pro Domain)
  • Denylist-Support für ungewünschte Domains
  • Seeds aus Backend-API (primär) oder lokale Seed-Files (Fallback)
  • URL-Normalisierung und Deduplication
  • Seed-Metadaten: Trust-Boost, Crawl-Tiefe, Kategorie, Bundesland
  • Crawl-Status-Feedback an Backend (Dokumentenzahl, Dauer, Fehler)

Robots (internal/robots/)

  • robots.txt Parser mit Caching (24h TTL)
  • Unterstützt Disallow, Allow, Crawl-delay
  • Wildcard-Patterns (*) und End-Anchors ($)
  • User-Agent-spezifische Regeln
  • Leniente Behandlung bei fehlenden robots.txt

Extractor (internal/extractor/)

  • HTML-Extraktion mit goquery
  • PDF-Textextraktion mit ledongthuc/pdf Bibliothek
    • ExtractPDF() - Standard-Extraktion mit GetPlainText
    • ExtractPDFWithMetadata() - Seiten-weise Extraktion für mehr Kontrolle
    • Fallback-Extraktion bei beschädigten PDFs
    • Automatische Titel-Erkennung (erste signifikante Zeile)
    • Heading-Erkennung (All-Caps, nummerierte Zeilen)
  • Metadaten-Extraktion (og:title, description, etc.)
  • Content-Feature-Berechnung (Ad-Density, Link-Density)
  • Sprach-Erkennung (Deutsch/Englisch)

Tagger (internal/tagger/)

  • Regelbasiertes Tagging via YAML-Konfiguration
  • DocType-Erkennung (Lehrplan, Arbeitsblatt, Studie, etc.)
  • Fächer-Erkennung (Mathematik, Deutsch, etc.)
  • Schulstufen-Erkennung (Grundschule, Sek I/II, etc.)
  • Bundesland-Erkennung aus URL-Patterns
  • Trust-Score-Berechnung

Quality (internal/quality/)

  • Multi-Faktor Quality-Score (0-1)
    • Content Length (20%)
    • Heading Structure (15%)
    • Link/Ad Quality (15%)
    • Text-to-HTML Ratio (15%)
    • Metadata Presence (10%)
    • Language Clarity (10%)
    • Content Freshness (10%)
    • PDF-Specific Signals (5%)
  • Konfigurierbare Gewichtungen
  • Date-Indicator-Extraktion für Frische-Bewertung

Indexer (internal/indexer/)

  • OpenSearch 2.11 Client
  • German Analyzer für BM25
  • Bulk-Indexierung
  • Custom Mapping für Bildungsdokumente

Search (internal/search/)

  • Multi-Match Query mit Boosting
  • Filter für alle Taxonomie-Felder
  • Function-Score mit Trust/Quality-Boosting
  • Highlighting-Support
  • Drei Suchmodi:
    • keyword - Klassische BM25-Suche (Default)
    • semantic - Reine Vektor-Ähnlichkeitssuche (k-NN)
    • hybrid - Kombination aus BM25 und Vektor-Score

Embedding (internal/embedding/)

  • OpenAI Provider - text-embedding-3-small (1536 Dimensionen)
  • Ollama Provider - Lokale Modelle (z.B. nomic-embed-text, 384-768 Dim.)
  • Batch-Embedding für effiziente Indexierung
  • Automatische Text-Kürzung (max. 30.000 Zeichen)

Scheduler (internal/scheduler/)

  • Automatisches Crawling in konfigurierbaren Intervallen
  • Default: täglich um 2:00 Uhr (minimale Auswirkung)
  • Manuelles Triggern via Admin-API
  • Status-Tracking (letzter Lauf, nächster Lauf, Ergebnis)

API Endpoints

Public Endpoints

Method Endpoint Beschreibung
GET /v1/health Health Check (kein Auth)
POST /v1/search Suche ausführen
GET /v1/document Einzeldokument abrufen

Admin Endpoints (Auth erforderlich)

Method Endpoint Beschreibung
GET /v1/admin/seeds Alle Seeds abrufen
POST /v1/admin/seeds Neuen Seed erstellen
PUT /v1/admin/seeds/:id Seed aktualisieren
DELETE /v1/admin/seeds/:id Seed löschen
GET /v1/admin/stats Crawl-Statistiken
POST /v1/admin/crawl/start Crawl starten

API Dokumentation

POST /v1/search

Request Body:

{
  "q": "Lehrplan Mathematik Gymnasium",
  "mode": "keyword",
  "limit": 10,
  "offset": 0,
  "filters": {
    "language": ["de"],
    "doc_type": ["Lehrplan"],
    "school_level": ["Gymnasium"],
    "state": ["BY", "NW"],
    "subjects": ["Mathematik"],
    "min_trust_score": 0.5
  },
  "include": {
    "snippets": true,
    "highlights": true
  }
}

Such-Modi (mode):

Mode Beschreibung
keyword BM25-Textsuche (Default)
semantic Vektor-Ähnlichkeitssuche via Embeddings
hybrid Kombination: 70% BM25 + 30% Vektor-Score

Hinweis: semantic und hybrid Modi erfordern SEMANTIC_SEARCH_ENABLED=true und konfigurierte Embedding-Provider.

Response:

{
  "query_id": "q-12345",
  "results": [
    {
      "doc_id": "uuid-...",
      "title": "Lehrplan Mathematik Gymnasium Bayern",
      "url": "https://www.isb.bayern.de/...",
      "domain": "isb.bayern.de",
      "language": "de",
      "doc_type": "Lehrplan",
      "school_level": "Gymnasium",
      "subjects": ["Mathematik"],
      "scores": {
        "bm25": 12.5,
        "trust": 0.85,
        "quality": 0.9,
        "final": 10.6
      },
      "snippet": "Der Lehrplan für das Fach Mathematik...",
      "highlights": ["<em>Lehrplan</em> für das Fach <em>Mathematik</em>..."]
    }
  ],
  "pagination": {
    "limit": 10,
    "offset": 0,
    "total_estimate": 156
  }
}

Filter-Optionen

Filter Werte
language de, en
doc_type Lehrplan, Arbeitsblatt, Unterrichtsentwurf, Erlass_Verordnung, Pruefung_Abitur, Studie_Bericht, Sonstiges
school_level Grundschule, Sek_I, Gymnasium, Berufsschule, Hochschule, Alle, NA
state BW, BY, BE, BB, HB, HH, HE, MV, NI, NW, RP, SL, SN, ST, SH, TH
subjects Mathematik, Deutsch, Englisch, Geschichte, Physik, Biologie, Chemie, etc.

Konfiguration

Umgebungsvariablen

Variable Beschreibung Default
PORT Server Port 8084
OPENSEARCH_URL OpenSearch URL http://opensearch:9200
OPENSEARCH_USERNAME OpenSearch User admin
OPENSEARCH_PASSWORD OpenSearch Passwort admin
INDEX_NAME Index Name bp_documents_v1
USER_AGENT Crawler User Agent BreakpilotEduCrawler/1.0
RATE_LIMIT_PER_SEC Requests pro Sekunde/Domain 0.2
MAX_DEPTH Max Crawl-Tiefe 4
MAX_PAGES_PER_RUN Max Seiten pro Crawl 500
SEEDS_DIR Seed-Dateien Verzeichnis ./seeds
RULES_DIR Tagging-Regeln Verzeichnis ./rules
EDU_SEARCH_API_KEY API Key für Auth ``
BACKEND_URL URL zum Python Backend http://backend:8000
SEEDS_FROM_API Seeds aus API laden true
Semantic Search
SEMANTIC_SEARCH_ENABLED Semantic Search aktivieren false
EMBEDDING_PROVIDER Provider: openai, ollama, none none
OPENAI_API_KEY API Key für OpenAI Embeddings ``
EMBEDDING_MODEL Embedding-Modell text-embedding-3-small
EMBEDDING_DIMENSION Vektor-Dimension 1536
OLLAMA_URL Ollama Server URL http://ollama:11434
Scheduler
SCHEDULER_ENABLED Automatisches Crawling aktivieren false
SCHEDULER_INTERVAL Crawl-Intervall 24h (täglich)

Installation & Start

Docker (empfohlen)

# Im edu-search-service Verzeichnis
docker compose up -d

# Logs anzeigen
docker compose logs -f edu-search

# Nur der Service (OpenSearch extern)
docker build -t edu-search-service .
docker run -p 8084:8084 \
  -e OPENSEARCH_URL=http://host.docker.internal:9200 \
  edu-search-service

Lokal (Entwicklung)

# Dependencies installieren
go mod download

# Service starten
go run cmd/server/main.go

# Tests ausführen
go test -v ./...

Seed-Kategorien

Kategorie Beschreibung Beispiele
federal Bundesweite Institutionen KMK, BMBF, IQB
states Landeskultusbehörden Kultusministerien, Landesinstitute
science Wissenschaftliche Studien PISA, IGLU, TIMSS
universities Hochschulen Pädagogische Hochschulen
schools Schulen direkt Schulhomepages
portals Bildungsportale Lehrer-Online, 4teachers
eu EU-Bildungsprogramme Erasmus+, Eurydice
authorities Schulbehörden Regierungspräsidien

Tagging-Regeln

Die YAML-Regeldateien im rules/ Verzeichnis definieren das Tagging:

  • doc_type_rules.yaml - Dokumenttyp-Erkennung
  • subject_rules.yaml - Fächer-Erkennung
  • level_rules.yaml - Schulstufen-Erkennung
  • trust_rules.yaml - Trust-Score-Berechnung

Beispiel: doc_type_rules.yaml

doc_types:
  Lehrplan:
    strong_terms:
      - Lehrplan
      - Kernlehrplan
      - Bildungsplan
    medium_terms:
      - Curriculum
      - Kompetenzerwartungen
    url_patterns:
      - /lehrplan
      - /kernlehrplan

priority_order:
  - Pruefung_Abitur
  - Lehrplan
  - Arbeitsblatt

Projektstruktur

edu-search-service/
├── cmd/
│   └── server/
│       └── main.go          # Entry Point
├── internal/
│   ├── api/
│   │   └── handlers/
│   │       ├── handlers.go       # Search & Health Handler
│   │       └── admin_handlers.go # Admin API Handler
│   ├── config/
│   │   └── config.go        # Konfiguration
│   ├── crawler/
│   │   ├── crawler.go       # URL Fetcher
│   │   └── api_client.go    # Backend API Client (Seeds)
│   ├── robots/
│   │   └── robots.go        # robots.txt Parser & Checker
│   ├── embedding/
│   │   └── embedding.go     # Embedding Provider (OpenAI/Ollama)
│   ├── extractor/
│   │   └── extractor.go     # HTML/PDF Extraktion
│   ├── indexer/
│   │   └── mapping.go       # OpenSearch Indexer
│   ├── pipeline/
│   │   └── pipeline.go      # Crawl Orchestrierung
│   ├── quality/
│   │   └── quality.go       # Multi-Faktor Quality Scoring
│   ├── scheduler/
│   │   └── scheduler.go     # Automatisches Crawl-Scheduling
│   ├── search/
│   │   └── search.go        # Search Service (Keyword/Semantic/Hybrid)
│   └── tagger/
│       └── tagger.go        # Regelbasiertes Tagging
├── rules/
│   ├── doc_type_rules.yaml
│   ├── subject_rules.yaml
│   ├── level_rules.yaml
│   └── trust_rules.yaml
├── seeds/
│   ├── federal.txt
│   ├── states.txt
│   └── denylist.txt
├── Dockerfile
├── docker-compose.yml
├── go.mod
└── README.md

Abhängigkeiten

Package Version Beschreibung Lizenz
github.com/gin-gonic/gin v1.9+ HTTP Framework MIT
github.com/opensearch-project/opensearch-go/v2 v2.3+ OpenSearch Client Apache-2.0
github.com/PuerkitoBio/goquery v1.8+ HTML Parser BSD-3-Clause
github.com/ledongthuc/pdf v0.0.0-20240201 PDF Text Extraktion MIT
gopkg.in/yaml.v3 v3.0+ YAML Parser MIT
github.com/google/uuid v1.4+ UUID Generation BSD-3-Clause
golang.org/x/net v0.19+ HTML Utilities BSD-3-Clause

Tests ausführen

# Alle Tests
go test -v ./...

# Mit Coverage
go test -cover ./...

# Nur Tagger Tests
go test -v ./internal/tagger/...

# Nur Crawler Tests
go test -v ./internal/crawler/...

Lizenz

Proprietär - BreakPilot GmbH

Kontakt