Update app.py
Browse files
app.py
CHANGED
|
@@ -47,7 +47,12 @@ except Exception as e:
|
|
| 47 |
raise e
|
| 48 |
|
| 49 |
# Inizializza il client di Hugging Face
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
|
| 52 |
def create_data_directory():
|
| 53 |
"""Crea la directory 'data/' se non esiste."""
|
|
@@ -207,38 +212,49 @@ def create_explanation_prompt(results_str: str) -> str:
|
|
| 207 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
| 208 |
"""
|
| 209 |
|
| 210 |
-
async def call_hf_model(prompt: str, temperature: float = 0.5, max_tokens: int = 150) -> str:
|
| 211 |
"""Chiama il modello Hugging Face tramite InferenceClient e gestisce la risposta."""
|
| 212 |
logger.debug("Chiamo HF con il seguente prompt:")
|
| 213 |
content_preview = (prompt[:300] + '...') if len(prompt) > 300 else prompt
|
| 214 |
logger.debug(f"PROMPT => {content_preview}")
|
| 215 |
|
| 216 |
try:
|
| 217 |
-
#
|
| 218 |
-
|
| 219 |
-
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
|
|
|
|
|
|
| 224 |
max_tokens=max_tokens,
|
|
|
|
| 225 |
top_p=0.7,
|
| 226 |
-
stream=
|
| 227 |
)
|
| 228 |
-
logger.debug(f"Risposta completa dal modello: {response}")
|
| 229 |
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
|
|
|
|
|
|
|
|
|
| 235 |
else:
|
| 236 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
-
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
| 242 |
except Exception as e:
|
| 243 |
logger.error(f"Errore nella chiamata all'API Hugging Face tramite InferenceClient: {e}")
|
| 244 |
raise HTTPException(status_code=500, detail=str(e))
|
|
@@ -290,9 +306,9 @@ async def generate_response(req: QueryRequest):
|
|
| 290 |
|
| 291 |
if not is_ontology_related(user_input):
|
| 292 |
# Prompt generico per domande non pertinenti all'ontologia
|
| 293 |
-
generic_prompt = f"
|
| 294 |
try:
|
| 295 |
-
response = await call_hf_model(generic_prompt, req.temperature, req.max_tokens)
|
| 296 |
return {
|
| 297 |
"type": "NATURAL",
|
| 298 |
"response": response.strip()
|
|
@@ -312,11 +328,11 @@ async def generate_response(req: QueryRequest):
|
|
| 312 |
return {"type": "ERROR", "response": f"Errore nel recupero delle linee: {e}"}
|
| 313 |
|
| 314 |
sys_msg = create_system_message(retrieved_docs)
|
| 315 |
-
prompt = f"
|
| 316 |
|
| 317 |
# Primo tentativo
|
| 318 |
try:
|
| 319 |
-
r1 = await call_hf_model(prompt, req.temperature, req.max_tokens)
|
| 320 |
logger.info(f"PRIMA RISPOSTA:\n{r1}")
|
| 321 |
except Exception as e:
|
| 322 |
logger.error(f"Errore nella chiamata al modello Hugging Face: {e}")
|
|
@@ -325,9 +341,9 @@ async def generate_response(req: QueryRequest):
|
|
| 325 |
# Se non parte con "PREFIX base:"
|
| 326 |
if not r1.startswith("PREFIX base:"):
|
| 327 |
sc = f"Non hai risposto con query SPARQL su una sola riga. Riprova. Domanda: {user_input}"
|
| 328 |
-
fallback_prompt = f"
|
| 329 |
try:
|
| 330 |
-
r2 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens)
|
| 331 |
logger.info(f"SECONDA RISPOSTA:\n{r2}")
|
| 332 |
if r2.startswith("PREFIX base:"):
|
| 333 |
sparql_query = r2
|
|
@@ -353,9 +369,9 @@ async def generate_response(req: QueryRequest):
|
|
| 353 |
logger.info(f"Query SPARQL eseguita con successo. Risultati: {len(results)}")
|
| 354 |
except Exception as e:
|
| 355 |
fallback = f"La query SPARQL ha fallito. Riprova. Domanda: {user_input}"
|
| 356 |
-
fallback_prompt = f"
|
| 357 |
try:
|
| 358 |
-
r3 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens)
|
| 359 |
logger.info(f"TERZA RISPOSTA (fallback):\n{r3}")
|
| 360 |
if r3.startswith("PREFIX base:"):
|
| 361 |
sparql_query = r3
|
|
@@ -386,7 +402,7 @@ async def generate_response(req: QueryRequest):
|
|
| 386 |
# Spiegazione
|
| 387 |
exp_prompt = create_explanation_prompt(results_str)
|
| 388 |
try:
|
| 389 |
-
explanation = await call_hf_model(exp_prompt, req.temperature, req.max_tokens)
|
| 390 |
except Exception as e:
|
| 391 |
logger.error(f"Errore nella generazione della spiegazione: {e}")
|
| 392 |
return {"type": "ERROR", "response": f"Errore nella generazione della spiegazione: {e}"}
|
|
|
|
| 47 |
raise e
|
| 48 |
|
| 49 |
# Inizializza il client di Hugging Face
|
| 50 |
+
try:
|
| 51 |
+
client = InferenceClient(HF_MODEL, token=HF_API_KEY)
|
| 52 |
+
logger.info("InferenceClient inizializzato correttamente.")
|
| 53 |
+
except Exception as e:
|
| 54 |
+
logger.error(f"Errore nell'inizializzazione di InferenceClient: {e}")
|
| 55 |
+
raise e
|
| 56 |
|
| 57 |
def create_data_directory():
|
| 58 |
"""Crea la directory 'data/' se non esiste."""
|
|
|
|
| 212 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
| 213 |
"""
|
| 214 |
|
| 215 |
+
async def call_hf_model(prompt: str, temperature: float = 0.5, max_tokens: int = 150, stream: bool = False) -> str:
|
| 216 |
"""Chiama il modello Hugging Face tramite InferenceClient e gestisce la risposta."""
|
| 217 |
logger.debug("Chiamo HF con il seguente prompt:")
|
| 218 |
content_preview = (prompt[:300] + '...') if len(prompt) > 300 else prompt
|
| 219 |
logger.debug(f"PROMPT => {content_preview}")
|
| 220 |
|
| 221 |
try:
|
| 222 |
+
# Costruisci i messaggi per il modello
|
| 223 |
+
messages = [
|
| 224 |
+
{"role": "system", "content": "You are a helpful assistant."},
|
| 225 |
+
{"role": "user", "content": prompt}
|
| 226 |
+
]
|
| 227 |
+
|
| 228 |
+
# Esegui la chat_completion
|
| 229 |
+
response = client.chat_completion(
|
| 230 |
+
messages=messages,
|
| 231 |
max_tokens=max_tokens,
|
| 232 |
+
temperature=temperature,
|
| 233 |
top_p=0.7,
|
| 234 |
+
stream=stream
|
| 235 |
)
|
|
|
|
| 236 |
|
| 237 |
+
if stream:
|
| 238 |
+
# Gestisci lo stream
|
| 239 |
+
generated_text = ""
|
| 240 |
+
async for token in response:
|
| 241 |
+
if token.choices and token.choices[0].delta.get("content"):
|
| 242 |
+
generated_text += token.choices[0].delta["content"]
|
| 243 |
+
print(token.choices[0].delta["content"], end="")
|
| 244 |
+
return generated_text.strip()
|
| 245 |
else:
|
| 246 |
+
# Risposta non in streaming
|
| 247 |
+
if isinstance(response, list) and len(response) > 0 and "generated_text" in response[0]:
|
| 248 |
+
raw = response[0]["generated_text"]
|
| 249 |
+
elif "generated_text" in response:
|
| 250 |
+
raw = response["generated_text"]
|
| 251 |
+
else:
|
| 252 |
+
raise ValueError("Nessun campo 'generated_text' nella risposta.")
|
| 253 |
|
| 254 |
+
# Forza la risposta su una singola linea se multilinea
|
| 255 |
+
single_line = " ".join(raw.splitlines())
|
| 256 |
+
logger.debug(f"Risposta HF single-line: {single_line}")
|
| 257 |
+
return single_line.strip()
|
| 258 |
except Exception as e:
|
| 259 |
logger.error(f"Errore nella chiamata all'API Hugging Face tramite InferenceClient: {e}")
|
| 260 |
raise HTTPException(status_code=500, detail=str(e))
|
|
|
|
| 306 |
|
| 307 |
if not is_ontology_related(user_input):
|
| 308 |
# Prompt generico per domande non pertinenti all'ontologia
|
| 309 |
+
generic_prompt = f"{user_input}"
|
| 310 |
try:
|
| 311 |
+
response = await call_hf_model(generic_prompt, req.temperature, req.max_tokens, stream=False)
|
| 312 |
return {
|
| 313 |
"type": "NATURAL",
|
| 314 |
"response": response.strip()
|
|
|
|
| 328 |
return {"type": "ERROR", "response": f"Errore nel recupero delle linee: {e}"}
|
| 329 |
|
| 330 |
sys_msg = create_system_message(retrieved_docs)
|
| 331 |
+
prompt = sys_msg + f"\nUtente: {user_input}\nAssistente:"
|
| 332 |
|
| 333 |
# Primo tentativo
|
| 334 |
try:
|
| 335 |
+
r1 = await call_hf_model(prompt, req.temperature, req.max_tokens, stream=False)
|
| 336 |
logger.info(f"PRIMA RISPOSTA:\n{r1}")
|
| 337 |
except Exception as e:
|
| 338 |
logger.error(f"Errore nella chiamata al modello Hugging Face: {e}")
|
|
|
|
| 341 |
# Se non parte con "PREFIX base:"
|
| 342 |
if not r1.startswith("PREFIX base:"):
|
| 343 |
sc = f"Non hai risposto con query SPARQL su una sola riga. Riprova. Domanda: {user_input}"
|
| 344 |
+
fallback_prompt = sys_msg + f"\nAssistente: {r1}\nUtente: {sc}\nAssistente:"
|
| 345 |
try:
|
| 346 |
+
r2 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens, stream=False)
|
| 347 |
logger.info(f"SECONDA RISPOSTA:\n{r2}")
|
| 348 |
if r2.startswith("PREFIX base:"):
|
| 349 |
sparql_query = r2
|
|
|
|
| 369 |
logger.info(f"Query SPARQL eseguita con successo. Risultati: {len(results)}")
|
| 370 |
except Exception as e:
|
| 371 |
fallback = f"La query SPARQL ha fallito. Riprova. Domanda: {user_input}"
|
| 372 |
+
fallback_prompt = sys_msg + f"\nAssistente: {sparql_query}\nUtente: {fallback}\nAssistente:"
|
| 373 |
try:
|
| 374 |
+
r3 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens, stream=False)
|
| 375 |
logger.info(f"TERZA RISPOSTA (fallback):\n{r3}")
|
| 376 |
if r3.startswith("PREFIX base:"):
|
| 377 |
sparql_query = r3
|
|
|
|
| 402 |
# Spiegazione
|
| 403 |
exp_prompt = create_explanation_prompt(results_str)
|
| 404 |
try:
|
| 405 |
+
explanation = await call_hf_model(exp_prompt, req.temperature, req.max_tokens, stream=False)
|
| 406 |
except Exception as e:
|
| 407 |
logger.error(f"Errore nella generazione della spiegazione: {e}")
|
| 408 |
return {"type": "ERROR", "response": f"Errore nella generazione della spiegazione: {e}"}
|