File size: 6,808 Bytes
2705160
23060b1
62ad9da
 
 
2705160
 
 
 
d123508
23060b1
d123508
2705160
 
23060b1
 
d6b82a1
23060b1
6c511d6
d6b82a1
e7e1e90
 
23060b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6c511d6
 
 
 
 
 
e7e1e90
 
 
23060b1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6b82a1
e7e1e90
d6b82a1
 
 
 
 
e7e1e90
 
d6b82a1
e7e1e90
 
 
 
 
d6b82a1
e7e1e90
 
 
6c511d6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6b82a1
 
 
e7e1e90
6c511d6
 
 
 
 
3075f91
 
23060b1
 
 
 
 
 
 
 
 
 
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
---
title: GAIA 问答 Agent 评测
emoji: 🕵🏻‍♂️
colorFrom: indigo
colorTo: indigo
sdk: gradio
sdk_version: 5.25.2
app_file: app.py
pinned: false
hf_oauth: true
# 可选配置。默认有效期为 8 小时/480 分钟,最长为 30 天/43200 分钟。
hf_oauth_expiration_minutes: 480
---

这是 Hugging Face Agents Course Final Assignment 的基础 Space,用于运行并提交 GAIA 风格问题的 Agent 作答结果。

当前版本已经改成 LangGraph 类型工作流 Agent:

- `app.py` 会通过课程评测接口拉取问题并提交答案。
- `agent.py` 中的 `GaiaAgent` 会先让 LLM 判断问题类型,再由 LangGraph 路由到对应工具节点。
- `tools/executor.py``tools/tool_specs.py` 负责注册、描述并执行工具。
- `tools/` 目录包含规则题、附件下载、Python 执行、Excel 计算、结构化网页、网页检索和体育数据工具。
- 登录 Hugging Face 后,界面会使用当前 HF 用户名提交答案。
- 提交时会携带当前 Space 的代码仓库链接,便于评测系统记录实现来源。

Space 配置参考:https://huggingface.co/docs/hub/spaces-config-reference

## 本地 GAIA 测试设计

本地测试不要直接等同于官方评分。课程评分接口的 `/questions` 可以返回问题列表,但不会返回标准答案;带附件的问题还需要额外处理文件。因此,本地测试应该拆成两层:

1.  流程测试:验证 Agent 能稳定读取问题、处理附件路径、调用工具、生成答案、记录日志,并输出符合提交接口要求的 JSON。
2.  正确率测试:使用你自己维护的本地 gold 数据,或公开/可访问的 GAIA 数据子集,对 Agent 的答案做离线比对。

建议的本地目录结构:

```text
.
├── app.py
├── agent.py
├── gaia_local_eval.py
├── tools/
│   ├── direct_rules.py
│   ├── attachment_loader.py
│   ├── code_runner.py
│   ├── spreadsheet_solver.py
│   ├── structured_web_tools.py
│   ├── sports_solver.py
│   ├── tool_specs.py
│   └── executor.py
├── data/
│   ├── questions.json
│   ├── gold_local.jsonl
│   └── attachments/
│       └── <task_id>/
│           └── <file_name>
└── runs/
    └── <timestamp>.jsonl
```

建议的执行流程:

1.  缓存题目:从 `https://agents-course-unit4-scoring.hf.space/questions` 拉取当前题目,保存为 `data/questions.json`,避免频繁请求接口导致限流或不稳定。
2.  准备附件:如果题目有 `file_name`,优先尝试用裸 `task_id` 请求 `/files/{task_id}`;如果接口不可用,就把附件手动放到 `data/attachments/<task_id>/` 下。
3.  抽离 Agent:把真实作答逻辑放入 `agent.py`,提供统一入口,例如 `answer(question: str, file_path: str | None = None) -> str`4.  编写本地 runner:`gaia_local_eval.py` 只负责读取 `questions.json`、定位附件、调用 Agent、保存每题的答案、耗时、错误、工具轨迹和置信度。
5.  编写答案规整器:对数字、货币、日期、大小写、逗号分隔列表、空格和标点做标准化,避免因为格式差异误判。
6.  维护 gold 文件:`gold_local.jsonl` 每行包含 `task_id``expected_answer``match_type` 和备注。没有标准答案的问题只做流程测试,不纳入正确率统计。
7.  分层运行:先跑 1 到 3 道 smoke test,再跑全部本地题;确认稳定后再通过 Space 按官方流程提交。

当前代码采用 LangGraph 三段式工作流:

1.  `classify`:LLM 只判断问题类型,例如 `direct_text``python_code``spreadsheet``wikipedia``sports``web_url``web_search``attachment_text``audio_media``video_media``vision_image``unknown`2.  类型节点:LangGraph 根据问题类型调用对应工具节点,例如 `direct_answer_tool``python_tool``spreadsheet_tool``wikipedia_tool``sports_tool``web_read_tool``web_search_tool`3.  `finalize`:LLM 只把工具结果格式化为题目要求的最终答案;如果 LLM 调用失败,则使用工具候选答案兜底。

分类输出格式:

```json
{"question_type":"wikipedia","confidence":"high","reason":"Wikipedia structured table question","query":"1928 Summer Olympics athletes"}
```

最终答案格式:

```json
{"answer":"CUB","confidence":"high"}
```

当前仍采用 40% 优先策略:为了先冲过最低分,不处理音频和视频题,只集中处理文本、网页、Python、Excel、体育统计和少量确定性规则题。

当前优先覆盖的题型:

- 反向句子题。
- 非交换表题。
- 植物学蔬菜分类题。
- Python 附件最终输出题。
- Excel 食品销售合计题。
- Mercedes Sosa Wikipedia 专辑计数题。
- Wikipedia Featured Article 恐龙提名人题。
- 1928 Summer Olympics 最少运动员 IOC 代码题。
- 1977 Yankees walks leader at-bats 题。

本地回归测试:

```bash
python3 gaia_local_eval.py
```

注意:现在本地回归会优先调用 LLM 做题型分类,并在最后调用 LLM 做答案格式化,因此需要 `HF_TOKEN`,并会消耗少量 Hugging Face Inference Providers 额度。这个 token 必须具备 `Make calls to Inference Providers` 权限,否则 LLM 请求会返回 403。分类失败或格式化失败时,工作流会进入兜底逻辑,尽量使用已有工具候选答案。`MAX_AGENT_STEPS` 可用于限制兜底阶段最多尝试的工具数。

默认不启用 `response_format={"type":"json_object"}`,因为 HF Router 的部分 provider 对这个参数支持不稳定,可能返回空 `message.content`。如果你确认当前模型/provider 支持 JSON mode,可以设置 `HF_PLANNER_USE_RESPONSE_FORMAT=1` 再启用。

如果本地没有安装依赖,先执行:

```bash
python3 -m pip install -r requirements.txt
```

如果以后要追求更高分,真实 Agent 至少应该补齐这些工具能力:

- 网页检索和网页阅读,用于维基、论文、新闻、体育数据等开放网络问题。
- Python 执行沙箱,用于数学、表格、代码题和可复现计算。
- 文件解析能力,包括图片、音频、Excel、CSV、Python 文件和普通文本。
- 音频转写能力,用于 `.mp3` 附件。
- 视频处理能力,用于 YouTube 问题,可结合字幕、抽帧和视觉模型。
- 棋类分析能力,用于棋盘图像和最优走法题。
- 答案格式控制能力,严格输出题目要求的最终答案,不输出推理过程。

本地 runner 的目标不是替代官方评分,而是在提交前暴露三类问题:Agent 崩溃、工具链缺失、答案格式错误。最终分数仍以官方 `/submit` 返回结果为准。