Update app.py
Browse files
app.py
CHANGED
@@ -45,14 +45,11 @@ def load_rdf_summary() -> str:
|
|
45 |
g = Graph()
|
46 |
g.parse(RDF_FILE, format="xml")
|
47 |
|
48 |
-
# Estrazione semplificata di classi e proprietà
|
49 |
classes = set()
|
50 |
properties = set()
|
51 |
for s, p, o in g.triples((None, None, None)):
|
52 |
-
# Se l'oggetto è 'Class', lo aggiungiamo a classes
|
53 |
if "Class" in str(o):
|
54 |
classes.add(s)
|
55 |
-
# Se l'oggetto è 'Property', lo aggiungiamo a properties
|
56 |
if "Property" in str(o):
|
57 |
properties.add(s)
|
58 |
|
@@ -88,68 +85,68 @@ def validate_sparql_query(query: str, rdf_file_path: str) -> bool:
|
|
88 |
return False
|
89 |
|
90 |
####################################
|
91 |
-
# Prompt di Sistema
|
92 |
####################################
|
93 |
def create_system_message(rdf_context: str) -> str:
|
94 |
"""
|
95 |
Crea il messaggio di sistema per il modello di linguaggio naturale.
|
96 |
-
|
97 |
"""
|
98 |
return f"""
|
99 |
Sei un'assistente esperta nella generazione di query SPARQL basate su un'ontologia RDF,
|
100 |
-
nell'interpretazione dei risultati delle query SPARQL in risposte naturali,
|
101 |
-
nel fare chatting minimale con i visitatori in diverse lingue (
|
102 |
|
103 |
In base alla domanda dell'utente, devi decidere se:
|
104 |
-
1
|
105 |
-
2
|
106 |
-
3
|
107 |
-
|
108 |
-
|
109 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
110 |
|
111 |
Regole TASSATIVE:
|
112 |
-
1. Se la domanda richiede una query SPARQL, restituisci la query SPARQL
|
113 |
-
2. Se la domanda richiede
|
114 |
-
3. Se la domanda è una chat minimale,
|
115 |
4. DEVI usare ESCLUSIVAMENTE questo prefisso di base (e NON modificarlo in nessun modo):
|
116 |
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
117 |
5. NON generare alcun altro prefisso o URI inventato.
|
118 |
-
6. Se non
|
119 |
-
o fare
|
120 |
-
"Non posso generare una query SPARQL, interpretare i risultati o fare una risposta di chat per questa richiesta."
|
121 |
|
122 |
Esempi:
|
123 |
- Domanda: "Quali sono le statue esposte del periodo medievale?"
|
124 |
-
Risposta:
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
Ecco le 5 statue medievali trovate: Statua1, Statua2, Statua3, Statua4, Statua5.
|
131 |
|
132 |
- Domanda: "Ciao!"
|
133 |
-
Risposta:
|
134 |
-
|
135 |
-
|
136 |
-
- Domanda: "
|
137 |
-
|
138 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
L'arte moderna è un'espressione affascinante e varia che riflette le dinamiche sociali e culturali contemporanee.
|
143 |
-
|
144 |
-
- Domanda: "How does this installation work?"
|
145 |
-
Risposta:
|
146 |
-
This interactive installation allows you to explore various artworks through digital interactions.
|
147 |
-
Simply approach and follow the on-screen instructions.
|
148 |
-
|
149 |
-
- Domanda: "Come funziona questa installazione?"
|
150 |
-
Risposta:
|
151 |
-
Questa installazione interattiva ti permette di esplorare diverse opere d'arte attraverso interazioni digitali.
|
152 |
-
Basta avvicinarti e seguire le istruzioni sullo schermo.
|
153 |
|
154 |
RISPONDI ESCLUSIVAMENTE CON IL FORMATO SPECIFICATO.
|
155 |
"""
|
@@ -173,7 +170,7 @@ async def call_model(messages, temperature=0.7, max_tokens=2048):
|
|
173 |
)
|
174 |
raw_text = response["choices"][0]["message"]["content"]
|
175 |
logger.debug(f"Risposta del modello ricevuta: {raw_text}")
|
176 |
-
# Rimuoviamo eventuali newline per forzare
|
177 |
return raw_text.replace("\n", " ").strip()
|
178 |
except Exception as e:
|
179 |
logger.error(f"Errore durante la chiamata al modello: {e}")
|
@@ -198,13 +195,13 @@ async def interpret_sparql_results(results):
|
|
198 |
])
|
199 |
logger.debug(f"Risultati SPARQL:\n{results_str}")
|
200 |
|
201 |
-
#
|
202 |
interpret_prompt = f"""
|
203 |
Mi hai fornito i seguenti risultati di una query SPARQL:
|
204 |
{results_str}
|
205 |
|
206 |
Per favore, interpreta questi risultati e fornisci una risposta naturale ed enfatica
|
207 |
-
come farebbe una guida museale femminile.
|
208 |
"""
|
209 |
|
210 |
messages = [
|
@@ -249,13 +246,12 @@ async def generate_response(request: QueryRequest):
|
|
249 |
if validate_sparql_query(sparql_query, RDF_FILE):
|
250 |
logger.info("La query SPARQL è valida. Inizio esecuzione della query.")
|
251 |
try:
|
252 |
-
# Esegui la query su RDF
|
253 |
g = Graph()
|
254 |
g.parse(RDF_FILE, format="xml")
|
255 |
results = g.query(sparql_query)
|
256 |
logger.info(f"Query SPARQL eseguita con successo. Numero di risultati: {len(results)}")
|
257 |
|
258 |
-
# Interpreta i risultati in una risposta naturale
|
259 |
interpreted_response = await interpret_sparql_results(results)
|
260 |
logger.info(f"Risposta naturale interpretata: {interpreted_response}")
|
261 |
return {"type": "NATURAL", "response": interpreted_response}
|
@@ -285,4 +281,4 @@ async def generate_response(request: QueryRequest):
|
|
285 |
|
286 |
@app.get("/")
|
287 |
async def root():
|
288 |
-
return {"message": "Server attivo e pronto a generare risposte!"}
|
|
|
45 |
g = Graph()
|
46 |
g.parse(RDF_FILE, format="xml")
|
47 |
|
|
|
48 |
classes = set()
|
49 |
properties = set()
|
50 |
for s, p, o in g.triples((None, None, None)):
|
|
|
51 |
if "Class" in str(o):
|
52 |
classes.add(s)
|
|
|
53 |
if "Property" in str(o):
|
54 |
properties.add(s)
|
55 |
|
|
|
85 |
return False
|
86 |
|
87 |
####################################
|
88 |
+
# Prompt di Sistema (Rafforzato)
|
89 |
####################################
|
90 |
def create_system_message(rdf_context: str) -> str:
|
91 |
"""
|
92 |
Crea il messaggio di sistema per il modello di linguaggio naturale.
|
93 |
+
Abbiamo rafforzato le istruzioni per gestire i literal con @it.
|
94 |
"""
|
95 |
return f"""
|
96 |
Sei un'assistente esperta nella generazione di query SPARQL basate su un'ontologia RDF,
|
97 |
+
nell'interpretazione dei risultati delle query SPARQL in risposte naturali,
|
98 |
+
e nel fare chatting minimale con i visitatori in diverse lingue (italiano, francese, inglese).
|
99 |
|
100 |
In base alla domanda dell'utente, devi decidere se:
|
101 |
+
1) generare una query SPARQL
|
102 |
+
2) fornire una risposta naturale basata su una query SPARQL
|
103 |
+
3) rispondere con una chat minimale.
|
104 |
+
|
105 |
+
ATTENZIONE IMPORTANTE:
|
106 |
+
- L'ontologia è su: http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#
|
107 |
+
- Alcuni literal (es. 'nomeOpera') hanno il tag di lingua '@it' (es. 'Amore e Psiche'@it).
|
108 |
+
- Se vuoi confrontare una stringa come 'Amore e Psiche', DEVI usare:
|
109 |
+
- base:nomeOpera 'Amore e Psiche'@it
|
110 |
+
OPPURE
|
111 |
+
- un FILTER(STR(?label) = 'Amore e Psiche')
|
112 |
+
per ignorare il tag di lingua.
|
113 |
+
- Se manca '@it', potresti non trovare risultati.
|
114 |
|
115 |
Regole TASSATIVE:
|
116 |
+
1. Se la domanda richiede una query SPARQL, restituisci SOLO la query SPARQL in testo semplice.
|
117 |
+
2. Se la domanda richiede interpretazione di risultati, dai una risposta naturale che spieghi quei risultati.
|
118 |
+
3. Se la domanda è una chat minimale, rispondi con una breve chat amichevole nella lingua dell'utente.
|
119 |
4. DEVI usare ESCLUSIVAMENTE questo prefisso di base (e NON modificarlo in nessun modo):
|
120 |
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
121 |
5. NON generare alcun altro prefisso o URI inventato.
|
122 |
+
6. Se non riesci a rispondere con una query SPARQL, interpretare i risultati o fare chat,
|
123 |
+
scrivi: "Non posso generare una query SPARQL, interpretare i risultati o fare una risposta di chat per questa richiesta."
|
|
|
124 |
|
125 |
Esempi:
|
126 |
- Domanda: "Quali sono le statue esposte del periodo medievale?"
|
127 |
+
Risposta SPARQL:
|
128 |
+
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
129 |
+
SELECT ?statua WHERE {{
|
130 |
+
?statua a base:Statua ;
|
131 |
+
base:periodoStoricoOpera "Medioevo"@it .
|
132 |
+
}}
|
|
|
133 |
|
134 |
- Domanda: "Ciao!"
|
135 |
+
Risposta (chat):
|
136 |
+
Ciao! Benvenuto al nostro museo. Come posso aiutarti oggi?
|
137 |
+
|
138 |
+
- Domanda: "Da chi è stato scolpito Amore e Psiche?"
|
139 |
+
(Se devi confrontare 'Amore e Psiche' con tag @it)
|
140 |
+
Risposta SPARQL:
|
141 |
+
PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
|
142 |
+
SELECT ?autore WHERE {{
|
143 |
+
?opera a base:Statua ;
|
144 |
+
base:nomeOpera "Amore e Psiche"@it ;
|
145 |
+
base:autoreOpera ?autore .
|
146 |
+
}}
|
147 |
|
148 |
+
Ecco un riassunto dell'ontologia su cui devi lavorare:
|
149 |
+
{rdf_context}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
RISPONDI ESCLUSIVAMENTE CON IL FORMATO SPECIFICATO.
|
152 |
"""
|
|
|
170 |
)
|
171 |
raw_text = response["choices"][0]["message"]["content"]
|
172 |
logger.debug(f"Risposta del modello ricevuta: {raw_text}")
|
173 |
+
# Rimuoviamo eventuali newline per forzare una singola riga
|
174 |
return raw_text.replace("\n", " ").strip()
|
175 |
except Exception as e:
|
176 |
logger.error(f"Errore durante la chiamata al modello: {e}")
|
|
|
195 |
])
|
196 |
logger.debug(f"Risultati SPARQL:\n{results_str}")
|
197 |
|
198 |
+
# Prompt per interpretare i risultati come una guida museale femminile
|
199 |
interpret_prompt = f"""
|
200 |
Mi hai fornito i seguenti risultati di una query SPARQL:
|
201 |
{results_str}
|
202 |
|
203 |
Per favore, interpreta questi risultati e fornisci una risposta naturale ed enfatica
|
204 |
+
come farebbe una guida museale femminile (in italiano).
|
205 |
"""
|
206 |
|
207 |
messages = [
|
|
|
246 |
if validate_sparql_query(sparql_query, RDF_FILE):
|
247 |
logger.info("La query SPARQL è valida. Inizio esecuzione della query.")
|
248 |
try:
|
|
|
249 |
g = Graph()
|
250 |
g.parse(RDF_FILE, format="xml")
|
251 |
results = g.query(sparql_query)
|
252 |
logger.info(f"Query SPARQL eseguita con successo. Numero di risultati: {len(results)}")
|
253 |
|
254 |
+
# Interpreta i risultati in una risposta naturale
|
255 |
interpreted_response = await interpret_sparql_results(results)
|
256 |
logger.info(f"Risposta naturale interpretata: {interpreted_response}")
|
257 |
return {"type": "NATURAL", "response": interpreted_response}
|
|
|
281 |
|
282 |
@app.get("/")
|
283 |
async def root():
|
284 |
+
return {"message": "Server attivo e pronto a generare risposte!"}
|