17 KiB
🧩 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
/<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.
# 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:
# 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:
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:
- von
BaseComponenterben (falls OOP), - in
start.pyeingetragen werden, - ihre Konfiguration in
config.yamlspeichern, - Unit-Tests unter
/tests/bereitstellen, - und saubere Logging- sowie Feedback-Mechanismen besitzen.
10. Beispielkommunikation
# 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:
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.
/<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.pybleibt 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.pybereitgestellt. - Der Webserver lauscht auf dem in der Konfiguration definierten Port (Standard 8000).
start.pystartet 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:
+-- 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.pygepflegt 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
CONFIGgesteuert.
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:
# 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:
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:
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:
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 inCONFIGdefinierten 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 /restartsowie AliasPOST /reload.
Vorgaben
- Nicht-blockierend: Der HTTP-Handler bestätigt den Auftrag zeitnah und plant den Neustart im Hintergrund mit kurzer Verzögerung (z. B. 300–1000 ms), 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_mszur Steuerung der Verzögerung vor dem Neustart. Weitere Steuerung (z. B. Freigabe-Flag, Backoff) kann über die zentraleCONFIGerfolgen. - 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/.
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.pybleibt dauerhaft aktiv (Webserver offen) und liest Konfiguration ausapp/config.- API für Start-Events und Admin-Endpunkte (POST
/start,/restart,/reload) liegt inapp/code/src/api.py. Diese Endpunkte dürfen nicht blockieren; Ausführung wird anapp/code/src/worker.pydelegiert (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 inapp/configgepflegt. - Logging wird über
CONFIGgesteuert. Ein Gerüst für Logging-Zugriff liegt inapp/code/src/logger.py; systemweite Handler/Formatter werden später konsolidiert. - Die beispielhafte Router-Struktur für REST-Endpunkte liegt in
app/code/apiund wird inapp/code/app/main.pyeingebunden. - Tests unter
app/code/tests(pytest-Namenskonventionentest_*.py).
Hinweis zu Restart/Reload:
- Die Endpunkte
POST /restartundPOST /reloadplanen (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.