polyglot-rag / core /generation /answer_generator.py
nvikou's picture
Deploy PolyglotRAG v1.1
2697b4c verified
Raw History Blame Contribute Delete
2.19 kB
"""
Appel du LLM génératif — DeepSeek-V4.1-Flash — via le routeur "Inference
Providers" de Hugging Face (https://router.huggingface.co), qui proxy
automatiquement vers un provider tiers (Novita à ce jour) tout en
n'exigeant qu'un seul jeton HF_TOKEN pour l'authentification et la
facturation. Aucune autre clé d'API n'est nécessaire.
"""
from __future__ import annotations
import time
from dataclasses import dataclass
from functools import lru_cache
from core.generation.prompts import build_messages, no_context_message
from core.retrieval.hybrid_search import RetrievalResult
from config import settings
@dataclass
class GenerationResult:
answer: str
used_fallback: bool
latency_seconds: float
sources: list[dict]
@lru_cache(maxsize=1)
def _get_client():
from huggingface_hub import InferenceClient
if not settings.hf_token:
raise RuntimeError("HF_TOKEN manquant : impossible d'appeler le LLM.")
return InferenceClient(api_key=settings.hf_token)
def generate_answer(
question: str,
retrieval: RetrievalResult,
target_language: str,
) -> GenerationResult:
start = time.perf_counter()
if not retrieval.is_sufficient:
return GenerationResult(
answer=no_context_message(target_language),
used_fallback=True,
latency_seconds=time.perf_counter() - start,
sources=[],
)
messages = build_messages(question, retrieval.hits, target_language)
client = _get_client()
completion = client.chat.completions.create(
model=settings.llm_model,
messages=messages,
temperature=settings.llm_temperature,
max_tokens=settings.llm_max_tokens,
)
answer = completion.choices[0].message.content
sources = [
{
"file": hit.source_file,
"language": hit.language,
"page": hit.page,
"score": round(hit.score, 3),
"title": hit.title,
}
for hit in retrieval.hits
]
return GenerationResult(
answer=answer,
used_fallback=False,
latency_seconds=time.perf_counter() - start,
sources=sources,
)