Fetch candidate pages sequentially with the full remaining download budget instead of dividing a quick run's 500 KB equally across every URL. This avoids aborting otherwise readable pages at roughly 33 KB before claim extraction can inspect them. Account for bytes consumed by failed downloads, preserve fetch errors in source responses, and fail runs with no successfully extracted document using an actionable error. Keep attempted sources on failed runs for diagnostics and cover the allocation and no-usable-source paths with regression tests.
NSCT — Neutral Search Crawler Tool
NSCT ist ein vollständig lokal betreibbares, containerisiertes Recherche- und Analyse-System. Es durchsucht Webquellen, extrahiert Inhalte, vergleicht Behauptungen (Claims) aus verschiedenen Quellen und erzeugt einen neutralen, quellengestützten Bericht.
NSCT steht für: Neutral Search Crawler Tool.
Architektur-Übersicht
┌─────────────┐ ┌──────────────────────────┐ ┌───────────────┐
│ User / CLI │───▶│ NSCT REST API (FastAPI) │───▶│ uvicorn │
│ │ │ (async, background pip.)│ │ :8080 │
└─────────────┘ └──────────┬───────────────┘ └───────────────┘
│
┌───────────────┼─────────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────────┐
│ Search │ │ Content │ │ Crawler │
│ Providers │ │ Fetcher │ │ (SSRF-Prot) │
│ (DDG, Multi) │ │ (HTTP/ │ │ (HTML,PDF, │
└──────┬───────┘ │ Playwright)│ │ PDF, ...) │
│ └──────┬─────┘ └──────────────┘
▼ ▼
┌─────────────────────────────────────────────┐
│ Evidence Pipeline (Orchestrator) │
│ Search → Fetch → Extract → Claim → │
│ Compare → Score → Synthesis → Report │
└──────────────────────────┬─────────────────┘
│
▼
┌────────────────────────┐
│ PostgreSQL (asyncpg) │
│ Evidence Store │
└────────────────────────┘
▲
│
┌──────────────┴──────────────┐
│ LLM (Qwen3.6-35B) │
│ Vision (Qwen2.5-VL-3B) │
│ Audio (STT) │
└──────────────────────────────┘
Quick Start
Docker Compose
# 1. Kopiere die Beispiel-Env
cp .env.example .env
# 2. Trage deine Endpunkte ein (LLM, Vision, Audio, PostgreSQL)
# 3. Starte alles
docker compose up --build
# 4. Prüfe den Health-Check
curl http://localhost:8080/health
Die API ist danach unter http://localhost:8080 erreichbar.
/docs zeigt die auto-generierte Swagger-Dokumentation (nur bei NSCT_DEBUG=true).
Frontend auf einem separaten Rechner
Das Backend kann unabhängig vom Frontend betrieben werden. Das Frontend leitet
seine Same-Origin-Anfragen an /api/* per Caddy an diese API weiter. Auf dem
Frontend-Rechner wird dazu im Frontend-Repository gesetzt:
NSCT_API_UPSTREAM=backend.example.com:8080
Der Backend-Rechner muss Port 8080 ausschließlich für die IP bzw. das Netz des Frontend-Rechners freigeben. Für öffentliche oder nicht vertrauenswürdige Netze soll die Verbindung zwischen den Rechnern über TLS, VPN oder einen abgesicherten Reverse Proxy erfolgen.
Projektstruktur
nsct/
├── src/nsct/
│ ├── api/ # FastAPI-Routen (health, research, search, etc.)
│ ├── agents/ # Research Planner & Validator
│ ├── crawler/ # Content Fetcher, Extraction, Normalization
│ ├── models/ # Pydantic v2 Schemas
│ ├── orchestration/# State Machine, Budget, Gap Analysis
│ ├── provenance.py # Vollständige Provenance Tracking
│ ├── providers/ # LLM, Vision, Audio, Search, Multi, Priority
│ ├── security/ # SSRF-Schutz, URL-Validierung
│ ├── stages/ # Pipeline-Stages (5-13: claim, evidence, synthesis)
│ ├── storage/ # SQLAlchemy 2.0 Models + Engine
│ ├── cli.py # Kommandozeileninterface
│ ├── config.py # Pydantic BaseSettings Konfiguration
│ ├── logging_config.py # Strukturiertes JSON-Logging
│ ├── metrics.py # Prometheus Metriken
│ └── main.py # FastAPI Application Factory
├── tests/ # pytest-Tests (Unit + Integration)
├── docker-compose.yml
├── Dockerfile
├── pyproject.toml
├── .env.example
├── README.md
├── ARCHITECTURE.md
├── SECURITY.md
├── METHODOLOGY.md
├── API.md
├── DEPLOYMENT.md
└── CHANGELOG.md
Schnellstart-Beispiel (CLI)
nsct research "Welche wesentlichen Entwicklungen gab es im letzten Jahr bei Kernfusion?" \
--depth normal \
--language de
Schnellstart-Beispiel (API)
curl -X POST http://localhost:8080/v1/research \
-H "Content-Type: application/json" \
-d '{
"query": "Welche Entwicklungen gab es bei Kernfusion?",
"language": "de",
"depth": "normal"
}'
Antwort:
{
"research_id": "uuid-...",
"status": "pending",
"query": "Welche Entwicklungen gab es bei Kernfusion?",
"depth": "normal",
"state": "created"
}
Den Status und das Ergebnis abrufen:
# Status
curl http://localhost:8080/v1/research/<research_id>/status
# Bericht
curl http://localhost:8080/v1/research/<research_id>/report
# Quellen
curl http://localhost:8080/v1/research/<research_id>/sources
# Claims
curl http://localhost:8080/v1/research/<research_id>/claims
# Evidence-Scores
curl http://localhost:8080/v1/research/<research_id>/evidence
Status
Stage 22 — Abschluss & Production Readiness.
Alle 22 Stages sind abgeschlossen. NSCT ist production-ready:
- Pipeline: Search → Fetch → Extract → Claim → Compare → Score → Synthesize → Report
- State Machine: 12 Zustände (CREATED → ... → COMPLETED/FAILED/CANCELLED)
- Budget Limits: Hard limits für Queries, Sources, LLM-Requests, Duration
- Iterative Research: Gap Analysis mit max 3 Runden
- REST API: Vollständiger Research Lifecycle (POST/GET/DELETE)
- CLI: Kommandozeileninterface mit depth, language, format Optionen
- Observability: Strukturiertes Logging + Prometheus Metriken
- Docker Hardening: Non-Root, Read-Only FS, Dropped Capabilities, Resource Limits
- Reproduzierbarkeit: Vollständige Provenance + research_run_hash
- Neutralitäts-Tests: Syndication, politische Aussagen, Dissens, Prompt Injection, fehlende Evidenz
- E2E-Tests: 9 Integrationstests für den vollständigen Pipeline-Durchlauf
Lizenz
MIT