AshenClock commited on
Commit
69d6e40
·
verified ·
1 Parent(s): 8b7bd74

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -31
app.py CHANGED
@@ -8,11 +8,11 @@ from typing import Optional
8
 
9
  # Configurazione logging
10
  logging.basicConfig(
11
- level=logging.DEBUG, # Livello di log aumentato per più dettagli
12
  format="%(asctime)s - %(levelname)s - %(message)s",
13
  handlers=[
14
- logging.FileHandler("app.log"),
15
- logging.StreamHandler()
16
  ]
17
  )
18
  logger = logging.getLogger(__name__)
@@ -31,7 +31,7 @@ RDF_FILE = "Ontologia.rdf"
31
  ####################################
32
  # Caricamento RDF (riassunto)
33
  ####################################
34
- def load_rdf_summary():
35
  """
36
  Carica un riassunto dell'ontologia dal file RDF.
37
  Estrae le classi e le proprietà presenti nell'ontologia.
@@ -40,21 +40,25 @@ def load_rdf_summary():
40
  if not os.path.exists(RDF_FILE):
41
  logger.error("Nessun file RDF trovato.")
42
  return "Nessun file RDF trovato."
 
43
  try:
44
  g = Graph()
45
  g.parse(RDF_FILE, format="xml")
46
-
47
  # Estrazione semplificata di classi e proprietà
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
 
56
  class_summary = "\n".join([f"- Classe: {cls}" for cls in classes])
57
  prop_summary = "\n".join([f"- Proprietà: {prop}" for prop in properties])
 
58
  summary = f"Classi:\n{class_summary}\n\nProprietà:\n{prop_summary}"
59
  logger.info("Caricamento RDF completato con successo.")
60
  return summary
@@ -89,10 +93,14 @@ def validate_sparql_query(query: str, rdf_file_path: str) -> bool:
89
  def create_system_message(rdf_context: str) -> str:
90
  """
91
  Crea il messaggio di sistema per il modello di linguaggio naturale.
 
92
  """
93
  return f"""
94
- Sei un'assistente esperta nella generazione di query SPARQL basate su un'ontologia RDF, nell'interpretazione dei risultati delle query SPARQL in risposte naturali, e nel fare chatting minimale con i visitatori in diverse lingue (ad esempio, italiano, francese, inglese). In base alla domanda dell'utente, devi decidere se:
95
-
 
 
 
96
  1. Generare una query SPARQL per interrogare la base di conoscenza.
97
  2. Fornire una risposta naturale basata sui risultati di una query SPARQL.
98
  3. Rispondere con una risposta di chat minimale nella stessa lingua dell'utente.
@@ -105,39 +113,43 @@ Regole TASSATIVE:
105
  2. Se la domanda richiede l'interpretazione di risultati SPARQL, restituisci una risposta naturale basata sui risultati.
106
  3. Se la domanda è una chat minimale, restituisci una risposta di chat nella stessa lingua dell'utente.
107
  4. DEVI usare ESCLUSIVAMENTE questo prefisso di base (e NON modificarlo in nessun modo):
108
- PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/2024/11/untitled-ontology-39/>
109
  5. NON generare alcun altro prefisso o URI inventato.
110
- 6. Se non puoi rispondere con una query SPARQL valida, interpretare i risultati o fare chatting, scrivi:
 
111
  "Non posso generare una query SPARQL, interpretare i risultati o fare una risposta di chat per questa richiesta."
112
 
113
  Esempi:
114
  - Domanda: "Quali sono le statue esposte del periodo medievale?"
115
  Risposta:
116
- PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/2024/11/untitled-ontology-39/> SELECT ?statua WHERE {{ ?statua a base:Statua . ?statua base:Periodo_Storico "Medioevo" . }}
117
-
 
118
  - Domanda: "La query ha restituito 5 statue. Puoi descriverle?"
119
  Risposta:
120
  Ecco le 5 statue medievali trovate: Statua1, Statua2, Statua3, Statua4, Statua5.
121
-
122
  - Domanda: "Ciao!"
123
  Risposta:
124
  Ciao! Benvenuto al nostro museo. Come posso aiutarti oggi?
125
-
126
  - Domanda: "Bonjour! Comment ça va?"
127
  Risposta:
128
  Bonjour! Bienvenue dans notre musée. Comment puis-je vous aider aujourd'hui?
129
-
130
  - Domanda: "Qual è la tua opinione sull'arte moderna?"
131
  Risposta:
132
  L'arte moderna è un'espressione affascinante e varia che riflette le dinamiche sociali e culturali contemporanee.
133
-
134
  - Domanda: "How does this installation work?"
135
  Risposta:
136
- This interactive installation allows you to explore various artworks through digital interactions. Simply approach and follow the on-screen instructions.
137
-
 
138
  - Domanda: "Come funziona questa installazione?"
139
  Risposta:
140
- Questa installazione interattiva ti permette di esplorare diverse opere d'arte attraverso interazioni digitali. Basta avvicinarti e seguire le istruzioni sullo schermo.
 
141
 
142
  RISPONDI ESCLUSIVAMENTE CON IL FORMATO SPECIFICATO.
143
  """
@@ -178,24 +190,27 @@ async def interpret_sparql_results(results):
178
  if not results:
179
  logger.info("Nessun risultato trovato per la query SPARQL.")
180
  return "Mi dispiace, non sono riuscita a trovare le informazioni che stavi cercando."
181
-
182
  # Converti i risultati in una stringa leggibile
183
- results_str = "\n".join([", ".join([f"{k}: {v}" for k, v in row.asdict().items()]) for row in results])
 
 
 
184
  logger.debug(f"Risultati SPARQL:\n{results_str}")
185
-
186
  # Crea un prompt per il modello per interpretare i risultati
187
  interpret_prompt = f"""
188
  Mi hai fornito i seguenti risultati di una query SPARQL:
189
  {results_str}
190
 
191
- Per favore, interpreta questi risultati e fornisci una risposta naturale ed enfatica come farebbe una guida museale femminile.
 
192
  """
193
-
194
  messages = [
195
  {"role": "system", "content": interpret_prompt},
196
  {"role": "user", "content": ""}
197
  ]
198
-
199
  logger.info("Invio dei risultati SPARQL al modello per l'interpretazione.")
200
  natural_response = await call_model(messages, temperature=0.7, max_tokens=2048)
201
  logger.info(f"Risposta interpretata ricevuta dal modello: {natural_response}")
@@ -223,40 +238,48 @@ async def generate_response(request: QueryRequest):
223
  {"role": "user", "content": user_msg}
224
  ]
225
  response_text = await call_model(messages, request.temperature, request.max_tokens)
226
-
227
  logger.info(f"Risposta generata dal modello: {response_text}")
228
 
229
  # 2) Determinazione se la risposta è una query SPARQL
230
  if response_text.startswith("PREFIX base:"):
231
  sparql_query = response_text
232
  logger.info("La risposta è stata identificata come una query SPARQL.")
 
233
  # Validazione della query SPARQL
234
  if validate_sparql_query(sparql_query, RDF_FILE):
235
  logger.info("La query SPARQL è valida. Inizio esecuzione della query.")
236
- # Esegui la query su GraphDB
237
  try:
 
238
  g = Graph()
239
  g.parse(RDF_FILE, format="xml")
240
  results = g.query(sparql_query)
241
  logger.info(f"Query SPARQL eseguita con successo. Numero di risultati: {len(results)}")
 
242
  # Interpreta i risultati in una risposta naturale tramite il modello
243
  interpreted_response = await interpret_sparql_results(results)
244
  logger.info(f"Risposta naturale interpretata: {interpreted_response}")
245
  return {"type": "NATURAL", "response": interpreted_response}
 
246
  except Exception as e:
247
  logger.error(f"Errore durante l'esecuzione della query SPARQL: {e}")
248
- return {"type": "ERROR", "response": "Mi dispiace, c'è stato un errore nell'esecuzione della tua richiesta."}
 
 
 
249
  else:
250
  logger.warning("La query SPARQL generata non è valida.")
251
- return {"type": "ERROR", "response": "La query SPARQL generata non è valida. Per favore, riprova con una domanda diversa."}
252
-
 
 
 
253
  elif "Non posso generare una query SPARQL" in response_text:
254
  # Risposta di errore dal modello
255
  logger.warning("Il modello ha risposto con un messaggio di errore.")
256
  return {"type": "ERROR", "response": response_text}
257
-
258
  else:
259
- # Presumiamo che sia una risposta naturale o una chat
260
  logger.info("La risposta è stata identificata come una risposta naturale o di chat.")
261
  return {"type": "NATURAL", "response": response_text}
262
 
 
8
 
9
  # Configurazione logging
10
  logging.basicConfig(
11
+ level=logging.DEBUG, # Livello di log aumentato per maggiori dettagli
12
  format="%(asctime)s - %(levelname)s - %(message)s",
13
  handlers=[
14
+ logging.FileHandler("app.log"), # Log su file
15
+ logging.StreamHandler() # Log su console
16
  ]
17
  )
18
  logger = logging.getLogger(__name__)
 
31
  ####################################
32
  # Caricamento RDF (riassunto)
33
  ####################################
34
+ def load_rdf_summary() -> str:
35
  """
36
  Carica un riassunto dell'ontologia dal file RDF.
37
  Estrae le classi e le proprietà presenti nell'ontologia.
 
40
  if not os.path.exists(RDF_FILE):
41
  logger.error("Nessun file RDF trovato.")
42
  return "Nessun file RDF trovato."
43
+
44
  try:
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
 
59
  class_summary = "\n".join([f"- Classe: {cls}" for cls in classes])
60
  prop_summary = "\n".join([f"- Proprietà: {prop}" for prop in properties])
61
+
62
  summary = f"Classi:\n{class_summary}\n\nProprietà:\n{prop_summary}"
63
  logger.info("Caricamento RDF completato con successo.")
64
  return summary
 
93
  def create_system_message(rdf_context: str) -> str:
94
  """
95
  Crea il messaggio di sistema per il modello di linguaggio naturale.
96
+ NOTA: Cambiato il prefisso per riflettere la tua ontologia 'progettoMuseo#'.
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, e
101
+ nel fare chatting minimale con i visitatori in diverse lingue (ad esempio, italiano, francese, inglese).
102
+
103
+ In base alla domanda dell'utente, devi decidere se:
104
  1. Generare una query SPARQL per interrogare la base di conoscenza.
105
  2. Fornire una risposta naturale basata sui risultati di una query SPARQL.
106
  3. Rispondere con una risposta di chat minimale nella stessa lingua dell'utente.
 
113
  2. Se la domanda richiede l'interpretazione di risultati SPARQL, restituisci una risposta naturale basata sui risultati.
114
  3. Se la domanda è una chat minimale, restituisci una risposta di chat nella stessa lingua dell'utente.
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 puoi rispondere con una query SPARQL valida, interpretare i risultati
119
+ o fare chatting, scrivi:
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
+ PREFIX base: <http://www.semanticweb.org/lucreziamosca/ontologies/progettoMuseo#>
126
+ SELECT ?statua WHERE {{ ?statua a base:Statua . ?statua base:periodoStoricoOpera "Medioevo" . }}
127
+
128
  - Domanda: "La query ha restituito 5 statue. Puoi descriverle?"
129
  Risposta:
130
  Ecco le 5 statue medievali trovate: Statua1, Statua2, Statua3, Statua4, Statua5.
131
+
132
  - Domanda: "Ciao!"
133
  Risposta:
134
  Ciao! Benvenuto al nostro museo. Come posso aiutarti oggi?
135
+
136
  - Domanda: "Bonjour! Comment ça va?"
137
  Risposta:
138
  Bonjour! Bienvenue dans notre musée. Comment puis-je vous aider aujourd'hui?
139
+
140
  - Domanda: "Qual è la tua opinione sull'arte moderna?"
141
  Risposta:
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
  """
 
190
  if not results:
191
  logger.info("Nessun risultato trovato per la query SPARQL.")
192
  return "Mi dispiace, non sono riuscita a trovare le informazioni che stavi cercando."
193
+
194
  # Converti i risultati in una stringa leggibile
195
+ results_str = "\n".join([
196
+ ", ".join([f"{k}: {v}" for k, v in row.asdict().items()])
197
+ for row in results
198
+ ])
199
  logger.debug(f"Risultati SPARQL:\n{results_str}")
200
+
201
  # Crea un prompt per il modello per interpretare i risultati
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 = [
211
  {"role": "system", "content": interpret_prompt},
212
  {"role": "user", "content": ""}
213
  ]
 
214
  logger.info("Invio dei risultati SPARQL al modello per l'interpretazione.")
215
  natural_response = await call_model(messages, temperature=0.7, max_tokens=2048)
216
  logger.info(f"Risposta interpretata ricevuta dal modello: {natural_response}")
 
238
  {"role": "user", "content": user_msg}
239
  ]
240
  response_text = await call_model(messages, request.temperature, request.max_tokens)
 
241
  logger.info(f"Risposta generata dal modello: {response_text}")
242
 
243
  # 2) Determinazione se la risposta è una query SPARQL
244
  if response_text.startswith("PREFIX base:"):
245
  sparql_query = response_text
246
  logger.info("La risposta è stata identificata come una query SPARQL.")
247
+
248
  # Validazione della query SPARQL
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 tramite il modello
259
  interpreted_response = await interpret_sparql_results(results)
260
  logger.info(f"Risposta naturale interpretata: {interpreted_response}")
261
  return {"type": "NATURAL", "response": interpreted_response}
262
+
263
  except Exception as e:
264
  logger.error(f"Errore durante l'esecuzione della query SPARQL: {e}")
265
+ return {
266
+ "type": "ERROR",
267
+ "response": "Mi dispiace, c'è stato un errore nell'esecuzione della tua richiesta."
268
+ }
269
  else:
270
  logger.warning("La query SPARQL generata non è valida.")
271
+ return {
272
+ "type": "ERROR",
273
+ "response": "La query SPARQL generata non è valida. Per favore, riprova con una domanda diversa."
274
+ }
275
+
276
  elif "Non posso generare una query SPARQL" in response_text:
277
  # Risposta di errore dal modello
278
  logger.warning("Il modello ha risposto con un messaggio di errore.")
279
  return {"type": "ERROR", "response": response_text}
280
+
281
  else:
282
+ # Presumiamo che sia una risposta naturale o di chat
283
  logger.info("La risposta è stata identificata come una risposta naturale o di chat.")
284
  return {"type": "NATURAL", "response": response_text}
285