Files
ai-agent/internal/agents/research/agent.go
Christoph K. ee7b4cc74f /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>
2026-03-21 19:49:38 +01:00

72 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// research/agent.go Research-Agent: wraps brain.AskQuery
package research
import (
"fmt"
"strings"
"my-brain-importer/internal/agents"
"my-brain-importer/internal/brain"
)
// Agent beantwortet Fragen mit der Wissensdatenbank.
type Agent struct{}
func New() *Agent { return &Agent{} }
func (a *Agent) Handle(req agents.Request) agents.Response {
if len(req.Args) == 0 {
return agents.Response{Text: "❌ Keine Frage angegeben."}
}
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)}
}
if len(chunks) == 0 {
return agents.Response{Text: "❌ Keine relevanten Informationen in der Datenbank gefunden.\nFüge mehr Daten mit `/ingest` hinzu."}
}
var sb strings.Builder
fmt.Fprintf(&sb, "💬 **Antwort auf:** _%s_\n\n", question)
sb.WriteString(answer)
sb.WriteString("\n\n📚 **Quellen:**\n")
for _, chunk := range chunks {
fmt.Fprintf(&sb, "• %.1f%% %s\n", chunk.Score*100, chunk.Source)
}
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}
}