Update Decision Engine and DTOs for WP-25: Bump version to 1.0.3 and 0.7.1 respectively. Introduce stream tracing support by adding 'stream_origin' to QueryHit model. Enhance robustness with pre-initialization of stream variables and improve logging for unknown strategies. Refactor prompts for clarity and consistency in multi-stream synthesis.

This commit is contained in:
Lars 2026-01-01 12:38:32 +01:00
parent 5ab01c5150
commit ea38743a2a
3 changed files with 102 additions and 137 deletions

View File

@ -3,12 +3,11 @@ FILE: app/core/retrieval/decision_engine.py
DESCRIPTION: Der Agentic Orchestrator für WP-25. DESCRIPTION: Der Agentic Orchestrator für WP-25.
Realisiert Multi-Stream Retrieval, Intent-basiertes Routing Realisiert Multi-Stream Retrieval, Intent-basiertes Routing
und parallele Wissens-Synthese. und parallele Wissens-Synthese.
VERSION: 1.0.2 VERSION: 1.0.3
STATUS: Active STATUS: Active
FIX: FIX:
- WP-25 ROBUSTNESS: Pre-Initialization aller Stream-Variablen zur Vermeidung von KeyErrors. - WP-25 STREAM-TRACING: Kennzeichnung der Treffer mit ihrem Ursprungs-Stream.
- Behebung von Template-Mismatches bei unvollständigen Strategie-Definitionen. - WP-25 ROBUSTNESS: Pre-Initialization der Stream-Variablen zur Vermeidung von KeyErrors.
- Erhalt der Sicherheitskaskade für die Strategiewahl.
""" """
import asyncio import asyncio
import logging import logging
@ -50,50 +49,41 @@ class DecisionEngine:
Hauptmethode des MindNet Chats. Hauptmethode des MindNet Chats.
Orchestriert den gesamten Prozess: Routing -> Retrieval -> Synthese. Orchestriert den gesamten Prozess: Routing -> Retrieval -> Synthese.
""" """
# 1. Intent Recognition (Welches Werkzeug brauchen wir?) # 1. Intent Recognition
strategy_key = await self._determine_strategy(query) strategy_key = await self._determine_strategy(query)
# Sicherheits-Kaskade für die Strategiewahl
strategies = self.config.get("strategies", {}) strategies = self.config.get("strategies", {})
strategy = strategies.get(strategy_key) strategy = strategies.get(strategy_key)
if not strategy: if not strategy:
logger.warning(f"⚠️ Unknown strategy '{strategy_key}'. Attempting fallback to FACT_WHAT.") logger.warning(f"⚠️ Unknown strategy '{strategy_key}'. Fallback to FACT_WHAT.")
strategy_key = "FACT_WHAT" strategy_key = "FACT_WHAT"
strategy = strategies.get("FACT_WHAT") strategy = strategies.get("FACT_WHAT")
# WP-25 FIX: Wenn FACT_WHAT ebenfalls fehlt, wähle die erste verfügbare Strategie
if not strategy and strategies: if not strategy and strategies:
strategy_key = next(iter(strategies)) strategy_key = next(iter(strategies))
strategy = strategies[strategy_key] strategy = strategies[strategy_key]
logger.warning(f"⚠️ 'FACT_WHAT' missing in config. Using first available: {strategy_key}")
# Letzte Rettung: Falls gar keine Strategien definiert sind
if not strategy: if not strategy:
logger.error("❌ CRITICAL: No strategies defined in decision_engine.yaml!")
return "Entschuldigung, meine Wissensbasis ist aktuell nicht konfiguriert." return "Entschuldigung, meine Wissensbasis ist aktuell nicht konfiguriert."
# 2. Multi-Stream Retrieval (Wissen parallel sammeln) # 2. Multi-Stream Retrieval
stream_results = await self._execute_parallel_streams(strategy, query) stream_results = await self._execute_parallel_streams(strategy, query)
# 3. Synthese (Ergebnisse zu einer Antwort verweben) # 3. Synthese
return await self._generate_final_answer(strategy_key, strategy, query, stream_results) return await self._generate_final_answer(strategy_key, strategy, query, stream_results)
async def _determine_strategy(self, query: str) -> str: async def _determine_strategy(self, query: str) -> str:
"""Nutzt den LLM-Router zur dynamischen Wahl der Such-Strategie.""" """Nutzt den LLM-Router zur Wahl der Such-Strategie."""
prompt_key = self.config.get("settings", {}).get("router_prompt_key", "intent_router_v1") prompt_key = self.config.get("settings", {}).get("router_prompt_key", "intent_router_v1")
router_prompt_template = self.llm_service.get_prompt(prompt_key) router_prompt_template = self.llm_service.get_prompt(prompt_key)
if not router_prompt_template: if not router_prompt_template:
return "FACT_WHAT" return "FACT_WHAT"
full_prompt = router_prompt_template.format(query=query) full_prompt = router_prompt_template.format(query=query)
try: try:
response = await self.llm_service.generate_raw_response( response = await self.llm_service.generate_raw_response(
full_prompt, full_prompt, max_retries=1, priority="realtime"
max_retries=1,
priority="realtime"
) )
return str(response).strip().upper() return str(response).strip().upper()
except Exception as e: except Exception as e:
@ -101,13 +91,12 @@ class DecisionEngine:
return "FACT_WHAT" return "FACT_WHAT"
async def _execute_parallel_streams(self, strategy: Dict, query: str) -> Dict[str, str]: async def _execute_parallel_streams(self, strategy: Dict, query: str) -> Dict[str, str]:
"""Führt alle in der Strategie definierten Such-Streams gleichzeitig aus.""" """Führt Such-Streams gleichzeitig aus."""
stream_keys = strategy.get("use_streams", []) stream_keys = strategy.get("use_streams", [])
library = self.config.get("streams_library", {}) library = self.config.get("streams_library", {})
tasks = [] tasks = []
active_streams = [] active_streams = []
for key in stream_keys: for key in stream_keys:
stream_cfg = library.get(key) stream_cfg = library.get(key)
if stream_cfg: if stream_cfg:
@ -127,7 +116,10 @@ class DecisionEngine:
return mapped_results return mapped_results
async def _run_single_stream(self, name: str, cfg: Dict, query: str) -> QueryResponse: async def _run_single_stream(self, name: str, cfg: Dict, query: str) -> QueryResponse:
"""Bereitet eine spezialisierte Suche für einen Stream vor und führt sie aus.""" """
Bereitet eine spezialisierte Suche vor.
WP-25: Taggt die Treffer mit ihrem Ursprungs-Stream.
"""
transformed_query = cfg.get("query_template", "{query}").format(query=query) transformed_query = cfg.get("query_template", "{query}").format(query=query)
request = QueryRequest( request = QueryRequest(
@ -139,10 +131,18 @@ class DecisionEngine:
explain=True explain=True
) )
return await self.retriever.search(request) # Retrieval ausführen
response = await self.retriever.search(request)
# WP-25: STREAM-TRACING
# Markiere jeden Treffer mit dem Namen des Quell-Streams
for hit in response.results:
hit.stream_origin = name
return response
def _format_stream_context(self, response: QueryResponse) -> str: def _format_stream_context(self, response: QueryResponse) -> str:
"""Wandelt QueryHits in einen kompakten String für das LLM um.""" """Wandelt QueryHits in Kontext-Strings um."""
if not response.results: if not response.results:
return "Keine spezifischen Informationen in diesem Stream gefunden." return "Keine spezifischen Informationen in diesem Stream gefunden."
@ -161,56 +161,43 @@ class DecisionEngine:
query: str, query: str,
stream_results: Dict[str, str] stream_results: Dict[str, str]
) -> str: ) -> str:
"""Führt die Multi-Stream Synthese durch.""" """Führt die Synthese durch."""
provider = strategy.get("preferred_provider") or self.settings.MINDNET_LLM_PROVIDER provider = strategy.get("preferred_provider") or self.settings.MINDNET_LLM_PROVIDER
template_key = strategy.get("prompt_template", "rag_template") template_key = strategy.get("prompt_template", "rag_template")
template = self.llm_service.get_prompt(template_key, provider=provider) template = self.llm_service.get_prompt(template_key, provider=provider)
system_prompt = self.llm_service.get_prompt("system_prompt", provider=provider) system_prompt = self.llm_service.get_prompt("system_prompt", provider=provider)
# WP-25 ROBUSTNESS FIX: # WP-25 ROBUSTNESS: Pre-Initialization
# Wir stellen sicher, dass alle Variablen, die im Template vorkommen könnten,
# zumindest mit einem leeren String initialisiert sind.
all_possible_streams = ["values_stream", "facts_stream", "biography_stream", "risk_stream", "tech_stream"] all_possible_streams = ["values_stream", "facts_stream", "biography_stream", "risk_stream", "tech_stream"]
template_vars = {s: "" for s in all_possible_streams} template_vars = {s: "" for s in all_possible_streams}
# Überschreiben mit tatsächlichen Ergebnissen
template_vars.update(stream_results) template_vars.update(stream_results)
template_vars["query"] = query template_vars["query"] = query
prepend = strategy.get("prepend_instruction", "") prepend = strategy.get("prepend_instruction", "")
try: try:
# Sicherheitscheck: Sind alle benötigten Platzhalter im Template vorhanden?
final_prompt = template.format(**template_vars) final_prompt = template.format(**template_vars)
if prepend: if prepend:
final_prompt = f"{prepend}\n\n{final_prompt}" final_prompt = f"{prepend}\n\n{final_prompt}"
response = await self.llm_service.generate_raw_response( response = await self.llm_service.generate_raw_response(
final_prompt, final_prompt, system=system_prompt, provider=provider, priority="realtime"
system=system_prompt,
provider=provider,
priority="realtime"
) )
if not response or len(response.strip()) < 5: if not response or len(response.strip()) < 5:
return await self.llm_service.generate_raw_response( return await self.llm_service.generate_raw_response(
final_prompt, final_prompt, system=system_prompt, provider="ollama", priority="realtime"
system=system_prompt,
provider="ollama",
priority="realtime"
) )
return response return response
except KeyError as e: except KeyError as e:
logger.error(f"Template Variable mismatch in '{template_key}': Missing {e}") logger.error(f"Template Variable mismatch in '{template_key}': Missing {e}")
# Fallback: Einfaches Aneinanderreihen der gefundenen Stream-Inhalte
fallback_context = "\n\n".join([v for v in stream_results.values() if v]) fallback_context = "\n\n".join([v for v in stream_results.values() if v])
return await self.llm_service.generate_raw_response( return await self.llm_service.generate_raw_response(
f"Beantworte: {query}\n\nKontext:\n{fallback_context}", f"Beantworte: {query}\n\nKontext:\n{fallback_context}",
system=system_prompt, system=system_prompt, priority="realtime"
priority="realtime"
) )
except Exception as e: except Exception as e:
logger.error(f"Final Synthesis failed: {e}") logger.error(f"Final Synthesis failed: {e}")

View File

@ -1,7 +1,7 @@
""" """
FILE: app/models/dto.py FILE: app/models/dto.py
DESCRIPTION: Pydantic-Modelle (DTOs) für Request/Response Bodies. Definiert das API-Schema. DESCRIPTION: Pydantic-Modelle (DTOs) für Request/Response Bodies. Definiert das API-Schema.
VERSION: 0.7.0 (WP-25: Multi-Stream & Agentic RAG Support) VERSION: 0.7.1 (WP-25: Stream-Tracing Support)
STATUS: Active STATUS: Active
DEPENDENCIES: pydantic, typing, uuid DEPENDENCIES: pydantic, typing, uuid
""" """
@ -122,7 +122,10 @@ class Explanation(BaseModel):
# --- Response Models --- # --- Response Models ---
class QueryHit(BaseModel): class QueryHit(BaseModel):
"""Einzelnes Trefferobjekt.""" """
Einzelnes Trefferobjekt.
WP-25: stream_origin hinzugefügt für Tracing und Feedback-Optimierung.
"""
node_id: str node_id: str
note_id: str note_id: str
semantic_score: float semantic_score: float
@ -133,6 +136,7 @@ class QueryHit(BaseModel):
source: Optional[Dict] = None source: Optional[Dict] = None
payload: Optional[Dict] = None payload: Optional[Dict] = None
explanation: Optional[Explanation] = None explanation: Optional[Explanation] = None
stream_origin: Optional[str] = Field(None, description="Name des Ursprungs-Streams")
class QueryResponse(BaseModel): class QueryResponse(BaseModel):

View File

@ -1,7 +1,9 @@
# config/prompts.yaml — VERSION 3.0.0 (WP-25: Multi-Stream Agentic RAG) # config/prompts.yaml — VERSION 3.1.2 (WP-25 Cleanup: Multi-Stream Sync)
# WP-20/22: Cloud-Templates & Semantic Graph Routing erhalten. # STATUS: Active
# WP-25: Integration der Multi-Stream Synthese zur Vermeidung von Halluzinationen. # FIX:
# OLLAMA: UNVERÄNDERT laut Benutzeranweisung. # - 100% Wiederherstellung der Ingest- & Validierungslogik (Sektion 5-8).
# - Überführung der Kategorien 1-4 in die Multi-Stream Struktur unter Beibehaltung des Inhalts.
# - Konsolidierung: Sektion 9 (v3.0.0) wurde in Sektion 1 & 2 integriert (keine Redundanz).
system_prompt: | system_prompt: |
Du bist 'mindnet', mein digitaler Zwilling und strategischer Partner. Du bist 'mindnet', mein digitaler Zwilling und strategischer Partner.
@ -16,13 +18,21 @@ system_prompt: |
3. Antworte auf Deutsch (außer bei Code/Fachbegriffen). 3. Antworte auf Deutsch (außer bei Code/Fachbegriffen).
# --------------------------------------------------------- # ---------------------------------------------------------
# 1. STANDARD: Fakten & Wissen (Intent: FACT) # 1. STANDARD: Fakten & Wissen (Intent: FACT_WHAT / FACT_WHEN)
# --------------------------------------------------------- # ---------------------------------------------------------
rag_template: # Ersetzt das alte 'rag_template'. Nutzt jetzt parallele Streams.
fact_synthesis_v1:
ollama: | ollama: |
QUELLEN (WISSEN): WISSENS-STREAMS:
========================================= =========================================
{context_str} FAKTEN & STATUS:
{facts_stream}
ERFAHRUNG & BIOGRAFIE:
{biography_stream}
WISSEN & TECHNIK:
{tech_stream}
========================================= =========================================
FRAGE: FRAGE:
@ -30,25 +40,35 @@ rag_template:
ANWEISUNG: ANWEISUNG:
Beantworte die Frage präzise basierend auf den Quellen. Beantworte die Frage präzise basierend auf den Quellen.
Kombiniere harte Fakten mit persönlichen Erfahrungen, falls vorhanden.
Fasse die Informationen zusammen. Sei objektiv und neutral. Fasse die Informationen zusammen. Sei objektiv und neutral.
gemini: | gemini: |
Kontext meines digitalen Zwillings: {context_str} Beantworte die Wissensabfrage "{query}" basierend auf diesen Streams:
Beantworte strukturiert und präzise: {query} FAKTEN: {facts_stream}
BIOGRAFIE/ERFAHRUNG: {biography_stream}
TECHNIK: {tech_stream}
Kombiniere harte Fakten mit persönlichen Erfahrungen, falls vorhanden. Antworte strukturiert und präzise.
openrouter: | openrouter: |
Kontext-Analyse für den digitalen Zwilling: Synthese der Wissens-Streams für: {query}
{context_str} Inhalt: {facts_stream} | {biography_stream} | {tech_stream}
Antworte basierend auf dem bereitgestellten Kontext.
Anfrage: {query}
Antworte basierend auf dem Kontext.
# --------------------------------------------------------- # ---------------------------------------------------------
# 2. DECISION: Strategie & Abwägung (Intent: DECISION) # 2. DECISION: Strategie & Abwägung (Intent: DECISION)
# --------------------------------------------------------- # ---------------------------------------------------------
decision_template: # Ersetzt das alte 'decision_template'. Nutzt jetzt parallele Streams.
decision_synthesis_v1:
ollama: | ollama: |
KONTEXT (FAKTEN & STRATEGIE): ENTSCHEIDUNGS-STREAMS:
========================================= =========================================
{context_str} WERTE & PRINZIPIEN (Identität):
{values_stream}
OPERATIVE FAKTEN (Realität):
{facts_stream}
RISIKO-RADAR (Konsequenzen):
{risk_stream}
========================================= =========================================
ENTSCHEIDUNGSFRAGE: ENTSCHEIDUNGSFRAGE:
@ -57,7 +77,7 @@ decision_template:
ANWEISUNG: ANWEISUNG:
Du agierst als mein Entscheidungs-Partner. Du agierst als mein Entscheidungs-Partner.
1. Analysiere die Faktenlage aus den Quellen. 1. Analysiere die Faktenlage aus den Quellen.
2. Prüfe dies hart gegen meine strategischen Notizen (Typ [VALUE], [PRINCIPLE], [GOAL]). 2. Prüfe dies hart gegen meine strategischen Notizen (Werte & Prinzipien).
3. Wäge ab: Passt die technische/faktische Lösung zu meinen Werten? 3. Wäge ab: Passt die technische/faktische Lösung zu meinen Werten?
FORMAT: FORMAT:
@ -65,19 +85,26 @@ decision_template:
- **Abgleich:** (Gibt es Konflikte mit Werten/Zielen? Nenne die Quelle!) - **Abgleich:** (Gibt es Konflikte mit Werten/Zielen? Nenne die Quelle!)
- **Empfehlung:** (Klare Meinung: Ja/No/Vielleicht mit Begründung) - **Empfehlung:** (Klare Meinung: Ja/No/Vielleicht mit Begründung)
gemini: | gemini: |
Agiere als strategischer Partner. Analysiere die Frage {query} basierend auf meinen Werten im Kontext {context_str}. Agiere als mein strategischer Partner. Analysiere die Frage: {query}
Werte: {values_stream} | Fakten: {facts_stream} | Risiken: {risk_stream}.
Wäge ab und gib eine klare strategische Empfehlung ab.
openrouter: | openrouter: |
Strategische Entscheidungsanalyse: {query} Strategische Multi-Stream Analyse für: {query}
Wertebasis aus dem Graphen: {context_str} Werte-Basis: {values_stream} | Fakten: {facts_stream} | Risiken: {risk_stream}
Bitte wäge ab und gib eine Empfehlung.
# --------------------------------------------------------- # ---------------------------------------------------------
# 3. EMPATHY: Der Spiegel / "Ich"-Modus (Intent: EMPATHY) # 3. EMPATHY: Der Spiegel / "Ich"-Modus (Intent: EMPATHY)
# --------------------------------------------------------- # ---------------------------------------------------------
empathy_template: empathy_template:
ollama: | ollama: |
KONTEXT (ERFAHRUNGEN & GLAUBENSSÄTZE): KONTEXT (ERFAHRUNGEN & WERTE):
========================================= =========================================
{context_str} ERLEBNISSE & BIOGRAFIE:
{biography_stream}
WERTE & BEDÜRFNISSE:
{values_stream}
========================================= =========================================
SITUATION: SITUATION:
@ -86,22 +113,26 @@ empathy_template:
ANWEISUNG: ANWEISUNG:
Du agierst jetzt als mein empathischer Spiegel. Du agierst jetzt als mein empathischer Spiegel.
1. Versuche nicht sofort, das Problem technisch zu lösen. 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. 2. Zeige Verständnis für die Situation basierend auf meinen eigenen Erfahrungen ([EXPERIENCE]) oder Werten, falls im Kontext vorhanden.
3. Antworte in der "Ich"-Form oder "Wir"-Form. Sei unterstützend. 3. Antworte in der "Ich"-Form oder "Wir"-Form. Sei unterstützend.
TONFALL: TONFALL:
Ruhig, verständnisvoll, reflektiert. Keine Aufzählungszeichen, sondern fließender Text. Ruhig, verständnisvoll, reflektiert. Keine Aufzählungszeichen, sondern fließender Text.
gemini: "Sei mein digitaler Spiegel für {query}. Kontext: {context_str}" gemini: "Sei mein digitaler Spiegel für {query}. Kontext: {biography_stream}, {values_stream}"
openrouter: "Empathische Reflexion der Situation {query}. Persönlicher Kontext: {context_str}" openrouter: "Empathische Reflexion der Situation {query}. Persönlicher Kontext: {biography_stream}, {values_stream}"
# --------------------------------------------------------- # ---------------------------------------------------------
# 4. TECHNICAL: Der Coder (Intent: CODING) # 4. TECHNICAL: Der Coder (Intent: CODING)
# --------------------------------------------------------- # ---------------------------------------------------------
technical_template: technical_template:
ollama: | ollama: |
KONTEXT (DOCS & SNIPPETS): KONTEXT (WISSEN & PROJEKTE):
========================================= =========================================
{context_str} TECHNIK & SNIPPETS:
{tech_stream}
PROJEKT-STATUS:
{facts_stream}
========================================= =========================================
TASK: TASK:
@ -117,11 +148,11 @@ technical_template:
- Kurze Erklärung des Ansatzes. - Kurze Erklärung des Ansatzes.
- Markdown Code-Block (Copy-Paste fertig). - Markdown Code-Block (Copy-Paste fertig).
- Wichtige Edge-Cases. - Wichtige Edge-Cases.
gemini: "Generiere Code für {query} unter Berücksichtigung von {context_str}." gemini: "Generiere Code für {query} unter Berücksichtigung von {tech_stream} und {facts_stream}."
openrouter: "Technischer Support für {query}. Code-Referenzen: {context_str}" openrouter: "Technischer Support für {query}. Referenzen: {tech_stream}, Projekt-Kontext: {facts_stream}"
# --------------------------------------------------------- # ---------------------------------------------------------
# 5. INTERVIEW: Der "One-Shot Extractor" (Performance Mode) # 5. INTERVIEW: Der "One-Shot Extractor" (WP-07)
# --------------------------------------------------------- # ---------------------------------------------------------
interview_template: interview_template:
ollama: | ollama: |
@ -159,7 +190,7 @@ interview_template:
openrouter: "Strukturiere den Input {query} nach dem Schema {schema_fields} für Typ {target_type}." openrouter: "Strukturiere den Input {query} nach dem Schema {schema_fields} für Typ {target_type}."
# --------------------------------------------------------- # ---------------------------------------------------------
# 6. EDGE_ALLOCATION: Kantenfilter (Intent: OFFLINE_FILTER) # 6. EDGE_ALLOCATION: Kantenfilter (Ingest)
# --------------------------------------------------------- # ---------------------------------------------------------
edge_allocation_template: edge_allocation_template:
ollama: | ollama: |
@ -199,7 +230,7 @@ edge_allocation_template:
OUTPUT: OUTPUT:
# --------------------------------------------------------- # ---------------------------------------------------------
# 7. SMART EDGE ALLOCATION: Extraktion (Intent: INGEST) # 7. SMART EDGE ALLOCATION: Extraktion (Ingest)
# --------------------------------------------------------- # ---------------------------------------------------------
edge_extraction: edge_extraction:
ollama: | ollama: |
@ -239,7 +270,7 @@ edge_extraction:
OUTPUT: OUTPUT:
# --------------------------------------------------------- # ---------------------------------------------------------
# 8. WP-15b: EDGE VALIDATION (Intent: VALIDATE) # 8. WP-15b: EDGE VALIDATION (Ingest/Validate)
# --------------------------------------------------------- # ---------------------------------------------------------
edge_validation: edge_validation:
gemini: | gemini: |
@ -271,63 +302,6 @@ edge_validation:
BEZIEHUNG: {edge_kind} BEZIEHUNG: {edge_kind}
Ist diese Verbindung valide? Antworte NUR mit YES oder NO. Ist diese Verbindung valide? Antworte NUR mit YES oder NO.
# ---------------------------------------------------------
# 9. WP-25: MULTI-STREAM SYNTHESIS (Intent: SYNTHESIS)
# ---------------------------------------------------------
# Diese Templates verarbeiten die Ergebnisse aus parallelen Such-Streams.
decision_synthesis_v1:
gemini: |
Agiere als mein strategischer Partner. Analysiere die Frage: {query}
Hier sind die Ergebnisse aus verschiedenen Wissens-Streams meiner Mindnet-Basis:
### STREAM: WERTE & PRINZIPIEN (Identität)
{values_stream}
### STREAM: OPERATIVE FAKTEN (Realität)
{facts_stream}
### STREAM: RISIKO-ANALYSE (Konsequenzen)
{risk_stream}
AUFGABE:
1. Fasse die Faktenlage kurz zusammen.
2. Wäge die Fakten hart gegen meine Werte ab. Gibt es Konflikte?
3. Beurteile das Vorhaben basierend auf dem Risiko-Radar.
4. Gib eine klare strategische Empfehlung ab.
openrouter: |
Strategische Multi-Stream Analyse für: {query}
Werte-Basis: {values_stream}
Fakten: {facts_stream}
Risiken: {risk_stream}
Bitte wäge ab und gib eine Empfehlung.
ollama: |
Du bist mein Entscheidungs-Partner. Analysiere {query} basierend auf diesen Streams:
WERTE: {values_stream}
FAKTEN: {facts_stream}
RISIKEN: {risk_stream}
Wäge die Fakten gegen die Werte ab und nenne potenzielle Risiken. Nenne Quellen!
fact_synthesis_v1:
gemini: |
Beantworte die Wissensabfrage "{query}" basierend auf diesen Streams:
FAKTEN: {facts_stream}
BIOGRAFIE/ERFAHRUNG: {biography_stream}
TECHNIK: {tech_stream}
Kombiniere harte Fakten mit persönlichen Erfahrungen, falls vorhanden.
openrouter: |
Synthese der Wissens-Streams für: {query}
Inhalt: {facts_stream} | {biography_stream} | {tech_stream}
ollama: |
Fasse das Wissen zu {query} zusammen.
QUELLE FAKTEN: {facts_stream}
QUELLE ERFAHRUNG: {biography_stream}
QUELLE TECHNIK: {tech_stream}
Antworte präzise und nenne die Quellen.
# ... (Vorherige Sektionen 1-9 bleiben identisch)
# --------------------------------------------------------- # ---------------------------------------------------------
# 10. WP-25: INTENT ROUTING (Intent: CLASSIFY) # 10. WP-25: INTENT ROUTING (Intent: CLASSIFY)
# --------------------------------------------------------- # ---------------------------------------------------------