Files
Orchestrator/bahn/teamlandkarte-mcp/.kiro/specs/llm-batch-matching/tasks.md
T
ankn a5f8fb49ab Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
      Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
      Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)

Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
2026-06-30 20:39:52 +02:00

101 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
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.
# Implementierungsplan: LLM Batch-Matching (Concurrent Requests)
## Übersicht
Sequenzielle LLM-Aufrufe in `LlmFulltextMatcher` werden durch `asyncio.gather()` mit Semaphore-Begrenzung ersetzt. Die Konfiguration wird um `max_concurrency` erweitert. Die öffentliche Schnittstelle bleibt unverändert.
## Tasks
- [x] 1. Konfiguration erweitern
- [x] 1.1 `AzureOpenAIConfig` um Feld `max_concurrency: int = 5` erweitern
- In `src/teamlandkarte_mcp/config.py` das frozen Dataclass `AzureOpenAIConfig` um das Feld ergänzen
- _Anforderungen: 2.5_
- [x] 1.2 Validierung in `_parse_azure_openai` hinzufügen
- `max_concurrency` aus Config lesen mit Default 5
- `ConfigError` werfen wenn Wert < 1 oder > 20
- Feld an `AzureOpenAIConfig`-Konstruktor übergeben
- Auch im `load_config`-Rebuild-Block (`azure_openai = AzureOpenAIConfig(...)`) das neue Feld durchreichen
- _Anforderungen: 2.1, 2.2, 2.3, 2.4_
- [x] 1.3 `config.toml` um kommentierten `max_concurrency`-Schlüssel erweitern
- Unter `[azure_openai]` einen Kommentar mit Erklärung und auskommentierten Default-Wert einfügen
- _Anforderungen: 2.1_
- [x] 1.4 Property-Test für Config-Validierung schreiben
- **Property 6: Config-Validierung**
- Teste mit hypothesis: `st.integers(min_value=-100, max_value=100)` Erfolg genau dann wenn 1 <= n <= 20, sonst `ConfigError`
- **Validiert: Anforderungen 2.1, 2.3, 2.4**
- [x] 2. `LlmFulltextMatcher` um Concurrency erweitern
- [x] 2.1 Konstruktor um `max_concurrency`-Parameter und Semaphore erweitern
- `max_concurrency: int = 5` als keyword-only Parameter hinzufügen
- `self._semaphore = asyncio.Semaphore(max_concurrency)` im `__init__` anlegen
- `self._max_concurrency = max_concurrency` speichern
- `import asyncio` und `import time` ergänzen
- _Anforderungen: 1.2, 1.5, 5.4_
- [x] 2.2 Neue Methode `_categorize_one_throttled` implementieren
- Async-Wrapper um `_categorize_one` der `async with self._semaphore:` verwendet
- Gleiche Signatur wie `_categorize_one` (item_id, user_prompt, raw)
- _Anforderungen: 1.2, 1.4, 1.5_
- [x] 2.3 `match_capacities` auf `asyncio.gather` umstellen
- Sequenzielle for-Schleife durch Liste von `_categorize_one_throttled`-Aufrufen ersetzen
- `asyncio.gather(*tasks)` für parallele Ausführung verwenden
- Ergebnisse iterieren und in `by_category` / `errors` einsortieren
- Logging (INFO) vor und nach dem Batch mit Kandidatenanzahl, Concurrency, Dauer, Erfolge, Fehler
- Bestehende Sortierung beibehalten
- _Anforderungen: 1.1, 3.1, 3.2, 4.2, 4.3, 4.4, 5.1, 6.1, 6.2_
- [x] 2.4 `match_tasks` auf `asyncio.gather` umstellen
- Analog zu 2.3: sequenzielle Schleife durch gather + throttled ersetzen
- Logging analog zu `match_capacities`
- _Anforderungen: 1.1, 3.1, 3.2, 4.2, 4.3, 4.4, 5.1, 6.1, 6.2_
- [x] 3. MCP-Server Verdrahtung
- [x] 3.1 `max_concurrency` an `LlmFulltextMatcher` übergeben
- In `build_server()` bei der Instanziierung von `LlmFulltextMatcher` den Wert `cfg.azure_openai.max_concurrency` übergeben
- _Anforderungen: 2.1, 5.4_
- [x] 4. Checkpoint
- Sicherstellen dass alle bestehenden Tests weiterhin bestehen. Bei Fragen den Nutzer konsultieren.
- [x] 5. Property-Based Tests
- [x] 5.1 Property-Test: Vollständigkeit der Ergebnisse (Partition)
- **Property 1: Vollständigkeit der Ergebnisse**
- Generiere zufällige Kandidatenlisten mit Mock-Client (Mix aus Erfolg/Fehler); prüfe `len(by_category items) + len(errors) == len(input)`
- **Validiert: Anforderungen 1.1, 1.4, 3.2, 4.2, 4.3**
- [x] 5.2 Property-Test: Concurrency-Begrenzung
- **Property 2: Concurrency-Begrenzung**
- Mock-Client mit asyncio-Counter für gleichzeitige Aufrufe; prüfe `max_concurrent <= max_concurrency` für verschiedene Werte
- **Validiert: Anforderungen 1.2**
- [x] 5.3 Property-Test: Deterministische Sortierung
- **Property 3: Deterministische Sortierung**
- Generiere Ergebnisse mit zufälligen Kategorien; prüfe dass jede Kategorie nach `item_id` aufsteigend sortiert ist
- **Validiert: Anforderungen 3.1**
- [x] 5.4 Property-Test: Eingabereihenfolge-Unabhängigkeit
- **Property 4: Eingabereihenfolge-Unabhängigkeit**
- Generiere Kandidatenliste, permutiere, führe Matching aus, vergleiche Ergebnisse auf Gleichheit
- **Validiert: Anforderungen 3.3**
- [x] 5.5 Property-Test: Korrekte Zuordnung (Response-Mapping)
- **Property 5: Korrekte Zuordnung**
- Mock gibt item_id-spezifische Kategorien zurück; prüfe dass jedes Item in der korrekten Kategorie landet
- **Validiert: Anforderungen 3.4**
- [x] 5.6 Property-Test: Logging-Konsistenz
- **Property 7: Logging-Konsistenz**
- Capture Logs mit `caplog`; prüfe dass Start- und End-Log die korrekte Kandidatenanzahl und Summe (Erfolge + Fehler) enthalten
- **Validiert: Anforderungen 6.1, 6.2**
- [x] 6. Unit Tests
- [x] 6.1 Unit Tests für Batch-Matching schreiben
- Leere Eingabe: sofort leeres Ergebnis ohne LLM-Aufrufe
- Alle Fehler: keine Exception, vollständige Fehlerliste
- Default-Wert: ohne `max_concurrency` wird 5 verwendet
- Einzelner Fehler beeinflusst andere Kandidaten nicht
- _Anforderungen: 4.2, 4.3, 4.4, 5.3_
- [x] 7. Abschluss-Checkpoint
- Sicherstellen dass alle Tests bestehen und die Schnittstelle abwärtskompatibel bleibt. Bei Fragen den Nutzer konsultieren.
## Hinweise
- Tasks mit `*` sind optional und können für ein schnelleres MVP übersprungen werden
- Jeder Task referenziert spezifische Anforderungen für Nachvollziehbarkeit
- Property-Tests verwenden `hypothesis` (pytest-Plugin)
- Der Score-Modus bleibt vollständig unberührt (Anforderung 7)