AI Frontier Database:每小时更新的 AI 模型对比仪表盘
Avo-Sarkissian/AI-Frontier-Database
AI Frontier Database 是一个在浏览器端运行的交互式仪表盘,对比 Artificial Analysis 上 31 家提供商的 155 个托管语言模型,覆盖成本、速度和智能水平,数据由 GitHub Actions 机器人每小时抓取更新。
An interactive dashboard mapping the entire AI model landscape — comparing every hosted language model Artificial Analysis benchmarks — 155 of them across 31 providers today — on cost, speed, and intelligence in one place, updated hourly.
🔗 Live dashboard → https://avo-sarkissian.github.io/AI-Frontier-Database/
Hosted free on GitHub Pages. The full interactive dashboard runs entirely in your browser — the same Python chart code is executed client-side via Pyodide (WebAssembly), so there is no server. Charts paint instantly from a pre-rendered snapshot; the live filters/calculators activate after a one-time background load (a few seconds, cached thereafter).
Overview
Every week, new AI models ship from OpenAI, Google, Anthropic, Meta, and dozens of others. Each makes different tradeoffs — some excel at reasoning but cost more, some are fast but less capable, and some punch well above their price point.
AI Frontier makes those tradeoffs visible. A GitHub Actions bot scrapes live benchmark data from Artificial Analysis every hour and surfaces the full competitive landscape through 10 interactive tabs — no sign-in, no API key required.
Dashboard Tabs
| Tab | Description |
|---|---|
| Overview | Bubble scatter of every model, togglable between Price and Speed on the x-axis (y = AA Intelligence Index either way). Dotted Pareto frontier highlights best value per dollar. The nine largest providers each get a distinct colour AND marker shape — a redundant encoding that survives colour-vision deficiency; the remaining providers share a grey "Other" series. |
| Agent Stack | Pick a workflow — API Only, Hybrid (fast local), Hybrid (fast + balanced local), or Local Only — plus a provider checklist, and get a three-tier model recommendation: Fast, Balanced, and Reasoning. Hybrid/Local modes add GPU, VRAM, and quantization controls. |
| Landscape | Treemap of the AI industry: tile area = model count per provider, color intensity = average intelligence. Followed by a provider leaderboard. |
| Rankings | Top 25 models by Intelligence, Value (score/$), or Speed, with tier-separator lines marking meaningful performance gaps — plus a "Value Leaders" chart ranking the top models by intelligence-per-dollar. |
| Compare | Head-to-head radar chart across five dimensions: Intelligence, Speed, Affordability, Context Window, and Latency. Supports up to 5 models simultaneously, with a raw-value table below the chart. |
| Budget | Enter a monthly token volume and see projected API cost per model, sorted cheapest-first. |
| Table | Full sortable table of every tracked model with every available metric. |
| Run Local | Select a GPU, quantization level, and capability tags (code, reasoning, vision, audio) to see which open-weight models fit in VRAM, with estimated inference speed. |
| Image Gen | ELO-based leaderboard of image generation models, filterable by provider and style tag, from the AA Image Arena. |
| Video Gen | Arena-Elo leaderboard of video generation models with per-minute pricing, from the AA Video Arena. Text-to-video and image-to-video are separate Elo pools with separate prices, so MODE switches between them. |
Screenshots
Captured from the built site by
scripts/capture_screenshots.py, with the header stat bar hidden — those counters change hourly, and an image containing them is wrong within the hour. Regenerate after a UI change with:.venv/bin/python build_static.py && .venv/bin/python scripts/capture_screenshots.py
Data Sources
| Metric | Source | Notes |
|---|---|---|
| Intelligence | Artificial Analysis | Composite of reasoning, coding, math, and knowledge benchmarks. AA rebuilt the index onto a new evaluation suite in 2026-09 (GDPval-AA v2, 𝜏³-Banking, Terminal-Bench v2.1, SciCode, AA-Omniscience, HLE, GPQA Diamond, CritPt, IFBench, MMMU-Pro) without changing the scale — the peak is still ~53 and every absolute threshold in this app stays calibrated. It also began marking scores it estimated rather than measured, for models it has not yet run the full suite on: that is 105 of our 198 hosted models and 147 of 190 open-weight ones. The flag rides through as quality_estimated in both CSV exports and is shown per model in the detail panel; it is never used to hide a model, only to say which kind of number you are reading. |
| Coding / Agentic / Omniscience | Artificial Analysis | Sibling indices added in the same 2026-09 overhaul, carried in the data and the detail panel but not charted. Coverage is partial by design upstream — AA scores Coding for 144 of our 198 models and Agentic for 107 — and an unscored model is blank, never 0. AA-Omniscience penalises hallucination and is legitimately negative for most of the catalogue (−77 to +44 here), so it does not share an axis with the others. |
| Price | Derived from Artificial Analysis | USD per 1M tokens, cheapest available host. Our blend, not AA's: 3 parts output to 1 part input. AA publishes the opposite weighting (3 parts input to 1 part output), so a price here reads roughly 1.9× theirs. Output-weighted is the honest basis for agentic and RAG workloads, where output dominates spend; the per-token price_in / price_out are shown beside it everywhere so you can compute either. |
| Speed | Artificial Analysis | Median tokens/second from the same host as the price |
| Latency | Artificial Analysis | Median time-to-first-token (TTFT) in seconds |
| Context Window | Artificial Analysis | Maximum input length the model supports, not what a given host serves — a host may cap it lower. Unlike price and speed this is not a cheapest-host figure. |
| Image ELO | AA Image Arena | Human-preference ranking, scraped live hourly |
| Open-weight / local models | AA model leaderboard | Parameter counts, context, licence and Intelligence Index, scraped live hourly. Read from the leaderboard rather than the hosted-models API on purpose: that API is keyed on host x model, so it only knows about open-weight models someone also sells API access to — 77 of 177 were invisible, including every model nobody hosts precisely because you would run it yourself. |
| Video Elo | AA Video Arena | Human-preference ranking across two generation arenas, scraped live hourly |
| Video generation time | AA Video Arena | End-to-end median over 14 trailing days — published by AA for only a handful of endpoints, and left blank rather than estimated for the rest |
The LLM dataset currently covers 155 models across 31 providers. Counts move every hour as Artificial Analysis adds and delists models — the header stats on the live site are always authoritative, and this number was last written on a day the catalogue held 155. It has been as high as 329 (before AA pruned ~181 legacy models on 2026-07-24) and as low as 148. Four separate scrapers (data/scraper.py, data/image_scraper.py, data/local_scraper.py, data/video_scraper.py) each pull their own Artificial Analysis source on the same hourly cadence. All four read a rendered page rather than an API, so data/rsc.py holds the Next.js payload parsing they share. Artificial Analysis has retired or gated every JSON endpoint this project used: the image arena went key-gated, video never had one, the models API omitted unhosted open-weight models, and on 2026-08-20 /api/data/website/host-models/performance — the last one in use — began returning 404.
Live Data Refresh
An hourly GitHub Actions workflow (.github/workflows/refresh.yml) is the sole source of truth for the deployed site — browsers can't call the Artificial Analysis API directly (CORS), so a scheduled job does it server-side (four cron entries an hour — :08, :23, :38, :53 — plus manual workflow_dispatch):
- Runs all four scrapers, falling back to the last-known-good cache per source if a fetch fails.
- Sanity-checks row counts, per-column health, and per-column medians before proceeding — a rename that zeroes a column, or a units change that leaves the row count intact, both fail the build.
- Skips the rebuild entirely if nothing changed (git-diff change guard).
- Runs
python build_static.py --data-onlyto swap the new CSVs into the static bundle without re-vendoring Plotly. - Commits and pushes the refreshed
docs/folder asgithub-actions[bot], which GitHub Pages auto-deploys.
The live site auto-loads the latest published snapshot on open.
GitHub does not honour the schedule. Since 2026-08-26 GitHub's schedule
service has been dropping cron runs outright — no run is created, nothing
fails — and this repo fell from 21–23 scheduled runs a day to 2–8, with gaps of
up to 13 hours (community discussion #206019,
#207346; unanswered by
GitHub). Four cron entries did not help: on 2026-09-22 GitHub skipped seven
consecutive slots. When a model has just been released and the site has not
caught up, gh workflow run refresh.yml publishes it in about two minutes.
The reliable trigger is an external scheduler calling workflow_dispatch —
the only workaround other affected users report working. Setup, once:
- Create a fine-grained personal access token at https://github.com/settings/personal-access-tokens/new: repository access only this repository, repository permission Actions: Read and write (Metadata: read is added automatically), nothing else. Note the expiry — the site stops refreshing the day it lapses.
- Smoke-test it from a terminal.
HTTP 204means a run was created; it shows up in the Actions tab as aworkflow_dispatchrun within seconds.GITHUB_TOKEN=github_pat_... scripts/dispatch_refresh.sh
- Add a job at a free cron service such as cron-job.org:
every hour (or every 30 minutes — the change guard makes a run with nothing
new a 35-second no-op), method POST, URL
https://api.github.com/repos/Avo-Sarkissian/AI-Frontier-Database/actions/workflows/refresh.yml/dispatches, headersAuthorization: Bearer <token>,Accept: application/vnd.github+jsonandX-GitHub-Api-Version: 2022-11-28, body{"ref":"main"}. Run it once from the service and confirm aworkflow_dispatchrun appears.
The GitHub cron entries stay as a backstop, and the workflow's concurrency group serialises overlapping triggers.
The freshness badge reports data age, not build age. Each scraper records
whether it actually fetched, when, and how many rows (data/raw/scrape_status.json),
and the badge shows the oldest successful fetch across all four datasets —
because a dashboard is only as fresh as its stalest panel. If any dataset is
failing or older than twelve hours the badge turns amber and adds a ⚠; hover it
for a per-dataset breakdown. Staleness is recomputed in the browser, so a page
left open ages honestly even if the hourly job stops.
That badge used to read the build timestamp. On one real CI run two of three scrapers failed, only the image arena refreshed, and a five-hour-stale catalogue published under "Updated just now" — with the failure step running after the push.
Running Locally
Requires Python 3.11+.
# Clone the repo git clone https://github.com/Avo-Sarkissian/AI-Frontier-Database.git cd AI-Frontier-Database # Create and activate a virtual environment. # Use .venv, not a name containing spaces: this repo lives under a path with a # space in it, and a venv whose activate script embeds that path silently # prepends a directory that does not exist. The script still exits 0 and still # sets the (name) prompt, so you get the SYSTEM python believing you are in a # venv — which is how a build once ran under plotly 6.0 and tripled the bundle. python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate python -c "import sys; print(sys.prefix)" # must print .../AI Frontier/.venv # Install dependencies. requirements.txt is the human-edited file; # requirements.lock is what CI installs, with a sha256 for every artifact. pip install -r requirements.txt # Launch the dashboard python app.py
Open http://localhost:8050. The scrapers fetch fresh data on startup and run in the background every hour — no manual refresh needed. (They are skipped under pytest, so the suite never touches the network or the committed cache.)
Tests
.venv/bin/python -m pytest -q # 383 tests, ~30sRun them from .venv, not the system Python: four full-build tests silently
skip when the ambient plotly ships the pre-6.1 validator tree, so a green run
outside the venv is not a green run.
The suite is mostly regression tests for defects an audit found, and each one names the failure it prevents rather than the function it calls — the docstrings are the useful documentation of why the code is shaped the way it is. Broadly:
| File | Guards |
|---|---|
test_data_semantics.py |
Price basis and attribution, context-window source, upstream renames, the row-loss guards |
test_encoding_calibration.py |
Every constant that decides a bar length, bubble size, spoke radius or colour stop matches the range the data occupies |
test_filter_semantics.py, test_controls_and_drift.py |
Controls do what they are labelled to do, and both renderings agree |
test_pipeline_and_hardware.py |
Empty states, freshness, atomic publishing, the local-hardware model |
test_claims_and_injection.py |
The product's claims about itself; scraped text reaching Plotly or a spreadsheet |
test_pybundle_freshness.py |
The deployed bundle matches the repo — a fix that is not shipped fails here |
Static site (GitHub Pages)
The public site at https://avo-sarkissian.github.io/AI-Frontier-Database/ is a static, server-free build of the same dashboard, served from the docs/ folder on main.
# Regenerate the static site into docs/ (pre-rendered figures + Pyodide bundle) python build_static.py # Or, after a data-only refresh (see Live Data Refresh above): python build_static.py --data-only git add docs && git commit -m "rebuild static site" && git push # Pages auto-deploys (~1 min)
How it works: build_static.py pre-renders every chart's default state to JSON and zips the project's Python (chart builders, data loaders, static_api.py) plus plotly into docs/pycode.zip, and the data CSVs into docs/pydata.zip. The page loads the pre-rendered figures instantly, then boots Pyodide in the background and calls the same Python chart code in the browser for live filtering — so the static site is faithful to the Dash app with zero hosting cost. In normal operation the hourly GitHub Actions bot handles the refresh + rebuild + deploy automatically; the manual commands above are only needed for local iteration or a full rebuild.
Architecture
app.py # Dash app entry point, tab routing, background scrapers
components/
charts/ # One module per visualization; constants.py holds the
# shared palette, escaping, and fixed-reference helpers
stack_recommender.py # Agent Stack tab recommendation logic
data/
scraper.py # Live LLM data — Artificial Analysis
image_scraper.py # Live image-gen data — AA Image Arena
local_scraper.py # Live open-weight model data — AA model leaderboard
video_scraper.py # Live video-gen data — AA Video Arena (both generation arenas)
rsc.py # Next.js RSC payload parsing shared by the image + video scrapers
ingest.py # Parses scraper output, manages CSV cache and daily history
scrape_status.py # Per-dataset ok/fetched_at/rows — drives the freshness badge
image_models.py, local_models.py, video_models.py # Per-domain data access helpers
raw/ # Live cache, coverage, scrape status + daily snapshots
assets/style.css # Global dark theme, typography (copied into docs/ by the build)
captions.py # Every chart caption, read by app.py AND shipped in the manifest
static_helpers.py # Pure dash-free helpers shared by app.py + the static build
static_api.py # Browser bridge — Dash callbacks as JSON-returning functions (Pyodide)
build_static.py # Pre-renders figures + bundles Python into docs/ for GitHub Pages
data_guard.py # Row-loss, cumulative-drain and per-column median checks
docs/ # The static GitHub Pages site (index.html, app.js, figures/, pycode.zip, pydata.zip)
scripts/
capture_screenshots.py # Regenerates the README screenshots from the built site
.github/workflows/refresh.yml # Hourly bot: scrape → guard → rebuild → commit + push
tests/ # 383 tests: data semantics, encoding calibration, control
# behaviour, pipeline integrity, injection surfaces
Two renderings, one source
The Dash app and the static site run the same Python. Everything a chart
needs — palettes, captions, filter vocabularies, numeric defaults, provider
aliases — lives in one module and is either imported by both or shipped to the
browser in docs/figures/manifest.json. That is not tidiness: the recurring
defect in this codebase has been two copies of one fact drifting apart, so the
rule is derive, never synchronise, and tests assert the two sides agree.
The deployed site executes the Python inside docs/pycode.zip, not the
repo's .py files. The hourly bot only rebuilds docs/pydata.zip (the CSVs),
so a code change needs a full build_static.py to reach visitors —
tests/test_pybundle_freshness.py fails if the two ever diverge. The code zip
is split from the data so the browser can keep it: the worker caches it in
CacheStorage under manifest.code_version (a hash of its contents), and a
returning visitor downloads its ~4 MB again only when the code changes, not on
every hourly refresh.
Built With
| Tool | Role |
|---|---|
| Plotly Dash | Interactive web framework — Python functions rendered as a live site |
| Plotly | All charts and visualizations |
| Pandas | Data ingestion, filtering, and Pareto computation |
| requests | Live data scraping from the Artificial Analysis API |
| NumPy | Numerical operations (Pareto frontier, correlation) |
| Pyodide | Runs the Python chart code in the browser (WebAssembly) for the static site |
| GitHub Actions | Hourly scrape → rebuild → deploy bot |
| GitHub Pages | Free static hosting for the live dashboard — auto-deploys on every push to main |
| pytest | 383 regression tests, each named for the defect it prevents |
| Playwright | Drives the built site to regenerate the README screenshots, and runs the browser smoke checks in tests/e2e/ (skipped unless Playwright is installed; see that file for the command) |
来源:GitHub · github.com

