Nonobench

io.github.mauricekleine由 GitHub 账号 mauricekleine 发布v1.1.0更新于 Oct 24, 2026

An open-source benchmark of how well LLMs solve nonogram puzzles, from 5x5 to 20x20.

已验证Streamable HTTP可网页运行数据与分析AI 与机器学习

概览

AI 生成的概览

只读访问 Nonobench——一个评测大模型解 5x5 至 20x20 数织(Nonogram)谜题能力的公开基准,提供排行榜、单模型结果与答案校验。

可以做什么
  • 浏览排行榜,并按准确率、成本、延迟和 token 用量并排比较模型或模型家族
  • 查看单个模型按网格尺寸细分的结果,以及某模型解出、答错、超时或未运行的谜题
  • 列出提供商、模型家族及其可选推理强度与最佳变体
  • 读取基准谜题及其行列线索,并可按要求获取参考答案
  • 用与基准评分器相同的规则校验候选网格是否符合谜题线索
  • 列出单次基准运行记录,可选择包含原始提示词与模型输出
适用场景
适合在比较不同模型或推理强度的大模型推理表现时使用,也适合查看已发布结果背后的数织谜题与评分逻辑。它是只读数据源,不能用来运行你自己的基准测试。
运行要求
远程 Streamable HTTP 端点 nonobench.com/mcp;无需认证、API 密钥或本地运行时。浏览器端客户端仅允许站点自身来源或 HTTP 的 localhost/127.0.0.1 来源。
安装前请注意
只读:仅提供基准数据与答案校验,不会写入、发送或删除任何内容。参考答案与原始模型输出仅在明确请求时返回,应有意为之。自行运行基准属于另一套本地流程,需要 OpenRouter API 密钥或自建模型服务器。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Nonobench,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Web executable,通过 Streamable HTTP。 远程服务在工作区中配置后即可从网页运行时运行。

交给智能体安装

把这段提示词粘贴到 Claude Code、Codex、Cursor 等智能体,或 SourceWeft 对话中。智能体会读取该服务器的安装指南,先向你展示发布者、端点和登录方式,经你同意后再把它添加到你的客户端。密钥不会写进任何命令。

阅读 https://sourceweft.com/mcp/io.github.mauricekleine%2Fnonobench/install.md,并按其中说明把这个 MCP 服务器接入我的客户端。修改任何配置之前,先告诉我它的发布者、端点和登录方式,等我确认。不要把 API 密钥写进命令或我会提交的文件;问我密钥应从哪里获取。

查看智能体所依据的安装指南

其他 MCP 客户端

把它添加到你客户端的 mcpServers 配置中。

{
  "mcpServers": {
    "nonobench": {
      "type": "http",
      "url": "https://www.nonobench.com/mcp"
    }
  }
}

README

Nonobench

A benchmark suite for evaluating LLM reasoning capabilities on Nonogram (Picross) puzzle solving across different grid sizes. Results are published at nonobench.com.

Built by Maurice Kleine.

What is a Nonogram?

Nonograms (also known as Picross, Griddlers, or Paint by Numbers) are logic puzzles where you fill in cells on a grid based on numeric clues for each row and column. The clues indicate consecutive groups of filled cells, separated by at least one empty cell. Solving these puzzles requires logical deduction and constraint satisfaction - making them an excellent test of LLM reasoning abilities.

Project Structure

nonobench/├── bench/          # Benchmark runner, results database and exporter└── visualizer/     # TanStack Start dashboard on Cloudflare Workers (nonobench.com), also home of the puzzle set

Prerequisites

Quick Start

1. Clone the Repository

bash
git clone https://github.com/mauricekleine/nonobench.gitcd nonobench

2. Set Up Environment Variables

Create a .env file in the bench/ directory (see bench/.env.example):

bash
OPENROUTER_API_KEY=your_openrouter_api_key_here

This is the only variable needed. The visualizer builds without any.

3. Running Benchmarks

bash
cd benchbun installbun run bench                       # prints the plan and exits, no API callsbun run bench --model <name>        # run one model (repeat --model for more)bun run bench --all-missing         # run every configured model with missing workbun run bench --model <name> --sizes 20x20  # opt in to the extended tier

Runs are incremental and append-only: a model/puzzle pair that already has a successful result is never run again, and the database refuses to overwrite it. Failed runs are retried on the next invocation. Results are stored in bench/results.db (SQLite).

Useful flags:

  • --max-cost <usd> stops launching new puzzles once this session's spend reaches the amount. Requests already in flight still finish, so a session can overshoot by up to --parallel requests per selected model. Use the OpenRouter key's own limit as the hard ceiling.
  • --parallel <n> sets concurrent requests per model (default 10); lower it for rate-limited providers.
  • --limit <n> runs only the first n puzzles of each size, for pilots against a scratch database (NONOBENCH_DB=/tmp/copy.db).

Output modes

New runs ask for the answer as strict structured output (a JSON schema, only routed to endpoints that enforce it), so models cannot wrap the grid in prose. For a few models the schema-enforcing endpoints measurably hurt answers; those run in text mode instead (outputMode: "text" in bench/constants.ts, chosen by a 5x5 A/B with the benchmark prompt). Every run records its mode, and grading is identical for both: the answer must satisfy every clue. The runner also stops a model that solves none of the 5x5 puzzles with structured output, and one whose early runs mostly report zero reasoning tokens, since both point at the harness rather than the model.

After benchmarking, export results for the visualizer:

bash
bun run export

This writes visualizer/app/results.json (aggregates) and visualizer/public/results-raw.json (every run, including prompts and outputs).

Other scripts:

  • bun test - parser, grader, database-policy and puzzle checks
  • bun run typecheck - TypeScript check
  • bun run regrade - read-only comparison of stored grades against the current grader

Running Against a Local Model

The runner can benchmark a model that you serve yourself. Any server with an OpenAI-compatible /v1 endpoint works: vLLM, SGLang, llama.cpp, LM Studio, and Ollama.

This setup uses two machines. The model server is the workstation that serves the model. The bench machine is the laptop that runs the benchmark.

1. Serve the model on the workstation

Bind the server to all interfaces. The default bind address, 127.0.0.1, accepts connections only from the model server itself.

vLLM:

bash
vllm serve Qwen/Qwen3-32B --host 0.0.0.0 --port 8000

Ollama:

bash
ollama pull qwen3:32bOLLAMA_HOST=0.0.0.0:11434 ollama serve

llama.cpp:

bash
llama-server -m ./qwen3-32b-Q4_K_M.gguf --host 0.0.0.0 --port 8080

SGLang:

bash
python -m sglang.launch_server --model-path Qwen/Qwen3-32B --host 0.0.0.0 --port 30000

LM Studio: open the Developer tab, then select Start Server. Turn on the Network Server switch, so the server listens on all interfaces.

CAUTION: Do not expose the port to the internet. Most local servers have no authentication, so anyone who reaches the port can run the model.

2. Open the port on the model server

Restrict the rule to your own subnet. Allow TCP traffic from your local network to the port:

bash
sudo ufw allow from 192.168.1.0/24 to any port 8000 proto tcp

On macOS, allow incoming connections for the server app in System Settings.

3. Verify the connection from the laptop

Find the LAN address of the model server. On Linux, run ip -4 addr show. On macOS, run ipconfig getifaddr en0.

From the laptop, request the model list:

bash
curl http://192.168.1.20:8000/v1/models

Make sure that the answer lists your model. Copy the exact id value. You need that value for NONOBENCH_LOCAL_MODEL.

If the request fails, check the bind address from step 1. Then check the firewall rule, the address, and the port.

If the model server is not reachable on your network, create an SSH tunnel to it instead. Then use the address http://127.0.0.1:8000/v1:

bash
ssh -N -L 8000:127.0.0.1:8000 [email protected]
4. Run the benchmark
bash
cd benchbun installNONOBENCH_LOCAL_BASE_URL=http://192.168.1.20:8000/v1 \NONOBENCH_LOCAL_MODEL=Qwen3-32B \bun run bench:local --model Qwen3-32B

Do a pilot first. The next command runs two 5x5 puzzles into a scratch database:

bash
NONOBENCH_LOCAL_BASE_URL=http://192.168.1.20:8000/v1 \NONOBENCH_LOCAL_MODEL=Qwen3-32B \NONOBENCH_DB=local-pilot.db \bun run bench --model Qwen3-32B --sizes 5x5 --limit 2

Make sure that the plan lists your model as [local, text].

Environment variables for a local model
VariableMeaning
NONOBENCH_LOCAL_BASE_URLThe /v1 endpoint of the server. Ollama uses port 11434.
NONOBENCH_LOCAL_MODELThe model id that the server returns from GET /v1/models.
NONOBENCH_LOCAL_NAMEThe display name and the value for --model. Defaults to the model id. Must not match a cloud model name.
NONOBENCH_LOCAL_EFFORTThe reasoning effort your server is configured with (none, low, xhigh, …). Label only — the runner never sends reasoning settings to a local server. Defaults to none.
NONOBENCH_LOCAL_API_KEYThe bearer token, when the server requires one. Defaults to local.

The runner adds the local model to the plan only when you set both NONOBENCH_LOCAL_BASE_URL and NONOBENCH_LOCAL_MODEL.

Notes on local runs
  • Local runs cost $0. Keep them out of the published dataset: run them with bun run bench:local, which is bun run bench with NONOBENCH_DB=local-results.db. bench/results.db is the shared dataset, and the export-contract test checks it against the committed exports. The runner refuses to write a local model to the shared database.
  • Before starting, the runner checks the model id against the server's GET /v1/models list. A typo fails with the models the server does serve, and an unreachable server fails before any run is recorded.
  • Text mode is the default for a local model. Many local servers accept a JSON schema request and then ignore it. If your server enforces the schema, set NONOBENCH_OUTPUT_MODE=json_schema.
  • Start with --parallel 1. One GPU serves fewer requests at the same time than a cloud provider does.
  • The 20x20 tier asks for 128,000 output tokens. If your server has a smaller context, run only the core sizes.
  • The runner does not apply the reasoning-token circuit breaker to a local model. Some local servers report zero reasoning tokens for every run.
  • Set the same variables in bench/.env to avoid the prefix on every command.
  • A bench run registers the local model in bench/local-models.json (name, server model id, family, server URL), so a later bun run export and the visualizer pick it up without any env vars. To register a model you already benched, add one entry there: "<name>": { "baseURL": "http://host:port/v1", "modelId": "<server model id>", "family": "<name>" }. Omit modelId when the name is the server's id.

4. Viewing Results

bash
cd visualizerbun installbun run dev

Then open http://localhost:3000 to view the interactive dashboard.

Your own runs live in a separate database. Serve them with:

bash
cd visualizerbun run dev:local

dev:local exports bench/local-results.db into the dashboard's data files, starts the dev server, and restores the committed files when you stop it. While it runs, the dashboard shows only the models in that database — your local runs, not the published leaderboard. Set NONOBENCH_LOCAL_DB to serve another database.

While that server runs, bun test in bench fails one test: the export-contract test compares the dashboard's data files against bench/results.db, and dev:local has put your runs in them. Stop the server, let the script restore the committed files, and the suite passes again.

5. Deploying

The visualizer is a Cloudflare Worker (visualizer/wrangler.jsonc). Pages are prerendered at build time and served as static assets; the Worker serves the API, the MCP server and the agent routes, reading the exported JSON through its assets binding. Workers Builds owns production deploys on merge to main: it runs bun install --frozen-lockfile && bun run build, then bunx wrangler deploy, from visualizer/ with Cloudflare credentials. Local deploy scripts and Wrangler logins are retired; agents use cf for Cloudflare access. From visualizer/:

  • CLOUDFLARE_ENV=beta bun run build builds the beta Worker for local preview. Nothing deploys it.
  • bun run deploy:verify <sha> waits until production runs a build containing that commit on main. Branch commits fail immediately unless DEPLOY_VERIFY_URL names a separately deployed target. The repository root runs the same script, so bun run deploy:verify <sha> works from either directory.

Agent Access

nonobench.com exposes the benchmark data to agents, with no authentication:

  • REST API under /api/v1 (leaderboard, models, puzzles, a solution checker, individual runs). The spec is at /api/openapi.json, and /.well-known/api-catalog (RFC 9727) points to it.

  • MCP server at /mcp (stateless Streamable HTTP, MCP 2026-07-28 with 2025 client compatibility), described by /.well-known/mcp/server-card.json. Add it to a client with claude mcp add --transport http nonobench https://www.nonobench.com/mcp. Browser requests may use the site's origins or HTTP localhost/127.0.0.1 origins. It's listed in the Claude Connectors Directory, the MCP Registry (io.github.mauricekleine/nonobench), Smithery, Glama and mcpservers.org.

    [Nonobench MCP connector] [Listed on mcpservers.org]

  • WebMCP tools registered in the browser via navigator.modelContext.

  • Markdown: / and /puzzles return markdown when requested with Accept: text/markdown. /llms.txt gives an overview.

  • Discovery: robots.txt (with Content Signals), sitemap.xml, Link headers on the homepage, an agent skill at /.well-known/agent-skills/index.json, and an ARD manifest at /.well-known/ai-catalog.json.

All of it is read from the same exported files as the dashboard (visualizer/app/results.json and visualizer/public/results-raw.json), so bun run export updates it too.

Grading

Each model receives the same system prompt and the puzzle's row and column clues. Standard answers are the grid as one string of 1s and 0s. Hard mode answers are one row per line, because at 400 cells most models miscount a single string (see LEARNINGS.md). An answer is correct when it satisfies every row and column clue.

Ten of the 30 puzzles (one 5x5, four 10x10, five 15x15) have more than one valid solution, so answers are checked against the clues rather than compared with the stored solution. Correctness is derived from the stored raw outputs at export time; the database is never rewritten. The puzzle test suite pins which puzzles are ambiguous, and any new puzzle must have a unique solution.

Puzzle Data

The core tier has 30 puzzles (10 each of 5x5, 10x10 and 15x15), defined in visualizer/components/puzzles/ and shared by the runner and the dashboard. They were sourced from nono-dataset. Hard mode has 10 generated 20x20 puzzles. A puzzle's ID is a hash of its solution, so changing a puzzle's solution creates a new puzzle.

Tiers and generation

Default benchmark runs cover the three core sizes (Standard). Use --sizes 20x20 with a model selection to run Hard mode; comma-separated sizes also work. The runner's plan reports missing 20x20 work separately. Headline overall accuracy and best-variant selection use Standard runs only; Hard mode has its own results. Hard-mode requests get a 128,000-token answer budget, capped at the endpoint's maximum (bench/max-output-tokens.json).

From bench/, bun run generate-puzzles recreates the 20x20 set with a fixed seed. It fills grids at random (no pictures, so a model can't guess the image), keeps grids with at least three blocks per line and little mirror symmetry, and checks uniqueness with an exact solver (NONOGRAM_SOLVER). The set mixes five puzzles that row-and-column propagation solves with five where it stalls with 20–200 cells left. bun test verifies their clues, uniqueness flags and line solvability; the original ambiguity list remains pinned.

Configuration

Edit bench/constants.ts to configure:

  • MODELS - Array of model configurations (OpenRouter model ID, display name, reasoning settings)
  • MAX_PARALLEL_RUNS_PER_MODEL - Concurrent puzzle runs per model (default: 10)
  • REQUEST_TIMEOUT_MS - Per-request timeout; a timed-out request is stored as a failed run (default: 30 minutes)

NONOBENCH_DB, NONOBENCH_RESULTS_JSON and NONOBENCH_RESULTS_RAW_JSON override the database and export paths, which is useful for testing against a copy.

Tech Stack

Benchmark Runner

  • Bun - JavaScript runtime and SQLite
  • AI SDK - Unified LLM interface
  • OpenRouter - LLM API gateway
  • TypeScript

Visualizer

Contributing

Contributions are welcome! Feel free to:

  • Add support for new LLM models
  • Improve the benchmark methodology
  • Enhance the visualization dashboard

License

MIT

来源:README.md,提交 796cedd

工具

11

get_leaderboard

Get leaderboard

Models ranked by accuracy; defaults to all effort levels for compatibility.

输入参数sizeeffortfamilyversionproviderreasoningmin_correctopen_weights

list_providers

List providers

Provider ids, names, families and variant counts.

无需输入参数。

list_families

List families

Model families, available efforts and best variants.

无需输入参数。

compare_models

Compare models

Side-by-side core overall and per-size accuracy, cost, latency and token results for model or family names.

输入参数models必填

get_model_results

Get model results

Accuracy, cost, latency and token use for one model, broken down by grid size.

输入参数model必填

list_puzzles

List puzzles

The benchmark puzzles with their ids and row/column clues.

输入参数size

get_puzzle

Get puzzle

One puzzle, including the clue text models were prompted with. The reference solution is only included on request; some puzzles have several valid solutions.

输入参数id必填include_solution

check_solution

Check solution

Check a grid against a puzzle's clues, using the same rule as the benchmark grader. Reports which rows and columns do not match.

输入参数id必填grid必填

get_puzzle_results

Get puzzle results

Per-model outcomes for one puzzle. Answers are omitted unless requested.

输入参数id必填effortfamilyproviderreasoningopen_weightsinclude_answers

get_model_puzzles

Get model puzzles

Which puzzles one model solved, missed, timed out on, or has not run.

输入参数model必填

list_runs

List runs

Individual benchmark runs (one model on one puzzle), optionally with the raw prompt and model output.

输入参数sizelimitmodeloffsetpuzzle_idinclude_output

版本历史

1
  1. v1.1.0最新Sep 30, 2026

评分

已满足适用检查项的 100%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通必需25 分
  • 已声明认证方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分