# Anforderungsdokument ## Einleitung Dieses Dokument beschreibt die Anforderungen für die Einführung eines zweiten Matching-Verfahrens in der Teamlandkarte: einen **LLM-basierten Volltext-Vergleich** zwischen Aufgaben und Kapazitäten. Das bestehende Score-basierte Verfahren (Rolle + Kompetenzen, BM25/RRF + LLM-Rollen-Similarity) bleibt unverändert verfügbar. Der Nutzer wählt pro Suche das Verfahren aus. Das neue Verfahren bezieht zusätzliche Felder aus der Datenbank ein (Beschreibung, Referenzen, Zertifikate auf Kapazitätsseite; Titel, Beschreibung und gesuchte Kompetenzen auf Aufgabenseite), berechnet kein numerisches Scoring mehr und ordnet jede Kapazität bzw. Aufgabe direkt einer der bestehenden Kategorien zu. Zusätzlich liefert das LLM für jeden Fall eine Kurzbegründung (1–2 Sätze). ## Glossar - **MCP_Server**: Der Teamlandkarte MCP-Server (Modul `mcp_server.py`), der die MCP-Tools für Matching, Suche und Datenanzeige bereitstellt. - **DBClient**: Protokollklasse aus `database/types.py`, die alle Datenbankzugriffe abstrahiert. - **TrinoClient**: Konkrete `DBClient`-Implementierung (`database/trino_client.py`) für Trino/Presto. - **Matcher**: Bestehende, Score-basierte Matching-Komponente in `matching/matcher.py`. - **LLM_Fulltext_Matcher**: Neues Modul, das den LLM-basierten Volltext-Vergleich durchführt und Kategorien direkt zuweist. - **AzureOpenAIClient**: Wrapper für Azure-OpenAI-Chat-Completions in `azure/openai_client.py`. - **LLM**: Large Language Model (Azure OpenAI Chat Completion). - **Capacity**: Frozen Dataclass `Capacity` in `models.py` (Kapazitätseintrag eines Mitarbeitenden). - **Task**: Frozen Dataclass `Task` in `models.py` (veröffentlichte Aufgabe). - **Capacity_Profile**: Aggregiertes Volltext-Profil einer Kapazität, bestehend aus Rolle, Kompetenzen, Beschreibung, Referenzen und Zertifikaten. - **Task_Profile**: Aggregiertes Volltext-Profil einer Aufgabe, bestehend aus Titel, Beschreibung und gesuchten Kompetenzen. - **Matching_Method**: Auswahlwert für das verwendete Verfahren. Erlaubte Werte: `score` (bisheriges Score-basiertes Matching) und `llm_fulltext` (neues LLM-Volltext-Matching). - **Kategorie**: Eine der bestehenden Ergebniskategorien `Top`, `Good`, `Partial`, `Low`, `Irrelevant`. - **Rationale**: Vom LLM erzeugte Kurzbegründung (1–2 Sätze) für die zugewiesene Kategorie. - **find_matching_capacities**: MCP-Tool für die Suchrichtung Aufgabe→Kapazität. - **find_matching_tasks**: MCP-Tool für die Suchrichtung Kapazität→Aufgabe. - **Teamlandkarte_Agent**: GitHub-Copilot-Agent in `.github/agents/teamlandkarte_agent.md` (sowie das Pendant in `.kiro/agents/teamlandkarte.md`) inklusive seiner Skills/Workflows. - **Architecture_Doc**: `docs/architecture.md`. - **Readme**: `README.md` im Repository-Root. - **Capacity_Description**: Inhalt der Spalte `description` in `teamlandkarte_v_capacities_latest`. - **Capacity_Certificate**: Eintrag aus `teamlandkarte_v_capacity_certificates_latest` (Feld `description`, Join via `capacity_id`, 1:n). - **Capacity_Reference**: Eintrag aus `teamlandkarte_v_capacity_references_latest` (Spalte `projects`, Join via `capacity_id`, 1:n) inklusive des zugehörigen Partner_Name aus `teamlandkarte_v_partners_latest`. - **Partner**: Eintrag aus `teamlandkarte_v_partners_latest`. Eine Capacity_Reference verweist über die Spalte `partner_id` auf einen Partner; die Verknüpfung erfolgt über `teamlandkarte_v_capacity_references_latest.partner_id = teamlandkarte_v_partners_latest.id`. - **Partner_Name**: Wert der Spalte `name` aus `teamlandkarte_v_partners_latest`, der einer Capacity_Reference über `partner_id` zugeordnet ist. Ist `partner_id` `NULL` oder existiert kein passender Partner, gilt der Partner_Name als leere Zeichenkette. ## Anforderungen ### Anforderung 1: Auswahl des Matching-Verfahrens **User Story:** Als Nutzer möchte ich pro Suchanfrage zwischen dem bisherigen Score-basierten Matching und dem neuen LLM-basierten Volltext-Matching wählen können, damit ich je nach Situation das passende Verfahren einsetzen kann. #### Akzeptanzkriterien 1. THE MCP_Server SHALL akzeptieren einen Parameter `matching_method` mit den erlaubten Werten `score` und `llm_fulltext` in den Tools `find_matching_capacities` und `find_matching_tasks`. 2. WHEN `matching_method` nicht übergeben wird, THE MCP_Server SHALL den Standardwert `score` verwenden, sodass das bestehende Verhalten unverändert bleibt. 3. WHEN `matching_method = "score"` übergeben wird, THE MCP_Server SHALL das bestehende Score-basierte Matching ausführen. 4. WHEN `matching_method = "llm_fulltext"` übergeben wird, THE MCP_Server SHALL das neue LLM-basierte Volltext-Matching über den LLM_Fulltext_Matcher ausführen. 5. IF ein ungültiger Wert für `matching_method` übergeben wird, THEN THE MCP_Server SHALL eine Fehlermeldung zurückgeben, die die erlaubten Werte (`score`, `llm_fulltext`) auflistet, und die Suche nicht ausführen. 6. THE MCP_Server SHALL den verwendeten Wert von `matching_method` im Antwort-`META`-JSON sowie in der angezeigten Suchkonfiguration ausweisen. ### Anforderung 2: Erweiterte Datenabfrage für Kapazitäten **User Story:** Als Entwickler möchte ich, dass für das LLM-Volltext-Matching die Kapazitäts-Beschreibung, alle Zertifikate und alle Referenzen aus der Datenbank verfügbar sind, damit das LLM ein vollständiges Profil bewerten kann. #### Akzeptanzkriterien 1. THE DBClient SHALL eine Methode bereitstellen, die für eine gegebene `capacity_id` die Capacity_Description aus `teamlandkarte_v_capacities_latest` (Spalte `description`) zurückgibt. 2. THE DBClient SHALL eine Methode bereitstellen, die für eine gegebene `capacity_id` alle zugeordneten Capacity_Certificate-Beschreibungen aus `teamlandkarte_v_capacity_certificates_latest` (Feld `description`, Join über `capacity_id`) als Liste von Strings zurückgibt. 3. THE DBClient SHALL eine Methode bereitstellen, die für eine gegebene `capacity_id` alle zugeordneten Capacity_Reference-Einträge aus `teamlandkarte_v_capacity_references_latest` (Spalte `projects`, Join über `capacity_id`) inklusive des zugehörigen Partner_Name aus `teamlandkarte_v_partners_latest` (Join `teamlandkarte_v_capacity_references_latest.partner_id = teamlandkarte_v_partners_latest.id`, Spalte `name`) als Liste strukturierter Einträge mit den Feldern `projects` und `partner_name` zurückgibt. 4. WHEN ein LLM-Volltext-Matching für mehrere Kapazitäten ausgeführt wird, THE DBClient SHALL eine Batch-Variante bereitstellen, die Beschreibungen, Zertifikate und Referenzen (inklusive Partner_Name über den Join auf `teamlandkarte_v_partners_latest`) für eine Liste von `capacity_id`-Werten in höchstens drei SQL-Abfragen lädt (eine pro Quelle); der Partner-Join SHALL Bestandteil derselben Referenz-Abfrage sein und keine zusätzliche SQL-Abfrage erzeugen. 5. WHEN für eine Kapazität keine Beschreibung in der Datenbank vorhanden ist (NULL oder leer), THE DBClient SHALL für die Capacity_Description den Wert `None` zurückgeben. 6. WHEN für eine Kapazität keine Zertifikate vorhanden sind, THE DBClient SHALL eine leere Liste für Capacity_Certificate zurückgeben. 7. WHEN für eine Kapazität keine Referenzen vorhanden sind, THE DBClient SHALL eine leere Liste für Capacity_Reference zurückgeben. 8. IF die `partner_id` einer Capacity_Reference `NULL` ist oder der Join auf `teamlandkarte_v_partners_latest` keinen Treffer liefert, THEN THE DBClient SHALL den Partner_Name dieser Capacity_Reference als leere Zeichenkette zurückgeben und die Referenz dennoch mit dem Feld `projects` in der Ergebnisliste belassen. 9. THE TrinoClient SHALL alle neuen SQL-Abfragen ausschließlich als `SELECT`-Statements ausführen und die bestehende Read-Only-Guard `_ensure_select_only` verwenden. 10. THE TrinoClient SHALL die neuen Abfragen über die bestehende Connection-Pool-Infrastruktur und die Retry-Logik (`_retry`) ausführen. ### Anforderung 3: Aufbau des Capacity_Profile **User Story:** Als Entwickler möchte ich, dass das System aus den Datenbankfeldern ein konsistentes Volltext-Profil pro Kapazität erzeugt, damit das LLM eine einheitliche Eingabe erhält. #### Akzeptanzkriterien 1. THE LLM_Fulltext_Matcher SHALL pro Kapazität ein Capacity_Profile bilden, das die folgenden Felder enthält: `id`, `owner_name`, `role_name`, `competences`, `description`, `references` und `certificates`. 2. THE LLM_Fulltext_Matcher SHALL jedes Element der Liste `references` im Capacity_Profile als strukturierten Eintrag mit den Feldern `partner_name` und `projects` führen, sodass beide Bestandteile einer Capacity_Reference erhalten bleiben. 3. WHEN ein Feld in der Datenbank leer oder `None` ist, THE LLM_Fulltext_Matcher SHALL das entsprechende Feld im Capacity_Profile mit einer leeren Zeichenkette bzw. einer leeren Liste belegen, ohne das gesamte Profil zu verwerfen. 4. WHEN der Partner_Name einer Capacity_Reference leer ist, THE LLM_Fulltext_Matcher SHALL die Referenz dennoch in `references` aufnehmen und ausschließlich das Feld `projects` in die serialisierte Darstellung übernehmen, ohne einen Platzhaltertext für den Partner einzufügen. 5. THE LLM_Fulltext_Matcher SHALL das Capacity_Profile in einer für das LLM lesbaren, deterministischen Textstruktur serialisieren, in der jedes Feld klar mit einer Überschrift gekennzeichnet ist (z. B. `Rolle:`, `Kompetenzen:`, `Beschreibung:`, `Referenzen:`, `Zertifikate:`). 6. THE LLM_Fulltext_Matcher SHALL jeden Eintrag im Abschnitt `Referenzen:` so darstellen, dass sowohl Partner_Name als auch Projekte für das LLM sichtbar sind (z. B. im Format `Partner: – Projekte: ` oder als gleichwertige strukturierte Darstellung mit benannten Feldern). 7. THE LLM_Fulltext_Matcher SHALL die Reihenfolge der Felder in der serialisierten Darstellung über alle Kapazitäten konstant halten, sodass die LLM-Eingabe deterministisch ist. ### Anforderung 4: Aufbau des Task_Profile **User Story:** Als Entwickler möchte ich, dass das System aus den Datenbankfeldern ein konsistentes Volltext-Profil pro Aufgabe erzeugt, damit das LLM eine einheitliche Eingabe erhält. #### Akzeptanzkriterien 1. THE LLM_Fulltext_Matcher SHALL pro Aufgabe ein Task_Profile bilden, das die folgenden Felder enthält: `id`, `title`, `description` und `skills` (gesuchte Kompetenzen). 2. WHEN ein Feld in der Datenbank leer oder `None` ist, THE LLM_Fulltext_Matcher SHALL das entsprechende Feld im Task_Profile mit einer leeren Zeichenkette bzw. einer leeren Liste belegen. 3. THE LLM_Fulltext_Matcher SHALL das Task_Profile in einer für das LLM lesbaren, deterministischen Textstruktur serialisieren, in der jedes Feld klar mit einer Überschrift gekennzeichnet ist (z. B. `Titel:`, `Beschreibung:`, `Gesuchte Kompetenzen:`). 4. THE LLM_Fulltext_Matcher SHALL die Reihenfolge der Felder in der serialisierten Darstellung über alle Aufgaben konstant halten. ### Anforderung 5: LLM-Volltext-Matching für die Richtung Aufgabe→Kapazität **User Story:** Als Nutzer möchte ich, dass `find_matching_capacities` mit `matching_method = "llm_fulltext"` einen LLM-basierten Volltext-Vergleich zwischen einem Task_Profile und allen Capacity_Profile-Einträgen durchführt, damit ich Kapazitäten über die rein lexikalische Kompetenzbetrachtung hinaus bewerten lassen kann. #### Akzeptanzkriterien 1. WHEN `find_matching_capacities` mit `matching_method = "llm_fulltext"` aufgerufen wird, THE LLM_Fulltext_Matcher SHALL für jede gefilterte Kapazität (gleicher Vorfilter wie beim Score-Matching, z. B. Verfügbarkeitsfilter) einen LLM-Vergleich zwischen Task_Profile und Capacity_Profile durchführen. 2. WHEN `find_matching_capacities` mit `matching_method = "llm_fulltext"` aufgerufen wird, THE MCP_Server SHALL als Eingabe das aktuell bestätigte Anforderungs-Set (`role_name`, `competences`, optionale Beschreibung, Zeitraum) sowie ggf. die zugrunde liegende Aufgabe verwenden, um das Task_Profile zu bilden. 3. THE LLM_Fulltext_Matcher SHALL pro Kapazität genau eine Kategorie aus der Menge `Top`, `Good`, `Partial`, `Low`, `Irrelevant` zurückgeben. 4. THE LLM_Fulltext_Matcher SHALL pro Kapazität eine Rationale mit 1 bis 2 Sätzen zurückgeben, die die Zuweisung in die jeweilige Kategorie erläutert. 5. THE LLM_Fulltext_Matcher SHALL die LLM-Antwort als strukturiertes JSON pro Kapazität anfordern und parsen (Felder: `category`, `rationale`). 6. IF das LLM für eine Kapazität eine Kategorie zurückgibt, die nicht in der erlaubten Menge liegt, THEN THE LLM_Fulltext_Matcher SHALL diese Kapazität der Kategorie `Irrelevant` zuordnen und die Rationale durch einen Hinweis auf die ungültige LLM-Antwort ergänzen. 7. IF der LLM-Aufruf für eine Kapazität fehlschlägt, THEN THE LLM_Fulltext_Matcher SHALL diese Kapazität in einer separaten Fehlerliste ausweisen und sie nicht als reguläres Ergebnis kategorisieren. 8. THE LLM_Fulltext_Matcher SHALL die Ergebnisse nach Kategorie gruppieren und innerhalb jeder Kategorie eine deterministische Sortierreihenfolge anwenden (Sortierung primär nach Kategorie, sekundär nach `capacity_id` aufsteigend). ### Anforderung 6: LLM-Volltext-Matching für die Richtung Kapazität→Aufgabe **User Story:** Als Nutzer möchte ich, dass `find_matching_tasks` mit `matching_method = "llm_fulltext"` einen LLM-basierten Volltext-Vergleich zwischen einem Capacity_Profile und allen Task_Profile-Einträgen durchführt, damit ich auch in dieser Suchrichtung das neue Verfahren nutzen kann. #### Akzeptanzkriterien 1. WHEN `find_matching_tasks` mit `matching_method = "llm_fulltext"` aufgerufen wird, THE LLM_Fulltext_Matcher SHALL für jede offene Aufgabe einen LLM-Vergleich zwischen Capacity_Profile und Task_Profile durchführen. 2. WHEN `find_matching_tasks` mit `matching_method = "llm_fulltext"` aufgerufen wird, THE MCP_Server SHALL für die angegebene `capacity_id` Beschreibung, Zertifikate und Referenzen aus der Datenbank laden und in das Capacity_Profile einbeziehen. 3. THE LLM_Fulltext_Matcher SHALL pro Aufgabe genau eine Kategorie aus der Menge `Top`, `Good`, `Partial`, `Low`, `Irrelevant` zurückgeben. 4. THE LLM_Fulltext_Matcher SHALL pro Aufgabe eine Rationale mit 1 bis 2 Sätzen zurückgeben. 5. THE LLM_Fulltext_Matcher SHALL die LLM-Antwort als strukturiertes JSON pro Aufgabe anfordern und parsen (Felder: `category`, `rationale`). 6. IF das LLM für eine Aufgabe eine Kategorie zurückgibt, die nicht in der erlaubten Menge liegt, THEN THE LLM_Fulltext_Matcher SHALL diese Aufgabe der Kategorie `Irrelevant` zuordnen und die Rationale durch einen Hinweis auf die ungültige LLM-Antwort ergänzen. 7. IF der LLM-Aufruf für eine Aufgabe fehlschlägt, THEN THE LLM_Fulltext_Matcher SHALL diese Aufgabe in einer separaten Fehlerliste ausweisen und sie nicht als reguläres Ergebnis kategorisieren. 8. THE LLM_Fulltext_Matcher SHALL die Ergebnisse nach Kategorie gruppieren und innerhalb jeder Kategorie eine deterministische Sortierreihenfolge anwenden (Sortierung primär nach Kategorie, sekundär nach `task_id` aufsteigend). ### Anforderung 7: Direkte Kategorisierung ohne mathematisches Scoring **User Story:** Als Nutzer möchte ich beim LLM-Volltext-Matching keine numerischen Score-Spalten mehr sehen, sondern ausschließlich die vom LLM zugewiesene Kategorie, damit das neue Verfahren als rein qualitative Bewertung erkennbar ist. #### Akzeptanzkriterien 1. WHEN `matching_method = "llm_fulltext"` verwendet wird, THE MCP_Server SHALL in den Ergebnistabellen keine Spalten `Role Score`, `Competence Score` oder `Overall Score` ausgeben. 2. WHEN `matching_method = "llm_fulltext"` verwendet wird, THE MCP_Server SHALL für jeden Treffer ausschließlich die LLM-zugewiesene Kategorie als Bewertungsfeld ausweisen. 3. WHEN `matching_method = "score"` verwendet wird, THE MCP_Server SHALL die bestehenden Score-Spalten unverändert ausgeben. 4. THE LLM_Fulltext_Matcher SHALL für jedes Ergebnis ein Datenfeld `category` (String) und ein Datenfeld `rationale` (String) im gespeicherten Suchergebnis (`SearchCache`) hinterlegen, ohne numerische Scores zu schreiben. 5. THE MCP_Server SHALL die Summary-Tabelle im LLM-Volltext-Modus weiterhin als Zähler je Kategorie (`Top`, `Good`, `Partial`, `Low`, `Irrelevant`) ausgeben. ### Anforderung 8: Begründungsspalte (Rationale) in der Ausgabe **User Story:** Als Nutzer möchte ich in der Ergebnistabelle des LLM-Volltext-Matchings eine zusätzliche Spalte sehen, die in 1–2 Sätzen erläutert, warum eine Kapazität bzw. Aufgabe in der jeweiligen Kategorie gelandet ist, damit ich die Entscheidung des LLM nachvollziehen kann. #### Akzeptanzkriterien 1. WHEN `matching_method = "llm_fulltext"` verwendet wird, THE MCP_Server SHALL die Ergebnistabellen für `find_matching_capacities` und `find_matching_tasks` um eine Spalte `Begründung` (Rationale) erweitern. 2. THE MCP_Server SHALL die Spalte `Begründung` direkt rechts neben der Spalte `Category` einfügen. 3. THE MCP_Server SHALL pro Zeile genau die vom LLM zurückgegebene Rationale (1–2 Sätze) anzeigen. 4. WHEN die Rationale Zeilenumbrüche oder Pipe-Zeichen enthält, THE MCP_Server SHALL diese so escapen oder ersetzen, dass die Markdown-Tabelle gültig bleibt. 5. WHEN die Rationale länger als 280 Zeichen ist, THE MCP_Server SHALL die Rationale auf 280 Zeichen kürzen und ein abschließendes Auslassungszeichen (`…`) anhängen, damit die Tabellendarstellung lesbar bleibt. 6. THE MCP_Server SHALL die ungekürzte Rationale im persistierten Suchergebnis (`SearchCache`) speichern, sodass nachgelagerte Tools (`get_results_by_category`, `filter_search_results`) den vollständigen Text ausgeben können. ### Anforderung 9: Kompatibilität mit Refinement- und Pagination-Tools **User Story:** Als Nutzer möchte ich auch beim LLM-Volltext-Matching durch Kategorien blättern und Filter anwenden können, damit der bestehende Such-Workflow konsistent bleibt. #### Akzeptanzkriterien 1. WHEN `matching_method = "llm_fulltext"` verwendet wird, THE MCP_Server SHALL ein gültiges `search_id` zurückgeben, das mit `get_results_by_category` und `filter_search_results` verwendet werden kann. 2. WHEN `get_results_by_category` ein Suchergebnis aus dem LLM-Volltext-Modus paginiert, THE MCP_Server SHALL die Ergebnistabelle ohne Score-Spalten und mit der Spalte `Begründung` ausgeben. 3. WHEN `filter_search_results` ein Suchergebnis aus dem LLM-Volltext-Modus filtert, THE MCP_Server SHALL die Filterung ausschließlich auf nicht-Score-basierten Filtern (Rollenfilter, Kompetenzfilter, Verfügbarkeitsfilter, Aufgaben-Textfilter, Aufgaben-Kompetenzfilter) durchführen. 4. IF ein Score-bezogener Filter (z. B. `min_similarity`) auf ein LLM-Volltext-Suchergebnis angewendet wird, THEN THE MCP_Server SHALL den Filter ignorieren und in der `Applied Filters`-Tabelle einen Hinweis aufnehmen, dass der Filter im LLM-Volltext-Modus nicht wirksam ist. 5. THE MCP_Server SHALL im `META`-JSON des Suchergebnisses das verwendete Verfahren als `matching_method` ausweisen, damit Folgewerkzeuge das Schema korrekt interpretieren können. ### Anforderung 10: Anpassung der Copilot-Agent-Konfiguration **User Story:** Als Nutzer möchte ich, dass sowohl der GitHub-Copilot-Agent `teamlandkarte_agent` als auch der Kiro-Pendant-Agent das neue Matching-Verfahren kennen und mich aktiv nach dem gewünschten Verfahren fragen, damit das neue Feature über die Agenten nutzbar ist. #### Akzeptanzkriterien 1. THE Teamlandkarte_Agent SHALL in seiner Konfigurationsdatei (`.github/agents/teamlandkarte_agent.md`) und im Pendant `.kiro/agents/teamlandkarte.md` die Existenz und den Zweck der beiden Verfahren `score` und `llm_fulltext` dokumentieren. 2. WHEN der Nutzer eine Suche nach passenden Kapazitäten oder Aufgaben startet, THE Teamlandkarte_Agent SHALL den Nutzer explizit nach dem gewünschten `matching_method` (Score-basiert oder LLM-Volltext) fragen, sofern dieses nicht bereits aus dem Verlauf hervorgeht. 3. THE Teamlandkarte_Agent SHALL die Skills/Workflows so erweitern, dass `find_matching_capacities` und `find_matching_tasks` mit dem zusätzlichen Parameter `matching_method` aufgerufen werden. 4. THE Teamlandkarte_Agent SHALL die Rolle der Spalte `Begründung` im Output dokumentieren und in den Hinweisen erwähnen, dass im LLM-Volltext-Modus keine numerischen Scores erscheinen. 5. THE Teamlandkarte_Agent SHALL den bestehenden Bestätigungs-Workflow (`show_pending_requirements`, `confirm_requirements`) beibehalten und für beide Verfahren gleich anwenden. ### Anforderung 11: Aktualisierung von Architektur- und README-Dokumentation **User Story:** Als Entwickler oder Onboardee möchte ich, dass `architecture.md` und `README.md` das neue Matching-Verfahren beschreiben, damit ich Architektur und Nutzung des Systems korrekt verstehe. #### Akzeptanzkriterien 1. THE Architecture_Doc SHALL einen Abschnitt enthalten, der den LLM_Fulltext_Matcher als Komponente innerhalb der Business-Logic-Layer beschreibt, einschließlich seiner Eingaben, Ausgaben und externen Abhängigkeiten (Azure OpenAI Chat Completion). 2. THE Architecture_Doc SHALL die zusätzlichen Datenquellen (`teamlandkarte_v_capacities_latest.description`, `teamlandkarte_v_capacity_certificates_latest`, `teamlandkarte_v_capacity_references_latest`, `teamlandkarte_v_partners_latest`) im Datenmodell- und Schema-Verifikationsabschnitt aufführen. 3. THE Architecture_Doc SHALL die Verknüpfung zwischen `teamlandkarte_v_capacity_references_latest.partner_id` und `teamlandkarte_v_partners_latest.id` sowie die Übernahme der Spalte `name` als Partner_Name in das Capacity_Profile dokumentieren. 4. THE Architecture_Doc SHALL den neuen Parameter `matching_method` und seine Wertebereiche im Tool-Surface-Abschnitt für `find_matching_capacities` und `find_matching_tasks` dokumentieren. 5. THE Architecture_Doc SHALL den Runtime-View für beide Suchrichtungen um den LLM-Volltext-Pfad ergänzen. 6. THE Readme SHALL im Quick-Start- und Usage-Abschnitt erklären, wie der Nutzer zwischen `score` und `llm_fulltext` wählt. 7. THE Readme SHALL beschreiben, dass im LLM-Volltext-Modus keine numerischen Scores ausgegeben werden und stattdessen eine Spalte `Begründung` erscheint. 8. THE Readme SHALL die zusätzlichen Datenbank-Views aufführen, die der Server im LLM-Volltext-Modus liest, einschließlich `teamlandkarte_v_partners_latest` und der Verknüpfung zu Capacity_Reference über `partner_id`. ### Anforderung 12: Anpassung weiterer Skripte und Tools **User Story:** Als Entwickler möchte ich, dass alle relevanten Hilfsskripte und MCP-Tools mit dem neuen Verfahren konsistent zusammenarbeiten, damit es keine Inkonsistenzen zwischen Server, Agent und Skripten gibt. #### Akzeptanzkriterien 1. THE MCP_Server SHALL den Parameter `matching_method` in allen Docstrings der betroffenen Tools (`find_matching_capacities`, `find_matching_tasks`, ggf. `filter_search_results`, `get_results_by_category`) dokumentieren. 2. THE MCP_Server SHALL die Konfigurationsdatei `config.toml` um einen optionalen Schlüssel `matching.default_method` erweitern, der den Standardwert für `matching_method` beim Server-Start festlegt. 3. WHEN `matching.default_method` in `config.toml` nicht gesetzt ist, THE MCP_Server SHALL den Default-Wert `score` verwenden. 4. IF `matching.default_method` einen anderen Wert als `score` oder `llm_fulltext` enthält, THEN THE MCP_Server SHALL beim Start einen `ConfigError` mit beschreibender Meldung werfen. 5. THE MCP_Server SHALL alle bestehenden Tests so erweitern oder ergänzen, dass sowohl der Modus `score` als auch der Modus `llm_fulltext` (mit gemocktem LLM) abgedeckt sind.