feat: min_score anti-rumore nella ricerca + igiene metadata

- gateway v2.2.0: SearchIn.min_score → score_threshold a livello Qdrant (filtra sotto soglia), audit e risposta con min_score
- estensione v1.2.0: qmem_search con min_score default 0.45 (guida punteggi in descrizione), marker ⚠️ per score<0.60, messaggio dedicato quando 0 risultati rilevanti
- dati: eliminato record rumore ('valuta preferita EUR'), assegnati project_id mancanti via supersede (domotics, pi-qmem x2, agy-pi)
- AGENTS.md: sezione interpretazione punteggi
This commit is contained in:
enne2
2026-08-13 13:02:37 +02:00
parent 1891f22a5e
commit f6d9c5872d
4 changed files with 29 additions and 11 deletions
+5 -3
View File
@@ -48,7 +48,7 @@ MAX_TEXT_LEN = int(os.environ.get("MAX_TEXT_LEN", "8000"))
logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
log = logging.getLogger("memory-gateway")
app = FastAPI(title="Memory Gateway", version="2.1.0")
app = FastAPI(title="Memory Gateway", version="2.2.0")
qdrant = QdrantClient(url=QDRANT_URL, api_key=QDRANT_API_KEY)
# Rate limit in-memory: {key: [timestamps]}
@@ -76,6 +76,7 @@ class SearchIn(BaseModel):
project_id: Optional[str] = None
scope: Optional[Literal["agent", "project", "org"]] = None
include_superseded: bool = False
min_score: Optional[float] = Field(default=None, ge=0.0, le=1.0)
top_k: int = Field(default=5, ge=1, le=20)
@@ -228,6 +229,7 @@ async def search_memories(body: SearchIn, key: str = Depends(require_auth)) -> d
query_vector=vector,
query_filter=qm.Filter(must=must) if must else None,
limit=body.top_k,
score_threshold=body.min_score, # filtra a livello motore: sotto soglia = rumore
with_payload=True,
)
results = [
@@ -247,8 +249,8 @@ async def search_memories(body: SearchIn, key: str = Depends(require_auth)) -> d
}
for h in hits
]
_audit(key, "search", query=body.query[:80], top_k=body.top_k, hits=len(results))
return {"results": results}
_audit(key, "search", query=body.query[:80], top_k=body.top_k, min_score=body.min_score, hits=len(results))
return {"results": results, "min_score": body.min_score, "total_hits": len(results)}
@app.get("/v1/memories/{memory_id}")