This commit is contained in:
Lars 2025-12-08 14:27:17 +01:00
parent f9af30b195
commit 21904e62ee
3 changed files with 59 additions and 52 deletions

View File

@ -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: Zweck:
Verbindet Retrieval mit LLM-Generation. Verbindet Retrieval mit LLM-Generation.
Enriched Context: Fügt Typen und Metadaten in den Prompt ein, Enriched Context: Fügt Typen und Metadaten in den Prompt ein,
damit das LLM komplexe Zusammenhänge versteht. damit das LLM komplexe Zusammenhänge (z.B. Decisions) versteht.
Version:
0.3.0 (Audit Finalization)
""" """
from fastapi import APIRouter, HTTPException, Depends 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): for i, hit in enumerate(hits, 1):
source = hit.source or {} source = hit.source or {}
# 1. Content extrahieren (Robust) # 1. Content extrahieren (Robust: prüft alle üblichen Felder)
content = ( content = (
source.get("text") or source.get("text") or
source.get("content") or source.get("content") or
@ -51,24 +48,14 @@ def _build_enriched_context(hits: List[QueryHit]) -> str:
# 2. Metadaten für "Context Intelligence" # 2. Metadaten für "Context Intelligence"
title = hit.note_id or "Unbekannte Notiz" title = hit.note_id or "Unbekannte Notiz"
# Typ in Großbuchstaben (z.B. "DECISION"), damit das LLM es als Signal erkennt
# 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.
note_type = source.get("type", "unknown").upper() 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 # 3. Formatierung als strukturiertes Dokument für das LLM
# Wir nutzen ein Format, das wie ein strukturiertes Dokument aussieht.
# Das hilft dem Modell, Grenzen zwischen Quellen zu erkennen.
entry = ( entry = (
f"### SOURCE [{i}]: {title}\n" f"### QUELLE {i}: {title}\n"
f"METADATA: [TYPE: {note_type}] [SCORE: {hit.total_score:.2f}] [TAGS: {tags_str}]\n" f"TYP: [{note_type}] (Score: {hit.total_score:.2f})\n"
f"CONTENT:\n{content}\n" f"INHALT:\n{content}\n"
) )
context_parts.append(entry) context_parts.append(entry)
@ -83,25 +70,21 @@ async def chat_endpoint(
start_time = time.time() start_time = time.time()
query_id = str(uuid.uuid4()) query_id = str(uuid.uuid4())
# Logging verkürzt für Übersichtlichkeit
logger.info(f"Chat request [{query_id}]: {request.message[:50]}...") logger.info(f"Chat request [{query_id}]: {request.message[:50]}...")
try: try:
# 1. Retrieval (Graph-Awareness) # 1. Retrieval (Hybrid erzwingen für Graph-Nutzung)
# Wir erzwingen 'hybrid', damit graph-basierte Nachbarn gefunden werden.
query_req = QueryRequest( query_req = QueryRequest(
query=request.message, query=request.message,
mode="hybrid", # <--- Audit Check: Hybrid Mode active mode="hybrid", # WICHTIG: Hybrid Mode für Graph-Nachbarn
top_k=request.top_k, top_k=request.top_k,
explain=request.explain, explain=request.explain
# Wir fordern Explizit Metadaten an, falls der Retriever das unterstützt
# (passiert implizit durch Payload-Return in WP-04)
) )
retrieve_result = await retriever.search(query_req) retrieve_result = await retriever.search(query_req)
hits = retrieve_result.results hits = retrieve_result.results
# 2. Context Assembly # 2. Context Building (Enriched)
if not hits: if not hits:
logger.info(f"[{query_id}] No hits found.") logger.info(f"[{query_id}] No hits found.")
context_str = "Keine relevanten Notizen gefunden." context_str = "Keine relevanten Notizen gefunden."

View File

@ -1,32 +1,24 @@
# config/prompts.yaml — Persönlichkeit & RAG-Strategie
# Version: 2.0 (Audit Update)
system_prompt: | system_prompt: |
Du bist 'mindnet', ein persönliches KI-Gedächtnis und der Digitale Zwilling deines Erschaffers ("User"). Du bist 'mindnet', ein persönliches KI-Gedächtnis.
DEINE PERSÖNLICHKEIT & WERTE: DEINE REGELN:
1. Pragmatismus: Du bevorzugst funktionierende Lösungen über theoretische Perfektion. 1. Antworte NUR basierend auf dem untenstehenden KONTEXT.
2. Transparenz: Du erfindest keine Fakten. Wenn Informationen im Kontext fehlen, sagst du das klar. 2. Achte auf den TYP der Quelle:
3. Vernetztes Denken: Du suchst aktiv nach Verbindungen zwischen den bereitgestellten Notizen. - [DECISION] enthält Begründungen (Warum?).
4. Erklärbarkeit: Wenn du eine Aussage machst, beziehst du dich implizit auf die Quelle (z.B. "Wie in Projekt X definiert..."). - [PROJECT] enthält Ziele (Was?).
- [CONCEPT] enthält Definitionen.
DEINE AUFGABE: 3. Sei präzise. Nenne konkrete technische Gründe, wenn sie im Text stehen.
Beantworte die Frage des Users ausschließlich basierend auf dem untenstehenden KONTEXT. 4. Halluziniere nicht.
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: | rag_template: |
HINTERGRUNDWISSEN (KONTEXT): KONTEXT (WISSEN):
========================================= =========================================
{context_str} {context_str}
========================================= =========================================
FRAGE DES USERS: FRAGE:
{query} {query}
ANWEISUNG: ANWEISUNG:
Analysiere die Quellen oben. Synthetisiere eine Antwort, die die Frage präzise beantwortet. Analysiere den Kontext. Wenn eine [DECISION] Quelle dabei ist, nutze deren Inhalt für die Begründung.
Nutze Markdown für Struktur (Fettgedrucktes für Wichtiges). Antworte kurz und präzise auf Deutsch.

32
config/prompts.yaml_old Normal file
View File

@ -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).