fix: KB-Hints Filter-Pipeline — generische Einträge rausfiltern [appimage]
All checks were successful
Build AppImage / build (push) Successful in 6m48s
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:
parent
f6a12de6ef
commit
60989cd44d
1 changed files with 44 additions and 8 deletions
|
|
@ -620,23 +620,59 @@ async fn search_knowledge_filtered(search_query: &str, limit: usize, project: &O
|
||||||
return Ok(String::new());
|
return Ok(String::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Relevanz-Schwelle: Ergebnisse mit zu niedrigem Score rausfiltern.
|
// === Filter-Pipeline: generische Referenz-Einträge raus ===
|
||||||
// MySQL FULLTEXT NATURAL LANGUAGE MODE gibt Scores > 0 zurück,
|
|
||||||
// aber generische Einzel-Wort-Treffer haben oft Score < 2.
|
// 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 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();
|
.collect();
|
||||||
|
|
||||||
if relevant.is_empty() {
|
if base_filtered.is_empty() {
|
||||||
println!("🔍 Keine Hints über Relevanz-Schwelle ({:.1})", min_relevance);
|
println!("🔍 Keine Hints über Relevanz-Schwelle ({:.1}) nach Kategorie-Filter", min_relevance);
|
||||||
return Ok(String::new());
|
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
|
// Bereits gezeigte IDs filtern
|
||||||
let filtered: Vec<_> = {
|
let filtered: Vec<_> = {
|
||||||
let topic = SESSION_TOPIC.lock().unwrap();
|
let topic = SESSION_TOPIC.lock().unwrap();
|
||||||
relevant.into_iter()
|
filtered_results.into_iter()
|
||||||
.filter(|(id, _, _, _, _, _, _)| !topic.shown_ids.contains(id))
|
.filter(|(id, _, _, _, _, _, _)| !topic.shown_ids.contains(id))
|
||||||
.take(limit)
|
.take(limit)
|
||||||
.collect()
|
.collect()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue