Dokumentation » API

API

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-27

REST-API Endpunkte für KI-Integration, Content-Management und Dokumentation.

API-Referenz

Chat API

RAG-Chat mit Vektorsuche und LLM-Integration

Docs API

Dokumentations-CRUD, Suche und RAG-Chat

Tasks API

Task-Management, Zuweisungen, KI-Ausführung

Content API

Content-Aufträge erstellen und bearbeiten

Explorer API

Dokumente, Chunks, Taxonomie, Hybrid-Suche

Config API

System-Prompts und RAG-Konfiguration

Services

OllamaService, QdrantService, ClaudeService

Architektur

Alle APIs sind vollständig in PHP implementiert:

Browser (HTMX/JS)
    ↓
PHP Controller (/src/Controller/Api/)
├── ChatController.php      (RAG-Chat)
├── DocsController.php      (Dokumentation)
├── TaskController.php      (Task-Management)
├── ContentController.php   (Content-Aufträge)
├── ExplorerController.php  (Doc2Vector Explorer)
└── ConfigController.php    (Konfiguration)
    ↓
PHP Services (/src/Infrastructure/AI/)
├── AIConfig.php         (Config & Factory)
├── ChatService.php      (RAG-Orchestrator)
├── OllamaService.php    (Embeddings & LLM)
├── QdrantService.php    (Vektorsuche)
└── ClaudeService.php    (Anthropic LLM)
    ↓
┌─────────────┬─────────────┬─────────────┐
│ Ollama API  │ Qdrant API  │ Claude API  │
│ :11434      │ :6333       │ anthropic   │
└─────────────┴─────────────┴─────────────┘

Endpunkte-Übersicht

Chat API

MethodePfadBeschreibung
POST/api/v1/chatChat-Nachricht senden
GET/api/v1/chat/searchVektorsuche
GET/api/v1/chat/statsStatistiken

Docs API

MethodePfadBeschreibung
GET/api/v1/docsDokumente auflisten
GET/api/v1/docs/{id}Dokument nach ID
GET/api/v1/docs/path/{path}Dokument nach Pfad
GET/api/v1/docs/searchSemantische Suche
GET/api/v1/docs/hierarchyDokumentationsbaum
POST/api/v1/docsDokument erstellen
PUT/api/v1/docs/{id}Dokument aktualisieren
DELETE/api/v1/docs/{id}Dokument löschen
POST/api/v1/docs/chatRAG-Chat

Tasks API

MethodePfadBeschreibung
GET/api/v1/tasksTasks auflisten
GET/api/v1/tasks/statisticsStatistiken
GET/api/v1/tasks/{id}Task-Details
POST/api/v1/tasksTask erstellen
PUT/api/v1/tasks/{id}Task aktualisieren
DELETE/api/v1/tasks/{id}Task löschen
POST/api/v1/tasks/{id}/assignTask zuweisen
PUT/api/v1/tasks/{id}/statusStatus ändern
GET/api/v1/tasks/{id}/resultsErgebnisse abrufen
POST/api/v1/tasks/{id}/resultsErgebnis speichern
POST/api/v1/tasks/{id}/executeKI-Ausführung

Content API

MethodePfadBeschreibung
PUT/api/v1/content/{id}Auftrag aktualisieren

Explorer API

MethodePfadBeschreibung
GET/api/v1/explorer/statsStatistiken
GET/api/v1/explorer/dokumenteDokumente-Liste
GET/api/v1/explorer/dokumente/{id}Dokument-Details
GET/api/v1/explorer/seitenSeiten-Liste
GET/api/v1/explorer/seiten/{id}Seite-Details
GET/api/v1/explorer/chunksChunks-Liste
GET/api/v1/explorer/chunks/{id}Chunk-Details
GET/api/v1/explorer/taxonomieTaxonomie
GET/api/v1/explorer/entitiesEntities
POST/api/v1/explorer/sucheHybrid-Suche

Config API

MethodePfadBeschreibung
GET/api/v1/config/{id}Config abrufen
POST/api/v1/config/{id}Config aktualisieren

Response-Format

Alle APIs verwenden ein einheitliches JSON-Response-Format:

Erfolg

{
  "success": true,
  "data": { ... },
  "meta": {
    "total": 100,
    "limit": 50,
    "offset": 0
  }
}

Fehler

{
  "success": false,
  "error": "Fehlermeldung"
}

Authentifizierung

Schreibende Operationen (POST, PUT, DELETE) erfordern einen CSRF-Token:

X-CSRF-TOKEN: {token}

Services

ServicePfadFunktion
AIConfig/src/Infrastructure/AI/AIConfig.phpConfig & Factory
ChatService/src/Infrastructure/AI/ChatService.phpRAG-Orchestrator
OllamaService/src/Infrastructure/AI/OllamaService.phpEmbeddings & LLM
QdrantService/src/Infrastructure/AI/QdrantService.phpVektorsuche
ClaudeService/src/Infrastructure/AI/ClaudeService.phpLLM-Antworten
]]>
Dokumentation » API » Docs API

Docs API

Erstellt: 2025-12-27 | Aktualisiert: 2025-12-27

REST-API für Dokumentations-Management mit CRUD-Operationen, semantischer Suche und RAG-Chat.

ControllerController\Api\DocsController
Base-URL/api/v1/docs
Datenbankki_dev.dokumentation
FormatJSON

Endpoints-Übersicht

MethodePfadBeschreibung
GET/api/v1/docsListe aller Dokumente
GET/api/v1/docs/{id}Dokument nach ID
GET/api/v1/docs/path/{path}Dokument nach Pfad
GET/api/v1/docs/searchSemantische Suche
GET/api/v1/docs/hierarchyDokumentationsbaum
POST/api/v1/docsDokument erstellen
PUT/api/v1/docs/{id}Dokument aktualisieren
DELETE/api/v1/docs/{id}Dokument löschen
POST/api/v1/docs/chatRAG-Chat mit Dokumentation

Dokumente auflisten

GET /api/v1/docs?status=published&parent_id=51&search=apache&limit=50&offset=0
ParameterTypDefaultBeschreibung
statusstring-published, draft
parent_idint-Filter nach Parent-Dokument
searchstring-Volltextsuche in Titel/Content
limitint50Max. Ergebnisse (max 100)
offsetint0Pagination-Offset

Response

{
  "success": true,
  "data": [
    {
      "id": 1,
      "parent_id": null,
      "slug": "server",
      "path": "/server",
      "title": "Server",
      "description": "Server-Dokumentation",
      "status": "published",
      "depth": 0,
      "created_at": "2025-12-20T10:00:00",
      "updated_at": "2025-12-27T12:00:00"
    }
  ],
  "meta": {
    "total": 100,
    "limit": 50,
    "offset": 0
  }
}

Dokument nach ID

GET /api/v1/docs/{id}?include_children=1&include_breadcrumb=1
ParameterTypBeschreibung
include_children0|1Kind-Dokumente einschließen
include_breadcrumb0|1Breadcrumb-Pfad einschließen

Response

{
  "success": true,
  "data": {
    "id": 51,
    "title": "API",
    "path": "/api",
    "content": "...",
    ...
  },
  "children": [...],
  "breadcrumb": [
    {"id": 51, "title": "API", "path": "/api"}
  ]
}

Dokument nach Pfad

GET /api/v1/docs/path/api/chat

Liefert Dokument mit Pfad /api/chat.

Semantische Suche

GET /api/v1/docs/search?q=Apache+SSL&limit=5&category=Betrieb
ParameterTypDefaultBeschreibung
qstringrequiredSuchanfrage
limitint5Max. Ergebnisse
categorystring-Taxonomie-Kategorie-Filter

Response

{
  "success": true,
  "data": [
    {
      "chunk_id": 42,
      "content": "Apache SSL Konfiguration...",
      "score": 0.92,
      "dokument_title": "Apache",
      "path": "/server/apache"
    }
  ],
  "meta": {
    "query": "Apache SSL",
    "limit": 5,
    "count": 3
  }
}

Dokumentationsbaum

GET /api/v1/docs/hierarchy

Liefert vollständigen Dokumentationsbaum als verschachtelte Struktur.

Response

{
  "success": true,
  "data": [
    {
      "id": 1,
      "title": "Server",
      "path": "/server",
      "children": [
        {"id": 2, "title": "SSH", "path": "/server/ssh", "children": []},
        {"id": 3, "title": "UFW", "path": "/server/ufw", "children": []}
      ]
    }
  ]
}

Dokument erstellen

POST /api/v1/docs
Content-Type: application/json

{
  "title": "Neues Dokument",
  "slug": "neues-dokument",
  "content": "

Inhalt

Text...

", "description": "Beschreibung", "parent_id": 51, "status": "draft", "sort_order": 10 }
FeldTypPflichtBeschreibung
titlestringJaDokumenttitel
slugstringJaURL-Slug (eindeutig pro Parent)
contentstringNeinHTML-Inhalt
descriptionstringNeinKurzbeschreibung
parent_idintNeinParent-Dokument-ID
statusstringNeindraft (default) oder published
sort_orderintNeinSortierreihenfolge

Response (201 Created)

{
  "success": true,
  "data": {...},
  "message": "Dokument erstellt"
}

Dokument aktualisieren

PUT /api/v1/docs/{id}
Content-Type: application/json

{
  "title": "Aktualisierter Titel",
  "content": "

Neuer Inhalt

", "description": "Neue Beschreibung", "status": "published" }

Alle Felder sind optional - nur übergebene Felder werden aktualisiert.

Dokument löschen

DELETE /api/v1/docs/{id}

Wichtig: Dokumente mit Unterdokumenten können nicht gelöscht werden. Lösche zuerst alle Kind-Dokumente.

Fehler-Response

{
  "success": false,
  "error": "Dokument hat Unterdokumente. Lösche diese zuerst."
}

RAG-Chat

POST /api/v1/docs/chat
Content-Type: application/json

{
  "question": "Wie konfiguriere ich Apache SSL?",
  "model": "mistral",
  "limit": 5
}
ParameterTypDefaultBeschreibung
questionstringrequiredBenutzer-Frage
modelstringmistralLLM-Modell (Ollama)
limitint5Max. Kontext-Chunks

Response

{
  "success": true,
  "data": {
    "answer": "Um Apache SSL zu konfigurieren...",
    "sources": [
      {"title": "Apache", "path": "/server/apache", "score": 0.89}
    ],
    "model": "mistral",
    "tokens": {"input": 1200, "output": 350}
  }
}

Fehlerbehandlung

HTTP CodeBedeutung
400Fehlende oder ungültige Parameter
404Dokument nicht gefunden
500Server-Fehler

Services

ServiceBeschreibung
DokumentationRepositoryCRUD-Operationen für Dokumente
ChunkSearchServiceSemantische Suche über Chunks
DocumentationChatUseCaseRAG-Chat mit Dokumentation

Verwandte Dokumentation

]]>
Dokumentation » API » Config API

Config API

Erstellt: 2025-12-27 | Aktualisiert: 2025-12-31

REST-API für Config-Management. Ermöglicht das Abrufen und Aktualisieren von System-Konfigurationen wie Prompts, Strukturen und Autorenprofile.

ControllerController\Api\ConfigController
Base-URL/api/v1/config
Datenbankki_content.content_config
UseCaseUseCases\Config\ManageConfigUseCase

Endpoints-Übersicht

MethodePfadBeschreibung
GET/api/v1/config/{id}Config abrufen
POST/api/v1/config/{id}Config aktualisieren

Config abrufen

GET /api/v1/config/{id}

Response

{
  "id": 1,
  "name": "System Prompt",
  "type": "system_prompt",
  "content": "Du bist ein hilfreicher Assistent...",
  "version": "1.5"
}

Response-Felder

FeldTypBeschreibung
idintConfig-ID
namestringConfig-Name
typestringConfig-Typ (siehe unten)
contentstringConfig-Inhalt
versionstringAktuelle Version

Fehler-Response (404)

{
  "error": "Config nicht gefunden"
}

Config aktualisieren

POST /api/v1/config/{id}
Content-Type: application/x-www-form-urlencoded
X-CSRF-TOKEN: {token}

content=Neuer+Config-Inhalt...

Request-Parameter

ParameterTypBeschreibung
contentstringNeuer Config-Inhalt

Hinweis: Die Version wird automatisch inkrementiert (1.5 → 1.6).

Response

{
  "success": true,
  "version": "1.6",
  "message": "Version 1.6 gespeichert"
}

Fehler-Response (400)

{
  "error": "Validierungsfehler..."
}

Authentifizierung

Das POST-Endpoint erfordert einen gültigen CSRF-Token im Header:

X-CSRF-TOKEN: abc123...

Config-Typen

TypBeschreibungBeispiel
author_profileAutorenprofile für SchreibstilKarl Kratz Stil, Akademisch
structureOutput-StrukturenLinkedIn-Post, Blog-Artikel
organizationOrganisations-InfosFirmenkontext
contractContent-VerträgeQualitätsregeln
ruleEinzelne RegelnFormatvorgaben
system_promptSystem-Prompts für ChatRAG-Prompt, Coaching-Prompt
criticKritik-PromptsQualitätsprüfer

Versionierung

Jede Änderung erstellt eine neue Version:

Fehlerbehandlung

HTTP CodeBedeutung
400Validierungsfehler
403CSRF-Token ungültig
404Config nicht gefunden
500Server-Fehler

Datenmodell

content_config (ki_content)

FeldTypNullBeschreibung
idint(11)NOPrimärschlüssel
typeenumNOauthor_profile, structure, organization, contract, rule, system_prompt, critic
namevarchar(100)NOConfig-Name
slugvarchar(100)NOURL-Slug
descriptiontextYESBeschreibung
contentlongtextNOConfig-Inhalt
versionvarchar(20)YESAktuelle Version (Default: 1.0)
statusenumYESdraft, active, deprecated (Default: draft)
parent_idint(11)YESParent-Config (optional)
prompt_idint(11)YESVerknüpfter Prompt
sort_orderint(11)NOSortierung (Default: 0)
created_atdatetimeYESErstellungsdatum
updated_atdatetimeYESLetzte Änderung

Verwandte Dokumentation

]]>
Dokumentation » API » Chat

Chat API

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-31

RAG-basierter Chat mit Vektorsuche und LLM-Integration. Verwendet lokale Embeddings (Ollama), Vektorsuche (Qdrant) und Claude (Anthropic) oder Ollama als LLM.

Endpoints-Übersicht

MethodePfadControllerBeschreibung
POST/api/v1/chatApi\ChatControllerEinfache Chat-Anfrage (JSON)
GET/api/v1/chat/searchApi\ChatControllerChunk-Suche
GET/api/v1/chat/statsApi\ChatControllerPipeline-Statistiken
POST/chat/{uuid}/messageChatControllerChat-Nachricht senden (HTML/HTMX)

JSON API: POST /api/v1/chat

Einfache Chat-Anfrage mit festen Einstellungen.

ControllerController\Api\ChatController
ServiceInfrastructure\AI\ChatService

Request

POST /api/v1/chat
Content-Type: application/json

{
    "message": "Was ist systemische Therapie?"
}
ParameterTypBeschreibung
messagestringBenutzer-Frage (required)

Hinweis: Dieser Endpunkt verwendet feste Einstellungen: Claude Opus 4.5, Collection "dokumentation_chunks", Limit 5. Für konfigurierbare Optionen den HTML-Endpunkt verwenden.

Response

{
    "answer": "Systemische Therapie ist ein psychotherapeutischer Ansatz...",
    "sources": [
        {
            "title": "Einführung in die systemische Therapie",
            "content": "...",
            "score": 0.89,
            "path": "/Documents/therapie/einfuehrung.pdf"
        }
    ],
    "model": "claude-opus-4-5-20251101",
    "tokens": 1234
}

HTML-Endpunkt: POST /chat/{uuid}/message

Vollständig konfigurierbarer Chat mit Session-Unterstützung.

ControllerController\ChatController

Request

POST /chat/{uuid}/message
Content-Type: application/x-www-form-urlencoded

message=Was+ist+systemische+Therapie%3F
&model=anthropic
&collections[]=documents
&collections[]=dokumentation
&contextLimit=5
&systemPromptId=1
&structureId=2
&qualityCheck=1

Parameter

ParameterTypDefaultBeschreibung
messagestringrequiredBenutzer-Frage
modelstring"anthropic""anthropic" (Claude) oder "ollama" (lokal)
collections[]string[]["documents"]Qdrant Collections (Array)
contextLimitint5Max. Kontext-Chunks (3/5/10/15)
systemPromptIdintnullSystem-Prompt aus content_config
structureIdintnullOutput-Struktur
qualityCheckint0Qualitätsprüfung aktivieren
author_profile_idintnullAutorenprofil für Schreibstil

GET /api/v1/chat/search

Suche nach relevanten Chunks ohne LLM-Anfrage.

GET /api/v1/chat/search?q=systemische+therapie&limit=5

Response

{
    "results": [
        {"id": 42, "score": 0.89, "payload": {...}}
    ]
}

GET /api/v1/chat/stats

Pipeline-Statistiken (Doc2Vector).

{
    "dokumente": 15,
    "seiten": 120,
    "chunks": 450,
    "tokens": 125000,
    "analyzed": 400,
    "synced": 380
}

RAG-Pipeline

1. Embedding erstellen (OllamaService)
   question → mxbai-embed-large → [1024-dim vector]

2. Vektorsuche (QdrantService)
   vector → Qdrant :6333 → top-k similar chunks

3. Kontext aufbauen (ChatService)
   chunks → formatierter Kontext mit Quellenangaben
   max. 3000 tokens (~12000 chars)

4. LLM-Anfrage (ClaudeService oder OllamaService)
   system_prompt + rag_prompt + context → answer

5. Response zusammenstellen (ChatService)
   answer + sources + metadata + usage

Fehlerbehandlung

HTTP CodeBedeutung
400Fehlende oder ungültige Parameter
500Service-Fehler (Ollama, Qdrant, Claude)
503Service nicht verfügbar
]]>
Dokumentation » API » Content API

Content API

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-31

REST-API für das Content Studio.

ControllerController\Api\ContentController
Base-URL/api/v1/content
FormatJSON
AuthentifizierungCSRF-Token erforderlich

Endpoints

MethodeEndpointBeschreibung
PUT/api/v1/content/{id}Auftrag aktualisieren

PUT /api/v1/content/{id}

Aktualisiert einen bestehenden Content-Auftrag.

Request-Body

{
  "title": "Neuer Titel",                  // required
  "briefing": "Aktualisiertes Briefing",   // required
  "author_profile_id": 1,                  // optional
  "contract_id": 1,                        // optional
  "structure_id": 1                        // optional
}

Beispiel

curl -X PUT https://dev.campus.systemische-tools.de/api/v1/content/1 \
  -H "Content-Type: application/json" \
  -H "X-CSRF-TOKEN: abc123..." \
  -d '{
    "title": "Blogpost über Teamcoaching",
    "briefing": "Schreibe einen informativen Artikel...",
    "author_profile_id": 1,
    "structure_id": 1
  }'

Response (200 OK)

{
  "success": true,
  "data": {
    "id": 1,
    "title": "Blogpost über Teamcoaching",
    "briefing": "Schreibe einen informativen Artikel...",
    "status": "draft",
    "author_profile_id": 1,
    "contract_id": null,
    "structure_id": 1,
    "profile_name": "Akademisch",
    "contract_name": null,
    "structure_name": "Blog-Artikel",
    "created_at": "2025-12-20 10:00:00",
    "updated_at": "2025-12-20 12:30:00"
  }
}

Error-Responses

// 400 Bad Request
{
  "success": false,
  "error": "Titel ist erforderlich"
}

// 404 Not Found
{
  "success": false,
  "error": "Auftrag nicht gefunden"
}

Workflow-Endpoints (HTMX)

Die folgenden Endpoints werden primär über HTMX aufgerufen und liefern HTML-Fragmente:

MethodeEndpointBeschreibung
POST/content/{id}/generateContent generieren
POST/content/{id}/critiqueKritik-Runde starten
POST/content/{id}/reviseRevision erstellen
POST/content/{id}/approveContent genehmigen
POST/content/{id}/declineContent ablehnen

← Zurück zur Content Studio Dokumentation

]]>
Dokumentation » API » Tasks API

Tasks API

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-31

REST-API für Task-Management mit Zuweisungen, Ergebnissen und KI-Ausführung.

ControllerController\Api\TaskController
Base-URL/api/v1/tasks
FormatJSON

Endpoints

Tasks auflisten

GET /api/v1/tasks?status=pending&type=ai_task&limit=50&offset=0
ParameterTypBeschreibung
statusstringpending, in_progress, completed, failed, cancelled
typestringhuman_task, ai_task, mixed
searchstringVolltextsuche
limitintMax. Ergebnisse (default: 50)
offsetintPagination-Offset

Task erstellen

POST /api/v1/tasks
Content-Type: application/json

{
  "title": "Dokumentation prüfen",
  "description": "Alle Links in der Doku validieren",
  "type": "ai_task",
  "due_date": "2025-12-25T12:00:00Z"
}

Task-Details abrufen

GET /api/v1/tasks/{id}

Liefert Task mit Assignments und Results.

Task aktualisieren

PUT /api/v1/tasks/{id}
Content-Type: application/json

{
  "title": "Neuer Titel",
  "description": "Neue Beschreibung",
  "type": "mixed",
  "due_date": "2025-12-30T18:00:00Z"
}

Task löschen

DELETE /api/v1/tasks/{id}

Status ändern

PUT /api/v1/tasks/{id}/status
Content-Type: application/json

{
  "status": "in_progress",
  "updated_by": "claude",
  "updated_by_type": "ai"
}

Task zuweisen

POST /api/v1/tasks/{id}/assign
Content-Type: application/json

{
  "assignee": "claude",
  "assignee_type": "claude",
  "model_name": "claude-3-5-sonnet",
  "notes": "Priorität hoch"
}

Ergebnis speichern

POST /api/v1/tasks/{id}/results
Content-Type: application/json

{
  "executor": "claude",
  "executor_type": "claude",
  "model_name": "claude-3-5-sonnet",
  "response": "Task erfolgreich abgeschlossen",
  "status": "success",
  "tokens_input": 1500,
  "tokens_output": 500
}

Ergebnisse abrufen

GET /api/v1/tasks/{id}/results

KI-Ausführung

POST /api/v1/tasks/{id}/execute
Content-Type: application/json

{
  "model": "mistral",
  "auto_complete": true
}

Führt den Task mit lokalem Ollama aus.

Statistiken

GET /api/v1/tasks/statistics

Liefert Statistiken zu Tasks, Token-Verbrauch und Modell-Nutzung.

Response

{
  "success": true,
  "data": {
    "tasks": {
      "by_status": {"pending": 10, "completed": 50, ...},
      "by_type": {"ai_task": 30, "human_task": 20, ...},
      "total": 60
    },
    "tokens": {
      "total_input": 150000,
      "total_output": 50000,
      "total": 200000
    },
    "models": [
      {"model_name": "claude-opus-4-5", "count": 25, "total_tokens": 80000},
      {"model_name": "mistral", "count": 15, "total_tokens": 40000}
    ]
  }
}

Response-Format

Erfolg

{
  "success": true,
  "data": { ... },
  "meta": {
    "total": 42,
    "limit": 50,
    "offset": 0
  }
}

Fehler

{
  "success": false,
  "error": "Fehlermeldung"
}

Task-Objekt

{
  "id": 100,
  "uuid": "76c8b3ed-...",
  "title": "Dokumentation prüfen",
  "description": "...",
  "type": "ai_task",
  "status": "pending",
  "created_by": "mcp-tasks",
  "created_by_type": "ai",
  "parent_task_id": null,
  "due_date": "2025-12-25T12:00:00",
  "created_at": "2025-12-20T10:00:00",
  "updated_at": "2025-12-20T10:00:00",
  "completed_at": null
}

UseCases

UseCaseBeschreibung
GetTasksUseCaseTasks laden und filtern
CreateTaskUseCaseTask erstellen
UpdateTaskStatusUseCaseStatus ändern
DeleteTaskUseCaseTask löschen
AssignTaskUseCaseZuweisung erstellen
SaveTaskResultUseCaseErgebnis speichern
ExecuteAITaskUseCaseKI-Ausführung mit Ollama

Verwandte Dokumentation

]]>

AI Services

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-27

PHP-Service-Klassen für KI-Integration. Native HTTP-Clients für Ollama, Qdrant und Claude API.

Pfad/src/Infrastructure/AI/
NamespaceInfrastructure\AI
Contractlayered-architecture-pruefung_v1.0.yaml
StatusProduktiv (Migration von Python abgeschlossen)

AIConfig

Zentralisierte Konfiguration und Service-Factory für alle AI-Services.

DateiAIConfig.php
Typreadonly class
FunktionConfig-Management, Service-Factory, Credentials-Loading

Properties

final readonly class AIConfig
{
    public string $ollamaHost;           // http://localhost:11434
    public string $qdrantHost;           // http://localhost:6333
    public string $anthropicApiKey;      // sk-ant-... (aus credentials.md)
    public string $embeddingModel;       // mxbai-embed-large
    public string $claudeModel;          // claude-opus-4-5-20251101
    public string $defaultCollection;    // documents
}

Factory-Methoden

// Config erstellen (lädt API-Key aus credentials.md)
$config = AIConfig::fromCredentialsFile();

// Einzelne Services erstellen
$ollama = $config->createOllamaService();
$qdrant = $config->createQdrantService();
$claude = $config->createClaudeService();

// Vollständiger ChatService (alle Dependencies)
$chatService = $config->createChatService();

Verwendung

use Infrastructure\AI\AIConfig;

// Einfachster Weg: ChatService direkt nutzen
$config = AIConfig::fromCredentialsFile();
$chat = $config->createChatService();
$result = $chat->chat('Was ist systemisches Coaching?');

// Alternative: Einzelne Services für spezielle Aufgaben
$config = AIConfig::fromCredentialsFile();
$ollama = $config->createOllamaService();
$embedding = $ollama->getEmbedding('Text zum Einbetten');

OllamaService

Embedding-Generierung und LLM-Generierung via Ollama REST API.

DateiOllamaService.php
Hosthttp://localhost:11434
Embedding-Modelmxbai-embed-large
LLM-Modelgemma3:4b-it-qat
Dimension1024

Methoden

final readonly class OllamaService
{
    public function __construct(string $host = 'http://localhost:11434');

    /**
     * Generiert Embedding-Vektor für Text.
     * @return array<int, float> 1024-dimensionaler Vektor
     * @throws RuntimeException
     */
    public function getEmbedding(
        string $text,
        string $model = 'mxbai-embed-large'
    ): array;

    /**
     * Generiert Text-Antwort mit Ollama-LLM.
     * @throws RuntimeException
     */
    public function generate(
        string $prompt,
        string $model = 'gemma3:4b-it-qat'
    ): string;

    /**
     * Prüft ob Ollama API erreichbar ist.
     */
    public function isAvailable(): bool;
}

Code-Beispiel

use Infrastructure\AI\OllamaService;

$ollama = new OllamaService('http://localhost:11434');

// Embedding erstellen
$embedding = $ollama->getEmbedding('Hello World');
// Returns: [0.123, -0.456, 0.789, ...] (1024 floats)

// Text generieren
$response = $ollama->generate('Explain quantum computing.');
// Returns: "Quantum computing is a type of computing that..."

// Health Check
if ($ollama->isAvailable()) {
    echo "Ollama läuft";
}

API-Aufruf

POST http://localhost:11434/api/embeddings
Content-Type: application/json

{
    "model": "mxbai-embed-large",
    "prompt": "Text zum Einbetten"
}

Response:
{
    "embedding": [0.123, -0.456, ...]
}

QdrantService

Vektorsuche via Qdrant REST API.

DateiQdrantService.php
Hosthttp://localhost:6333
Collectiondocuments
DistanceCosine
Timeout30s

Methoden

final readonly class QdrantService
{
    public function __construct(string $host = 'http://localhost:6333');

    /**
     * Sucht ähnliche Dokumente per Vektor-Similarity.
     * @param array<int, float> $vector Embedding-Vektor
     * @return array<int, array{id: int|string, score: float, payload: array}>
     * @throws RuntimeException
     */
    public function search(
        array $vector,
        string $collection = 'documents',
        int $limit = 5
    ): array;

    /**
     * Prüft ob Collection existiert.
     */
    public function collectionExists(string $collection): bool;

    /**
     * Prüft ob Qdrant API erreichbar ist.
     */
    public function isAvailable(): bool;

    /**
     * Holt Collection-Informationen.
     * @return array<string, mixed>|null
     * @throws RuntimeException
     */
    public function getCollectionInfo(string $collection): ?array;
}

Code-Beispiel

use Infrastructure\AI\QdrantService;

$qdrant = new QdrantService('http://localhost:6333');

// Vektorsuche
$vector = [0.123, -0.456, 0.789, ...]; // 1024-dimensional
$results = $qdrant->search($vector, 'documents', 5);
// Returns: [
//   ['id' => 1, 'score' => 0.89, 'payload' => ['content' => '...', 'title' => '...']],
//   ['id' => 2, 'score' => 0.76, 'payload' => ['content' => '...', 'title' => '...']]
// ]

// Collection prüfen
if ($qdrant->collectionExists('documents')) {
    $info = $qdrant->getCollectionInfo('documents');
    echo "Vektoren: " . $info['vectors_count'];
}

API-Aufruf

POST http://localhost:6333/collections/documents/points/search
Content-Type: application/json

{
    "vector": [0.123, -0.456, ...],
    "limit": 5,
    "with_payload": true
}

Response:
{
    "result": [
        {
            "id": 1,
            "score": 0.89,
            "payload": {
                "content": "...",
                "document_title": "..."
            }
        }
    ]
}

ClaudeService

LLM-Anfragen via Anthropic API.

DateiClaudeService.php
APIhttps://api.anthropic.com/v1/messages
API Version2023-06-01
Modelclaude-opus-4-5-20251101
Max Tokens4000
Timeout120s

Methoden

final readonly class ClaudeService
{
    public function __construct(string $apiKey);

    /**
     * Sendet Prompt an Claude und gibt Antwort zurück.
     * @return array{text: string, usage: array{input_tokens: int, output_tokens: int}}
     * @throws RuntimeException
     */
    public function ask(
        string $prompt,
        ?string $systemPrompt = null,
        string $model = 'claude-opus-4-5-20251101',
        int $maxTokens = 4000
    ): array;

    /**
     * Erstellt RAG-Prompt mit Kontext.
     */
    public function buildRagPrompt(string $question, string $context): string;

    /**
     * Liefert Standard-System-Prompt für RAG.
     */
    public function getDefaultSystemPrompt(): string;

    /**
     * Prüft ob Claude API erreichbar ist.
     */
    public function isAvailable(): bool;
}

Code-Beispiel

use Infrastructure\AI\ClaudeService;

$claude = new ClaudeService('sk-ant-...');

// Einfache Anfrage
$result = $claude->ask('Explain quantum computing');
echo $result['text'];
echo "Tokens: " . $result['usage']['output_tokens'];

// Mit System-Prompt
$system = 'You are a physics teacher.';
$result = $claude->ask('Explain relativity', $system);

// RAG-Prompt erstellen
$question = 'Was ist systemisches Coaching?';
$context = '[Quelle 1: Coaching Grundlagen]\nSystemisches Coaching betrachtet...';
$prompt = $claude->buildRagPrompt($question, $context);
$systemPrompt = $claude->getDefaultSystemPrompt();
$result = $claude->ask($prompt, $systemPrompt);

API-Aufruf

POST https://api.anthropic.com/v1/messages
Content-Type: application/json
x-api-key: sk-ant-...
anthropic-version: 2023-06-01

{
    "model": "claude-opus-4-5-20251101",
    "max_tokens": 4000,
    "system": "Du bist ein hilfreicher Assistent...",
    "messages": [
        {
            "role": "user",
            "content": "..."
        }
    ]
}

Response:
{
    "content": [
        {
            "type": "text",
            "text": "..."
        }
    ],
    "usage": {
        "input_tokens": 100,
        "output_tokens": 200
    }
}

ChatService

Orchestriert RAG-Pipeline mit allen Services. Vollständiger Ablauf: Embedding → Vektorsuche → Kontext → LLM-Antwort.

DateiChatService.php
AbhängigkeitenOllamaService, QdrantService, ClaudeService
Pipeline-Schritte6 (Embedding, Search, Context, LLM, Sources, Response)

Methoden

final readonly class ChatService
{
    public function __construct(
        OllamaService $ollama,
        QdrantService $qdrant,
        ClaudeService $claude
    );

    /**
     * Führt vollständige RAG-Chat-Pipeline aus.
     * @return array{
     *   question: string,
     *   answer: string,
     *   sources: array,
     *   model: string,
     *   usage?: array,
     *   chunks_used: int
     * }
     * @throws RuntimeException
     */
    public function chat(
        string $question,
        string $model = 'anthropic',
        string $collection = 'documents',
        int $limit = 5
    ): array;
}

Code-Beispiel

use Infrastructure\AI\AIConfig;

// Mit Factory (empfohlen)
$config = AIConfig::fromCredentialsFile();
$chat = $config->createChatService();

$result = $chat->chat(
    question: 'Was ist systemisches Coaching?',
    model: 'anthropic',
    collection: 'documents',
    limit: 5
);

echo $result['answer'];
echo "Chunks: " . $result['chunks_used'];
foreach ($result['sources'] as $source) {
    echo $source['title'] . " (Score: " . $source['score'] . ")";
}

Response-Struktur

{
    "question": "Was ist systemisches Coaching?",
    "answer": "Systemisches Coaching ist ein Ansatz...",
    "sources": [
        {
            "title": "Coaching Grundlagen",
            "score": 0.89,
            "content": "..."
        }
    ],
    "model": "anthropic",
    "usage": {
        "input_tokens": 234,
        "output_tokens": 567
    },
    "chunks_used": 5
}

Fehlerbehandlung

Alle Services werfen RuntimeException bei Fehlern:

ServiceFehlerfall
OllamaServiceAPI nicht erreichbar, ungültiges Embedding, Timeout
QdrantServiceAPI nicht erreichbar, Collection fehlt, ungültige Antwort
ClaudeServiceAPI nicht erreichbar, ungültiger API-Key, Rate-Limit, Timeout
ChatServiceEmbedding-Fehler, Search-Fehler, keine Dokumente, LLM-Fehler
try {
    $result = $chat->chat('Was ist systemisches Coaching?');
} catch (RuntimeException $e) {
    error_log('Chat failed: ' . $e->getMessage());
    // Fehlerbehandlung
}

Konfiguration

Alle Konfigurationswerte werden von AIConfig verwaltet:

ParameterDefault-WertQuelle
ollamaHosthttp://localhost:11434AIConfig
qdrantHosthttp://localhost:6333AIConfig
anthropicApiKeysk-ant-.../var/www/docs/credentials/credentials.md
embeddingModelmxbai-embed-largeAIConfig
claudeModelclaude-opus-4-5-20251101AIConfig
defaultCollectiondocumentsAIConfig

Custom-Konfiguration

use Infrastructure\AI\AIConfig;

// Vollständig custom
$config = new AIConfig(
    ollamaHost: 'http://192.168.1.100:11434',
    qdrantHost: 'http://192.168.1.101:6333',
    anthropicApiKey: 'sk-ant-...',
    embeddingModel: 'mxbai-embed-large',
    claudeModel: 'claude-opus-4-5-20251101',
    defaultCollection: 'my_docs'
);

$chat = $config->createChatService();
Dokumentation » API » Explorer API

Explorer API

Erstellt: 2025-12-20 | Aktualisiert: 2025-12-31

REST-API für den Doc2Vector Explorer mit Dokumenten, Seiten, Chunks, Entitäten, Taxonomie und Suche.

ControllerController\Api\ExplorerController
Base-URL/api/v1/explorer
Datenbankki_content (documents, chunks, entities, ...)

Endpoints-Übersicht

MethodePfadBeschreibung
GET/api/v1/explorer/statsStatistiken
GET/api/v1/explorer/dokumenteAlle Dokumente
GET/api/v1/explorer/dokumente/{id}Dokument-Details
GET/api/v1/explorer/seitenAlle Seiten
GET/api/v1/explorer/seiten/{id}Seiten-Details
GET/api/v1/explorer/chunksAlle Chunks
GET/api/v1/explorer/chunks/{id}Chunk-Details
GET/api/v1/explorer/taxonomieTaxonomie-Kategorien
GET/api/v1/explorer/entitiesEntitäten gruppiert
POST/api/v1/explorer/sucheHybrid-Suche

Statistiken

GET /api/v1/explorer/stats

Liefert Übersicht über alle Daten:

{
  "success": true,
  "data": {
    "dokumente": 15,
    "seiten": 120,
    "chunks": {
      "total": 450,
      "tokens": 125000,
      "analyzed": 400,
      "synced": 380
    },
    "taxonomy_categories": [...]
  }
}

Dokumente

Liste aller Dokumente

GET /api/v1/explorer/dokumente

Liefert alle Quelldokumente mit Statistiken.

Dokument-Details

GET /api/v1/explorer/dokumente/{id}

Liefert Dokument mit zugehörigen Seiten und Taxonomie.

Seiten

Seiten auflisten

GET /api/v1/explorer/seiten?search=&parent_id=&limit=50&offset=0
ParameterTypBeschreibung
searchstringSuche in Inhalt
parent_idintFilter nach Parent-Dokument
limitintMax. Ergebnisse (max 50)
offsetintPagination-Offset

Seiten-Details

GET /api/v1/explorer/seiten/{id}

Liefert Seite mit Chunks und Unterseiten.

Chunks

Chunks auflisten

GET /api/v1/explorer/chunks?category=&status=&search=&limit=50&offset=0
ParameterTypBeschreibung
categorystringTaxonomie-Kategorie
statusstringChunk-Status
searchstringSuche in Content
limitintMax. Ergebnisse (max 50)
offsetintPagination-Offset

Chunk-Details

GET /api/v1/explorer/chunks/{id}

Liefert Chunk mit allen Metadaten:

{
  "success": true,
  "data": {
    "id": 42,
    "chunk_index": 3,
    "content": "...",
    "token_count": 280,
    "entities": [
      {"name": "Carl Rogers", "type": "PERSON"}
    ],
    "keywords": ["Therapie", "Empathie"],
    "qdrant_id": "abc123..."
  }
}

Taxonomie

GET /api/v1/explorer/taxonomie

Liefert Top-Kategorien und Keywords:

{
  "success": true,
  "data": {
    "categories": [...],
    "top_keywords": [...]
  }
}

Entitäten

GET /api/v1/explorer/entities

Liefert Entitäten gruppiert nach Typ.

Hybrid-Suche

POST /api/v1/explorer/suche
Content-Type: application/json

{
  "query": "Systemische Therapie",
  "category": "Psychotherapie",
  "limit": 10
}

Kombiniert Vektor- und Keyword-Suche:

{
  "success": true,
  "data": {
    "query": "Systemische Therapie",
    "results": [...],
    "suggestions": [...],
    "count": 8
  }
}

Response-Format

{
  "success": true,
  "data": { ... },
  "meta": {
    "total": 450,
    "limit": 50,
    "offset": 0
  }
}

Datenmodell

documents (ki_content)

FeldTypBeschreibung
idintPrimärschlüssel
filenamevarcharDateiname
titlevarcharTitel
sourcevarcharQuelle (Nextcloud-Pfad)
page_countintSeitenanzahl
statusenumpending, processing, completed, error

chunks (ki_content)

FeldTypBeschreibung
idintPrimärschlüssel
document_idintFK zu documents
chunk_indexintPosition in Dokument
contenttextChunk-Inhalt
token_countintToken-Anzahl
embedding_modelvarcharVerwendetes Modell
qdrant_idvarcharQdrant-Vektor-ID

entities (ki_content)

FeldTypBeschreibung
idintPrimärschlüssel
namevarcharEntity-Name
canonical_namevarcharNormalisierter Name
typeenumPERSON, CONCEPT, ORGANIZATION, ...

Verwandte Dokumentation

]]>