内容
# 模型指标 API
从 [artificialanalysis.ai](https://artificialanalysis.ai/leaderboards/models) 抓取模型指标,并通过 REST API 和 MCP 服务器提供服务。
## 快速开始
```bash
task build
bin/scrape-aa serve
```
```bash
# 所有模型,按智力指数排序(默认)
curl http://localhost:8080/api/v1/models | jq '.models[0:5] | .[].name'
# 按编码分数排序的Anthropic模型
curl "http://localhost:8080/api/v1/models?creator=anthropic&sort_by=coding_index" | jq '.models[].name'
# GPQA上得分高于0.5的模型,按价格排序
curl "http://localhost:8080/api/v1/models?bench=gpqa&min=0.5&sort_by=price_input&order=asc" \
| jq '.models[] | {name, gpqa, price1mInputTokens}'
# 单个模型
curl http://localhost:8080/api/v1/models/claude-sonnet-4-5 \
| jq '{name, intelligenceIndex, price1mInputTokens}'
```
## 概念
**抓取** — 从 artificialanalysis.ai 进行一次获取,带有时间戳并存储在 SQLite 中。服务器在启动时抓取,然后在每个 `--interval` 时间间隔内抓取。每次抓取都会保留,因此可以查询历史数据。
**Slug** — 每个模型的稳定 URL 安全标识符(例如 `claude-sonnet-4-5`)。Slugs 在抓取过程中保持一致,因此可以随时间跟踪模型。
## 命令
### `scrape` — 一次抓取到 JSON
```bash
bin/scrape-aa scrape [--out models.json]
```
获取所有模型,写入 JSON 文件,并打印智力指数前 5 名。
### `serve` — 带有 REST + MCP API 的守护进程
```bash
bin/scrape-aa serve [--addr :8080] [--db ./data.db] [--interval 1h]
```
启动后立即抓取,然后按照间隔进行抓取。在 SQLite 中存储历史记录。
## REST API
基准:`http://localhost:8080/api/v1`
### 端点
| 方法 | 路径 | 描述 |
| ------ | ---- | ----------- |
| `GET` | `/scrapes` | 列出所有抓取记录(最新的在前) |
| `GET` | `/scrapes/latest` | 最新抓取记录的元数据 |
| `POST` | `/scrapes` | 触发立即重新抓取 |
| `GET` | `/models` | 最新抓取记录中的模型 |
| `GET` | `/models/{slug}` | 按 slug 获取单个模型(最新抓取记录) |
### `/models` 查询参数
所有参数都是可选的,可以自由组合。
| 参数 | 类型 | 默认值 | 描述 |
| --------- | ---- | ------- | ----------- |
| `scrape_id` | integer | — | 返回来自特定抓取记录的模型 |
| `as_of` | RFC3339 字符串 | — | 返回在指定时间之前或等于指定时间的最近抓取记录中的模型 |
| `creator` | 字符串 | — | 按创建者名称过滤(不区分大小写) |
| `bench` | 字符串 | — | 按基准分数过滤(参见 [基准字段](#基准字段)) |
| `min` | float | — | 最小基准分数(含) |
| `max` | float | — | 最大基准分数(含) |
| `sort_by` | 字符串 | `intelligence_index` | 排序字段:`intelligence_index`、`coding_index`、`price_input`、`price_output`、`name` |
| `order` | `asc` \| `desc` | `desc` | 排序方向 |
**示例:**
```bash
# 来自特定历史抓取记录的模型
curl "http://localhost:8080/api/v1/models?scrape_id=3"
# 特定时间点的模型
curl "http://localhost:8080/api/v1/models?as_of=2025-01-01T00:00:00Z"
# 组合过滤器和排序
curl "http://localhost:8080/api/v1/models?creator=openai&bench=hle&min=0.2&sort_by=price_input&order=asc"
# 历史模型快照
curl "http://localhost:8080/api/v1/models/gpt-4o?scrape_id=1"
```
### 基准字段
将以下字段名称之一作为 `bench` 查询参数传递。
| 字段 | 基准 |
| ----- | --------- |
| `intelligenceIndex` | AA 智力指数(综合) |
| `codingIndex` | AA 编码指数(综合) |
| `agenticIndex` | AA 代理指数(综合) |
| `gpqa` | GPQA Diamond — 研究生级科学问题 |
| `hle` | 人类的最后考试 |
| `mmmuPro` | MMMU-Pro — 多模态理解 |
| `omniscience` | Omniscience — 事实知识和非幻觉 |
| `scicode` | SciCode — 科学编码任务 |
| `critpt` | CritPT — 临界点推理 |
| `gdpvalNormalized` | GDPVal — 长上下文对话 |
| `ifbench` | IFBench — 指令遵循 |
| `lcr` | LCR — 长上下文检索 |
| `tau2` | TAU-bench v2 — 工具使用和代理任务 |
| `apexAgents` | APEX Agents |
| `itbenchSre` | ITBench SRE — IT/站点可靠性操作 |
| `terminalbenchHard` | TerminalBench Hard — CLI 任务 |
### 响应形状
**抓取对象**(由 `/scrapes` 和 `POST /scrapes` 返回):
```json
{
"id": 4,
"scrapedAt": "2025-05-31T12:00:00Z",
"modelCount": 183
}
```
**模型响应**(由 `GET /models` 返回):
```json
{
"scrapeId": 4,
"scrapedAt": "2025-05-31T12:00:00Z",
"models": [ ...模型对象... ]
}
```
**模型对象** — 关键字段:
```json
{
"id": "claude-sonnet-4-5",
"slug": "claude-sonnet-4-5",
"name": "Claude Sonnet 4.5",
"shortName": "Sonnet 4.5",
"modelCreatorName": "Anthropic",
"modelCreatorSlug": "anthropic",
"intelligenceIndex": 76.4,
"codingIndex": 71.2,
"agenticIndex": 68.0,
"gpqa": 0.718,
"hle": 0.241,
"price1mInputTokens": 3.0,
"price1mOutputTokens": 15.0,
"cacheHitPrice": 0.3,
"contextWindowTokens": 200000,
"totalParameters": null,
"reasoningModel": false,
"isOpenWeights": false,
"deprecated": false,
"medianOutputTokensPerSecond": 98.4,
"medianTimeToFirstTokenSeconds": 0.61,
"inputModalityText": true,
"inputModalityImage": true,
"inputModalitySpeech": false,
"outputModalityText": true
}
```
可空字段在模型无该数据时为 `null`。完整的模型对象包含约 60 个其他字段,用于定价混合、token 计数分解、开放性元数据和每个领域的 Omniscience 分数。
## MCP 服务器
SSE 端点:`http://localhost:8080/mcp/sse`
使用 SSE 传输协议与任何 MCP 兼容的客户端(Claude Desktop、Continue 等)连接。
### 工具
#### `list_models`
从最新抓取记录返回模型,格式为 JSON 数组。
| 参数 | 类型 | 是否必需 | 默认值 | 描述 |
| --------- | ---- | -------- | ------- | ----------- |
| `sort_by` | 字符串 | 否 | `intelligence_index` | `intelligence_index`、`coding_index`、`price_input`、`price_output`、`name` |
| `creator` | 字符串 | 否 | — | 按创建者名称过滤(不区分大小写) |
| `bench` | 字符串 | 否 | — | 按基准字段名称过滤(参见上表) |
| `min` | number | 否 | — | 最小基准分数(含) |
| `max` | number | 否 | — | 最大基准分数(含) |
| `limit` | integer | 否 | `50` | 结果的最大数量 |
#### `get_model`
按 slug 返回单个模型。
| 参数 | 类型 | 是否必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `slug` | 字符串 | **是** | 模型 slug(例如 `claude-sonnet-4-5`) |
如果 slug 不存在,则返回 `"model not found"`。
#### `search_models`
对模型名称和创建者名称进行不区分大小写的子字符串搜索。
| 参数 | 类型 | 是否必需 | 描述 |
| --------- | ---- | -------- | ----------- |
| `query` | 字符串 | **是** | 搜索字符串 |
### 资源
| URI | 描述 |
| --- | ----------- |
| `aa://models` | 最新抓取记录的完整模型列表,格式为 JSON 数组 |
| `aa://models/{slug}` | 单个模型,格式为 JSON(例如 `aa://models/claude-sonnet-4-5`) |
## 开发
```bash
task build # 编译到 bin/scrape-aa
task test # go test -race ./...
task lint # golangci-lint + govulncheck + nilaway + go-arch-lint
task generate # sqlc generate (在模式/查询更改后)
```
需要
- [Task](https://taskfile.dev)
- [golangci-lint](https://golangci-lint.run)
- [govulncheck](https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck)
- [nilaway](https://github.com/uber-go/nilaway)
- [sqlc](https://sqlc.dev)
- [go-arch-lint](https://github.com/fe3dback/go-arch-lint)