gateway/modules/services/serviceAi/REFACTORING_PLAN.md
2025-12-25 23:51:47 +01:00

126 lines
4.1 KiB
Markdown

# Refactoring Plan für mainServiceAi.py
## Ziel
Aufteilen des 3000-Zeilen-Moduls in überschaubare Submodule (~300-600 Zeilen pro Modul).
## Vorgeschlagene Struktur
### Bereits erstellt:
1.`subResponseParsing.py` - ResponseParser Klasse
2.`subDocumentIntents.py` - DocumentIntentAnalyzer Klasse
### Noch zu erstellen:
3. `subContentExtraction.py` - ContentExtractor Klasse
- `extractAndPrepareContent()` (~490 Zeilen)
- `extractTextFromImage()` (~55 Zeilen)
- `processTextContentWithAi()` (~72 Zeilen)
- `_isBinary()` (~10 Zeilen)
4. `subStructureGeneration.py` - StructureGenerator Klasse
- `generateStructure()` (~60 Zeilen)
- `_buildStructurePrompt()` (~130 Zeilen)
5. `subStructureFilling.py` - StructureFiller Klasse
- `fillStructure()` (~290 Zeilen)
- `_buildSectionGenerationPrompt()` (~185 Zeilen)
- `_findContentPartById()` (~5 Zeilen)
- `_needsAggregation()` (~20 Zeilen)
6. `subAiCallLooping.py` - AiCallLooper Klasse
- `callAiWithLooping()` (~405 Zeilen)
- `_defineKpisFromPrompt()` (~92 Zeilen)
## Refactoring-Schritte für mainServiceAi.py
### Schritt 1: Submodule-Initialisierung erweitern
```python
def _initializeSubmodules(self):
"""Initialize all submodules after aiObjects is ready."""
if self.aiObjects is None:
raise RuntimeError("aiObjects must be initialized before initializing submodules")
if self.extractionService is None:
logger.info("Initializing ExtractionService...")
self.extractionService = ExtractionService(self.services)
# Neue Submodule initialisieren
from modules.services.serviceAi.subResponseParsing import ResponseParser
from modules.services.serviceAi.subDocumentIntents import DocumentIntentAnalyzer
from modules.services.serviceAi.subContentExtraction import ContentExtractor
from modules.services.serviceAi.subStructureGeneration import StructureGenerator
from modules.services.serviceAi.subStructureFilling import StructureFiller
if not hasattr(self, 'responseParser'):
self.responseParser = ResponseParser(self.services)
if not hasattr(self, 'intentAnalyzer'):
self.intentAnalyzer = DocumentIntentAnalyzer(self.services, self)
if not hasattr(self, 'contentExtractor'):
self.contentExtractor = ContentExtractor(self.services, self)
if not hasattr(self, 'structureGenerator'):
self.structureGenerator = StructureGenerator(self.services, self)
if not hasattr(self, 'structureFiller'):
self.structureFiller = StructureFiller(self.services, self)
```
### Schritt 2: Methoden durch Delegation ersetzen
**Beispiel für Response Parsing:**
```python
# ALT:
def _extractSectionsFromResponse(self, ...):
# 100 Zeilen Code
...
# NEU:
def _extractSectionsFromResponse(self, ...):
return self.responseParser.extractSectionsFromResponse(...)
```
**Beispiel für Document Intents:**
```python
# ALT:
async def _clarifyDocumentIntents(self, ...):
# 100 Zeilen Code
...
# NEU:
async def _clarifyDocumentIntents(self, ...):
return await self.intentAnalyzer.clarifyDocumentIntents(...)
```
### Schritt 3: Helper-Methoden beibehalten
Kleine Helper-Methoden bleiben im Hauptmodul:
- `_buildPromptWithPlaceholders()`
- `_getIntentForDocument()`
- `_shouldSkipContentPart()`
- `_determineDocumentName()`
### Schritt 4: Public API unverändert lassen
Die öffentliche API (`callAiPlanning`, `callAiContent`) bleibt unverändert.
## Erwartete Ergebnis-Größen
- `mainServiceAi.py`: ~800-1000 Zeilen (von 3016)
- `subResponseParsing.py`: ~200 Zeilen ✅
- `subDocumentIntents.py`: ~300 Zeilen ✅
- `subContentExtraction.py`: ~600 Zeilen
- `subStructureGeneration.py`: ~200 Zeilen
- `subStructureFilling.py`: ~400 Zeilen
- `subAiCallLooping.py`: ~500 Zeilen
**Gesamt: ~3000 Zeilen** (gleich, aber besser organisiert)
## Vorteile
1. **Übersichtlichkeit**: Jedes Modul hat eine klare Verantwortlichkeit
2. **Wartbarkeit**: Änderungen sind lokalisiert
3. **Testbarkeit**: Module können einzeln getestet werden
4. **Wiederverwendbarkeit**: Module können in anderen Kontexten verwendet werden