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.
8.6 KiB
Implementation Plan: LLM-Kompetenz-Inferenz Bugfix
Übersicht
Explorativer Bugfix-Workflow: Zuerst den Bug durch Tests bestätigen, dann Preservation sicherstellen, anschließend den Fix implementieren und validieren. Die infer_competences-Methode wird in VocabularyCache ergänzt und an drei Stellen im mcp_server.py integriert.
Tasks
-
1. Bug-Condition Explorationstest schreiben
- Property 1: Fault Condition - Kompetenz-Inferenz liefert stets leere Liste
- CRITICAL: Dieser Test MUSS auf dem unfixierten Code FEHLSCHLAGEN – das Fehlschlagen bestätigt den Bug
- DO NOT versuchen den Test oder den Code zu fixen wenn er fehlschlägt
- NOTE: Dieser Test kodiert das erwartete Verhalten – er validiert den Fix wenn er nach der Implementierung besteht
- GOAL: Counterexamples aufdecken, die demonstrieren dass der Bug existiert
- Scoped PBT Approach: Property auf konkrete Fälle scopen: nicht-leerer Task-Text mit vorhandenen Kompetenzen in der DB
- Test-Datei:
tests/test_competence_inference_fault_pbt.py - Hypothesis-Strategie:
st.text(min_size=1)für Task-Text,st.lists(st.text(min_size=1), min_size=1, max_size=50)für Kompetenzliste - Mock
AzureOpenAIClient.chat_completionso dass er gültiges JSON mit Kompetenzen zurückgibt - Assertion:
infer_competences(task_text)liefert eine nicht-leere Liste von bis zu 10 Tupeln(name, confidence)wobei jeder Name in der Kompetenzliste enthalten ist undconfidencein [0.0, 1.0] liegt - Test auf UNFIXIERTEM Code ausführen – ERWARTETES ERGEBNIS: Test SCHLÄGT FEHL (bestätigt Bug)
- Counterexamples dokumentieren (z.B. "infer_competences('Python Backend') gibt [] zurück statt Kompetenzen")
- Task als abgeschlossen markieren wenn Test geschrieben, ausgeführt und Fehlschlag dokumentiert ist
- Requirements: 1.1, 1.2, 1.3, 2.1, 2.2, 2.3
-
2. Preservation Property-Tests schreiben (VOR der Fix-Implementierung)
- Property 2: Preservation - Rollen-Inferenz und Leer-Eingaben unverändert
- IMPORTANT: Observation-First-Methodik befolgen
- Test-Datei:
tests/test_competence_inference_preservation_pbt.py - Beobachten:
infer_primary_roleliefert auf unfixiertem Code weiterhin eine Rolle mit Konfidenz - Beobachten: Leerer Task-Text liefert auf unfixiertem Code
[](korrektes Verhalten) - Beobachten: Leere Kompetenzliste in DB liefert auf unfixiertem Code
[](korrektes Verhalten) - Property-Based Test 1: Für alle nicht-leeren Task-Texte liefert
infer_primary_roleweiterhin ein Tupel(role_name, confidence)oderNonebei Fehler (aus Preservation Requirements) - Property-Based Test 2: Für alle leeren Task-Texte (
st.just("")oderst.from_regex(r'^\s*$')) liefertinfer_competencesstets[] - Property-Based Test 3: Für leere Kompetenzliste in DB liefert
infer_competencesstets[] - Tests auf UNFIXIERTEM Code ausführen – ERWARTETES ERGEBNIS: Tests BESTEHEN (bestätigt Baseline-Verhalten)
- Task als abgeschlossen markieren wenn Tests geschrieben, ausgeführt und bestanden auf unfixiertem Code
- Requirements: 3.1, 3.2, 3.3, 3.4, 3.5
-
3. Fix für LLM-Kompetenz-Inferenz implementieren
-
3.1 System-Prompt
_COMPETENCE_INFERENCE_SYSTEM_PROMPTinvocabulary.pyhinzufügen- Modul-Level-Konstante analog zu
_ROLE_INFERENCE_SYSTEM_PROMPT - Prompt instruiert das LLM, aus einer Kompetenzliste bis zu 10 passende Kompetenzen für einen Task-Text auszuwählen
- Antwortformat:
{"competences": [{"name": "<name>", "confidence": <float>}]} - Bug_Condition: isBugCondition(input) where task_text.strip() != "" AND len(competence_names) > 0 AND infer_competences(task_text) == []
- Expected_Behavior: Nicht-leere Liste von bis zu 10 (name, confidence)-Tupeln
- Requirements: 2.1, 2.2, 2.3
- Modul-Level-Konstante analog zu
-
3.2 Methode
infer_competencesinVocabularyCacheimplementieren- Signatur:
async def infer_competences(self, *, task_text: str, max_competences: int = 10) -> list[tuple[str, float]] - Kompetenzliste via
self._db.get_all_competence_names()holen - Bei leerer Liste oder leerem Text:
[]zurückgeben - LLM-Aufruf via
self._client.chat_completion(system, user) - JSON-Parsing, Validierung gegen DB-Kompetenzliste (nur bekannte Namen übernehmen)
- Bei Fehler (Exception, ungültiges JSON): leere Liste zurückgeben + Warning loggen
- Bug_Condition: isBugCondition(input) where task_text.strip() != "" AND len(competence_names) > 0
- _Expected_Behavior: expectedBehavior(result) = len(result) > 0 AND len(result) <= 10 AND all(name in competence_names for name, _ in result) AND all(0.0 <= conf <= 1.0 for , conf in result)
- Preservation: Leerer Text → [], Leere DB → [], Fehler → [] + Warning
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5
- Signatur:
-
3.3 LLM-Aufruf in
validate_task_requirementsintegrieren- Ersetze
inferred_comps: list[tuple[str, float]] = []durchinferred_comps = await vocab_cache.infer_competences(task_text=task_text) - Bug_Condition: validate_task_requirements aufgerufen mit Task der beschriebenen Text hat
- Expected_Behavior: inferred_comps enthält bis zu 10 Kompetenzen mit Konfidenz
- Preservation: Rollen-Inferenz und DB-Skills bleiben unverändert
- Requirements: 2.1, 3.1, 3.2
- Ersetze
-
3.4 LLM-Aufruf in
extract_requirementsintegrieren- Ersetze
inferred_competences: list[tuple[str, float]] = []durchinferred_competences = await vocab_cache.infer_competences(task_text=desc) - Bug_Condition: extract_requirements aufgerufen mit nicht-leerem Text
- Expected_Behavior: inferred_competences enthält bis zu 10 Kompetenzen
- Requirements: 2.2
- Ersetze
-
3.5 LLM-Aufruf in
find_matching_tasks(Score-Modus) integrieren- Ersetze den bestehenden
inferred_comp_names-Block durch LLM-Inferenz mit Fallback auf DB-Skills inferred_comp_tuples = await vocab_cache.infer_competences(task_text=full_text)inferred_comp_names = [name for name, _conf in inferred_comp_tuples]- Fallback:
if not inferred_comp_names: inferred_comp_names = [str(x) for x in (getattr(t, "skills", None) or []) if x] - Bug_Condition: find_matching_tasks im Score-Modus mit Task der beschriebenen Text hat
- Expected_Behavior: inferred_comp_names enthält LLM-inferierte Kompetenzen für Scoring
- Preservation: LLM-Fulltext-Modus bleibt unverändert
- Requirements: 2.3, 3.3
- Ersetze den bestehenden
-
3.6 Unit-Tests für
infer_competencesmit gemocktem LLM-Client- Test gültige JSON-Antwort → korrekte Tupel-Liste
- Test leerer Task-Text →
[] - Test leere Kompetenzliste in DB →
[] - Test LLM-Fehler (Exception) →
[]+ Warning geloggt - Test ungültige JSON-Antwort →
[] - Test Kompetenz-Namen die nicht in DB sind → werden herausgefiltert
- Test max_competences Begrenzung auf 10
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5
-
3.7 Bug-Condition Explorationstest erneut ausführen – Verifizieren dass er jetzt besteht
- Property 1: Expected Behavior - Kompetenz-Inferenz liefert Ergebnisse
- IMPORTANT: Den GLEICHEN Test aus Task 1 erneut ausführen – KEINEN neuen Test schreiben
- Der Test aus Task 1 kodiert das erwartete Verhalten
- Wenn dieser Test besteht, bestätigt das dass das erwartete Verhalten erfüllt ist
- Bug-Condition Explorationstest aus Schritt 1 ausführen
- ERWARTETES ERGEBNIS: Test BESTEHT (bestätigt Bug ist behoben)
- Requirements: 2.1, 2.2, 2.3
-
3.8 Preservation-Tests erneut ausführen – Verifizieren dass sie weiterhin bestehen
- Property 2: Preservation - Rollen-Inferenz und Leer-Eingaben unverändert
- IMPORTANT: Die GLEICHEN Tests aus Task 2 erneut ausführen – KEINE neuen Tests schreiben
- Preservation Property-Tests aus Schritt 2 ausführen
- ERWARTETES ERGEBNIS: Tests BESTEHEN (bestätigt keine Regressionen)
- Bestätigen dass alle Tests nach dem Fix weiterhin bestehen
- Requirements: 3.1, 3.2, 3.3, 3.4, 3.5
-
-
4. Checkpoint - Sicherstellen dass alle Tests bestehen
- Alle Tests ausführen und sicherstellen dass sie bestehen, bei Fragen den User konsultieren.
Hinweise
- Property-Based Tests verwenden Hypothesis mit
@settings(max_examples=100). - Unit- und Integrationstests verwenden
pytest(Run-once, kein Watch-Modus); derAzureOpenAIClientwird stets gemockt. - Die Implementierungssprache ist Python (bestehende Codebase).
- Tasks referenzieren explizit Anforderungen aus
bugfix.mdzur lückenlosen Nachverfolgbarkeit. - Der Fix ist additiv: bestehende Funktionalität (Rollen-Inferenz, DB-Skills, LLM-Fulltext-Matching) bleibt unverändert.