fix: KB-Hints Filter-Pipeline — generische Einträge rausfiltern [appimage]
All checks were successful
Build AppImage / build (push) Successful in 6m48s

Kategorien wie setup, access, claude-md, skill, slash-command, hook
werden aus Hints ausgeschlossen. Bei erkanntem Projekt werden Einträge
mit passendem Tag bevorzugt (Fallback auf alle wenn Projekt-Filter leer).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eddy 2026-05-02 22:50:27 +02:00
parent f6a12de6ef
commit 60989cd44d

View file

@ -620,23 +620,59 @@ async fn search_knowledge_filtered(search_query: &str, limit: usize, project: &O
return Ok(String::new());
}
// Relevanz-Schwelle: Ergebnisse mit zu niedrigem Score rausfiltern.
// MySQL FULLTEXT NATURAL LANGUAGE MODE gibt Scores > 0 zurück,
// aber generische Einzel-Wort-Treffer haben oft Score < 2.
// === Filter-Pipeline: generische Referenz-Einträge raus ===
// 1. Kategorien die als Hints keinen Wert haben (Referenzdaten, Config-Backups)
const EXCLUDED_CATEGORIES: &[&str] = &[
"setup", "access", "claude-md", "skill", "slash-command", "hook",
];
// 2. Relevanz-Schwelle
let min_relevance = 1.5;
let relevant: Vec<_> = results.into_iter()
.filter(|(_, _, _, _, _, _, relevance)| *relevance >= min_relevance)
// 3. Basis-Filter: Relevanz + Kategorie
let base_filtered: Vec<_> = results.into_iter()
.filter(|(_, category, _, _, _, _, relevance)| {
if *relevance < min_relevance { return false; }
if EXCLUDED_CATEGORIES.contains(&category.as_str()) { return false; }
true
})
.collect();
if relevant.is_empty() {
println!("🔍 Keine Hints über Relevanz-Schwelle ({:.1})", min_relevance);
if base_filtered.is_empty() {
println!("🔍 Keine Hints über Relevanz-Schwelle ({:.1}) nach Kategorie-Filter", min_relevance);
return Ok(String::new());
}
// 4. Projekt-Filter: wenn Projekt erkannt, bevorzuge Einträge mit passendem Tag.
// Fallback auf base_filtered wenn Projekt-Filter alles wegfiltert.
let filtered_results = if let Some(ref proj) = project {
let proj_lower = proj.to_lowercase();
let proj_filtered: Vec<_> = base_filtered.iter()
.filter(|(_, _, _, _, tags, _, _)| {
if let Some(ref t) = tags {
t.to_lowercase().contains(&proj_lower)
} else {
false
}
})
.cloned()
.collect();
if proj_filtered.is_empty() {
println!("🔍 Projekt-Filter '{}' ergab 0 Treffer, Fallback auf {} Basis-Treffer", proj, base_filtered.len());
base_filtered
} else {
println!("🔍 Projekt-Filter '{}': {} von {} Treffern", proj, proj_filtered.len(), base_filtered.len());
proj_filtered
}
} else {
base_filtered
};
// Bereits gezeigte IDs filtern
let filtered: Vec<_> = {
let topic = SESSION_TOPIC.lock().unwrap();
relevant.into_iter()
filtered_results.into_iter()
.filter(|(id, _, _, _, _, _, _)| !topic.shown_ids.contains(id))
.take(limit)
.collect()