/deepask: Multi-Step Reasoning mit iterativer RAG-Suche

Neuer Discord-Command für tiefe Recherche in 3 Phasen:
1. Initiale Qdrant-Suche mit der Originalfrage
2. LLM generiert Folgefragen, sucht erneut (max 2 Iterationen)
3. Synthese aller gesammelten Chunks zu umfassender Antwort

Nutzbar via /deepask oder @bot deepask.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christoph K.
2026-03-21 19:49:38 +01:00
parent b6b451779d
commit ee7b4cc74f
4 changed files with 293 additions and 1 deletions

View File

@@ -3,7 +3,8 @@ package agents
const (
// Research
ActionQuery = "query"
ActionQuery = "query"
ActionDeepAsk = "deepask"
// Memory
ActionStore = "store"

View File

@@ -20,6 +20,10 @@ func (a *Agent) Handle(req agents.Request) agents.Response {
}
question := strings.Join(req.Args, " ")
if req.Action == agents.ActionDeepAsk {
return a.handleDeepAsk(question, req.History)
}
answer, chunks, err := brain.AskQuery(question, req.History)
if err != nil {
return agents.Response{Error: err, Text: fmt.Sprintf("❌ Fehler: %v", err)}
@@ -37,3 +41,31 @@ func (a *Agent) Handle(req agents.Request) agents.Response {
}
return agents.Response{Text: sb.String(), RawAnswer: answer}
}
// handleDeepAsk führt eine tiefe Recherche mit Multi-Step Reasoning durch.
func (a *Agent) handleDeepAsk(question string, history []agents.HistoryMessage) agents.Response {
answer, chunks, err := brain.DeepAskQuery(question, history)
if err != nil {
return agents.Response{Error: err, Text: fmt.Sprintf("❌ Fehler: %v", err)}
}
if len(chunks) == 0 {
return agents.Response{Text: "❌ Keine relevanten Informationen in der Datenbank gefunden.\nFüge mehr Daten mit `/ingest` hinzu."}
}
// Quellen deduplizieren
seenSources := make(map[string]float32)
for _, chunk := range chunks {
if existing, ok := seenSources[chunk.Source]; !ok || chunk.Score > existing {
seenSources[chunk.Source] = chunk.Score
}
}
var sb strings.Builder
fmt.Fprintf(&sb, "🔬 **Tiefe Recherche:** _%s_\n\n", question)
sb.WriteString(answer)
fmt.Fprintf(&sb, "\n\n📚 **Quellen** (%d Chunks aus %d Quellen):\n", len(chunks), len(seenSources))
for source, score := range seenSources {
fmt.Fprintf(&sb, "• %.1f%% %s\n", score*100, source)
}
return agents.Response{Text: sb.String(), RawAnswer: answer}
}