Context
services/ai/app/services/reranker.py esiste già con cross-encoder/ms-marco-MiniLM-L-6-v2 e la logica di reranking è implementata, ma non viene mai chiamato da chat_service.py. Il flusso attuale recupera direttamente top-5 da QVAC e li passa al LLM senza riordino semantico. Wirare il reranker è il miglioramento a più alto rapporto impatto/effort dello Sprint 1.
File coinvolti
services/ai/app/services/chat_service.py
services/ai/app/services/reranker.py (già implementato, da usare as-is)
Azioni richieste
-
In chat_service.py → answer():
- Aumentare
topK a 20 per la chiamata QVAC (o usare una costante separata _RERANK_FETCH_K = 20)
- Dopo aver ricevuto i risultati, chiamare
reranker.rerank(question, sources)
- Passare solo i top-5 riordinati al LLM
-
Verificare che il fallback ChromaDB passi anch'esso per il reranker.
-
Aggiungere rerank_score alla struttura Citation se non già presente, per visibilità nel debug.
-
Test A/B su un set di query campione: confrontare la posizione del chunk atteso prima e dopo il reranking.
Acceptance criteria
reranker.rerank() viene chiamato in ogni path di answer() che restituisce risultati
- Il LLM riceve sempre ≤5 chunk (top-5 riordinati), non 20
- La latenza aggiuntiva del reranker è accettabile su CPU (<200ms per batch di 20 chunk)
- I test esistenti passano; aggiungere almeno un test che verifica l'ordine dei risultati
Note
- Il modello
ms-marco-MiniLM-L-6-v2 pesa ~22–100 MB ed è CPU-only
- Latenza stimata: ~50–200ms per batch di 20 chunk su CPU
- Alternativa più leggera se latenza troppo alta:
ms-marco-MiniLM-L-6-v2 via FlashRank (~22 MB)
Riferimenti
- [rag-sota-2026.md §2.5 — Hybrid Search + Reranking]
services/ai/app/services/reranker.py (implementazione esistente)
Context
services/ai/app/services/reranker.pyesiste già concross-encoder/ms-marco-MiniLM-L-6-v2e la logica di reranking è implementata, ma non viene mai chiamato dachat_service.py. Il flusso attuale recupera direttamente top-5 da QVAC e li passa al LLM senza riordino semantico. Wirare il reranker è il miglioramento a più alto rapporto impatto/effort dello Sprint 1.File coinvolti
services/ai/app/services/chat_service.pyservices/ai/app/services/reranker.py(già implementato, da usare as-is)Azioni richieste
In
chat_service.py → answer():topKa 20 per la chiamata QVAC (o usare una costante separata_RERANK_FETCH_K = 20)reranker.rerank(question, sources)Verificare che il fallback ChromaDB passi anch'esso per il reranker.
Aggiungere
rerank_scorealla strutturaCitationse non già presente, per visibilità nel debug.Test A/B su un set di query campione: confrontare la posizione del chunk atteso prima e dopo il reranking.
Acceptance criteria
reranker.rerank()viene chiamato in ogni path dianswer()che restituisce risultatiNote
ms-marco-MiniLM-L-6-v2pesa ~22–100 MB ed è CPU-onlyms-marco-MiniLM-L-6-v2via FlashRank (~22 MB)Riferimenti
services/ai/app/services/reranker.py(implementazione esistente)