s1144662's picture
Update app.py
54756e4 verified
raw
history blame
5.22 kB
import os
import gradio as gr
import requests
import pandas as pd
from typing import Optional
from smolagents import CodeAgent, OpenAIServerModel, tool
# --- 搜尋工具 (防封鎖增強版) ---
try:
from duckduckgo_search import DDGS
except ImportError:
import os
os.system('pip install duckduckgo-search>=6.0.0')
from duckduckgo_search import DDGS
@tool
def web_search(query: str) -> str:
"""
Performs a web search using DuckDuckGo with anti-blocking measures.
Args:
query: The search query string.
"""
print(f"🕵️ [Debug] Searching: {query}")
try:
# 關鍵修正:使用 backend='html' 模式,這比 API 模式更不容易被封鎖
# 限制 max_results=3 以節省讀取時間
with DDGS() as ddgs:
results = ddgs.text(query, max_results=3, backend="html")
if not results:
return "No search results found. Try simpler keywords."
# 格式化結果給模型看
formatted = []
for r in results:
title = r.get('title', 'No Title')
body = r.get('body', 'No Description')
formatted.append(f"Title: {title}\nSnippet: {body}")
return "\n---\n".join(formatted)
except Exception as e:
print(f"❌ Search Error: {e}")
# 回傳錯誤訊息而不是讓程式崩潰,讓模型有機會猜測
return f"Search failed. Please ignore search and answer based on your knowledge."
# -----------------------------------------------------------
DEFAULT_API_URL = "https://agents-course-unit4-scoring.hf.space"
class GroqAgent:
def __init__(self):
self.api_key = os.getenv("GROQ_API_KEY")
if not self.api_key:
self.agent = None
return
# 🏆 使用 Groq 目前最強的 Llama 3.3 70B 模型
model = OpenAIServerModel(
model_id="llama-3.3-70b-versatile",
api_base="https://api.groq.com/openai/v1",
api_key=self.api_key
)
# Agent 設定
self.agent = CodeAgent(
tools=[web_search],
model=model,
max_steps=3,
verbosity_level=1
)
def __call__(self, question: str) -> str:
if self.agent is None:
return "Error: GROQ_API_KEY not configured."
try:
# 提示詞優化:明確告訴它如果搜尋失敗該怎麼做
prompt = f"""
You are a helpful assistant. Answer the question concisely.
1. Use the 'web_search' tool to find specific facts (names, dates, numbers).
2. If the search returns "No results" or fails, DO NOT retry endlessly. Just give your best guess immediately.
3. For questions about images/audio you cannot see, search for the description text provided in the question.
Question: {question}
"""
return str(self.agent.run(prompt))
except Exception as e:
return f"Error processing request: {str(e)[:150]}"
def run_and_submit_all(profile: Optional[gr.OAuthProfile] = None):
if profile is None:
return "⚠️ Please login first!", None
username = profile.username
space_id = os.getenv("SPACE_ID", "s1144662")
api_url = DEFAULT_API_URL
try:
agent_wrapper = GroqAgent()
if agent_wrapper.agent is None:
return "❌ Error: GROQ_API_KEY not found!", None
except Exception as e:
return f"❌ Init failed: {str(e)}", None
try:
print("Fetching questions...")
response = requests.get(f"{api_url}/questions", timeout=30)
questions = response.json()
except Exception as e:
return f"❌ Fetch failed: {str(e)}", None
answers = []
logs = []
total = len(questions)
for idx, item in enumerate(questions, 1):
q = item.get("question")
tid = item.get("task_id")
print(f"🚀 [{idx}/{total}] Task: {tid}")
# 執行 Agent
ans = agent_wrapper(q)
answers.append({"task_id": tid, "submitted_answer": ans})
logs.append({"Task": tid, "Answer": str(ans)[:100]})
try:
print("Submitting...")
res = requests.post(f"{api_url}/submit", json={
"username": username,
"agent_code": f"https://huggingface.co/spaces/{space_id}/tree/main",
"answers": answers
}, timeout=60)
data = res.json()
score = data.get('score', 0)
msg = f"🎉 Final Score: {score}%"
return msg, pd.DataFrame(logs)
except Exception as e:
return f"Submit error: {str(e)}", pd.DataFrame(logs)
with gr.Blocks(title="Final Agent (Llama 3.3 + Anti-Block)") as demo:
gr.Markdown("# 🚀 Final Agent (Llama 3.3 70B)")
with gr.Row():
gr.LoginButton()
btn = gr.Button("Run Evaluation", variant="primary")
out = gr.Textbox(label="Status")
tab = gr.DataFrame(label="Logs")
btn.click(run_and_submit_all, outputs=[out, tab])
if __name__ == "__main__":
demo.launch()