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.
25 KiB
Implementation Plan: LLM-Volltext-Matching als zweites Verfahren
Overview
Inkrementelle Einführung des neuen llm_fulltext-Matching-Verfahrens neben dem bestehenden score-Verfahren. Die Reihenfolge stellt sicher, dass keine Zwischenstände kaputt sind: zuerst Datenbankschicht (DBClient/TrinoClient) erweitern, dann Datenmodelle (CapacityProfile/TaskProfile) und der LlmFulltextMatcher, anschließend Konfiguration und MCP-Tool-Integration, am Ende Cache-/Tabellenausgabe sowie Anpassungen an get_results_by_category/filter_search_results und Dokumentation.
Tasks
-
1. Datenbankschicht für Capacity-Volltext-Felder erweitern
-
1.1 Neue Methoden im
DBClient-Protokoll deklarieren (database/types.py)CapacityReferenceRowalsTypedDictmit Feldernpartner_name: strundprojects: strim Protokoll-Modul (bzw. unterdatabase/types.py) deklarieren;partner_namedarf leer sein (NULLpartner_idoder Join-Mismatch, Anforderung 2.8)get_capacity_description(capacity_id) -> str | Noneget_capacity_certificates(capacity_id) -> list[str]get_capacity_references(capacity_id) -> list[CapacityReferenceRow]batch_get_capacity_descriptions(capacity_ids) -> dict[str, str | None]batch_get_capacity_certificates(capacity_ids) -> dict[str, list[str]]batch_get_capacity_references(capacity_ids) -> dict[str, list[CapacityReferenceRow]]- Docstrings gemäß Design (Quelle, Join-Verhalten inkl. Partner-Join
partner_id = id, Rückgabetyp bei leerer Eingabe, leererpartner_namebei NULL/Mismatch) - Requirements: 2.1, 2.2, 2.3, 2.4, 2.8
-
1.2 Einzel-Methoden im
TrinoClientimplementieren (database/trino_client.py)- SELECT-Only-Statements mit
_ensure_select_only, Connection-Pool und_retry get_capacity_description: NULL/leerer String →Noneget_capacity_certificates: Join übercapacity_id, leere Strings filtern, Rückgabe[]wenn keine Trefferget_capacity_references: zusätzlichLEFT JOIN teamlandkarte_v_partners_latest p ON r.partner_id = p.idundCOALESCE(p.name, '') AS partner_namein derselben Abfrage; Rückgabe alsCapacityReferenceRow-Liste mitpartner_nameundprojects- NULL
partner_idbzw. Join-Mismatch → leererpartner_name, Referenz bleibt mitprojectserhalten (Anforderung 2.8) - Parameter-Bindung gegen SQL-Injection
- Requirements: 2.1, 2.2, 2.3, 2.5, 2.6, 2.7, 2.8, 2.9, 2.10
- SELECT-Only-Statements mit
-
1.3 Batch-Methoden im
TrinoClientimplementieren- Genau eine SQL-Abfrage pro Quelle (Anforderung 2.4); der Partner-LEFT-JOIN ist Bestandteil derselben Referenz-Abfrage und erzeugt keinen zusätzlichen Roundtrip
batch_get_capacity_references:SELECT r.capacity_id, r.projects, COALESCE(p.name, '') AS partner_name ... LEFT JOIN teamlandkarte_v_partners_latest p ON r.partner_id = p.id- Schlüssel der Rückgaben sind
str(capacity_id)(deterministisch) - Fehlende IDs als
None(Beschreibungen) bzw.[](Listen) vorbelegen - Gruppierung n:1 via
defaultdict(list), leereprojects-Strings filtern; leererpartner_name(NULL/Mismatch) führt nicht zum Verwerfen der Referenz - Frühe Rückkehr bei leerer Eingabeliste (
{}) - Requirements: 2.4, 2.5, 2.6, 2.7, 2.8, 2.9, 2.10
-
1.4 Unit-Tests für die neuen DB-Methoden mit Mock-Cursor*
- Genau eine SQL-Abfrage je Methode wird abgesetzt; LEFT JOIN auf
teamlandkarte_v_partners_latestist Bestandteil derselben Referenz-Abfrage (kein zusätzlicher Roundtrip) - SELECT-Only-Guard wird angewendet
- Korrekte Gruppierung n:1 in den Batch-Varianten
- Mock-Cursor liefert für
referencesdrei Spalten (capacity_id,projects,partner_name); Test inkl. Fall NULLpartner_id→ leererpartner_name, Referenz bleibt erhalten - Defaults für fehlende IDs (None / [])
- Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8
- Genau eine SQL-Abfrage je Methode wird abgesetzt; LEFT JOIN auf
-
-
2. Datenmodelle
CapacityProfileundTaskProfile-
2.1 Neue frozen Dataclasses anlegen (
matching/profiles.py)CapacityReferenceEntryals@dataclass(frozen=True)mit Feldernpartner_name: strundprojects: str(partner_namedarf leer sein, vgl. Anforderung 2.8 / 3.2)CapacityProfilemit Feldernid,owner_name,role_name,competences,description,references: list[CapacityReferenceEntry],certificatesTaskProfilemit Feldernid,title,description,skills- Beide
@dataclass(frozen=True)und nur primitive Felder bzw.list[str]/list[CapacityReferenceEntry] - Requirements: 3.1, 3.2, 4.1
-
2.2 Profil-Builder implementieren (
matching/profiles.py)build_capacity_profile(capacity, *, description, certificates, references) -> CapacityProfile- Konvertiere
CapacityReferenceRow-Einträge aus dem DBClient inCapacityReferenceEntry-Instanzen; ein leererpartner_nameführt nicht zum Verwerfen der Referenz (Anforderung 3.4) build_task_profile(task) -> TaskProfile(alternativbuild_task_profile_from_requirements(...)für Suchrichtung Aufgabe→Kapazität)- Leere/
None-Felder → leerer String bzw. leere Liste, Profil wird nie verworfen - Reihenfolge der Felder ist über alle Profile konstant
- Requirements: 3.1, 3.2, 3.4, 4.1, 4.2
-
2.3 Deterministische Profil-Serialisierung implementieren
serialize_capacity_profile(profile) -> strmit fixer ReihenfolgeRolle:,Kompetenzen:,Beschreibung:,Referenzen:,Zertifikate:_format_reference(entry: CapacityReferenceEntry) -> str: bei nicht-leerempartner_name→Partner: <partner_name> – Projekte: <projects>; bei leerempartner_name→Projekte: <projects>(kein Platzhalter, keinPartner:-Token)serialize_task_profile(profile) -> strmit fixer ReihenfolgeTitel:,Beschreibung:,Gesuchte Kompetenzen:- Leere Listen werden als
(keine)ausgegeben, alle Feldüberschriften erscheinen immer; Reihenfolge der Felder und Referenzen bleibt deterministisch - Requirements: 3.3, 3.4, 3.6, 3.7, 4.3, 4.4
-
2.4 Property-Test für deterministische Serialisierung schreiben
- Property 1: Profil-Serialisierung ist deterministisch und feldvollständig
- Hypothesis mit
@settings(max_examples=100),st.builds(...)für Profile inkl.CapacityReferenceEntrymit/ohnepartner_name - Zwei Aufrufe liefern identischen String; alle Feldüberschriften enthalten; Partner-Name erscheint deterministisch in der serialisierten Ausgabe, sofern nicht leer
- Validates: Requirements 3.3, 3.4, 3.6, 3.7, 4.3, 4.4
-
2.5 Property-Test für Profil-Builder mit leeren Feldern schreiben
- Property 2: Leere/None-Felder verwerfen das Profil nicht
- Capacity-/Task-Strategien mit
st.one_of(st.none(), st.text()); Referenzen-Strategie mit gemischtempartner_name(st.one_of(st.just(""), st.text(min_size=1))) - Profil enthält leere Strings/Listen; Serialisierung enthält weiterhin alle Überschriften; auch Referenzen mit leerem
partner_namewerden nicht verworfen - Validates: Requirements 3.2, 3.4, 4.2
-
2.6 Property-Test für Referenzen mit leerem Partner-Name schreiben
- Property 2b: Referenzen mit leerem Partner_Name behalten projects, ohne Partner-Token
- Hypothesis-Generator mischt leere und nicht-leere
partner_name-Werte:st.lists(st.builds(CapacityReferenceEntry, partner_name=st.one_of(st.just(""), st.text(min_size=1)), projects=st.text(min_size=1))) - Prüft (a) die Anzahl der Referenz-Zeilen entspricht der Anzahl der Einträge mit nicht-leerem
projects, (b) jede Zeile zu einem Eintrag mit leerempartner_namebeginnt mitProjekte:und enthält keinenPartner:-Token, (c) jede Zeile zu einem Eintrag mit nicht-leerempartner_nameenthält sowohlPartner: <name>als auchProjekte: <projects> - Validates: Requirements 2.8, 3.4, 3.6
-
-
3.
LlmFulltextMatcher-Komponente bauen-
3.1 Modul-Skelett
matching/llm_fulltext_matcher.pyanlegen- Konstanten
_ALLOWED_CATEGORIES = ("Top", "Good", "Partial", "Low", "Irrelevant")und_ALIAS - Dataclasses
LlmFulltextItem,LlmFulltextError,LlmFulltextResult - Klasse
LlmFulltextMatchermit Konstruktor(*, db, client, rationale_max_chars=280) - Requirements: 5.1, 5.3, 6.1, 6.3, 7.4
- Konstanten
-
3.2 Kategorie-Normalisierung implementieren
normalize_category(value) -> tuple[str, bool]- Trim + lowercase, Mapping über
_ALIAS, ungültige Werte →("Irrelevant", False) - Nicht-String-Eingaben →
("Irrelevant", False) - Requirements: 5.3, 5.6, 6.3, 6.6
-
3.3 Property-Test für Kategorie-Normalisierung schreiben
- Property 3: Kategorienormalisierung bildet auf erlaubte Menge ab
- Hypothesis mit
st.text()und Aliase viast.sampled_from - Output immer in erlaubter Menge;
is_validkorrekt - Validates: Requirements 5.3, 5.6, 6.3, 6.6
-
3.4 LLM-Aufruf und Antwort-Parsing implementieren
- System-Prompt gemäß Design (deutschsprachig, deterministisch, JSON-only)
- User-Prompt baut auf
serialize_task_profile/serialize_capacity_profileauf chat_completion(system, user, response_format=json_object)aufrufen- JSON parsen, Felder
categoryundrationaleextrahieren - Bei
JSONDecodeError→LlmFulltextErrormit Meldung"invalid JSON: <excerpt>" - Bei ungültiger Kategorie → Item nach
Irrelevantmit Hinweis[Hinweis: ungültige LLM-Kategorie: <wert>]an Rationale anhängen - Bei
AzureAPIError/Timeout/sonstiger Exception →LlmFulltextErrormit Klassenname + erstem Satz - Requirements: 5.4, 5.5, 5.6, 5.7, 6.4, 6.5, 6.6, 6.7
-
3.5
match_capacitiesimplementieren- Eingabe:
task_profile,capacities(bereits vorgefiltert) - Capacity-IDs sammeln,
batch_get_capacity_descriptions/certificates/referencesaufrufen - Pro Kapazität
CapacityProfilebauen und LLM-Aufruf durchführen - Erfolgreiche Items in
by_categoryeinsortieren, fehlerhafte inerrors - Innerhalb jeder Kategorie deterministisch nach
item_idaufsteigend (lexikographisch) sortieren - Requirements: 5.1, 5.2, 5.3, 5.4, 5.5, 5.7, 5.8
- Eingabe:
-
3.6
match_tasksimplementieren- Eingabe:
capacity_profile,tasks - Pro Aufgabe
TaskProfilebauen und LLM-Aufruf durchführen - Sortierung primär nach Kategorie, sekundär nach
task_idaufsteigend - Requirements: 6.1, 6.2, 6.3, 6.4, 6.5, 6.7, 6.8
- Eingabe:
-
3.7 Property-Test für ungültige LLM-Kategorie schreiben
- Property 4: Ungültige LLM-Kategorie wird auf Irrelevant gemappt
- Mock-LLM gibt zufällige ungültige Kategorie zurück
- Item landet in
Irrelevant, Rationale enthält Originaltext + Hinweis - Validates: Requirements 5.6, 6.6
-
3.8 Property-Test für LLM-Fehler-Trennung schreiben
- Property 5: LLM-Fehler erscheinen in der Fehlerliste, nicht als Ergebnis
- Hypothesis-Strategy
st.lists(st.booleans())als Fehlermaske - Items aus Fehlermaske erscheinen ausschließlich in
result.errors - Validates: Requirements 5.7, 6.7
-
3.9 Property-Test für deterministische Sortierung schreiben
- Property 6: Ergebnisse sind innerhalb jeder Kategorie deterministisch sortiert
- Permutationen der Eingabeliste erzeugen identische
by_category-Reihenfolge - Validates: Requirements 5.8, 6.8
-
3.10 Unit-Tests für
LlmFulltextMatchermit gemocktemAzureOpenAIClient*- Erfolgsfall (gültige Kategorie + Rationale)
- Ungültiges JSON
- Gültiges JSON mit unbekannter Kategorie
chat_completionwirftAzureAPIError- Vermischung mehrerer Items: Reihenfolge und Sortierung korrekt
- Requirements: 5.4, 5.5, 5.6, 5.7, 5.8, 6.4, 6.5, 6.6, 6.7, 6.8
-
-
4. Checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
5. Konfiguration
matching.default_methodeinführen-
5.1
MatchingConfigum Felddefault_method: str = "score"erweitern (config.py)- Validierung in
load_config: Wert muss"score"oder"llm_fulltext"sein - Bei ungültigem Wert
ConfigErrormit beschreibender Meldung werfen - Fehlender Schlüssel → Default
"score" - Requirements: 12.2, 12.3, 12.4
- Validierung in
-
5.2
config.tomlundconfig.toml.exampleaktualisieren- Neuer Abschnitt
[matching].default_method = "score"mit Kommentar zu erlaubten Werten - Requirements: 12.2, 12.3
- Neuer Abschnitt
-
5.3 Unit-Tests für Konfigurations-Validierung*
default_methodfehlt → Default"score"default_method = "llm_fulltext"→ übernommendefault_method = "irgendwas"→ConfigError- Requirements: 12.3, 12.4
-
-
6. MCP-Tool-Integration für
matching_method-
6.1 Hilfsfunktion
_resolve_matching_methodimmcp_server.pyimplementierenNone→cfg.matching.default_method- Trim + lowercase, gegen
("score", "llm_fulltext")validieren - Bei ungültigem Wert
ValueErrormit beiden erlaubten Werten in der Meldung werfen - Requirements: 1.1, 1.2, 1.5, 12.3
-
6.2
find_matching_capacitiesummatching_methoderweitern- Neuer Parameter
matching_method: Optional[str] = None - Validierung vor DB-/LLM-Aufrufen, bei Fehler frühe Markdown-Fehlermeldung mit erlaubten Werten zurückgeben
- Routing:
"score"→ bestehenderMatcher-Pfad;"llm_fulltext"→LlmFulltextMatcher.match_capacities - Im LLM-Modus Vorfilter (z. B. Verfügbarkeit) identisch zum Score-Modus anwenden
- Task_Profile aus aktuell bestätigtem Anforderungs-Set bauen
- Requirements: 1.1, 1.3, 1.4, 1.5, 5.1, 5.2
- Neuer Parameter
-
6.3
find_matching_tasksummatching_methoderweitern- Neuer Parameter
matching_method: Optional[str] = None - Routing analog 6.2
- Im LLM-Modus für die
capacity_idBeschreibung, Zertifikate und Referenzen aus DB laden und insCapacityProfileeinbeziehen - Requirements: 1.1, 1.3, 1.4, 1.5, 6.1, 6.2
- Neuer Parameter
-
6.4 Docstrings für betroffene MCP-Tools aktualisieren
find_matching_capacities,find_matching_tasks: Parametermatching_methodmit erlaubten Werten dokumentieren- Hinweis auf Unterschiede in Ausgabe-Schema (keine Score-Spalten im LLM-Modus,
Begründung-Spalte) - Requirements: 12.1
-
6.5 Property-Test für
matching_method-Validierung schreiben- Property 9: matching_method-Validierung lehnt unbekannte Werte ab
- Hypothesis-Strategy
st.text() - Bei ungültiger Eingabe enthält die Fehlermeldung beide erlaubten Werte; DB- und LLM-Mocks werden nicht aufgerufen
- Validates: Requirements 1.5
-
6.6 Unit-Tests für Routing in beiden MCP-Tools
matching_method=None→ Default greift, Schema entspricht Score-Modusmatching_method="llm_fulltext"→LlmFulltextMatcherwird aufgerufen, Score-Pfad nichtmatching_method="bogus"→ Fehlermeldung, weder DB noch LLM werden aufgerufen- Requirements: 1.1, 1.2, 1.3, 1.4, 1.5
-
-
7. SearchCache-Payload und META-JSON
-
7.1 Persistenz im SearchCache an LLM-Modus anpassen
matching_methodals Schlüssel im Payload aufnehmen (auch im Score-Modus)- Im LLM-Modus pro Item Felder
categoryundrationale(ungekürzt) speichern, keinerole_score/competence_score/overall_score - Optionale
errors-Liste mit{"item_id", "error"}im LLM-Modus - Im Score-Modus bisheriges Schema unverändert (keine
rationale/errors) - Requirements: 7.1, 7.4, 8.6, 9.5
-
7.2 META-JSON in Tool-Antworten um
matching_methoderweitern- In beiden Modi setzen, sodass Folgewerkzeuge das Schema korrekt interpretieren
- Requirements: 1.6, 9.5
-
7.3 Property-Test für persistierte ungekürzte Rationale schreiben
- Property 8: Ungekürzte Rationale wird persistiert
- Hypothesis
st.text(min_size=300), Cache-Eintrag muss exakt der LLM-Antwort entsprechen - Validates: Requirements 8.6
-
7.4 Property-Test für META-
matching_methodschreiben- Property 11: META enthält das verwendete Verfahren
- Aus Tool-Output META-JSON parsen und Wert prüfen
- Validates: Requirements 1.6, 9.5
-
7.5 Property-Test für Score-Modus-Abwärtskompatibilität schreiben
- Property 10: Score-Modus ist abwärtskompatibel
- Tool-Aufruf ohne
matching_methodbzw. mit"score": Persistiertes Payload-Schema entspricht weiter dem bisherigen (Felderrole_score,competence_score,overall_score; keinrationale) - Validates: Requirements 1.2, 1.3, 7.3
-
-
8. Tabellenausgabe mit
Begründung-Spalte und Rationale-Formatierung-
8.1 Hilfsfunktion
_format_rationale_for_tableimplementieren- Pipes (
|) →/, Carriage Return / Linefeed → Leerzeichen - Whitespace zusammenfalten
- Bei > 280 Zeichen kürzen und mit
…abschließen - Requirements: 8.4, 8.5
- Pipes (
-
8.2 Ausgabe-Tabellen für
find_matching_capacities(LLM-Modus) anpassen- Spalten:
ID | Owner | Role | Competences | Availability | Category | Begründung - Keine Spalten
Role Score,Competence Score,Overall Score - Pro Zeile gekürzte Rationale via
_format_rationale_for_table - Leere Ergebnistabelle weiterhin korrekt rendern (Header-Konsistenz)
- Requirements: 7.1, 7.2, 8.1, 8.2, 8.3, 8.4, 8.5
- Spalten:
-
8.3 Ausgabe-Tabellen für
find_matching_tasks(LLM-Modus) anpassen- Spalten:
task_id | Title | Required Competences | Availability | Category | Begründung - Verhalten analog 8.2
- Requirements: 7.1, 7.2, 8.1, 8.2, 8.3, 8.4, 8.5
- Spalten:
-
8.4 Summary-Tabelle und Errors-Block einbauen
- Summary bleibt in beiden Modi identisch (Counter je Kategorie)
- Wenn
errorsnicht leer: zusätzlicher Markdown-Block## Errorsnach der Ergebnistabelle - Requirements: 5.7, 6.7, 7.5
-
8.5 Score-Modus-Tabelle unverändert lassen (Regression)
- Bestehende Spalten
Role Score,Competence Score,Overall Score,Categorybleiben - Keine
Begründung-Spalte - Requirements: 7.3
- Bestehende Spalten
-
8.6 Property-Test für
_format_rationale_for_tableschreiben- Property 7: Tabellen-Rationale ist gültiges Markdown und längenbegrenzt
- Hypothesis erzeugt Strings inkl.
|,\n, sehr lang - Output ≤ 280 Zeichen, weder
|noch Zeilenumbrüche,…-Suffix genau dann, wenn normalisierte Eingabe > 280 Zeichen war - Validates: Requirements 8.4, 8.5
-
-
9. Checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
10. Anpassungen für
get_results_by_category-
10.1 Hilfsfunktion
_format_results_table(items, *, search_type, matching_method, ref_start, ref_end)einführen- Routing nach
matching_method: Score-Tabelle (bisher) oder LLM-Tabelle mitBegründung-Spalte - Wiederverwendbar in
find_matching_capacities,find_matching_tasksundget_results_by_category - Requirements: 7.1, 7.2, 8.1, 8.2, 9.2
- Routing nach
-
10.2
get_results_by_categoryan LLM-Modus anpassenmatching_methodaus persistiertem SearchEntry lesen- Im LLM-Modus Tabelle ohne Score-Spalten und mit
Begründung-Spalte rendern - Im Score-Modus unverändertes Verhalten
- META-JSON enthält
matching_method - Requirements: 9.1, 9.2, 9.5
-
10.3 Docstring für
get_results_by_categoryaktualisieren- Hinweis auf modusabhängige Spalten (
Begründungim LLM-Modus) - Requirements: 12.1
- Hinweis auf modusabhängige Spalten (
-
-
11. Anpassungen für
filter_search_results-
11.1 Modus-Erkennung über persistiertes
matching_method- Im LLM-Modus bestehende Filter (Rollen-, Kompetenz-, Verfügbarkeits-, Aufgaben-Text-/Kompetenzfilter) weiterhin anwenden
- Score-bezogenen Filter
min_similarityignorieren und inApplied Filterseinen Hinweis aufnehmen (min_similarity (ignored: not applicable in llm_fulltext mode)) - Requirements: 9.3, 9.4
-
11.2 Sortierung in
filter_search_resultsmodusabhängig- Score-Modus: bestehende Sortierung nach
overall_score - LLM-Modus: stabile Sortierung nach
(category_rank, item_id) - Requirements: 5.8, 6.8, 9.3
- Score-Modus: bestehende Sortierung nach
-
11.3 Tabellen-Rendering in
filter_search_resultsan_format_results_tableanbinden- Verwendung der neuen Hilfsfunktion (siehe 10.1) für konsistente Spalten
- META-JSON enthält
matching_method - Requirements: 9.2, 9.5
-
11.4 Docstring für
filter_search_resultsaktualisieren- Hinweis, dass
min_similarityim LLM-Modus ignoriert wird - Requirements: 12.1
- Hinweis, dass
-
11.5 Unit-Tests für
get_results_by_categoryundfilter_search_resultsin beiden Modi- LLM-Modus:
Begründung-Spalte vorhanden,min_similarityignoriert mit Hinweis - Score-Modus: bestehendes Verhalten unverändert (Regression)
- Requirements: 9.1, 9.2, 9.3, 9.4, 9.5
- LLM-Modus:
-
-
12. Server-Wiring und Integrationstests
-
12.1
LlmFulltextMatcherinbuild_serverinstanziieren- Konstruktor mit
db,client(AzureOpenAIClient) verdrahten - Komponente an MCP-Tool-Handler weiterreichen
- Requirements: 1.4, 5.1, 6.1
- Konstruktor mit
-
12.2 End-to-End-Integrationstests mit gemocktem LLM-Client und gemocktem
DBClientfind_matching_capacitiesundfind_matching_tasksmitmatching_method="llm_fulltext"- Verfügbarkeitsfilter im LLM-Modus identisch zum Score-Modus
- SearchCache enthält
matching_method, ungekürzterationale,errors-Liste - Requirements: 5.1, 5.2, 6.1, 6.2, 7.4, 8.6, 9.5
-
12.3 Tabellen-Snapshot-Test für Header in beiden Modi
- Score-Modus-Header unverändert
- LLM-Modus-Header endet auf
... | Category | Begründung - Requirements: 7.1, 8.1, 8.2
-
-
13. Checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
-
14. Dokumentation aktualisieren
-
14.1
docs/architecture.mderweiternLLM_Fulltext_Matcherals Komponente in der Business-Logic-Layer beschreiben (Eingaben, Ausgaben, externe Abhängigkeit Azure OpenAI Chat Completion)- Zusätzliche Datenquellen (
teamlandkarte_v_capacities_latest.description,teamlandkarte_v_capacity_certificates_latest,teamlandkarte_v_capacity_references_latest,teamlandkarte_v_partners_latest.{id, name}) im Schema-Verifikationsabschnitt aufführen - Join
teamlandkarte_v_capacity_references_latest.partner_id = teamlandkarte_v_partners_latest.idund Übernahme der Spaltenameals Partner_Name dokumentieren - Tool-Surface-Tabelle um Parameter
matching_method(Wertebereichscore/llm_fulltext) ergänzen - Runtime-View für beide Suchrichtungen um den LLM-Volltext-Pfad erweitern
- Requirements: 11.1, 11.2, 11.3, 11.4, 11.5
-
14.2
README.mderweitern- Quick-Start- und Usage-Abschnitt: Auswahl zwischen
scoreundllm_fulltextper Tool-Parameter - Hinweis: Im LLM-Volltext-Modus keine numerischen Scores; stattdessen Spalte
Begründung - Zusätzliche Datenbank-Views auflisten, die der Server im LLM-Volltext-Modus liest, einschließlich
teamlandkarte_v_partners_latestmit Hinweis auf den LEFT JOIN überpartner_idin der Referenz-Abfrage - Default-Konfiguration
[matching].default_method - Requirements: 11.6, 11.7, 11.8
- Quick-Start- und Usage-Abschnitt: Auswahl zwischen
-
14.3
.github/agents/teamlandkarte_agent.mdaktualisieren- Beschreibung beider Verfahren
scoreundllm_fulltext(Existenz und Zweck) - Pflicht-Frage nach
matching_methodvorfind_matching_capacities/find_matching_tasks, sofern nicht aus dem Verlauf bekannt - Skills/Workflows: Aufruf der Tools mit zusätzlichem Parameter
matching_method - Rolle der Spalte
Begründungund Hinweis, dass im LLM-Modus keine numerischen Scores erscheinen - Bestehender Bestätigungs-Workflow (
show_pending_requirements,confirm_requirements) bleibt für beide Verfahren gleich - Requirements: 10.1, 10.2, 10.3, 10.4, 10.5
- Beschreibung beider Verfahren
-
14.4
.kiro/agents/teamlandkarte.mdanalog zu 14.3 aktualisieren- Inhaltliche Gleichheit zum GitHub-Pendant sicherstellen
- Requirements: 10.1, 10.2, 10.3, 10.4, 10.5
-
14.5 Beispiele und Mini-Walkthroughs in README/Architektur ergänzen
- Beispielausgabe einer LLM-Volltext-Tabelle inkl. Spalte
Begründung - Beispielhafte META-JSON-Ausgabe mit
matching_method - Requirements: 11.5, 11.6
- Beispielausgabe einer LLM-Volltext-Tabelle inkl. Spalte
-
-
15. Final checkpoint - Ensure all tests pass
- Ensure all tests pass, ask the user if questions arise.
Notes
- Tasks markiert mit
*sind optional und können für einen schnelleren MVP übersprungen werden. - Property-Based Tests verwenden Hypothesis mit
@settings(max_examples=100)(mindestens 100 Iterationen pro Property) und werden als# Feature: llm-fulltext-matching, Property {N}: {title}getaggt. - Unit- und Integrationstests verwenden
pytest(Run-once, kein Watch-Modus); derAzureOpenAIClientwird stets gemockt. - Tasks referenzieren explizit Anforderungen aus
requirements.mdzur lückenlosen Nachverfolgbarkeit. - Die Implementierungssprache ist Python (bestehende Codebase).
- Score-Modus bleibt vollständig abwärtskompatibel; nur additive Erweiterungen am Payload und am META-JSON.