Quando GPT-4, uno dei modelli più avanzati al mondo, riesce a risolvere solo il 15% delle domande di un benchmark mentre un umano medio raggiunge il 92%, capisci che c'è qualcosa di speciale in quel benchmark.
Quel benchmark si chiama GAIA, e rappresenta una delle sfide più interessanti nell'AI moderna.
🎯 Cos'è GAIA e perché è rivoluzionario
GAIA (General AI Assistants) è un benchmark che ribalta completamente l'approccio tradizionale alla valutazione AI. Presentato nel paper "GAIA: A Benchmark for General AI Assistants", che Invece di proporre task sempre più difficili per gli umani, GAIA presenta domande che sono:
Semplici per umani (92% di successo) ma difficili per AI (GPT-4: ~15%)
Multi-modali: richiedono comprensione di testo, immagini, audio e video
Tool-dependent: necessitano di web search, analisi file e esecuzione codice
Oggettivamente misurabili: con risposte fattuali inequivocabili
Esempi dal Benchmark
Level 1 - Task di base (5-10 passi):
Domanda: "What was the actual enrollment count of the clinical trial
on H. pylori in acne vulgaris patients from Jan-May 2018 as listed
on the NIH website?"
Risposta: 90Code language:PHP(php)
Domanda: "In NASA's Astronomy Picture of the Day on 2006 January 21,
two astronauts are visible... which one spent the least time in space?"
Risposta: White; 5876Code language:PHP(php)
🎓 Il Contesto: Hugging Face AI Agents Course
Questo progetto nasce come finale del corso "AI Agents" di Hugging Face (Unit 4). L'obiettivo era chiaro: costruire un agent capace di affrontare GAIA e raggiungere performance superiori ai modelli base.
Ma da dove iniziare quando devi battere GPT-4?
🔍 La Scoperta: LangGraph ReAct Template
La svolta è arrivata scoprendo il LangGraph ReAct Agent Template. Questo template implementa il pattern ReAct:
Reason: L'agent analizza il problema e pianifica
Act: Esegue azioni usando tools specifici
Observe: Processa i risultati ottenuti
Repeat: Continua iterativamente fino alla soluzione
Anatomia del Template
Dal codice in src/react_agent/graph.py:
# Il cuore del sistema: StateGraph con gestione stato
builder = StateGraph(State, input=InputState, config_schema=Configuration)
# I due nodi principali del ciclo ReAct
builder.add_node(call_model) # 🧠 Reasoning
builder.add_node("tools", ToolNode(TOOLS)) # 🛠️ Action# Il punto di partenza
builder.add_edge("__start__", "call_model")
# La logica decisionale
def route_model_output(state: State) -> Literal["__end__", "tools"]:
last_message = state.messages[-1]
if not last_message.tool_calls:
return"__end__"# 🏁 Risposta finalereturn"tools"# 🔄 Continua con tools# Connessioni condizionali
builder.add_conditional_edges("call_model", route_model_output)
builder.add_edge("tools", "call_model") # Torna sempre al reasoningCode language:PHP(php)
Il Ciclo in Azione
Esempio Concreto: Excel Analysis
Domanda: "Calcola vendite totali cibo (no bevande) da Excel allegato"
Ciclo 1: 🧠 "Devo scaricare e analizzare il file"
🛠️ download_gaia_file() → file scaricato
Ciclo 2: 🧠 "Ora devo leggere l'Excel"
🛠️ read_spreadsheet() → struttura dati rilevata
Ciclo 3: 🧠 "Devo calcolare totale escludendo bevande"
🛠️ python_repl("food_columns = ['Burgers', 'Hot Dogs', 'Salads', 'Fries', 'Ice Cream']
total_sales = df[food_columns].sum().sum()")
Ciclo 4: 🧠 "Ho il risultato: $89,706.00"
✅ FINAL ANSWER: 89706.00Code language:PHP(php)
🎯 La Nostra Strategia: Focus su Level 1
Perché Ci Siamo Concentrati su Level 1
Analizzando il nostro dataset questions.json, tutte le 20 domande sono classificate come Level 1. Questa è stata una scelta strategica:
Vantaggi dell'Approccio Level 1-First:
✅ Foundation solida prima di task complessi
✅ Debugging semplificato con trace brevi
✅ Feedback loop veloce per ottimizzazioni
✅ ROI migliore: molte domande Level 1 nel benchmark reale
Tipologie Level 1 nel Nostro Dataset
Dal file questions.json:
Categoria
Categoria
Categoria
🎵 Audio
Strawberry pie recipe, homework instructions
2
🎥 Video
YouTube bird counting, TV show quotes
2
📊 Data
Restaurant sales Excel, Python code output
2
🔍 Web Research
Wikipedia searches, scientific papers
8
🧮 Logic/Math
Chess moves, commutative operations
3
🖼️ Image
Chess position analysis
1
🧩 Puzzles
Reversed text, botanical classification
2
Esempi Concreti:
// Audio Analysis
{
"task_id": "99c9cc74-fdc8-46c6-8f8d-3ce2d3bfeea3",
"question": "Could you please listen to the recipe and list all ingredients? I've attached Strawberry pie.mp3",
"file_name": "99c9cc74-fdc8-46c6-8f8d-3ce2d3bfeea3.mp3"
}
// YouTube Analysis
{
"task_id": "a1e91b78-d3d8-4675-bb8d-62741b4b68a6",
"question": "In the video https://www.youtube.com/watch?v=L1vXCYZAYYM, what is the highest number of bird species on camera simultaneously?"
}
// Excel Processing
{
"task_id": "7bd855d8-463d-4ed5-93ca-5fe35145f733",
"question": "What were the total sales from food (not drinks)? Express in USD with two decimal places.",
"file_name": "7bd855d8-463d-4ed5-93ca-5fe35145f733.xlsx"
}
Code language:JSON / JSON with Comments(json)
🛠️ L'Arsenal: 15+ Tools Specializzati
Il segreto del successo è stato implementare tools specifici per ogni tipo di challenge GAIA:
Categoria
Categoria
Categoria
🌐 Web & Search
search, extract_text_from_url
Info real-time dal web
🎥 Media Analysis
analyze_youtube_video, transcribe_audio
Contenuti video/audio
📊 Data Processing
python_repl, analyze_spreadsheet_data
Calcoli complessi
📁 File Handling
analyze_file, download_gaia_file
Multi-format support
🖼️ Vision
analyze_image, describe_image
Analisi immagini
🔗 GAIA Integration
fetch_gaia_task, list_gaia_tasks
Automazione benchmark
Tool Spotlight: analyze_youtube_video
async def analyze_youtube_video(video_url: str, query: Optional[str] = None) -> str:
"""Analizza video YouTube con approccio ibrido ottimizzato"""try:
print(f"🎥 Analizzando video YouTube: {video_url}")
# STEP 1: Prova prima i sottotitoli (gratuito)
transcript = await get_youtube_transcript(video_url)
if not transcript.startswith("Errore"):
print("✅ Sottotitoli trovati - usando trascrizione gratuita")
if query:
return f"Trascrizione YouTube:\n{transcript}\n\nAnalisi per: '{query}'"return f"Trascrizione YouTube completa:\n{transcript}"# STEP 2: Solo se fallisce, usa Whisper (a pagamento)print("⚠️ Sottotitoli non disponibili, scaricando audio per Whisper...")
audio_file = await download_youtube_audio(video_url)
if audio_file and not audio_file.startswith("Errore"):
result = await transcribe_audio(audio_file, query)
# Cleanup file temporaneotry:
os.remove(audio_file)
except:
pass
return result
return"Errore: Impossibile ottenere contenuto audio dal video YouTube"
except Exceptionas e:
return f"Errore nell'analisi del video YouTube: {str(e)}"Code language:PHP(php)
Perché questo tool è geniale per GAIA:
✅ Approccio ibrido: Prima sottotitoli gratuiti, poi Whisper
✅ Gestione errori: Fallback automatico robusto
✅ Ottimizzazione costi: Whisper solo quando necessario
✅ Cleanup automatico: Rimuove file temporanei
Tool Spotlight: python_repl
async def python_repl(code: str) -> str:
"""Esegue codice Python e restituisce il risultato."""try:
# Crea un ambiente isolato per l'esecuzione
local_vars = {}
global_vars = {
'__builtins__': __builtins__,
'pd': None, # pandas sarà importato se necessario
}
# Importa pandas se il codice lo richiedeif'pd.' in code or'pandas' in code:
import pandas as pd
global_vars['pd'] = pd
# Esegui il codice
exec(code, global_vars, local_vars)
# Cerca variabili di output comuni con priorità
output_vars = ['final_answer', 'result', 'answer', 'output', 'total']
for var_name in output_vars:
if var_name in local_vars:
return str(local_vars[var_name])
# Se non trova variabili specifiche, cerca l'ultima espressione valutata
lines = code.strip().split('\n')
if lines:
last_line = lines[-1].strip()
if last_line and not last_line.startswith('#'):
try:
last_result = eval(last_line, global_vars, local_vars)
if last_result is not None:
return str(last_result)
except:
pass
# Se tutto fallisce, mostra le variabili disponibili
available_vars = [k for k in local_vars.keys() if not k.startswith('_')]
if available_vars:
return f"Codice eseguito. Variabili disponibili: {available_vars}"else:
return"Codice eseguito con successo"
except Exceptionas e:
return f"Errore nell'esecuzione: {str(e)}"Code language:PHP(php)
Il segreto del successo:
🎯 Priorità intelligente: Cerca final_answer prima di result
🔒 Ambiente isolato: Sicurezza per l'esecuzione di codice
📦 Auto-import: Pandas disponibile automaticamente
🧠 Context awareness: Capisce cosa cerca l'utente
🎛️ System Prompt Ottimizzato per GAIA
SYSTEM_PROMPT = """You are a general AI assistant specialized in solving GAIA benchmark tasks.
=== GAIA RESPONSE FORMAT ===
CRITICAL: Always end your response with: FINAL ANSWER: [YOUR FINAL ANSWER]
Your FINAL ANSWER should be:
- A number (don't use commas or units like $ or % unless specified otherwise)
- As few words as possible (don't use articles or abbreviations unless specified)
- A comma-separated list of numbers/strings (apply above rules for each element)
- For strings: write digits in plain text unless specified otherwise
- For cities: use full names without abbreviations
=== AUTONOMY REQUIREMENTS ===
CRITICAL: Work independently and autonomously:
- NEVER ask the user for guidance, clarification, or additional information
- NEVER say "Could you provide more guidance" or similar phrases
- Always provide a FINAL ANSWER based on your best analysis
- Make reasonable connections and inferences from available information
=== GAIA REASONING STRATEGY ===
GAIA tasks require systematic, multi-step problem solving:
1. ANALYZE THE QUESTION:
- Extract ALL key details (specific sections, dates, authors, requirements)
- Identify what type of answer is expected (name, number, list, etc.)
- Note any specific constraints or formatting requirements
- If question contains URLs (YouTube, websites), identify them immediately
2. RESEARCH SYSTEMATICALLY:
- For YouTube URLs: Use analyze_youtube_video tool to get transcription
- For websites: Use extract_text_from_url to get full content
- For search queries: Use search tool with specific terms from question
- If no results, broaden search gradually with alternative terms
3. EXTRACT AND ANALYZE CONTENT:
- When you get transcriptions or text content, READ CAREFULLY
- Look for specific details requested in the question
- Count items, identify names, extract numbers as requested
- For counting questions: List each item found, then provide total count
- Look for synonyms and related terms (e.g., "horse doctor" = "equine veterinarian")
4. VERIFY YOUR ANSWER:
- Double-check the answer matches what was asked
- Ensure correct format (no articles, abbreviations, etc.)
- For numbers: provide just the number without units unless specified
- Confirm you're answering the right question
=== TOOL USAGE ===
- For YouTube URLs in questions: Use analyze_youtube_video(url, query)
- For web URLs: Use extract_text_from_url for promising URLs
- For audio files: Use transcribe_audio for .mp3, .wav, .m4a files
- For calculations: Use python_repl for data analysis
- For files: Download with download_gaia_file, then use analyze_file
- Be thorough and systematic in your research
System time: {system_time}"""Code language:PHP(php)
Configurazione Modelli
Da src/react_agent/configuration.py:
@dataclass(kw_only=True)
class Configuration:
"""The configuration for the agent."""
system_prompt: str = field(
default=prompts.SYSTEM_PROMPT,
metadata={
"description": "The system prompt to use for the agent's interactions."
},
)
model: Annotated[str, {"__template_metadata__": {"kind": "llm"}}] = field(
default="openai/gpt-4o",
metadata={
"description": "The name of the language model to use. "
"Should be in the form: provider/model-name."
},
)
max_search_results: int = field(
default=10,
metadata={
"description": "The maximum number of search results to return."
},
)
🧪 Testing e Debug con LangGraph Studio
LangGraph Studio in Azione
Il debugging è stato rivoluzionario grazie a LangGraph Studio:
🔍 State Inspection
Visualizzazione completa dello stato interno
Trace di ogni singolo step del reasoning
Analisi dei tool calls e response
📊 Performance Monitoring
Durata di ogni step
Costi per chiamata API
Success/failure patterns
🎯 Debug Precision
Problema identificato: Agent si fermava al primo risultato Google Insight da LangSmith: 60% dei fallimenti per informazioni incomplete Soluzione: Implementato multiple search queries con validation
Esempio di Trace Completo
🚀 Orchestrazione Benchmark con GAIA Runner
Automazione Completa
Da src/react_agent/gaia_runner.py:
async def run_all_gaia_tasks(username: str = "your_username", max_questions: int = None) -> Dict[str, Any]:
"""Risolve automaticamente tutte (o alcune) task GAIA"""print("🚀 Starting GAIA benchmark run...")
# 1. Fetch tutte le domande
questions = await fetch_all_questions()
if max_questions:
questions = questions[:max_questions]
answers = []
for i, question in enumerate(questions, 1):
print(f"\n🔍 Question {i}/{len(questions)}: {question['task_id']}")
# 2. Risolvi ogni domanda
response = await solve_gaia_question(question)
# ✅ DELAY PER LIMITI DI RATEif i < len(questions):
print("⏱️ Waiting 5 seconds to avoid rate limit...")
await asyncio.sleep(5)
# 3. Verifica formato rispostaif is_valid_answer(response):
final_answer = extract_final_answer(response)
print(f"✅ Answer: {final_answer}")
else:
print(f"⚠️ No FINAL ANSWER found, using full response")
final_answer = response.strip()
answers.append({
"task_id": question["task_id"],
"submitted_answer": final_answer
})
# 4. Submit tutte le risposteprint(f"\n📤 Submitting {len(answers)} answers...")
result = await submit_answers(answers, username)
return resultCode language:PHP(php)
Gestione Intelligente dei File
async def solve_gaia_question(question: Dict[str, Any]) -> str:
"""Risolve una singola domanda GAIA usando il graph esistente"""# Costruisci il messaggio completo per l'agente
question_text = question["question"]
# Se c'è un file, aggiungi le istruzioni specifiche
has_file = question.get('file_name') and question['file_name'].strip()
if has_file:
question_text += f"\n\n=== ATTACHED FILE INFORMATION ===\n"
question_text += f"File: {question['file_name']}\n"
question_text += f"Task ID: {question['task_id']}\n"
question_text += f"INSTRUCTIONS:\n"
question_text += f"1. First use download_gaia_file('{question['task_id']}') to download this file\n"
question_text += f"2. Then analyze the downloaded file using the appropriate tool\n"
question_text += f"3. Answer the question based on the file content\n"
result = await graph.ainvoke({
"messages": [("user", question_text)]
})
return result["messages"][-1].contentCode language:PHP(php)
📊 I Risultati: Performance su Level 1
✅ Completed GAIA benchmark!
🎉 Results: {'username': 'pandagan', 'score': 60.0, 'correct_count': 11, 'total_attempted': 20, 'message': 'Score calculated successfully: 11/20 total questions answered correctly (20 valid tasks attempted). Score did not improve previous record, leaderboard not updated.', 'timestamp': '2025-06-17T17:50:38.705403+00:00'}Code language:JavaScript(javascript)
Qui puoi vedere la Leaderboard, e cercare il mio nome utente "pandagan" per nuovi sviluppi 🚀
🎯 Specializzazione vs Generalizzazione
Tools specifici per ogni tipo di task Level 1
Prompting ottimizzato per GAIA format
Gestione errori e retry logic robusti
🔄 Orchestrazione Intelligente
Pattern ReAct con cicli multipli
State management robusto tra tool calls
Tool chaining automatico per task complessi
📈 Ottimizzazioni Specifiche
Rate limiting (5 secondi) per stabilità API
File cleanup automatico per gestione memoria
Format validation per compliance GAIA
🎓 Lezioni Apprese
1. L'Orchestrazione Batte la Potenza Bruta
Un modello medio (GPT-4o) con tools ben orchestrati supera modelli top senza augmentation.
2. Il Pattern ReAct Funziona Davvero
L'iterazione Reason→Act→Observe è naturale per problemi complessi multi-step come GAIA.
3. LangGraph come Framework di Produzione
State management robusto con StateGraph
Error handling automatico nel routing
Debugging capabilities avanzate con Studio
Scalabilità enterprise-ready
4. GAIA Insegna l'Autonomia
Il benchmark forza l'agent a lavorare completamente autonomo - skill cruciale per applicazioni reali.
5. Level 1 è una Strategia Vincente
Padroneggiare i task base prima di affrontare la complessità massima porta a risultati migliori.
🔧 Architettura Finale
🎯 Conclusioni
Passare dal 9.1% di GPT-4 vanilla al ~55% del nostro agent su Level 1 non è stato solo questione di aggiungere tools, ma di:
Comprendere profondamente GAIA e i suoi requisiti specifici
Sfruttare il pattern ReAct per orchestrazione intelligente multi-step
Implementare tools specializzati per ogni categoria di problema Level 1
Ottimizzare continuamente usando LangSmith tracing e debugging
Automatizzare l'intero pipeline per testing rapido e iterazione
Focalizzarsi su Level 1 per costruire una foundation solida
Il Futuro
Prossimi Passi:
Estensione a Level 2 e Level 3 tasks
Implementazione di memory persistence
Tool optimization basata su usage patterns
Multi-agent collaboration per task complessi
Il risultato finale: Un sistema che non solo performa significativamente meglio di GPT-4 su GAIA Level 1, ma rappresenta un template solido e production-ready per costruire AI agents specializzati.
Il futuro dell'AI non è solo nei modelli più grandi, ma nell'orchestrazione intelligente di capabilities specifiche attraverso frameworks robusti come LangGraph.
🔍 Vuoi vedere altri progetti simili? Visita la sezione AI Projects per scoprire i miei altri esperimenti con AI agents, machine learning e tecnologie emergenti.
📚 Interessato ad approfondire l'argomento? Sul mio blog trovi tutorial dettagliati, analisi tecniche e riflessioni sul mondo dell'intelligenza artificiale.
Questo progetto è stato sviluppato per il corso "AI Agents" di Hugging Face.
Nextcloud self-hosted è la mia soluzione per sostituire Google Calendar, Contacts e Drive con un'alternativa open-source che controllo completamente. Deploy su Oracle Cloud Infrastructure usando il free tier (4 OCPU ARM, 24GB RAM - gratis per sempre). Il problema: La prima versione funzionava, ma era fragile. Setup manuale con 50+ comandi, 1GB RAM che crashava, […]
Ogni tanto capita un progetto che ti cambia la prospettiva. Per me, questo è stato uno di quelli. Durante il corso Build AI Agents with AWS di Zero To Mastery, ho avuto la sensazione di aver sbloccato un nuovo livello: Mi ha fatto scoprire un mondo completamente nuovo: quello dell’orchestrazione multi-agente in cloud, dove ogni […]