415 lines
7.8 KiB
Markdown
415 lines
7.8 KiB
Markdown
# NSCT — API-Referenz
|
||
|
||
> **Hinweis:** Diese API-Referenz beschreibt den aktuellen Stand (Stage 22).
|
||
|
||
## Server-Adresse
|
||
|
||
```
|
||
http://localhost:8080
|
||
```
|
||
|
||
Nach `docker compose up`.
|
||
|
||
---
|
||
|
||
## System-Endpunkte
|
||
|
||
### GET /health
|
||
|
||
**Beschreibung:** Basic health check — gibt den Status und die Version zurück.
|
||
Wird von Docker Healthchecks und Load Balancern verwendet.
|
||
|
||
**Request:**
|
||
```
|
||
GET /health
|
||
```
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"version": "0.1.0"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /ready
|
||
|
||
**Beschreibung:** Readiness check — prüft die Erreichbarkeit von
|
||
Downstream-Services (LLM-Provider, ggf. Datenbank).
|
||
|
||
**Request:**
|
||
```
|
||
GET /ready
|
||
```
|
||
|
||
**Response (200 OK):**
|
||
|
||
Wenn bereit:
|
||
```json
|
||
{
|
||
"status": "ready",
|
||
"llm": "ok",
|
||
"database": "unknown",
|
||
"llm_model": "Qwen3.6-35B"
|
||
}
|
||
```
|
||
|
||
Wenn nicht bereit:
|
||
```json
|
||
{
|
||
"status": "not_ready",
|
||
"llm": "error:Connection refused",
|
||
"database": "unknown"
|
||
}
|
||
```
|
||
|
||
**Mögliche `status`-Werte:**
|
||
- `ready` — Alle geprüften Services sind erreichbar
|
||
- `not_ready` — Mindestens ein Service ist nicht erreichbar
|
||
|
||
---
|
||
|
||
### GET /providers
|
||
|
||
**Beschreibung:** Listet die konfigurierten Provider ohne Secrets.
|
||
|
||
**Request:**
|
||
```
|
||
GET /providers
|
||
```
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"llm": {
|
||
"available": true,
|
||
"model": "Qwen3.6-35B",
|
||
"max_concurrency": 3
|
||
},
|
||
"vision": {
|
||
"available": true,
|
||
"model": "Qwen2.5-VL-3B"
|
||
},
|
||
"audio": {
|
||
"available": true,
|
||
"model": "default"
|
||
}
|
||
}
|
||
```
|
||
|
||
**Falls kein Provider konfiguriert:**
|
||
```json
|
||
{
|
||
"llm": { "available": false },
|
||
"vision": { "available": false },
|
||
"audio": { "available": false }
|
||
}
|
||
```
|
||
|
||
**Wichtig:** Dieser Endpoint gibt **keinerlei** Secrets, API-Keys
|
||
oder sensible Konfigurationswerte zurück.
|
||
|
||
---
|
||
|
||
## Research API (Stage 14+)
|
||
|
||
Alle Research-Endpoints haben das Präfix `/v1/research`.
|
||
|
||
---
|
||
|
||
### POST /v1/research
|
||
|
||
**Beschreibung:** Startet eine neue Recherche asynchron (Background-Pipeline).
|
||
Die Antwort kommt sofort — das eigentliche Ergebnis ist über
|
||
`GET /v1/research/{id}/report` abrufbar.
|
||
|
||
**Request:**
|
||
```json
|
||
{
|
||
"query": "Welche wesentlichen Fortschritte gab es im letzten Jahr bei Kernfusion?",
|
||
"language": "de",
|
||
"depth": "normal",
|
||
"extra_queries": ["Fusion breakthroughs 2025", "commercial fusion progress"]
|
||
}
|
||
```
|
||
|
||
**Parameter:**
|
||
|
||
| Field | Type | Required | Default | Description |
|
||
|-------|------|----------|---------|-------------|
|
||
| `query` | string | yes | — | Forschungsfrage (1–2000 Zeichen) |
|
||
| `language` | string | no | `"de"` | Sprachcode (z.B. `"de"`, `"en"`) |
|
||
| `depth` | string | no | `"normal"` | Suchtiefe: `"quick"`, `"normal"`, `"deep"` |
|
||
| `extra_queries` | string[] | no | `null` | Optionale zusätzliche Suchanfragen |
|
||
|
||
**Depth-Konfiguration:**
|
||
|
||
| Tiefe | max_search_queries | max_sources | max_llm_requests | max_duration | max_context |
|
||
|-------|--------------------|-------------|-------------------|--------------|-------------|
|
||
| `quick` | 10 | 15 | 15 | 300s | 16k |
|
||
| `normal` | 20 | 30 | 30 | 300s | 24k |
|
||
| `deep` | 40 | 60 | 60 | 600s | 32k |
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"status": "pending",
|
||
"query": "Welche Fortschritte bei Kernfusion?",
|
||
"depth": "normal",
|
||
"state": "created"
|
||
}
|
||
```
|
||
|
||
**Error (400):**
|
||
```json
|
||
{
|
||
"detail": "Ungültige Tiefe 'ultra'. Gültig: 'quick', 'normal', 'deep'."
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research
|
||
|
||
**Beschreibung:** Liste aller Research-Runs (paginiert).
|
||
|
||
**Query-Parameter:**
|
||
|
||
| Parameter | Type | Default | Description |
|
||
|-----------|------|---------|-------------|
|
||
| `limit` | int | 10 | Max Anzahl Ergebnisse |
|
||
| `offset` | int | 0 | Offset für Pagination |
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"total": 5,
|
||
"limit": 10,
|
||
"offset": 0,
|
||
"items": [
|
||
{
|
||
"research_id": "uuid-...",
|
||
"query": "Kernfusion",
|
||
"depth": "normal",
|
||
"state": "completed",
|
||
"created_at": "2025-01-01T00:00:00+00:00",
|
||
"source_count": 5,
|
||
"claim_count": 12
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}
|
||
|
||
**Beschreibung:** Metadaten eines Research-Runs.
|
||
|
||
**Path-Parameter:**
|
||
|
||
| Parameter | Type | Description |
|
||
|-----------|------|-------------|
|
||
| `id` | string | UUID des Research-Runs |
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"query": "Kernfusion 2025",
|
||
"depth": "normal",
|
||
"state": "completed",
|
||
"created_at": "2025-01-01T00:00:00+00:00",
|
||
"updated_at": "2025-01-01T00:05:00+00:00",
|
||
"search_count": 20,
|
||
"source_count": 5,
|
||
"claim_count": 12,
|
||
"is_completed": true,
|
||
"is_running": false
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}/status
|
||
|
||
**Beschreibung:** State-Machine Status eines Research-Runs.
|
||
|
||
Identisch zu `GET /v1/research/{id}` — gleicher Response.
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}/sources
|
||
|
||
**Beschreibung:** Quellen für einen Research-Run.
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"sources": [
|
||
{
|
||
"id": "s1",
|
||
"url": "https://example.com/1",
|
||
"title": "Beispiel Quelle",
|
||
"domain": "example.com",
|
||
"source_type": "primary",
|
||
"retrieved_at": "2025-01-01T00:01:00+00:00"
|
||
}
|
||
],
|
||
"total": 1
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}/claims
|
||
|
||
**Beschreibung:** Claims (Behauptungen) für einen Research-Run.
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"claims": [
|
||
{
|
||
"id": "c1",
|
||
"research_run_id": "uuid-...",
|
||
"source_id": "s1",
|
||
"claim_text": "Behauptung A",
|
||
"evidence_span": "Quelle 1, Abschnitt 2",
|
||
"claim_type": "factual",
|
||
"confidence": 0.85
|
||
}
|
||
],
|
||
"total": 1
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}/evidence
|
||
|
||
**Beschreibung:** Evidence-Scores (6-dimensional) für einen Research-Run.
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"evidence": [
|
||
{
|
||
"claim_id": "c1",
|
||
"research_run_id": "uuid-...",
|
||
"evidence_type": "primary_report",
|
||
"source_independence_score": 0.9,
|
||
"primary_source_proximity": 0.95,
|
||
"cross_source_support": 0.7,
|
||
"contradiction_level": 0.2,
|
||
"evidence_directness": 0.88,
|
||
"date_relevance_score": 0.95
|
||
}
|
||
],
|
||
"total": 1
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### GET /v1/research/{id}/report
|
||
|
||
**Beschreibung:** Synthese-Bericht (finaler Research Report).
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"research_id": "uuid-...",
|
||
"query": "Kernfusion 2025",
|
||
"summary": "Zusammenfassung der Recherche...",
|
||
"findings": [
|
||
{
|
||
"text": "Fundamentale Erkenntnis A",
|
||
"confidence": 0.85,
|
||
"source_ids": ["s1", "s2"]
|
||
}
|
||
],
|
||
"disagreements": [
|
||
{
|
||
"claim": "Behauptung X",
|
||
"positions": [
|
||
{"source": "Quelle 1", "view": "Für X"},
|
||
{"source": "Quelle 2", "view": "Gegen X"}
|
||
]
|
||
}
|
||
],
|
||
"uncertainties": ["Nicht ausreichend belegte Behauptung Y"],
|
||
"source_statistics": {
|
||
"total_sources": 5,
|
||
"primary_sources": 2,
|
||
"secondary_sources": 3
|
||
},
|
||
"methodology": "NSCT Evidence Pipeline — Search, Extract, Claim, Compare, Synthesize",
|
||
"generated_at": "2025-01-01T00:00:00+00:00"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### DELETE /v1/research/{id}
|
||
|
||
**Beschreibung:** Löscht einen Research-Run (nur wenn nicht completed).
|
||
|
||
**Response (200 OK):**
|
||
```json
|
||
{
|
||
"status": "deleted",
|
||
"research_id": "uuid-..."
|
||
}
|
||
```
|
||
|
||
**Error (400):** Completed runs sind immutable.
|
||
|
||
---
|
||
|
||
## Prometheus Metrics
|
||
|
||
### GET /metrics
|
||
|
||
**Response:** Prometheus Text Format mit allen Metriken:
|
||
|
||
- `search_queries_total`
|
||
- `sources_discovered_total`
|
||
- `sources_fetched_total`
|
||
- `sources_rejected_total`
|
||
- `claims_extracted_total`
|
||
- `duplicate_sources_total`
|
||
- `contradictions_detected_total`
|
||
- `llm_requests_total`
|
||
- `llm_tokens_input_total`
|
||
- `llm_tokens_output_total`
|
||
- `research_duration_seconds`
|
||
- `research_completed_total`
|
||
- `research_failed_total`
|
||
- `active_research_runs`
|
||
|
||
---
|
||
|
||
## Error Response Format
|
||
|
||
Alle Fehler folgen einem konsistenten Format:
|
||
|
||
```json
|
||
{
|
||
"detail": "Fehlerbeschreibung"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Authentifizierung
|
||
|
||
Stage 22: Keine Authentifizierung. Dies kann in späteren Stages
|
||
hinzugefügt werden (API-Key, OAuth, etc.).
|