Update app.py
Browse files
app.py
CHANGED
|
@@ -32,7 +32,7 @@ if not API_KEY:
|
|
| 32 |
# Definisci i percorsi dei file
|
| 33 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 34 |
RDF_FILE = os.path.join(BASE_DIR, "Ontologia.rdf")
|
| 35 |
-
HF_MODEL = "
|
| 36 |
|
| 37 |
MAX_CLASSES = 30
|
| 38 |
MAX_PROPERTIES = 30
|
|
@@ -96,7 +96,7 @@ def extract_ontology(rdf_file: str, output_file: str):
|
|
| 96 |
# Estrai le proprietà dell'entità
|
| 97 |
entity_properties = {}
|
| 98 |
for predicate, obj in g.predicate_objects(entity):
|
| 99 |
-
if predicate
|
| 100 |
entity_properties[str(predicate)] = str(obj)
|
| 101 |
entities.append({
|
| 102 |
"entity": str(entity),
|
|
@@ -111,7 +111,7 @@ def extract_ontology(rdf_file: str, output_file: str):
|
|
| 111 |
"classes": classes[:MAX_CLASSES],
|
| 112 |
"properties": properties[:MAX_PROPERTIES],
|
| 113 |
"entities": entities, # Aggiungi le entità
|
| 114 |
-
"full_ontology": g.serialize(format="xml") # Decodifica rimossa
|
| 115 |
}
|
| 116 |
|
| 117 |
# Salva il documento in JSON
|
|
@@ -236,11 +236,11 @@ def extract_classes_and_properties(rdf_file: str) -> str:
|
|
| 236 |
txt_entities = "\n".join([f"- ENTITÀ: {e}" for e in entities_list])
|
| 237 |
|
| 238 |
summary = f"""\
|
| 239 |
-
|
| 240 |
{txt_classes}
|
| 241 |
-
|
| 242 |
{txt_props}
|
| 243 |
-
|
| 244 |
{txt_entities}
|
| 245 |
"""
|
| 246 |
logger.info("Estrazione di classi, proprietà ed entità completata.")
|
|
@@ -287,18 +287,15 @@ def create_system_message(ont_text: str, retrieved_docs: str) -> str:
|
|
| 287 |
Prompt di sistema robusto, con regole su query in una riga e
|
| 288 |
informazioni recuperate tramite RAG.
|
| 289 |
"""
|
| 290 |
-
return f"""
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
### Ontologia ###
|
| 295 |
{ont_text}
|
| 296 |
-
|
| 297 |
-
|
| 298 |
Ecco alcune informazioni rilevanti recuperate dalla base di conoscenza:
|
| 299 |
{retrieved_docs}
|
| 300 |
-
|
| 301 |
-
|
| 302 |
1) Se l'utente chiede informazioni su questa ontologia, genera SEMPRE una query SPARQL in UNA SOLA RIGA, con prefix:
|
| 303 |
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
| 304 |
2) La query SPARQL deve essere precisa e cercare esattamente le entità specificate dall'utente. Ad esempio, se l'utente chiede "Chi ha creato l'opera 'Amore e Psiche'?", la query dovrebbe cercare l'opera esattamente con quel nome.
|
|
@@ -307,20 +304,15 @@ Ecco alcune informazioni rilevanti recuperate dalla base di conoscenza:
|
|
| 307 |
5) Se trovi risultati, la risposta finale deve essere la query SPARQL (una sola riga).
|
| 308 |
6) Se non trovi nulla, rispondi con 'Nessuna info.'
|
| 309 |
7) Non multiline. Esempio: PREFIX base: <...> SELECT ?x WHERE { ... }.
|
| 310 |
-
|
| 311 |
-
**Esempi:**
|
| 312 |
Utente: Chi ha creato l'opera 'Amore e Psiche'?
|
| 313 |
Risposta: PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#> SELECT ?creatore WHERE { ?opera base:hasName "Amore e Psiche" . ?opera base:creatoDa ?creatore . }
|
| 314 |
-
|
| 315 |
-
Utente: che ore sono?
|
| 316 |
-
Risposta: Ciao! Sono un assistente museale e non ho informazioni sulle ore attuali. Ti consiglio di consultare un orologio o un dispositivo mobile per conoscere l'ora esatta.
|
| 317 |
-
|
| 318 |
-
### FINE Regole Stringenti ###
|
| 319 |
"""
|
| 320 |
|
| 321 |
def create_explanation_prompt(results_str: str) -> str:
|
| 322 |
"""Prompt per generare una spiegazione museale dei risultati SPARQL."""
|
| 323 |
-
return f"""
|
| 324 |
Ho ottenuto questi risultati SPARQL:
|
| 325 |
{results_str}
|
| 326 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
|
@@ -473,7 +465,7 @@ async def generate_response(req: QueryRequest):
|
|
| 473 |
row_list = []
|
| 474 |
for row in results:
|
| 475 |
row_dict = row.asdict()
|
| 476 |
-
row_str = ", ".join([f"{k}:{v}" for k, v in row_dict.items()])
|
| 477 |
row_list.append(row_str)
|
| 478 |
results_str = "\n".join(row_list)
|
| 479 |
|
|
@@ -494,4 +486,4 @@ async def generate_response(req: QueryRequest):
|
|
| 494 |
|
| 495 |
@app.get("/")
|
| 496 |
def home():
|
| 497 |
-
return {"message": "
|
|
|
|
| 32 |
# Definisci i percorsi dei file
|
| 33 |
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
| 34 |
RDF_FILE = os.path.join(BASE_DIR, "Ontologia.rdf")
|
| 35 |
+
HF_MODEL = "google/flan-t5-xxl" # Modello ottimizzato per seguire istruzioni
|
| 36 |
|
| 37 |
MAX_CLASSES = 30
|
| 38 |
MAX_PROPERTIES = 30
|
|
|
|
| 96 |
# Estrai le proprietà dell'entità
|
| 97 |
entity_properties = {}
|
| 98 |
for predicate, obj in g.predicate_objects(entity):
|
| 99 |
+
if predicate not in [RDFS.label, RDFS.comment]:
|
| 100 |
entity_properties[str(predicate)] = str(obj)
|
| 101 |
entities.append({
|
| 102 |
"entity": str(entity),
|
|
|
|
| 111 |
"classes": classes[:MAX_CLASSES],
|
| 112 |
"properties": properties[:MAX_PROPERTIES],
|
| 113 |
"entities": entities, # Aggiungi le entità
|
| 114 |
+
"full_ontology": g.serialize(format="xml").decode('utf-8') if isinstance(g.serialize(format="xml"), bytes) else g.serialize(format="xml") # Decodifica rimossa
|
| 115 |
}
|
| 116 |
|
| 117 |
# Salva il documento in JSON
|
|
|
|
| 236 |
txt_entities = "\n".join([f"- ENTITÀ: {e}" for e in entities_list])
|
| 237 |
|
| 238 |
summary = f"""\
|
| 239 |
+
# CLASSI (max {MAX_CLASSES})
|
| 240 |
{txt_classes}
|
| 241 |
+
# PROPRIETÀ (max {MAX_PROPERTIES})
|
| 242 |
{txt_props}
|
| 243 |
+
# ENTITÀ (max {MAX_CLASSES})
|
| 244 |
{txt_entities}
|
| 245 |
"""
|
| 246 |
logger.info("Estrazione di classi, proprietà ed entità completata.")
|
|
|
|
| 287 |
Prompt di sistema robusto, con regole su query in una riga e
|
| 288 |
informazioni recuperate tramite RAG.
|
| 289 |
"""
|
| 290 |
+
return f"""\
|
| 291 |
+
Sei un assistente museale esperto in ontologie RDF. Utilizza le informazioni fornite per generare query SPARQL precise e pertinenti. Ecco un estratto di CLASSI, PROPRIETÀ ed ENTità dell'ontologia (senza NamedIndividuals):
|
| 292 |
+
--- ONTOLOGIA ---
|
|
|
|
|
|
|
| 293 |
{ont_text}
|
| 294 |
+
--- FINE ---
|
|
|
|
| 295 |
Ecco alcune informazioni rilevanti recuperate dalla base di conoscenza:
|
| 296 |
{retrieved_docs}
|
| 297 |
+
Suggerimento: se l'utente chiede il 'materiale' di un'opera, potresti usare qualcosa come 'base:materialeOpera' o un'altra proprietà simile (se esiste). Non è tassativo: usa la proprietà che ritieni più affine se ci sono riferimenti in ontologia.
|
| 298 |
+
REGOLE STRINGENTI:
|
| 299 |
1) Se l'utente chiede informazioni su questa ontologia, genera SEMPRE una query SPARQL in UNA SOLA RIGA, con prefix:
|
| 300 |
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
| 301 |
2) La query SPARQL deve essere precisa e cercare esattamente le entità specificate dall'utente. Ad esempio, se l'utente chiede "Chi ha creato l'opera 'Amore e Psiche'?", la query dovrebbe cercare l'opera esattamente con quel nome.
|
|
|
|
| 304 |
5) Se trovi risultati, la risposta finale deve essere la query SPARQL (una sola riga).
|
| 305 |
6) Se non trovi nulla, rispondi con 'Nessuna info.'
|
| 306 |
7) Non multiline. Esempio: PREFIX base: <...> SELECT ?x WHERE { ... }.
|
| 307 |
+
Esempio:
|
|
|
|
| 308 |
Utente: Chi ha creato l'opera 'Amore e Psiche'?
|
| 309 |
Risposta: PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#> SELECT ?creatore WHERE { ?opera base:hasName "Amore e Psiche" . ?opera base:creatoDa ?creatore . }
|
| 310 |
+
FINE REGOLE
|
|
|
|
|
|
|
|
|
|
|
|
|
| 311 |
"""
|
| 312 |
|
| 313 |
def create_explanation_prompt(results_str: str) -> str:
|
| 314 |
"""Prompt per generare una spiegazione museale dei risultati SPARQL."""
|
| 315 |
+
return f"""\
|
| 316 |
Ho ottenuto questi risultati SPARQL:
|
| 317 |
{results_str}
|
| 318 |
Ora fornisci una breve spiegazione museale (massimo ~10 righe), senza inventare oltre i risultati.
|
|
|
|
| 465 |
row_list = []
|
| 466 |
for row in results:
|
| 467 |
row_dict = row.asdict()
|
| 468 |
+
row_str = ", ".join([f"{k}: {v}" for k, v in row_dict.items()])
|
| 469 |
row_list.append(row_str)
|
| 470 |
results_str = "\n".join(row_list)
|
| 471 |
|
|
|
|
| 486 |
|
| 487 |
@app.get("/")
|
| 488 |
def home():
|
| 489 |
+
return {"message": "Assistente Museale con supporto SPARQL."}
|