Spaces:
Sleeping
Sleeping
File size: 7,965 Bytes
4b24546 bdc5edd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | ---
title: Template Final Assignment
emoji: ๐ต๐ปโโ๏ธ
colorFrom: indigo
colorTo: indigo
sdk: gradio
sdk_version: 6.14.0
app_file: app.py
pinned: false
hf_oauth: true
hf_oauth_expiration_minutes: 480
---
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
# ๐ GAIA Benchmark Agent
**An autonomous, multi-modal agent that tackles the GAIA reasoning benchmark.**




> [!NOTE]
> Developed as part of the **Hugging Face Agents Course (Unit 4: GAIA)**.
## ๐ Overview
GAIA tasks require multi-step reasoning, tool use, and the ability to process diverse file types (documents, spreadsheets, audio, images, code). This agent uses a **LangGraph** state machine to plan, retrieve few-shot context, call tools, and produce a strictly-formatted answer.
The solver model is **`Qwen/Qwen3-32B`** via Hugging Face Inference Providers; the formatter (separate node) reuses the same model bound to a single `emit_final_answer` tool to enforce the strict GAIA output contract. A Supabase + BM25 hybrid retriever surfaces similar past tasks as few-shot exemplars.
## ๐ Key Features
- **๐ง Plan-Execute-Observe-Refine loop** driven by LangGraph.
- **๐ช Two-stage output**: a solver node reasons freely, then a dedicated formatter node returns the GAIA-compliant answer via a Pydantic-shaped tool call โ eliminating regex parsing of the LLM's free text.
- **๐ Multi-modal file processing**:
- **Documents**: PDF, Word (`.docx`), PowerPoint (`.pptx`), Text
- **Data**: Excel (`.xlsx`, multi-sheet), CSV, JSON-LD, PDB (Protein Data Bank)
- **Media**: Audio transcription (`openai/whisper-large-v3` via HF), image analysis (`Qwen/Qwen3-VL-32B-Instruct`)
- **Code**: Python source files (read & execute)
- **Archives**: ZIP extraction + inspection
- **๐ Hybrid RAG**: Vector search (Supabase RPC over `Alibaba-NLP/gte-modernbert-base`) **+** BM25 over a local 165-question corpus, fused with Reciprocal Rank Fusion, then reranked with a ModernBERT cross-encoder.
- **๐ Web tooling**: DuckDuckGo, Tavily, Wikipedia, ArXiv, full-page extraction (Trafilatura), YouTube transcripts.
- **๐ ๏ธ Modular tool layout**: tools are organised by domain in `gaia/tools/` (basic, web, files, media, dispatcher) so adding a new capability is a single-file change.
## ๐๏ธ Architecture
```mermaid
graph TD
START --> FileDL["File Downloader<br/>(fetches /files/{task_id})"]
FileDL --> Retriever["Retriever<br/>(Vector + BM25 + RRF)"]
Retriever --> Reranker["Reranker<br/>(ModernBERT cross-encoder)"]
Reranker --> Processor["Solver<br/>(Qwen3-32B + tools)"]
Processor -->|tool call| Tools["Tool Node"]
Tools --> Processor
Processor -->|done| Formatter["Formatter<br/>(emit_final_answer tool)"]
Formatter --> END
```
| Node | Role |
| :--- | :--- |
| **`file_downloader_node`** | If the question has an associated file, download from `{api.base_url}/files/{task_id}` and cache on disk under `data/task_files/{task_id}/`. |
| **`retriever_node`** | Hybrid search: Supabase vector RPC + local BM25 over `data/metadata.jsonl`, fused with RRF. Returns up to 20 candidate task IDs. |
| **`reranker_node`** | `Alibaba-NLP/gte-reranker-modernbert-base` re-scores candidates and injects the top-K as few-shot examples (Question + Final Answer + Solution Steps). |
| **`processor_node`** | Qwen3-32B with all tools bound. Reasons, calls tools, loops until satisfied. |
| **`tools`** | LangGraph `ToolNode` executing the chosen tool, then returning control to the processor. |
| **`formatter_node`** | A second Qwen3-32B call bound to a single `emit_final_answer(answer: str)` tool โ produces the strictly-formatted value the GAIA scorer compares against. |
## ๐ ๏ธ Stack
| Category | Libraries | Purpose |
| :--- | :--- | :--- |
| **Orchestration** | `langgraph`, `langchain`, `langchain-huggingface` | State graph, tool binding, structured output. |
| **LLM / VLM / ASR** | `huggingface_hub` Inference API | `Qwen/Qwen3-32B`, `Qwen/Qwen3-VL-32B-Instruct`, `openai/whisper-large-v3`. |
| **Embeddings & Vector Store** | `sentence-transformers`, `supabase` | Semantic search via `Alibaba-NLP/gte-modernbert-base`. |
| **Keyword search** | `bm25s` | Local BM25 index over the 165-question GAIA corpus. |
| **Documents** | `pypdf`, `python-docx`, `python-pptx`, `openpyxl` | Office formats. |
| **Data** | `polars`, `biopython` | Tabular and PDB structural analysis. |
| **Media** | `pillow`, `librosa`, `soundfile` | Image + audio I/O. |
| **Web** | `ddgs`, `tavily-python`, `wikipedia`, `arxiv`, `trafilatura`, `youtube-transcript-api` | Search, page extraction, captions. |
| **UI** | `gradio` | Evaluation runner (HF Space entry point). |
## ๐ป Installation & Setup
```bash
git clone <repo_url>
cd gaia
uv sync # or: pip install -r requirements.txt
cp .env.example .env # populate the keys below
```
Required environment variables (place in `.env` or set as HF Space Secrets):
| Variable | Required? | Purpose |
| :--- | :--- | :--- |
| `HF_INFERENCE_KEY` | yes | Hugging Face token โ must have **"Make calls to Inference Providers"** permission. |
| `SUPABASE_URL` | yes (if `retrievers.enable_vector_search: true`) | Supabase project URL. |
| `SUPABASE_SERVICE_KEY` | yes (same) | Supabase `service_role` key. |
| `TAVILY_API_KEY` | optional | Only needed when the agent picks `tavily_web_search`. |
## ๐ฎ Usage
Start the Gradio interface:
```bash
python app.py
```
The UI requires a Hugging Face login. Click **"Run Evaluation & Submit All Answers"** to fetch the GAIA question set, run the agent on each, and submit to the scoring API.
To (re)populate the Supabase vector store from the local corpus:
```bash
python scripts/create_vector_database.py
```
## ๐ Project Structure
```
.
โโโ app.py # HF Space entry point (Gradio)
โโโ config.yaml # All tunable parameters
โโโ pyproject.toml / requirements.txt # Dependencies (uv + pip parity)
โโโ gaia/ # Application package
โ โโโ agent.py # LangGraph nodes, graph, formatter
โ โโโ states.py # AgentState TypedDict
โ โโโ utils.py # config / prompt loaders, BM25, RRF, answer + youtube helpers
โ โโโ prompts/
โ โ โโโ prompt.yaml # Solver system prompt
โ โ โโโ vlm_prompt.yaml # analyze_image system prompt
โ โโโ tools/
โ โโโ __init__.py # Aggregates tools_list
โ โโโ basic.py # calculator, python_eval
โ โโโ web.py # ddg / tavily / wiki / arxiv / fetch_webpage / youtube_transcript
โ โโโ files.py # PDF, DOCX, PPTX, TXT, CSV, XLSX, JSON-LD, PDB, Python, ZIP
โ โโโ media.py # analyze_image (VLM), transcribe_audio (ASR), shared HF client
โ โโโ dispatcher.py # read_file extension router
โโโ scripts/
โ โโโ create_vector_database.py # One-shot embedder for Supabase
โโโ notebooks/ # Exploratory work
โโโ data/
โ โโโ metadata.jsonl # Local GAIA corpus (165 examples)
โโโ models/ # HF model cache (gitignored)
```
All tunable knobs โ model IDs, retrieval depth, thinking mode, recursion limit โ live in `config.yaml`; no code change required to swap models or tweak retrieval.
|