Update app.py
Browse files
app.py
CHANGED
|
@@ -48,6 +48,7 @@ def create_data_directory():
|
|
| 48 |
"""Crea la directory 'data/' se non esiste."""
|
| 49 |
os.makedirs(os.path.join(BASE_DIR, "data"), exist_ok=True)
|
| 50 |
logger.info("Directory 'data/' creata o già esistente.")
|
|
|
|
| 51 |
def extract_ontology(rdf_file: str, output_file: str):
|
| 52 |
"""
|
| 53 |
Estrae classi, proprietà ed entità dall'ontologia RDF e le salva in un file JSON come un unico documento.
|
|
@@ -125,7 +126,6 @@ def extract_ontology(rdf_file: str, output_file: str):
|
|
| 125 |
logger.error(f"Errore nel salvataggio di {output_file}: {e}")
|
| 126 |
raise e
|
| 127 |
|
| 128 |
-
|
| 129 |
def create_faiss_index(documents_file: str, index_file: str, embedding_model: str = 'all-MiniLM-L6-v2'):
|
| 130 |
"""
|
| 131 |
Crea un indice FAISS a partire dal documento estratto.
|
|
@@ -284,7 +284,7 @@ def retrieve_relevant_documents(query: str, top_k: int = 5):
|
|
| 284 |
except Exception as e:
|
| 285 |
logger.error(f"Errore nel recupero dei documenti rilevanti: {e}")
|
| 286 |
raise e
|
| 287 |
-
|
| 288 |
def create_system_message(ont_text: str, retrieved_docs: str) -> str:
|
| 289 |
"""
|
| 290 |
Prompt di sistema robusto, con regole su query in una riga e
|
|
@@ -323,23 +323,25 @@ Ho ottenuto questi risultati SPARQL:
|
|
| 323 |
{results_str}
|
| 324 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
| 325 |
"""
|
| 326 |
-
|
| 327 |
-
async def call_hf_model(
|
| 328 |
"""Chiama il modello Hugging Face e gestisce la risposta."""
|
| 329 |
-
logger.debug("Chiamo HF con
|
| 330 |
-
|
| 331 |
-
|
| 332 |
-
logger.debug(f"ROLE={m['role']} => {content_preview}")
|
| 333 |
try:
|
| 334 |
-
resp = client.
|
| 335 |
model=HF_MODEL,
|
| 336 |
-
|
| 337 |
-
|
| 338 |
-
|
| 339 |
-
|
|
|
|
|
|
|
| 340 |
)
|
| 341 |
-
|
| 342 |
-
|
|
|
|
| 343 |
single_line = " ".join(raw.splitlines())
|
| 344 |
logger.debug(f"Risposta HF single-line: {single_line}")
|
| 345 |
return single_line.strip()
|
|
@@ -373,14 +375,11 @@ async def generate_response(req: QueryRequest):
|
|
| 373 |
return {"type": "ERROR", "response": f"Errore nel recupero dei documenti: {e}"}
|
| 374 |
|
| 375 |
sys_msg = create_system_message(knowledge_text, retrieved_docs)
|
| 376 |
-
|
| 377 |
-
{"role": "system", "content": sys_msg},
|
| 378 |
-
{"role": "user", "content": user_input}
|
| 379 |
-
]
|
| 380 |
|
| 381 |
# Primo tentativo
|
| 382 |
try:
|
| 383 |
-
r1 = await call_hf_model(
|
| 384 |
logger.info(f"PRIMA RISPOSTA:\n{r1}")
|
| 385 |
except Exception as e:
|
| 386 |
logger.error(f"Errore nella chiamata al modello Hugging Face: {e}")
|
|
@@ -389,13 +388,9 @@ async def generate_response(req: QueryRequest):
|
|
| 389 |
# Se non parte con "PREFIX base:"
|
| 390 |
if not r1.startswith("PREFIX base:"):
|
| 391 |
sc = f"Non hai risposto con query SPARQL su una sola riga. Riprova. Domanda: {user_input}"
|
| 392 |
-
|
| 393 |
-
{"role": "system", "content": sys_msg},
|
| 394 |
-
{"role": "assistant", "content": r1},
|
| 395 |
-
{"role": "user", "content": sc}
|
| 396 |
-
]
|
| 397 |
try:
|
| 398 |
-
r2 = await call_hf_model(
|
| 399 |
logger.info(f"SECONDA RISPOSTA:\n{r2}")
|
| 400 |
if r2.startswith("PREFIX base:"):
|
| 401 |
sparql_query = r2
|
|
@@ -421,13 +416,9 @@ async def generate_response(req: QueryRequest):
|
|
| 421 |
logger.info(f"Query SPARQL eseguita con successo. Risultati: {len(results)}")
|
| 422 |
except Exception as e:
|
| 423 |
fallback = f"La query SPARQL ha fallito. Riprova. Domanda: {user_input}"
|
| 424 |
-
|
| 425 |
-
{"role": "system", "content": sys_msg},
|
| 426 |
-
{"role": "assistant", "content": sparql_query},
|
| 427 |
-
{"role": "user", "content": fallback}
|
| 428 |
-
]
|
| 429 |
try:
|
| 430 |
-
r3 = await call_hf_model(
|
| 431 |
logger.info(f"TERZA RISPOSTA (fallback):\n{r3}")
|
| 432 |
if r3.startswith("PREFIX base:"):
|
| 433 |
sparql_query = r3
|
|
@@ -456,12 +447,8 @@ async def generate_response(req: QueryRequest):
|
|
| 456 |
|
| 457 |
# Spiegazione
|
| 458 |
exp_prompt = create_explanation_prompt(results_str)
|
| 459 |
-
msgs4 = [
|
| 460 |
-
{"role": "system", "content": exp_prompt},
|
| 461 |
-
{"role": "user", "content": ""}
|
| 462 |
-
]
|
| 463 |
try:
|
| 464 |
-
explanation = await call_hf_model(
|
| 465 |
except Exception as e:
|
| 466 |
logger.error(f"Errore nella generazione della spiegazione: {e}")
|
| 467 |
return {"type": "ERROR", "response": f"Errore nella generazione della spiegazione: {e}"}
|
|
|
|
| 48 |
"""Crea la directory 'data/' se non esiste."""
|
| 49 |
os.makedirs(os.path.join(BASE_DIR, "data"), exist_ok=True)
|
| 50 |
logger.info("Directory 'data/' creata o già esistente.")
|
| 51 |
+
|
| 52 |
def extract_ontology(rdf_file: str, output_file: str):
|
| 53 |
"""
|
| 54 |
Estrae classi, proprietà ed entità dall'ontologia RDF e le salva in un file JSON come un unico documento.
|
|
|
|
| 126 |
logger.error(f"Errore nel salvataggio di {output_file}: {e}")
|
| 127 |
raise e
|
| 128 |
|
|
|
|
| 129 |
def create_faiss_index(documents_file: str, index_file: str, embedding_model: str = 'all-MiniLM-L6-v2'):
|
| 130 |
"""
|
| 131 |
Crea un indice FAISS a partire dal documento estratto.
|
|
|
|
| 284 |
except Exception as e:
|
| 285 |
logger.error(f"Errore nel recupero dei documenti rilevanti: {e}")
|
| 286 |
raise e
|
| 287 |
+
|
| 288 |
def create_system_message(ont_text: str, retrieved_docs: str) -> str:
|
| 289 |
"""
|
| 290 |
Prompt di sistema robusto, con regole su query in una riga e
|
|
|
|
| 323 |
{results_str}
|
| 324 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
| 325 |
"""
|
| 326 |
+
|
| 327 |
+
async def call_hf_model(prompt: str, temperature=0.5, max_tokens=1024) -> str:
|
| 328 |
"""Chiama il modello Hugging Face e gestisce la risposta."""
|
| 329 |
+
logger.debug("Chiamo HF con il seguente prompt:")
|
| 330 |
+
content_preview = (prompt[:300] + '...') if len(prompt) > 300 else prompt
|
| 331 |
+
logger.debug(f"PROMPT => {content_preview}")
|
|
|
|
| 332 |
try:
|
| 333 |
+
resp = client.text_generation(
|
| 334 |
model=HF_MODEL,
|
| 335 |
+
inputs=prompt,
|
| 336 |
+
parameters={
|
| 337 |
+
"temperature": temperature,
|
| 338 |
+
"max_new_tokens": max_tokens,
|
| 339 |
+
"top_p": 0.9
|
| 340 |
+
}
|
| 341 |
)
|
| 342 |
+
# La struttura della risposta dipende dall'API; verifica se "generated_text" è il campo corretto
|
| 343 |
+
raw = resp["generated_text"]
|
| 344 |
+
# Forza la risposta su una singola linea se multilinea
|
| 345 |
single_line = " ".join(raw.splitlines())
|
| 346 |
logger.debug(f"Risposta HF single-line: {single_line}")
|
| 347 |
return single_line.strip()
|
|
|
|
| 375 |
return {"type": "ERROR", "response": f"Errore nel recupero dei documenti: {e}"}
|
| 376 |
|
| 377 |
sys_msg = create_system_message(knowledge_text, retrieved_docs)
|
| 378 |
+
prompt = f"{sys_msg}\nUtente: {user_input}\nAssistente:"
|
|
|
|
|
|
|
|
|
|
| 379 |
|
| 380 |
# Primo tentativo
|
| 381 |
try:
|
| 382 |
+
r1 = await call_hf_model(prompt, req.temperature, req.max_tokens)
|
| 383 |
logger.info(f"PRIMA RISPOSTA:\n{r1}")
|
| 384 |
except Exception as e:
|
| 385 |
logger.error(f"Errore nella chiamata al modello Hugging Face: {e}")
|
|
|
|
| 388 |
# Se non parte con "PREFIX base:"
|
| 389 |
if not r1.startswith("PREFIX base:"):
|
| 390 |
sc = f"Non hai risposto con query SPARQL su una sola riga. Riprova. Domanda: {user_input}"
|
| 391 |
+
fallback_prompt = f"{sys_msg}\nAssistente: {r1}\nUtente: {sc}\nAssistente:"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 392 |
try:
|
| 393 |
+
r2 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens)
|
| 394 |
logger.info(f"SECONDA RISPOSTA:\n{r2}")
|
| 395 |
if r2.startswith("PREFIX base:"):
|
| 396 |
sparql_query = r2
|
|
|
|
| 416 |
logger.info(f"Query SPARQL eseguita con successo. Risultati: {len(results)}")
|
| 417 |
except Exception as e:
|
| 418 |
fallback = f"La query SPARQL ha fallito. Riprova. Domanda: {user_input}"
|
| 419 |
+
fallback_prompt = f"{sys_msg}\nAssistente: {sparql_query}\nUtente: {fallback}\nAssistente:"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 420 |
try:
|
| 421 |
+
r3 = await call_hf_model(fallback_prompt, req.temperature, req.max_tokens)
|
| 422 |
logger.info(f"TERZA RISPOSTA (fallback):\n{r3}")
|
| 423 |
if r3.startswith("PREFIX base:"):
|
| 424 |
sparql_query = r3
|
|
|
|
| 447 |
|
| 448 |
# Spiegazione
|
| 449 |
exp_prompt = create_explanation_prompt(results_str)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 450 |
try:
|
| 451 |
+
explanation = await call_hf_model(exp_prompt, req.temperature, req.max_tokens)
|
| 452 |
except Exception as e:
|
| 453 |
logger.error(f"Errore nella generazione della spiegazione: {e}")
|
| 454 |
return {"type": "ERROR", "response": f"Errore nella generazione della spiegazione: {e}"}
|