oniwaka commited on
Commit
bad2ddc
·
verified ·
1 Parent(s): 81917a3

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +183 -8
app.py CHANGED
@@ -10,15 +10,190 @@ DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
10
 
11
  # --- Basic Agent Definition ---
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
13
- class BasicAgent:
14
- def __init__(self):
15
- print("BasicAgent initialized.")
16
- def __call__(self, question: str) -> str:
17
- print(f"Agent received question (first 50 chars): {question[:50]}...")
18
- fixed_answer = "This is a default answer."
19
- print(f"Agent returning fixed answer: {fixed_answer}")
20
- return fixed_answer
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  def run_and_submit_all( profile: gr.OAuthProfile | None):
23
  """
24
  Fetches all questions, runs the BasicAgent on them, submits all answers,
 
10
 
11
  # --- Basic Agent Definition ---
12
  # ----- THIS IS WERE YOU CAN BUILD WHAT YOU WANT ------
 
 
 
 
 
 
 
 
13
 
14
+ class GAIAAgent:
15
+ def __init__(self):
16
+ self.setup_models()
17
+ self.setup_agent()
18
+
19
+ def setup_models(self):
20
+ """Configura i modelli necessari"""
21
+ # Gemini per capacità multimodali
22
+ genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
23
+ self.gemini_model = genai.GenerativeModel('gemini-2.0-flash-exp')
24
+
25
+ # Pipeline per trascrizione audio
26
+ self.whisper_pipeline = pipeline(
27
+ "automatic-speech-recognition",
28
+ model="openai/whisper-large-v3",
29
+ device_map="auto"
30
+ )
31
+
32
+ def setup_agent(self):
33
+ """Configura l'agente con tools ottimizzati"""
34
+ self.agent = CodeAgent(
35
+ tools=[
36
+ self.analyze_image,
37
+ self.transcribe_audio,
38
+ self.extract_text_from_file,
39
+ self.web_search,
40
+ self.calculate_precise
41
+ ],
42
+ model="microsoft/DialoGPT-medium",
43
+ max_iterations=10,
44
+ verbosity=2
45
+ )
46
+
47
+ @tool
48
+ def analyze_image(self, image_path: str, question: str) -> str:
49
+ """Analizza immagini usando Gemini Vision per domande GAIA"""
50
+ try:
51
+ import PIL.Image
52
+ image = PIL.Image.open(image_path)
53
+
54
+ prompt = f"""
55
+ Analizza questa immagine per rispondere alla domanda: {question}
56
+
57
+ Fornisci una risposta precisa e dettagliata. Se la domanda richiede:
58
+ - Conteggio di oggetti: conta accuratamente
59
+ - Identificazione di testo: trascrivi esattamente
60
+ - Descrizione di elementi: sii specifico e ordinato
61
+ - Posizioni relative: usa riferimenti chiari (orario, coordinate)
62
+
63
+ Risposta:
64
+ """
65
+
66
+ response = self.gemini_model.generate_content([prompt, image])
67
+ return response.text
68
+ except Exception as e:
69
+ return f"Errore nell'analisi dell'immagine: {str(e)}"
70
+
71
+ @tool
72
+ def transcribe_audio(self, audio_path: str) -> str:
73
+ """Trascrizione audio ad alta precisione"""
74
+ try:
75
+ result = self.whisper_pipeline(audio_path)
76
+ return result["text"]
77
+ except Exception as e:
78
+ return f"Errore nella trascrizione: {str(e)}"
79
+
80
+ @tool
81
+ def extract_text_from_file(self, file_path: str) -> str:
82
+ """Estrae testo da vari formati di file"""
83
+ try:
84
+ if file_path.endswith('.txt'):
85
+ with open(file_path, 'r', encoding='utf-8') as f:
86
+ return f.read()
87
+ elif file_path.endswith('.csv'):
88
+ import pandas as pd
89
+ df = pd.read_csv(file_path)
90
+ return df.to_string()
91
+ elif file_path.endswith(('.xlsx', '.xls')):
92
+ import pandas as pd
93
+ df = pd.read_excel(file_path)
94
+ return df.to_string()
95
+ else:
96
+ return "Formato file non supportato"
97
+ except Exception as e:
98
+ return f"Errore nella lettura del file: {str(e)}"
99
+
100
+ @tool
101
+ def web_search(self, query: str) -> str:
102
+ """Ricerca web per informazioni aggiornate"""
103
+ try:
104
+ # Implementa ricerca web usando API disponibili
105
+ # Per semplicità, qui usiamo un placeholder
106
+ return f"Risultati ricerca per: {query}"
107
+ except Exception as e:
108
+ return f"Errore nella ricerca: {str(e)}"
109
+
110
+ @tool
111
+ def calculate_precise(self, expression: str) -> str:
112
+ """Calcoli matematici precisi"""
113
+ try:
114
+ # Sanitizza l'espressione per sicurezza
115
+ safe_expr = re.sub(r'[^0-9+\-*/().\s]', '', expression)
116
+ result = eval(safe_expr)
117
+ return str(result)
118
+ except Exception as e:
119
+ return f"Errore nel calcolo: {str(e)}"
120
+
121
+ def solve_question(self, question: str, file_path: Optional[str] = None) -> str:
122
+ """Risolve una domanda GAIA con approccio ottimizzato"""
123
+
124
+ # Prompt engineering ottimizzato per GAIA Level 1[3][8]
125
+ system_prompt = f"""
126
+ Sei un agente AI specializzato nel risolvere domande del benchmark GAIA Level 1.
127
+
128
+ OBIETTIVO: Fornire risposte ESATTE che corrispondano perfettamente al formato richiesto.
129
+
130
+ REGOLE CRITICHE:
131
+ 1. Leggi attentamente la domanda e identifica il formato di risposta richiesto
132
+ 2. Se c'è un file allegato, analizzalo completamente prima di rispondere
133
+ 3. Per domande numeriche: fornisci solo il numero (es. "42", non "La risposta è 42")
134
+ 4. Per liste: usa il formato esatto richiesto (virgole, punti, etc.)
135
+ 5. Per date: usa il formato specificato nella domanda
136
+ 6. NON aggiungere prefissi come "Risposta:", "Il risultato è:", etc.
137
+
138
+ STRATEGIA DI RISOLUZIONE:
139
+ 1. Analizza la domanda per identificare il tipo di task
140
+ 2. Pianifica i passaggi necessari
141
+ 3. Usa gli strumenti appropriati
142
+ 4. Verifica la risposta prima di fornirla
143
+ 5. Formatta la risposta nel modo ESATTO richiesto
144
+
145
+ DOMANDA: {question}
146
+ {f"FILE ALLEGATO: {file_path}" if file_path else ""}
147
+
148
+ Risolvi step-by-step e fornisci SOLO la risposta finale nel formato richiesto.
149
+ """
150
+
151
+ try:
152
+ # Esegui l'agente con il prompt ottimizzato
153
+ response = self.agent.run(system_prompt)
154
+
155
+ # Post-processing per garantire formato corretto
156
+ answer = self.clean_answer(response, question)
157
+
158
+ return answer
159
+
160
+ except Exception as e:
161
+ return f"Errore nella risoluzione: {str(e)}"
162
+
163
+ def clean_answer(self, raw_answer: str, question: str) -> str:
164
+ """Pulisce e formatta la risposta per EXACT MATCH"""
165
+
166
+ # Rimuovi prefissi comuni
167
+ prefixes_to_remove = [
168
+ "Final Answer:", "Risposta:", "Answer:", "Il risultato è:",
169
+ "La risposta è:", "Risposta finale:", "ANSWER:", "RISPOSTA:"
170
+ ]
171
+
172
+ cleaned = raw_answer.strip()
173
+ for prefix in prefixes_to_remove:
174
+ if cleaned.startswith(prefix):
175
+ cleaned = cleaned[len(prefix):].strip()
176
+
177
+ # Gestione formati specifici basati sulla domanda
178
+ if "comma-separated" in question.lower():
179
+ # Assicura formato lista separata da virgole
180
+ cleaned = re.sub(r'\s*,\s*', ', ', cleaned)
181
+
182
+ if "number" in question.lower() or "how many" in question.lower():
183
+ # Estrai solo numeri per domande numeriche
184
+ numbers = re.findall(r'\d+(?:\.\d+)?', cleaned)
185
+ if numbers:
186
+ cleaned = numbers[0]
187
+
188
+ if "yes" in question.lower() and "no" in question.lower():
189
+ # Domande yes/no
190
+ if "yes" in cleaned.lower():
191
+ cleaned = "Yes"
192
+ elif "no" in cleaned.lower():
193
+ cleaned = "No"
194
+
195
+ return cleaned.strip()
196
+
197
  def run_and_submit_all( profile: gr.OAuthProfile | None):
198
  """
199
  Fetches all questions, runs the BasicAgent on them, submits all answers,