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

Maggio 6, 2025
Interview Preparation Assistant with CrewAI

Introduzione al Progetto L'AI Interview Preparation Assistant è un'applicazione che utilizza agenti AI per aiutare gli utenti a prepararsi per colloqui di lavoro. Il progetto combina un'interfaccia utente Streamlit con il framework CrewAI per creare un'esperienza completa di preparazione ai colloqui, dalla ricerca sull'azienda alla simulazione di interviste con feedback in tempo reale. Questo progetto […]

Marzo 18, 2025
Averna Spazio Open

• Sviluppo del sito web di Averna Spazio Open utilizzando WordPress, con Oxygen Builder per un design personalizzato e Advanced Custom Fields (ACF) per la gestione dinamica del contenuto. • Creato un sistema di invio di idee degli utenti, che venivano pubblicate sul sito, con una funzione di voto per selezionare l’idea migliore annualmente. • […]

veronicaschembri
Copyright © Veronica Schembri

Privacy Policy
Cookie Policy
💬