Files
Orchestrator/bahn/teamlandkarte-mcp/.kiro/specs/llm-competence-inference/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

8.6 KiB
Raw Blame History

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_completion so 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 und confidence in [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_role liefert 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_role weiterhin ein Tupel (role_name, confidence) oder None bei Fehler (aus Preservation Requirements)
    • Property-Based Test 2: Für alle leeren Task-Texte (st.just("") oder st.from_regex(r'^\s*$')) liefert infer_competences stets []
    • Property-Based Test 3: Für leere Kompetenzliste in DB liefert infer_competences stets []
    • 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_PROMPT in vocabulary.py hinzufü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
    • 3.2 Methode infer_competences in VocabularyCache implementieren

      • 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
    • 3.3 LLM-Aufruf in validate_task_requirements integrieren

      • Ersetze inferred_comps: list[tuple[str, float]] = [] durch inferred_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
    • 3.4 LLM-Aufruf in extract_requirements integrieren

      • Ersetze inferred_competences: list[tuple[str, float]] = [] durch inferred_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
    • 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
    • 3.6 Unit-Tests für infer_competences mit 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); der AzureOpenAIClient wird stets gemockt.
  • Die Implementierungssprache ist Python (bestehende Codebase).
  • Tasks referenzieren explizit Anforderungen aus bugfix.md zur lückenlosen Nachverfolgbarkeit.
  • Der Fix ist additiv: bestehende Funktionalität (Rollen-Inferenz, DB-Skills, LLM-Fulltext-Matching) bleibt unverändert.