Merge pull request 'WP06' (#4) from WP06 into main
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
All checks were successful
Deploy mindnet to llm-node / deploy (push) Successful in 3s
feat(wp06): Release v2.3.1 - Decision Engine & Hybrid Intent Router Abschluss von WP-06: Transformation des Chatbots zum strategischen Partner. Hauptänderungen: - Feature: Hybrid Intent Router implementiert (Fast Path: Keywords / Slow Path: LLM-Fallback). - Feature: Strategic Retrieval (Injektion von [VALUE], [GOAL], [EXPERIENCE] basierend auf Intent). - Feature: Multi-Persona Support (Berater, Empathischer Spiegel, Coder, Bibliothekar). - Config: Late Binding Logik komplett in `config/decision_engine.yaml` ausgelagert. - Tech: LLM-Service erweitert um konfigurierbaren Timeout (CPU-Inference Support) und Raw-Generation Mode. - Docs: Vollständige Aktualisierung der Kern-Dokumentation (Architektur, Playbooks, Guides) auf v2.3.1. Version Bump: 2.3.0 -> 2.3.1
This commit is contained in:
commit
86faf5b8f0
|
|
@ -1,8 +1,45 @@
|
||||||
# mindnet v2.2 — Programmplan
|
# mindnet v2.2 — Programmplan
|
||||||
**Version:** 2.3.0 (Post-WP05 RAG Integration)
|
**Version:** 2.3.1 (Post-WP06 Decision Engine)
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** Aktiv
|
**Status:** Aktiv
|
||||||
|
|
||||||
|
---
|
||||||
|
- [mindnet v2.2 — Programmplan](#mindnet-v22--programmplan)
|
||||||
|
- [1. Programmauftrag](#1-programmauftrag)
|
||||||
|
- [2. Vision](#2-vision)
|
||||||
|
- [3. Programmziele](#3-programmziele)
|
||||||
|
- [3.1 Kurzfristig (Abgeschlossen / Laufend)](#31-kurzfristig-abgeschlossen--laufend)
|
||||||
|
- [3.2 Mittelfristig (Nächste Schritte)](#32-mittelfristig-nächste-schritte)
|
||||||
|
- [3.3 Langfristig](#33-langfristig)
|
||||||
|
- [4. Architekturprinzipien](#4-architekturprinzipien)
|
||||||
|
- [5. Programmstruktur (Phasenmodell)](#5-programmstruktur-phasenmodell)
|
||||||
|
- [6. Workpackages – detaillierte Übersicht](#6-workpackages--detaillierte-übersicht)
|
||||||
|
- [Legende Aufwand / Komplexität](#legende-aufwand--komplexität)
|
||||||
|
- [WP-01 – Wissensdesign (abgeschlossen)](#wp-01--wissensdesign-abgeschlossen)
|
||||||
|
- [WP-02 – Chunking \& Hash-Strategie (abgeschlossen)](#wp-02--chunking--hash-strategie-abgeschlossen)
|
||||||
|
- [WP-03 – Import-Pipeline \& Edge-System v2 (abgeschlossen)](#wp-03--import-pipeline--edge-system-v2-abgeschlossen)
|
||||||
|
- [WP-04a – Retriever \& Graph-Scoring (abgeschlossen)](#wp-04a--retriever--graph-scoring-abgeschlossen)
|
||||||
|
- [WP-04b – Explanation Layer ("Why-Layer") (abgeschlossen)](#wp-04b--explanation-layer-why-layer-abgeschlossen)
|
||||||
|
- [WP-04c – Feedback Logging \& Bewertungsdaten (abgeschlossen)](#wp-04c--feedback-logging--bewertungsdaten-abgeschlossen)
|
||||||
|
- [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-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 (geplant)](#wp-10--chat-interface--writeback-geplant)
|
||||||
|
- [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)
|
||||||
|
- [WP-14 – Review / Refactoring / Dokumentation (geplant)](#wp-14--review--refactoring--dokumentation-geplant)
|
||||||
|
- [7. Abhängigkeiten (vereinfacht, aktualisiert)](#7-abhängigkeiten-vereinfacht-aktualisiert)
|
||||||
|
- [8. Laufzeit- \& Komplexitätsindikatoren (aktualisiert)](#8-laufzeit---komplexitätsindikatoren-aktualisiert)
|
||||||
|
- [9. Programmfortschritt (Ampel, aktualisiert)](#9-programmfortschritt-ampel-aktualisiert)
|
||||||
|
- [10. Governance \& Versionierung](#10-governance--versionierung)
|
||||||
|
- [11. Executive Summary](#11-executive-summary)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Programmauftrag
|
## 1. Programmauftrag
|
||||||
|
|
@ -14,7 +51,7 @@ mindnet v2.2 entwickelt ein persönliches, wachsendes KI-Gedächtnis, das:
|
||||||
- einen KI-Zwilling aufbaut, der ähnlich argumentiert, entscheidet und reflektiert wie du,
|
- einen KI-Zwilling aufbaut, der ähnlich argumentiert, entscheidet und reflektiert wie du,
|
||||||
- über mehrere Kanäle gefüttert wird:
|
- über mehrere Kanäle gefüttert wird:
|
||||||
- Obsidian-Markdown (primäre Quelle),
|
- Obsidian-Markdown (primäre Quelle),
|
||||||
- Chat-basierter Agent (RAG-Chat aktiv),
|
- Chat-basierter Agent (Decision Engine & RAG-Chat aktiv),
|
||||||
- später: Interview-Assistent (strukturierte Dialogerfassung),
|
- später: Interview-Assistent (strukturierte Dialogerfassung),
|
||||||
- automatisch neue Zusammenhänge erkennt und vernetzt (Edges, Typen, Hinweise),
|
- automatisch neue Zusammenhänge erkennt und vernetzt (Edges, Typen, Hinweise),
|
||||||
- sich durch Rückmeldungen (Feedback) selbst verbessert (Self-Tuning).
|
- sich durch Rückmeldungen (Feedback) selbst verbessert (Self-Tuning).
|
||||||
|
|
@ -50,7 +87,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.
|
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):**
|
- **Flexibilität (Late Binding):**
|
||||||
Semantik wird überwiegend in Konfiguration (z. B. `types.yaml`, `prompts.yaml`, Policies) festgelegt. Die Persönlichkeit entsteht durch das Prompt-Design, nicht durch Hardcoding.
|
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.
|
||||||
|
|
||||||
- **Autonomie & Self-Healing:**
|
- **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.
|
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.
|
||||||
|
|
@ -59,7 +96,7 @@ Kernprinzipien der Vision:
|
||||||
Feedback zu Antworten (gut/schlecht, relevant/nicht relevant) fließt in Score-Gewichte, Policies und ggf. Edge-Struktur ein.
|
Feedback zu Antworten (gut/schlecht, relevant/nicht relevant) fließt in Score-Gewichte, Policies und ggf. Edge-Struktur ein.
|
||||||
|
|
||||||
- **Persönlichkeit:**
|
- **Persönlichkeit:**
|
||||||
Entscheidungen werden wert- und erfahrungsbasiert begründet; das System agiert als KI-Zwilling durch Nutzung lokaler LLMs (z.B. Phi-3/Mistral).
|
Entscheidungen werden wert- und erfahrungsbasiert begründet; das System agiert als KI-Zwilling durch Nutzung lokaler LLMs (z.B. Phi-3/Mistral) und eines Intent-Routers.
|
||||||
|
|
||||||
- **Incremental Growth:**
|
- **Incremental Growth:**
|
||||||
Das System muss mit wenigen, heterogenen Notizen starten und sich fortlaufend verdichten können – ohne Retro-Massenmigrationen im Vault.
|
Das System muss mit wenigen, heterogenen Notizen starten und sich fortlaufend verdichten können – ohne Retro-Massenmigrationen im Vault.
|
||||||
|
|
@ -76,17 +113,17 @@ Kernprinzipien der Vision:
|
||||||
- **Erklärbarkeit:** Why-Layer liefert Begründungen zu Treffern (WP-04b abgeschlossen).
|
- **Erklärbarkeit:** Why-Layer liefert Begründungen zu Treffern (WP-04b abgeschlossen).
|
||||||
- **Feedback-Loop:** Systematisches Logging von Suche und Bewertung (WP-04c abgeschlossen).
|
- **Feedback-Loop:** Systematisches Logging von Suche und Bewertung (WP-04c abgeschlossen).
|
||||||
- **RAG-Chat:** KI antwortet in natürlicher Sprache auf Basis von Wissen und Persönlichkeit (WP-05 abgeschlossen).
|
- **RAG-Chat:** KI antwortet in natürlicher Sprache auf Basis von Wissen und Persönlichkeit (WP-05 abgeschlossen).
|
||||||
|
- **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).
|
||||||
- Technische Basis: FastAPI, Qdrant, Ollama (Local LLM).
|
- Technische Basis: FastAPI, Qdrant, Ollama (Local LLM).
|
||||||
- Automatisierte Erkennung von Beziehungen:
|
- Automatisierte Erkennung von Beziehungen:
|
||||||
- Wikilinks, Inline-Relationen, Callout-Edges, Typ-Defaults.
|
- Wikilinks, Inline-Relationen, Callout-Edges, Typ-Defaults.
|
||||||
- Schrittweises Lernen über Feedback (Score-Tuning, noch „manuell“ konfiguriert).
|
|
||||||
- „Mitwachsendes“ Schema ohne Obsidian-Umstrukturierungen:
|
- „Mitwachsendes“ Schema ohne Obsidian-Umstrukturierungen:
|
||||||
- Neues Wissen kann sofort erfasst werden,
|
- Neues Wissen kann sofort erfasst werden,
|
||||||
- bestehende Notizen bleiben gültig (Virtual Schema Layer).
|
- bestehende Notizen bleiben gültig (Virtual Schema Layer).
|
||||||
|
|
||||||
### 3.2 Mittelfristig (Nächste Schritte)
|
### 3.2 Mittelfristig (Nächste Schritte)
|
||||||
|
|
||||||
- **Decision Engine (WP-06):** Das System berät aktiv bei Entscheidungen, indem es `type: value` und `type: principle` Notizen gegen eine Fragestellung abwägt.
|
|
||||||
- **Chat Interface (WP-10):** Ablösung der Terminal-Interaktion durch ein Web-Frontend (Streamlit/React) für bessere UX und einfacheres Feedback-Geben.
|
- **Chat Interface (WP-10):** Ablösung der Terminal-Interaktion durch ein Web-Frontend (Streamlit/React) für bessere UX und einfacheres Feedback-Geben.
|
||||||
- Interview-Assistent erstellt neue Notes automatisch (strukturierte Dialoge → Markdown).
|
- Interview-Assistent erstellt neue Notes automatisch (strukturierte Dialoge → Markdown).
|
||||||
- mindnet erzeugt Vorschläge für neue Notes & Edges und bietet einen „Vernetzungs-Assistenten“ für manuell angelegte Notizen.
|
- mindnet erzeugt Vorschläge für neue Notes & Edges und bietet einen „Vernetzungs-Assistenten“ für manuell angelegte Notizen.
|
||||||
|
|
@ -109,7 +146,7 @@ Kernprinzipien der Vision:
|
||||||
Die folgenden Prinzipien steuern alle Workpackages und Entscheidungen:
|
Die folgenden Prinzipien steuern alle Workpackages und Entscheidungen:
|
||||||
|
|
||||||
1. **Late Binding (späte Semantik)**
|
1. **Late Binding (späte Semantik)**
|
||||||
- Struktur und Interpretation werden in Konfigurationen (z. B. `types.yaml`, `prompts.yaml`, Policies) definiert, nicht direkt in den Vault-Dateien.
|
- Struktur und Interpretation werden in Konfigurationen (z. B. `types.yaml`, `prompts.yaml`, `decision_engine.yaml`) definiert, nicht direkt in den Vault-Dateien.
|
||||||
- Die "Persönlichkeit" des Chats ist ein Prompt-Template, kein Code.
|
- Die "Persönlichkeit" des Chats ist ein Prompt-Template, kein Code.
|
||||||
|
|
||||||
2. **Virtual Schema Layer**
|
2. **Virtual Schema Layer**
|
||||||
|
|
@ -151,11 +188,11 @@ Die folgenden Prinzipien steuern alle Workpackages und Entscheidungen:
|
||||||
|
|
||||||
Phase A – Fundament & Import (Fertig)
|
Phase A – Fundament & Import (Fertig)
|
||||||
Phase B – Semantik, Graph & Lernen (Fertig)
|
Phase B – Semantik, Graph & Lernen (Fertig)
|
||||||
Phase C – Persönlichkeitsmodell & KI-Zwilling (Laufend)
|
Phase C – Persönlichkeitsmodell & KI-Zwilling (Fertig)
|
||||||
Phase D – Agenten, MCP & Interaktion (Startend)
|
Phase D – Agenten, MCP & Interaktion (Startend)
|
||||||
Phase E – Review, Refactoring, Dokumentation
|
Phase E – Review, Refactoring, Dokumentation
|
||||||
|
|
||||||
Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-05 sind bereits erfolgreich abgeschlossen.
|
Alle Workpackages sind einer Phase zugeordnet. WP-01 bis WP-06 sind bereits erfolgreich abgeschlossen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -294,18 +331,20 @@ Erweiterung des Chats um Gedächtnis (History) und einfache Tools.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### WP-06 – Decision Engine (geplant)
|
### WP-06 – Decision Engine & Hybrid Router (abgeschlossen)
|
||||||
|
|
||||||
**Phase:** C
|
**Phase:** C
|
||||||
**Status:** 🟡 geplant (Priorität A)
|
**Status:** 🟢 abgeschlossen
|
||||||
|
|
||||||
**Ziel:**
|
**Ziel:**
|
||||||
Entscheidungsunterstützung auf Basis von Wissen, Persönlichkeit und Zielen – inklusive nachvollziehbarer Begründung.
|
Transformation vom reinen Wissens-Abrufer zum strategischen Entscheidungspartner durch Intent-Erkennung.
|
||||||
|
|
||||||
**Umfang:**
|
**Erreichte Ergebnisse:**
|
||||||
- Erweiterung des RAG-Kontexts um gezieltes Nachladen von `type: value` und `type: principle`.
|
- **Hybrid Intent Router:** Kombination aus schnellem Keyword-Matching und intelligentem LLM-Fallback zur Erkennung der Absicht (`DECISION`, `EMPATHY`, `FACT`, `CODING`).
|
||||||
- Prompt-Engineering für "Trade-off Analyse" (Pro/Contra basierend auf Werten).
|
- **Strategic Retrieval:** Gezieltes Nachladen von Werten (`value`), Zielen (`goal`) oder Erfahrungen (`experience`) basierend auf dem Intent.
|
||||||
- Output-Formatierung als Entscheidungsvorlage.
|
- **Multi-Persona:** Dynamische Anpassung des Tonfalls (Berater vs. Spiegel vs. Techniker) durch `prompts.yaml`.
|
||||||
|
- **Late Binding:** Vollständige Konfiguration via `decision_engine.yaml`.
|
||||||
|
- **Robustheit:** Konfigurierbare Timeouts für CPU-Inference.
|
||||||
|
|
||||||
**Aufwand / Komplexität:**
|
**Aufwand / Komplexität:**
|
||||||
- Aufwand: Mittel
|
- Aufwand: Mittel
|
||||||
|
|
@ -488,7 +527,7 @@ Aufräumen, dokumentieren, stabilisieren – insbesondere für Onboarding Dritte
|
||||||
| WP04c | 🟢 |
|
| WP04c | 🟢 |
|
||||||
| WP05 | 🟢 |
|
| WP05 | 🟢 |
|
||||||
| WP05b | ⚪ |
|
| WP05b | ⚪ |
|
||||||
| WP06 | 🟡 |
|
| WP06 | 🟢 |
|
||||||
| WP07 | 🟡 |
|
| WP07 | 🟡 |
|
||||||
| WP08 | 🟡 |
|
| WP08 | 🟡 |
|
||||||
| WP09 | 🟡 |
|
| WP09 | 🟡 |
|
||||||
|
|
@ -519,8 +558,8 @@ mindnet v2.2 ist so aufgesetzt, dass:
|
||||||
- die Struktur **mitwächst**, ohne Retro-Massenarbeit im Vault,
|
- die Struktur **mitwächst**, ohne Retro-Massenarbeit im Vault,
|
||||||
- ein **hybrider Retriever** qualitativ hochwertige, erklärbare Antworten liefert,
|
- ein **hybrider Retriever** qualitativ hochwertige, erklärbare Antworten liefert,
|
||||||
- ein **Self-Healing- und Self-Tuning-Mechanismus** vorbereitet ist (durch WP-04c Feedback-Daten),
|
- ein **Self-Healing- und Self-Tuning-Mechanismus** vorbereitet ist (durch WP-04c Feedback-Daten),
|
||||||
- ein **Persönlichkeitsmodell** und eine **Decision Engine** entstehen,
|
- ein **Persönlichkeitsmodell** (Decision Engine, Empathie) existiert und den Tonfall situativ anpasst,
|
||||||
- langfristig ein **KI-Zwilling** aufgebaut wird, der deine Werte, Erfahrungen und Denkweise spiegelt,
|
- 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.
|
- die technische Architektur (FastAPI, Qdrant, YAML-Policies, MCP-Integration) lokal, nachvollziehbar und erweiterbar bleibt.
|
||||||
|
|
||||||
Dieser Programmplan bildet die konsolidierte Grundlage (v2.3.0) für alle weiteren Arbeiten.
|
Dieser Programmplan bildet die konsolidierte Grundlage (v2.3.1) für alle weiteren Arbeiten.
|
||||||
|
|
@ -1,12 +1,7 @@
|
||||||
"""
|
"""
|
||||||
app/config.py — zentrale Konfiguration (ENV → Settings)
|
app/config.py — zentrale Konfiguration
|
||||||
|
Version: 0.4.0 (WP-06 Complete)
|
||||||
Version:
|
|
||||||
0.3.1 (WP-05: Switch default to Mistral for CPU inference)
|
|
||||||
Stand:
|
|
||||||
2025-12-08
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
import os
|
import os
|
||||||
from functools import lru_cache
|
from functools import lru_cache
|
||||||
|
|
@ -25,9 +20,12 @@ class Settings:
|
||||||
|
|
||||||
# WP-05 LLM / Ollama
|
# WP-05 LLM / Ollama
|
||||||
OLLAMA_URL: str = os.getenv("MINDNET_OLLAMA_URL", "http://127.0.0.1:11434")
|
OLLAMA_URL: str = os.getenv("MINDNET_OLLAMA_URL", "http://127.0.0.1:11434")
|
||||||
# ÄNDERUNG: Standard auf 'mistral' gesetzt, da bereits lokal vorhanden
|
|
||||||
LLM_MODEL: str = os.getenv("MINDNET_LLM_MODEL", "phi3:mini")
|
LLM_MODEL: str = os.getenv("MINDNET_LLM_MODEL", "phi3:mini")
|
||||||
PROMPTS_PATH: str = os.getenv("MINDNET_PROMPTS_PATH", "config/prompts.yaml")
|
PROMPTS_PATH: str = os.getenv("MINDNET_PROMPTS_PATH", "config/prompts.yaml")
|
||||||
|
|
||||||
|
# NEU für WP-06
|
||||||
|
LLM_TIMEOUT: float = float(os.getenv("MINDNET_LLM_TIMEOUT", "120.0"))
|
||||||
|
DECISION_CONFIG_PATH: str = os.getenv("MINDNET_DECISION_CONFIG", "config/decision_engine.yaml")
|
||||||
|
|
||||||
# API
|
# API
|
||||||
DEBUG: bool = os.getenv("DEBUG", "false").lower() == "true"
|
DEBUG: bool = os.getenv("DEBUG", "false").lower() == "true"
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
"""
|
"""
|
||||||
app/models/dto.py — Pydantic-Modelle (DTOs) für WP-04/WP-05 Endpunkte
|
app/models/dto.py — Pydantic-Modelle (DTOs) für WP-04/WP-05/WP-06
|
||||||
|
|
||||||
Zweck:
|
Zweck:
|
||||||
Laufzeit-Modelle für FastAPI (Requests/Responses).
|
Laufzeit-Modelle für FastAPI (Requests/Responses).
|
||||||
WP-05 Update: Chat-Modelle.
|
WP-06 Update: Intent in ChatResponse.
|
||||||
|
|
||||||
Version:
|
Version:
|
||||||
0.4.0 (Update für WP-05 Chat)
|
0.6.0 (WP-06: Decision Engine)
|
||||||
Stand:
|
Stand:
|
||||||
2025-12-08
|
2025-12-08
|
||||||
"""
|
"""
|
||||||
|
|
@ -144,9 +144,10 @@ class GraphResponse(BaseModel):
|
||||||
|
|
||||||
class ChatResponse(BaseModel):
|
class ChatResponse(BaseModel):
|
||||||
"""
|
"""
|
||||||
WP-05: Antwortstruktur für /chat.
|
WP-05/06: Antwortstruktur für /chat.
|
||||||
"""
|
"""
|
||||||
query_id: str = Field(..., description="Traceability ID (dieselbe wie für Search)")
|
query_id: str = Field(..., description="Traceability ID (dieselbe wie für Search)")
|
||||||
answer: str = Field(..., description="Generierte Antwort vom LLM")
|
answer: str = Field(..., description="Generierte Antwort vom LLM")
|
||||||
sources: List[QueryHit] = Field(..., description="Die für die Antwort genutzten Quellen")
|
sources: List[QueryHit] = Field(..., description="Die für die Antwort genutzten Quellen")
|
||||||
latency_ms: int
|
latency_ms: int
|
||||||
|
intent: Optional[str] = Field("FACT", description="WP-06: Erkannter Intent (FACT/DECISION)")
|
||||||
|
|
@ -1,18 +1,17 @@
|
||||||
"""
|
"""
|
||||||
app/routers/chat.py — RAG Endpunkt (WP-05 Final Audit Version)
|
app/routers/chat.py — RAG Endpunkt (WP-06 Hybrid Router v2)
|
||||||
|
Update: Robusteres LLM-Parsing für Small Language Models (SLMs).
|
||||||
Zweck:
|
|
||||||
Verbindet Retrieval mit LLM-Generation.
|
|
||||||
Enriched Context: Fügt Typen und Metadaten in den Prompt ein,
|
|
||||||
damit das LLM komplexe Zusammenhänge (z.B. Decisions) versteht.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from fastapi import APIRouter, HTTPException, Depends
|
from fastapi import APIRouter, HTTPException, Depends
|
||||||
from typing import List
|
from typing import List, Dict, Any
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import logging
|
import logging
|
||||||
|
import yaml
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from app.config import get_settings
|
||||||
from app.models.dto import ChatRequest, ChatResponse, QueryRequest, QueryHit
|
from app.models.dto import ChatRequest, ChatResponse, QueryRequest, QueryHit
|
||||||
from app.services.llm_service import LLMService
|
from app.services.llm_service import LLMService
|
||||||
from app.core.retriever import Retriever
|
from app.core.retriever import Retriever
|
||||||
|
|
@ -20,38 +19,65 @@ from app.core.retriever import Retriever
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# --- Helper: Config Loader ---
|
||||||
|
|
||||||
|
_DECISION_CONFIG_CACHE = None
|
||||||
|
|
||||||
|
def _load_decision_config() -> Dict[str, Any]:
|
||||||
|
settings = get_settings()
|
||||||
|
path = Path(settings.DECISION_CONFIG_PATH)
|
||||||
|
default_config = {
|
||||||
|
"strategies": {
|
||||||
|
"FACT": {"trigger_keywords": []}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if not path.exists():
|
||||||
|
logger.warning(f"Decision config not found at {path}, using defaults.")
|
||||||
|
return default_config
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
|
return yaml.safe_load(f)
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to load decision config: {e}")
|
||||||
|
return default_config
|
||||||
|
|
||||||
|
def get_full_config() -> Dict[str, Any]:
|
||||||
|
global _DECISION_CONFIG_CACHE
|
||||||
|
if _DECISION_CONFIG_CACHE is None:
|
||||||
|
_DECISION_CONFIG_CACHE = _load_decision_config()
|
||||||
|
return _DECISION_CONFIG_CACHE
|
||||||
|
|
||||||
|
def get_decision_strategy(intent: str) -> Dict[str, Any]:
|
||||||
|
config = get_full_config()
|
||||||
|
strategies = config.get("strategies", {})
|
||||||
|
return strategies.get(intent, strategies.get("FACT", {}))
|
||||||
|
|
||||||
|
|
||||||
|
# --- Dependencies ---
|
||||||
|
|
||||||
def get_llm_service():
|
def get_llm_service():
|
||||||
return LLMService()
|
return LLMService()
|
||||||
|
|
||||||
def get_retriever():
|
def get_retriever():
|
||||||
return Retriever()
|
return Retriever()
|
||||||
|
|
||||||
|
|
||||||
|
# --- Logic ---
|
||||||
|
|
||||||
def _build_enriched_context(hits: List[QueryHit]) -> str:
|
def _build_enriched_context(hits: List[QueryHit]) -> str:
|
||||||
"""
|
|
||||||
Baut einen 'Rich Context' String.
|
|
||||||
Statt nur Text, injizieren wir Metadaten (Typ, Tags), damit das LLM
|
|
||||||
die semantische Rolle des Schnipsels versteht.
|
|
||||||
"""
|
|
||||||
context_parts = []
|
context_parts = []
|
||||||
|
|
||||||
for i, hit in enumerate(hits, 1):
|
for i, hit in enumerate(hits, 1):
|
||||||
source = hit.source or {}
|
source = hit.source or {}
|
||||||
|
|
||||||
# 1. Content extrahieren (Robust: prüft alle üblichen Felder)
|
|
||||||
content = (
|
content = (
|
||||||
source.get("text") or
|
source.get("text") or source.get("content") or
|
||||||
source.get("content") or
|
source.get("page_content") or source.get("chunk_text") or
|
||||||
source.get("page_content") or
|
"[Kein Text]"
|
||||||
source.get("chunk_text") or
|
|
||||||
"[Kein Textinhalt verfügbar]"
|
|
||||||
)
|
)
|
||||||
|
title = hit.note_id or "Unbekannt"
|
||||||
# 2. Metadaten für "Context Intelligence"
|
|
||||||
title = hit.note_id or "Unbekannte Notiz"
|
|
||||||
# Typ in Großbuchstaben (z.B. "DECISION"), damit das LLM es als Signal erkennt
|
|
||||||
note_type = source.get("type", "unknown").upper()
|
note_type = source.get("type", "unknown").upper()
|
||||||
|
|
||||||
# 3. Formatierung als strukturiertes Dokument für das LLM
|
|
||||||
entry = (
|
entry = (
|
||||||
f"### QUELLE {i}: {title}\n"
|
f"### QUELLE {i}: {title}\n"
|
||||||
f"TYP: [{note_type}] (Score: {hit.total_score:.2f})\n"
|
f"TYP: [{note_type}] (Score: {hit.total_score:.2f})\n"
|
||||||
|
|
@ -61,6 +87,71 @@ def _build_enriched_context(hits: List[QueryHit]) -> str:
|
||||||
|
|
||||||
return "\n\n".join(context_parts)
|
return "\n\n".join(context_parts)
|
||||||
|
|
||||||
|
async def _classify_intent(query: str, llm: LLMService) -> str:
|
||||||
|
"""
|
||||||
|
Hybrid Router v2:
|
||||||
|
1. Keyword Check (Best/Longest Match) -> FAST
|
||||||
|
2. LLM Fallback (Robust Parsing) -> SMART
|
||||||
|
"""
|
||||||
|
config = get_full_config()
|
||||||
|
strategies = config.get("strategies", {})
|
||||||
|
settings = config.get("settings", {})
|
||||||
|
|
||||||
|
query_lower = query.lower()
|
||||||
|
best_intent = None
|
||||||
|
max_match_length = 0
|
||||||
|
|
||||||
|
# 1. FAST PATH: Keywords
|
||||||
|
for intent_name, strategy in strategies.items():
|
||||||
|
if intent_name == "FACT": continue
|
||||||
|
keywords = strategy.get("trigger_keywords", [])
|
||||||
|
for k in keywords:
|
||||||
|
if k.lower() in query_lower:
|
||||||
|
if len(k) > max_match_length:
|
||||||
|
max_match_length = len(k)
|
||||||
|
best_intent = intent_name
|
||||||
|
|
||||||
|
if best_intent:
|
||||||
|
logger.info(f"Intent detected via KEYWORD: {best_intent}")
|
||||||
|
return best_intent
|
||||||
|
|
||||||
|
# 2. SLOW PATH: LLM Router
|
||||||
|
if settings.get("llm_fallback_enabled", False):
|
||||||
|
router_prompt_template = settings.get("llm_router_prompt", "")
|
||||||
|
if router_prompt_template:
|
||||||
|
prompt = router_prompt_template.replace("{query}", query)
|
||||||
|
logger.info("Keywords failed. Asking LLM for Intent...")
|
||||||
|
|
||||||
|
# Kurzer Raw Call
|
||||||
|
raw_response = await llm.generate_raw_response(prompt)
|
||||||
|
|
||||||
|
# --- Robust Parsing für SLMs ---
|
||||||
|
# Wir suchen nach den bekannten Strategie-Namen im Output
|
||||||
|
llm_output_upper = raw_response.upper()
|
||||||
|
logger.info(f"LLM Router Raw Output: '{raw_response}'") # Debugging
|
||||||
|
|
||||||
|
found_intents = []
|
||||||
|
for strat_key in strategies.keys():
|
||||||
|
# Wir prüfen, ob der Strategie-Name (z.B. "EMPATHY") im Text vorkommt
|
||||||
|
if strat_key in llm_output_upper:
|
||||||
|
found_intents.append(strat_key)
|
||||||
|
|
||||||
|
# Entscheidung
|
||||||
|
final_intent = "FACT"
|
||||||
|
if len(found_intents) == 1:
|
||||||
|
# Eindeutiger Treffer
|
||||||
|
final_intent = found_intents[0]
|
||||||
|
logger.info(f"Intent detected via LLM (Parsed): {final_intent}")
|
||||||
|
return final_intent
|
||||||
|
elif len(found_intents) > 1:
|
||||||
|
# Mehrere Treffer (z.B. "Es ist FACT oder DECISION") -> Nimm den ersten oder Fallback
|
||||||
|
logger.warning(f"LLM returned multiple intents {found_intents}. Using first match: {found_intents[0]}")
|
||||||
|
return found_intents[0]
|
||||||
|
else:
|
||||||
|
logger.warning(f"LLM did not return a valid strategy name. Falling back to FACT.")
|
||||||
|
|
||||||
|
return "FACT"
|
||||||
|
|
||||||
@router.post("/", response_model=ChatResponse)
|
@router.post("/", response_model=ChatResponse)
|
||||||
async def chat_endpoint(
|
async def chat_endpoint(
|
||||||
request: ChatRequest,
|
request: ChatRequest,
|
||||||
|
|
@ -69,44 +160,74 @@ async def chat_endpoint(
|
||||||
):
|
):
|
||||||
start_time = time.time()
|
start_time = time.time()
|
||||||
query_id = str(uuid.uuid4())
|
query_id = str(uuid.uuid4())
|
||||||
|
|
||||||
logger.info(f"Chat request [{query_id}]: {request.message[:50]}...")
|
logger.info(f"Chat request [{query_id}]: {request.message[:50]}...")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. Retrieval (Hybrid erzwingen für Graph-Nutzung)
|
# 1. Intent Detection
|
||||||
|
intent = await _classify_intent(request.message, llm)
|
||||||
|
logger.info(f"[{query_id}] Final Intent: {intent}")
|
||||||
|
|
||||||
|
# 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_req = QueryRequest(
|
||||||
query=request.message,
|
query=request.message,
|
||||||
mode="hybrid", # WICHTIG: Hybrid Mode für Graph-Nachbarn
|
mode="hybrid",
|
||||||
top_k=request.top_k,
|
top_k=request.top_k,
|
||||||
explain=request.explain
|
explain=request.explain
|
||||||
)
|
)
|
||||||
|
|
||||||
retrieve_result = await retriever.search(query_req)
|
retrieve_result = await retriever.search(query_req)
|
||||||
hits = retrieve_result.results
|
hits = retrieve_result.results
|
||||||
|
|
||||||
|
# 3. Strategic Retrieval
|
||||||
|
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)
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
# 2. Context Building (Enriched)
|
# 4. Context Building
|
||||||
if not hits:
|
if not hits:
|
||||||
logger.info(f"[{query_id}] No hits found.")
|
|
||||||
context_str = "Keine relevanten Notizen gefunden."
|
context_str = "Keine relevanten Notizen gefunden."
|
||||||
else:
|
else:
|
||||||
context_str = _build_enriched_context(hits)
|
context_str = _build_enriched_context(hits)
|
||||||
|
|
||||||
# 3. Generation
|
# 5. Generation
|
||||||
logger.info(f"[{query_id}] Context built with {len(hits)} chunks. Sending to LLM...")
|
template = llm.prompts.get(prompt_key, "{context_str}\n\n{query}")
|
||||||
answer_text = await llm.generate_rag_response(
|
system_prompt = llm.prompts.get("system_prompt", "")
|
||||||
query=request.message,
|
|
||||||
context_str=context_str
|
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
|
||||||
|
answer_text = await llm.generate_raw_response(prompt=final_prompt, system=system_prompt)
|
||||||
|
|
||||||
# 4. Response
|
|
||||||
duration_ms = int((time.time() - start_time) * 1000)
|
duration_ms = int((time.time() - start_time) * 1000)
|
||||||
logger.info(f"[{query_id}] Completed in {duration_ms}ms")
|
|
||||||
|
|
||||||
return ChatResponse(
|
return ChatResponse(
|
||||||
query_id=retrieve_result.query_id,
|
query_id=query_id,
|
||||||
answer=answer_text,
|
answer=answer_text,
|
||||||
sources=hits,
|
sources=hits,
|
||||||
latency_ms=duration_ms
|
latency_ms=duration_ms,
|
||||||
|
intent=intent
|
||||||
)
|
)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
"""
|
"""
|
||||||
app/services/llm_service.py — LLM Client (Ollama)
|
app/services/llm_service.py — LLM Client (Ollama)
|
||||||
|
Version: 0.2.1 (Fix: System Prompt Handling for Phi-3)
|
||||||
Version:
|
|
||||||
0.1.2 (WP-05 Fix: Increased Timeout for CPU Inference)
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import httpx
|
import httpx
|
||||||
|
|
@ -18,19 +16,16 @@ class LLMService:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.settings = get_settings()
|
self.settings = get_settings()
|
||||||
self.prompts = self._load_prompts()
|
self.prompts = self._load_prompts()
|
||||||
# FIX: Timeout auf 120 Sekunden erhöht für CPU-Only Server
|
|
||||||
self.client = httpx.AsyncClient(base_url=self.settings.OLLAMA_URL, timeout=120.0)
|
self.client = httpx.AsyncClient(
|
||||||
|
base_url=self.settings.OLLAMA_URL,
|
||||||
|
timeout=self.settings.LLM_TIMEOUT
|
||||||
|
)
|
||||||
|
|
||||||
def _load_prompts(self) -> dict:
|
def _load_prompts(self) -> dict:
|
||||||
"""Lädt Prompts aus der konfigurierten YAML-Datei."""
|
|
||||||
path = Path(self.settings.PROMPTS_PATH)
|
path = Path(self.settings.PROMPTS_PATH)
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
logger.warning(f"Prompt config not found at {path}, using defaults.")
|
return {}
|
||||||
return {
|
|
||||||
"system_prompt": "You are a helpful AI assistant.",
|
|
||||||
"rag_template": "Context: {context_str}\nQuestion: {query}"
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(path, "r", encoding="utf-8") as f:
|
with open(path, "r", encoding="utf-8") as f:
|
||||||
return yaml.safe_load(f)
|
return yaml.safe_load(f)
|
||||||
|
|
@ -38,46 +33,48 @@ class LLMService:
|
||||||
logger.error(f"Failed to load prompts: {e}")
|
logger.error(f"Failed to load prompts: {e}")
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
async def generate_rag_response(self, query: str, context_str: str) -> str:
|
async def generate_raw_response(self, prompt: str, system: str = None) -> str:
|
||||||
"""
|
"""
|
||||||
Generiert eine Antwort basierend auf Query und Kontext.
|
Führt einen LLM Call aus.
|
||||||
|
Unterstützt nun explizite System-Prompts für sauberes Templating.
|
||||||
"""
|
"""
|
||||||
system_prompt = self.prompts.get("system_prompt", "")
|
|
||||||
template = self.prompts.get("rag_template", "{context_str}\n\n{query}")
|
|
||||||
|
|
||||||
# Template füllen
|
|
||||||
final_prompt = template.format(context_str=context_str, query=query)
|
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
"model": self.settings.LLM_MODEL,
|
"model": self.settings.LLM_MODEL,
|
||||||
"system": system_prompt,
|
"prompt": prompt,
|
||||||
"prompt": final_prompt,
|
|
||||||
"stream": False,
|
"stream": False,
|
||||||
"options": {
|
"options": {
|
||||||
"temperature": 0.7,
|
# Temperature etwas höher für Empathie, niedriger für Code?
|
||||||
# Kleinerer Context spart Rechenzeit, falls 4096 zu viel ist
|
# Wir lassen es auf Standard, oder steuern es später via Config.
|
||||||
"num_ctx": 2048
|
"temperature": 0.7,
|
||||||
|
"num_ctx": 2048
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# WICHTIG: System-Prompt separat übergeben, damit Ollama formatiert
|
||||||
|
if system:
|
||||||
|
payload["system"] = system
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = await self.client.post("/api/generate", json=payload)
|
response = await self.client.post("/api/generate", json=payload)
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
error_msg = response.text
|
logger.error(f"Ollama Error ({response.status_code}): {response.text}")
|
||||||
logger.error(f"Ollama API Error ({response.status_code}): {error_msg}")
|
return "Fehler bei der Generierung."
|
||||||
return f"Fehler vom LLM (Modell '{self.settings.LLM_MODEL}' vorhanden?): {error_msg}"
|
|
||||||
|
data = response.json()
|
||||||
data = response.json()
|
return data.get("response", "").strip()
|
||||||
return data.get("response", "")
|
|
||||||
|
|
||||||
except httpx.ReadTimeout:
|
|
||||||
return "Timeout: Das Modell braucht zu lange zum Antworten (>120s). Hardware-Limit erreicht?"
|
|
||||||
except httpx.ConnectError:
|
|
||||||
return "Verbindungsfehler: Ist Ollama gestartet (Port 11434)?"
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"LLM Service Exception: {e}")
|
logger.error(f"LLM Raw Gen Error: {e}")
|
||||||
return f"Interner Fehler: {str(e)}"
|
return "Interner LLM Fehler."
|
||||||
|
|
||||||
|
async def generate_rag_response(self, query: str, context_str: str) -> str:
|
||||||
|
"""Legacy Support"""
|
||||||
|
system_prompt = self.prompts.get("system_prompt", "")
|
||||||
|
rag_template = self.prompts.get("rag_template", "{context_str}\n\n{query}")
|
||||||
|
final_prompt = rag_template.format(context_str=context_str, query=query)
|
||||||
|
|
||||||
|
# Leite an die neue Methode weiter
|
||||||
|
return await self.generate_raw_response(final_prompt, system=system_prompt)
|
||||||
|
|
||||||
async def close(self):
|
async def close(self):
|
||||||
await self.client.aclose()
|
await self.client.aclose()
|
||||||
89
config/decision_engine.yaml
Normal file
89
config/decision_engine.yaml
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
# config/decision_engine.yaml
|
||||||
|
# Steuerung der Decision Engine (WP-06)
|
||||||
|
# Hybrid-Modus: Keywords (Fast) + LLM Router (Smart Fallback)
|
||||||
|
version: 1.2
|
||||||
|
|
||||||
|
settings:
|
||||||
|
llm_fallback_enabled: true
|
||||||
|
|
||||||
|
# Few-Shot Prompting für bessere SLM-Performance
|
||||||
|
llm_router_prompt: |
|
||||||
|
Du bist ein Klassifikator. Analysiere die Nachricht und wähle die passende Strategie.
|
||||||
|
Antworte NUR mit dem Namen der Strategie.
|
||||||
|
|
||||||
|
STRATEGIEN:
|
||||||
|
- DECISION: Rat, Strategie, Vor/Nachteile, "Soll ich".
|
||||||
|
- EMPATHY: Gefühle, Frust, Freude, Probleme, "Alles ist sinnlos", "Ich bin traurig".
|
||||||
|
- CODING: Code, Syntax, Programmierung, Python.
|
||||||
|
- FACT: Wissen, Fakten, Definitionen.
|
||||||
|
|
||||||
|
BEISPIELE:
|
||||||
|
User: "Wie funktioniert Qdrant?" -> FACT
|
||||||
|
User: "Soll ich Qdrant nutzen?" -> DECISION
|
||||||
|
User: "Schreibe ein Python Script" -> CODING
|
||||||
|
User: "Alles ist grau und sinnlos" -> EMPATHY
|
||||||
|
User: "Mir geht es heute gut" -> EMPATHY
|
||||||
|
|
||||||
|
NACHRICHT: "{query}"
|
||||||
|
|
||||||
|
STRATEGIE:
|
||||||
|
|
||||||
|
strategies:
|
||||||
|
# 1. Fakten-Abfrage (Fallback & Default)
|
||||||
|
FACT:
|
||||||
|
description: "Reine Wissensabfrage."
|
||||||
|
trigger_keywords: []
|
||||||
|
inject_types: []
|
||||||
|
prompt_template: "rag_template"
|
||||||
|
prepend_instruction: null
|
||||||
|
|
||||||
|
# 2. Entscheidungs-Frage
|
||||||
|
DECISION:
|
||||||
|
description: "Der User sucht Rat, Strategie oder Abwägung."
|
||||||
|
trigger_keywords:
|
||||||
|
- "soll ich"
|
||||||
|
- "meinung"
|
||||||
|
- "besser"
|
||||||
|
- "empfehlung"
|
||||||
|
- "strategie"
|
||||||
|
- "entscheidung"
|
||||||
|
- "wert"
|
||||||
|
- "prinzip"
|
||||||
|
- "vor- und nachteile"
|
||||||
|
- "abwägung"
|
||||||
|
inject_types: ["value", "principle", "goal"]
|
||||||
|
prompt_template: "decision_template"
|
||||||
|
prepend_instruction: |
|
||||||
|
!!! ENTSCHEIDUNGS-MODUS !!!
|
||||||
|
BITTE WÄGE FAKTEN GEGEN FOLGENDE WERTE, PRINZIPIEN UND ZIELE AB:
|
||||||
|
|
||||||
|
# 3. Empathie / "Ich"-Modus
|
||||||
|
EMPATHY:
|
||||||
|
description: "Reaktion auf emotionale Zustände."
|
||||||
|
trigger_keywords:
|
||||||
|
- "ich fühle"
|
||||||
|
- "traurig"
|
||||||
|
- "glücklich"
|
||||||
|
- "gestresst"
|
||||||
|
- "angst"
|
||||||
|
- "nervt"
|
||||||
|
- "überfordert"
|
||||||
|
inject_types: ["experience", "belief", "profile"]
|
||||||
|
prompt_template: "empathy_template"
|
||||||
|
prepend_instruction: null
|
||||||
|
|
||||||
|
# 4. Coding / Technical
|
||||||
|
CODING:
|
||||||
|
description: "Technische Anfragen und Programmierung."
|
||||||
|
trigger_keywords:
|
||||||
|
- "code"
|
||||||
|
- "python"
|
||||||
|
- "script"
|
||||||
|
- "funktion"
|
||||||
|
- "bug"
|
||||||
|
- "syntax"
|
||||||
|
- "json"
|
||||||
|
- "yaml"
|
||||||
|
inject_types: ["snippet", "reference", "source"]
|
||||||
|
prompt_template: "technical_template"
|
||||||
|
prepend_instruction: null
|
||||||
|
|
@ -1,15 +1,20 @@
|
||||||
# config/prompts.yaml — Final V2.1
|
# config/prompts.yaml — Final V2.3.1 (Multi-Personality Support)
|
||||||
# Optimiert für Phi-3 Mini (Small Language Model)
|
|
||||||
|
|
||||||
system_prompt: |
|
system_prompt: |
|
||||||
Du bist 'mindnet', das KI-Gedächtnis.
|
Du bist 'mindnet', mein digitaler Zwilling und strategischer Partner.
|
||||||
|
|
||||||
DEINE REGELN:
|
DEINE IDENTITÄT:
|
||||||
1. Deine Antwort muss zu 100% auf dem KONTEXT basieren. Erfinde nichts.
|
- Du bist nicht nur eine Datenbank, sondern handelst nach MEINEN Werten und Zielen.
|
||||||
2. Wenn eine Quelle den Typ [DECISION] hat, ist sie die wichtigste Quelle für das "Warum".
|
- Du passt deinen Stil dynamisch an die Situation an (Analytisch, Empathisch oder Technisch).
|
||||||
3. Nenne konkrete technische Details aus dem Text (z.B. genannte Features, Gründe), statt nur allgemein zu antworten.
|
|
||||||
4. Antworte auf Deutsch.
|
|
||||||
|
|
||||||
|
DEINE REGELN:
|
||||||
|
1. Deine Antwort muss zu 100% auf dem bereitgestellten KONTEXT basieren.
|
||||||
|
2. Halluziniere keine Fakten, die nicht in den Quellen stehen.
|
||||||
|
3. Antworte auf Deutsch (außer bei Code/Fachbegriffen).
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 1. STANDARD: Fakten & Wissen (Intent: FACT)
|
||||||
|
# ---------------------------------------------------------
|
||||||
rag_template: |
|
rag_template: |
|
||||||
QUELLEN (WISSEN):
|
QUELLEN (WISSEN):
|
||||||
=========================================
|
=========================================
|
||||||
|
|
@ -20,5 +25,72 @@ rag_template: |
|
||||||
{query}
|
{query}
|
||||||
|
|
||||||
ANWEISUNG:
|
ANWEISUNG:
|
||||||
Beantworte die Frage basierend auf den Quellen.
|
Beantworte die Frage präzise basierend auf den Quellen.
|
||||||
Nenne die spezifischen Gründe, die im Text stehen (besonders aus [DECISION] Quellen).
|
Fasse die Informationen zusammen. Sei objektiv und neutral.
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 2. DECISION: Strategie & Abwägung (Intent: DECISION)
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
decision_template: |
|
||||||
|
KONTEXT (FAKTEN & STRATEGIE):
|
||||||
|
=========================================
|
||||||
|
{context_str}
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
ENTSCHEIDUNGSFRAGE:
|
||||||
|
{query}
|
||||||
|
|
||||||
|
ANWEISUNG:
|
||||||
|
Du agierst als mein Entscheidungs-Partner.
|
||||||
|
1. Analysiere die Faktenlage aus den Quellen.
|
||||||
|
2. Prüfe dies hart gegen meine strategischen Notizen (Typ [VALUE], [PRINCIPLE], [GOAL]).
|
||||||
|
3. Wäge ab: Passt die technische/faktische Lösung zu meinen Werten?
|
||||||
|
|
||||||
|
FORMAT:
|
||||||
|
- **Analyse:** (Kurze Zusammenfassung der Fakten)
|
||||||
|
- **Abgleich:** (Gibt es Konflikte mit Werten/Zielen? Nenne die Quelle!)
|
||||||
|
- **Empfehlung:** (Klare Meinung: Ja/Nein/Vielleicht mit Begründung)
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 3. EMPATHY: Der Spiegel / "Ich"-Modus (Intent: EMPATHY)
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
empathy_template: |
|
||||||
|
KONTEXT (ERFAHRUNGEN & GLAUBENSSÄTZE):
|
||||||
|
=========================================
|
||||||
|
{context_str}
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
SITUATION:
|
||||||
|
{query}
|
||||||
|
|
||||||
|
ANWEISUNG:
|
||||||
|
Du agierst jetzt als mein empathischer Spiegel.
|
||||||
|
1. Versuche nicht sofort, das Problem technisch zu lösen.
|
||||||
|
2. Zeige Verständnis für die Situation basierend auf meinen eigenen Erfahrungen ([EXPERIENCE]) oder Glaubenssätzen ([BELIEF]), falls im Kontext vorhanden.
|
||||||
|
3. Antworte in der "Ich"-Form oder "Wir"-Form. Sei unterstützend.
|
||||||
|
|
||||||
|
TONFALL:
|
||||||
|
Ruhig, verständnisvoll, reflektiert. Keine Aufzählungszeichen, sondern fließender Text.
|
||||||
|
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
# 4. TECHNICAL: Der Coder (Intent: CODING)
|
||||||
|
# ---------------------------------------------------------
|
||||||
|
technical_template: |
|
||||||
|
KONTEXT (DOCS & SNIPPETS):
|
||||||
|
=========================================
|
||||||
|
{context_str}
|
||||||
|
=========================================
|
||||||
|
|
||||||
|
TASK:
|
||||||
|
{query}
|
||||||
|
|
||||||
|
ANWEISUNG:
|
||||||
|
Du bist Senior Developer.
|
||||||
|
1. Ignoriere Smalltalk. Komm sofort zum Punkt.
|
||||||
|
2. Generiere validen, performanten Code basierend auf den Quellen.
|
||||||
|
3. Wenn Quellen fehlen, nutze dein allgemeines Programmierwissen, aber weise darauf hin.
|
||||||
|
|
||||||
|
FORMAT:
|
||||||
|
- Kurze Erklärung des Ansatzes.
|
||||||
|
- Markdown Code-Block (Copy-Paste fertig).
|
||||||
|
- Wichtige Edge-Cases.
|
||||||
|
|
@ -1,20 +1,32 @@
|
||||||
# mindnet v2.2 – Knowledge Design Manual
|
# mindnet v2.2 – Knowledge Design Manual
|
||||||
**Datei:** `docs/mindnet_knowledge_design_manual_v2.2.md`
|
**Datei:** `docs/mindnet_knowledge_design_manual_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Integrierter Stand WP01–WP05)
|
**Status:** **FINAL** (Integrierter Stand WP01–WP06)
|
||||||
**Quellen:** `knowledge_design.md`, `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_functional_architecture.md`.
|
**Quellen:** `knowledge_design.md`, `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_functional_architecture.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## ⚡ Die 5 Goldenen Regeln (TL;DR)
|
||||||
|
|
||||||
|
Damit Mindnet als dein Digitaler Zwilling funktioniert, beachte beim Schreiben diese Grundsätze:
|
||||||
|
|
||||||
|
1. **Atomare Gedanken:** Eine Notiz = Ein Thema. Wenn du über zwei Projekte schreibst, mach zwei Notizen draus.
|
||||||
|
2. **Explizite Typen:** Setze immer den `type` im Frontmatter. Mindnet behandelt eine `decision` ("Wir machen X") völlig anders als ein `concept` ("Was ist X").
|
||||||
|
3. **Semantische Links:** Schreibe nicht nur `[[Link]]`, sondern `[[rel:depends_on Link]]`. Sag dem System *wie* Dinge zusammenhängen.
|
||||||
|
4. **Werte & Ziele definieren:** Damit die **Decision Engine** dich beraten kann, musst du deine Kriterien (`type: value`, `type: goal`) explizit als Notizen anlegen.
|
||||||
|
5. **Emotionales Bridging:** Damit die **Empathie** funktioniert, nutze in Erfahrungsberichten (`type: experience`) emotionale Schlüsselwörter ("Krise", "Freude", "Angst"), damit der Vektor-Retriever sie bei Gefühls-Anfragen findet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 1. Zweck & Scope
|
## 1. Zweck & Scope
|
||||||
|
|
||||||
Dieses Handbuch ist die **primäre Arbeitsanweisung** für dich als Mindmaster (Owner) und alle Autoren, die Inhalte im mindnet-Vault erstellen.
|
Dieses Handbuch ist die **primäre Arbeitsanweisung** für dich als Mindmaster (Owner) und alle Autoren, die Inhalte im mindnet-Vault erstellen.
|
||||||
|
|
||||||
### 1.1 Zielsetzung
|
### 1.1 Zielsetzung
|
||||||
Mindnet ist mehr als eine Dokumentablage. Es ist ein vernetztes System, das deine Persönlichkeit, Entscheidungen und Erfahrungen abbildet.
|
Mindnet ist mehr als eine Dokumentablage. Es ist ein vernetztes System, das deine Persönlichkeit, Entscheidungen und Erfahrungen abbildet.
|
||||||
Seit Version 2.2 verfügt Mindnet über:
|
Seit Version 2.3.1 verfügt Mindnet über:
|
||||||
* **Explanation Engine:** Das System erklärt, warum es Notizen findet (über Edges).
|
* **Hybrid Router:** Das System erkennt, ob du Fakten, Entscheidungen oder Empathie brauchst.
|
||||||
* **RAG-Chat (KI-Zwilling):** Das System antwortet in natürlicher Sprache. **Wie** du schreibst, bestimmt, **wie schlau** die KI antwortet.
|
* **Context Intelligence:** Das System lädt je nach Situation unterschiedliche Notiz-Typen (z.B. Werte bei Entscheidungen).
|
||||||
|
|
||||||
### 1.2 Der Vault als „Source of Truth“
|
### 1.2 Der Vault als „Source of Truth“
|
||||||
Die Markdown-Dateien in deinem Vault sind die **einzige Quelle der Wahrheit**.
|
Die Markdown-Dateien in deinem Vault sind die **einzige Quelle der Wahrheit**.
|
||||||
|
|
@ -32,7 +44,7 @@ Jede Notiz benötigt einen YAML-Header (Frontmatter) am Dateianfang. Dieser Bloc
|
||||||
Jede Datei muss mindestens folgende Felder enthalten, um korrekt verarbeitet zu werden:
|
Jede Datei muss mindestens folgende Felder enthalten, um korrekt verarbeitet zu werden:
|
||||||
|
|
||||||
---
|
---
|
||||||
id: 20251110-projekt-alpha-8a9b2c # Eindeutige Kennung
|
id: 20251110-projekt-alpha-8a9b2c # Eindeutige Kennung (YYYYMMDD-slug)
|
||||||
title: Projekt Alpha # Sprechender Titel (wird in Suchergebnissen angezeigt)
|
title: Projekt Alpha # Sprechender Titel (wird in Suchergebnissen angezeigt)
|
||||||
type: project # Steuert Verarbeitung & Vernetzung (siehe Kap. 3)
|
type: project # Steuert Verarbeitung & Vernetzung (siehe Kap. 3)
|
||||||
status: active # Status (z.B. draft, active, archived)
|
status: active # Status (z.B. draft, active, archived)
|
||||||
|
|
@ -66,22 +78,23 @@ Diese Felder sind technisch nicht zwingend, aber für bestimmte Typen sinnvoll:
|
||||||
|
|
||||||
## 3. Note-Typen & Typ-Registry
|
## 3. Note-Typen & Typ-Registry
|
||||||
|
|
||||||
Der `type` ist der wichtigste Hebel im Knowledge Design. Er verknüpft die Notiz mit der Konfiguration in `config/types.yaml`.
|
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").
|
||||||
|
|
||||||
### 3.1 Übersicht der Kern-Typen
|
### 3.1 Übersicht der Kern-Typen
|
||||||
|
|
||||||
Mindnet unterscheidet verschiedene Wissensarten. Wähle den Typ, der die **Rolle** der Notiz am besten beschreibt:
|
Mindnet unterscheidet verschiedene Wissensarten. Wähle den Typ, der die **Rolle** der Notiz am besten beschreibt:
|
||||||
|
|
||||||
| Typ | Beschreibung & Einsatzzweck | Wichtigkeit für Chat |
|
| Typ | Beschreibung & Einsatzzweck | Rolle im Chat (Intent) |
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| **`concept`** | Fachbegriffe, Theorien. Zeitloses Wissen. | Mittel (Basiswissen) |
|
| **`concept`** | Fachbegriffe, Theorien. Zeitloses Wissen. | **FACT** (Basiswissen) |
|
||||||
| **`project`** | Ein Vorhaben mit Ziel, Dauer und Aufgaben. | Hoch (Kontext) |
|
| **`project`** | Ein Vorhaben mit Ziel, Dauer und Aufgaben. | **FACT / DECISION** (Kontext) |
|
||||||
| **`experience`** | Persönliche Erfahrung, Lektion oder Erkenntnis. | Sehr Hoch (Persönlichkeit) |
|
| **`experience`** | Persönliche Erfahrung, Lektion oder Erkenntnis. | **EMPATHY** (Spiegelung) |
|
||||||
| **`decision`** | Eine bewusst getroffene Entscheidung (ADR). | **Kritisch** (Begründung "Warum") |
|
| **`decision`** | Eine bewusst getroffene Entscheidung (ADR). | **DECISION** (Begründung "Warum") |
|
||||||
| **`value`** | Ein persönlicher Wert oder ein Prinzip. | **Kritisch** (Moralischer Kompass) |
|
| **`value`** | Ein persönlicher Wert oder ein Prinzip. | **DECISION** (Moralischer Kompass) |
|
||||||
| **`person`** | Eine reale Person (Netzwerk, Autor). | Niedrig |
|
| **`goal`** | Ein strategisches Ziel (kurz- oder langfristig). | **DECISION** (Abgleich) |
|
||||||
| **`journal`** | Zeitbezogener Log-Eintrag, Daily Note. | Mittel (Historie) |
|
| **`person`** | Eine reale Person (Netzwerk, Autor). | **FACT** |
|
||||||
| **`source`** | Externe Quelle (Buch, PDF, Artikel). | Niedrig (Faktenbasis) |
|
| **`journal`** | Zeitbezogener Log-Eintrag, Daily Note. | **FACT** (Historie) |
|
||||||
|
| **`source`** | Externe Quelle (Buch, PDF, Artikel). | **FACT** (Faktenbasis) |
|
||||||
|
|
||||||
### 3.2 Zusammenspiel mit `types.yaml`
|
### 3.2 Zusammenspiel mit `types.yaml`
|
||||||
|
|
||||||
|
|
@ -134,9 +147,58 @@ Für Zusammenfassungen oder "Siehe auch"-Blöcke am Ende einer Notiz.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 5. Best Practices & Beispiele
|
## 5. Schreiben für den KI-Zwilling (New in v2.3)
|
||||||
|
|
||||||
### 5.1 Beispiel: Projekt-Notiz
|
Damit der **RAG-Chat (WP05/06)** nicht nur dumm Fakten wiedergibt, sondern dich berät, musst du "Futter" für die Decision Engine und das Empathie-Modul liefern.
|
||||||
|
|
||||||
|
### 5.1 Futter für die Decision Engine (`DECISION`)
|
||||||
|
Das System soll abwägen: "Passt Tool X zu mir?". Dazu muss es wissen, was "Du" bist.
|
||||||
|
|
||||||
|
**Best Practice: Werte definieren**
|
||||||
|
Erstelle Notizen mit `type: value`.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: value
|
||||||
|
title: Prinzip: Datensparsamkeit
|
||||||
|
---
|
||||||
|
# Prinzip: Datensparsamkeit
|
||||||
|
Wir speichern nur das Minimum an Daten. Cloud-Uploads persönlicher Daten sind verboten, es sei denn, sie sind E2E-verschlüsselt.
|
||||||
|
|
||||||
|
**Best Practice: Ziele definieren**
|
||||||
|
Erstelle Notizen mit `type: goal`.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: goal
|
||||||
|
title: Ziel: Unabhängigkeit 2026
|
||||||
|
---
|
||||||
|
# Ziel: Unabhängigkeit 2026
|
||||||
|
Bis Ende 2026 wollen wir alle SaaS-Abos durch Self-Hosted Lösungen ersetzt haben.
|
||||||
|
|
||||||
|
*Effekt:* Wenn du fragst "Soll ich Notion nutzen?", lädt die Engine diese beiden Notizen und antwortet: *"Nein, Notion ist SaaS und nicht E2E-verschlüsselt. Das verletzt dein Prinzip der Datensparsamkeit und dein Ziel der Unabhängigkeit."*
|
||||||
|
|
||||||
|
### 5.2 Futter für den Empathie-Modus (`EMPATHY`)
|
||||||
|
Das System soll dich verstehen, wenn du sagst: "Alles ist grau." Dazu braucht es deine Resonanzerfahrungen.
|
||||||
|
|
||||||
|
**Best Practice: Erfahrungen & Bridging**
|
||||||
|
Erstelle Notizen mit `type: experience`. Nutze im Text **emotionale Brückenwörter**, damit der Retriever auch bei abstrakten Gefühlen ("grau") einen Treffer landet.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: experience
|
||||||
|
title: Erfahrung: Der Durchbruch nach der Krise
|
||||||
|
tags: [krise, hoffnung, grau, angst]
|
||||||
|
---
|
||||||
|
# Erfahrung: Der Durchbruch nach der Krise
|
||||||
|
Es gibt Projektphasen, da wirkt alles **sinnlos** und **grau**.
|
||||||
|
Ich habe gelernt: Das ist oft das Zeichen kurz vor dem Durchbruch.
|
||||||
|
Mein Mantra in solchen Zeiten: "Einfach weitermachen, der Nebel lichtet sich."
|
||||||
|
|
||||||
|
*Effekt:* Wenn du im Chat jammerst ("Alles ist sinnlos"), findet das System diese Notiz und spiegelt dir deine eigene Erfahrung zurück.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Best Practices & Beispiele (Klassik)
|
||||||
|
|
||||||
|
### 6.1 Beispiel: Projekt-Notiz
|
||||||
Projekte profitieren von `depends_on`, um Abhängigkeiten zu klären.
|
Projekte profitieren von `depends_on`, um Abhängigkeiten zu klären.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -156,7 +218,7 @@ Projekte profitieren von `depends_on`, um Abhängigkeiten zu klären.
|
||||||
## Architektur
|
## Architektur
|
||||||
Das Konzept basiert auf [[RAG Architecture]]. (Automatisch 'depends_on' durch Typ-Default).
|
Das Konzept basiert auf [[RAG Architecture]]. (Automatisch 'depends_on' durch Typ-Default).
|
||||||
|
|
||||||
### 5.2 Beispiel: Entscheidung (Decision Record)
|
### 6.2 Beispiel: Entscheidung (Decision Record)
|
||||||
Entscheidungen sind hoch gewichtet (`retriever_weight: 1.0`).
|
Entscheidungen sind hoch gewichtet (`retriever_weight: 1.0`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -179,35 +241,15 @@ Entscheidungen sind hoch gewichtet (`retriever_weight: 1.0`).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. Langfristige Stabilität & Virtual Schema Layer
|
## 7. Langfristige Stabilität & Virtual Schema Layer
|
||||||
|
|
||||||
Mindnet ist auf Langlebigkeit ausgelegt.
|
Mindnet ist auf Langlebigkeit ausgelegt.
|
||||||
|
|
||||||
### 6.1 Das "Virtual Schema" Prinzip
|
### 7.1 Das "Virtual Schema" Prinzip
|
||||||
Wir vermeiden es, Logik in den Markdown-Dateien hart zu kodieren.
|
Wir vermeiden es, Logik in den Markdown-Dateien hart zu kodieren.
|
||||||
* Statt in jeder Notiz zu schreiben `chunk_size: 500`, schreiben wir nur `type: essay`.
|
* Statt in jeder Notiz zu schreiben `chunk_size: 500`, schreiben wir nur `type: essay`.
|
||||||
* Wie groß ein Chunk für ein Essay ist, definieren wir in der Konfiguration (`types.yaml`).
|
* Wie groß ein Chunk für ein Essay ist, definieren wir in der Konfiguration (`types.yaml`).
|
||||||
|
|
||||||
### 6.2 Was bedeutet das für dich?
|
### 7.2 Was bedeutet das für dich?
|
||||||
* Du kannst dich auf den Inhalt konzentrieren.
|
* Du kannst dich auf den Inhalt konzentrieren.
|
||||||
* Wenn wir in Zukunft (WP08) basierend auf Feedback lernen, dass "Projekte" noch wichtiger sind, ändern wir **eine Zeile** in der Konfiguration, und das gesamte System passt sich beim nächsten Import an.
|
* Wenn wir in Zukunft (WP08) basierend auf Feedback lernen, dass "Projekte" noch wichtiger sind, ändern wir **eine Zeile** in der Konfiguration, und das gesamte System passt sich beim nächsten Import an.
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Schreiben für den KI-Zwilling (New in v2.2)
|
|
||||||
|
|
||||||
Damit der **RAG-Chat (WP05)** gute Antworten liefert, beachte diese Regeln:
|
|
||||||
|
|
||||||
1. **Atomare Konzepte:**
|
|
||||||
* Der Chatbot baut seine Antwort aus mehreren kleinen Text-Stücken ("Chunks") zusammen.
|
|
||||||
* Schreibe so, dass ein Absatz auch für sich allein verständlich ist.
|
|
||||||
2. **Explizite Entscheidungen:**
|
|
||||||
* Wenn du eine Meinung hast ("Tool X ist schlecht"), schreibe sie nicht in einen Nebensatz.
|
|
||||||
* Erstelle eine Notiz `type: experience` oder `decision` ("Warum Tool X nicht geeignet ist").
|
|
||||||
* Die KI sucht gezielt nach `[DECISION]`-Typen, um "Warum"-Fragen zu beantworten.
|
|
||||||
3. **Werte definieren:**
|
|
||||||
* Erstelle Notizen mit `type: value` (z.B. "Datenschutz First").
|
|
||||||
* Die KI nutzt diese, um bei Konflikten ("Soll ich Cloud oder Lokal nutzen?") in deinem Sinne zu argumentieren.
|
|
||||||
4. **Verlinken ist Pflicht:**
|
|
||||||
* Der Chatbot nutzt **Hybrid Search**. Er findet Notizen nur, wenn sie über Kanten verbunden sind.
|
|
||||||
* Eine isolierte Notiz (ohne Links) ist für die KI fast unsichtbar.
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Mindnet v2.2 – Overview & Einstieg
|
# Mindnet v2.2 – Overview & Einstieg
|
||||||
**Datei:** `docs/mindnet_overview_v2.2.md`
|
**Datei:** `docs/mindnet_overview_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Post-WP05 Release)
|
**Status:** **FINAL** (Post-WP06 Release)
|
||||||
**Version:** 2.3.0
|
**Version:** 2.3.1
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -13,10 +13,10 @@
|
||||||
Anders als herkömmliche Notiz-Apps (wie Obsidian oder Evernote), die Texte nur passiv speichern, ist Mindnet ein **aktives System**:
|
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 **versteht** Zusammenhänge über einen Wissensgraphen.
|
||||||
* Es **begründet** Antworten ("Warum ist das so?").
|
* Es **begründet** Antworten ("Warum ist das so?").
|
||||||
* Es **antwortet** im Dialog als Persona (RAG-Chat), basierend auf deinen Werten.
|
* Es **antwortet** situativ angepasst: Mal als harter Strategieberater, mal als empathischer Spiegel.
|
||||||
|
|
||||||
### Die Vision
|
### Die Vision
|
||||||
> „Ein System, das nicht nur speichert, was ich weiß, sondern auch wie ich denke.“
|
> „Ein System, das nicht nur speichert, was ich weiß, sondern auch wie ich denke und fühle.“
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -39,8 +39,10 @@ Mindnet arbeitet auf drei Schichten, die aufeinander aufbauen:
|
||||||
### Ebene 3: Identität (Die Persönlichkeit)
|
### Ebene 3: Identität (Die Persönlichkeit)
|
||||||
* **Funktion:** Interaktion und Bewertung. Das System nimmt eine Haltung ein.
|
* **Funktion:** Interaktion und Bewertung. Das System nimmt eine Haltung ein.
|
||||||
* **Logik:** "Ich empfehle Lösung X, weil sie unserem Wert 'Datensparsamkeit' entspricht."
|
* **Logik:** "Ich empfehle Lösung X, weil sie unserem Wert 'Datensparsamkeit' entspricht."
|
||||||
* **Technik:** RAG-Chat, LLM (Phi-3), Prompt Engineering, Feedback Loop.
|
* **Technik:** * **Intent Router:** Erkennt Absichten (Fakt vs. Gefühl vs. Entscheidung).
|
||||||
* **Status:** 🟢 Live (WP05).
|
* **Strategic Retrieval:** Lädt gezielt Werte oder Erfahrungen nach.
|
||||||
|
* **Multi-Persona:** Passt den Tonfall an.
|
||||||
|
* **Status:** 🟢 Live (WP05–WP06).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -50,9 +52,10 @@ Der Datenfluss in Mindnet ist zyklisch ("Data Flywheel"):
|
||||||
|
|
||||||
1. **Input:** Du schreibst Notizen in Obsidian.
|
1. **Input:** Du schreibst Notizen in Obsidian.
|
||||||
2. **Ingest:** Ein Python-Skript importiert, zerlegt (Chunking) und vernetzt (Edges) die Daten in Qdrant.
|
2. **Ingest:** Ein Python-Skript importiert, zerlegt (Chunking) und vernetzt (Edges) die Daten in Qdrant.
|
||||||
3. **Retrieval:** Bei einer Frage sucht das System semantisch (Text) und graph-basiert (Nachbarn).
|
3. **Intent Recognition:** Der Router analysiert deine Frage: Willst du Fakten, Code oder Empathie?
|
||||||
4. **Generation:** Ein lokales LLM (Ollama) formuliert die Antwort, angereichert mit Kontext-Metadaten.
|
4. **Retrieval:** Das System sucht Inhalte passend zum Intent (z.B. "Lade Erfahrungen bei Empathie").
|
||||||
5. **Feedback:** Du bewertest die Antwort. Das System lernt (langfristig) daraus.
|
5. **Generation:** Ein lokales LLM (Ollama) formuliert die Antwort.
|
||||||
|
6. **Feedback:** Du bewertest die Antwort. Das System lernt (langfristig) daraus.
|
||||||
|
|
||||||
**Tech-Stack:**
|
**Tech-Stack:**
|
||||||
* **Backend:** Python 3.12, FastAPI.
|
* **Backend:** Python 3.12, FastAPI.
|
||||||
|
|
@ -88,5 +91,5 @@ Wo findest du was?
|
||||||
|
|
||||||
## 6. Aktueller Fokus
|
## 6. Aktueller Fokus
|
||||||
|
|
||||||
Wir befinden uns im Übergang von **Phase C (Persönlichkeit)** zu **Phase D (Interaktion)**.
|
Wir haben **Phase C (Persönlichkeit)** mit WP06 (Decision Engine) abgeschlossen.
|
||||||
Das "Gehirn" (WP05) ist fertig. Als Nächstes folgen die **Decision Engine (WP06)** für komplexe Entscheidungen und das **Frontend (WP10)** für bessere Usability.
|
Das System kann nun strategisch denken und fühlen. Als Nächstes folgt **Phase D (Interaktion)** mit dem **Chat Interface (WP10)** für bessere Usability.
|
||||||
|
|
@ -1,39 +1,11 @@
|
||||||
# Mindnet v2.2 – Admin Guide
|
# Mindnet v2.2 – Admin Guide
|
||||||
**Datei:** `docs/mindnet_admin_guide_v2.2.md`
|
**Datei:** `docs/mindnet_admin_guide_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Inkl. RAG & LLM Ops)
|
**Status:** **FINAL** (Inkl. RAG, Decision Engine & LLM Ops)
|
||||||
**Quellen:** `Handbuch.md`, `mindnet_developer_guide_v2.2.md`.
|
**Quellen:** `Handbuch.md`, `mindnet_developer_guide_v2.2.md`.
|
||||||
|
|
||||||
> Dieses Handbuch richtet sich an **Administratoren**. Es beschreibt Installation, Konfiguration, Backup-Strategien, Monitoring und den sicheren Betrieb der Mindnet-Instanz (API + DB + LLM).
|
> Dieses Handbuch richtet sich an **Administratoren**. Es beschreibt Installation, Konfiguration, Backup-Strategien, Monitoring und den sicheren Betrieb der Mindnet-Instanz (API + DB + LLM).
|
||||||
|
|
||||||
---
|
|
||||||
<details>
|
|
||||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
|
||||||
|
|
||||||
- [Mindnet v2.2 – Admin Guide](#mindnet-v22--admin-guide)
|
|
||||||
- [1. Zielgruppe \& Scope](#1-zielgruppe--scope)
|
|
||||||
- [2. Initial Setup \& Installation](#2-initial-setup--installation)
|
|
||||||
- [2.1 Systemvoraussetzungen](#21-systemvoraussetzungen)
|
|
||||||
- [2.2 Installation (Code)](#22-installation-code)
|
|
||||||
- [2.3 Qdrant Setup (Docker)](#23-qdrant-setup-docker)
|
|
||||||
- [2.4 Ollama Setup (LLM Service)](#24-ollama-setup-llm-service)
|
|
||||||
- [2.5 Konfiguration (ENV)](#25-konfiguration-env)
|
|
||||||
- [2.6 Deployment via Systemd](#26-deployment-via-systemd)
|
|
||||||
- [3. Betrieb im Alltag](#3-betrieb-im-alltag)
|
|
||||||
- [3.1 Regelmäßige Importe](#31-regelmäßige-importe)
|
|
||||||
- [3.2 Health-Checks](#32-health-checks)
|
|
||||||
- [3.3 Logs \& Monitoring](#33-logs--monitoring)
|
|
||||||
- [4. Update-Prozess](#4-update-prozess)
|
|
||||||
- [5. Backup \& Restore](#5-backup--restore)
|
|
||||||
- [5.1 Vault-Backup (Priorität 1)](#51-vault-backup-priorität-1)
|
|
||||||
- [5.2 Qdrant-Snapshots (Priorität 2)](#52-qdrant-snapshots-priorität-2)
|
|
||||||
- [5.3 Log-Daten (Priorität 3)](#53-log-daten-priorität-3)
|
|
||||||
- [5.4 Notfall-Wiederherstellung (Rebuild)](#54-notfall-wiederherstellung-rebuild)
|
|
||||||
- [6. Governance \& Sicherheit](#6-governance--sicherheit)
|
|
||||||
- [6.1 Zugriffsschutz](#61-zugriffsschutz)
|
|
||||||
- [6.2 Typen-Governance](#62-typen-governance)
|
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Zielgruppe & Scope
|
## 1. Zielgruppe & Scope
|
||||||
|
|
@ -56,6 +28,7 @@ Wir unterscheiden strikt zwischen:
|
||||||
* Disk: SSD empfohlen für Qdrant-Performance.
|
* Disk: SSD empfohlen für Qdrant-Performance.
|
||||||
|
|
||||||
### 2.2 Installation (Code)
|
### 2.2 Installation (Code)
|
||||||
|
|
||||||
# 1. Repository klonen
|
# 1. Repository klonen
|
||||||
git clone <repo-url> /home/llmadmin/mindnet
|
git clone <repo-url> /home/llmadmin/mindnet
|
||||||
cd /home/llmadmin/mindnet
|
cd /home/llmadmin/mindnet
|
||||||
|
|
@ -70,6 +43,7 @@ Wir unterscheiden strikt zwischen:
|
||||||
|
|
||||||
### 2.3 Qdrant Setup (Docker)
|
### 2.3 Qdrant Setup (Docker)
|
||||||
Wir nutzen Qdrant als Vektor-Datenbank. Persistenz ist wichtig.
|
Wir nutzen Qdrant als Vektor-Datenbank. Persistenz ist wichtig.
|
||||||
|
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name mindnet_qdrant \
|
--name mindnet_qdrant \
|
||||||
--restart always \
|
--restart always \
|
||||||
|
|
@ -79,6 +53,7 @@ Wir nutzen Qdrant als Vektor-Datenbank. Persistenz ist wichtig.
|
||||||
|
|
||||||
### 2.4 Ollama Setup (LLM Service)
|
### 2.4 Ollama Setup (LLM Service)
|
||||||
Mindnet benötigt einen lokalen LLM-Server für den Chat.
|
Mindnet benötigt einen lokalen LLM-Server für den Chat.
|
||||||
|
|
||||||
# 1. Installieren (Linux Script)
|
# 1. Installieren (Linux Script)
|
||||||
curl -fsSL https://ollama.com/install.sh | sh
|
curl -fsSL https://ollama.com/install.sh | sh
|
||||||
|
|
||||||
|
|
@ -89,7 +64,7 @@ Mindnet benötigt einen lokalen LLM-Server für den Chat.
|
||||||
curl http://localhost:11434/api/generate -d '{"model": "phi3:mini", "prompt":"Hi"}'
|
curl http://localhost:11434/api/generate -d '{"model": "phi3:mini", "prompt":"Hi"}'
|
||||||
|
|
||||||
### 2.5 Konfiguration (ENV)
|
### 2.5 Konfiguration (ENV)
|
||||||
Erstelle eine `.env` Datei im Root-Verzeichnis.
|
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.
|
||||||
|
|
||||||
# Qdrant Verbindung
|
# Qdrant Verbindung
|
||||||
QDRANT_URL="http://localhost:6333"
|
QDRANT_URL="http://localhost:6333"
|
||||||
|
|
@ -97,11 +72,18 @@ Erstelle eine `.env` Datei im Root-Verzeichnis.
|
||||||
# Mindnet Core Settings
|
# Mindnet Core Settings
|
||||||
COLLECTION_PREFIX="mindnet"
|
COLLECTION_PREFIX="mindnet"
|
||||||
MINDNET_TYPES_FILE="./config/types.yaml"
|
MINDNET_TYPES_FILE="./config/types.yaml"
|
||||||
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
|
||||||
|
|
||||||
# LLM Settings
|
# LLM / RAG Settings
|
||||||
MINDNET_LLM_MODEL="phi3:mini"
|
MINDNET_LLM_MODEL="phi3:mini"
|
||||||
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
||||||
|
|
||||||
|
# NEU in v2.3: Config & Timeouts
|
||||||
|
# Pfad zu Prompts
|
||||||
|
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
||||||
|
# Pfad zur Decision Engine Config
|
||||||
|
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
|
||||||
|
# Timeout in Sekunden (300s = 5min fuer Cold Starts)
|
||||||
|
MINDNET_LLM_TIMEOUT=300.0
|
||||||
|
|
||||||
### 2.6 Deployment via Systemd
|
### 2.6 Deployment via Systemd
|
||||||
Mindnet wird als Systemdienst gestartet. Ollama läuft meist als eigener Dienst (`ollama.service`).
|
Mindnet wird als Systemdienst gestartet. Ollama läuft meist als eigener Dienst (`ollama.service`).
|
||||||
|
|
@ -120,25 +102,29 @@ Mindnet wird als Systemdienst gestartet. Ollama läuft meist als eigener Dienst
|
||||||
Der Vault-Zustand sollte regelmäßig (z.B. stündlich per Cronjob) nach Qdrant synchronisiert werden.
|
Der Vault-Zustand sollte regelmäßig (z.B. stündlich per Cronjob) nach Qdrant synchronisiert werden.
|
||||||
|
|
||||||
**Cronjob-Beispiel (stündlich):**
|
**Cronjob-Beispiel (stündlich):**
|
||||||
|
|
||||||
0 * * * * cd /home/llmadmin/mindnet && .venv/bin/python3 -m scripts.import_markdown --vault /path/to/vault --prefix "mindnet" --apply --purge-before-upsert --sync-deletes >> ./logs/import.log 2>&1
|
0 * * * * cd /home/llmadmin/mindnet && .venv/bin/python3 -m scripts.import_markdown --vault /path/to/vault --prefix "mindnet" --apply --purge-before-upsert --sync-deletes >> ./logs/import.log 2>&1
|
||||||
|
|
||||||
### 3.2 Health-Checks
|
### 3.2 Health-Checks
|
||||||
Prüfe regelmäßig, ob alle drei Komponenten (API, DB, LLM) laufen.
|
Prüfe regelmäßig, ob alle drei Komponenten (API, DB, LLM) laufen.
|
||||||
|
|
||||||
**Status prüfen:**
|
**Status prüfen:**
|
||||||
|
|
||||||
sudo systemctl status mindnet-prod
|
sudo systemctl status mindnet-prod
|
||||||
sudo systemctl status ollama
|
sudo systemctl status ollama
|
||||||
|
|
||||||
**Logischer Smoke-Test:**
|
**Logischer Smoke-Test:**
|
||||||
|
|
||||||
python3 scripts/test_retriever_smoke.py --mode hybrid --url http://localhost:8001/query
|
python3 scripts/test_retriever_smoke.py --mode hybrid --url http://localhost:8001/query
|
||||||
|
|
||||||
### 3.3 Logs & Monitoring
|
### 3.3 Logs & Monitoring
|
||||||
* **Technische Fehler (API):** `journalctl -u mindnet-prod -f`
|
* **Technische Fehler (API):** `journalctl -u mindnet-prod -f`
|
||||||
|
* Achte auf: `LLM Router Raw Output`. Hier siehst du, wie die Decision Engine entscheidet.
|
||||||
* **LLM Fehler (Ollama):** `journalctl -u ollama -f`
|
* **LLM Fehler (Ollama):** `journalctl -u ollama -f`
|
||||||
* **Fachliche Logs:** `data/logs/search_history.jsonl`
|
* **Fachliche Logs:** `data/logs/search_history.jsonl`
|
||||||
|
|
||||||
**Troubleshooting Chat:**
|
**Troubleshooting Chat:**
|
||||||
* Wenn `/chat` in den Timeout läuft (>300s): Prüfe, ob `phi3:mini` geladen ist und ob der Server überlastet ist.
|
* Wenn `/chat` in den Timeout läuft (>300s): Prüfe `MINDNET_LLM_TIMEOUT` in `.env` und ob das Modell im RAM liegt.
|
||||||
* Wenn `/chat` halluziniert: Prüfe `config/prompts.yaml` und ob der Import aktuell ist.
|
* Wenn `/chat` halluziniert: Prüfe `config/prompts.yaml` und ob der Import aktuell ist.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -148,14 +134,21 @@ Prüfe regelmäßig, ob alle drei Komponenten (API, DB, LLM) laufen.
|
||||||
Wenn neue Versionen ausgerollt werden (Deployment):
|
Wenn neue Versionen ausgerollt werden (Deployment):
|
||||||
|
|
||||||
1. **Code aktualisieren:**
|
1. **Code aktualisieren:**
|
||||||
|
|
||||||
cd /home/llmadmin/mindnet
|
cd /home/llmadmin/mindnet
|
||||||
git pull origin main
|
git pull origin main
|
||||||
|
|
||||||
2. **Dependencies prüfen:**
|
2. **Dependencies prüfen:**
|
||||||
|
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
|
||||||
3. **Dienst neustarten (Zwingend!):**
|
3. **Dienst neustarten (Zwingend!):**
|
||||||
|
|
||||||
sudo systemctl restart mindnet-prod
|
sudo systemctl restart mindnet-prod
|
||||||
|
|
||||||
4. **Schema-Migration (falls nötig):**
|
4. **Schema-Migration (falls nötig):**
|
||||||
|
|
||||||
python3 -m scripts.import_markdown ... --apply
|
python3 -m scripts.import_markdown ... --apply
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -169,6 +162,7 @@ Der Markdown-Vault ist die **Single Source of Truth**. Er muss klassisch gesiche
|
||||||
|
|
||||||
### 5.2 Qdrant-Snapshots (Priorität 2)
|
### 5.2 Qdrant-Snapshots (Priorität 2)
|
||||||
Für schnelle Wiederherstellung des Suchindex.
|
Für schnelle Wiederherstellung des Suchindex.
|
||||||
|
|
||||||
docker stop mindnet_qdrant
|
docker stop mindnet_qdrant
|
||||||
tar -czf qdrant_backup_$(date +%F).tar.gz ./qdrant_storage
|
tar -czf qdrant_backup_$(date +%F).tar.gz ./qdrant_storage
|
||||||
docker start mindnet_qdrant
|
docker start mindnet_qdrant
|
||||||
|
|
@ -178,6 +172,7 @@ Sichere den Ordner `data/logs/`. Verlust dieser Daten bedeutet, dass das System
|
||||||
|
|
||||||
### 5.4 Notfall-Wiederherstellung (Rebuild)
|
### 5.4 Notfall-Wiederherstellung (Rebuild)
|
||||||
Wenn die Datenbank korrupt ist:
|
Wenn die Datenbank korrupt ist:
|
||||||
|
|
||||||
# 1. DB komplett leeren (Wipe)
|
# 1. DB komplett leeren (Wipe)
|
||||||
python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet" --yes
|
python3 -m scripts.reset_qdrant --mode wipe --prefix "mindnet" --yes
|
||||||
# 2. Alles neu importieren
|
# 2. Alles neu importieren
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# Mindnet v2.2 – Appendices & Referenzen
|
# Mindnet v2.2 – Appendices & Referenzen
|
||||||
**Datei:** `docs/mindnet_appendices_v2.2.md`
|
**Datei:** `docs/mindnet_appendices_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Integrierter Stand WP01–WP05)
|
**Status:** **FINAL** (Integrierter Stand WP01–WP06)
|
||||||
**Quellen:** `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_technical_architecture.md`, `Handbuch.md`.
|
**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.
|
> 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)
|
## Anhang A: Typ-Registry Referenz (Default-Werte)
|
||||||
|
|
||||||
Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.2).
|
Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.3.1).
|
||||||
|
|
||||||
| Typ (`type`) | Chunk Profile | Retriever Weight | Edge Defaults (Auto-Kanten) | Beschreibung |
|
| Typ (`type`) | Chunk Profile | Retriever Weight | Edge Defaults (Auto-Kanten) | Beschreibung |
|
||||||
| :--- | :--- | :--- | :--- | :--- |
|
| :--- | :--- | :--- | :--- | :--- |
|
||||||
|
|
@ -23,6 +23,8 @@ Diese Tabelle zeigt die Standard-Konfiguration der `types.yaml` (Stand v2.2).
|
||||||
| **source** | `long` | 0.50 | *(keine)* | Externe Quellen (Bücher, PDFs). |
|
| **source** | `long` | 0.50 | *(keine)* | Externe Quellen (Bücher, PDFs). |
|
||||||
| **event** | `short` | 0.60 | `related_to` | Meetings, Konferenzen. |
|
| **event** | `short` | 0.60 | `related_to` | Meetings, Konferenzen. |
|
||||||
| **value** | `medium` | 1.00 | `related_to` | Persönliche Werte/Prinzipien. |
|
| **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). |
|
||||||
| **default** | `medium` | 1.00 | `references` | Fallback, wenn Typ unbekannt. |
|
| **default** | `medium` | 1.00 | `references` | Fallback, wenn Typ unbekannt. |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -47,9 +49,10 @@ Referenz aller implementierten Kantenarten (`kind`).
|
||||||
|
|
||||||
## Anhang C: Datenmodelle (JSON Payloads)
|
## Anhang C: Datenmodelle (JSON Payloads)
|
||||||
|
|
||||||
Dies sind die Felder, die effektiv in Qdrant gespeichert werden.
|
Diese sind die Felder, die effektiv in Qdrant gespeichert werden.
|
||||||
|
|
||||||
### C.1 Note Payload (`mindnet_notes`)
|
### C.1 Note Payload (`mindnet_notes`)
|
||||||
|
|
||||||
{
|
{
|
||||||
"note_id": "string (keyword)", // UUIDv5 oder Slug
|
"note_id": "string (keyword)", // UUIDv5 oder Slug
|
||||||
"title": "string (text)", // Titel aus Frontmatter
|
"title": "string (text)", // Titel aus Frontmatter
|
||||||
|
|
@ -64,6 +67,7 @@ Dies sind die Felder, die effektiv in Qdrant gespeichert werden.
|
||||||
}
|
}
|
||||||
|
|
||||||
### C.2 Chunk Payload (`mindnet_chunks`)
|
### C.2 Chunk Payload (`mindnet_chunks`)
|
||||||
|
|
||||||
{
|
{
|
||||||
"chunk_id": "string (keyword)", // Format: {note_id}#c{index}
|
"chunk_id": "string (keyword)", // Format: {note_id}#c{index}
|
||||||
"note_id": "string (keyword)", // FK zur Note
|
"note_id": "string (keyword)", // FK zur Note
|
||||||
|
|
@ -76,6 +80,7 @@ Dies sind die Felder, die effektiv in Qdrant gespeichert werden.
|
||||||
}
|
}
|
||||||
|
|
||||||
### C.3 Edge Payload (`mindnet_edges`)
|
### C.3 Edge Payload (`mindnet_edges`)
|
||||||
|
|
||||||
{
|
{
|
||||||
"edge_id": "string (keyword)", // Deterministischer Hash
|
"edge_id": "string (keyword)", // Deterministischer Hash
|
||||||
"source_id": "string (keyword)", // Chunk-ID (Start)
|
"source_id": "string (keyword)", // Chunk-ID (Start)
|
||||||
|
|
@ -101,8 +106,10 @@ Diese Variablen steuern das Verhalten der Skripte und Container.
|
||||||
| `MINDNET_TYPES_FILE` | `config/types.yaml` | Pfad zur Typ-Registry. |
|
| `MINDNET_TYPES_FILE` | `config/types.yaml` | Pfad zur Typ-Registry. |
|
||||||
| `MINDNET_RETRIEVER_CONFIG`| `config/retriever.yaml`| Pfad zur Scoring-Konfiguration. |
|
| `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_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_LLM_MODEL` | `phi3:mini` | Name des Ollama-Modells (Neu in v2.2). |
|
| `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_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_HASH_COMPARE` | `Body` | Vergleichsmodus für Import (`Body`, `Frontmatter`, `Full`). |
|
| `MINDNET_HASH_COMPARE` | `Body` | Vergleichsmodus für Import (`Body`, `Frontmatter`, `Full`). |
|
||||||
| `MINDNET_HASH_SOURCE` | `parsed` | Quelle für Hash (`parsed`, `raw`, `file`). |
|
| `MINDNET_HASH_SOURCE` | `parsed` | Quelle für Hash (`parsed`, `raw`, `file`). |
|
||||||
| `VECTOR_DIM` | `384` | Dimension der Embeddings (Modellabhängig). |
|
| `VECTOR_DIM` | `384` | Dimension der Embeddings (Modellabhängig). |
|
||||||
|
|
@ -112,19 +119,15 @@ Diese Variablen steuern das Verhalten der Skripte und Container.
|
||||||
## Anhang E: Glossar
|
## Anhang E: Glossar
|
||||||
|
|
||||||
* **Callout-Edge:** Kante via `> [!edge]`.
|
* **Callout-Edge:** Kante via `> [!edge]`.
|
||||||
* **Chunking:** Zerlegung von Notizen in kleinere Einheiten.
|
* **Decision Engine:** Komponente, die den Intent prüft und Strategien wählt (WP06).
|
||||||
* **Confidence:** Vertrauenswürdigkeit einer Kante (0.0-1.0).
|
|
||||||
* **Explanation Layer:** Komponente, die Scores und Graphen als Begründung liefert.
|
* **Explanation Layer:** Komponente, die Scores und Graphen als Begründung liefert.
|
||||||
* **Feedback Loop:** Prozess des Loggens und Auswertens von User-Reaktionen.
|
* **Hybrid Router:** Kombination aus Keyword-Matching und LLM-Klassifizierung für Intents.
|
||||||
* **Idempotenz:** Mehrfache Ausführung liefert gleiches Ergebnis.
|
|
||||||
* **Inline-Edge:** Kante via `[[rel:type Ziel]]`.
|
|
||||||
* **RAG (Retrieval Augmented Generation):** Kombination aus Suche und Text-Generierung.
|
* **RAG (Retrieval Augmented Generation):** Kombination aus Suche und Text-Generierung.
|
||||||
* **Retriever:** Suchmaschine (FastAPI).
|
* **Strategic Retrieval:** Gezieltes Nachladen von Werten (`value`) bei Entscheidungfragen.
|
||||||
* **Vault:** Ordner mit Markdown-Dateien.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Anhang F: Workpackage Status (v2.3.0)
|
## Anhang F: Workpackage Status (v2.3.1)
|
||||||
|
|
||||||
Aktueller Implementierungsstand der Module.
|
Aktueller Implementierungsstand der Module.
|
||||||
|
|
||||||
|
|
@ -137,6 +140,6 @@ Aktueller Implementierungsstand der Module.
|
||||||
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
|
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
|
||||||
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
||||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Chat mit Context Enrichment. |
|
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Chat mit Context Enrichment. |
|
||||||
| **WP06** | Decision Engine | 🟡 Geplant | Nächster Schritt (Logik). |
|
| **WP06** | Decision Engine | 🟢 Live | Hybrid Router, Strategic Retrieval, Multi-Persona. |
|
||||||
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
||||||
| **WP10** | Chat Interface | 🟡 Geplant | Nächster Schritt (Frontend). |
|
| **WP10** | Chat Interface | 🟡 Geplant | Nächster Schritt (Frontend). |
|
||||||
255
docs/archiv/knowledge_design.md
Normal file
255
docs/archiv/knowledge_design.md
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
# mindnet v2.2 – Knowledge Design Manual
|
||||||
|
**Datei:** `docs/mindnet_knowledge_design_manual_v2.2.md`
|
||||||
|
**Stand:** 2025-12-09
|
||||||
|
**Status:** **FINAL** (Integrierter Stand WP01–WP06)
|
||||||
|
**Quellen:** `knowledge_design.md`, `TYPE_REGISTRY_MANUAL.md`, `chunking_strategy.md`, `mindnet_functional_architecture.md`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚡ Die 5 Goldenen Regeln (TL;DR)
|
||||||
|
|
||||||
|
Damit Mindnet als dein Digitaler Zwilling funktioniert, beachte beim Schreiben diese Grundsätze:
|
||||||
|
|
||||||
|
1. **Atomare Gedanken:** Eine Notiz = Ein Thema. Wenn du über zwei Projekte schreibst, mach zwei Notizen draus.
|
||||||
|
2. **Explizite Typen:** Setze immer den `type` im Frontmatter. Mindnet behandelt eine `decision` ("Wir machen X") völlig anders als ein `concept` ("Was ist X").
|
||||||
|
3. **Semantische Links:** Schreibe nicht nur `[[Link]]`, sondern `[[rel:depends_on Link]]`. Sag dem System *wie* Dinge zusammenhängen.
|
||||||
|
4. **Werte & Ziele definieren:** Damit die **Decision Engine** dich beraten kann, musst du deine Kriterien (`type: value`, `type: goal`) explizit als Notizen anlegen.
|
||||||
|
5. **Emotionales Bridging:** Damit die **Empathie** funktioniert, nutze in Erfahrungsberichten (`type: experience`) emotionale Schlüsselwörter ("Krise", "Freude", "Angst"), damit der Vektor-Retriever sie bei Gefühls-Anfragen findet.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Zweck & Scope
|
||||||
|
|
||||||
|
Dieses Handbuch ist die **primäre Arbeitsanweisung** für dich als Mindmaster (Owner) und alle Autoren, die Inhalte im mindnet-Vault erstellen.
|
||||||
|
|
||||||
|
### 1.1 Zielsetzung
|
||||||
|
Mindnet ist mehr als eine Dokumentablage. Es ist ein vernetztes System, das deine Persönlichkeit, Entscheidungen und Erfahrungen abbildet.
|
||||||
|
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).
|
||||||
|
|
||||||
|
### 1.2 Der Vault als „Source of Truth“
|
||||||
|
Die Markdown-Dateien in deinem Vault sind die **einzige Quelle der Wahrheit**.
|
||||||
|
* Mindnet importiert diesen Zustand deterministisch in die Datenbank (Qdrant).
|
||||||
|
* Änderungen an IDs, Typen oder Inhalten müssen **immer** im Markdown erfolgen, niemals direkt in der Datenbank.
|
||||||
|
* Was nicht im Markdown steht (z. B. implizites Wissen im Kopf), existiert für das System nicht.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Note-Struktur & Frontmatter
|
||||||
|
|
||||||
|
Jede Notiz benötigt einen YAML-Header (Frontmatter) am Dateianfang. Dieser Block macht die Notiz maschinenlesbar.
|
||||||
|
|
||||||
|
### 2.1 Pflichtfelder
|
||||||
|
Jede Datei muss mindestens folgende Felder enthalten, um korrekt verarbeitet zu werden:
|
||||||
|
|
||||||
|
---
|
||||||
|
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)
|
||||||
|
created: 2025-11-10 # Erstellungsdatum (ISO 8601 oder YYYY-MM-DD)
|
||||||
|
updated: 2025-12-07 # Letzte Änderung
|
||||||
|
tags: [ki, entwicklung] # Taxonomie für Filterung
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.2 Optionale Felder
|
||||||
|
Diese Felder sind technisch nicht zwingend, aber für bestimmte Typen sinnvoll:
|
||||||
|
|
||||||
|
lang: de # Sprache (Default: de)
|
||||||
|
aliases: [Alpha Projekt, Project A] # Synonyme für die Suche
|
||||||
|
visibility: internal # internal (default), public, private
|
||||||
|
|
||||||
|
> **Hinweis:** Felder wie `retriever_weight` oder `chunk_profile` sollten **nicht** mehr manuell im Frontmatter gesetzt werden. Diese werden zentral über den `type` gesteuert (siehe Kap. 3), um die Wartbarkeit zu sichern.
|
||||||
|
|
||||||
|
### 2.3 Empfehlungen für IDs und Pfade
|
||||||
|
|
||||||
|
**Die ID (Identifikator):**
|
||||||
|
* Muss global eindeutig und **stabil** sein.
|
||||||
|
* Darf sich nicht ändern, wenn die Datei umbenannt oder verschoben wird.
|
||||||
|
* **Empfehlung:** `YYYYMMDD-slug-hash` (z. B. `20231027-vektor-db-a1b2`). Dies garantiert Eindeutigkeit und Chronologie.
|
||||||
|
|
||||||
|
**Dateinamen & Pfade:**
|
||||||
|
* Pfade dienen der menschlichen Ordnung (Ordnerstruktur), sind für Mindnet aber sekundär.
|
||||||
|
* Dateinamen sollten dem Titel entsprechen (`Projekt Alpha.md`) oder dem Slug (`projekt-alpha.md`).
|
||||||
|
* Sonderzeichen vermeiden (außer Bindestrich und Unterstrich).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 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").
|
||||||
|
|
||||||
|
### 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) |
|
||||||
|
|
||||||
|
### 3.2 Zusammenspiel mit `types.yaml`
|
||||||
|
|
||||||
|
Der `type` steuert im Hintergrund drei technische Mechanismen:
|
||||||
|
|
||||||
|
1. **`retriever_weight` (Wichtigkeit):**
|
||||||
|
* Ein `concept` (0.6) wiegt weniger als ein `project` (0.97) oder eine `decision` (1.0).
|
||||||
|
* **Warum?** Bei einer Suche nach "Datenbank" soll Mindnet bevorzugt deine *Entscheidung* ("Warum wir X nutzen") anzeigen.
|
||||||
|
2. **`chunk_profile` (Textzerlegung):**
|
||||||
|
* `journal` (short): Wird fein zerlegt.
|
||||||
|
* `project` (long): Längere Kontext-Fenster.
|
||||||
|
3. **`edge_defaults` (Automatische Vernetzung):**
|
||||||
|
* Mindnet ergänzt automatisch Kanten.
|
||||||
|
* Beispiel: Ein Link in einem `project` wird automatisch als `depends_on` (Abhängigkeit) interpretiert.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Edges & Referenzen in Notes
|
||||||
|
|
||||||
|
Um aus isolierten Dateien ein **Netzwerk** zu machen, nutzen wir Verlinkungen. In Version 2.2 sind diese Verlinkungen die Basis für den **Hybrid Retriever** (Suche über Nachbarn).
|
||||||
|
|
||||||
|
### 4.1 Wikilinks (Die Basis-Referenz)
|
||||||
|
Der klassische Obsidian-Link.
|
||||||
|
|
||||||
|
Wir nutzen [[Qdrant]] als Vektordatenbank.
|
||||||
|
|
||||||
|
* **Bedeutung:** "Diese Notiz erwähnt Qdrant."
|
||||||
|
* **Edge-Typ:** `references`
|
||||||
|
|
||||||
|
### 4.2 Inline-Relationen (Semantische Verknüpfung)
|
||||||
|
Dies ist die **mächtigste** Methode. Du sagst dem System explizit, **wie** Dinge zusammenhängen.
|
||||||
|
|
||||||
|
Daher [[rel:depends_on Qdrant]].
|
||||||
|
Dieses Konzept ist [[rel:similar_to Pinecone]].
|
||||||
|
|
||||||
|
* **Syntax:** `[[rel:RELATION ZIEL]]`.
|
||||||
|
* **Gültige Relationen:**
|
||||||
|
* `depends_on`: Hängt ab von / Benötigt. (Trigger für hohe Graph-Relevanz).
|
||||||
|
* `similar_to`: Ähnelt / Ist vergleichbar mit.
|
||||||
|
* `related_to`: Hat zu tun mit (allgemein).
|
||||||
|
* `caused_by`: Wurde verursacht durch.
|
||||||
|
* `solves`: Löst (Problem).
|
||||||
|
|
||||||
|
### 4.3 Callout-Edges (Kuratierte Listen)
|
||||||
|
Für Zusammenfassungen oder "Siehe auch"-Blöcke am Ende einer Notiz.
|
||||||
|
|
||||||
|
> [!edge] related_to: [[Vector Embeddings]] [[AI Agents]]
|
||||||
|
|
||||||
|
* **Funktion:** Erzeugt `related_to`-Kanten zu allen genannten Zielen in dieser Zeile.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Schreiben für den KI-Zwilling (New in v2.3)
|
||||||
|
|
||||||
|
Damit der **RAG-Chat (WP05/06)** nicht nur dumm Fakten wiedergibt, sondern dich berät, musst du "Futter" für die Decision Engine und das Empathie-Modul liefern.
|
||||||
|
|
||||||
|
### 5.1 Futter für die Decision Engine (`DECISION`)
|
||||||
|
Das System soll abwägen: "Passt Tool X zu mir?". Dazu muss es wissen, was "Du" bist.
|
||||||
|
|
||||||
|
**Best Practice: Werte definieren**
|
||||||
|
Erstelle Notizen mit `type: value`.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: value
|
||||||
|
title: Prinzip: Datensparsamkeit
|
||||||
|
---
|
||||||
|
# Prinzip: Datensparsamkeit
|
||||||
|
Wir speichern nur das Minimum an Daten. Cloud-Uploads persönlicher Daten sind verboten, es sei denn, sie sind E2E-verschlüsselt.
|
||||||
|
|
||||||
|
**Best Practice: Ziele definieren**
|
||||||
|
Erstelle Notizen mit `type: goal`.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: goal
|
||||||
|
title: Ziel: Unabhängigkeit 2026
|
||||||
|
---
|
||||||
|
# Ziel: Unabhängigkeit 2026
|
||||||
|
Bis Ende 2026 wollen wir alle SaaS-Abos durch Self-Hosted Lösungen ersetzt haben.
|
||||||
|
|
||||||
|
*Effekt:* Wenn du fragst "Soll ich Notion nutzen?", lädt die Engine diese beiden Notizen und antwortet: *"Nein, Notion ist SaaS und nicht E2E-verschlüsselt. Das verletzt dein Prinzip der Datensparsamkeit und dein Ziel der Unabhängigkeit."*
|
||||||
|
|
||||||
|
### 5.2 Futter für den Empathie-Modus (`EMPATHY`)
|
||||||
|
Das System soll dich verstehen, wenn du sagst: "Alles ist grau." Dazu braucht es deine Resonanzerfahrungen.
|
||||||
|
|
||||||
|
**Best Practice: Erfahrungen & Bridging**
|
||||||
|
Erstelle Notizen mit `type: experience`. Nutze im Text **emotionale Brückenwörter**, damit der Retriever auch bei abstrakten Gefühlen ("grau") einen Treffer landet.
|
||||||
|
|
||||||
|
---
|
||||||
|
type: experience
|
||||||
|
title: Erfahrung: Der Durchbruch nach der Krise
|
||||||
|
tags: [krise, hoffnung, grau, angst]
|
||||||
|
---
|
||||||
|
# Erfahrung: Der Durchbruch nach der Krise
|
||||||
|
Es gibt Projektphasen, da wirkt alles **sinnlos** und **grau**.
|
||||||
|
Ich habe gelernt: Das ist oft das Zeichen kurz vor dem Durchbruch.
|
||||||
|
Mein Mantra in solchen Zeiten: "Einfach weitermachen, der Nebel lichtet sich."
|
||||||
|
|
||||||
|
*Effekt:* Wenn du im Chat jammerst ("Alles ist sinnlos"), findet das System diese Notiz und spiegelt dir deine eigene Erfahrung zurück.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Best Practices & Beispiele (Klassik)
|
||||||
|
|
||||||
|
### 6.1 Beispiel: Projekt-Notiz
|
||||||
|
Projekte profitieren von `depends_on`, um Abhängigkeiten zu klären.
|
||||||
|
|
||||||
|
---
|
||||||
|
id: 20251115-proj-mindnet
|
||||||
|
title: Mindnet Implementierung
|
||||||
|
type: project
|
||||||
|
status: active
|
||||||
|
---
|
||||||
|
|
||||||
|
# Mindnet Implementierung
|
||||||
|
|
||||||
|
Wir bauen ein persönliches Wissensnetz.
|
||||||
|
|
||||||
|
## Tech Stack
|
||||||
|
Wir nutzen [[rel:depends_on Qdrant]] für die Vektorsuche und [[rel:depends_on FastAPI]] für das Backend.
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
Das Konzept basiert auf [[RAG Architecture]]. (Automatisch 'depends_on' durch Typ-Default).
|
||||||
|
|
||||||
|
### 6.2 Beispiel: Entscheidung (Decision Record)
|
||||||
|
Entscheidungen sind hoch gewichtet (`retriever_weight: 1.0`).
|
||||||
|
|
||||||
|
---
|
||||||
|
id: 20251120-adr-vektordb
|
||||||
|
title: ADR: Wahl von Qdrant
|
||||||
|
type: decision
|
||||||
|
status: final
|
||||||
|
tags: [architektur, db]
|
||||||
|
---
|
||||||
|
|
||||||
|
# Entscheidung: Qdrant
|
||||||
|
|
||||||
|
Wir haben uns für Qdrant entschieden.
|
||||||
|
|
||||||
|
## Alternativen
|
||||||
|
Wir haben auch [[rel:similar_to Pinecone]] und [[rel:similar_to Weaviate]] betrachtet.
|
||||||
|
|
||||||
|
## Begründung
|
||||||
|
Qdrant erlaubt lokalen Betrieb und [[rel:solves Payload Filtering Requirements]].
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Langfristige Stabilität & Virtual Schema Layer
|
||||||
|
|
||||||
|
Mindnet ist auf Langlebigkeit ausgelegt.
|
||||||
|
|
||||||
|
### 7.1 Das "Virtual Schema" Prinzip
|
||||||
|
Wir vermeiden es, Logik in den Markdown-Dateien hart zu kodieren.
|
||||||
|
* Statt in jeder Notiz zu schreiben `chunk_size: 500`, schreiben wir nur `type: essay`.
|
||||||
|
* Wie groß ein Chunk für ein Essay ist, definieren wir in der Konfiguration (`types.yaml`).
|
||||||
|
|
||||||
|
### 7.2 Was bedeutet das für dich?
|
||||||
|
* Du kannst dich auf den Inhalt konzentrieren.
|
||||||
|
* Wenn wir in Zukunft (WP08) basierend auf Feedback lernen, dass "Projekte" noch wichtiger sind, ändern wir **eine Zeile** in der Konfiguration, und das gesamte System passt sich beim nächsten Import an.
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# Mindnet v2.2 – Entwickler-Workflow
|
# Mindnet v2.2 – Entwickler-Workflow
|
||||||
**Datei:** `DEV_WORKFLOW.md`
|
**Datei:** `DEV_WORKFLOW.md`
|
||||||
**Stand:** 2025-12-08 (Aktualisiert: Systemd Services & Sync-First)
|
**Stand:** 2025-12-09 (Aktualisiert: LLM Timeouts & Systemd)
|
||||||
|
|
||||||
Dieses Handbuch beschreibt den Entwicklungszyklus zwischen **Windows PC** (IDE), **Raspberry Pi** (Gitea) und **Beelink** (Runtime/Server).
|
Dieses Handbuch beschreibt den Entwicklungszyklus zwischen **Windows PC** (IDE), **Raspberry Pi** (Gitea) und **Beelink** (Runtime/Server).
|
||||||
|
|
||||||
|
|
@ -31,14 +31,14 @@ Hier erstellst du die neue Funktion in einer sicheren Umgebung.
|
||||||
2. **Branch erstellen:**
|
2. **Branch erstellen:**
|
||||||
* Klicke wieder unten links auf `main`.
|
* Klicke wieder unten links auf `main`.
|
||||||
* Wähle `+ Create new branch...`.
|
* Wähle `+ Create new branch...`.
|
||||||
* Gib den Namen ein: `feature/was-ich-tue` (z.B. `feature/wp05-chat`).
|
* Gib den Namen ein: `feature/was-ich-tue` (z.B. `feature/wp06-decision`).
|
||||||
* Drücke **Enter**.
|
* Drücke **Enter**.
|
||||||
|
|
||||||
3. **Sicherheits-Check:**
|
3. **Sicherheits-Check:**
|
||||||
* Steht unten links jetzt dein Feature-Branch? **Nur dann darfst du Code ändern!**
|
* Steht unten links jetzt dein Feature-Branch? **Nur dann darfst du Code ändern!**
|
||||||
|
|
||||||
4. **Coden:**
|
4. **Coden:**
|
||||||
* Nimm deine Änderungen vor.
|
* Nimm deine Änderungen vor (z.B. neue YAML-Configs).
|
||||||
|
|
||||||
5. **Sichern & Hochladen:**
|
5. **Sichern & Hochladen:**
|
||||||
* **Source Control** Icon (Gabel-Symbol) -> Nachricht eingeben -> **Commit**.
|
* **Source Control** Icon (Gabel-Symbol) -> Nachricht eingeben -> **Commit**.
|
||||||
|
|
@ -60,7 +60,7 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
|
||||||
```bash
|
```bash
|
||||||
git fetch
|
git fetch
|
||||||
# Tipp: 'git branch -r' zeigt alle verfügbaren Branches an
|
# Tipp: 'git branch -r' zeigt alle verfügbaren Branches an
|
||||||
git checkout feature/wp05-chat
|
git checkout feature/wp06-decision
|
||||||
git pull
|
git pull
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -101,8 +101,8 @@ Hier prüfst du, ob dein neuer Code auf dem echten Server läuft.
|
||||||
6. **Validieren:**
|
6. **Validieren:**
|
||||||
Führe deine Tests in einem **zweiten Terminal** aus:
|
Führe deine Tests in einem **zweiten Terminal** aus:
|
||||||
```bash
|
```bash
|
||||||
# Beispiel für Smoke-Test gegen Dev-Port
|
# Beispiel für Decision Engine Test
|
||||||
python3 tests/test_chat_smoke.py --url http://localhost:8002/chat
|
python tests/test_wp06_decision.py -p 8002 -q "Soll ich...?"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -148,9 +148,8 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
|
||||||
cd ~/mindnet_dev
|
cd ~/mindnet_dev
|
||||||
git checkout main
|
git checkout main
|
||||||
git pull
|
git pull
|
||||||
git branch -d feature/wp05-chat
|
git branch -d feature/wp06-decision
|
||||||
```
|
```
|
||||||
*Hinweis: Der `mindnet-dev` Service läuft jetzt mit dem Code von `main`, was okay ist.*
|
|
||||||
3. **VS Code:**
|
3. **VS Code:**
|
||||||
* Auf `main` wechseln.
|
* Auf `main` wechseln.
|
||||||
* Sync drücken.
|
* Sync drücken.
|
||||||
|
|
@ -164,24 +163,24 @@ Damit das Chaos nicht wächst, löschen wir den fertigen Branch.
|
||||||
| :--- | :--- | :--- |
|
| :--- | :--- | :--- |
|
||||||
| **VS Code** | `Sync (auf main)` | **WICHTIG:** Holt neuesten Code vom Server. |
|
| **VS Code** | `Sync (auf main)` | **WICHTIG:** Holt neuesten Code vom Server. |
|
||||||
| **Beelink** | `git fetch` | Aktualisiert Liste der Remote-Branches. |
|
| **Beelink** | `git fetch` | Aktualisiert Liste der Remote-Branches. |
|
||||||
| **Beelink** | `git checkout <name>` | Wechsle Branch. |
|
|
||||||
| **Beelink** | `git pull` | Aktualisiere aktuellen Branch. |
|
|
||||||
| **Beelink** | `sudo systemctl restart mindnet-dev` | **Neustart Dev-Server (Port 8002).** |
|
| **Beelink** | `sudo systemctl restart mindnet-dev` | **Neustart Dev-Server (Port 8002).** |
|
||||||
| **Beelink** | `sudo systemctl stop mindnet-dev` | **Stoppt Dev-Server (macht Port frei).** |
|
|
||||||
| **Beelink** | `sudo systemctl restart mindnet-prod`| **Neustart Prod-Server (Port 8001).** |
|
|
||||||
| **Beelink** | `journalctl -u mindnet-dev -f` | **Live-Logs vom Dev-Server sehen.** |
|
| **Beelink** | `journalctl -u mindnet-dev -f` | **Live-Logs vom Dev-Server sehen.** |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Troubleshooting
|
## 4. Troubleshooting
|
||||||
|
|
||||||
**"Port 8002 already in use"**
|
**"Read timed out (120s)" / 500 Error beim Chat**
|
||||||
* Du willst `uvicorn` manuell starten, aber der Service läuft noch.
|
* **Ursache:** Das LLM (Ollama) braucht zu lange zum Laden ("Cold Start").
|
||||||
* **Lösung:** `sudo systemctl stop mindnet-dev`
|
|
||||||
|
|
||||||
**"Hilfe, in meinem neuen Branch fehlen Dateien!"**
|
|
||||||
* Das passiert, wenn du beim Erstellen nicht aktuell warst.
|
|
||||||
* **Lösung:**
|
* **Lösung:**
|
||||||
```bash
|
1. Erhöhe in `.env` den Wert: `MINDNET_LLM_TIMEOUT=300.0`.
|
||||||
git checkout feature/mein-kaputter-branch
|
2. Starte den Server neu (`sudo systemctl restart mindnet-dev`).
|
||||||
git merge main
|
3. Stelle sicher, dass dein Test-Skript (Client) auch ein hohes Timeout hat.
|
||||||
|
|
||||||
|
**"Port 8002 already in use"**
|
||||||
|
* **Ursache:** Du willst `uvicorn` manuell starten, aber der Service läuft noch.
|
||||||
|
* **Lösung:** `sudo systemctl stop mindnet-dev`.
|
||||||
|
|
||||||
|
**"UnicodeDecodeError in .env"**
|
||||||
|
* **Ursache:** Umlaute oder Sonderzeichen in der `.env` Datei.
|
||||||
|
* **Lösung:** `.env` bereinigen (nur ASCII nutzen) und sicherstellen, dass sie UTF-8 ohne BOM ist.
|
||||||
|
|
@ -1,15 +1,37 @@
|
||||||
# Mindnet v2.2 – Developer Guide
|
# Mindnet v2.2 – Developer Guide
|
||||||
**Datei:** `docs/mindnet_developer_guide_v2.2.md`
|
**Datei:** `docs/mindnet_developer_guide_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Inkl. RAG, Edge-Config & AI-Teaching)
|
**Status:** **FINAL** (Inkl. RAG, Decision Engine & AI-Teaching)
|
||||||
**Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`.
|
**Quellen:** `mindnet_technical_architecture.md`, `Handbuch.md`, `DEV_WORKFLOW.md`.
|
||||||
|
|
||||||
> **Zielgruppe:** Entwickler:innen.
|
> **Zielgruppe:** Entwickler:innen.
|
||||||
> **Zweck:** Anleitung zum Aufsetzen der Entwicklungsumgebung, Verständnis der Modulstruktur und Durchführung von Tests.
|
> **Zweck:** Anleitung zum Aufsetzen der Entwicklungsumgebung, Verständnis der Modulstruktur und Durchführung von Tests.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
- [Mindnet v2.2 – Developer Guide](#mindnet-v22--developer-guide)
|
||||||
|
- [1. Projektstruktur (Post-WP06)](#1-projektstruktur-post-wp06)
|
||||||
|
- [2. Lokales Setup (Development)](#2-lokales-setup-development)
|
||||||
|
- [2.1 Voraussetzungen](#21-voraussetzungen)
|
||||||
|
- [2.2 Installation](#22-installation)
|
||||||
|
- [2.3 Konfiguration (Environment)](#23-konfiguration-environment)
|
||||||
|
- [2.4 Dienste starten (Systemd bevorzugt)](#24-dienste-starten-systemd-bevorzugt)
|
||||||
|
- [3. Core-Module \& Entwicklung](#3-core-module--entwicklung)
|
||||||
|
- [3.1 Der Importer (`scripts.import_markdown`)](#31-der-importer-scriptsimport_markdown)
|
||||||
|
- [3.2 Der Hybrid Router (`app.routers.chat`)](#32-der-hybrid-router-approuterschat)
|
||||||
|
- [3.3 Der Retriever (`app.core.retriever`)](#33-der-retriever-appcoreretriever)
|
||||||
|
- [4. Tests \& Debugging](#4-tests--debugging)
|
||||||
|
- [4.1 Unit Tests (Pytest)](#41-unit-tests-pytest)
|
||||||
|
- [4.2 Integration / Pipeline Tests](#42-integration--pipeline-tests)
|
||||||
|
- [4.3 Smoke Tests (E2E)](#43-smoke-tests-e2e)
|
||||||
|
- [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)
|
||||||
|
- [Fazit](#fazit)
|
||||||
|
- [6. Nützliche Einzeiler](#6-nützliche-einzeiler)
|
||||||
|
|
||||||
## 1. Projektstruktur (Aktualisiert)
|
---
|
||||||
|
|
||||||
|
## 1. Projektstruktur (Post-WP06)
|
||||||
|
|
||||||
Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt.
|
Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung) getrennt.
|
||||||
|
|
||||||
|
|
@ -25,17 +47,18 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
|
||||||
│ │ └── dto.py # Zentrale DTO-Definition
|
│ │ └── dto.py # Zentrale DTO-Definition
|
||||||
│ ├── routers/ # FastAPI Endpoints
|
│ ├── routers/ # FastAPI Endpoints
|
||||||
│ │ ├── query.py # Suche
|
│ │ ├── query.py # Suche
|
||||||
│ │ ├── chat.py # RAG-Chat (WP05)
|
│ │ ├── chat.py # Hybrid Router & Decision Engine (WP06)
|
||||||
│ │ ├── feedback.py # Feedback (WP04c)
|
│ │ ├── feedback.py # Feedback (WP04c)
|
||||||
│ │ └── ...
|
│ │ └── ...
|
||||||
│ ├── services/ # Interne & Externe Dienste
|
│ ├── services/ # Interne & Externe Dienste
|
||||||
│ │ ├── llm_service.py # Ollama Client (WP05)
|
│ │ ├── llm_service.py # Ollama Client (Mit Timeout & Raw-Mode)
|
||||||
│ │ ├── feedback_service.py # Logging (JSONL Writer)
|
│ │ ├── feedback_service.py # Logging (JSONL Writer)
|
||||||
│ │ └── embeddings_client.py
|
│ │ └── embeddings_client.py
|
||||||
│ └── main.py # Entrypoint der API
|
│ └── main.py # Entrypoint der API
|
||||||
├── config/ # YAML-Konfigurationen (Single Source of Truth)
|
├── config/ # YAML-Konfigurationen (Single Source of Truth)
|
||||||
│ ├── types.yaml # Import-Regeln
|
│ ├── types.yaml # Import-Regeln
|
||||||
│ ├── prompts.yaml # LLM Prompts & RAG Templates (WP05)
|
│ ├── prompts.yaml # LLM Prompts & RAG Templates (WP06)
|
||||||
|
│ ├── decision_engine.yaml # Router-Strategien (WP06)
|
||||||
│ └── retriever.yaml # Scoring-Regeln & Kantengewichte
|
│ └── retriever.yaml # Scoring-Regeln & Kantengewichte
|
||||||
├── data/
|
├── data/
|
||||||
│ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl)
|
│ └── logs/ # Lokale Logs (search_history.jsonl, feedback.jsonl)
|
||||||
|
|
@ -71,7 +94,7 @@ Der Code ist modular in `app` (Logik), `scripts` (CLI) und `config` (Steuerung)
|
||||||
ollama pull phi3:mini
|
ollama pull phi3:mini
|
||||||
|
|
||||||
### 2.3 Konfiguration (Environment)
|
### 2.3 Konfiguration (Environment)
|
||||||
Erstelle eine `.env` Datei im Root-Verzeichnis.
|
Erstelle eine `.env` Datei im Root-Verzeichnis. Die Timeout-Settings sind kritisch für CPU-Inference.
|
||||||
|
|
||||||
# Qdrant Verbindung
|
# Qdrant Verbindung
|
||||||
QDRANT_URL="http://localhost:6333"
|
QDRANT_URL="http://localhost:6333"
|
||||||
|
|
@ -82,10 +105,12 @@ Erstelle eine `.env` Datei im Root-Verzeichnis.
|
||||||
MINDNET_TYPES_FILE="./config/types.yaml"
|
MINDNET_TYPES_FILE="./config/types.yaml"
|
||||||
MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml"
|
MINDNET_RETRIEVER_CONFIG="./config/retriever.yaml"
|
||||||
|
|
||||||
# LLM / RAG Settings (WP05)
|
# LLM / RAG Settings (WP06)
|
||||||
MINDNET_LLM_MODEL="phi3:mini"
|
MINDNET_LLM_MODEL="phi3:mini"
|
||||||
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
MINDNET_OLLAMA_URL="http://127.0.0.1:11434"
|
||||||
|
MINDNET_LLM_TIMEOUT=300.0
|
||||||
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
MINDNET_PROMPTS_PATH="./config/prompts.yaml"
|
||||||
|
MINDNET_DECISION_CONFIG="./config/decision_engine.yaml"
|
||||||
|
|
||||||
# Import-Strategie
|
# Import-Strategie
|
||||||
MINDNET_HASH_COMPARE="Body"
|
MINDNET_HASH_COMPARE="Body"
|
||||||
|
|
@ -97,7 +122,7 @@ Auf dem Entwicklungsserver (Beelink) nutzen wir Systemd.
|
||||||
# Starten / Neustarten
|
# Starten / Neustarten
|
||||||
sudo systemctl restart mindnet-dev
|
sudo systemctl restart mindnet-dev
|
||||||
|
|
||||||
# Logs prüfen
|
# Logs prüfen (Wichtig für LLM Debugging)
|
||||||
journalctl -u mindnet-dev -f
|
journalctl -u mindnet-dev -f
|
||||||
|
|
||||||
Falls du lokal auf Windows entwickelst:
|
Falls du lokal auf Windows entwickelst:
|
||||||
|
|
@ -119,14 +144,16 @@ Dies ist das komplexeste Modul.
|
||||||
* **Idempotenz:** Der Importer muss mehrfach laufen können, ohne Duplikate zu erzeugen. Wir nutzen deterministische IDs (UUIDv5).
|
* **Idempotenz:** Der Importer muss mehrfach laufen können, ohne Duplikate zu erzeugen. Wir nutzen deterministische IDs (UUIDv5).
|
||||||
* **Debugging:** Nutze `--dry-run` oder `scripts/payload_dryrun.py`.
|
* **Debugging:** Nutze `--dry-run` oder `scripts/payload_dryrun.py`.
|
||||||
|
|
||||||
### 3.2 Edge-Logik (`app.core.derive_edges`)
|
### 3.2 Der Hybrid Router (`app.routers.chat`)
|
||||||
Hier wird entschieden, welche Kanten entstehen.
|
Hier liegt die Logik für Intent Detection (WP06).
|
||||||
* **Rule-ID:** Vergib zwingend eine eindeutige `rule_id` (z.B. `custom:my_rule`), damit die Herkunft für die Explanation nachvollziehbar bleibt.
|
* **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`.
|
||||||
|
* **Erweiterung:** Um neue Intents hinzuzufügen, editiere nur die YAML, nicht den Python-Code (Late Binding).
|
||||||
|
|
||||||
### 3.3 Der Retriever & Chat (`app.core.retriever` / `app.routers.chat`)
|
### 3.3 Der Retriever (`app.core.retriever`)
|
||||||
Hier passiert das Scoring und die Generation.
|
Hier passiert das Scoring.
|
||||||
* **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`.
|
* **Hybrid Search:** Der Chat-Endpoint erzwingt `mode="hybrid"`.
|
||||||
* **Context Enrichment:** In `_build_enriched_context` (chat.py) werden Metadaten (Typ, Score) in den Prompt injiziert. Achte darauf, dass neue Typen hier ggf. berücksichtigt werden, falls sie spezielle Behandlung brauchen (aktuell generisch gelöst).
|
* **Strategic Retrieval:** In `chat.py` wird der Retriever *zweimal* aufgerufen, wenn ein Intent (z.B. `DECISION`) eine Injection (`value`) erfordert.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -157,11 +184,15 @@ Prüfen das laufende System (API) gegen eine echte Qdrant-Instanz und Ollama.
|
||||||
# 1. Retriever Test (Hybrid + Explanation)
|
# 1. Retriever Test (Hybrid + Explanation)
|
||||||
python scripts/test_retriever_smoke.py --query "Test" --mode hybrid --top-k 5 --explain
|
python scripts/test_retriever_smoke.py --query "Test" --mode hybrid --top-k 5 --explain
|
||||||
|
|
||||||
# 2. Chat / RAG Test (WP05)
|
# 2. Decision Engine Test (WP06)
|
||||||
# Prüft die gesamte Kette: Suche -> Kontext -> LLM -> Antwort
|
# Prüft Intent, Retrieval und Reasoning (mit Timeout-Handling)
|
||||||
python tests/test_chat_wp05.py
|
python tests/test_wp06_decision.py -p 8002 -e DECISION -q "Soll ich X tun?"
|
||||||
|
|
||||||
# 3. Feedback Test (WP04c)
|
# 3. Empathy Test (WP06)
|
||||||
|
# Prüft LLM-Router Fallback
|
||||||
|
python tests/test_wp06_decision.py -p 8002 -e EMPATHY -q "Alles ist grau"
|
||||||
|
|
||||||
|
# 4. Feedback Test (WP04c)
|
||||||
python tests/test_feedback_smoke.py --url http://localhost:8002/query
|
python tests/test_feedback_smoke.py --url http://localhost:8002/query
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -180,19 +211,20 @@ Definiere die "Physik" des Typs (Import-Regeln und Basis-Wichtigkeit).
|
||||||
retriever_weight: 0.90 # Sehr wichtig, fast so hoch wie Decisions
|
retriever_weight: 0.90 # Sehr wichtig, fast so hoch wie Decisions
|
||||||
edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten
|
edge_defaults: ["blocks"] # Automatische Kante zu verlinkten Projekten
|
||||||
|
|
||||||
*Ergebnis:* Notizen werden importiert und landen bei Suchen weit oben.
|
**2. Strategie-Ebene (`config/decision_engine.yaml`)**
|
||||||
|
Damit dieser Typ aktiv geladen wird, musst du ihn einer Strategie zuordnen.
|
||||||
|
|
||||||
**2. Labeling-Ebene (`app/routers/chat.py`)**
|
DECISION:
|
||||||
Der Router liest das Feld `type` automatisch aus und injiziert es als `TYP: [RISK]` in den Prompt.
|
inject_types: ["value", "principle", "goal", "risk"] # <--- "risk" hinzugefügt
|
||||||
* *Prüfung:* Keine Code-Änderung nötig, da der Router generisch ist.
|
|
||||||
|
*Ergebnis:* Wenn der Intent `DECISION` erkannt wird, sucht das System nun auch aktiv nach Risiken.
|
||||||
|
|
||||||
**3. Kognitive Ebene (`config/prompts.yaml`)**
|
**3. Kognitive Ebene (`config/prompts.yaml`)**
|
||||||
Erkläre dem LLM, was `[RISK]` bedeutet. Ergänze den `system_prompt`:
|
Erkläre dem LLM im Template, was es damit tun soll.
|
||||||
|
|
||||||
system_prompt: |
|
decision_template: |
|
||||||
...
|
...
|
||||||
REGELN FÜR TYPEN:
|
- Prüfe auf [RISK]: Wenn vorhanden, warne mich davor!
|
||||||
- [RISK]: Warnung! Wenn ein [RISK] im Kontext ist, weise den User darauf hin.
|
|
||||||
|
|
||||||
### B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`)
|
### B. Workflow: Neue Beziehungen (Edges) nutzen (z. B. `beeinflusst_von`)
|
||||||
|
|
||||||
|
|
@ -203,30 +235,17 @@ Du musst dem System keinen neuen Edge-Typ "beibringen" (Schema-less). Du nutzt i
|
||||||
Nutze die Inline-Syntax im Fließtext:
|
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]].
|
||||||
Diese Strategie ist eine [[rel:reaktion_auf Marktveränderung]].
|
|
||||||
|
|
||||||
*Ergebnis:* Der Importer erzeugt Kanten mit `kind="beeinflusst_von"`.
|
|
||||||
|
|
||||||
**2. Gewichtung (`config/retriever.yaml`)**
|
**2. Gewichtung (`config/retriever.yaml`)**
|
||||||
Standardmäßig werden alle expliziten Kanten gleich behandelt (hoher Bonus). Wenn du willst, dass `beeinflusst_von` *wichtiger* ist als `related_to`, konfigurierst du dies hier.
|
Standardmäßig werden alle expliziten Kanten gleich behandelt. Wenn Kausalität wichtiger ist als Ähnlichkeit, konfiguriere dies hier.
|
||||||
|
|
||||||
scoring:
|
scoring:
|
||||||
edge_weight: 0.7
|
|
||||||
# Optional: Spezifische Boosts für Kanten-Typen (Advanced)
|
|
||||||
edge_type_weights:
|
edge_type_weights:
|
||||||
beeinflusst_von: 1.5 # Sehr starker Einfluss auf das Ranking
|
beeinflusst_von: 1.5 # Sehr starker Einfluss auf das Ranking
|
||||||
reaktion_auf: 1.2
|
|
||||||
related_to: 0.5 # Schwächerer Einfluss
|
|
||||||
|
|
||||||
*Hinweis:* Wenn `edge_type_weights` nicht definiert ist, gilt der Standard-Algorithmus (Confidence ~0.95 für Inline-Relations).
|
|
||||||
|
|
||||||
**3. Verständnis beim LLM (`config/prompts.yaml`)**
|
|
||||||
Damit der Chatbot versteht, dass "beeinflusst_von" eine Kausalität ist (und nicht nur Ähnlichkeit), kannst du dies im Prompt erklären, falls die Explanation-Daten in den Kontext geladen werden (Roadmap WP-06).
|
|
||||||
|
|
||||||
### Fazit
|
### Fazit
|
||||||
Nur wenn **Daten** (Vault), **Physik** (Config) und **Semantik** (Prompt) zusammenspielen, entsteht ein intelligenter Zwilling.
|
|
||||||
* **Vault:** Liefert das Wissen.
|
* **Vault:** Liefert das Wissen.
|
||||||
* **Config:** Liefert die Priorität (Weights).
|
* **Config:** Liefert die Strategie (Router & Weights).
|
||||||
* **Prompt:** Liefert die Interpretation.
|
* **Prompt:** Liefert die Interpretation.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -241,6 +260,6 @@ Nur wenn **Daten** (Vault), **Physik** (Config) und **Semantik** (Prompt) zusamm
|
||||||
|
|
||||||
python3 tests/inspect_one_note.py --file ./vault/MeinFile.md
|
python3 tests/inspect_one_note.py --file ./vault/MeinFile.md
|
||||||
|
|
||||||
**Live-Logs sehen (Beelink):**
|
**Live-Logs sehen (Beelink) - inkl. LLM Thoughts:**
|
||||||
|
|
||||||
journalctl -u mindnet-dev -f
|
journalctl -u mindnet-dev -f
|
||||||
|
|
@ -1,216 +0,0 @@
|
||||||
# mindnet – Knowledge Design
|
|
||||||
**Version:** 1.5.0 (aktualisiert 2025-11-09)
|
|
||||||
|
|
||||||
> Dieses Dokument beschreibt das Ziel, die Architektur, die Datenmodelle sowie die Regeln und Prozesse für den Aufbau von **mindnet** – einem persönlichen, lokal betriebenen Wissensnetz, das auf Markdown-Quellen, Graph-Beziehungen und Vektor-Suche basiert. Es soll die Persönlichkeit, Werte und Erfahrungen des Besitzers widerspiegeln und künftig Antworten generieren, die diese Perspektive authentisch berücksichtigen.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 1. Ziel von mindnet
|
|
||||||
|
|
||||||
**1.1 Zweck**
|
|
||||||
- mindnet dient als persönliches Wissensnetz, das Erfahrungen, Werte, Prinzipien, Ziele und prägenden Ereignisse langfristig strukturiert.
|
|
||||||
- Es ermöglicht spätere Einsichten in Entscheidungen und Entwicklungen und kann in Zukunft für die Familie (z. B. Kinder) eine nachvollziehbare Quelle sein.
|
|
||||||
|
|
||||||
**1.2 Leitidee**
|
|
||||||
- Statt einer reinen Dokumentablage wird Wissen durch **Knoten (Notes/Chunks)** und **Kanten (Edges)** vernetzt.
|
|
||||||
- Antworten sollen **persönlich** kontextualisiert werden (Perspektive, Konditionierung, Persönlichkeit).
|
|
||||||
|
|
||||||
**1.3 Langfristigkeit**
|
|
||||||
- Stabiler, zukunftsfähiger Entwurf; spätere Massenmigrationen sollen vermieden werden.
|
|
||||||
- Architektur unterstützt schrittweise Erweiterung (neue Quellen, neue Agenten, neue Regeln).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Zielarchitektur (High Level)
|
|
||||||
|
|
||||||
- **Datenquellen:** Markdown-Vault (Obsidian-kompatibel), perspektivisch weitere Quellen (MediaWiki, PDFs, Web-Exporte, E-Mail-Auszüge).
|
|
||||||
- **Import-Pipeline:** Parser → Frontmatter/Body → Chunking → Embedding → Qdrant (Notes/Chunks/Edges).
|
|
||||||
- **Speicher:** Qdrant (Vektoren + Payload + Textindex), Dateien bleiben im Filesystem (Quelle ist Referenz).
|
|
||||||
- **Graph-Schicht:** Edges explizit modelliert (Typ, Richtung, Evidenz, Confidence); optionale abgeleitete Edges per Batch-Job.
|
|
||||||
- **Retriever/Composer:** Hybrid-Retrieval (Vektor + Filter + optional Volltext), Komposition zu Antwortkandidaten.
|
|
||||||
- **Erklärbarkeit:** Begründungspfade (Top-Chunks, Graph-Kette, Provenienz).
|
|
||||||
- **Schnittstellen:** REST/CLI, n8n-Glue, lokale LLM-Anbindung (Ollama).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Collections in Qdrant
|
|
||||||
|
|
||||||
- `mindnet_notes` – Note-Metadaten (id, title, type, path, timestamps, tags, …).
|
|
||||||
- `mindnet_chunks` – inhaltstragende Segmente inkl. Vektoren und Textindex.
|
|
||||||
- `mindnet_edges` – Beziehungen (src/dst, relation, direction, evidence, confidence, …).
|
|
||||||
- (optional) `mindnet_people` – strukturierte Personenobjekte (Eigen-/Fremdbezug).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 4. Identitäten & IDs
|
|
||||||
|
|
||||||
- **Deterministische IDs** für Notes (z. B. Namespace-basierte UUIDv5) und stabile, ableitbare IDs für Chunks/Edges.
|
|
||||||
- ID-Stabilität ist Voraussetzung für Idempotenz (Re-Imports ohne Duplikate).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 5. Frontmatter & Typen
|
|
||||||
|
|
||||||
- Pflichtfelder: `id`, `title`, `type`, `created`, `updated`, `tags`, `source_path`.
|
|
||||||
- Note-Typen (Auszug): `experience`, `principle`, `value`, `goal`, `role`, `persona`, `plan`, `project`, `journal`, `reference`, `translation`.
|
|
||||||
- **types.yaml** definiert Regeln/Defaults je Typ und für Relationstypen (siehe Abschnitt 10).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 6. Chunking-Strategie
|
|
||||||
|
|
||||||
- Satz- bis Absatz-Chunks, moderate Überlappung; Meta-Felder verweisen auf Note/Quelle.
|
|
||||||
- Named Vectors (z. B. `content`, optional `title`, `tags`) ermöglichen hybride Scores.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 7. Embeddings & Vektoren
|
|
||||||
|
|
||||||
- Einheitliche Metrik (cosine), reproduzierbares Embedding-Setup.
|
|
||||||
- Konsistenz über Zeit durch Versionsfeld (`embedding_model`, `embedding_version`).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 8. Volltext & Filter
|
|
||||||
|
|
||||||
- Textindex auf `mindnet_chunks.body` für exakte Term/Operator-Queries.
|
|
||||||
- Payload-Filter zur schnellen Einschränkung (tags, types, time-buckets, visibility u. a.).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. Edges – Beziehungen
|
|
||||||
|
|
||||||
- **Explizit**: Jede tatsächliche Beziehung wird als Kante gespeichert (kein Workaround).
|
|
||||||
- Felder u. a.: `src_id`, `dst_id`, `relation`, `direction`, `confidence (0–1)`, `evidence` (Chunk-IDs), `created_at`, `updated_at`.
|
|
||||||
- **edge_defaults** liefern **Interpretations-Hints** (Gewichte, Symmetrie, Transitivität) und parametrisieren abgeleitete Edges; sie **ersetzen** keine Originalkanten.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. Regeln & Policies (types.yaml)
|
|
||||||
|
|
||||||
- Per Typ/Relation:
|
|
||||||
- Default-Eigenschaften (Gewicht, Directedness, Symmetrie, Transitivität).
|
|
||||||
- Scoring-Hooks für Graph-Kontext im Retriever.
|
|
||||||
- (später) Privacy-Hooks je Relation (Mindest-Visibility).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 11. Retrieval & Ranking (Komposition)
|
|
||||||
|
|
||||||
- Hybrid: Vektor-Score + Filter + optional BM25/Volltext.
|
|
||||||
- Zeitgewicht (Decays) und Graph-Kontext werden komponiert (Formel siehe 16.3).
|
|
||||||
- Konfiguration über `.env`/`config.yaml` (gewichts- und halbwertszeit-basiert).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 12. Erklärbarkeit
|
|
||||||
|
|
||||||
- „Warum-Pfad“: Top-Chunks mit Score-Zerlegung (Vektor/Time/Graph), Graph-Kette, Provenienz.
|
|
||||||
- Mehrschichtige Narrative (Kindheit/Erlebnisse, Werte/Prinzipien, Ziele/Leitbild, Gegenwart).
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 13. Betrieb & Sicherheit
|
|
||||||
|
|
||||||
- Lokal auf Single-Node starten (Backups via Snapshots).
|
|
||||||
- Zugriff nur intern/Reverse-Proxy; Festplattenverschlüsselung OS-seitig.
|
|
||||||
- Migrationspfad zu Qdrant-Distributed (Shards, Replikation) einplanen.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 14. Qualität & Monitoring
|
|
||||||
|
|
||||||
- Offline-Eval-Sets, Telemetrie (lokal), Drift-Checks, manuelle Reviews.
|
|
||||||
- Kennzahlen: Hit-Rate, Overlap, Quellen-Alter, Erklärungspfad-Nutzung.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 15. Offene Punkte
|
|
||||||
|
|
||||||
- Ausdetaillierung `types.yaml` (Relationen, Hooks).
|
|
||||||
- UI-Oberfläche für Erklärpfade und Provenienz.
|
|
||||||
- Batch-Jobs für abgeleitete Edges.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 16. Ergänzungen 2025-11-09 (v1.5.0)
|
|
||||||
|
|
||||||
**Kontext:** Basierend auf den neuen Rahmenbedingungen (nur Deutsch; perspektivische externe Abfragen; einheitliche Vertraulichkeit mit Option auf feinere Stufen; Recency-Priorisierung als Default; Regeln später konfigurierbar; zunächst lokale Speicherung mit optionaler Migration; heutige Hardware, später skalierbar; hohe Erklärbarkeit mit mehreren Erklärungsebenen) werden folgende Entscheidungen und Erweiterungen getroffen. Alle bisherigen Inhalte bleiben gültig und werden **nicht** verändert.
|
|
||||||
|
|
||||||
### 16.1 Sprach- und Inhaltsrichtlinie (nur Deutsch)
|
|
||||||
- `lang: "de"` als verpflichtendes Feld in allen Note-, Chunk- und Edge-Payloads.
|
|
||||||
- Für spätere Mehrsprachigkeit **nicht** die Collection splitten, sondern ein Feld `lang` + optional `lang_original` behalten; Translation-Artefakte als eigener `type: translation` (verweisend auf `source_id`).
|
|
||||||
|
|
||||||
### 16.2 Vertraulichkeit & Sichtbarkeit
|
|
||||||
- Heute: einheitliche Stufe `visibility: "internal"`.
|
|
||||||
- Vorausschauend: reservierte Felder in allen Payloads
|
|
||||||
- `visibility`: `"public" | "internal" | "restricted"`
|
|
||||||
- `sensitivity`: Integer 0–3 (0 = unkritisch, 3 = hochsensibel)
|
|
||||||
- `acl`: Liste erlaubter Rollen/Personen-IDs (App-Layer erzwingt Filter vor Query).
|
|
||||||
- Access-Control erfolgt **im Applikations-Layer** mittels Qdrant-Payload-Filtern (`must: [ { key: "visibility", match: { any: [...] }}, ... ]`); Qdrant bleibt „dumm“ in Bezug auf ACL.
|
|
||||||
|
|
||||||
### 16.3 Recency-Modell & Ranking (konfigurierbar)
|
|
||||||
- Default: **Zeitnähe** priorisieren (sanfte Abwertung älterer Inhalte).
|
|
||||||
- Im Retrieval kombinieren wir:
|
|
||||||
1) Vektor-Score (cosine) aus Qdrant
|
|
||||||
2) Zeitgewicht `time_decay = exp( - ln(2) * age_days / half_life_days )`
|
|
||||||
3) Graph-Kontext aus Edges (z. B. Degree, Path-Hops zum Anker „Ich/Persona“)
|
|
||||||
- Konfigurierbare Gewichte (per `.env` oder `config.yaml`):
|
|
||||||
```text
|
|
||||||
FINAL_SCORE = w_vec * norm(vec_score)
|
|
||||||
+ w_time * time_decay
|
|
||||||
+ w_graph * graph_context_score
|
|
||||||
# Vorschlag: w_vec=0.70, w_time=0.20, w_graph=0.10; half_life_days=365
|
|
||||||
```
|
|
||||||
- Für Fragen, die „zeitlos“ sind, kann `half_life_days = inf` gesetzt werden (kein Decay).
|
|
||||||
|
|
||||||
### 16.4 Erklärbarkeit („Warum diese Antwort?“)
|
|
||||||
- Jeder Antwort wird ein **Erklärpfad** mitgegeben (optional im UI):
|
|
||||||
- Top-Chunks (mit Score-Zerlegung w_vec/w_time/w_graph)
|
|
||||||
- **Kausalpfad** im Graphen: `Note → Edge(relation, confidence) → Note …`
|
|
||||||
- **Provenienz** (Quelle, Erstellungszeit, letzte Änderung).
|
|
||||||
- Ein **Multi-Layer-Explanations**-Modul ordnet Beiträge zu: Kindheit/Erlebnisse, Werte & Prinzipien, aktuelle Ziele/Leitbild, Gegenwartskontext.
|
|
||||||
|
|
||||||
### 16.5 Qdrant-Schemata (Ergänzungen, rückwärtskompatibel)
|
|
||||||
- **Collections** bleiben: `mindnet_notes`, `mindnet_chunks`, `mindnet_edges` (+ `mindnet_people` falls noch nicht vorhanden).
|
|
||||||
- Gemeinsame Zusatzfelder (alle Payloads):
|
|
||||||
- `lang: "de"`
|
|
||||||
- `visibility`/`sensitivity`/`acl` (s. 16.2)
|
|
||||||
- `created_at` (ISO-8601), `updated_at` (ISO-8601), `age_days` (App-seitig berechnet)
|
|
||||||
- **Chunks**:
|
|
||||||
- Named-Vectors (z. B. `"content"`, optional `"title"`, `"tags"` für Hybrid-Scores).
|
|
||||||
- `text_index` auf `body` für BM25-ähnliche Volltextsuche (Qdrant-Textindex).
|
|
||||||
- `recency_group`: Jahr-Monat `YYYY-MM` (ermöglicht Pre-Filter für „letzte N Monate“).
|
|
||||||
- **Edges** (explizit, keine Workarounds):
|
|
||||||
- Felder: `src_id`, `dst_id`, `relation`, `direction`, `confidence` (0–1), `evidence` (Chunk-IDs), `created_at`, `updated_at`.
|
|
||||||
- **edge_defaults** bleiben als **Interpretations-Hints**: z. B. `default_weight`, `symmetry`, `transitivity`. Sie ersetzen **nicht** echte Kanten, sondern parametrisieren abgeleitete/zusätzliche Kantenbildung.
|
|
||||||
- Abgeleitete Edges: optionaler Batch-Job erzeugt *ergänzende* Kanten entlang `types.yaml`-Regeln (z. B. Backlinks, „inspired_by“ aus Zitaten), niemals statt der Originalkanten.
|
|
||||||
|
|
||||||
### 16.6 Regeln & Typen (konfigurierbar)
|
|
||||||
- `types.yaml` erweitert um:
|
|
||||||
- Relationstypen mit Default-Eigenschaften (`weight`, `directed`, `symmetric`, `transitive`).
|
|
||||||
- **Scoring-Hooks**: pro Relation optionaler Einfluss auf `graph_context_score`.
|
|
||||||
- **Privacy-Hooks**: pro Relation Minimal-Visibility (z. B. Beziehungen zu Personen sind mindestens `internal`).
|
|
||||||
|
|
||||||
### 16.7 Speicher- & Betriebsstrategie (heute lokal, später skalierbar)
|
|
||||||
- **Heute**: Single-Node Qdrant mit HNSW-Index, Text-Index und Payload-Filtern; regelmäßiges Backup (Snapshots).
|
|
||||||
- **Morgen**: Migrationspfad in **Qdrant-Distributed** (Shards, ggf. Replikation) bei Bedarf; Parameter-Gleichheit sichern (named-vectors, Metrik, HNSW-Param).
|
|
||||||
- **Sicherheit**: Zugriff nur über internes Netz/Reverse-Proxy, Auth vor Qdrant; Festplatten-Verschlüsselung auf OS-Ebene (z. B. LUKS).
|
|
||||||
|
|
||||||
### 16.8 Persona-Layer („meine Essenz“)
|
|
||||||
- Eigenständiger **Persona-Knoten** (z. B. Note `person/lars`), verbunden mit:
|
|
||||||
- Werten/Prinzipien, Leitbild, prägenden Erlebnissen, Zielen, Rollen.
|
|
||||||
- Jede Antwort kann gegen diesen Knoten **kontextualisiert** werden (Graph-Pfadnähe).
|
|
||||||
- Feld `persona_weight` in Chunks/Notes zur Priorisierung persönlicher Relevanz.
|
|
||||||
|
|
||||||
### 16.9 Evaluierung & Qualitätssicherung
|
|
||||||
- **Offline-Sets** aus echten Fragen (inkl. gewünschter Perspektiven) mit erwarteten Top-Quellen.
|
|
||||||
- **Telemetrie** (lokal): Query-Arten, Treffer-Overlaps, Zeitgewicht-Effekte, „Warum-Pfad“ genutzt/ignoriert.
|
|
||||||
- **Drift-Checks**: Anteil sehr alter vs. neuer Quellen in Antworten; manuelle Reviews.
|
|
||||||
|
|
||||||
### 16.10 Offene Punkte / Nächste Schritte
|
|
||||||
1) `types.yaml` um Relationseigenschaften erweitern (s. 16.6).
|
|
||||||
2) Retriever-Komposition inkl. Zeitgewicht (s. 16.3) implementieren.
|
|
||||||
3) Explanations-Pfad inkl. Provenienzoberfläche (s. 16.4) im UI.
|
|
||||||
4) Feld-Erweiterungen in Import-Pipelines (`lang`, `visibility`, Zeitfelder).
|
|
||||||
5) Optional: Batch-Job für abgeleitete Edges nach Regeln (ergänzend, nicht ersetzend).
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
# Mindnet v2.2 – Fachliche Architektur
|
# Mindnet v2.2 – Fachliche Architektur
|
||||||
**Datei:** `docs/mindnet_functional_architecture_v2.2.md`
|
**Datei:** `docs/mindnet_functional_architecture_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Integrierter Stand WP01–WP05)
|
**Status:** **FINAL** (Integrierter Stand WP01–WP06)
|
||||||
|
|
||||||
> 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 neuen **RAG-Chat** (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 neuen **RAG-Chat** (Decision Engine & Persönlichkeit). Die technische Umsetzung wird im technischen Dokument detailliert.
|
||||||
|
|
||||||
---
|
---
|
||||||
<details>
|
<details>
|
||||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
||||||
|
|
||||||
- [Mindnet v2.2 – Fachliche Architektur](#mindnet-v22--fachliche-architektur)
|
- [Mindnet v2.2 – Fachliche Architektur](#mindnet-v22--fachliche-architektur)
|
||||||
|
- [](#)
|
||||||
- [0) Zielbild \& Grundprinzip](#0-zielbild--grundprinzip)
|
- [0) Zielbild \& Grundprinzip](#0-zielbild--grundprinzip)
|
||||||
- [1) Notizen \& Chunks (fachliche Perspektive)](#1-notizen--chunks-fachliche-perspektive)
|
- [1) Notizen \& Chunks (fachliche Perspektive)](#1-notizen--chunks-fachliche-perspektive)
|
||||||
- [1.1 Notiz (Note)](#11-notiz-note)
|
- [1.1 Notiz (Note)](#11-notiz-note)
|
||||||
|
|
@ -25,21 +26,27 @@
|
||||||
- [5) Der Retriever (Funktionaler Layer)](#5-der-retriever-funktionaler-layer)
|
- [5) Der Retriever (Funktionaler Layer)](#5-der-retriever-funktionaler-layer)
|
||||||
- [5.1 Scoring-Modell](#51-scoring-modell)
|
- [5.1 Scoring-Modell](#51-scoring-modell)
|
||||||
- [5.2 Erklärbarkeit (Explainability) – WP04b](#52-erklärbarkeit-explainability--wp04b)
|
- [5.2 Erklärbarkeit (Explainability) – WP04b](#52-erklärbarkeit-explainability--wp04b)
|
||||||
- [6) Der RAG-Chat \& Persönlichkeit (WP05)](#6-der-rag-chat--persönlichkeit-wp05)
|
- [6) Context Intelligence \& Intent Router (WP06)](#6-context-intelligence--intent-router-wp06)
|
||||||
- [6.1 Stil \& Tonfall (System Prompt)](#61-stil--tonfall-system-prompt)
|
- [6.1 Das Problem: Statische vs. Dynamische Antworten](#61-das-problem-statische-vs-dynamische-antworten)
|
||||||
- [6.2 Strategische Persönlichkeit (Ausblick WP06)](#62-strategische-persönlichkeit-ausblick-wp06)
|
- [6.2 Der Intent-Router (Keyword \& Semantik)](#62-der-intent-router-keyword--semantik)
|
||||||
- [7) Erweiterbarkeit \& Teaching (Context Intelligence)](#7-erweiterbarkeit--teaching-context-intelligence)
|
- [6.3 Strategic Retrieval (Injektion von Werten)](#63-strategic-retrieval-injektion-von-werten)
|
||||||
|
- [6.4 Reasoning (Das Gewissen)](#64-reasoning-das-gewissen)
|
||||||
|
- [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)
|
||||||
|
- [7.3 Glaubenssätze \& Rituale](#73-glaubenssätze--rituale)
|
||||||
|
- [8) Erweiterbarkeit \& Teaching (Context Intelligence)](#8-erweiterbarkeit--teaching-context-intelligence)
|
||||||
- [A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)](#a-workflow-einen-neuen-typ-implementieren-z-b-type-risk)
|
- [A. Workflow: Einen neuen Typ implementieren (z. B. `type: risk`)](#a-workflow-einen-neuen-typ-implementieren-z-b-type-risk)
|
||||||
- [B. Workflow: Neue Beziehungen nutzen (z. B. `beeinflusst_von`)](#b-workflow-neue-beziehungen-nutzen-z-b-beeinflusst_von)
|
- [B. Workflow: Neue Beziehungen nutzen (z. B. `beeinflusst_von`)](#b-workflow-neue-beziehungen-nutzen-z-b-beeinflusst_von)
|
||||||
- [8) Feedback \& Lernen – WP04c](#8-feedback--lernen--wp04c)
|
- [9) Feedback \& Lernen – WP04c](#9-feedback--lernen--wp04c)
|
||||||
- [8.1 Der Feedback-Loop](#81-der-feedback-loop)
|
- [9.1 Der Feedback-Loop](#91-der-feedback-loop)
|
||||||
- [9) Confidence \& Provenance – wozu?](#9-confidence--provenance--wozu)
|
- [10) Confidence \& Provenance – wozu?](#10-confidence--provenance--wozu)
|
||||||
- [10) Semantik ausgewählter `kind`-Werte](#10-semantik-ausgewählter-kind-werte)
|
- [11) Semantik ausgewählter `kind`-Werte](#11-semantik-ausgewählter-kind-werte)
|
||||||
- [11) Frontmatter-Eigenschaften – Rolle \& Empfehlung](#11-frontmatter-eigenschaften--rolle--empfehlung)
|
- [12) Frontmatter-Eigenschaften – Rolle \& Empfehlung](#12-frontmatter-eigenschaften--rolle--empfehlung)
|
||||||
- [12) Lösch-/Update-Garantien (Idempotenz)](#12-lösch-update-garantien-idempotenz)
|
- [13) Lösch-/Update-Garantien (Idempotenz)](#13-lösch-update-garantien-idempotenz)
|
||||||
- [13) Beispiel – Von Markdown zu Kanten (v2.2)](#13-beispiel--von-markdown-zu-kanten-v22)
|
- [14) Beispiel – Von Markdown zu Kanten (v2.2)](#14-beispiel--von-markdown-zu-kanten-v22)
|
||||||
- [14) Referenzen (Projektdateien \& Leitlinien)](#14-referenzen-projektdateien--leitlinien)
|
- [15) Referenzen (Projektdateien \& Leitlinien)](#15-referenzen-projektdateien--leitlinien)
|
||||||
- [15) Workpackage Status (v2.3.0)](#15-workpackage-status-v230)
|
- [16) Workpackage Status (v2.3.1)](#16-workpackage-status-v231)
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
---
|
---
|
||||||
|
|
@ -201,24 +208,62 @@ Die API gibt diese Analysen als menschenlesbare Sätze (`reasons`) und als Daten
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6) Der RAG-Chat & Persönlichkeit (WP05)
|
## 6) Context Intelligence & Intent Router (WP06)
|
||||||
|
|
||||||
Seit WP-05 kann Mindnet nicht nur suchen, sondern als **KI-Zwilling** antworten. Die Persönlichkeit entsteht dabei auf zwei Ebenen:
|
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.
|
||||||
|
|
||||||
### 6.1 Stil & Tonfall (System Prompt)
|
### 6.1 Das Problem: Statische vs. Dynamische Antworten
|
||||||
In `config/prompts.yaml` wird die Persona definiert.
|
* **Früher (Pre-WP06):** Jede Frage ("Was ist X?" oder "Soll ich X?") wurde gleich behandelt -> Fakten-Retrieval.
|
||||||
* **System Prompt:** Definiert die Rolle ("Ich bin dein digitales Gedächtnis...").
|
* **Heute (WP06):** Das System erkennt, *was* der User will, und lädt unterschiedliche Wissensbausteine.
|
||||||
* **Werte im Prompt:** Pragmatismus, Transparenz (kein Halluzinieren), Vernetztes Denken.
|
|
||||||
* **Context Intelligence:** Dem LLM werden Metadaten (Typ, Score) injiziert, damit es komplexe Zusammenhänge erkennt (z.B. dass eine `[DECISION]` wichtiger ist als ein `[CONCEPT]`).
|
|
||||||
|
|
||||||
### 6.2 Strategische Persönlichkeit (Ausblick WP06)
|
### 6.2 Der Intent-Router (Keyword & Semantik)
|
||||||
Ein echter KI-Zwilling spiegelt nicht nur den Stil, sondern die **Werte** des Users wider.
|
Der Router prüft vor jeder Antwort die Absicht über konfigurierbare Strategien (`config/decision_engine.yaml`):
|
||||||
* **Logik:** Bei komplexen Fragen oder Entscheidungen ("Soll ich X tun?") lädt das System gezielt Notizen vom Typ `[VALUE]` und `[PRINCIPLE]` in den Kontext.
|
|
||||||
* **Effekt:** Das System wägt die Fakten (aus der Suche) gegen die Werte (aus dem Profil) ab.
|
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.
|
||||||
|
|
||||||
|
### 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:
|
||||||
|
* **Values (`type: value`):** Moralische Werte (z.B. "Privacy First").
|
||||||
|
* **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").
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7) Erweiterbarkeit & Teaching (Context Intelligence)
|
## 7) Future Concepts: The Empathic Digital Twin (Ausblick)
|
||||||
|
|
||||||
|
Um Mindnet von einer Entscheidungsmaschine zu einem echten **Spiegel der Persönlichkeit** zu entwickeln, sind folgende Erweiterungen konzeptionell vorgesehen:
|
||||||
|
|
||||||
|
### 7.1 Antizipation durch Erfahrung
|
||||||
|
* **Konzept:** Das System soll Konsequenzen vorhersagen ("Was passiert, wenn...?").
|
||||||
|
* **Umsetzung:** Neben Werten werden vergangene Erfahrungen (`type: experience`) geladen.
|
||||||
|
* **Logik:** *"In einer ähnlichen Situation (Projekt A) hat Entscheidung X zu Ergebnis Y geführt."*
|
||||||
|
|
||||||
|
### 7.2 Empathie & "Ich"-Modus
|
||||||
|
* **Konzept:** Das System antwortet nicht wie ein Roboter, sondern im Tonfall und Stil des Nutzers.
|
||||||
|
* **Umsetzung (Few-Shot Prompting):** Der System-Prompt wird dynamisch mit Beispielen gefüttert, wie der Nutzer typischerweise auf E-Mails oder Fragen antwortet.
|
||||||
|
* **Datenbasis:** `type: profile` oder `type: manifesto` definieren das Selbstbild.
|
||||||
|
|
||||||
|
### 7.3 Glaubenssätze & Rituale
|
||||||
|
* **Konzept:** Berücksichtigung weicher Faktoren und Gewohnheiten.
|
||||||
|
* **Umsetzung:** Erweiterung der `decision_engine.yaml` um `inject_types: ["belief", "ritual"]`.
|
||||||
|
* **Szenario:** Bei Terminplanungen werden Rituale ("Keine Meetings vor 10 Uhr") automatisch als harte Restriktion gegen Anfragen geprüft.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8) Erweiterbarkeit & Teaching (Context Intelligence)
|
||||||
|
|
||||||
Mindnet lernt nicht durch klassisches Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Dies ist das **"Teach-the-AI" Paradigma**: Wenn du dem System ein neues Konzept beibringen willst, musst du an drei Stellen eingreifen.
|
Mindnet lernt nicht durch klassisches Training (Fine-Tuning), sondern durch **Konfiguration**, **Vernetzung** und **Prompting**. Dies ist das **"Teach-the-AI" Paradigma**: Wenn du dem System ein neues Konzept beibringen willst, musst du an drei Stellen eingreifen.
|
||||||
|
|
||||||
|
|
@ -234,15 +279,8 @@ Mindnet lernt nicht durch klassisches Training (Fine-Tuning), sondern durch **Ko
|
||||||
```
|
```
|
||||||
*Effekt:* Der Retriever spült diese Notizen bei relevanten Anfragen nach oben.
|
*Effekt:* Der Retriever spült diese Notizen bei relevanten Anfragen nach oben.
|
||||||
|
|
||||||
2. **Semantik erklären (`config/prompts.yaml`)**
|
2. **Semantik erklären (`config/prompts.yaml` / `decision_engine.yaml`)**
|
||||||
Bringe dem LLM bei, wie es mit diesem Typ umgehen soll.
|
Bringe dem LLM bei, wie es mit diesem Typ umgehen soll. Füge `risk` zur `DECISION`-Strategie hinzu (`inject_types`), damit es bei Entscheidungen geladen wird.
|
||||||
```yaml
|
|
||||||
system_prompt: |
|
|
||||||
...
|
|
||||||
REGELN FÜR TYPEN:
|
|
||||||
- [RISK]: Warnung! Wenn ein Chunk vom Typ 'risk' im Kontext ist, weise den User explizit darauf hin.
|
|
||||||
```
|
|
||||||
*Effekt:* Der Chatbot ignoriert das Risiko nicht nur, sondern "versteht" die Warnfunktion.
|
|
||||||
|
|
||||||
### B. Workflow: Neue Beziehungen nutzen (z. B. `beeinflusst_von`)
|
### B. Workflow: Neue Beziehungen nutzen (z. B. `beeinflusst_von`)
|
||||||
|
|
||||||
|
|
@ -270,11 +308,11 @@ Beziehungen sind der Klebstoff für logische Schlussfolgerungen.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8) Feedback & Lernen – WP04c
|
## 9) Feedback & Lernen – WP04c
|
||||||
|
|
||||||
Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, das die Basis für zukünftiges Lernen bildet.
|
Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, das die Basis für zukünftiges Lernen bildet.
|
||||||
|
|
||||||
### 8.1 Der Feedback-Loop
|
### 9.1 Der Feedback-Loop
|
||||||
1. **Suche (Situation):**
|
1. **Suche (Situation):**
|
||||||
Wenn ein Nutzer eine Anfrage stellt, loggt Mindnet die "Situation":
|
Wenn ein Nutzer eine Anfrage stellt, loggt Mindnet die "Situation":
|
||||||
* Den Query-Text.
|
* Den Query-Text.
|
||||||
|
|
@ -291,7 +329,7 @@ Das System verfügt nun über ein **Kurzzeitgedächtnis für Interaktionen**, da
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 9) Confidence & Provenance – wozu?
|
## 10) Confidence & Provenance – wozu?
|
||||||
|
|
||||||
Der Retriever kann Edges gewichten:
|
Der Retriever kann Edges gewichten:
|
||||||
- **provenance**: *explicit* > *rule*
|
- **provenance**: *explicit* > *rule*
|
||||||
|
|
@ -303,7 +341,7 @@ Eine typische Gewichtung (konfigurierbar in `retriever.yaml`) ist:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 10) Semantik ausgewählter `kind`-Werte
|
## 11) Semantik ausgewählter `kind`-Werte
|
||||||
|
|
||||||
- `references` – „Nutzt/erwähnt“; neutral, aber stützend für Kontext.
|
- `references` – „Nutzt/erwähnt“; neutral, aber stützend für Kontext.
|
||||||
- `related_to` – Ähnlichkeit/Verwandtschaft (symmetrisch interpretierbar).
|
- `related_to` – Ähnlichkeit/Verwandtschaft (symmetrisch interpretierbar).
|
||||||
|
|
@ -315,7 +353,7 @@ Eine typische Gewichtung (konfigurierbar in `retriever.yaml`) ist:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 11) Frontmatter-Eigenschaften – Rolle & Empfehlung
|
## 12) Frontmatter-Eigenschaften – Rolle & Empfehlung
|
||||||
|
|
||||||
Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
||||||
- **type** – steuert Typ-Defaults via Registry (Pflicht für differenziertes Verhalten).
|
- **type** – steuert Typ-Defaults via Registry (Pflicht für differenziertes Verhalten).
|
||||||
|
|
@ -325,7 +363,7 @@ Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 12) Lösch-/Update-Garantien (Idempotenz)
|
## 13) Lösch-/Update-Garantien (Idempotenz)
|
||||||
|
|
||||||
- Jede Note hat einen stabilen **note_id** (Frontmatter/Hash).
|
- Jede Note hat einen stabilen **note_id** (Frontmatter/Hash).
|
||||||
- Vor einem Upsert können *alte Chunks/Edges einer Note* gefiltert gelöscht werden (`note_id`-Filter) – das hält Collections sauber bei Re-Imports.
|
- Vor einem Upsert können *alte Chunks/Edges einer Note* gefiltert gelöscht werden (`note_id`-Filter) – das hält Collections sauber bei Re-Imports.
|
||||||
|
|
@ -333,7 +371,7 @@ Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 13) Beispiel – Von Markdown zu Kanten (v2.2)
|
## 14) Beispiel – Von Markdown zu Kanten (v2.2)
|
||||||
|
|
||||||
**Markdown (Auszug)**
|
**Markdown (Auszug)**
|
||||||
# Relations Showcase
|
# Relations Showcase
|
||||||
|
|
@ -352,18 +390,19 @@ Frontmatter-Eigenschaften (Properties) bleiben **minimiert**:
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 14) Referenzen (Projektdateien & Leitlinien)
|
## 15) Referenzen (Projektdateien & Leitlinien)
|
||||||
|
|
||||||
- Import-Pipeline & Registry-Auflösung: `scripts/import_markdown.py`.
|
- Import-Pipeline & Registry-Auflösung: `scripts/import_markdown.py`.
|
||||||
- Kantenbildung (V2-Logic): `app/core/derive_edges.py`.
|
- Kantenbildung (V2-Logic): `app/core/derive_edges.py`.
|
||||||
- Typ-Registry: `config/types.yaml` & `TYPE_REGISTRY_MANUAL.md`.
|
- Typ-Registry: `config/types.yaml` & `TYPE_REGISTRY_MANUAL.md`.
|
||||||
- Retriever-Scoring & Explanation: `app/core/retriever.py`.
|
- Retriever-Scoring & Explanation: `app/core/retriever.py`.
|
||||||
- Persönlichkeit & Chat: `config/prompts.yaml` & `app/routers/chat.py`.
|
- Persönlichkeit & Chat: `config/prompts.yaml` & `app/routers/chat.py`.
|
||||||
|
- Decision Engine: `config/decision_engine.yaml`.
|
||||||
- Logging Service: `app/services/feedback_service.py`.
|
- Logging Service: `app/services/feedback_service.py`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 15) Workpackage Status (v2.3.0)
|
## 16) Workpackage Status (v2.3.1)
|
||||||
|
|
||||||
Aktueller Implementierungsstand der Module.
|
Aktueller Implementierungsstand der Module.
|
||||||
|
|
||||||
|
|
@ -376,5 +415,5 @@ Aktueller Implementierungsstand der Module.
|
||||||
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
|
| **WP04b**| Explanation Layer | 🟢 Live | API liefert Reasons & Breakdown. |
|
||||||
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
| **WP04c**| Feedback Loop | 🟢 Live | Logging (JSONL) & Traceability aktiv. |
|
||||||
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
|
| **WP05** | Persönlichkeit / Chat | 🟢 Live | RAG-Integration mit Context Enrichment. |
|
||||||
| **WP06** | Decision Engine | 🟡 Geplant | Fokus: Strategic Retrieval von Werten. |
|
| **WP06** | Decision Engine | 🟢 Live | Intent-Router & Strategic Retrieval. |
|
||||||
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
| **WP08** | Self-Tuning | 🔴 Geplant | Auto-Adjustment der Gewichte. |
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
# Mindnet v2.2 – Technische Architektur
|
# Mindnet v2.2 – Technische Architektur
|
||||||
**Datei:** `docs/mindnet_technical_architecture_v2.2.md`
|
**Datei:** `docs/mindnet_technical_architecture_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Integrierter Stand WP01–WP05)
|
**Status:** **FINAL** (Integrierter Stand WP01–WP06)
|
||||||
**Quellen:** `Programmplan_V2.2.md`, `Handbuch.md`, `chunking_strategy.md`, `wp04_retriever_scoring.md`.
|
**Quellen:** `Programmplan_V2.2.md`, `Handbuch.md`, `chunking_strategy.md`, `wp04_retriever_scoring.md`.
|
||||||
|
|
||||||
> **Ziel dieses Dokuments:**
|
> **Ziel dieses Dokuments:**
|
||||||
> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik und der **neuen RAG-Komponenten (LLM/Chat)**.
|
> Vollständige Beschreibung der technischen Architektur inkl. Graph-Datenbank, Retrieval-Logik und der **neuen RAG-Komponenten (Decision Engine & Hybrid Router)**.
|
||||||
|
|
||||||
---
|
---
|
||||||
<details>
|
<details>
|
||||||
|
|
@ -15,7 +15,7 @@
|
||||||
- [](#)
|
- [](#)
|
||||||
- [1. Systemüberblick](#1-systemüberblick)
|
- [1. Systemüberblick](#1-systemüberblick)
|
||||||
- [1.1 Architektur-Zielbild](#11-architektur-zielbild)
|
- [1.1 Architektur-Zielbild](#11-architektur-zielbild)
|
||||||
- [1.2 Verzeichnisstruktur \& Komponenten (Post-WP05)](#12-verzeichnisstruktur--komponenten-post-wp05)
|
- [1.2 Verzeichnisstruktur \& Komponenten (Post-WP06)](#12-verzeichnisstruktur--komponenten-post-wp06)
|
||||||
- [2. Datenmodell \& Collections (Qdrant)](#2-datenmodell--collections-qdrant)
|
- [2. Datenmodell \& Collections (Qdrant)](#2-datenmodell--collections-qdrant)
|
||||||
- [2.1 Notes Collection (`<prefix>_notes`)](#21-notes-collection-prefix_notes)
|
- [2.1 Notes Collection (`<prefix>_notes`)](#21-notes-collection-prefix_notes)
|
||||||
- [2.2 Chunks Collection (`<prefix>_chunks`)](#22-chunks-collection-prefix_chunks)
|
- [2.2 Chunks Collection (`<prefix>_chunks`)](#22-chunks-collection-prefix_chunks)
|
||||||
|
|
@ -23,8 +23,9 @@
|
||||||
- [3. Konfiguration](#3-konfiguration)
|
- [3. Konfiguration](#3-konfiguration)
|
||||||
- [3.1 Typ-Registry (`config/types.yaml`)](#31-typ-registry-configtypesyaml)
|
- [3.1 Typ-Registry (`config/types.yaml`)](#31-typ-registry-configtypesyaml)
|
||||||
- [3.2 Retriever-Config (`config/retriever.yaml`)](#32-retriever-config-configretrieveryaml)
|
- [3.2 Retriever-Config (`config/retriever.yaml`)](#32-retriever-config-configretrieveryaml)
|
||||||
- [3.3 Prompts (`config/prompts.yaml`)](#33-prompts-configpromptsyaml)
|
- [3.3 Decision Engine (`config/decision_engine.yaml`)](#33-decision-engine-configdecision_engineyaml)
|
||||||
- [3.4 Environment (`.env`)](#34-environment-env)
|
- [3.4 Prompts (`config/prompts.yaml`)](#34-prompts-configpromptsyaml)
|
||||||
|
- [3.5 Environment (`.env`)](#35-environment-env)
|
||||||
- [4. Import-Pipeline (Markdown → Qdrant)](#4-import-pipeline-markdown--qdrant)
|
- [4. Import-Pipeline (Markdown → Qdrant)](#4-import-pipeline-markdown--qdrant)
|
||||||
- [4.1 Verarbeitungsschritte](#41-verarbeitungsschritte)
|
- [4.1 Verarbeitungsschritte](#41-verarbeitungsschritte)
|
||||||
- [5. Retriever-Architektur \& Scoring](#5-retriever-architektur--scoring)
|
- [5. Retriever-Architektur \& Scoring](#5-retriever-architektur--scoring)
|
||||||
|
|
@ -32,11 +33,12 @@
|
||||||
- [5.2 Scoring-Formel (WP04a)](#52-scoring-formel-wp04a)
|
- [5.2 Scoring-Formel (WP04a)](#52-scoring-formel-wp04a)
|
||||||
- [5.3 Explanation Layer (WP04b)](#53-explanation-layer-wp04b)
|
- [5.3 Explanation Layer (WP04b)](#53-explanation-layer-wp04b)
|
||||||
- [5.4 Graph-Expansion](#54-graph-expansion)
|
- [5.4 Graph-Expansion](#54-graph-expansion)
|
||||||
- [6. RAG \& Chat Architektur (WP05)](#6-rag--chat-architektur-wp05)
|
- [6. RAG \& Chat Architektur (WP06 Hybrid Router)](#6-rag--chat-architektur-wp06-hybrid-router)
|
||||||
- [6.1 Schritt 1: Intent \& Retrieval](#61-schritt-1-intent--retrieval)
|
- [6.1 Architektur-Pattern: Intent Router](#61-architektur-pattern-intent-router)
|
||||||
- [6.2 Schritt 2: Context Enrichment (Das "Context Intelligence" Pattern)](#62-schritt-2-context-enrichment-das-context-intelligence-pattern)
|
- [6.2 Schritt 1: Intent Detection (Hybrid)](#62-schritt-1-intent-detection-hybrid)
|
||||||
- [6.3 Schritt 3: Generation (LLM Service)](#63-schritt-3-generation-llm-service)
|
- [6.3 Schritt 2: Strategy Resolution (Late Binding)](#63-schritt-2-strategy-resolution-late-binding)
|
||||||
- [6.4 Schritt 4: Response \& Traceability](#64-schritt-4-response--traceability)
|
- [6.4 Schritt 3: Multi-Stage Retrieval](#64-schritt-3-multi-stage-retrieval)
|
||||||
|
- [6.5 Schritt 4: Generation \& Response](#65-schritt-4-generation--response)
|
||||||
- [7. Feedback \& Logging Architektur (WP04c)](#7-feedback--logging-architektur-wp04c)
|
- [7. Feedback \& Logging Architektur (WP04c)](#7-feedback--logging-architektur-wp04c)
|
||||||
- [7.1 Komponenten](#71-komponenten)
|
- [7.1 Komponenten](#71-komponenten)
|
||||||
- [7.2 Log-Dateien](#72-log-dateien)
|
- [7.2 Log-Dateien](#72-log-dateien)
|
||||||
|
|
@ -60,9 +62,9 @@ Mindnet ist ein **lokales RAG-System (Retrieval Augmented Generation)**.
|
||||||
4. **Service:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit.
|
4. **Service:** Eine FastAPI-Anwendung stellt Endpunkte für **Semantische** und **Hybride Suche** sowie **Feedback** bereit.
|
||||||
5. **Inference:** Lokales LLM (Ollama: Phi-3 Mini) für RAG-Chat und Antwortgenerierung.
|
5. **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`, `prompts.yaml`).
|
Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsgetrieben** (`types.yaml`, `retriever.yaml`, `decision_engine.yaml`, `prompts.yaml`).
|
||||||
|
|
||||||
### 1.2 Verzeichnisstruktur & Komponenten (Post-WP05)
|
### 1.2 Verzeichnisstruktur & Komponenten (Post-WP06)
|
||||||
|
|
||||||
/mindnet/
|
/mindnet/
|
||||||
├── app/
|
├── app/
|
||||||
|
|
@ -77,20 +79,21 @@ Das System arbeitet **deterministisch** (stabile IDs) und ist **konfigurationsge
|
||||||
│ │ ├── derive_edges.py # Logik der Kantenableitung (WP03)
|
│ │ ├── derive_edges.py # Logik der Kantenableitung (WP03)
|
||||||
│ │ ├── graph_adapter.py # Subgraph & Reverse-Lookup (WP04b)
|
│ │ ├── graph_adapter.py # Subgraph & Reverse-Lookup (WP04b)
|
||||||
│ │ └── retriever.py # Scoring, Expansion & Explanation (WP04a/b)
|
│ │ └── retriever.py # Scoring, Expansion & Explanation (WP04a/b)
|
||||||
│ ├── models/ # Pydantic DTOs (QueryHit, Explanation, FeedbackRequest, ChatRequest)
|
│ ├── models/ # Pydantic DTOs
|
||||||
│ ├── routers/
|
│ ├── routers/
|
||||||
│ │ ├── query.py # Such-Endpunkt
|
│ │ ├── query.py # Such-Endpunkt
|
||||||
│ │ ├── chat.py # RAG-Chat Endpunkt (WP05)
|
│ │ ├── chat.py # Hybrid Router & Decision Engine (WP06)
|
||||||
│ │ ├── feedback.py # Feedback-Endpunkt (WP04c)
|
│ │ ├── feedback.py # Feedback-Endpunkt (WP04c)
|
||||||
│ │ └── ...
|
│ │ └── ...
|
||||||
│ ├── services/
|
│ ├── services/
|
||||||
│ │ ├── llm_service.py # Ollama Client (WP05)
|
│ │ ├── llm_service.py # Ollama Client mit Timeout & Raw-Mode
|
||||||
│ │ ├── feedback_service.py # JSONL Logging (WP04c)
|
│ │ ├── feedback_service.py # JSONL Logging (WP04c)
|
||||||
│ │ └── embeddings_client.py
|
│ │ └── embeddings_client.py
|
||||||
├── config/
|
├── config/
|
||||||
│ ├── types.yaml # Typ-Definitionen (Import-Zeit)
|
│ ├── types.yaml # Typ-Definitionen (Import-Zeit)
|
||||||
│ ├── retriever.yaml # Scoring-Gewichte (Laufzeit)
|
│ ├── retriever.yaml # Scoring-Gewichte (Laufzeit)
|
||||||
│ └── prompts.yaml # LLM System-Prompts & Templates (WP05)
|
│ ├── decision_engine.yaml # Strategien & Keywords (WP06)
|
||||||
|
│ └── prompts.yaml # LLM System-Prompts & Templates (WP06)
|
||||||
├── data/
|
├── data/
|
||||||
│ └── logs/ # Lokale JSONL-Logs (WP04c)
|
│ └── logs/ # Lokale JSONL-Logs (WP04c)
|
||||||
├── scripts/
|
├── scripts/
|
||||||
|
|
@ -181,20 +184,23 @@ Steuert das Scoring zur Laufzeit (WP04a).
|
||||||
edge_weight: 0.7
|
edge_weight: 0.7
|
||||||
centrality_weight: 0.5
|
centrality_weight: 0.5
|
||||||
|
|
||||||
### 3.3 Prompts (`config/prompts.yaml`)
|
### 3.3 Decision Engine (`config/decision_engine.yaml`)
|
||||||
Steuert die LLM-Persönlichkeit (WP05).
|
**Neu in WP06:** Steuert den Intent-Router.
|
||||||
* **Inhalt (Beispiel):**
|
* Definiert Strategien (`DECISION`, `EMPATHY`, `CODING`, `FACT`).
|
||||||
|
* Definiert `trigger_keywords` und `inject_types` (Late Binding).
|
||||||
|
* Definiert LLM-Router-Settings (`llm_fallback_enabled`).
|
||||||
|
|
||||||
system_prompt: |
|
### 3.4 Prompts (`config/prompts.yaml`)
|
||||||
Du bist 'mindnet', das KI-Gedächtnis.
|
Steuert die LLM-Persönlichkeit und Templates.
|
||||||
rag_template: |
|
* Enthält Templates für alle Strategien (z.B. `decision_template`, `empathy_template`, `technical_template`).
|
||||||
QUELLEN (WISSEN): {context_str}
|
|
||||||
|
|
||||||
### 3.4 Environment (`.env`)
|
### 3.5 Environment (`.env`)
|
||||||
Erweiterung für LLM-Steuerung:
|
Erweiterung für LLM-Steuerung:
|
||||||
|
|
||||||
MINDNET_LLM_MODEL=phi3:mini
|
MINDNET_LLM_MODEL=phi3:mini
|
||||||
MINDNET_OLLAMA_URL=http://127.0.0.1:11434
|
MINDNET_OLLAMA_URL=http://127.0.0.1:11434
|
||||||
|
MINDNET_LLM_TIMEOUT=300.0 # Neu: Erhöht für CPU-Inference Cold-Starts
|
||||||
|
MINDNET_DECISION_CONFIG="config/decision_engine.yaml"
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -259,30 +265,45 @@ Der Hybrid-Modus lädt dynamisch die Nachbarschaft der Top-K Vektor-Treffer ("Se
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 6. RAG & Chat Architektur (WP05)
|
## 6. RAG & Chat Architektur (WP06 Hybrid Router)
|
||||||
|
|
||||||
Der Flow für eine Chat-Anfrage (`/chat`) ist eine Pipeline aus vier Schritten.
|
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.
|
||||||
|
|
||||||
### 6.1 Schritt 1: Intent & Retrieval
|
### 6.1 Architektur-Pattern: Intent Router
|
||||||
* Der `ChatRouter` ruft den `Retriever` im **Hybrid-Modus** auf.
|
Die Behandlung einer Anfrage ist nicht mehr hartkodiert, sondern wird dynamisch zur Laufzeit entschieden.
|
||||||
* Dies stellt sicher, dass logisch verknüpfte Notizen (z.B. Entscheidungen zu einem Projekt) gefunden werden.
|
* **Input:** User Message.
|
||||||
|
* **Config:** `config/decision_engine.yaml` (Strategien & Keywords).
|
||||||
|
* **Komponenten:**
|
||||||
|
* **Fast Path:** Keyword Matching (CPU-schonend).
|
||||||
|
* **Slow Path:** LLM-basierter Semantic Router (für subtile Intents).
|
||||||
|
|
||||||
### 6.2 Schritt 2: Context Enrichment (Das "Context Intelligence" Pattern)
|
### 6.2 Schritt 1: Intent Detection (Hybrid)
|
||||||
* Der Router (`_build_enriched_context`) reichert die Chunks mit Metadaten an:
|
Der Router ermittelt die Absicht (`Intent`) des Nutzers.
|
||||||
* **Typ-Injection:** `[DECISION]`, `[PROJECT]`, `[CONCEPT]`.
|
1. **Keyword Scan (Fast Path):**
|
||||||
* **Score-Transparenz:** `(Score: 0.75)`.
|
* Iteration über alle Strategien in `decision_engine.yaml`.
|
||||||
* **Formatierung:** Markdown-Header pro Quelle.
|
* Prüfung auf `trigger_keywords`.
|
||||||
* *Ziel:* Kleine Modelle (SLMs wie Phi-3) benötigen diese expliziten Signale, um komplexe Zusammenhänge ("Warum nutzen wir X?") aus den Texten abzuleiten.
|
* **Best Match:** Bei mehreren Treffern gewinnt das längste/spezifischste Keyword (Robustheit gegen Shadowing).
|
||||||
|
2. **LLM Fallback (Slow Path):**
|
||||||
|
* 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).
|
||||||
|
|
||||||
### 6.3 Schritt 3: Generation (LLM Service)
|
### 6.3 Schritt 2: Strategy Resolution (Late Binding)
|
||||||
* **Service:** `app/services/llm_service.py` nutzt `httpx` (async).
|
Basierend auf dem Intent lädt der Router die Parameter:
|
||||||
* **Backend:** Ollama (lokal).
|
* **inject_types:** Liste der Notiz-Typen, die erzwungen werden sollen (z.B. `["value", "goal"]` bei `DECISION`).
|
||||||
* **Modell:** `phi3:mini` (3.8B Parameter).
|
* **prompt_template:** Schlüssel für das Template in `prompts.yaml` (z.B. `decision_template`, `empathy_template`).
|
||||||
* **Timeout:** Erhöht auf 300s für CPU-Inference Sicherheit.
|
|
||||||
|
|
||||||
### 6.4 Schritt 4: Response & Traceability
|
### 6.4 Schritt 3: Multi-Stage Retrieval
|
||||||
* Die Antwort enthält die generierte Nachricht **und** die verwendeten Quellen (`sources`).
|
1. **Primary Retrieval:** Hybride Suche nach der User-Query (findet Fakten).
|
||||||
* Eine `query_id` wird generiert und durchgereicht, um späteres Feedback (WP04c) zu ermöglichen.
|
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.
|
||||||
|
|
||||||
|
### 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).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
# mindnet v2.2 – Pipeline Playbook
|
# mindnet v2.2 – Pipeline Playbook
|
||||||
**Datei:** `docs/mindnet_pipeline_playbook_v2.2.md`
|
**Datei:** `docs/mindnet_pipeline_playbook_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Inkl. WP05 RAG Pipeline)
|
**Status:** **FINAL** (Inkl. WP06 Decision Engine)
|
||||||
**Quellen:** `mindnet_v2_implementation_playbook.md`, `Handbuch.md`, `chunking_strategy.md`, `docs_mindnet_retriever.md`, `mindnet_admin_guide_v2.2.md`.
|
**Quellen:** `mindnet_v2_implementation_playbook.md`, `Handbuch.md`, `chunking_strategy.md`, `docs_mindnet_retriever.md`, `mindnet_admin_guide_v2.2.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
<summary>📖 <b>Inhaltsverzeichnis (Klicken zum Öffnen)</b></summary>
|
||||||
|
|
||||||
- [mindnet v2.2 – Pipeline Playbook](#mindnet-v22--pipeline-playbook)
|
- [mindnet v2.2 – Pipeline Playbook](#mindnet-v22--pipeline-playbook)
|
||||||
|
- [](#)
|
||||||
- [1. Zweck \& Einordnung](#1-zweck--einordnung)
|
- [1. Zweck \& Einordnung](#1-zweck--einordnung)
|
||||||
- [2. Die Import-Pipeline (Runbook)](#2-die-import-pipeline-runbook)
|
- [2. Die Import-Pipeline (Runbook)](#2-die-import-pipeline-runbook)
|
||||||
- [2.1 Der 12-Schritte-Prozess](#21-der-12-schritte-prozess)
|
- [2.1 Der 12-Schritte-Prozess](#21-der-12-schritte-prozess)
|
||||||
|
|
@ -23,28 +24,27 @@
|
||||||
- [4.2 Typ-Defaults](#42-typ-defaults)
|
- [4.2 Typ-Defaults](#42-typ-defaults)
|
||||||
- [5. Retriever, Chat \& Generation (RAG Pipeline)](#5-retriever-chat--generation-rag-pipeline)
|
- [5. Retriever, Chat \& Generation (RAG Pipeline)](#5-retriever-chat--generation-rag-pipeline)
|
||||||
- [5.1 Retrieval (Hybrid)](#51-retrieval-hybrid)
|
- [5.1 Retrieval (Hybrid)](#51-retrieval-hybrid)
|
||||||
- [5.2 Context Enrichment (Das "Context Intelligence" Pattern)](#52-context-enrichment-das-context-intelligence-pattern)
|
- [5.2 Intent Router (WP06)](#52-intent-router-wp06)
|
||||||
- [5.3 Generation (LLM)](#53-generation-llm)
|
- [5.3 Context Enrichment](#53-context-enrichment)
|
||||||
- [5.4 Explanation Mode (WP04b)](#54-explanation-mode-wp04b)
|
- [5.4 Generation (LLM)](#54-generation-llm)
|
||||||
- [6. Feedback \& Lernen (WP04c)](#6-feedback--lernen-wp04c)
|
- [6. Feedback \& Lernen (WP04c)](#6-feedback--lernen-wp04c)
|
||||||
- [7. Quality Gates \& Tests](#7-quality-gates--tests)
|
- [7. Quality Gates \& Tests](#7-quality-gates--tests)
|
||||||
- [7.1 Pflicht-Tests vor Commit](#71-pflicht-tests-vor-commit)
|
- [7.1 Pflicht-Tests vor Commit](#71-pflicht-tests-vor-commit)
|
||||||
- [7.2 Smoke-Test (E2E)](#72-smoke-test-e2e)
|
- [7.2 Smoke-Test (E2E)](#72-smoke-test-e2e)
|
||||||
- [8. Ausblick \& Roadmap (Technische Skizzen)](#8-ausblick--roadmap-technische-skizzen)
|
- [8. Ausblick \& Roadmap (Technische Skizzen)](#8-ausblick--roadmap-technische-skizzen)
|
||||||
- [8.1 WP-06: Decision Engine (Skizze)](#81-wp-06-decision-engine-skizze)
|
- [8.1 WP-08: Self-Tuning (Skizze)](#81-wp-08-self-tuning-skizze)
|
||||||
- [8.2 WP-08: Self-Tuning (Skizze)](#82-wp-08-self-tuning-skizze)
|
|
||||||
|
|
||||||
|
|
||||||
|
</details>
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Zweck & Einordnung
|
## 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** 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) funktioniert.
|
||||||
|
|
||||||
**Zielgruppe:** Dev/Ops, Tech-Leads.
|
**Zielgruppe:** Dev/Ops, Tech-Leads.
|
||||||
**Scope:**
|
**Scope:**
|
||||||
* **Ist-Stand (WP01–WP05):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat, Feedback Loop.
|
* **Ist-Stand (WP01–WP06):** Import, Chunking, Edge-Erzeugung, Hybrider Retriever, RAG-Chat (Hybrid Router), Feedback Loop.
|
||||||
* **Roadmap (Ausblick):** Technische Skizzen für Self-Healing (WP06) und Self-Tuning (WP08).
|
* **Roadmap (Ausblick):** Technische Skizze für Self-Tuning (WP08).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -92,7 +92,7 @@ Nach einem Import oder Code-Update muss der API-Prozess neu gestartet werden.
|
||||||
|
|
||||||
# Neustart des Produktions-Services
|
# Neustart des Produktions-Services
|
||||||
sudo systemctl restart mindnet-prod
|
sudo systemctl restart mindnet-prod
|
||||||
|
|
||||||
# Prüfung
|
# Prüfung
|
||||||
sudo systemctl status mindnet-prod
|
sudo systemctl status mindnet-prod
|
||||||
|
|
||||||
|
|
@ -152,26 +152,24 @@ Wenn in `types.yaml` für einen Typ `edge_defaults` definiert sind, werden diese
|
||||||
Der Datenfluss endet nicht beim Finden. Er geht weiter bis zur Antwort.
|
Der Datenfluss endet nicht beim Finden. Er geht weiter bis zur Antwort.
|
||||||
|
|
||||||
### 5.1 Retrieval (Hybrid)
|
### 5.1 Retrieval (Hybrid)
|
||||||
total_score =
|
|
||||||
semantic_weight * semantic_score
|
|
||||||
+ edge_weight * edge_bonus
|
|
||||||
+ centrality_weight * centrality_bonus
|
|
||||||
+ type_weight * retriever_weight
|
|
||||||
|
|
||||||
Der `/chat` Endpunkt nutzt **Hybrid Retrieval** (Semantic + Graph), um auch logisch verbundene, aber textlich unterschiedliche Notizen zu finden (z.B. Decisions zu einem Projekt).
|
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 Context Enrichment (Das "Context Intelligence" Pattern)
|
### 5.2 Intent Router (WP06)
|
||||||
Bevor der Text an das LLM geht, reichert der Router (`chat.py`) ihn an.
|
Der Request durchläuft den **Hybrid Router**:
|
||||||
* **Metadaten-Injection:** `[DECISION]`, `[PROJECT]`, `[SCORE: 0.9]`.
|
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).
|
||||||
|
|
||||||
|
### 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?").
|
* **Zweck:** Ermöglicht kleinen Modellen (Phi-3) das Erkennen von logischen Rollen ("Warum?" vs "Was?").
|
||||||
|
|
||||||
### 5.3 Generation (LLM)
|
### 5.4 Generation (LLM)
|
||||||
* **Engine:** Ollama (lokal).
|
* **Engine:** Ollama (lokal).
|
||||||
* **Modell:** `phi3:mini` (Standard).
|
* **Modell:** `phi3:mini` (Standard).
|
||||||
* **Prompting:** Gesteuert über `config/prompts.yaml`.
|
* **Prompting:** Template wird basierend auf Intent gewählt (`decision_template` vs `empathy_template`).
|
||||||
|
|
||||||
### 5.4 Explanation Mode (WP04b)
|
|
||||||
Wird `/query` mit `explain=True` aufgerufen, führt der Retriever eine Post-Processing-Analyse durch und liefert `reasons` ("Verweist auf...", "Hoher Typ-Bonus").
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -205,8 +203,8 @@ Prüft am laufenden System (Prod oder Dev), ob Semantik, Graph und Feedback funk
|
||||||
# Retriever Test
|
# Retriever Test
|
||||||
python scripts/test_retriever_smoke.py --mode hybrid --top-k 5
|
python scripts/test_retriever_smoke.py --mode hybrid --top-k 5
|
||||||
|
|
||||||
# Chat Test (Neu WP05)
|
# Chat / Decision Engine Test (Neu WP06)
|
||||||
python tests/test_chat_wp05.py
|
python tests/test_wp06_decision.py -p 8002 -e EMPATHY -q "Alles ist grau"
|
||||||
|
|
||||||
# Feedback Test
|
# Feedback Test
|
||||||
python tests/test_feedback_smoke.py --url http://localhost:8001/query
|
python tests/test_feedback_smoke.py --url http://localhost:8001/query
|
||||||
|
|
@ -217,11 +215,7 @@ Prüft am laufenden System (Prod oder Dev), ob Semantik, Graph und Feedback funk
|
||||||
|
|
||||||
Wie entwickeln wir die Pipeline weiter?
|
Wie entwickeln wir die Pipeline weiter?
|
||||||
|
|
||||||
### 8.1 WP-06: Decision Engine (Skizze)
|
### 8.1 WP-08: Self-Tuning (Skizze)
|
||||||
**Ziel:** Aktive Entscheidungsberatung.
|
|
||||||
**Erweiterung:** Der Chat-Router lädt bei Entscheidungfragen gezielt `type: value` Notizen nach, um Optionen gegen Werte abzuwägen.
|
|
||||||
|
|
||||||
### 8.2 WP-08: Self-Tuning (Skizze)
|
|
||||||
**Ziel:** Die Gewichte in `retriever.yaml` basierend auf `feedback.jsonl` optimieren.
|
**Ziel:** Die Gewichte in `retriever.yaml` basierend auf `feedback.jsonl` optimieren.
|
||||||
**Ansatz:** Ein Offline-Learning-Skript `scripts/optimize_weights.py`.
|
**Ansatz:** Ein Offline-Learning-Skript `scripts/optimize_weights.py`.
|
||||||
1. **Load:** Liest `search_history.jsonl` und joint mit `feedback.jsonl` via `query_id`.
|
1. **Load:** Liest `search_history.jsonl` und joint mit `feedback.jsonl` via `query_id`.
|
||||||
|
|
|
||||||
|
|
@ -1,85 +1,95 @@
|
||||||
# Mindnet v2.2 – User Guide
|
# Mindnet v2.2 – User Guide
|
||||||
**Datei:** `docs/mindnet_user_guide_v2.2.md`
|
**Datei:** `docs/mindnet_user_guide_v2.2.md`
|
||||||
**Stand:** 2025-12-08
|
**Stand:** 2025-12-09
|
||||||
**Status:** **FINAL** (Inkl. RAG & Chat)
|
**Status:** **FINAL** (Inkl. RAG & Multi-Personality Chat)
|
||||||
**Quellen:** `knowledge_design.md`, `wp04_retriever_scoring.md`, `Programmplan_V2.2.md`, `Handbuch.md`.
|
**Quellen:** `knowledge_design.md`, `wp04_retriever_scoring.md`, `Programmplan_V2.2.md`, `Handbuch.md`.
|
||||||
|
|
||||||
> **Willkommen bei Mindnet.**
|
> **Willkommen bei Mindnet.**
|
||||||
> Dies ist dein persönliches Wissensnetzwerk. Im Gegensatz zu einer normalen Suche (wie Google Drive), die nur Texte findet, "denkt" Mindnet mit. Es erklärt dir, warum es etwas gefunden hat, und kann dir im Chat Fragen beantworten.
|
> Dies ist dein persönliches Wissensnetzwerk und dein Digitaler Zwilling. Es hilft dir beim Erinnern, beim Entscheiden und beim Reflektieren.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Was Mindnet für dich tut
|
## 1. Was Mindnet für dich tut
|
||||||
|
|
||||||
Mindnet ist ein **assoziatives Gedächtnis**. Es verbindet deine Notizen zu einem Graphen.
|
Mindnet ist ein **assoziatives Gedächtnis** mit Persönlichkeit. Es unterscheidet sich von einer reinen Suche (wie Google) dadurch, dass es **kontextsensitiv** agiert.
|
||||||
|
|
||||||
### 1.1 Mehr als nur Stichworte
|
### 1.1 Das Gedächtnis (Der Graph)
|
||||||
Wenn du nach "Projekt Alpha" suchst, findet Mindnet nicht nur das Dokument mit diesem Titel. Es findet auch:
|
Wenn du nach "Projekt Alpha" suchst, findet Mindnet nicht nur das Dokument. Es findet auch:
|
||||||
* **Abhängigkeiten:** "Technologie X wird benötigt" (weil sie verlinkt ist).
|
* **Abhängigkeiten:** "Technologie X wird benötigt".
|
||||||
* **Entscheidungen:** "Warum nutzen wir X?" (weil eine Decision-Note existiert).
|
* **Entscheidungen:** "Warum nutzen wir X?".
|
||||||
* **Ähnliches:** "Projekt Beta war ähnlich" (weil es strukturell verwandt ist).
|
* **Ähnliches:** "Projekt Beta war ähnlich".
|
||||||
|
|
||||||
### 1.2 Dein KI-Zwilling (Vision)
|
### 1.2 Der Zwilling (Die Personas)
|
||||||
Mindnet speichert nicht nur Fakten, sondern deine **Perspektive**. Durch die Gewichtung von Typen (z.B. "Prinzipien sind wichtiger als Quellen") lernt das System, Antworten so zu priorisieren, wie du es tun würdest.
|
Seit Version 2.3.1 passt Mindnet 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 2. Gute Fragen an Mindnet stellen
|
## 2. Den Chat steuern (Intents)
|
||||||
|
|
||||||
Mindnet nutzt eine **Hybride Suche**. Das heißt, es schaut auf deine Worte (Semantik) und auf das Netzwerk (Graph).
|
Du steuerst die Persönlichkeit von Mindnet durch deine Wortwahl. Das System nutzt einen **Hybrid Router**, der sowohl auf Schlüsselwörter als auch auf die Bedeutung achtet.
|
||||||
|
|
||||||
### 2.1 Frage-Muster
|
### 2.1 Modus: Entscheidung ("Der Berater")
|
||||||
Um gute Antworten zu erhalten, formuliere deine Anfragen präzise:
|
Wenn du vor einer Wahl stehst, hilft Mindnet dir, konform zu deinen Prinzipien zu bleiben.
|
||||||
|
|
||||||
* **Faktensuche:** "Wie installiere ich Qdrant?"
|
* **Auslöser (Keywords):** "Soll ich...", "Was ist deine Meinung?", "Strategie für...", "Vor- und Nachteile".
|
||||||
* *Mindnet sucht:* Chunks mit technischer Anleitung.
|
* **Was passiert:** Mindnet lädt deine **Werte** (`type: value`) und **Ziele** (`type: goal`) in den Kontext und prüft die Fakten dagegen.
|
||||||
* **Zusammenhänge:** "Womit hängt Projekt Alpha zusammen?"
|
* **Beispiel-Dialog:**
|
||||||
* *Mindnet sucht:* Den Projekt-Knoten und folgt den Kanten (`depends_on`, `related_to`).
|
* *Du:* "Soll ich Tool X nutzen?"
|
||||||
* **Entscheidungen:** "Warum nutzen wir Vektordatenbanken?"
|
* *Mindnet:* "Nein. Tool X speichert Daten in den USA. Das verstößt gegen dein Prinzip 'Privacy First' und dein Ziel 'Digitale Autarkie'."
|
||||||
* *Mindnet sucht:* Notizen vom Typ `decision` oder `principle`.
|
|
||||||
|
|
||||||
### 2.2 Tipps für bessere Ergebnisse
|
### 2.2 Modus: Empathie ("Der Spiegel")
|
||||||
1. **Nutze deine Sprache:** Verwende die Begriffe, die du auch in deinen Notizen benutzt hast.
|
Wenn du frustriert bist oder reflektieren willst, wechselt Mindnet in den "Ich"-Modus.
|
||||||
2. **Kontext geben:** Statt nur "Qdrant" zu tippen, frage "Qdrant Setup für Mindnet", um den Kontext einzuschränken.
|
|
||||||
|
* **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.
|
||||||
|
* **Beispiel-Dialog:**
|
||||||
|
* *Du:* "Ich bin total überfordert, nichts funktioniert."
|
||||||
|
* *Mindnet:* "Das Gefühl kenne ich. Erinnere dich an die Situation im Projekt X ('Der Durchbruch nach der Krise'). Damals hat uns das Mantra 'Einfach weitermachen, der Nebel lichtet sich' geholfen."
|
||||||
|
|
||||||
|
### 2.3 Modus: Coding ("Der Techniker")
|
||||||
|
* **Auslöser:** "Code", "Python", "Funktion", "Syntax".
|
||||||
|
* **Was passiert:** Mindnet antwortet kurz, prägnant und liefert Code-Blöcke. Smalltalk wird reduziert.
|
||||||
|
|
||||||
|
### 2.4 Modus: Fakten (Standard)
|
||||||
|
* **Auslöser:** Alles andere. "Was ist Qdrant?", "Zusammenfassung von X".
|
||||||
|
* **Was passiert:** Standard-Suche nach Wissen ohne spezielle Filter.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 3. Ergebnisse interpretieren (Explanation Layer)
|
## 3. Ergebnisse interpretieren (Explanation Layer)
|
||||||
|
|
||||||
Mindnet liefert nicht einfach nur Treffer. Es liefert eine **Begründung** (Explanation). Achte auf diese Hinweise in der Antwort:
|
Mindnet liefert nicht einfach nur Treffer. Es liefert eine **Begründung** (Explanation), warum es etwas gefunden hat.
|
||||||
|
|
||||||
### 3.1 Die Gründe ("Reasons")
|
### 3.1 Die Gründe ("Reasons")
|
||||||
Das System sagt dir in natürlicher Sprache, warum ein Treffer relevant ist:
|
Das System sagt dir in natürlicher Sprache, warum ein Treffer relevant ist:
|
||||||
* *"Hohe textuelle Übereinstimmung."* (Semantik war stark)
|
* *"Hohe textuelle Übereinstimmung."* (Semantik)
|
||||||
* *"Bevorzugt aufgrund des Typs 'decision'."* (Typ war wichtig)
|
* *"Bevorzugt aufgrund des Typs 'decision'."* (Wichtigkeit)
|
||||||
* *"Verweist auf 'Projekt X' via 'depends_on'."* (Dieser Treffer ist eine wichtige Grundlage für deine Suche)
|
* *"Verweist auf 'Projekt X' via 'depends_on'."* (Graph-Kontext)
|
||||||
* *"Wird referenziert von 'Wichtige Notiz Y'."* (Dieser Treffer ist eine Autorität im Netzwerk)
|
|
||||||
|
|
||||||
### 3.2 Der Score Breakdown
|
### 3.2 Der Score Breakdown
|
||||||
Wenn du es genau wissen willst, schau auf die Aufschlüsselung:
|
Wenn du es genau wissen willst, schau auf die Aufschlüsselung:
|
||||||
Score = (Text) + (Typ-Bonus) + (Vernetzungs-Bonus)
|
|
||||||
|
|
||||||
Ein Treffer mit niedrigem Text-Score kann trotzdem auf Platz 1 landen, wenn er extrem gut vernetzt ist ("Hidden Champion").
|
Score = (Text) + (Typ-Bonus) + (Vernetzungs-Bonus)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 4. Neues Wissen beisteuern (Authoring)
|
## 4. Neues Wissen beisteuern (Authoring)
|
||||||
|
|
||||||
Mindnet lebt von deinem Input. Du musst kein Techniker sein, um gutes Wissen zu designen. Du schreibst einfach Markdown.
|
Mindnet lebt von deinem Input. Du musst kein Techniker sein, um gutes Wissen zu designen. Siehe dazu das **Knowledge Design Manual** für Details.
|
||||||
|
|
||||||
### 4.1 Die Goldene Regel: "Verlinke semantisch"
|
### 4.1 Die Goldene Regel: "Verlinke semantisch"
|
||||||
Statt einfach nur `[[Link]]` zu schreiben, versuche zu sagen, *wie* es zusammenhängt.
|
Statt einfach nur `[[Link]]` zu schreiben, versuche zu sagen, *wie* es zusammenhängt.
|
||||||
* Hängt es davon ab? -> `[[rel:depends_on Ziel]]`
|
* Hängt es davon ab? -> `[[rel:depends_on Ziel]]`
|
||||||
* Ist es ähnlich? -> `[[rel:similar_to Ziel]]`
|
* Ist es ähnlich? -> `[[rel:similar_to Ziel]]`
|
||||||
* Ist es eine Folge davon? -> `[[rel:caused_by Ziel]]`
|
|
||||||
|
|
||||||
### 4.2 Struktur hilft dem Chunker
|
### 4.2 Typen nutzen (Wichtig!)
|
||||||
Mindnet zerlegt deinen Text in Häppchen ("Chunks"). Hilf dabei:
|
Setze im Frontmatter deiner Notizen den richtigen Typ. Das ist der wichtigste Hebel für den Chat:
|
||||||
* Verwende **Überschriften** (##), um Themen zu trennen.
|
* Willst du, dass Mindnet etwas als **Regel** nutzt? -> `type: principle`
|
||||||
* Schreibe **Absätze**, die einen Gedanken fassen.
|
* Willst du, dass Mindnet dich an eine **Lektion** erinnert? -> `type: experience`
|
||||||
|
|
||||||
### 4.3 Typen nutzen
|
|
||||||
Setze im Frontmatter deiner Notizen den richtigen Typ (z.B. `type: project`, `type: decision`). Das steuert automatisch, wie wichtig die Notiz ist.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -88,34 +98,11 @@ Setze im Frontmatter deiner Notizen den richtigen Typ (z.B. `type: project`, `ty
|
||||||
Mindnet wird schlauer, wenn du es pflegst.
|
Mindnet wird schlauer, wenn du es pflegst.
|
||||||
|
|
||||||
### 5.1 Feedback geben (Data Flywheel)
|
### 5.1 Feedback geben (Data Flywheel)
|
||||||
Das System zeichnet nun auf, welche Ergebnisse es liefert (`search_history`).
|
Das System zeichnet auf, welche Ergebnisse es liefert. Du kannst Treffer bewerten (geplant für WP-10 UI).
|
||||||
Du kannst Treffer bewerten (1-5 Sterne oder Daumen hoch/runter).
|
In Zukunft analysiert das System diese Daten, um seine Gewichte selbstständig anzupassen (Self-Tuning).
|
||||||
* **Was passiert damit?** Mindnet speichert "Situation" (Query) und "Reaktion" (Rating).
|
|
||||||
* **Wozu?** In Zukunft analysiert das System diese Daten, um zu lernen: "Aha, der Nutzer mag Entscheidungen lieber als Quellen". Es passt seine Gewichte dann selbstständig an (Self-Tuning).
|
|
||||||
|
|
||||||
### 5.2 Ergebnis fehlt?
|
### 5.2 Ergebnis fehlt? Troubleshooting
|
||||||
* Existiert die Notiz im Vault?
|
Wenn Mindnet etwas nicht findet:
|
||||||
* Ist sie isoliert (keine Links)? Isolierte Notizen haben keinen Graph-Bonus. **Verlinke sie!**
|
1. **Existiert** die Notiz im Vault? (Dateiname korrekt?)
|
||||||
|
2. **Typ korrekt?** (Eine Erfahrung als `concept` getaggt wird im Empathie-Modus vielleicht übersehen).
|
||||||
---
|
3. **Keywords?** (Wenn du "grau" sagst, aber in der Notiz nur "schlecht" steht, füge das Wort "grau" zur Notiz hinzu).
|
||||||
|
|
||||||
## 6. Chat mit Mindnet (Neu in v2.2)
|
|
||||||
|
|
||||||
Neben der Suche (`/query`) gibt es jetzt den Chat (`/chat`).
|
|
||||||
|
|
||||||
### 6.1 Wann Chat, wann Suche?
|
|
||||||
* **Suche:** Wenn du ein konkretes Dokument oder einen Link brauchst.
|
|
||||||
* **Chat:** Wenn du eine Frage hast, die sich aus mehreren Dokumenten zusammensetzt.
|
|
||||||
* *Frage:* "Was ist der Status von Projekt X und welche Risiken gibt es?"
|
|
||||||
* *Antwort:* Mindnet liest die Projekt-Notiz UND verknüpfte Risiko-Notizen und fasst sie zusammen.
|
|
||||||
|
|
||||||
### 6.2 Die Persönlichkeit
|
|
||||||
Der Chatbot agiert als dein "Digitaler Zwilling". Er versucht:
|
|
||||||
1. **Pragmatisch** zu sein (Lösungen statt Theorie).
|
|
||||||
2. **Transparent** zu sein (er sagt, wenn er etwas nicht weiß).
|
|
||||||
3. **Wertebasiert** zu handeln (er bevorzugt Lösungen, die deinen `type: value` Notizen entsprechen).
|
|
||||||
|
|
||||||
### 6.3 Quellen-Check
|
|
||||||
Der Chatbot halluziniert nicht (oder sehr selten). Unter jeder Antwort listet er die **Quellen** auf, die er genutzt hat.
|
|
||||||
* Prüfe immer: Hat er die richtige `[DECISION]`-Notiz gefunden?
|
|
||||||
* Falls nein: Füge in deinem Vault einen Link (`[[rel:depends_on]]`) hinzu, damit er den Zusammenhang beim nächsten Mal sieht.
|
|
||||||
103
tests/test_wp06_decision.py
Normal file
103
tests/test_wp06_decision.py
Normal file
|
|
@ -0,0 +1,103 @@
|
||||||
|
"""
|
||||||
|
tests/test_wp06_decision.py — Flexibler Integrationstest für WP-06
|
||||||
|
Update: Timeout auf 300s erhöht für CPU-Inference Cold-Starts.
|
||||||
|
"""
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
def test_decision_engine(query: str, port: int, expected_intent: str):
|
||||||
|
api_url = f"http://localhost:{port}"
|
||||||
|
print(f"🔵 Starte WP-06 Decision Engine Test gegen {api_url}...\n")
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"message": query,
|
||||||
|
"top_k": 3,
|
||||||
|
"explain": True
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Request senden
|
||||||
|
print(f"FRAGE: '{query}'")
|
||||||
|
print("... warte auf LLM (kann auf CPU >120s dauern) ...")
|
||||||
|
|
||||||
|
# FIX: Timeout auf 300 erhöht, passend zur Server-Config
|
||||||
|
response = requests.post(f"{api_url}/chat/", json=payload, timeout=300)
|
||||||
|
response.raise_for_status()
|
||||||
|
data = response.json()
|
||||||
|
|
||||||
|
# --- CHECKS ---
|
||||||
|
|
||||||
|
# 1. Intent Check
|
||||||
|
intent = data.get("intent", "UNKNOWN")
|
||||||
|
match = intent == expected_intent
|
||||||
|
print(f"\n1. INTENT DETECTION: [{'✅' if match else '❌'}]")
|
||||||
|
print(f" Erkannt: {intent} (Erwartet: {expected_intent})")
|
||||||
|
|
||||||
|
# 2. Source Check (Strategic Retrieval)
|
||||||
|
sources = data.get("sources", [])
|
||||||
|
strategic_hits = []
|
||||||
|
fact_hits = []
|
||||||
|
|
||||||
|
print(f"\n2. RETRIEVED SOURCES:")
|
||||||
|
if not sources:
|
||||||
|
print(" (Keine Quellen gefunden)")
|
||||||
|
|
||||||
|
for i, source in enumerate(sources):
|
||||||
|
# Safe access auf Source-Dict
|
||||||
|
src_meta = source.get("source", {})
|
||||||
|
node_type = src_meta.get("type", "unknown")
|
||||||
|
title = source.get("note_id", "Unknown")
|
||||||
|
score = source.get("total_score", 0.0)
|
||||||
|
|
||||||
|
# Marker für Ausgabe
|
||||||
|
marker = " "
|
||||||
|
if node_type in ["value", "principle", "goal", "experience", "belief", "profile"]:
|
||||||
|
marker = "🎯" # Strategischer Treffer
|
||||||
|
strategic_hits.append(title)
|
||||||
|
else:
|
||||||
|
marker = "📄"
|
||||||
|
fact_hits.append(title)
|
||||||
|
|
||||||
|
print(f" {marker} [{i+1}] {title} (Typ: {node_type}, Score: {score:.2f})")
|
||||||
|
|
||||||
|
# Analyse der Strategie
|
||||||
|
if strategic_hits:
|
||||||
|
print(f"\n ✅ ERFOLG: Strategische Quellen geladen: {strategic_hits}")
|
||||||
|
else:
|
||||||
|
print(f"\n ℹ️ INFO: Keine strategischen Quellen (Value/Experience/etc.) gefunden.")
|
||||||
|
|
||||||
|
# 3. Reasoning Check (LLM Antwort)
|
||||||
|
answer = data.get("answer", "")
|
||||||
|
print(f"\n3. REASONING (LLM Antwort):")
|
||||||
|
print("-" * 60)
|
||||||
|
print(answer)
|
||||||
|
print("-" * 60)
|
||||||
|
|
||||||
|
except requests.exceptions.ReadTimeout:
|
||||||
|
print(f"\n❌ TIMEOUT: Der Server hat nicht innerhalb von 300s geantwortet.")
|
||||||
|
print(" Tipp: Prüfe die Server-Logs. Lädt er noch das Modell?")
|
||||||
|
sys.exit(1)
|
||||||
|
except requests.exceptions.ConnectionError:
|
||||||
|
print(f"\n❌ FEHLER: Keine Verbindung zu {api_url}. Läuft der Server?")
|
||||||
|
sys.exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"\n❌ CRITICAL ERROR: {e}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parser = argparse.ArgumentParser(description="Testet die WP-06 Decision Engine.")
|
||||||
|
parser.add_argument("--query", "-q", type=str,
|
||||||
|
default="Soll ich SuperCloud Sync für meine privaten Tagebücher nutzen?",
|
||||||
|
help="Die Frage, die an das System gestellt wird.")
|
||||||
|
parser.add_argument("--port", "-p", type=int,
|
||||||
|
default=8002,
|
||||||
|
help="Der Port der API (Default: 8002 für Dev).")
|
||||||
|
parser.add_argument("--expect", "-e", type=str,
|
||||||
|
default="DECISION",
|
||||||
|
help="Der erwartete Intent (z.B. DECISION, EMPATHY).")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
test_decision_engine(args.query, args.port, args.expect)
|
||||||
Loading…
Reference in New Issue
Block a user