WP07 #7
|
|
@ -1,5 +1,5 @@
|
|||
# mindnet v2.2 — Programmplan
|
||||
**Version:** 2.3.2 (Inkl. WP-10a GUI Evolution)
|
||||
**Version:** 2.4.0 (Inkl. WP-07 Interview & WP-10a Draft Editor)
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** Aktiv
|
||||
|
||||
|
|
@ -24,11 +24,11 @@
|
|||
- [WP-05 – Persönlichkeitsmodell \& RAG-Chat (abgeschlossen)](#wp-05--persönlichkeitsmodell--rag-chat-abgeschlossen)
|
||||
- [WP-05b – Advanced Chat (Optional)](#wp-05b--advanced-chat-optional)
|
||||
- [WP-06 – Decision Engine \& Hybrid Router (abgeschlossen)](#wp-06--decision-engine--hybrid-router-abgeschlossen)
|
||||
- [WP-07 – Interview-Assistent (geplant)](#wp-07--interview-assistent-geplant)
|
||||
- [WP-07 – Interview-Assistent (abgeschlossen)](#wp-07--interview-assistent-abgeschlossen)
|
||||
- [WP-08 – Self-Tuning v1/v2 (geplant)](#wp-08--self-tuning-v1v2-geplant)
|
||||
- [WP-09 – Vault-Onboarding \& Migration (geplant)](#wp-09--vault-onboarding--migration-geplant)
|
||||
- [WP-10 – Chat-Interface \& Writeback (abgeschlossen)](#wp-10--chat-interface--writeback-abgeschlossen)
|
||||
- [WP-10a – GUI Evolution: Interaktion \& Tools (geplant)](#wp-10a--gui-evolution-interaktion--tools-geplant)
|
||||
- [WP-10a – GUI Evolution: Draft Editor (abgeschlossen)](#wp-10a--gui-evolution-draft-editor-abgeschlossen)
|
||||
- [WP-11 – Knowledge-Builder \& Vernetzungs-Assistent (geplant)](#wp-11--knowledge-builder--vernetzungs-assistent-geplant)
|
||||
- [WP-12 – Knowledge Rewriter (Soft Mode, geplant)](#wp-12--knowledge-rewriter-soft-mode-geplant)
|
||||
- [WP-13 – MCP-Integration \& Agenten-Layer (geplant)](#wp-13--mcp-integration--agenten-layer-geplant)
|
||||
|
|
@ -39,13 +39,11 @@
|
|||
- [10. Governance \& Versionierung](#10-governance--versionierung)
|
||||
- [11. Executive Summary](#11-executive-summary)
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 1. Programmauftrag
|
||||
|
||||
mindnet v2.2 entwickelt ein persönliches, wachsendes KI-Gedächtnis, das:
|
||||
mindnet v2.4 entwickelt ein persönliches, wachsendes KI-Gedächtnis, das:
|
||||
|
||||
- Wissen, Erfahrungen, Werte und Entscheidungen speichert,
|
||||
- diese Informationen semantisch verknüpft und rekonstruierbar macht,
|
||||
|
|
@ -53,7 +51,7 @@ mindnet v2.2 entwickelt ein persönliches, wachsendes KI-Gedächtnis, das:
|
|||
- über mehrere Kanäle gefüttert wird:
|
||||
- Obsidian-Markdown (primäre Quelle),
|
||||
- Chat-basierter Agent (Decision Engine & RAG-Chat aktiv),
|
||||
- später: Interview-Assistent (strukturierte Dialogerfassung),
|
||||
- **Interview-Assistent (One-Shot Extraction aktiv)**,
|
||||
- automatisch neue Zusammenhänge erkennt und vernetzt (Edges, Typen, Hinweise),
|
||||
- sich durch Rückmeldungen (Feedback) selbst verbessert (Self-Tuning).
|
||||
|
||||
|
|
@ -88,7 +86,7 @@ Kernprinzipien der Vision:
|
|||
Das System arbeitet von Anfang an mit unvollständigen Daten, kann aber schrittweise dichter werden, ohne dass alte Notizen massenhaft manuell angepasst werden müssen.
|
||||
|
||||
- **Flexibilität (Late Binding):**
|
||||
Semantik wird überwiegend in Konfiguration (z. B. `types.yaml`, `prompts.yaml`, `decision_engine.yaml`, Policies) festgelegt. Die Persönlichkeit entsteht durch das Config-Design, nicht durch Hardcoding.
|
||||
Semantik wird überwiegend in Konfiguration (z. B. `types.yaml`, `prompts.yaml`, `decision_engine.yaml`) festgelegt. Die Persönlichkeit entsteht durch das Config-Design, nicht durch Hardcoding.
|
||||
|
||||
- **Autonomie & Self-Healing:**
|
||||
mindnet schlägt fehlende Typen, Relationen und Edges vor (z. B. aus Inline-Relationen, Edge-Defaults, Ähnlichkeitsbeziehungen) und baut damit einen „self-healing graph“ auf.
|
||||
|
|
@ -117,6 +115,7 @@ Kernprinzipien der Vision:
|
|||
- **Decision Engine:** System erkennt Intent (Fakt vs. Entscheidung) und wägt Werte ab (WP-06 abgeschlossen).
|
||||
- **Multi-Persona:** System wechselt den Tonfall (Empathisch vs. Analytisch) situativ (WP-06 abgeschlossen).
|
||||
- **Chat Interface:** Web-basiertes Frontend (Streamlit) für einfache Interaktion und Feedback-Gabe (WP-10 abgeschlossen).
|
||||
- **Interview-Assistent (WP-07):** One-Shot Extraction von Notizen ("Neues Projekt anlegen") ist live.
|
||||
- Technische Basis: FastAPI, Qdrant, Ollama (Local LLM), Streamlit.
|
||||
- Automatisierte Erkennung von Beziehungen:
|
||||
- Wikilinks, Inline-Relationen, Callout-Edges, Typ-Defaults.
|
||||
|
|
@ -126,10 +125,9 @@ Kernprinzipien der Vision:
|
|||
|
||||
### 3.2 Mittelfristig (Nächste Schritte)
|
||||
|
||||
- **Interview-Assistent (WP-07):** Geführte Dialoge zur Erfassung neuer Notizen (Startbereit).
|
||||
- mindnet erzeugt Vorschläge für neue Notes & Edges und bietet einen „Vernetzungs-Assistenten“ für manuell angelegte Notizen.
|
||||
- **Self-Tuning (WP-08):** Optimierung der Gewichte in `retriever.yaml` basierend auf dem gesammelten Feedback.
|
||||
- **Knowledge-Builder (WP-11):** Assistent zur Analyse und Vernetzung manuell erstellter Notizen.
|
||||
- Agenten können über MCP-Tools (`mindnet_query`, `mindnet_chat`) auf mindnet zugreifen.
|
||||
- Self-Tuning optimiert die Gewichte in `retriever.yaml` basierend auf dem gesammelten Feedback (WP-08).
|
||||
|
||||
### 3.3 Langfristig
|
||||
|
||||
|
|
@ -191,10 +189,10 @@ Die folgenden Prinzipien steuern alle Workpackages und Entscheidungen:
|
|||
Phase A – Fundament & Import (Fertig)
|
||||
Phase B – Semantik, Graph & Lernen (Fertig)
|
||||
Phase C – Persönlichkeitsmodell & KI-Zwilling (Fertig)
|
||||
Phase D – Agenten, MCP & Interaktion (Laufend)
|
||||
Phase D – Agenten, MCP & Interaktion (Aktiv)
|
||||
Phase E – Review, Refactoring, Dokumentation
|
||||
|
||||
Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-06 und WP-10 sind bereits erfolgreich abgeschlossen.
|
||||
Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-07 und WP-10/10a sind erfolgreich abgeschlossen.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -354,17 +352,18 @@ Transformation vom reinen Wissens-Abrufer zum strategischen Entscheidungspartner
|
|||
|
||||
---
|
||||
|
||||
### WP-07 – Interview-Assistent (geplant)
|
||||
### WP-07 – Interview-Assistent (abgeschlossen)
|
||||
|
||||
**Phase:** C/D
|
||||
**Status:** 🟡 geplant (Nächster Fokus)
|
||||
**Status:** 🟢 abgeschlossen
|
||||
|
||||
**Ziel:**
|
||||
Dialogbasierter Erfassungs-Assistent, der strukturierte Interviews führt und daraus konsistente Markdown-Notizen generiert.
|
||||
|
||||
**Umfang:**
|
||||
- Design von Interview-Flows (via Router-Strategie `INTERVIEW`).
|
||||
- Konvertierung von Dialogtranskripten in typisierte Notes (Draft-Erstellung).
|
||||
**Erreichte Ergebnisse:**
|
||||
- **One-Shot Extractor:** Extrahiert Notiz-Inhalte aus einem Prompt.
|
||||
- **Schema Injection:** Typspezifische Pflichtfelder (Late Binding).
|
||||
- **Draft Generator:** Liefert validen Markdown-Codeblock mit `status: draft`.
|
||||
|
||||
**Aufwand / Komplexität:**
|
||||
- Aufwand: Niedrig/Mittel
|
||||
|
|
@ -375,7 +374,7 @@ Dialogbasierter Erfassungs-Assistent, der strukturierte Interviews führt und da
|
|||
### WP-08 – Self-Tuning v1/v2 (geplant)
|
||||
|
||||
**Phase:** B/C
|
||||
**Status:** 🟡 geplant
|
||||
**Status:** 🟡 geplant (Nächster Fokus)
|
||||
|
||||
**Ziel:**
|
||||
Aufbau eines Self-Tuning-Mechanismus, der auf Basis von Feedback-Daten (WP-04c) Vorschläge für Retriever- und Policy-Anpassungen macht.
|
||||
|
|
@ -429,18 +428,18 @@ Ablösung der Terminal-Interaktion durch ein grafisches Interface.
|
|||
|
||||
---
|
||||
|
||||
### WP-10a – GUI Evolution: Interaktion & Tools (geplant)
|
||||
### WP-10a – GUI Evolution: Draft Editor (abgeschlossen)
|
||||
|
||||
**Phase:** D
|
||||
**Status:** 🟡 geplant (nach WP07/11)
|
||||
**Status:** 🟢 abgeschlossen
|
||||
|
||||
**Ziel:**
|
||||
Anpassung der GUI an komplexe Interaktionsmuster, die durch den Interview-Assistenten und Knowledge-Builder entstehen.
|
||||
|
||||
**Umfang:**
|
||||
- **Draft-Editor:** Interaktive Bearbeitung und Bestätigung der Markdown-Entwürfe aus WP-07.
|
||||
- **Suggestion-UI:** Checkboxen/Toggles für Kanten-Vorschläge aus WP-11 (Human-in-the-Loop).
|
||||
- **Writeback:** Physisches Speichern der bestätigten Inhalte im Vault.
|
||||
**Erreichte Ergebnisse:**
|
||||
- **Draft Editor:** Interaktive `st.text_area` für generierte Entwürfe.
|
||||
- **Sanitizer:** `normalize_meta_and_body` zur Korrektur von LLM-Fehlern.
|
||||
- **Download/Copy:** Export-Funktionen für Markdown.
|
||||
|
||||
**Aufwand / Komplexität:**
|
||||
- Aufwand: Mittel
|
||||
|
|
@ -512,7 +511,7 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
|
|||
WP01 → WP02 → WP03 → WP04a
|
||||
WP04a → WP04b → WP04c → WP08
|
||||
WP03 → WP05 → WP06 → WP07
|
||||
WP07/WP11 → WP10a
|
||||
WP07 → WP10a
|
||||
WP03 → WP09
|
||||
WP01/WP03 → WP10 → WP11 → WP12
|
||||
WP03/WP04 → WP13
|
||||
|
|
@ -553,11 +552,11 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
|
|||
| WP05 | 🟢 |
|
||||
| WP05b | ⚪ |
|
||||
| WP06 | 🟢 |
|
||||
| WP07 | 🟡 |
|
||||
| WP07 | 🟢 |
|
||||
| WP08 | 🟡 |
|
||||
| WP09 | 🟡 |
|
||||
| WP10 | 🟢 |
|
||||
| WP10a | 🟡 |
|
||||
| WP10a | 🟢 |
|
||||
| WP11 | 🟡 |
|
||||
| WP12 | 🟡 |
|
||||
| WP13 | 🟡 |
|
||||
|
|
@ -578,15 +577,15 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
|
|||
|
||||
## 11. Executive Summary
|
||||
|
||||
mindnet v2.2 ist so aufgesetzt, dass:
|
||||
mindnet v2.4 ist so aufgesetzt, dass:
|
||||
|
||||
- du **schrittweise** Wissen erfassen kannst (Obsidian + Chat + später Interview-Assistent),
|
||||
- du **schrittweise** Wissen erfassen kannst (Obsidian + Chat + Interview-Drafts),
|
||||
- die Struktur **mitwächst**, ohne Retro-Massenarbeit im Vault,
|
||||
- ein **hybrider Retriever** qualitativ hochwertige, erklärbare Antworten liefert,
|
||||
- ein **Self-Healing- und Self-Tuning-Mechanismus** vorbereitet ist (durch WP-04c Feedback-Daten),
|
||||
- ein **Persönlichkeitsmodell** (Decision Engine, Empathie) existiert und den Tonfall situativ anpasst,
|
||||
- eine **grafische Oberfläche** (WP-10) existiert, die komplexe Zusammenhänge (Intents, Quellen) visualisiert,
|
||||
- eine **grafische Oberfläche** (WP-10/10a) existiert, die komplexe Zusammenhänge visualisiert und Co-Creation ermöglicht,
|
||||
- langfristig ein **KI-Zwilling** aufgebaut wird, der deine Werte, Erfahrungen und Denkweise spiegelt,
|
||||
- die technische Architektur (FastAPI, Qdrant, YAML-Policies, MCP-Integration) lokal, nachvollziehbar und erweiterbar bleibt.
|
||||
|
||||
Dieser Programmplan bildet die konsolidierte Grundlage (v2.3.1) für alle weiteren Arbeiten.
|
||||
Dieser Programmplan bildet die konsolidierte Grundlage (v2.4.0) für alle weiteren Arbeiten.
|
||||
|
|
@ -3,6 +3,9 @@ import requests
|
|||
import uuid
|
||||
import os
|
||||
import json
|
||||
import re
|
||||
import yaml
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from dotenv import load_dotenv
|
||||
|
||||
|
|
@ -18,15 +21,13 @@ timeout_setting = os.getenv("MINDNET_API_TIMEOUT") or os.getenv("MINDNET_LLM_TIM
|
|||
API_TIMEOUT = float(timeout_setting) if timeout_setting else 300.0
|
||||
|
||||
# --- PAGE SETUP ---
|
||||
st.set_page_config(page_title="mindnet v2.3.1", page_icon="🧠", layout="wide")
|
||||
st.set_page_config(page_title="mindnet v2.3.2", page_icon="🧠", layout="wide")
|
||||
|
||||
# --- CSS STYLING ---
|
||||
st.markdown("""
|
||||
<style>
|
||||
/* Hauptcontainer enger machen für Lesbarkeit */
|
||||
.block-container { padding-top: 2rem; max_width: 900px; margin: auto; }
|
||||
.block-container { padding-top: 2rem; max_width: 1000px; margin: auto; }
|
||||
|
||||
/* Intent Badges */
|
||||
.intent-badge {
|
||||
background-color: #e8f0fe; color: #1a73e8;
|
||||
padding: 4px 10px; border-radius: 12px;
|
||||
|
|
@ -34,24 +35,138 @@ st.markdown("""
|
|||
border: 1px solid #d2e3fc; display: inline-block; margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Chat Message Styling */
|
||||
.stChatMessage { padding: 1rem; border-radius: 8px; margin-bottom: 1rem;}
|
||||
div[data-testid="stChatMessageContent"] p { font-size: 1.05rem; line-height: 1.6; }
|
||||
.draft-box {
|
||||
border: 1px solid #d0d7de;
|
||||
border-radius: 6px;
|
||||
padding: 16px;
|
||||
background-color: #f6f8fa;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* Expander Cleaner */
|
||||
.streamlit-expanderHeader { font-size: 0.9rem; font-weight: 600; color: #444; }
|
||||
.preview-box {
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 6px;
|
||||
padding: 24px;
|
||||
background-color: white;
|
||||
font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif;
|
||||
}
|
||||
|
||||
.debug-info {
|
||||
font-size: 0.7rem;
|
||||
color: #888;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
""", unsafe_allow_html=True)
|
||||
|
||||
# --- SESSION STATE ---
|
||||
if "messages" not in st.session_state: st.session_state.messages = []
|
||||
if "user_id" not in st.session_state: st.session_state.user_id = str(uuid.uuid4())
|
||||
if "draft_note" not in st.session_state: st.session_state.draft_note = {"title": "", "content": "", "type": "concept"}
|
||||
|
||||
# --- HELPER FUNCTIONS ---
|
||||
|
||||
def normalize_meta_and_body(meta, body):
|
||||
"""
|
||||
Sanitizer: Stellt sicher, dass nur erlaubte Felder im Frontmatter bleiben.
|
||||
Alles andere wird in den Body verschoben (Repair-Strategie).
|
||||
"""
|
||||
ALLOWED_KEYS = {"title", "type", "status", "tags", "id", "created", "updated", "aliases", "lang"}
|
||||
|
||||
clean_meta = {}
|
||||
extra_content = []
|
||||
|
||||
# 1. Title/Titel Normalisierung
|
||||
if "titel" in meta and "title" not in meta:
|
||||
meta["title"] = meta.pop("titel")
|
||||
|
||||
# 2. Tags Normalisierung (Synonyme)
|
||||
tag_candidates = ["tags", "emotionale_keywords", "keywords", "schluesselwoerter"]
|
||||
all_tags = []
|
||||
for key in tag_candidates:
|
||||
if key in meta:
|
||||
val = meta[key]
|
||||
if isinstance(val, list): all_tags.extend(val)
|
||||
elif isinstance(val, str): all_tags.extend([t.strip() for t in val.split(",")])
|
||||
|
||||
# 3. Filterung und Verschiebung
|
||||
for key, val in meta.items():
|
||||
if key in ALLOWED_KEYS:
|
||||
clean_meta[key] = val
|
||||
elif key in tag_candidates:
|
||||
pass # Schon oben behandelt
|
||||
else:
|
||||
# Unerlaubtes Feld (z.B. 'situation') -> Ab in den Body!
|
||||
if val and isinstance(val, str):
|
||||
header = key.replace("_", " ").title()
|
||||
extra_content.append(f"## {header}\n{val}\n")
|
||||
|
||||
if all_tags:
|
||||
clean_meta["tags"] = list(set(all_tags))
|
||||
|
||||
# 4. Body Zusammenbau
|
||||
if extra_content:
|
||||
new_section = "\n".join(extra_content)
|
||||
final_body = f"{new_section}\n{body}"
|
||||
else:
|
||||
final_body = body
|
||||
|
||||
return clean_meta, final_body
|
||||
|
||||
def parse_markdown_draft(full_text):
|
||||
"""
|
||||
Robustes Parsing + Sanitization.
|
||||
"""
|
||||
clean_text = full_text
|
||||
|
||||
# Codeblock entfernen
|
||||
pattern_block = r"```(?:markdown|md)?\s*(.*?)\s*```"
|
||||
match_block = re.search(pattern_block, full_text, re.DOTALL | re.IGNORECASE)
|
||||
if match_block:
|
||||
clean_text = match_block.group(1).strip()
|
||||
|
||||
# Frontmatter splitten
|
||||
parts = re.split(r"^---+\s*$", clean_text, maxsplit=2, flags=re.MULTILINE)
|
||||
|
||||
meta = {}
|
||||
body = clean_text
|
||||
|
||||
if len(parts) >= 3:
|
||||
yaml_str = parts[1]
|
||||
body_candidate = parts[2]
|
||||
try:
|
||||
parsed = yaml.safe_load(yaml_str)
|
||||
if isinstance(parsed, dict):
|
||||
meta = parsed
|
||||
body = body_candidate.strip()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return normalize_meta_and_body(meta, body)
|
||||
|
||||
def build_markdown_doc(meta, body):
|
||||
"""Baut das finale Dokument zusammen."""
|
||||
if "id" not in meta or meta["id"] == "generated_on_save":
|
||||
safe_title = re.sub(r'[^a-zA-Z0-9]', '-', meta.get('title', 'note')).lower()[:30]
|
||||
meta["id"] = f"{datetime.now().strftime('%Y%m%d')}-{safe_title}-{uuid.uuid4().hex[:4]}"
|
||||
|
||||
meta["updated"] = datetime.now().strftime("%Y-%m-%d")
|
||||
|
||||
# Sortierung für UX
|
||||
ordered_meta = {}
|
||||
prio_keys = ["id", "type", "title", "status", "tags"]
|
||||
for k in prio_keys:
|
||||
if k in meta: ordered_meta[k] = meta.pop(k)
|
||||
ordered_meta.update(meta)
|
||||
|
||||
try:
|
||||
yaml_str = yaml.dump(ordered_meta, default_flow_style=None, sort_keys=False, allow_unicode=True).strip()
|
||||
except:
|
||||
yaml_str = "error: generating_yaml"
|
||||
|
||||
return f"---\n{yaml_str}\n---\n\n{body}"
|
||||
|
||||
def load_history_from_logs(limit=10):
|
||||
"""Liest die letzten N Queries aus dem Logfile."""
|
||||
queries = []
|
||||
if HISTORY_FILE.exists():
|
||||
try:
|
||||
|
|
@ -65,8 +180,7 @@ def load_history_from_logs(limit=10):
|
|||
queries.append(q)
|
||||
if len(queries) >= limit: break
|
||||
except: continue
|
||||
except Exception as e:
|
||||
st.sidebar.warning(f"Log-Fehler: {e}")
|
||||
except: pass
|
||||
return queries
|
||||
|
||||
def send_chat_message(message: str, top_k: int, explain: bool):
|
||||
|
|
@ -84,8 +198,7 @@ def send_chat_message(message: str, top_k: int, explain: bool):
|
|||
def submit_feedback(query_id, node_id, score, comment=None):
|
||||
try:
|
||||
requests.post(FEEDBACK_ENDPOINT, json={"query_id": query_id, "node_id": node_id, "score": score, "comment": comment}, timeout=2)
|
||||
target = "Antwort" if node_id == "generated_answer" else "Quelle"
|
||||
st.toast(f"Feedback für {target} gespeichert! (Score: {score})")
|
||||
st.toast(f"Feedback ({score}) gesendet!")
|
||||
except: pass
|
||||
|
||||
# --- UI COMPONENTS ---
|
||||
|
|
@ -93,115 +206,170 @@ def submit_feedback(query_id, node_id, score, comment=None):
|
|||
def render_sidebar():
|
||||
with st.sidebar:
|
||||
st.title("🧠 mindnet")
|
||||
st.caption("v2.3.1 | WP-10 UI")
|
||||
|
||||
mode = st.radio("Modus", ["💬 Chat", "📝 Neuer Eintrag (WP-07)"], index=0)
|
||||
|
||||
st.caption("v2.3.2 | WP-10 UI")
|
||||
mode = st.radio("Modus", ["💬 Chat", "📝 Manueller Editor"], index=0)
|
||||
st.divider()
|
||||
st.subheader("⚙️ Settings")
|
||||
top_k = st.slider("Quellen (Top-K)", 1, 10, 5)
|
||||
explain = st.toggle("Explanation Layer", True)
|
||||
|
||||
st.divider()
|
||||
st.subheader("🕒 Verlauf")
|
||||
history = load_history_from_logs(8)
|
||||
if not history:
|
||||
st.caption("Noch keine Einträge.")
|
||||
for q in history:
|
||||
if st.button(f"🔎 {q[:30]}...", key=f"hist_{q}", help=q, use_container_width=True):
|
||||
for q in load_history_from_logs(8):
|
||||
if st.button(f"🔎 {q[:25]}...", key=f"hist_{q}", use_container_width=True):
|
||||
st.session_state.messages.append({"role": "user", "content": q})
|
||||
st.rerun()
|
||||
|
||||
return mode, top_k, explain
|
||||
|
||||
def render_draft_editor(msg):
|
||||
qid = msg.get('query_id', str(uuid.uuid4()))
|
||||
key_base = f"draft_{qid}"
|
||||
|
||||
# 1. Init
|
||||
if f"{key_base}_init" not in st.session_state:
|
||||
meta, body = parse_markdown_draft(msg["content"])
|
||||
|
||||
st.session_state[f"{key_base}_type"] = meta.get("type", "default")
|
||||
st.session_state[f"{key_base}_title"] = meta.get("title", "")
|
||||
|
||||
tags_raw = meta.get("tags", [])
|
||||
st.session_state[f"{key_base}_tags"] = ", ".join(tags_raw) if isinstance(tags_raw, list) else str(tags_raw)
|
||||
|
||||
st.session_state[f"{key_base}_body"] = body.strip()
|
||||
st.session_state[f"{key_base}_meta"] = meta
|
||||
st.session_state[f"{key_base}_init"] = True
|
||||
|
||||
# 2. UI
|
||||
st.markdown(f'<div class="draft-box">', unsafe_allow_html=True)
|
||||
st.markdown("### 📝 Entwurf bearbeiten")
|
||||
|
||||
# Metadata
|
||||
c1, c2 = st.columns([2, 1])
|
||||
with c1:
|
||||
new_title = st.text_input("Titel", value=st.session_state.get(f"{key_base}_title", ""), key=f"{key_base}_inp_title")
|
||||
with c2:
|
||||
known_types = ["concept", "project", "decision", "experience", "journal", "person", "value", "goal", "principle", "default"]
|
||||
curr_type = st.session_state.get(f"{key_base}_type", "default")
|
||||
if curr_type not in known_types: known_types.append(curr_type)
|
||||
new_type = st.selectbox("Typ", known_types, index=known_types.index(curr_type), key=f"{key_base}_sel_type")
|
||||
|
||||
new_tags = st.text_input("Tags (kommagetrennt)", value=st.session_state.get(f"{key_base}_tags", ""), key=f"{key_base}_inp_tags")
|
||||
|
||||
# Tabs
|
||||
tab_edit, tab_view = st.tabs(["✏️ Inhalt", "👁️ Vorschau"])
|
||||
|
||||
with tab_edit:
|
||||
st.caption("Bearbeite hier den Inhalt. Metadaten (oben) werden automatisch hinzugefügt.")
|
||||
new_body = st.text_area(
|
||||
"Body",
|
||||
value=st.session_state.get(f"{key_base}_body", ""),
|
||||
height=500,
|
||||
key=f"{key_base}_txt_body",
|
||||
label_visibility="collapsed"
|
||||
)
|
||||
|
||||
# Reassembly
|
||||
final_tags_list = [t.strip() for t in new_tags.split(",") if t.strip()]
|
||||
final_meta = st.session_state.get(f"{key_base}_meta", {}).copy()
|
||||
final_meta.update({
|
||||
"id": "generated_on_save",
|
||||
"type": new_type,
|
||||
"title": new_title,
|
||||
"status": "draft",
|
||||
"tags": final_tags_list
|
||||
})
|
||||
|
||||
final_doc = build_markdown_doc(final_meta, new_body)
|
||||
|
||||
with tab_view:
|
||||
st.markdown('<div class="preview-box">', unsafe_allow_html=True)
|
||||
st.markdown(final_doc)
|
||||
st.markdown('</div>', unsafe_allow_html=True)
|
||||
|
||||
st.markdown("---")
|
||||
|
||||
# Actions
|
||||
b1, b2 = st.columns([1, 1])
|
||||
with b1:
|
||||
fname = f"{datetime.now().strftime('%Y%m%d')}-{new_type}.md"
|
||||
st.download_button("💾 Download .md", data=final_doc, file_name=fname, mime="text/markdown")
|
||||
with b2:
|
||||
if st.button("📋 Code anzeigen", key=f"{key_base}_btn_copy"):
|
||||
st.code(final_doc, language="markdown")
|
||||
|
||||
st.markdown("</div>", unsafe_allow_html=True)
|
||||
|
||||
|
||||
def render_chat_interface(top_k, explain):
|
||||
# Render History
|
||||
for msg in st.session_state.messages:
|
||||
for idx, msg in enumerate(st.session_state.messages):
|
||||
with st.chat_message(msg["role"]):
|
||||
if msg["role"] == "assistant":
|
||||
# Intent Badge MIT SOURCE (Fix für Debugging)
|
||||
if "intent" in msg:
|
||||
icon = {"EMPATHY": "❤️", "DECISION": "⚖️", "CODING": "💻", "FACT": "📚"}.get(msg["intent"], "🧠")
|
||||
source_info = msg.get("intent_source", "Unknown")
|
||||
# Hier wird die Quelle wieder angezeigt:
|
||||
st.markdown(f'<div class="intent-badge">{icon} Intent: {msg["intent"]} <span style="opacity:0.6; font-size: 0.9em; margin-left:5px;">via {source_info}</span></div>', unsafe_allow_html=True)
|
||||
# Meta
|
||||
intent = msg.get("intent", "UNKNOWN")
|
||||
src = msg.get("intent_source", "?")
|
||||
icon = {"EMPATHY":"❤️", "DECISION":"⚖️", "CODING":"💻", "FACT":"📚", "INTERVIEW":"📝"}.get(intent, "🧠")
|
||||
st.markdown(f'<div class="intent-badge">{icon} Intent: {intent} <span style="opacity:0.6; font-size:0.8em">({src})</span></div>', unsafe_allow_html=True)
|
||||
|
||||
st.markdown(msg["content"])
|
||||
# Debugging (Always visible for safety)
|
||||
with st.expander("🐞 Debug Raw Payload", expanded=False):
|
||||
st.json(msg)
|
||||
|
||||
# Logic
|
||||
if intent == "INTERVIEW":
|
||||
render_draft_editor(msg)
|
||||
else:
|
||||
st.markdown(msg["content"])
|
||||
|
||||
# Sources
|
||||
if "sources" in msg:
|
||||
if "sources" in msg and msg["sources"]:
|
||||
for hit in msg["sources"]:
|
||||
score = hit.get('total_score', 0)
|
||||
icon = "🟢" if score > 0.8 else "🟡" if score > 0.5 else "⚪"
|
||||
with st.expander(f"{icon} {hit.get('note_id', '?')} ({score:.2f})"):
|
||||
with st.expander(f"📄 {hit.get('note_id', '?')} ({hit.get('total_score', 0):.2f})"):
|
||||
st.markdown(f"_{hit.get('source', {}).get('text', '')[:300]}..._")
|
||||
if hit.get('explanation'):
|
||||
st.caption(f"Grund: {hit['explanation']['reasons'][0]['message']}")
|
||||
|
||||
# Granular Feedback (Faces)
|
||||
def _cb(qid=msg["query_id"], nid=hit['node_id']):
|
||||
def _cb(qid=msg.get("query_id"), nid=hit.get('node_id')):
|
||||
val = st.session_state.get(f"fb_src_{qid}_{nid}")
|
||||
if val is not None: submit_feedback(qid, nid, val+1, "Faces UI")
|
||||
|
||||
st.feedback("faces", key=f"fb_src_{msg['query_id']}_{hit['node_id']}", on_change=_cb)
|
||||
|
||||
# Global Feedback (Stars)
|
||||
qid = msg["query_id"]
|
||||
st.feedback("stars", key=f"fb_glob_{qid}", on_change=lambda: submit_feedback(qid, "generated_answer", st.session_state[f"fb_glob_{qid}"]+1))
|
||||
if val is not None: submit_feedback(qid, nid, val+1)
|
||||
st.feedback("faces", key=f"fb_src_{msg.get('query_id')}_{hit.get('node_id')}", on_change=_cb)
|
||||
|
||||
if "query_id" in msg:
|
||||
qid = msg["query_id"]
|
||||
st.feedback("stars", key=f"fb_glob_{qid}", on_change=lambda: submit_feedback(qid, "generated_answer", st.session_state[f"fb_glob_{qid}"]+1))
|
||||
else:
|
||||
st.markdown(msg["content"])
|
||||
|
||||
# Input Logic
|
||||
last_msg_is_user = len(st.session_state.messages) > 0 and st.session_state.messages[-1]["role"] == "user"
|
||||
|
||||
if prompt := st.chat_input("Frage Mindnet..."):
|
||||
st.session_state.messages.append({"role": "user", "content": prompt})
|
||||
st.rerun()
|
||||
|
||||
if last_msg_is_user:
|
||||
last_prompt = st.session_state.messages[-1]["content"]
|
||||
if len(st.session_state.messages) > 0 and st.session_state.messages[-1]["role"] == "user":
|
||||
with st.chat_message("assistant"):
|
||||
with st.spinner("Thinking..."):
|
||||
resp = send_chat_message(last_prompt, top_k, explain)
|
||||
|
||||
resp = send_chat_message(st.session_state.messages[-1]["content"], top_k, explain)
|
||||
if "error" in resp:
|
||||
st.error(resp["error"])
|
||||
else:
|
||||
msg_data = {
|
||||
st.session_state.messages.append({
|
||||
"role": "assistant",
|
||||
"content": resp.get("answer"),
|
||||
"intent": resp.get("intent", "FACT"),
|
||||
"intent_source": resp.get("intent_source", "Unknown"), # Wichtig für Anzeige
|
||||
"intent_source": resp.get("intent_source", "Unknown"),
|
||||
"sources": resp.get("sources", []),
|
||||
"query_id": resp.get("query_id")
|
||||
}
|
||||
st.session_state.messages.append(msg_data)
|
||||
})
|
||||
st.rerun()
|
||||
|
||||
def render_creation_interface():
|
||||
st.header("📝 Neuer Wissens-Eintrag (WP-07/11)")
|
||||
st.info("Hier kannst du strukturierte Notizen erstellen, die direkt in den Obsidian Vault gespeichert werden.")
|
||||
def render_manual_editor():
|
||||
st.header("📝 Manueller Editor")
|
||||
c1, c2 = st.columns([1, 2])
|
||||
n_type = c1.selectbox("Typ", ["concept", "project", "decision", "experience", "value", "goal"])
|
||||
tags = c2.text_input("Tags")
|
||||
body = st.text_area("Inhalt", height=400, placeholder="# Titel\n\nText...")
|
||||
if st.button("Code anzeigen"):
|
||||
meta = {"type": n_type, "status": "draft", "tags": [t.strip() for t in tags.split(",")]}
|
||||
st.code(build_markdown_doc(meta, body), language="markdown")
|
||||
|
||||
with st.form("new_entry"):
|
||||
col1, col2 = st.columns([3, 1])
|
||||
title = col1.text_input("Titel der Notiz", placeholder="z.B. Projekt Gamma Meeting")
|
||||
n_type = col2.selectbox("Typ", ["concept", "meeting", "person", "project", "decision"])
|
||||
|
||||
content = st.text_area("Inhalt (Markdown)", height=300, placeholder="# Protokoll\n\n- Punkt 1...")
|
||||
|
||||
st.markdown("**Automatische Vernetzung:**")
|
||||
st.caption("Verwende `[[Link]]` für Referenzen und `[[rel:depends_on X]]` für logische Kanten.")
|
||||
|
||||
submitted = st.form_submit_button("💾 Speichern & Indizieren")
|
||||
if submitted:
|
||||
st.success(f"Mockup: Notiz '{title}' ({n_type}) wäre jetzt gespeichert worden!")
|
||||
st.balloons()
|
||||
|
||||
# --- MAIN LOOP ---
|
||||
mode, top_k, explain = render_sidebar()
|
||||
|
||||
if mode == "💬 Chat":
|
||||
render_chat_interface(top_k, explain)
|
||||
else:
|
||||
render_creation_interface()
|
||||
render_manual_editor()
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
"""
|
||||
app/routers/chat.py — RAG Endpunkt (WP-06 Hybrid Router + WP-04c Feedback)
|
||||
Version: 2.3.2 (Merged Stability Patch)
|
||||
app/routers/chat.py — RAG Endpunkt (WP-06 Hybrid Router + WP-07 Interview Mode)
|
||||
Version: 2.4.0 (Interview Support)
|
||||
|
||||
Features:
|
||||
- Hybrid Intent Router (Keyword + LLM)
|
||||
- Strategic Retrieval (Late Binding via Config)
|
||||
- Interview Loop (Schema-driven Data Collection)
|
||||
- Context Enrichment (Payload/Source Fallback)
|
||||
- Data Flywheel (Feedback Logging Integration)
|
||||
"""
|
||||
|
|
@ -21,7 +22,6 @@ from app.config import get_settings
|
|||
from app.models.dto import ChatRequest, ChatResponse, QueryRequest, QueryHit
|
||||
from app.services.llm_service import LLMService
|
||||
from app.core.retriever import Retriever
|
||||
# [MERGE] Integration Feedback Service (WP-04c)
|
||||
from app.services.feedback_service import log_search
|
||||
|
||||
router = APIRouter()
|
||||
|
|
@ -62,6 +62,47 @@ def get_decision_strategy(intent: str) -> Dict[str, Any]:
|
|||
strategies = config.get("strategies", {})
|
||||
return strategies.get(intent, strategies.get("FACT", {}))
|
||||
|
||||
# --- Helper: Target Type Detection (WP-07) ---
|
||||
|
||||
def _detect_target_type(message: str, configured_schemas: Dict[str, Any]) -> str:
|
||||
"""
|
||||
Versucht zu erraten, welchen Notiz-Typ der User erstellen will.
|
||||
Nutzt Keywords und Mappings.
|
||||
"""
|
||||
message_lower = message.lower()
|
||||
|
||||
# 1. Direkter Match mit Schema-Keys (z.B. "projekt", "entscheidung")
|
||||
# Ignoriere 'default' hier
|
||||
for type_key in configured_schemas.keys():
|
||||
if type_key == "default":
|
||||
continue
|
||||
if type_key in message_lower:
|
||||
return type_key
|
||||
|
||||
# 2. Synonym-Mapping (Deutsch -> Schema Key)
|
||||
# Dies verbessert die UX, falls User deutsche Begriffe nutzen
|
||||
synonyms = {
|
||||
"projekt": "project",
|
||||
"vorhaben": "project",
|
||||
"entscheidung": "decision",
|
||||
"beschluss": "decision",
|
||||
"ziel": "goal",
|
||||
"erfahrung": "experience",
|
||||
"lektion": "experience",
|
||||
"wert": "value",
|
||||
"prinzip": "principle",
|
||||
"grundsatz": "principle",
|
||||
"notiz": "default",
|
||||
"idee": "default"
|
||||
}
|
||||
|
||||
for term, schema_key in synonyms.items():
|
||||
if term in message_lower:
|
||||
# Prüfen, ob der gemappte Key auch konfiguriert ist
|
||||
if schema_key in configured_schemas:
|
||||
return schema_key
|
||||
|
||||
return "default"
|
||||
|
||||
# --- Dependencies ---
|
||||
|
||||
|
|
@ -167,67 +208,118 @@ async def chat_endpoint(
|
|||
|
||||
# Strategy Load
|
||||
strategy = get_decision_strategy(intent)
|
||||
inject_types = strategy.get("inject_types", [])
|
||||
prompt_key = strategy.get("prompt_template", "rag_template")
|
||||
prepend_instr = strategy.get("prepend_instruction", "")
|
||||
|
||||
# 2. Primary Retrieval
|
||||
query_req = QueryRequest(
|
||||
query=request.message,
|
||||
mode="hybrid",
|
||||
top_k=request.top_k,
|
||||
explain=request.explain
|
||||
)
|
||||
retrieve_result = await retriever.search(query_req)
|
||||
hits = retrieve_result.results
|
||||
# --- SPLIT LOGIC: INTERVIEW vs. RAG ---
|
||||
|
||||
# 3. Strategic Retrieval (WP-06 Kernfeature)
|
||||
if inject_types:
|
||||
logger.info(f"[{query_id}] Executing Strategic Retrieval for types: {inject_types}...")
|
||||
strategy_req = QueryRequest(
|
||||
sources_hits = []
|
||||
final_prompt = ""
|
||||
|
||||
if intent == "INTERVIEW":
|
||||
# --- WP-07: INTERVIEW MODE ---
|
||||
# Kein Retrieval. Wir nutzen den Dialog-Kontext.
|
||||
|
||||
# 1. Schema Loading (Late Binding)
|
||||
schemas = strategy.get("schemas", {})
|
||||
target_type = _detect_target_type(request.message, schemas)
|
||||
active_schema = schemas.get(target_type, schemas.get("default"))
|
||||
|
||||
logger.info(f"[{query_id}] Starting Interview for Type: {target_type}")
|
||||
|
||||
# Robustes Schema-Parsing (Dict vs List)
|
||||
if isinstance(active_schema, dict):
|
||||
fields_list = active_schema.get("fields", [])
|
||||
hint_str = active_schema.get("hint", "")
|
||||
else:
|
||||
fields_list = active_schema # Fallback falls nur Liste definiert
|
||||
hint_str = ""
|
||||
|
||||
fields_str = "\n- " + "\n- ".join(fields_list)
|
||||
|
||||
# 2. Context Logic
|
||||
# Hinweis: In einer Stateless-API ist {context_str} idealerweise die History.
|
||||
# Da ChatRequest (noch) kein History-Feld hat, nutzen wir einen Placeholder
|
||||
# oder verlassen uns darauf, dass der Client die History im Prompt mitschickt
|
||||
# (Streamlit Pattern: Appends history to prompt).
|
||||
# Wir labeln es hier explizit.
|
||||
context_str = "Bisheriger Verlauf (falls vorhanden): Siehe oben/unten."
|
||||
|
||||
# 3. Prompt Assembly
|
||||
template = llm.prompts.get(prompt_key, "")
|
||||
final_prompt = template.replace("{context_str}", context_str) \
|
||||
.replace("{query}", request.message) \
|
||||
.replace("{target_type}", target_type) \
|
||||
.replace("{schema_fields}", fields_str) \
|
||||
.replace("{schema_hint}", hint_str)
|
||||
|
||||
# Keine Hits im Interview
|
||||
sources_hits = []
|
||||
|
||||
else:
|
||||
# --- WP-06: STANDARD RAG MODE ---
|
||||
inject_types = strategy.get("inject_types", [])
|
||||
prepend_instr = strategy.get("prepend_instruction", "")
|
||||
|
||||
# 2. Primary Retrieval
|
||||
query_req = QueryRequest(
|
||||
query=request.message,
|
||||
mode="hybrid",
|
||||
top_k=3,
|
||||
filters={"type": inject_types},
|
||||
explain=False
|
||||
top_k=request.top_k,
|
||||
explain=request.explain
|
||||
)
|
||||
strategy_result = await retriever.search(strategy_req)
|
||||
retrieve_result = await retriever.search(query_req)
|
||||
hits = retrieve_result.results
|
||||
|
||||
existing_ids = {h.node_id for h in hits}
|
||||
for strat_hit in strategy_result.results:
|
||||
if strat_hit.node_id not in existing_ids:
|
||||
hits.append(strat_hit)
|
||||
# 3. Strategic Retrieval (WP-06 Kernfeature)
|
||||
if inject_types:
|
||||
logger.info(f"[{query_id}] Executing Strategic Retrieval for types: {inject_types}...")
|
||||
strategy_req = QueryRequest(
|
||||
query=request.message,
|
||||
mode="hybrid",
|
||||
top_k=3,
|
||||
filters={"type": inject_types},
|
||||
explain=False
|
||||
)
|
||||
strategy_result = await retriever.search(strategy_req)
|
||||
|
||||
# 4. Context Building
|
||||
if not hits:
|
||||
context_str = "Keine relevanten Notizen gefunden."
|
||||
else:
|
||||
context_str = _build_enriched_context(hits)
|
||||
existing_ids = {h.node_id for h in hits}
|
||||
for strat_hit in strategy_result.results:
|
||||
if strat_hit.node_id not in existing_ids:
|
||||
hits.append(strat_hit)
|
||||
|
||||
# 4. Context Building
|
||||
if not hits:
|
||||
context_str = "Keine relevanten Notizen gefunden."
|
||||
else:
|
||||
context_str = _build_enriched_context(hits)
|
||||
|
||||
# 5. Generation Setup
|
||||
template = llm.prompts.get(prompt_key, "{context_str}\n\n{query}")
|
||||
|
||||
if prepend_instr:
|
||||
context_str = f"{prepend_instr}\n\n{context_str}"
|
||||
|
||||
final_prompt = template.replace("{context_str}", context_str).replace("{query}", request.message)
|
||||
sources_hits = hits
|
||||
|
||||
# --- COMMON GENERATION ---
|
||||
|
||||
# 5. Generation
|
||||
template = llm.prompts.get(prompt_key, "{context_str}\n\n{query}")
|
||||
system_prompt = llm.prompts.get("system_prompt", "")
|
||||
|
||||
if prepend_instr:
|
||||
context_str = f"{prepend_instr}\n\n{context_str}"
|
||||
|
||||
final_prompt = template.replace("{context_str}", context_str).replace("{query}", request.message)
|
||||
|
||||
logger.info(f"[{query_id}] Sending to LLM (Intent: {intent}, Template: {prompt_key})...")
|
||||
|
||||
# System-Prompt separat übergeben (WP-06a Fix)
|
||||
# System-Prompt separat übergeben
|
||||
answer_text = await llm.generate_raw_response(prompt=final_prompt, system=system_prompt)
|
||||
|
||||
duration_ms = int((time.time() - start_time) * 1000)
|
||||
|
||||
# 6. Logging (Fire & Forget) - [MERGE POINT]
|
||||
# Wir loggen alles für das Data Flywheel (WP-08 Self-Tuning)
|
||||
# 6. Logging (Fire & Forget)
|
||||
try:
|
||||
log_search(
|
||||
query_id=query_id,
|
||||
query_text=request.message,
|
||||
results=hits,
|
||||
mode="chat_rag",
|
||||
results=sources_hits,
|
||||
mode="interview" if intent == "INTERVIEW" else "chat_rag",
|
||||
metadata={
|
||||
"intent": intent,
|
||||
"intent_source": intent_source,
|
||||
|
|
@ -242,7 +334,7 @@ async def chat_endpoint(
|
|||
return ChatResponse(
|
||||
query_id=query_id,
|
||||
answer=answer_text,
|
||||
sources=hits,
|
||||
sources=sources_hits,
|
||||
latency_ms=duration_ms,
|
||||
intent=intent,
|
||||
intent_source=intent_source
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
# config/decision_engine.yaml
|
||||
# Steuerung der Decision Engine (WP-06)
|
||||
# Steuerung der Decision Engine (WP-06 + WP-07)
|
||||
# Hybrid-Modus: Keywords (Fast) + LLM Router (Smart Fallback)
|
||||
version: 1.2
|
||||
version: 1.3
|
||||
|
||||
settings:
|
||||
llm_fallback_enabled: true
|
||||
|
||||
# Few-Shot Prompting für bessere SLM-Performance
|
||||
# Erweitert um INTERVIEW Beispiele
|
||||
llm_router_prompt: |
|
||||
Du bist ein Klassifikator. Analysiere die Nachricht und wähle die passende Strategie.
|
||||
Antworte NUR mit dem Namen der Strategie.
|
||||
|
||||
STRATEGIEN:
|
||||
- INTERVIEW: User will Wissen strukturieren, Notizen anlegen, Projekte starten ("Neu", "Festhalten").
|
||||
- DECISION: Rat, Strategie, Vor/Nachteile, "Soll ich".
|
||||
- EMPATHY: Gefühle, Frust, Freude, Probleme, "Alles ist sinnlos", "Ich bin traurig".
|
||||
- CODING: Code, Syntax, Programmierung, Python.
|
||||
|
|
@ -20,6 +22,8 @@ settings:
|
|||
BEISPIELE:
|
||||
User: "Wie funktioniert Qdrant?" -> FACT
|
||||
User: "Soll ich Qdrant nutzen?" -> DECISION
|
||||
User: "Ich möchte ein neues Projekt anlegen" -> INTERVIEW
|
||||
User: "Lass uns eine Entscheidung festhalten" -> INTERVIEW
|
||||
User: "Schreibe ein Python Script" -> CODING
|
||||
User: "Alles ist grau und sinnlos" -> EMPATHY
|
||||
User: "Mir geht es heute gut" -> EMPATHY
|
||||
|
|
@ -87,3 +91,53 @@ strategies:
|
|||
inject_types: ["snippet", "reference", "source"]
|
||||
prompt_template: "technical_template"
|
||||
prepend_instruction: null
|
||||
|
||||
# 5. Interview / Datenerfassung (WP-07)
|
||||
INTERVIEW:
|
||||
description: "Der User möchte strukturiertes Wissen erfassen (Projekt, Notiz, Idee)."
|
||||
trigger_keywords:
|
||||
- "neue notiz"
|
||||
- "neues projekt"
|
||||
- "neue entscheidung"
|
||||
- "neues ziel"
|
||||
- "festhalten"
|
||||
- "entwurf erstellen"
|
||||
- "interview"
|
||||
- "dokumentieren"
|
||||
- "erfassen"
|
||||
- "idee speichern"
|
||||
inject_types: [] # Keine RAG-Suche, reiner Kontext-Dialog
|
||||
prompt_template: "interview_template"
|
||||
prepend_instruction: null
|
||||
|
||||
# LATE BINDING SCHEMAS:
|
||||
# Definition der Pflichtfelder pro Typ (korrespondiert mit types.yaml)
|
||||
# Wenn ein Typ hier fehlt, wird 'default' genutzt.
|
||||
schemas:
|
||||
default:
|
||||
fields: ["Titel", "Thema/Inhalt", "Tags"]
|
||||
hint: "Halte es einfach und übersichtlich."
|
||||
|
||||
project:
|
||||
fields: ["Titel", "Zielsetzung (Goal)", "Status (draft/active)", "Wichtige Stakeholder", "Nächste Schritte"]
|
||||
hint: "Achte darauf, Abhängigkeiten zu anderen Projekten mit [[rel:depends_on]] zu erfragen."
|
||||
|
||||
decision:
|
||||
fields: ["Titel", "Kontext (Warum entscheiden wir?)", "Getroffene Entscheidung", "Betrachtete Alternativen", "Status (proposed/final)"]
|
||||
hint: "Wichtig: Frage explizit nach den Gründen gegen die Alternativen."
|
||||
|
||||
goal:
|
||||
fields: ["Titel", "Zeitrahmen (Deadline)", "Messkriterien (KPIs)", "Verbundene Werte"]
|
||||
hint: "Ziele sollten SMART formuliert sein."
|
||||
|
||||
experience:
|
||||
fields: ["Titel", "Situation (Kontext)", "Erkenntnis (Learning)", "Emotionale Keywords (für Empathie-Suche)"]
|
||||
hint: "Fokussiere dich auf die persönliche Lektion."
|
||||
|
||||
value:
|
||||
fields: ["Titel (Name des Werts)", "Definition (Was bedeutet das für uns?)", "Anti-Beispiel (Was ist es nicht?)"]
|
||||
hint: "Werte dienen als Entscheidungsgrundlage."
|
||||
|
||||
principle:
|
||||
fields: ["Titel", "Handlungsanweisung", "Begründung"]
|
||||
hint: "Prinzipien sind härter als Werte."
|
||||
|
|
@ -94,3 +94,47 @@ technical_template: |
|
|||
- Kurze Erklärung des Ansatzes.
|
||||
- Markdown Code-Block (Copy-Paste fertig).
|
||||
- Wichtige Edge-Cases.
|
||||
# ---------------------------------------------------------
|
||||
# 5. INTERVIEW: Der "One-Shot Extractor" (Performance Mode)
|
||||
# ---------------------------------------------------------
|
||||
|
||||
interview_template: |
|
||||
TASK:
|
||||
Erstelle einen Markdown-Entwurf für eine Notiz vom Typ '{target_type}'.
|
||||
|
||||
SCHEMA (Inhaltliche Pflichtfelder für den Body):
|
||||
{schema_fields}
|
||||
|
||||
USER INPUT:
|
||||
"{query}"
|
||||
|
||||
ANWEISUNG:
|
||||
1. Extrahiere Informationen aus dem Input.
|
||||
2. Generiere validen Markdown.
|
||||
|
||||
OUTPUT REGELN (STRIKT BEACHTEN):
|
||||
A. FRONTMATTER (YAML):
|
||||
- Darf NUR folgende Felder enthalten: [type, status, title, tags].
|
||||
- Schreibe KEINE inhaltlichen Sätze (wie 'Situation', 'Ziel') in das YAML!
|
||||
- Setze 'status: draft'.
|
||||
|
||||
B. BODY (Markdown):
|
||||
- Nutze für jedes Schema-Feld eine Markdown-Überschrift (## Feldname).
|
||||
- Schreibe den Inhalt DARUNTER.
|
||||
- Nutze "[TODO: Ergänzen]", wenn Infos fehlen.
|
||||
|
||||
HINWEIS ZUM TYP:
|
||||
{schema_hint}
|
||||
|
||||
OUTPUT FORMAT BEISPIEL:
|
||||
```markdown
|
||||
---
|
||||
type: {target_type}
|
||||
status: draft
|
||||
title: ...
|
||||
tags: [...]
|
||||
---
|
||||
# Titel der Notiz
|
||||
|
||||
## Erstes Schema Feld
|
||||
Der Inhalt hier...
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
# mindnet v2.2 – Knowledge Design Manual
|
||||
**Datei:** `docs/mindnet_knowledge_design_manual_v2.2.md`
|
||||
# mindnet v2.4 – Knowledge Design Manual
|
||||
**Datei:** `docs/mindnet_knowledge_design_manual_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10)
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10a)
|
||||
**Quellen:** `knowledge_design.md`, `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_functional_architecture.md`.
|
||||
|
||||
---
|
||||
|
|
@ -28,6 +28,7 @@ Seit Version 2.3.1 verfügt Mindnet über:
|
|||
* **Hybrid Router:** Das System erkennt, ob du Fakten, Entscheidungen oder Empathie brauchst.
|
||||
* **Context Intelligence:** Das System lädt je nach Situation unterschiedliche Notiz-Typen (z.B. Werte bei Entscheidungen).
|
||||
* **Web UI (WP10):** Du kannst direkt sehen, welche Quellen genutzt wurden.
|
||||
* **Interview Modus (WP07):** Du kannst Notizen direkt im Chat entwerfen lassen.
|
||||
|
||||
### 1.2 Der Vault als „Source of Truth“
|
||||
Die Markdown-Dateien in deinem Vault sind die **einzige Quelle der Wahrheit**.
|
||||
|
|
@ -48,7 +49,7 @@ Jede Datei muss mindestens folgende Felder enthalten, um korrekt verarbeitet zu
|
|||
id: 20251110-projekt-alpha-8a9b2c # Eindeutige Kennung (YYYYMMDD-slug)
|
||||
title: Projekt Alpha # Sprechender Titel (wird in Suchergebnissen angezeigt)
|
||||
type: project # Steuert Verarbeitung & Vernetzung (siehe Kap. 3)
|
||||
status: active # Status (z.B. draft, active, archived)
|
||||
status: active # active, archived oder 'draft' (für generierte Notes)
|
||||
created: 2025-11-10 # Erstellungsdatum (ISO 8601 oder YYYY-MM-DD)
|
||||
updated: 2025-12-07 # Letzte Änderung
|
||||
tags: [ki, entwicklung] # Taxonomie für Filterung
|
||||
|
|
@ -79,23 +80,23 @@ Diese Felder sind technisch nicht zwingend, aber für bestimmte Typen sinnvoll:
|
|||
|
||||
## 3. Note-Typen & Typ-Registry
|
||||
|
||||
Der `type` ist der wichtigste Hebel im Knowledge Design. Er steuert nicht nur das Gewicht bei der Suche, sondern seit WP-06 auch, **wann** eine Notiz aktiv in den Chat geholt wird ("Strategic Retrieval").
|
||||
Der `type` ist der wichtigste Hebel im Knowledge Design. Er steuert nicht nur das Gewicht bei der Suche, sondern seit WP-06 auch, **wann** eine Notiz aktiv in den Chat geholt wird ("Strategic Retrieval") und **welche Felder** im Interview abgefragt werden.
|
||||
|
||||
### 3.1 Übersicht der Kern-Typen
|
||||
|
||||
Mindnet unterscheidet verschiedene Wissensarten. Wähle den Typ, der die **Rolle** der Notiz am besten beschreibt:
|
||||
|
||||
| Typ | Beschreibung & Einsatzzweck | Rolle im Chat (Intent) |
|
||||
| :--- | :--- | :--- |
|
||||
| **`concept`** | Fachbegriffe, Theorien. Zeitloses Wissen. | **FACT** (Basiswissen) |
|
||||
| **`project`** | Ein Vorhaben mit Ziel, Dauer und Aufgaben. | **FACT / DECISION** (Kontext) |
|
||||
| **`experience`** | Persönliche Erfahrung, Lektion oder Erkenntnis. | **EMPATHY** (Spiegelung) |
|
||||
| **`decision`** | Eine bewusst getroffene Entscheidung (ADR). | **DECISION** (Begründung "Warum") |
|
||||
| **`value`** | Ein persönlicher Wert oder ein Prinzip. | **DECISION** (Moralischer Kompass) |
|
||||
| **`goal`** | Ein strategisches Ziel (kurz- oder langfristig). | **DECISION** (Abgleich) |
|
||||
| **`person`** | Eine reale Person (Netzwerk, Autor). | **FACT** |
|
||||
| **`journal`** | Zeitbezogener Log-Eintrag, Daily Note. | **FACT** (Historie) |
|
||||
| **`source`** | Externe Quelle (Buch, PDF, Artikel). | **FACT** (Faktenbasis) |
|
||||
| Typ | Beschreibung & Einsatzzweck | Rolle im Chat (Intent) | Interview Schema (WP07) |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| **`concept`** | Fachbegriffe, Theorien. Zeitloses Wissen. | **FACT** | Titel, Definition, Tags |
|
||||
| **`project`** | Ein Vorhaben mit Ziel, Dauer und Aufgaben. | **FACT / DECISION** | Ziel, Status, Stakeholder, Steps |
|
||||
| **`experience`** | Persönliche Erfahrung, Lektion oder Erkenntnis. | **EMPATHY** | Situation, Erkenntnis, Emotionen |
|
||||
| **`decision`** | Eine bewusst getroffene Entscheidung (ADR). | **DECISION** | Kontext, Entscheidung, Alternativen |
|
||||
| **`value`** | Ein persönlicher Wert oder ein Prinzip. | **DECISION** | Definition, Anti-Beispiel |
|
||||
| **`goal`** | Ein strategisches Ziel (kurz- oder langfristig). | **DECISION** | Zeitrahmen, KPIs, Werte |
|
||||
| **`person`** | Eine reale Person (Netzwerk, Autor). | **FACT** | Rolle, Kontext |
|
||||
| **`journal`** | Zeitbezogener Log-Eintrag, Daily Note. | **FACT** | Datum, Tags |
|
||||
| **`source`** | Externe Quelle (Buch, PDF, Artikel). | **FACT** | Autor, URL |
|
||||
|
||||
### 3.2 Zusammenspiel mit `types.yaml`
|
||||
|
||||
|
|
@ -200,6 +201,14 @@ Da deine Notizen im Web-Interface (WP10) angezeigt werden:
|
|||
* **Kurze Absätze:** Das LLM liest besser, und der Mensch scannt schneller.
|
||||
* **Klare Headings:** Nutze H1/H2, um dem Chunker logische Trennlinien zu geben.
|
||||
|
||||
### 5.4 Der Interview-Modus (Auto-Drafting)
|
||||
Seit v2.4 (WP07) kann Mindnet Notizen für dich entwerfen.
|
||||
|
||||
* **Wie:** Schreibe im Chat einfach: *"Ich möchte ein neues Projekt 'Alpha' anlegen, Ziel ist die Markteroberung."*
|
||||
* **Was passiert:** Mindnet erkennt den Wunsch (`INTERVIEW`), wählt das Schema für `project` und generiert **sofort** einen Markdown-Entwurf.
|
||||
* **Ergebnis:** Du erhältst einen Code-Block mit `status: draft`. Diesen kannst du im Draft-Editor (UI) direkt bearbeiten und herunterladen.
|
||||
* **Drafts:** Enthalten oft Platzhalter `[TODO]`. Das ist Absicht. Ergänze sie im Editor.
|
||||
|
||||
---
|
||||
|
||||
## 6. Best Practices & Beispiele (Klassik)
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
# Mindnet v2.2 – Overview & Einstieg
|
||||
**Datei:** `docs/mindnet_overview_v2.2.md`
|
||||
# Mindnet v2.4 – Overview & Einstieg
|
||||
**Datei:** `docs/mindnet_overview_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Post-WP10 Release)
|
||||
**Version:** 2.3.1
|
||||
**Status:** **FINAL** (Inkl. Interview-Assistent & Web-Editor)
|
||||
**Version:** 2.4.0
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -13,10 +13,10 @@
|
|||
Anders als herkömmliche Notiz-Apps (wie Obsidian oder Evernote), die Texte nur passiv speichern, ist Mindnet ein **aktives System**:
|
||||
* Es **versteht** Zusammenhänge über einen Wissensgraphen.
|
||||
* Es **begründet** Antworten ("Warum ist das so?").
|
||||
* Es **antwortet** situativ angepasst: Mal als harter Strategieberater, mal als empathischer Spiegel.
|
||||
* Es **antwortet** situativ angepasst: Mal als Strategieberater, mal als empathischer Spiegel, und neu: **als Interviewer, der hilft, Wissen zu erfassen.**
|
||||
|
||||
### Die Vision
|
||||
> „Ein System, das nicht nur speichert, was ich weiß, sondern auch wie ich denke und fühle.“
|
||||
> „Ein System, das nicht nur speichert, was ich weiß, sondern auch wie ich denke, fühle und arbeite.“
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -36,14 +36,16 @@ Mindnet arbeitet auf drei Schichten, die aufeinander aufbauen:
|
|||
* **Technik:** Hybrider Retriever (Graph + Vektor), Explanation Engine.
|
||||
* **Status:** 🟢 Live (WP04).
|
||||
|
||||
### Ebene 3: Identität (Die Persönlichkeit)
|
||||
* **Funktion:** Interaktion und Bewertung. Das System nimmt eine Haltung ein.
|
||||
* **Logik:** "Ich empfehle Lösung X, weil sie unserem Wert 'Datensparsamkeit' entspricht."
|
||||
### Ebene 3: Identität & Interaktion (Die Persönlichkeit)
|
||||
* **Funktion:** Interaktion, Bewertung und Co-Creation.
|
||||
* **Logik:**
|
||||
* "Ich empfehle Lösung X, weil sie unserem Wert 'Datensparsamkeit' entspricht."
|
||||
* "Ich sehe, du willst ein Projekt starten. Lass uns die Eckdaten erfassen."
|
||||
* **Technik:**
|
||||
* **Intent Router:** Erkennt Absichten (Fakt vs. Gefühl vs. Entscheidung).
|
||||
* **Intent Router:** Erkennt Absichten (Fakt vs. Gefühl vs. Entscheidung vs. Interview).
|
||||
* **Strategic Retrieval:** Lädt gezielt Werte oder Erfahrungen nach.
|
||||
* **Multi-Persona:** Passt den Tonfall an.
|
||||
* **Status:** 🟢 Live (WP05–WP06).
|
||||
* **One-Shot Extraction:** Generiert Entwürfe für neue Notizen.
|
||||
* **Status:** 🟢 Live (WP05–WP07, WP10).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -51,18 +53,20 @@ Mindnet arbeitet auf drei Schichten, die aufeinander aufbauen:
|
|||
|
||||
Der Datenfluss in Mindnet ist zyklisch ("Data Flywheel"):
|
||||
|
||||
1. **Input:** Du schreibst Notizen in Obsidian.
|
||||
1. **Input:** Du schreibst Notizen in Obsidian **ODER** lässt sie von Mindnet im Chat entwerfen.
|
||||
2. **Ingest:** Ein Python-Skript importiert, zerlegt (Chunking) und vernetzt (Edges) die Daten in Qdrant.
|
||||
3. **Intent Recognition:** Der Router analysiert deine Frage: Willst du Fakten, Code oder Empathie?
|
||||
4. **Retrieval:** Das System sucht Inhalte passend zum Intent (z.B. "Lade Erfahrungen bei Empathie").
|
||||
5. **Generation:** Ein lokales LLM (Ollama) formuliert die Antwort.
|
||||
3. **Intent Recognition:** Der Router analysiert deine Frage: Willst du Fakten, Code, Empathie oder etwas dokumentieren?
|
||||
4. **Retrieval / Action:**
|
||||
* Bei Fragen: Das System sucht Inhalte passend zum Intent.
|
||||
* Bei Interviews: Das System wählt das passende Schema (z.B. Projekt-Vorlage).
|
||||
5. **Generation:** Ein lokales LLM (Ollama) formuliert die Antwort oder den Markdown-Draft.
|
||||
6. **Feedback:** Du bewertest die Antwort. Das System lernt (langfristig) daraus.
|
||||
|
||||
**Tech-Stack:**
|
||||
* **Backend:** Python 3.12, FastAPI.
|
||||
* **Backend:** Python 3.10+, FastAPI.
|
||||
* **Datenbank:** Qdrant (Vektor & Graph).
|
||||
* **KI:** Ollama (Phi-3 Mini / Mistral) – 100% lokal.
|
||||
* **Frontend:** Streamlit Web-UI (v2.3.1).
|
||||
* **KI:** Ollama (Phi-3 Mini) – 100% lokal.
|
||||
* **Frontend:** Streamlit Web-UI (v2.4).
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -72,25 +76,25 @@ Wo findest du was?
|
|||
|
||||
| Wenn du... | ...lies dieses Dokument |
|
||||
| :--- | :--- |
|
||||
| **...wissen willst, wie man Notizen schreibt.** | `mindnet_knowledge_design_manual_v2.2.md` |
|
||||
| **...das System installieren oder betreiben musst.** | `mindnet_admin_guide_v2.2.md` |
|
||||
| **...am Python-Code entwickeln willst.** | `mindnet_developer_guide_v2.2.md` |
|
||||
| **...die Pipeline (Import -> RAG) verstehen willst.** | `mindnet_pipeline_playbook_v2.2.md` |
|
||||
| **...wissen willst, wie man Notizen schreibt.** | `mindnet_knowledge_design_manual_v2.4.md` |
|
||||
| **...das System installieren oder betreiben musst.** | `mindnet_admin_guide_v2.4.md` |
|
||||
| **...am Python-Code entwickeln willst.** | `mindnet_developer_guide_v2.4.md` |
|
||||
| **...die Pipeline (Import -> RAG) verstehen willst.** | `mindnet_pipeline_playbook_v2.4.md` |
|
||||
| **...die genaue JSON-Struktur oder APIs suchst.** | `mindnet_technical_architecture.md` |
|
||||
| **...verstehen willst, was fachlich passiert.** | `mindnet_functional_architecture.md` |
|
||||
| **...den aktuellen Projektstatus suchst.** | `Programmplan_V2.2.md` |
|
||||
| **...den aktuellen Projektstatus suchst.** | `mindnet_appendices_v2.4.md` |
|
||||
|
||||
---
|
||||
|
||||
## 5. Rollen im System
|
||||
|
||||
* **Mindmaster (User/Owner):** Du. Du erstellst Inhalte, stellst Fragen und gibst Feedback. Du definierst die Werte (`type: value`).
|
||||
* **Mindnet (Der Agent):** Der digitale Zwilling. Er agiert als pragmatischer, transparenter Assistent im Chat.
|
||||
* **Mindnet (Der Agent):** Der digitale Zwilling. Er agiert als pragmatischer, transparenter Assistent und Analyst.
|
||||
* **Administrator:** Verantwortlich für Docker-Container, Backups und LLM-Ressourcen.
|
||||
|
||||
---
|
||||
|
||||
## 6. Aktueller Fokus
|
||||
|
||||
Wir haben **Phase D (Interaktion)** mit WP10 (Chat Interface) begonnen und die UI erfolgreich deployed.
|
||||
Das System ist nun für Endnutzer bedienbar. Als Nächstes folgt der **Interview-Assistent (WP07)**, um Wissen dialogisch zu erfassen.
|
||||
Wir haben den **Interview-Assistenten (WP07)** und den **Draft-Editor (WP10a)** erfolgreich integriert.
|
||||
Das System kann nun aktiv helfen, Wissen zu strukturieren, anstatt es nur abzurufen. Der Fokus verschiebt sich nun in Richtung **Self-Tuning (WP08)**, um aus dem gesammelten Feedback automatisch zu lernen.
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
# Mindnet v2.2 – Admin Guide
|
||||
**Datei:** `docs/mindnet_admin_guide_v2.2.md`
|
||||
# Mindnet v2.4 – Admin Guide
|
||||
**Datei:** `docs/mindnet_admin_guide_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Inkl. Frontend Deployment)
|
||||
**Quellen:** `Handbuch.md`, `mindnet_developer_guide_v2.2.md`.
|
||||
**Status:** **FINAL** (Inkl. Frontend Deployment & Interview Config)
|
||||
**Quellen:** `Handbuch.md`, `mindnet_developer_guide_v2.4.md`.
|
||||
|
||||
> Dieses Handbuch richtet sich an **Administratoren**. Es beschreibt Installation, Konfiguration, Backup-Strategien, Monitoring und den sicheren Betrieb der Mindnet-Instanz (API + UI + DB).
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ Mindnet benötigt einen lokalen LLM-Server für den Chat.
|
|||
curl http://localhost:11434/api/generate -d '{"model": "phi3:mini", "prompt":"Hi"}'
|
||||
|
||||
### 2.5 Konfiguration (ENV)
|
||||
Erstelle eine `.env` Datei im Root-Verzeichnis. Die neuen Settings für WP-06 (Timeout, Decision Config) sind essenziell für stabilen Betrieb auf CPUs.
|
||||
Erstelle eine `.env` Datei im Root-Verzeichnis. Die neuen Settings für WP-06/WP-07 (Timeout, Decision Config) sind essenziell für stabilen Betrieb auf CPUs.
|
||||
|
||||
# Qdrant Verbindung
|
||||
QDRANT_URL="http://localhost:6333"
|
||||
|
|
@ -77,7 +77,7 @@ Erstelle eine `.env` Datei im Root-Verzeichnis. Die neuen Settings für WP-06 (T
|
|||
|
||||
# LLM / RAG Settings
|
||||
MINDNET_LLM_MODEL="phi3:mini"
|
||||
MINDNET_OLLAMA_URL="[http://127.0.0.1:11434](http://127.0.0.1:11434)"
|
||||
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
||||
|
||||
# Config & Timeouts
|
||||
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Mindnet v2.2 – Appendices & Referenzen
|
||||
**Datei:** `docs/mindnet_appendices_v2.2.md`
|
||||
# Mindnet v2.4 – Appendices & Referenzen
|
||||
**Datei:** `docs/mindnet_appendices_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10)
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10a)
|
||||
**Quellen:** `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_technical_architecture.md`, `Handbuch.md`.
|
||||
|
||||
> Dieses Dokument bündelt Tabellen, Schemata und technische Referenzen, die in den Prozess-Dokumenten (Playbook, Guides) den Lesefluss stören würden.
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
## Anhang A: Typ-Registry Referenz (Default-Werte)
|
||||
|
||||
Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.3.1).
|
||||
Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.4).
|
||||
|
||||
| Typ (`type`) | Chunk Profile | Retriever Weight | Edge Defaults (Auto-Kanten) | Beschreibung |
|
||||
| :--- | :--- | :--- | :--- | :--- |
|
||||
|
|
@ -23,8 +23,8 @@ Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.3.1).
|
|||
| **source** | `long` | 0.50 | *(keine)* | Externe Quellen (Bücher, PDFs). |
|
||||
| **event** | `short` | 0.60 | `related_to` | Meetings, Konferenzen. |
|
||||
| **value** | `medium` | 1.00 | `related_to` | Persönliche Werte/Prinzipien. |
|
||||
| **goal** | `medium` | 0.95 | `depends_on` | Strategische Ziele (Neu in WP06). |
|
||||
| **belief** | `medium` | 0.90 | `related_to` | Glaubenssätze (Neu in WP06). |
|
||||
| **goal** | `medium` | 0.95 | `depends_on` | Strategische Ziele. |
|
||||
| **belief** | `medium` | 0.90 | `related_to` | Glaubenssätze. |
|
||||
| **default** | `medium` | 1.00 | `references` | Fallback, wenn Typ unbekannt. |
|
||||
|
||||
---
|
||||
|
|
@ -71,7 +71,7 @@ Diese sind die Felder, die effektiv in Qdrant gespeichert werden.
|
|||
{
|
||||
"chunk_id": "string (keyword)", // Format: {note_id}#c{index}
|
||||
"note_id": "string (keyword)", // FK zur Note
|
||||
"type": "string (keyword)", // Typ-Kopie aus Note (Neu in WP06a)
|
||||
"type": "string (keyword)", // Typ-Kopie aus Note
|
||||
"text": "string (text)", // Reintext für Anzeige (ohne Overlap)
|
||||
"window": "string (text)", // Text + Overlap (für Embedding)
|
||||
"ord": "integer", // Laufende Nummer (1..N)
|
||||
|
|
@ -87,10 +87,10 @@ Diese sind die Felder, die effektiv in Qdrant gespeichert werden.
|
|||
"source_id": "string (keyword)", // Chunk-ID (Start)
|
||||
"target_id": "string (keyword)", // Chunk-ID oder Note-Titel (Ziel)
|
||||
"kind": "string (keyword)", // z.B. 'depends_on'
|
||||
"scope": "string (keyword)", // Immer 'chunk' in v2.2
|
||||
"scope": "string (keyword)", // Immer 'chunk'
|
||||
"rule_id": "string (keyword)", // Traceability: 'inline:rel', 'explicit:wikilink'
|
||||
"confidence": "float", // 0.0 - 1.0
|
||||
"note_id": "string (keyword)" // Owner Note ID (für Löschung)
|
||||
"note_id": "string (keyword)" // Owner Note ID
|
||||
}
|
||||
|
||||
---
|
||||
|
|
@ -107,10 +107,11 @@ Diese Variablen steuern das Verhalten der Skripte und Container.
|
|||
| `MINDNET_TYPES_FILE` | `config/types.yaml` | Pfad zur Typ-Registry. |
|
||||
| `MINDNET_RETRIEVER_CONFIG`| `config/retriever.yaml`| Pfad zur Scoring-Konfiguration. |
|
||||
| `MINDNET_PROMPTS_PATH` | `config/prompts.yaml` | Pfad zu LLM-Prompts (Neu in v2.2). |
|
||||
| `MINDNET_DECISION_CONFIG` | `config/decision_engine.yaml` | Pfad zur Router-Config (Neu in v2.3). |
|
||||
| `MINDNET_DECISION_CONFIG` | `config/decision_engine.yaml` | Router & Interview Config (Neu in v2.3). |
|
||||
| `MINDNET_LLM_MODEL` | `phi3:mini` | Name des Ollama-Modells (Neu in v2.2). |
|
||||
| `MINDNET_OLLAMA_URL` | `http://127.0.0.1:11434`| URL zum LLM-Server (Neu in v2.2). |
|
||||
| `MINDNET_LLM_TIMEOUT` | `120.0` | Timeout für Ollama (Erhöhen auf 300.0 für CPU). |
|
||||
| `MINDNET_LLM_TIMEOUT` | `300.0` | Timeout für Ollama (Erhöht für CPU-Inference). |
|
||||
| `MINDNET_API_TIMEOUT` | `300.0` | Frontend Timeout (Streamlit). |
|
||||
| `MINDNET_HASH_COMPARE` | `Body` | Vergleichsmodus für Import (`Body`, `Frontmatter`, `Full`). |
|
||||
| `MINDNET_HASH_SOURCE` | `parsed` | Quelle für Hash (`parsed`, `raw`, `file`). |
|
||||
| `VECTOR_DIM` | `384` | Dimension der Embeddings (Modellabhängig). |
|
||||
|
|
@ -119,16 +120,16 @@ Diese Variablen steuern das Verhalten der Skripte und Container.
|
|||
|
||||
## Anhang E: Glossar
|
||||
|
||||
* **Callout-Edge:** Kante via `> [!edge]`.
|
||||
* **Decision Engine:** Komponente, die den Intent prüft und Strategien wählt (WP06).
|
||||
* **Draft Editor:** Web-Komponente zur Bearbeitung generierter Notizen (WP10a).
|
||||
* **Explanation Layer:** Komponente, die Scores und Graphen als Begründung liefert.
|
||||
* **Hybrid Router:** Kombination aus Keyword-Matching und LLM-Klassifizierung für Intents.
|
||||
* **One-Shot Extractor:** LLM-Strategie zur sofortigen Generierung von Drafts ohne Rückfragen (WP07).
|
||||
* **RAG (Retrieval Augmented Generation):** Kombination aus Suche und Text-Generierung.
|
||||
* **Strategic Retrieval:** Gezieltes Nachladen von Werten (`value`) bei Entscheidungfragen.
|
||||
|
||||
---
|
||||
|
||||
## Anhang F: Workpackage Status (v2.3.2)
|
||||
## Anhang F: Workpackage Status (v2.4.0)
|
||||
|
||||
Aktueller Implementierungsstand der Module.
|
||||
|
||||
|
|
@ -140,9 +141,9 @@ Aktueller Implementierungsstand der Module.
|
|||
| **WP04a**| Retriever Scoring | 🟢 Live | Hybrider Score (Semantik + Graph). |
|
||||
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
|
||||
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Chat mit Context Enrichment. |
|
||||
| **WP06** | Decision Engine | 🟢 Live | Hybrid Router, Strategic Retrieval, Multi-Persona. |
|
||||
| **WP07** | Interview Assistent | 🟡 Geplant | Dialog-Modus (Nächster Schritt). |
|
||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
|
||||
| **WP06** | Decision Engine | 🟢 Live | Intent-Router & Strategic Retrieval. |
|
||||
| **WP07** | Interview Assistent | 🟢 Live | **One-Shot Extractor & Schemas aktiv.** |
|
||||
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
||||
| **WP10** | Chat Interface | 🟢 Live | Web-Interface (Streamlit). |
|
||||
| **WP10a**| GUI Evolution | 🔴 Geplant | Interaktive Tools & Editor. |
|
||||
| **WP10a**| Draft Editor | 🟢 Live | **Interaktives UI für WP07 Drafts.** |
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
# Mindnet v2.2 – Entwickler-Workflow
|
||||
**Datei:** `DEV_WORKFLOW.md`
|
||||
**Stand:** 2025-12-10 (Aktualisiert: Inkl. Frontend WP10)
|
||||
# Mindnet v2.4 – Entwickler-Workflow
|
||||
**Datei:** `docs/DEV_WORKFLOW.md`
|
||||
**Stand:** 2025-12-10 (Aktualisiert: Inkl. Interview-Tests WP07)
|
||||
|
||||
Dieses Handbuch beschreibt den Entwicklungszyklus zwischen **Windows PC** (IDE), **Raspberry Pi** (Gitea) und **Beelink** (Runtime/Server).
|
||||
|
||||
|
|
@ -35,14 +35,14 @@ Hier erstellst du die neue Funktion in einer sicheren Umgebung.
|
|||
2. **Branch erstellen:**
|
||||
* Klicke wieder unten links auf `main`.
|
||||
* Wähle `+ Create new branch...`.
|
||||
* Gib den Namen ein: `feature/was-ich-tue` (z.B. `feature/wp06-decision`).
|
||||
* Gib den Namen ein: `feature/was-ich-tue` (z.B. `feature/wp07-interview`).
|
||||
* Drücke **Enter**.
|
||||
|
||||
3. **Sicherheits-Check:**
|
||||
* Steht unten links jetzt dein Feature-Branch? **Nur dann darfst du Code ändern!**
|
||||
|
||||
4. **Coden:**
|
||||
* Nimm deine Änderungen vor (z.B. neue YAML-Configs).
|
||||
* Nimm deine Änderungen vor (z.B. neue Schemas in `decision_engine.yaml`).
|
||||
|
||||
5. **Sichern & Hochladen:**
|
||||
* **Source Control** Icon (Gabel-Symbol) -> Nachricht eingeben -> **Commit**.
|
||||
|
|
@ -64,7 +64,7 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
|
|||
```bash
|
||||
git fetch
|
||||
# Tipp: 'git branch -r' zeigt alle verfügbaren Branches an
|
||||
git checkout feature/wp06-decision
|
||||
git checkout feature/wp07-interview
|
||||
git pull
|
||||
```
|
||||
|
||||
|
|
@ -80,9 +80,9 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
|
|||
**Option A: Standard (Als Service laufen lassen)**
|
||||
Ideal, wenn du nur testen willst, ob es läuft.
|
||||
```bash
|
||||
# 1. API neustarten
|
||||
# 1. API neustarten (Backend)
|
||||
sudo systemctl restart mindnet-dev
|
||||
# 2. UI neustarten (falls Frontend-Änderungen)
|
||||
# 2. UI neustarten (Frontend)
|
||||
sudo systemctl restart mindnet-ui-dev
|
||||
|
||||
# Logs prüfen (um Fehler zu sehen):
|
||||
|
|
@ -109,12 +109,21 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
|
|||
sudo systemctl start mindnet-ui-dev
|
||||
```
|
||||
|
||||
6. **Validieren:**
|
||||
* **Browser:** Öffne `http://<IP>:8502` um die UI zu testen.
|
||||
6. **Validieren (Smoke Tests):**
|
||||
|
||||
* **Browser:** Öffne `http://<IP>:8502` um die UI zu testen (Intent Badge prüfen!).
|
||||
* **CLI:** Führe Testskripte in einem **zweiten Terminal** aus:
|
||||
|
||||
**Test A: Decision Engine**
|
||||
```bash
|
||||
# Beispiel für Decision Engine Test
|
||||
python tests/test_wp06_decision.py -p 8002 -q "Soll ich...?"
|
||||
python tests/test_wp06_decision.py -p 8002 -q "Soll ich Qdrant nutzen?"
|
||||
# Erwartung: Intent DECISION
|
||||
```
|
||||
|
||||
**Test B: Interview Modus (Neu!)**
|
||||
```bash
|
||||
python tests/test_wp06_decision.py -p 8002 -q "Ich will ein neues Projekt starten"
|
||||
# Erwartung: Intent INTERVIEW, Output ist Markdown Codeblock
|
||||
```
|
||||
|
||||
---
|
||||
|
|
@ -165,7 +174,7 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
|
|||
cd ~/mindnet_dev
|
||||
git checkout main
|
||||
git pull
|
||||
git branch -d feature/wp06-decision
|
||||
git branch -d feature/wp07-interview
|
||||
```
|
||||
3. **VS Code:**
|
||||
* Auf `main` wechseln.
|
||||
|
|
@ -189,12 +198,11 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
|
|||
|
||||
## 4. Troubleshooting
|
||||
|
||||
**"Read timed out (120s)" / 500 Error beim Chat**
|
||||
* **Ursache:** Das LLM (Ollama) braucht zu lange zum Laden ("Cold Start").
|
||||
**"Read timed out (300s)" / 500 Error beim Interview**
|
||||
* **Ursache:** Das LLM (Ollama) braucht für den One-Shot Draft länger als das Timeout erlaubt.
|
||||
* **Lösung:**
|
||||
1. Erhöhe in `.env` den Wert: `MINDNET_LLM_TIMEOUT=300.0` (Backend) oder `MINDNET_API_TIMEOUT` (Frontend).
|
||||
1. Erhöhe in `.env` den Wert: `MINDNET_LLM_TIMEOUT=300.0`.
|
||||
2. Starte die Server neu.
|
||||
3. Stelle sicher, dass dein Test-Skript (Client) auch ein hohes Timeout hat.
|
||||
|
||||
**"Port 8002 / 8502 already in use"**
|
||||
* **Ursache:** Du willst `uvicorn` oder `streamlit` manuell starten, aber der Service läuft noch.
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
# Mindnet v2.2 – Developer Guide
|
||||
**Datei:** `docs/mindnet_developer_guide_v2.2.md`
|
||||
# Mindnet v2.4 – Developer Guide
|
||||
**Datei:** `docs/mindnet_developer_guide_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Inkl. RAG, Decision Engine & Frontend WP10)
|
||||
**Status:** **FINAL** (Inkl. RAG, Interview Mode & Frontend WP10)
|
||||
**Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`.
|
||||
|
||||
> **Zielgruppe:** Entwickler:innen.
|
||||
> **Zweck:** Anleitung zum Aufsetzen der Entwicklungsumgebung, Verständnis der Modulstruktur und Durchführung von Tests.
|
||||
|
||||
---
|
||||
- [Mindnet v2.2 – Developer Guide](#mindnet-v22--developer-guide)
|
||||
- [Mindnet v2.4 – Developer Guide](#mindnet-v24--developer-guide)
|
||||
- [1. Projektstruktur (Post-WP10)](#1-projektstruktur-post-wp10)
|
||||
- [2. Lokales Setup (Development)](#2-lokales-setup-development)
|
||||
- [2.1 Voraussetzungen](#21-voraussetzungen)
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
- [5. Das "Teach-the-AI" Paradigma (Context Intelligence)](#5-das-teach-the-ai-paradigma-context-intelligence)
|
||||
- [A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)](#a-workflow-einen-neuen-typ-implementieren-z-b-type-risk)
|
||||
- [B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`)](#b-workflow-neue-beziehungen-edges-nutzen-z-b-beeinflusst_von)
|
||||
- [C. Workflow: Interview-Schema anpassen (WP07)](#c-workflow-interview-schema-anpassen-wp07)
|
||||
- [Fazit](#fazit)
|
||||
- [6. Nützliche Einzeiler](#6-nützliche-einzeiler)
|
||||
|
||||
|
|
@ -48,7 +49,7 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
|
|||
│ │ └── dto.py # Zentrale DTO-Definition
|
||||
│ ├── routers/ # FastAPI Endpoints
|
||||
│ │ ├── query.py # Suche
|
||||
│ │ ├── chat.py # Hybrid Router & Decision Engine (WP06)
|
||||
│ │ ├── chat.py # Hybrid Router & Interview Logic (WP06/WP07)
|
||||
│ │ ├── feedback.py # Feedback (WP04c)
|
||||
│ │ └── ...
|
||||
│ ├── services/ # Interne & Externe Dienste
|
||||
|
|
@ -56,12 +57,12 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
|
|||
│ │ ├── feedback_service.py # Logging (JSONL Writer)
|
||||
│ │ └── embeddings_client.py
|
||||
│ ├── frontend/ # NEU (WP10)
|
||||
│ │ └── ui.py # Streamlit Application
|
||||
│ │ └── ui.py # Streamlit Application inkl. Draft-Editor
|
||||
│ └── main.py # Entrypoint der API
|
||||
├── config/ # YAML-Konfigurationen (Single Source of Truth)
|
||||
│ ├── types.yaml # Import-Regeln
|
||||
│ ├── prompts.yaml # LLM Prompts & RAG Templates (WP06)
|
||||
│ ├── decision_engine.yaml # Router-Strategien (WP06)
|
||||
│ ├── prompts.yaml # LLM Prompts & Interview Templates (WP06/07)
|
||||
│ ├── decision_engine.yaml # Router-Strategien & Schemas (WP06/07)
|
||||
│ └── retriever.yaml # Scoring-Regeln & Kantengewichte
|
||||
├── data/
|
||||
│ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl)
|
||||
|
|
@ -108,7 +109,7 @@ Erstelle eine `.env` Datei im Root-Verzeichnis.
|
|||
MINDNET_TYPES_FILE="./config/types.yaml"
|
||||
MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml"
|
||||
|
||||
# LLM / RAG Settings (WP06)
|
||||
# LLM / RAG Settings (WP06/07)
|
||||
MINDNET_LLM_MODEL="phi3:mini"
|
||||
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
||||
MINDNET_LLM_TIMEOUT=300.0
|
||||
|
|
@ -148,9 +149,9 @@ Dies ist das komplexeste Modul.
|
|||
* **Debugging:** Nutze `--dry-run` oder `scripts/payload_dryrun.py`.
|
||||
|
||||
### 3.2 Der Hybrid Router (`app.routers.chat`)
|
||||
Hier liegt die Logik für Intent Detection (WP06).
|
||||
Hier liegt die Logik für Intent Detection (WP06) und Interview-Modus (WP07).
|
||||
* **Logic:** `_classify_intent` prüft zuerst Keywords (Fast Path) und fällt auf `llm_service.generate_raw_response` zurück (Slow Path), wenn konfiguriert.
|
||||
* **Config:** Gesteuert durch `decision_engine.yaml`.
|
||||
* **One-Shot:** Wenn Intent `INTERVIEW` erkannt wird, wird **kein Retrieval** ausgeführt. Stattdessen wird ein Draft generiert.
|
||||
* **Erweiterung:** Um neue Intents hinzuzufügen, editiere nur die YAML, nicht den Python-Code (Late Binding).
|
||||
|
||||
### 3.3 Der Retriever (`app.core.retriever`)
|
||||
|
|
@ -160,9 +161,9 @@ Hier passiert das Scoring.
|
|||
|
||||
### 3.4 Das Frontend (`app.frontend.ui`)
|
||||
Eine Streamlit-App (WP10).
|
||||
* **Draft Editor:** Enthält einen YAML-Sanitizer (`normalize_meta_and_body`), der sicherstellt, dass LLM-Halluzinationen im Frontmatter nicht das File zerstören.
|
||||
* **State:** Nutzt `st.session_state` für Chat-History und Drafts.
|
||||
* **Logik:** Ruft `/chat` und `/feedback` Endpoints der API auf.
|
||||
* **Anpassung:** CSS Styles sind direkt in `ui.py` eingebettet.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -204,7 +205,7 @@ Prüfen das laufende System gegen eine echte Qdrant-Instanz und Ollama.
|
|||
|
||||
## 5. Das "Teach-the-AI" Paradigma (Context Intelligence)
|
||||
|
||||
Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Wenn du dem System ein neues Konzept beibringen willst, musst du in der Regel an drei Stellen eingreifen. Dies ist der **Core-Workflow** für Erweiterungen.
|
||||
Mindnet lernt nicht durch Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Dies ist der **Core-Workflow** für Erweiterungen.
|
||||
|
||||
### A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)
|
||||
|
||||
|
|
@ -227,26 +228,29 @@ Damit dieser Typ aktiv geladen wird, musst du ihn einer Strategie zuordnen.
|
|||
**3. Kognitive Ebene (`config/prompts.yaml`)**
|
||||
Erkläre dem LLM im Template, was es damit tun soll.
|
||||
|
||||
decision_template: |
|
||||
...
|
||||
- Prüfe auf [RISK]: Wenn vorhanden, warne mich davor!
|
||||
|
||||
### B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`)
|
||||
|
||||
Beziehungen sind der Klebstoff für die "Why"-Erklärungen.
|
||||
|
||||
**1. Erfassung im Vault (Markdown)**
|
||||
Du musst dem System keinen neuen Edge-Typ "beibringen" (Schema-less). Du nutzt ihn einfach.
|
||||
Nutze die Inline-Syntax im Fließtext:
|
||||
|
||||
Die Entscheidung für Qdrant wurde [[rel:beeinflusst_von Budgetkürzung 2024]].
|
||||
> "Die Entscheidung für Qdrant wurde [[rel:beeinflusst_von Budgetkürzung 2024]]."
|
||||
|
||||
**2. Gewichtung (`config/retriever.yaml`)**
|
||||
Standardmäßig werden alle expliziten Kanten gleich behandelt. Wenn Kausalität wichtiger ist als Ähnlichkeit, konfiguriere dies hier.
|
||||
Konfiguriere `edge_weights`, wenn Kausalität wichtiger ist als Ähnlichkeit.
|
||||
|
||||
scoring:
|
||||
edge_type_weights:
|
||||
beeinflusst_von: 1.5 # Sehr starker Einfluss auf das Ranking
|
||||
### C. Workflow: Interview-Schema anpassen (WP07)
|
||||
|
||||
Wenn Mindnet neue Fragen stellen soll:
|
||||
|
||||
**1. Schema erweitern (`config/decision_engine.yaml`)**
|
||||
Füge das Feld in die Liste ein.
|
||||
|
||||
project:
|
||||
fields: ["Titel", "Ziel", "Budget"] # <--- Budget neu
|
||||
|
||||
**2. Keine Code-Änderung nötig**
|
||||
Der `One-Shot Extractor` (Prompt Template) liest diese Liste dynamisch und weist das LLM an, das Budget zu extrahieren oder `[TODO]` zu setzen.
|
||||
|
||||
### Fazit
|
||||
* **Vault:** Liefert das Wissen.
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# Mindnet v2.2 – Fachliche Architektur
|
||||
**Datei:** `docs/mindnet_functional_architecture_v2.2.md`
|
||||
# Mindnet v2.4 – Fachliche Architektur
|
||||
**Datei:** `docs/mindnet_functional_architecture_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10)
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10 + WP07)
|
||||
|
||||
> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** – mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten), die Logik des Retrievers und den **RAG-Chat** (Decision Engine & Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
|
||||
> Dieses Dokument beschreibt **was** Mindnet fachlich tut und **warum** – mit Fokus auf die Erzeugung und Nutzung von **Edges** (Kanten), die Logik des Retrievers und den **RAG-Chat** (Decision Engine, Interview-Modus & Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
|
||||
|
||||
---
|
||||
<details>
|
||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
||||
|
||||
- [Mindnet v2.2 – Fachliche Architektur](#mindnet-v22--fachliche-architektur)
|
||||
- [Mindnet v2.4 – Fachliche Architektur](#mindnet-v24--fachliche-architektur)
|
||||
- [](#)
|
||||
- [0) Zielbild \& Grundprinzip](#0-zielbild--grundprinzip)
|
||||
- [1) Notizen \& Chunks (fachliche Perspektive)](#1-notizen--chunks-fachliche-perspektive)
|
||||
|
|
@ -26,11 +26,12 @@
|
|||
- [5) Der Retriever (Funktionaler Layer)](#5-der-retriever-funktionaler-layer)
|
||||
- [5.1 Scoring-Modell](#51-scoring-modell)
|
||||
- [5.2 Erklärbarkeit (Explainability) – WP04b](#52-erklärbarkeit-explainability--wp04b)
|
||||
- [6) Context Intelligence \& Intent Router (WP06)](#6-context-intelligence--intent-router-wp06)
|
||||
- [6) Context Intelligence \& Intent Router (WP06/WP07)](#6-context-intelligence--intent-router-wp06wp07)
|
||||
- [6.1 Das Problem: Statische vs. Dynamische Antworten](#61-das-problem-statische-vs-dynamische-antworten)
|
||||
- [6.2 Der Intent-Router (Keyword \& Semantik)](#62-der-intent-router-keyword--semantik)
|
||||
- [6.3 Strategic Retrieval (Injektion von Werten)](#63-strategic-retrieval-injektion-von-werten)
|
||||
- [6.4 Reasoning (Das Gewissen)](#64-reasoning-das-gewissen)
|
||||
- [6.5 Der Interview-Modus (One-Shot Extraction) – Neu in v2.4](#65-der-interview-modus-one-shot-extraction--neu-in-v24)
|
||||
- [7) Future Concepts: The Empathic Digital Twin (Ausblick)](#7-future-concepts-the-empathic-digital-twin-ausblick)
|
||||
- [7.1 Antizipation durch Erfahrung](#71-antizipation-durch-erfahrung)
|
||||
- [7.2 Empathie \& "Ich"-Modus](#72-empathie--ich-modus)
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
- [13) Lösch-/Update-Garantien (Idempotenz)](#13-lösch-update-garantien-idempotenz)
|
||||
- [14) Beispiel – Von Markdown zu Kanten (v2.2)](#14-beispiel--von-markdown-zu-kanten-v22)
|
||||
- [15) Referenzen (Projektdateien \& Leitlinien)](#15-referenzen-projektdateien--leitlinien)
|
||||
- [16) Workpackage Status (v2.3.2)](#16-workpackage-status-v232)
|
||||
- [16) Workpackage Status (v2.4.0)](#16-workpackage-status-v240)
|
||||
|
||||
</details>
|
||||
---
|
||||
|
|
@ -208,13 +209,13 @@ Die API gibt diese Analysen als menschenlesbare Sätze (`reasons`) und als Daten
|
|||
|
||||
---
|
||||
|
||||
## 6) Context Intelligence & Intent Router (WP06)
|
||||
## 6) Context Intelligence & Intent Router (WP06/WP07)
|
||||
|
||||
Seit WP06 agiert Mindnet nicht mehr statisch, sondern passt seine Suchstrategie dem **Intent** (der Absicht) des Nutzers an. Dies ist die Transformation vom reinen Wissens-Abrufer zum strategischen Entscheidungspartner.
|
||||
Seit WP06/WP07 agiert Mindnet nicht mehr statisch, sondern passt seine Suchstrategie dem **Intent** (der Absicht) des Nutzers an. Dies ist die Transformation vom reinen Wissens-Abrufer zum strategischen Partner.
|
||||
|
||||
### 6.1 Das Problem: Statische vs. Dynamische Antworten
|
||||
* **Früher (Pre-WP06):** Jede Frage ("Was ist X?" oder "Soll ich X?") wurde gleich behandelt -> Fakten-Retrieval.
|
||||
* **Heute (WP06):** Das System erkennt, *was* der User will, und lädt unterschiedliche Wissensbausteine.
|
||||
* **Heute (WP06):** Das System erkennt, *was* der User will (Rat, Fakten oder Datenerfassung) und wechselt den Modus.
|
||||
|
||||
### 6.2 Der Intent-Router (Keyword & Semantik)
|
||||
Der Router prüft vor jeder Antwort die Absicht über konfigurierbare Strategien (`config/decision_engine.yaml`):
|
||||
|
|
@ -222,11 +223,8 @@ Der Router prüft vor jeder Antwort die Absicht über konfigurierbare Strategien
|
|||
1. **FACT:** Reine Wissensfrage ("Was ist Qdrant?"). → Standard RAG.
|
||||
2. **DECISION:** Frage nach Rat oder Strategie ("Soll ich Qdrant nutzen?"). → Aktiviert die Decision Engine.
|
||||
3. **EMPATHY:** Emotionale Zustände ("Ich bin gestresst"). → Aktiviert den empathischen Modus.
|
||||
4. **CODING:** Technische Anfragen.
|
||||
|
||||
**Erkennung:**
|
||||
* **Fast Path:** Prüfung auf Schlüsselwörter (z.B. "soll ich").
|
||||
* **Slow Path (Smart Fallback):** Wenn kein Keyword passt, prüft ein LLM (Phi-3) die Semantik des Satzes.
|
||||
4. **INTERVIEW (Neu in WP07):** Wunsch, Wissen zu erfassen ("Neues Projekt anlegen"). → Aktiviert den Draft-Generator.
|
||||
5. **CODING:** Technische Anfragen.
|
||||
|
||||
### 6.3 Strategic Retrieval (Injektion von Werten)
|
||||
Im Modus `DECISION` führt das System eine **zweite Suchstufe** aus. Es sucht nicht nur nach semantisch passenden Texten zur Frage, sondern erzwingt das Laden von strategischen Notizen wie:
|
||||
|
|
@ -234,12 +232,18 @@ Im Modus `DECISION` führt das System eine **zweite Suchstufe** aus. Es sucht ni
|
|||
* **Principles (`type: principle`):** Handlungsanweisungen.
|
||||
* **Goals (`type: goal`):** Strategische Ziele.
|
||||
|
||||
Dies wird über **Late Binding** in `config/decision_engine.yaml` gesteuert. Neue Facetten der Persönlichkeit können dort konfiguriert werden, ohne den Code zu ändern.
|
||||
|
||||
### 6.4 Reasoning (Das Gewissen)
|
||||
Das LLM erhält im Prompt die explizite Anweisung: *"Wäge die Fakten (aus der Suche) gegen die injizierten Werte ab."*
|
||||
Dadurch entstehen Antworten, die nicht nur technisch korrekt sind, sondern subjektiv passend ("Tool X passt nicht zu deinem Ziel Z").
|
||||
|
||||
### 6.5 Der Interview-Modus (One-Shot Extraction) – Neu in v2.4
|
||||
Wenn der User Wissen erfassen will ("Ich möchte ein neues Projekt anlegen"), wechselt Mindnet in den **Interview-Modus**.
|
||||
|
||||
* **Late Binding Schema:** Das System lädt ein konfiguriertes Schema für den Ziel-Typ (z.B. `project`: Pflichtfelder sind Titel, Ziel, Status).
|
||||
* **One-Shot Extraction:** Statt eines langen Dialogs extrahiert das LLM **sofort** alle verfügbaren Infos aus dem Prompt und generiert einen validen Markdown-Draft mit Frontmatter.
|
||||
* **Draft-Status:** Fehlende Pflichtfelder werden mit `[TODO]` markiert.
|
||||
* **UI-Integration:** Das Frontend rendert statt einer Chat-Antwort einen **interaktiven Editor** (WP10), in dem der Entwurf finalisiert werden kann.
|
||||
|
||||
---
|
||||
|
||||
## 7) Future Concepts: The Empathic Digital Twin (Ausblick)
|
||||
|
|
@ -401,10 +405,11 @@ Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
|||
- Persönlichkeit & Chat: `config/prompts.yaml` & `app/routers/chat.py`.
|
||||
- Decision Engine: `config/decision_engine.yaml`.
|
||||
- Logging Service: `app/services/feedback_service.py`.
|
||||
- Frontend UI: `app/frontend/ui.py`.
|
||||
|
||||
---
|
||||
|
||||
## 16) Workpackage Status (v2.3.2)
|
||||
## 16) Workpackage Status (v2.4.0)
|
||||
|
||||
Aktueller Implementierungsstand der Module.
|
||||
|
||||
|
|
@ -418,7 +423,7 @@ Aktueller Implementierungsstand der Module.
|
|||
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
|
||||
| **WP06** | Decision Engine | 🟢 Live | Intent-Router & Strategic Retrieval. |
|
||||
| **WP07** | Interview Assistent | 🟡 Geplant | Dialog-Modus (Nächster Schritt). |
|
||||
| **WP07** | Interview Assistent | 🟢 Live | **One-Shot Extractor & Schemas aktiv.** |
|
||||
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
||||
| **WP10** | Chat Interface | 🟢 Live | Web-UI mit Feedback & Intents. |
|
||||
| **WP10a**| GUI Evolution | 🔴 Geplant | Erweiterte Interaktion. |
|
||||
| **WP10a**| Draft Editor | 🟢 Live | **Interaktiver Editor für WP07 Drafts.** |
|
||||
|
|
@ -1,17 +1,17 @@
|
|||
# Mindnet v2.2 – Technische Architektur
|
||||
**Datei:** `docs/mindnet_technical_architecture_v2.2.md`
|
||||
# Mindnet v2.4 – Technische Architektur
|
||||
**Datei:** `docs/mindnet_technical_architecture_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10)
|
||||
**Status:** **FINAL** (Integrierter Stand WP01–WP10 + WP07)
|
||||
**Quellen:** `Programmplan_V2.2.md`, `Handbuch.md`, `chunking_strategy.md`, `wp04_retriever_scoring.md`.
|
||||
|
||||
> **Ziel dieses Dokuments:**
|
||||
> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik, der **neuen RAG-Komponenten (Decision Engine & Hybrid Router)** und dem **Frontend (Streamlit)**.
|
||||
> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik, der **RAG-Komponenten (Decision Engine & Hybrid Router)**, des **Interview-Modus** und dem **Frontend (Streamlit)**.
|
||||
|
||||
---
|
||||
<details>
|
||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
||||
|
||||
- [Mindnet v2.2 – Technische Architektur](#mindnet-v22--technische-architektur)
|
||||
- [Mindnet v2.4 – Technische Architektur](#mindnet-v24--technische-architektur)
|
||||
- [](#)
|
||||
- [1. Systemüberblick](#1-systemüberblick)
|
||||
- [1.1 Architektur-Zielbild](#11-architektur-zielbild)
|
||||
|
|
@ -33,16 +33,17 @@
|
|||
- [5.2 Scoring-Formel (WP04a)](#52-scoring-formel-wp04a)
|
||||
- [5.3 Explanation Layer (WP04b)](#53-explanation-layer-wp04b)
|
||||
- [5.4 Graph-Expansion](#54-graph-expansion)
|
||||
- [6. RAG \& Chat Architektur (WP06 Hybrid Router)](#6-rag--chat-architektur-wp06-hybrid-router)
|
||||
- [6. RAG \& Chat Architektur (WP06 Hybrid Router + WP07 Interview)](#6-rag--chat-architektur-wp06-hybrid-router--wp07-interview)
|
||||
- [6.1 Architektur-Pattern: Intent Router](#61-architektur-pattern-intent-router)
|
||||
- [6.2 Schritt 1: Intent Detection (Hybrid)](#62-schritt-1-intent-detection-hybrid)
|
||||
- [6.3 Schritt 2: Strategy Resolution (Late Binding)](#63-schritt-2-strategy-resolution-late-binding)
|
||||
- [6.4 Schritt 3: Multi-Stage Retrieval](#64-schritt-3-multi-stage-retrieval)
|
||||
- [6.4 Schritt 3: Retrieval vs. Extraction](#64-schritt-3-retrieval-vs-extraction)
|
||||
- [6.5 Schritt 4: Generation \& Response](#65-schritt-4-generation--response)
|
||||
- [7. Frontend Architektur (WP10)](#7-frontend-architektur-wp10)
|
||||
- [7.1 Kommunikation](#71-kommunikation)
|
||||
- [7.2 Features \& UI-Logik](#72-features--ui-logik)
|
||||
- [7.3 Deployment Ports](#73-deployment-ports)
|
||||
- [7.3 Draft-Editor \& Sanitizer (Neu in WP10a)](#73-draft-editor--sanitizer-neu-in-wp10a)
|
||||
- [7.4 Deployment Ports](#74-deployment-ports)
|
||||
- [8. Feedback \& Logging Architektur (WP04c)](#8-feedback--logging-architektur-wp04c)
|
||||
- [8.1 Komponenten](#81-komponenten)
|
||||
- [8.2 Log-Dateien](#82-log-dateien)
|
||||
|
|
@ -64,7 +65,7 @@ Mindnet ist ein **lokales RAG-System (Retrieval Augmented Generation)** mit Web-
|
|||
* **Qdrant:** Vektor-Datenbank für Graph und Semantik (Collections: notes, chunks, edges).
|
||||
* **Local Files (JSONL):** Append-Only Logs für Feedback und Search-History (Data Flywheel).
|
||||
4. **Backend:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit.
|
||||
5. **Frontend:** Streamlit-App (`ui.py`) für Interaktion und Visualisierung.
|
||||
5. **Frontend:** Streamlit-App (`ui.py`) für Interaktion und Visualisierung inkl. **Draft Editor**.
|
||||
6. **Inference:** Lokales LLM (Ollama: Phi-3 Mini) für RAG-Chat und Antwortgenerierung.
|
||||
|
||||
Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsgetrieben** (`types.yaml`, `retriever.yaml`, `decision_engine.yaml`, `prompts.yaml`).
|
||||
|
|
@ -87,7 +88,7 @@ Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsge
|
|||
│ ├── models/ # Pydantic DTOs
|
||||
│ ├── routers/
|
||||
│ │ ├── query.py # Such-Endpunkt
|
||||
│ │ ├── chat.py # Hybrid Router & Decision Engine (WP06)
|
||||
│ │ ├── chat.py # Hybrid Router & Interview Logic (WP06/07)
|
||||
│ │ ├── feedback.py # Feedback-Endpunkt (WP04c)
|
||||
│ │ └── ...
|
||||
│ ├── services/
|
||||
|
|
@ -95,11 +96,11 @@ Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsge
|
|||
│ │ ├── feedback_service.py # JSONL Logging (WP04c)
|
||||
│ │ └── embeddings_client.py
|
||||
│ ├── frontend/ # NEU (WP10)
|
||||
│ └── ui.py # Streamlit Application
|
||||
│ └── ui.py # Streamlit Application inkl. Sanitizer
|
||||
├── config/
|
||||
│ ├── types.yaml # Typ-Definitionen (Import-Zeit)
|
||||
│ ├── retriever.yaml # Scoring-Gewichte (Laufzeit)
|
||||
│ ├── decision_engine.yaml # Strategien & Keywords (WP06)
|
||||
│ ├── decision_engine.yaml # Strategien & Schemas (WP06/WP07)
|
||||
│ └── prompts.yaml # LLM System-Prompts & Templates (WP06)
|
||||
├── data/
|
||||
│ └── logs/ # Lokale JSONL-Logs (WP04c)
|
||||
|
|
@ -193,14 +194,14 @@ Steuert das Scoring zur Laufzeit (WP04a).
|
|||
centrality_weight: 0.5
|
||||
|
||||
### 3.3 Decision Engine (`config/decision_engine.yaml`)
|
||||
**Neu in WP06:** Steuert den Intent-Router.
|
||||
* Definiert Strategien (`DECISION`, `EMPATHY`, `CODING`, `FACT`).
|
||||
* Definiert `trigger_keywords` und `inject_types` (Late Binding).
|
||||
**Neu in WP06/07:** Steuert den Intent-Router und die Interview-Schemas.
|
||||
* Definiert Strategien (`DECISION`, `INTERVIEW`, etc.).
|
||||
* Definiert `schemas` für den Interview-Modus (Pflichtfelder pro Typ).
|
||||
* Definiert LLM-Router-Settings (`llm_fallback_enabled`).
|
||||
|
||||
### 3.4 Prompts (`config/prompts.yaml`)
|
||||
Steuert die LLM-Persönlichkeit und Templates.
|
||||
* Enthält Templates für alle Strategien (z.B. `decision_template`, `empathy_template`, `technical_template`).
|
||||
* Enthält Templates für alle Strategien inkl. `interview_template` mit One-Shot Logik.
|
||||
|
||||
### 3.5 Environment (`.env`)
|
||||
Erweiterung für LLM-Steuerung:
|
||||
|
|
@ -273,7 +274,7 @@ Der Hybrid-Modus lädt dynamisch die Nachbarschaft der Top-K Vektor-Treffer ("Se
|
|||
|
||||
---
|
||||
|
||||
## 6. RAG & Chat Architektur (WP06 Hybrid Router)
|
||||
## 6. RAG & Chat Architektur (WP06 Hybrid Router + WP07 Interview)
|
||||
|
||||
Der Flow für eine Chat-Anfrage (`/chat`) wurde in WP06 auf eine **Configuration-Driven Architecture** umgestellt. Der `ChatRouter` (`app/routers/chat.py`) fungiert als zentraler Dispatcher.
|
||||
|
||||
|
|
@ -295,46 +296,61 @@ Der Router ermittelt die Absicht (`Intent`) des Nutzers.
|
|||
* Nur aktiv, wenn `llm_fallback_enabled: true`.
|
||||
* Greift, wenn keine Keywords gefunden wurden.
|
||||
* Sendet die Query an das LLM mit einem Klassifizierungs-Prompt (`llm_router_prompt`).
|
||||
* Ergebnis: `EMPATHY`, `DECISION`, `CODING` oder `FACT` (Default).
|
||||
* Ergebnis: `EMPATHY`, `DECISION`, `INTERVIEW`, `CODING` oder `FACT`.
|
||||
|
||||
### 6.3 Schritt 2: Strategy Resolution (Late Binding)
|
||||
Basierend auf dem Intent lädt der Router die Parameter:
|
||||
* **inject_types:** Liste der Notiz-Typen, die erzwungen werden sollen (z.B. `["value", "goal"]` bei `DECISION`).
|
||||
* **prompt_template:** Schlüssel für das Template in `prompts.yaml` (z.B. `decision_template`, `empathy_template`).
|
||||
* **Bei RAG (FACT/DECISION):** `inject_types` für Strategic Retrieval.
|
||||
* **Bei INTERVIEW (WP07):** `schemas` (Pflichtfelder) basierend auf der erkannten Ziel-Entität (`_detect_target_type`).
|
||||
|
||||
### 6.4 Schritt 3: Multi-Stage Retrieval
|
||||
1. **Primary Retrieval:** Hybride Suche nach der User-Query (findet Fakten).
|
||||
### 6.4 Schritt 3: Retrieval vs. Extraction
|
||||
Der Router verzweigt hier:
|
||||
|
||||
**A) RAG Modus (FACT, DECISION, EMPATHY):**
|
||||
1. **Primary Retrieval:** Hybride Suche nach der User-Query.
|
||||
2. **Strategic Retrieval (Conditional):** Wenn `inject_types` definiert sind, erfolgt eine zweite Suche, die explizit auf diese Typen filtert.
|
||||
3. **Merge:** Ergebnisse werden dedupliziert zusammengeführt.
|
||||
|
||||
**B) Interview Modus (INTERVIEW):**
|
||||
1. **Kein Retrieval:** Der Kontext ist der Chat-Verlauf (oder initial die Query).
|
||||
2. **Schema Injection:** Das Schema für den erkannten Typ (z.B. "Project") wird geladen.
|
||||
3. **Prompt Assembly:** Der `interview_template` Prompt wird mit der Schema-Definition ("Ziel", "Status") gefüllt.
|
||||
|
||||
### 6.5 Schritt 4: Generation & Response
|
||||
* **Context Enrichment:** Metadaten (`[VALUE]`, `[GOAL]`, `[SCORE]`) werden in den Context-String injiziert, um dem LLM die Rolle des Textstücks zu signalisieren.
|
||||
* **Templating:** Das LLM erhält den Prompt basierend auf dem gewählten Template.
|
||||
* **Execution:** Der `LLMService` führt den Call aus. Ein konfigurierbarer Timeout (`MINDNET_LLM_TIMEOUT`) fängt Cold-Start-Verzögerungen auf CPU-Hardware ab.
|
||||
* **Response:** Rückgabe enthält Antworttext, Quellenliste und den erkannten `intent` (für Debugging/Frontend).
|
||||
* **Response:** Rückgabe enthält Antworttext (im Interview-Modus: Markdown Codeblock), Quellenliste und den erkannten `intent`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Frontend Architektur (WP10)
|
||||
|
||||
Das Frontend ist eine **Streamlit-Anwendung**, die als separater Prozess läuft und via HTTP mit dem Backend kommuniziert.
|
||||
Das Frontend ist eine **Streamlit-Anwendung** (`app/frontend/ui.py`), die als separater Prozess läuft und via HTTP mit dem Backend kommuniziert.
|
||||
|
||||
### 7.1 Kommunikation
|
||||
* **Backend-URL:** Konfiguriert via `MINDNET_API_URL` (Default: `http://localhost:8002`).
|
||||
* **Endpoints:** Nutzt `/chat` für Interaktion und `/feedback` für Bewertungen.
|
||||
* **Resilienz:** Das Frontend implementiert eigene Timeouts (`MINDNET_API_TIMEOUT`, Default 300s), um lange Wartezeiten lokaler LLMs abzufangen.
|
||||
* **Resilienz:** Das Frontend implementiert eigene Timeouts (`MINDNET_API_TIMEOUT`, Default 300s).
|
||||
|
||||
### 7.2 Features & UI-Logik
|
||||
* **State Management:** Session-State speichert Chat-Verlauf und `query_id` für Feedback.
|
||||
* **State Management:** Session-State speichert Chat-Verlauf und `query_id`.
|
||||
* **Visualisierung:**
|
||||
* **Intent Badges:** Zeigt Router-Entscheidung (`DECISION`, `FACT`, etc.) und Quelle (`Keyword` vs. `LLM`).
|
||||
* **Intent Badges:** Zeigt Router-Entscheidung (`DECISION`, `INTERVIEW`, etc.).
|
||||
* **Source Expanders:** Zeigt verwendete Chunks inkl. Score und "Why"-Explanation.
|
||||
* **Sidebar:** Zeigt Suchhistorie (Log-basiert) und Konfiguration.
|
||||
* **Feedback:**
|
||||
* Global (Antwort): 1-5 Sterne Rating.
|
||||
* Granular (Quellen): Faces-Rating (Mapped auf 1-5 Score).
|
||||
|
||||
### 7.3 Deployment Ports
|
||||
### 7.3 Draft-Editor & Sanitizer (Neu in WP10a)
|
||||
Wenn der Intent `INTERVIEW` ist, rendert die UI statt einer Textblase den **Draft-Editor**.
|
||||
|
||||
1. **Parsing:** Die Funktion `parse_markdown_draft` extrahiert den Codeblock aus der LLM-Antwort.
|
||||
2. **Sanitization (`normalize_meta_and_body`):**
|
||||
* Prüft den YAML-Frontmatter auf unerlaubte Felder (Halluzinationen des LLMs).
|
||||
* Verschiebt ungültige Felder (z.B. "Situation") in den Body der Notiz.
|
||||
* Stellt sicher, dass das Markdown valide bleibt.
|
||||
3. **Editor Widget:** `st.text_area` erlaubt das Bearbeiten des Inhalts vor dem Speichern.
|
||||
4. **Action:** Buttons zum Download oder Kopieren des fertigen Markdowns.
|
||||
|
||||
### 7.4 Deployment Ports
|
||||
Zur sauberen Trennung von Prod und Dev laufen Frontend und Backend auf dedizierten Ports:
|
||||
|
||||
| Umgebung | Backend (FastAPI) | Frontend (Streamlit) |
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
# mindnet v2.2 – Pipeline Playbook
|
||||
**Datei:** `docs/mindnet_pipeline_playbook_v2.2.md`
|
||||
# mindnet v2.4 – Pipeline Playbook
|
||||
**Datei:** `docs/mindnet_pipeline_playbook_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Inkl. WP10 Frontend)
|
||||
**Quellen:** `mindnet_v2_implementation_playbook.md`, `Handbuch.md`, `chunking_strategy.md`, `docs_mindnet_retriever.md`, `mindnet_admin_guide_v2.2.md`.
|
||||
**Status:** **FINAL** (Inkl. WP07 Interview & WP10a Editor)
|
||||
**Quellen:** `mindnet_v2_implementation_playbook.md`, `Handbuch.md`, `chunking_strategy.md`, `docs_mindnet_retriever.md`, `mindnet_admin_guide_v2.4.md`.
|
||||
|
||||
---
|
||||
<details>
|
||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
||||
|
||||
- [mindnet v2.2 – Pipeline Playbook](#mindnet-v22--pipeline-playbook)
|
||||
- [mindnet v2.4 – Pipeline Playbook](#mindnet-v24--pipeline-playbook)
|
||||
- [](#)
|
||||
- [1. Zweck \& Einordnung](#1-zweck--einordnung)
|
||||
- [2. Die Import-Pipeline (Runbook)](#2-die-import-pipeline-runbook)
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
- [4.2 Typ-Defaults](#42-typ-defaults)
|
||||
- [5. Retriever, Chat \& Generation (RAG Pipeline)](#5-retriever-chat--generation-rag-pipeline)
|
||||
- [5.1 Retrieval (Hybrid)](#51-retrieval-hybrid)
|
||||
- [5.2 Intent Router (WP06)](#52-intent-router-wp06)
|
||||
- [5.2 Intent Router (WP06/07)](#52-intent-router-wp0607)
|
||||
- [5.3 Context Enrichment](#53-context-enrichment)
|
||||
- [5.4 Generation (LLM)](#54-generation-llm)
|
||||
- [6. Feedback \& Lernen (WP04c)](#6-feedback--lernen-wp04c)
|
||||
|
|
@ -33,18 +33,18 @@
|
|||
- [7.2 Smoke-Test (E2E)](#72-smoke-test-e2e)
|
||||
- [8. Ausblick \& Roadmap (Technische Skizzen)](#8-ausblick--roadmap-technische-skizzen)
|
||||
- [8.1 WP-08: Self-Tuning (Skizze)](#81-wp-08-self-tuning-skizze)
|
||||
- [16. Workpackage Status (v2.3.2)](#16-workpackage-status-v232)
|
||||
- [16. Workpackage Status (v2.4.0)](#16-workpackage-status-v240)
|
||||
|
||||
</details>
|
||||
---
|
||||
|
||||
## 1. Zweck & Einordnung
|
||||
|
||||
Dieses Playbook ist das zentrale operative Handbuch für die **mindnet-Pipeline**. Es beschreibt, wie Daten vom Markdown-Vault in den Wissensgraphen (Qdrant) gelangen, wie der Retriever betrieben wird und wie die **RAG-Generierung** (inkl. Decision Engine) funktioniert.
|
||||
Dieses Playbook ist das zentrale operative Handbuch für die **mindnet-Pipeline**. Es beschreibt, wie Daten vom Markdown-Vault in den Wissensgraphen (Qdrant) gelangen, wie der Retriever betrieben wird und wie die **RAG-Generierung** (inkl. Decision Engine & Interviewer) funktioniert.
|
||||
|
||||
**Zielgruppe:** Dev/Ops, Tech-Leads.
|
||||
**Scope:**
|
||||
* **Ist-Stand (WP01–WP10):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat (Hybrid Router), Feedback Loop, Frontend.
|
||||
* **Ist-Stand (WP01–WP10a):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat (Hybrid Router), Feedback Loop, Frontend, Draft Editor.
|
||||
* **Roadmap (Ausblick):** Technische Skizze für Self-Tuning (WP08).
|
||||
|
||||
---
|
||||
|
|
@ -156,22 +156,26 @@ Der Datenfluss endet nicht beim Finden. Er geht weiter bis zur Antwort.
|
|||
### 5.1 Retrieval (Hybrid)
|
||||
Der `/chat` Endpunkt nutzt **Hybrid Retrieval** (Semantic + Graph), um auch logisch verbundene, aber textlich unterschiedliche Notizen zu finden (z.B. Decisions zu einem Projekt).
|
||||
|
||||
### 5.2 Intent Router (WP06)
|
||||
### 5.2 Intent Router (WP06/07)
|
||||
Der Request durchläuft den **Hybrid Router**:
|
||||
1. **Fast Path:** Prüfung auf `trigger_keywords` aus `decision_engine.yaml`.
|
||||
2. **Slow Path:** Falls kein Keyword matched und `llm_fallback_enabled=true`, klassifiziert das LLM den Intent (`DECISION`, `EMPATHY`, `FACT`, `CODING`).
|
||||
3. **Result:** Auswahl der Strategie und der `inject_types` (z.B. Values & Goals).
|
||||
2. **Slow Path:** Falls kein Keyword matched und `llm_fallback_enabled=true`, klassifiziert das LLM den Intent.
|
||||
* `FACT`: Wissen abfragen.
|
||||
* `DECISION`: Rat suchen.
|
||||
* `EMPATHY`: Trost suchen.
|
||||
* `INTERVIEW`: Wissen eingeben (Neu in WP07).
|
||||
3. **Result:** Auswahl der Strategie und der `inject_types` oder `schemas`.
|
||||
|
||||
### 5.3 Context Enrichment
|
||||
Der Router (`chat.py`) reichert die gefundenen Chunks mit Metadaten an:
|
||||
* **Typ-Injection:** `[DECISION]`, `[PROJECT]`.
|
||||
* **Reasoning-Infos:** `(Score: 0.75)`.
|
||||
* **Zweck:** Ermöglicht kleinen Modellen (Phi-3) das Erkennen von logischen Rollen ("Warum?" vs "Was?").
|
||||
|
||||
### 5.4 Generation (LLM)
|
||||
* **Engine:** Ollama (lokal).
|
||||
* **Modell:** `phi3:mini` (Standard).
|
||||
* **Prompting:** Template wird basierend auf Intent gewählt (`decision_template` vs `empathy_template`).
|
||||
* **Prompting:** Template wird basierend auf Intent gewählt (`decision_template`, `interview_template` etc.).
|
||||
* **One-Shot (WP07):** Im Interview-Modus generiert das LLM direkt einen Markdown-Block ohne Rückfragen.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -208,6 +212,9 @@ Prüft am laufenden System (Prod oder Dev), ob Semantik, Graph und Feedback funk
|
|||
# Decision Engine Test (WP06)
|
||||
python tests/test_wp06_decision.py -p 8002 -e EMPATHY -q "Alles ist grau"
|
||||
|
||||
# Interview Test (WP07)
|
||||
python tests/test_wp06_decision.py -p 8002 -e INTERVIEW -q "Neues Projekt starten"
|
||||
|
||||
# Feedback Test
|
||||
python tests/test_feedback_smoke.py --url http://localhost:8001/query
|
||||
|
||||
|
|
@ -226,7 +233,7 @@ Wie entwickeln wir die Pipeline weiter?
|
|||
|
||||
---
|
||||
|
||||
## 16. Workpackage Status (v2.3.2)
|
||||
## 16. Workpackage Status (v2.4.0)
|
||||
|
||||
Aktueller Implementierungsstand der Module.
|
||||
|
||||
|
|
@ -240,7 +247,7 @@ Aktueller Implementierungsstand der Module.
|
|||
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
|
||||
| **WP06** | Decision Engine | 🟢 Live | Hybrid Router, Strategic Retrieval. |
|
||||
| **WP07** | Interview Assistent | 🟡 Geplant | Nächster Schritt (Dialog-Modus). |
|
||||
| **WP07** | Interview Assistent | 🟢 Live | **One-Shot Extractor & Schemas aktiv.** |
|
||||
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
||||
| **WP10** | Chat Interface | 🟢 Live | Streamlit Web-UI mit Feedback & Intents. |
|
||||
| **WP10a**| GUI Evolution | 🔴 Geplant | Draft-Editor & Interaktionstools. |
|
||||
| **WP10** | Chat Interface | 🟢 Live | Web-Interface (Streamlit). |
|
||||
| **WP10a**| Draft Editor | 🟢 Live | **Interaktives UI für WP07 Drafts.** |
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
# Mindnet v2.2 – User Guide
|
||||
**Datei:** `docs/mindnet_user_guide_v2.2.md`
|
||||
# Mindnet v2.4 – User Guide
|
||||
**Datei:** `docs/mindnet_user_guide_v2.4.md`
|
||||
**Stand:** 2025-12-10
|
||||
**Status:** **FINAL** (Inkl. RAG & Web-Interface)
|
||||
**Status:** **FINAL** (Inkl. RAG, Web-Interface & Interview-Assistent)
|
||||
**Quellen:** `knowledge_design.md`, `wp04_retriever_scoring.md`, `Programmplan_V2.2.md`, `Handbuch.md`.
|
||||
|
||||
> **Willkommen bei Mindnet.**
|
||||
> Dies ist dein persönliches Wissensnetzwerk und dein Digitaler Zwilling. Es hilft dir beim Erinnern, beim Entscheiden und beim Reflektieren.
|
||||
> Dies ist dein persönliches Wissensnetzwerk und dein Digitaler Zwilling. Es hilft dir beim Erinnern, beim Entscheiden, beim Reflektieren und beim **Erstellen von Inhalten**.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -24,7 +24,7 @@ Mindnet passt seinen Charakter dynamisch an deine Frage an:
|
|||
1. **Der Bibliothekar (FACT):** Liefert präzise Fakten und Definitionen.
|
||||
2. **Der Berater (DECISION):** Hilft dir beim Abwägen, basierend auf deinen Werten und Zielen.
|
||||
3. **Der Spiegel (EMPATHY):** Hört zu und antwortet basierend auf deinen Erfahrungen ("Ich"-Perspektive).
|
||||
4. **Der Coder (CODING):** Liefert technische Schnipsel ohne Smalltalk.
|
||||
4. **Der Analyst (INTERVIEW):** Hilft dir, neue Notizen zu entwerfen und strukturiert zu erfassen.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -41,7 +41,7 @@ Seit Version 2.3.1 bedienst du Mindnet über eine grafische Oberfläche im Brows
|
|||
* **Klick darauf:** Zeigt den Textauszug und die **Begründung** ("Warum wurde das gefunden?").
|
||||
|
||||
### 2.2 Die Sidebar (Einstellungen & Verlauf)
|
||||
* **Modus-Wahl:** Umschalten zwischen "💬 Chat" und "📝 Neuer Eintrag" (Vorbereitung für WP07).
|
||||
* **Modus-Wahl:** Umschalten zwischen "💬 Chat" und "📝 Manueller Editor".
|
||||
* **Verlauf:** Die letzten Suchanfragen sind hier gelistet. Ein Klick führt die Suche erneut aus.
|
||||
* **Settings:**
|
||||
* **Top-K:** Wie viele Quellen sollen gelesen werden? (Standard: 5).
|
||||
|
|
@ -68,9 +68,11 @@ Wenn du frustriert bist oder reflektieren willst, wechselt Mindnet in den "Ich"-
|
|||
* **Auslöser (Keywords & Semantik):** "Ich fühle mich...", "Traurig", "Gestresst", "Alles ist sinnlos", "Ich bin überfordert".
|
||||
* **Was passiert:** Mindnet lädt deine **Erfahrungen** (`type: experience`) und **Glaubenssätze** (`type: belief`). Es antwortet verständnisvoll und zitiert deine eigenen Lektionen.
|
||||
|
||||
### 3.3 Modus: Fakten (Standard)
|
||||
* **Auslöser:** Alles andere. "Was ist Qdrant?", "Zusammenfassung von X".
|
||||
* **Was passiert:** Standard-Suche nach Wissen ohne spezielle Filter.
|
||||
### 3.3 Modus: Interview ("Der Analyst") – Neu!
|
||||
Wenn du Wissen festhalten willst, statt zu suchen.
|
||||
|
||||
* **Auslöser:** "Neues Projekt", "Notiz erstellen", "Ich will etwas festhalten", "Neue Entscheidung dokumentieren".
|
||||
* **Was passiert:** Siehe Kapitel 6.3.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -116,3 +118,14 @@ Statt einfach nur `[[Link]]` zu schreiben, versuche zu sagen, *wie* es zusammenh
|
|||
Setze im Frontmatter deiner Notizen den richtigen Typ. Das ist der wichtigste Hebel für den Chat:
|
||||
* Willst du, dass Mindnet etwas als **Regel** nutzt? -> `type: principle`
|
||||
* Willst du, dass Mindnet dich an eine **Lektion** erinnert? -> `type: experience`
|
||||
|
||||
### 6.3 Der Interview-Assistent (Drafting)
|
||||
Mindnet kann dir helfen, Markdown-Notizen zu schreiben.
|
||||
|
||||
1. **Start:** Schreibe im Chat: *"Ich möchte ein neues Projekt 'Apollo' starten, Ziel ist die Mondlandung."*
|
||||
2. **Generierung:** Mindnet erkennt den Wunsch (`INTERVIEW`), analysiert den Satz und erstellt **sofort** einen Entwurf.
|
||||
3. **Editor:** Die UI wechselt von der Chat-Blase zu einem **Draft-Editor**.
|
||||
* Du siehst das generierte Frontmatter (`type: project`, `status: draft`).
|
||||
* Du siehst den Body-Text mit Platzhaltern (`[TODO]`), wo Infos fehlten (z.B. Stakeholder).
|
||||
4. **Finalisierung:** Ergänze die fehlenden Infos direkt im Editor und klicke auf **Download** oder **Kopieren**.
|
||||
5. **Speichern:** Speichere die Datei in deinen Obsidian Vault. Beim nächsten Import ist sie im System.
|
||||
40
tests/test_interview_intent.py
Normal file
40
tests/test_interview_intent.py
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import requests
|
||||
import sys
|
||||
|
||||
API_URL = "http://localhost:8002/chat/"
|
||||
|
||||
def test_intent(message):
|
||||
print(f"📡 Sende: '{message}' ...")
|
||||
payload = {
|
||||
"message": message,
|
||||
"top_k": 0,
|
||||
"explain": False
|
||||
}
|
||||
|
||||
try:
|
||||
# Timeout nach 30 Sekunden erzwingen
|
||||
response = requests.post(API_URL, json=payload, timeout=30)
|
||||
|
||||
if response.status_code != 200:
|
||||
print(f"❌ Server Error {response.status_code}: {response.text}")
|
||||
return
|
||||
|
||||
data = response.json()
|
||||
intent = data.get("intent")
|
||||
source = data.get("intent_source")
|
||||
answer = data.get("answer")
|
||||
|
||||
print(f"✅ Ergebnis erhalten:")
|
||||
print(f" Intent: {intent} (Quelle: {source})")
|
||||
print(f" Antwort: {answer[:100]}...") # Nur die ersten 100 Zeichen
|
||||
print("-" * 40)
|
||||
|
||||
except requests.exceptions.Timeout:
|
||||
print("❌ TIMEOUT: Das Backend antwortet nicht innerhalb von 30 Sekunden.")
|
||||
print(" -> Prüfe das Terminal, wo uvicorn läuft. Gibt es dort Fehlermeldungen?")
|
||||
except Exception as e:
|
||||
print(f"❌ Fehler: {e}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Testfall: Muss INTERVIEW auslösen
|
||||
test_intent("Ich möchte ein neues Projekt anlegen")
|
||||
Loading…
Reference in New Issue
Block a user