Files
KI-Cluster-Roadmap/00_Globale_Richtlinien/Planung/Komponenten_Standardstruktur.md
2025-11-12 11:49:38 +01:00

471 lines
17 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 🧩 Komponenten-Standardstruktur
## 1. Ziel
Dieses Dokument beschreibt die einheitliche interne Struktur, den Lebenszyklus und die Schnittstellen aller Programme, Module und Komponenten im KI-Cluster.
Ziel ist, dass jede Komponente ob Router, API-Server, Agent, Speicher oder Tool nach demselben Aufbau funktioniert und sich konsistent starten, erweitern und warten lässt.
---
## 2. Grundprinzip
Jede Komponente ist ein eigenständiges, klar abgegrenztes Modul.
Eine Komponente kann:
- Aufgaben empfangen (z.B. vom Router oder über eine API),
- eigene Logik ausführen (lokal oder verteilt),
- Ergebnisse speichern oder weiterleiten,
- und Statusinformationen melden.
Diese Struktur erlaubt, dass alle Module untereinander austauschbar bleiben und dennoch einheitlich funktionieren.
---
## 3. Standardverzeichnisstruktur
```plaintext
/<Komponentenname>/
├── Planung/
│ ├── Architektur.md
│ ├── Funktionsbeschreibung.md
│ └── Kommunikationsschnittstellen.md
├── Entworfener_Code/
│ ├── start.py
│ ├── config.yaml
│ ├── src/
│ │ ├── core.py
│ │ ├── logic.py
│ │ ├── api_connector.py
│ │ └── storage.py
│ ├── tests/
│ │ └── test_core.py
│ └── README.md
└── README.md
```
---
## 4. Klassenaufbau
Jede Komponente kann, falls objektorientiert entwickelt, auf einer einheitlichen Basisklasse aufbauen, um Grundfunktionen wie Logging, Config-Handling und Kommunikation gemeinsam zu nutzen.
```python
# Datei: src/core.py
from utils.api_client import APIClient
from utils.memory_connector import Memory
from utils.logging_setup import get_logger
class BaseComponent:
"""Abstrakte Basisklasse für alle Komponenten des KI-Clusters."""
def __init__(self, name: str):
self.name = name
self.api = APIClient()
self.memory = Memory()
self.logger = get_logger(name)
def register(self):
"""Registriert die Komponente beim Router oder Systembus."""
self.logger.info(f"{self.name} registriert sich beim System.")
self.api.register_component(self.name)
def start(self):
raise NotImplementedError("Jede Komponente muss eine start()-Methode implementieren.")
```
Beispiel für eine spezialisierte Komponente:
```python
# Beispiel: Router-Modul
from src.core import BaseComponent
class RouterModule(BaseComponent):
"""Koordiniert Aufgaben zwischen Komponenten und verteilt Anfragen."""
def start(self):
self.logger.info("Router gestartet.")
self.listen_for_tasks()
def listen_for_tasks(self):
# Beispielhafte Implementierung
self.logger.info("Warte auf eingehende Aufgaben...")
```
---
## 5. Lebenszyklus einer Komponente
| Phase | Beschreibung |
|--------|---------------|
| **Initialisierung** | `start.py` lädt Konfiguration, Logging und die `src/core.py`-Klasse. |
| **Registrierung** | Komponente meldet sich beim Router oder globalen System an. |
| **Ausführung** | Logik läuft (z.B. Verarbeitung, API-Handling, Kommunikation). |
| **Feedback** | Ergebnisse oder Status werden an zentrale Systeme übermittelt. |
| **Beendigung** | Logs und Speicherzustände werden gesichert, Prozesse sauber beendet. |
---
## 6. Konfigurationsdatei (`config.yaml`)
Beispiel:
```yaml
component:
name: "RouterModule"
type: "Systemkomponente"
version: "1.0"
communication:
router_endpoint: "http://localhost:5000"
memory_endpoint: "http://localhost:6000"
logging:
level: "INFO"
file: "logs/router_module.log"
```
---
## 7. Gemeinsame Schnittstellen
| Schnittstelle | Zweck | Implementierung |
|----------------|--------|------------------|
| **APIClient** | Kommunikation zwischen Komponenten | `utils/api_client.py` |
| **Memory** | Zugriff auf Wissensspeicher | `utils/memory_connector.py` |
| **Logger** | Zentrales Logging-System | `utils/logging_setup.py` |
| **Config Loader** | Einheitliche YAML-Konfiguration | `utils/config_loader.py` |
---
## 8. Kommunikation zwischen Komponenten
Jede Komponente unterstützt mindestens folgende Methoden:
| Methode | Beschreibung |
|----------|---------------|
| `register()` | Meldet sich beim zentralen System an |
| `start()` | Startet die Logik der Komponente |
| `receive_message(data: dict)` | Empfängt Nachrichten oder Aufgaben |
| `send_message(data: dict)` | Sendet Ergebnisse oder Events |
| `shutdown()` | Fährt die Komponente kontrolliert herunter |
---
## 9. Anforderungen an neue Komponenten
Neue Komponenten müssen:
1. von `BaseComponent` erben (falls OOP),
2. in `start.py` eingetragen werden,
3. ihre Konfiguration in `config.yaml` speichern,
4. Unit-Tests unter `/tests/` bereitstellen,
5. und saubere Logging- sowie Feedback-Mechanismen besitzen.
---
## 10. Beispielkommunikation
```python
# Beispiel: Router sendet Aufgabe an API-Modul
task = {
"type": "fetch_data",
"parameters": {"url": "https://example.com/api"}
}
api_module.receive_message(task)
```
Die Komponente führt die Aufgabe aus und antwortet:
```python
result = {
"status": "success",
"data": {"records": 24}
}
api_module.send_message(result)
```
---
## 11. Zusammenfassung
Alle Komponenten im System folgen diesem Grundschema.
Dadurch wird erreicht, dass:
- der Router alle Programme gleich ansprechen kann,
- der Builder-Agent neue Komponenten automatisch integrieren kann,
- und das gesamte System modular, testbar und erweiterbar bleibt.
---
© 2025 KI-Cluster Homelab Architektur
Autor: *[Dein Name oder Alias]*
### 3.1 Variante: FastAPI-Web-API-Komponente (empfohlen)
Diese Variante verankert die lauffähige Grundstruktur für API-basierte Komponenten mit FastAPI, Logging und Tests.
```plaintext
/<Komponentenname>/
├── Planung/
│ ├── Architektur.md
│ ├── Funktionsbeschreibung.md
│ └── Kommunikationsschnittstellen.md
├── Entworfener_Code/
│ ├── start.py
│ ├── requirements.txt
│ ├── README.md
│ ├── Dockerfile
│ ├── docker-compose.yml
│ ├── app/
│ │ └── main.py
│ ├── api/
│ │ ├── __init__.py
│ │ ├── router.py
│ │ └── routes/
│ │ ├── __init__.py
│ │ └── execute.py
│ ├── core/
│ │ └── base_component.py
│ ├── config/
│ │ ├── config.yaml
│ │ └── logging.yaml
│ └── tests/
│ └── test_smoke.py
└── README.md
```
Pflichten dieser Struktur:
- start.py: lädt Konfiguration (config/config.yaml), initialisiert Logging (config/logging.yaml) und startet den FastAPI-Server (uvicorn, optional Factory/Reload).
- app/main.py: erzeugt die FastAPI-App (create_app), bindet CORS und registriert Router.
- api/router.py und api/routes/execute.py: Beispiel-Routenstruktur inkl. POST /api/execute sowie GET /health.
- core/base_component.py: Basisklasse mit Schnittstelle register() und start() für spätere Komponenten.
- config/logging.yaml: Rotierende Logs (TimedRotatingFileHandler) und zentrale Logger (uvicorn, root).
- tests/test_smoke.py: pytest-Smoketests für Health-Endpoint und /api/execute.
- requirements.txt: Abhängigkeiten (u. a. fastapi, uvicorn, pyyaml, pytest, httpx).
- Dockerfile, docker-compose.yml: Containerisierter Betrieb, Port 8000, Mounts für config/logs.
- Namens-/Code-Style: snake_case, vollständige Typannotationen, Docstrings gemäß Richtlinien.
Hinweis: Diese Variante ergänzt die allgemeine Standardstruktur aus Abschnitt 3 für API-orientierte Komponenten und dient als verbindlicher Grundstock, auf dem spätere Erweiterungen aufbauen.
## 12. Laufzeit-Zielsetzung und Start-Events
- Das Laufzeitprogramm `start.py` bleibt dauerhaft aktiv, da es einen Webserver offen hält und Anfragen entgegennimmt.
- Der Code ist so vorzubereiten, dass bei eingehenden Start-Events (z.B. POST /start) ein Start-Prozess ausgelöst werden kann.
- Mehrere Start-Events dürfen möglich sein. Die Entscheidung, ob diese ignoriert, parallel oder in einer Queue verarbeitet werden, wird in dieser Phase bewusst offengelassen und nur als Planungs-Hinweis dokumentiert. Die konkrete Ausführungsstrategie wird später festgelegt.
---
## 13. API-Struktur (Minimal-API unter src/api.py)
- Eine Minimal-API wird in `src/api.py` bereitgestellt.
- Der Webserver lauscht auf dem in der Konfiguration definierten Port (Standard 8000).
- `start.py` startet den API-Server und bleibt aktiv, um Anfragen verarbeiten zu können.
- Die Minimal-API umfasst mindestens:
- POST /start: löst den Start-Prozess aus (nicht-blockierend).
- Optional GET /health: einfacher Health-Check.
- Die API darf den Event-Handling-Pfad nicht blockieren; Start-Prozesse werden asynchron oder in eigenen Threads/Tasks ausgeführt.
---
## 14. Globales Konfigurationssystem
Es gibt eine einzige globale Konfiguration. Die Struktur ist folgendermaßen vorgegeben:
```plaintext
+-- globale_configuration
| |-- variablename
| | |-- beschreibung erklärung
| | |-- wert
|
+-- logging
| |-- variablename
| | |-- beschreibung erklärung
| | |-- wert
|
+-- worker
|-- variablename
| |-- beschreibung erklärung
| |-- wert
```
- Diese Konfiguration wird als Python-Struktur in `src/config.py` gepflegt und systemweit verwendet.
- Zugriff erfolgt zentral über `from src.config import CONFIG`.
- Der HTTP-Port wird ebenfalls in der globalen Konfiguration gepflegt (z.B. `CONFIG["globale_configuration"]["port"]["wert"]`).
- Logging-Parameter (Level, Aktivierung, Ausgabeziele) werden ausschließlich über `CONFIG` gesteuert.
---
## 15. Technische Anforderungen (Laufzeit und Architektur)
- Der Webserver darf beim Event-Handling nicht blockieren. HTTP-Handler delegieren die Start-Logik in asynchrone Tasks oder Threads.
- Start-Routinen laufen asynchron (z.B. asyncio/BackgroundTasks) oder in eigenen Threads, sodass die API schnell antwortet.
- Logging ist vollständig über die globale Konfiguration steuerbar (z.B. Level, Aktivierung).
- Modulstruktur:
- start.py: Einstiegspunkt (startet Webserver, bleibt aktiv)
- src/config.py: zentrale Konfiguration (`CONFIG`)
- src/api.py: API-Definition (u.a. POST /start)
- src/worker.py: Start-/Arbeitslogik (ausgelöst durch Events)
- src/logger.py: Logging-Setup/-Zugriff
---
## 16. Beispiel-/Gerüstcode in Entworfener_Code
Hinweis: Es handelt sich um Struktur- und Ablaufgerüste (kein finaler Code, keine vollständige Implementierung). Ziel ist, Verantwortlichkeiten und Aufrufreihenfolge klar zu dokumentieren.
Beispiel src/config.py:
```python
# Globale Konfiguration als Python-Struktur (zentrale Quelle der Wahrheit)
CONFIG: dict = {
"globale_configuration": {
"port": {
"beschreibung": "HTTP-Port des API-Servers",
"wert": 8000,
},
"environment": {
"beschreibung": "Laufzeitumgebung",
"wert": "dev",
},
},
"logging": {
"enabled": {"beschreibung": "Aktiviert das Logging", "wert": True},
"level": {"beschreibung": "Log-Level (z. B. INFO, DEBUG)", "wert": "INFO"},
},
"worker": {
"concurrency": {
"beschreibung": "Parallelisierungsgrad (Threads/Tasks), strategische Nutzung offen",
"wert": 1,
},
},
}
```
Beispiel src/logger.py:
```python
import logging
from src.config import CONFIG
def get_logger(name: str) -> logging.Logger:
logger = logging.getLogger(name)
logger.setLevel(getattr(logging, str(CONFIG["logging"]["level"]["wert"]).upper(), logging.INFO))
return logger
```
Beispiel src/worker.py:
```python
from typing import Any, Dict
from src.logger import get_logger
async def trigger_start(payload: Dict[str, Any]) -> None:
logger = get_logger("worker")
logger.info("Start-Event angenommen (Gerüst).")
```
Beispiel src/api.py:
```python
from typing import Any, Dict, Optional
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
from src.config import CONFIG
from src.logger import get_logger
from src.worker import trigger_start
app = FastAPI(title="Minimal-API (Gerüst)")
class StartRequest(BaseModel):
job_id: Optional[str] = None
params: Optional[Dict[str, Any]] = None
@app.post("/start")
async def start_endpoint(req: StartRequest, background: BackgroundTasks) -> Dict[str, str]:
logger = get_logger("api")
logger.info("Start-Event empfangen (Gerüst).")
background.add_task(trigger_start, (req.dict()))
return {"status": "accepted"}
```
Ablauf-Skizze start.py (Beschreibung):
- Liest die globale Konfiguration aus `src/config.py` (oder eine projektspezifische Quelle).
- Initialisiert das Logging über `src/logger.py`.
- Startet den Webserver (z.B. `uvicorn src.api:app`) auf dem in `CONFIG` definierten Port und bleibt aktiv.
- Nicht-blockierender Betrieb: API antwortet unmittelbar; Arbeitslogik läuft asynchron/parallel.
## 17. Restart-/Reload-Funktion (über API)
Ziel
- Während der Laufzeit soll eine über die API verfügbare Funktion einen Neustart des Python-Prozesses anstoßen, um Konfigurationsänderungen zu übernehmen oder nach Laufzeiterweiterungen sauber durchzustarten.
- Endpunkte: `POST /restart` sowie Alias `POST /reload`.
Vorgaben
- Nicht-blockierend: Der HTTP-Handler bestätigt den Auftrag zeitnah und plant den Neustart im Hintergrund mit kurzer Verzögerung (z.B. 3001000ms), damit die Antwort noch übertragen werden kann.
- Prozess-Neustart: Entweder durch einen Vollneustart des Python-Prozesses (z.B. via os.execv) oder durch einen Supervisor (Docker/Compose/Systemd/K8s). In der Scaffold-Phase wird der direkte Prozess-Neustart skizziert.
- Konfiguration: Optionaler Request-Parameter `delay_ms` zur Steuerung der Verzögerung vor dem Neustart. Weitere Steuerung (z.B. Freigabe-Flag, Backoff) kann über die zentrale `CONFIG` erfolgen.
- Sicherheit/Robustheit (Hinweise):
- Schutz vor Restart-Loops (Backoff/Minimum-Delay).
- Optional Authentisierung/Autorisierung für administrative Endpunkte.
- Log-Einträge vor Neustart (Grund, Zeitstempel, Kontext).
- Start-/Mehrfach-Events: Die Strategie für konkurrierende Ereignisse bleibt offen (ignorieren, parallel, Queue). Der Restart-Event ist administrativ und sollte priorisiert behandelt werden, Details werden in der späteren Implementierung festgelegt.
Schnittstellenbeschreibung (Minimal)
- `POST /restart` → Antwort: `{"status": "scheduled", "delay_ms": <int>}`
- `POST /reload` → Alias zu `/restart`
Modulzuordnung
- `src/api.py`: definiert die Endpunkte und plant den Neustart im Hintergrund.
- `src/worker.py`: enthält die Restart-Hilfsroutine (z.B. `restart_process(reason, delay_seconds)`), die nach einer kurzen Verzögerung den Prozess ersetzt/neustartet.
- `start.py`: bleibt dauerhaft aktiv; Neustart führt zur Neuinitialisierung inkl. erneuter Auswertung der Konfiguration.
## 3.2 Alternative Struktur: app/code-Aufteilung (empfohlen für klare Trennung)
Diese Variante verschiebt den ausführbaren Code, Tests und die API-Struktur unterhalb von `app/code`, während Konfigurationsdateien unter `app/config` leben. Einstiegspunkt und komponentenbezogene README liegen unter `app/`. Artefakte wie Dockerfile, docker-compose und requirements verbleiben auf oberster Ebene von `Entworfener_Code/`.
```plaintext
Entworfener_Code
├── app
│ ├── code
│ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── router.py
│ │ │ └── routes
│ │ │ ├── execute.py
│ │ │ └── __init__.py
│ │ ├── app
│ │ │ └── main.py
│ │ ├── core
│ │ │ └── base_component.py
│ │ ├── src
│ │ │ ├── api.py
│ │ │ ├── config.py
│ │ │ ├── logger.py
│ │ │ └── worker.py
│ │ └── tests
│ │ └── test_smoke.py
│ ├── config
│ │ ├── config.yaml
│ │ └── logging.yaml
│ ├── README.md
│ └── start.py
├── docker-compose.yml
├── Dockerfile
└── requirements.txt
```
Leitlinien für diese Struktur:
- `app/start.py` bleibt dauerhaft aktiv (Webserver offen) und liest Konfiguration aus `app/config`.
- API für Start-Events und Admin-Endpunkte (POST `/start`, `/restart`, `/reload`) liegt in `app/code/src/api.py`. Diese Endpunkte dürfen nicht blockieren; Ausführung wird an `app/code/src/worker.py` delegiert (async/Threads).
- Zentrale, einzige globale Konfiguration als Python-Struktur in `app/code/src/config.py` (`from src.config import CONFIG`); YAML-Konfigurationsdateien ergänzen diese bei Bedarf (z.B. für externe Operatoren) und werden in `app/config` gepflegt.
- Logging wird über `CONFIG` gesteuert. Ein Gerüst für Logging-Zugriff liegt in `app/code/src/logger.py`; systemweite Handler/Formatter werden später konsolidiert.
- Die beispielhafte Router-Struktur für REST-Endpunkte liegt in `app/code/api` und wird in `app/code/app/main.py` eingebunden.
- Tests unter `app/code/tests` (pytest-Namenskonventionen `test_*.py`).
Hinweis zu Restart/Reload:
- Die Endpunkte `POST /restart` und `POST /reload` planen (nicht-blockierend) einen Prozessneustart ein, um Konfigurationsänderungen oder Erweiterungen aufzunehmen. Die konkrete Neustartstrategie (Supervisor/execv, Backoff, Auth) ist bewusst noch offen und wird in einer späteren Implementierungsphase festgelegt.