- Бэкенд: FastAPI + SQLAlchemy async + PostgreSQL, JWT-аутентификация, Qdrant multi-tenant векторное хранилище, Celery воркер - Фронтенд: React + Vite + TypeScript SPA (логин, регистрация, дашборд, поиск по коллекциям, настройки) - Инфраструктура: docker-compose, Helm-чарт, GitHub Actions CI, Prometheus/Grafana мониторинг - Embedding через OpenRouter (nvidia/llama-nemotron-embed-vl-1b-v2:free) - LLM: google/gemma-4-31b-it:free через OpenRouter
27 lines
772 B
Python
27 lines
772 B
Python
from sentence_transformers import CrossEncoder
|
|
|
|
reranker = CrossEncoder(
|
|
"cross-encoder/mmarco-mMiniLMv2-L12-H384-v1",
|
|
max_length=512,
|
|
device="cpu",
|
|
)
|
|
|
|
|
|
def rerank(query: str, results: list[dict], k: int = 5) -> list[dict]:
|
|
if not results:
|
|
return []
|
|
|
|
pairs = [(query, r["payload"]["full_text"]) for r in results]
|
|
scores = reranker.predict(pairs)
|
|
|
|
scored = []
|
|
for i, score in enumerate(scores):
|
|
scored.append({
|
|
"ticket_id": results[i]["payload"]["ticket_id"],
|
|
"score": float(score),
|
|
"full_text": results[i]["payload"]["full_text"],
|
|
"category": results[i]["payload"].get("category", ""),
|
|
})
|
|
|
|
scored.sort(key=lambda x: x["score"], reverse=True)
|
|
return scored[:k]
|