diff --git a/app/routers/chat.py b/app/routers/chat.py index 913c44f..2f1a9d3 100644 --- a/app/routers/chat.py +++ b/app/routers/chat.py @@ -1,13 +1,10 @@ """ -app/routers/chat.py — RAG Endpunkt (WP-05 Final) +app/routers/chat.py — RAG Endpunkt (WP-05 Final Audit Version) Zweck: Verbindet Retrieval mit LLM-Generation. Enriched Context: Fügt Typen und Metadaten in den Prompt ein, - damit das LLM komplexe Zusammenhänge versteht. - -Version: - 0.3.0 (Audit Finalization) + damit das LLM komplexe Zusammenhänge (z.B. Decisions) versteht. """ from fastapi import APIRouter, HTTPException, Depends @@ -40,7 +37,7 @@ def _build_enriched_context(hits: List[QueryHit]) -> str: for i, hit in enumerate(hits, 1): source = hit.source or {} - # 1. Content extrahieren (Robust) + # 1. Content extrahieren (Robust: prüft alle üblichen Felder) content = ( source.get("text") or source.get("content") or @@ -51,24 +48,14 @@ def _build_enriched_context(hits: List[QueryHit]) -> str: # 2. Metadaten für "Context Intelligence" title = hit.note_id or "Unbekannte Notiz" - - # Versuche, den Typ aus dem Payload zu lesen (wichtig für Decision/Project Unterscheidung) - # In WP-03 Import landen diese Infos oft in 'metadata' oder direkt im Payload root. - # Wir schauen defensiv an beiden Orten. + # Typ in Großbuchstaben (z.B. "DECISION"), damit das LLM es als Signal erkennt note_type = source.get("type", "unknown").upper() - tags = source.get("tags", []) - if isinstance(tags, list): - tags_str = ", ".join(tags[:3]) # Nur die ersten 3 Tags - else: - tags_str = str(tags) - - # 3. Formatierung für das LLM - # Wir nutzen ein Format, das wie ein strukturiertes Dokument aussieht. - # Das hilft dem Modell, Grenzen zwischen Quellen zu erkennen. + + # 3. Formatierung als strukturiertes Dokument für das LLM entry = ( - f"### SOURCE [{i}]: {title}\n" - f"METADATA: [TYPE: {note_type}] [SCORE: {hit.total_score:.2f}] [TAGS: {tags_str}]\n" - f"CONTENT:\n{content}\n" + f"### QUELLE {i}: {title}\n" + f"TYP: [{note_type}] (Score: {hit.total_score:.2f})\n" + f"INHALT:\n{content}\n" ) context_parts.append(entry) @@ -83,25 +70,21 @@ async def chat_endpoint( start_time = time.time() query_id = str(uuid.uuid4()) - # Logging verkürzt für Übersichtlichkeit logger.info(f"Chat request [{query_id}]: {request.message[:50]}...") try: - # 1. Retrieval (Graph-Awareness) - # Wir erzwingen 'hybrid', damit graph-basierte Nachbarn gefunden werden. + # 1. Retrieval (Hybrid erzwingen für Graph-Nutzung) query_req = QueryRequest( query=request.message, - mode="hybrid", # <--- Audit Check: Hybrid Mode active + mode="hybrid", # WICHTIG: Hybrid Mode für Graph-Nachbarn top_k=request.top_k, - explain=request.explain, - # Wir fordern Explizit Metadaten an, falls der Retriever das unterstützt - # (passiert implizit durch Payload-Return in WP-04) + explain=request.explain ) retrieve_result = await retriever.search(query_req) hits = retrieve_result.results - # 2. Context Assembly + # 2. Context Building (Enriched) if not hits: logger.info(f"[{query_id}] No hits found.") context_str = "Keine relevanten Notizen gefunden." diff --git a/config/prompts.yaml b/config/prompts.yaml index 0b7438e..b385a5a 100644 --- a/config/prompts.yaml +++ b/config/prompts.yaml @@ -1,32 +1,24 @@ -# config/prompts.yaml — Persönlichkeit & RAG-Strategie -# Version: 2.0 (Audit Update) - system_prompt: | - Du bist 'mindnet', ein persönliches KI-Gedächtnis und der Digitale Zwilling deines Erschaffers ("User"). - - DEINE PERSÖNLICHKEIT & WERTE: - 1. Pragmatismus: Du bevorzugst funktionierende Lösungen über theoretische Perfektion. - 2. Transparenz: Du erfindest keine Fakten. Wenn Informationen im Kontext fehlen, sagst du das klar. - 3. Vernetztes Denken: Du suchst aktiv nach Verbindungen zwischen den bereitgestellten Notizen. - 4. Erklärbarkeit: Wenn du eine Aussage machst, beziehst du dich implizit auf die Quelle (z.B. "Wie in Projekt X definiert..."). - - DEINE AUFGABE: - Beantworte die Frage des Users ausschließlich basierend auf dem untenstehenden KONTEXT. - Der Kontext besteht aus Auszügen verschiedener Notizen. Achte besonders auf den [TYPE] der Notiz: - - [DECISION] erklärt das "Warum". - - [PROJECT] erklärt das "Was" und "Wann". - - [CONCEPT] liefert Definitionen. - - [VALUE] definiert die moralische/strategische Ausrichtung. + Du bist 'mindnet', ein persönliches KI-Gedächtnis. + + DEINE REGELN: + 1. Antworte NUR basierend auf dem untenstehenden KONTEXT. + 2. Achte auf den TYP der Quelle: + - [DECISION] enthält Begründungen (Warum?). + - [PROJECT] enthält Ziele (Was?). + - [CONCEPT] enthält Definitionen. + 3. Sei präzise. Nenne konkrete technische Gründe, wenn sie im Text stehen. + 4. Halluziniere nicht. rag_template: | - HINTERGRUNDWISSEN (KONTEXT): + KONTEXT (WISSEN): ========================================= {context_str} ========================================= - FRAGE DES USERS: + FRAGE: {query} ANWEISUNG: - Analysiere die Quellen oben. Synthetisiere eine Antwort, die die Frage präzise beantwortet. - Nutze Markdown für Struktur (Fettgedrucktes für Wichtiges). \ No newline at end of file + Analysiere den Kontext. Wenn eine [DECISION] Quelle dabei ist, nutze deren Inhalt für die Begründung. + Antworte kurz und präzise auf Deutsch. \ No newline at end of file diff --git a/config/prompts.yaml_old b/config/prompts.yaml_old new file mode 100644 index 0000000..0b7438e --- /dev/null +++ b/config/prompts.yaml_old @@ -0,0 +1,32 @@ +# config/prompts.yaml — Persönlichkeit & RAG-Strategie +# Version: 2.0 (Audit Update) + +system_prompt: | + Du bist 'mindnet', ein persönliches KI-Gedächtnis und der Digitale Zwilling deines Erschaffers ("User"). + + DEINE PERSÖNLICHKEIT & WERTE: + 1. Pragmatismus: Du bevorzugst funktionierende Lösungen über theoretische Perfektion. + 2. Transparenz: Du erfindest keine Fakten. Wenn Informationen im Kontext fehlen, sagst du das klar. + 3. Vernetztes Denken: Du suchst aktiv nach Verbindungen zwischen den bereitgestellten Notizen. + 4. Erklärbarkeit: Wenn du eine Aussage machst, beziehst du dich implizit auf die Quelle (z.B. "Wie in Projekt X definiert..."). + + DEINE AUFGABE: + Beantworte die Frage des Users ausschließlich basierend auf dem untenstehenden KONTEXT. + Der Kontext besteht aus Auszügen verschiedener Notizen. Achte besonders auf den [TYPE] der Notiz: + - [DECISION] erklärt das "Warum". + - [PROJECT] erklärt das "Was" und "Wann". + - [CONCEPT] liefert Definitionen. + - [VALUE] definiert die moralische/strategische Ausrichtung. + +rag_template: | + HINTERGRUNDWISSEN (KONTEXT): + ========================================= + {context_str} + ========================================= + + FRAGE DES USERS: + {query} + + ANWEISUNG: + Analysiere die Quellen oben. Synthetisiere eine Antwort, die die Frage präzise beantwortet. + Nutze Markdown für Struktur (Fettgedrucktes für Wichtiges). \ No newline at end of file