AI Agent per il benchmark GAIA

Link Progetto

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)

Level 2 - Task intermedi (10-15 passi):

Domanda: "The attached Excel file contains the sales of menu items 
for a local fast-food chain. What were the total sales that the chain 
made from food (not including drinks)?"

Risposta: 89706.00Code language: CSS (css)

Level 3 - Task complessi (15+ passi):

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 finale
    return "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:

CategoriaCategoriaCategoria
🎵 AudioStrawberry pie recipe, homework instructions2
🎥 VideoYouTube bird counting, TV show quotes2
📊 DataRestaurant sales Excel, Python code output2
🔍 Web ResearchWikipedia searches, scientific papers8
🧮 Logic/MathChess moves, commutative operations3
🖼️ ImageChess position analysis1
🧩 PuzzlesReversed text, botanical classification2

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:

CategoriaCategoriaCategoria
🌐 Web & Searchsearch, extract_text_from_urlInfo real-time dal web
🎥 Media Analysisanalyze_youtube_video, transcribe_audioContenuti video/audio
📊 Data Processingpython_repl, analyze_spreadsheet_dataCalcoli complessi
📁 File Handlinganalyze_file, download_gaia_fileMulti-format support
🖼️ Visionanalyze_image, describe_imageAnalisi immagini
🔗 GAIA Integrationfetch_gaia_task, list_gaia_tasksAutomazione 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 temporaneo
            try:
                os.remove(audio_file)
            except:
                pass
            return result

        return "Errore: Impossibile ottenere contenuto audio dal video YouTube"

    except Exception as 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 richiede
        if '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 Exception as 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 RATE
        if i < len(questions):
            print("⏱️ Waiting 5 seconds to avoid rate limit...")
            await asyncio.sleep(5)

        # 3. Verifica formato risposta
        if 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 risposte
    print(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:

  1. Comprendere profondamente GAIA e i suoi requisiti specifici
  2. Sfruttare il pattern ReAct per orchestrazione intelligente multi-step
  3. Implementare tools specializzati per ogni categoria di problema Level 1
  4. Ottimizzare continuamente usando LangSmith tracing e debugging
  5. Automatizzare l'intero pipeline per testing rapido e iterazione
  6. 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.

Related Projects

Novembre 11, 2025
Nextcloud Self-Hosted: Il Salto da Setup Manuale a Infrastructure as Code

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, […]

Aprile 12, 2025
AI Travel Agent with AWS

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 […]

veronicaschembri
Copyright © Veronica Schembri

Privacy Policy
Cookie Policy
💬