KPatelis's picture
Update README.md
4b24546 verified
|
Raw
History Blame Contribute Delete
7.97 kB

A newer version of the Gradio SDK is available: 6.22.0

Upgrade
metadata
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.

Python LangGraph HuggingFace Supabase

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

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

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:

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:

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.