tojonatolotra's picture
Update agent.py
ed5e747 verified
Raw
History Blame Contribute Delete
4.45 kB
"""
agent.py - GAIA Agent (Phase 2)
Core agent for solving GAIA Level 1 benchmark questions using smolagents + Qwen2.5-72B.
"""
import os
from dotenv import load_dotenv
load_dotenv() # Load .env locally; no effect in HF Space production (env vars take priority)
from smolagents import CodeAgent, OpenAIModel, DuckDuckGoSearchTool
# ---------------------------------------------------------------------------
# System prompt - tuned for GAIA Exact Match evaluation
# ---------------------------------------------------------------------------
SYSTEM_PROMPT = """You are an expert assistant solving questions from the GAIA benchmark.
STRICT RULES:
1. Reply ONLY with the final answer value - nothing else.
2. No introduction, no explanation, no trailing punctuation unless it is part of the answer.
3. No surrounding quotes unless the question explicitly asks for a quoted string.
4. If the answer is a number, return only the number (e.g. 42).
5. If the answer is a list, separate items with commas (e.g. apple, banana, cherry).
6. If the answer is a proper noun, use the exact correct spelling.
7. If the question is reversed, encoded, or obfuscated, write Python code to decode it first, and then follow the decoded instruction to find the final answer.
Format examples:
- Question: "What is the capital of France?" -> Paris
- Question: "How much is 15 + 27?" -> 42
- Question: "List these fruits alphabetically: banana, apricot, cherry" -> apricot, banana, cherry
- Question: "What is the chemical symbol for gold?" -> Au
"""
class GAIAAgent:
"""Agent for solving GAIA Level 1 benchmark questions.
Uses smolagents CodeAgent backed by Qwen/Qwen2.5-72B-Instruct:novita via the
Hugging Face OpenAI-compatible Router API.
"""
def __init__(self):
token = os.environ.get("HF_TOKEN") or os.environ.get("HUGGINGFACEHUB_API_TOKEN")
if not token:
raise ValueError(
"Hugging Face token not found (checked HF_TOKEN and HUGGINGFACEHUB_API_TOKEN). "
"Check your .env file or your HF Space secrets."
)
print("Initializing model Qwen/Qwen2.5-72B-Instruct:novita via HF Router...")
self.model = OpenAIModel(
model_id="Qwen/Qwen2.5-72B-Instruct:novita",
api_base="https://router.huggingface.co/v1",
api_key=token,
)
# Tools: DuckDuckGo for web search + built-in Python executor
self.agent = CodeAgent(
tools=[DuckDuckGoSearchTool()],
model=self.model,
add_base_tools=True, # enables python_interpreter and visit_webpage
max_steps=20,
verbosity_level=1,
)
print("GAIAAgent ready.")
def __call__(self, question: str) -> str:
"""Solve a GAIA question and return a short, precise answer.
Args:
question: The GAIA question text.
Returns:
Final answer as a short string.
"""
# Build the prompt with strict format rules
formatted_question = (
f"{SYSTEM_PROMPT}\n\n"
f"Question: {question}\n\n"
"Final answer (short and precise):"
)
try:
result = self.agent.run(formatted_question)
answer = str(result).strip()
# Post-processing: strip common spurious prefixes
for prefix in [
"FINAL ANSWER:",
"Final answer:",
"Answer:",
"The answer is",
"The answer is:",
]:
if answer.startswith(prefix):
answer = answer[len(prefix):].strip()
# Strip surrounding quotes if present
if len(answer) >= 2 and answer[0] in ('"', "'") and answer[-1] == answer[0]:
answer = answer[1:-1].strip()
# Ensure comma-separated lists have spaces after commas
if "," in answer:
answer = ", ".join([item.strip() for item in answer.split(",")])
# Strip trailing period if present (unless it is an abbreviation like U.S. or decimal)
if answer.endswith(".") and not answer.endswith("..") and not (len(answer) > 2 and answer[-2].isupper()):
answer = answer[:-1].strip()
return answer
except Exception as e:
print(f" [error] Failed to process question: {e}")
return ""