Write Kaggle Benchmarks logo

Write Kaggle Benchmarks

Organization
Kaggle
write-kaggle-benchmarks

Write, push, run, publish, and manage Kaggle Benchmark tasks using the kaggle CLI and the kaggle-benchmarks Python SDK. Use when the user wants to create or push a benchmark task (optionally with attached Kaggle datasets), run benchmarks against LLM models, check task/run status, stream or fetch execution logs, download results and source notebooks, publish a task to make it public, or troubleshoot benchmark workflows.

Overview

PublisherKaggle
Repositorykaggle-skills
Skill namewrite-kaggle-benchmarks
Stars
70
Forks
24
Bundled files
Instructions only
LicenseApache-2.0
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by Kaggle on GitHub. Read the source before you install it.

Installation

Install the Write Kaggle Benchmarks AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/Kaggle/kaggle-skills/tree/main/write-kaggle-benchmarks
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/Kaggle/kaggle-skills.git /tmp/kaggle-skills
mkdir -p .claude/skills
cp -r /tmp/kaggle-skills/write-kaggle-benchmarks .claude/skills/write-kaggle-benchmarks
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Write Kaggle Benchmarks in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Write Kaggle Benchmarks on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Write Kaggle Benchmarks is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Write Kaggle Benchmarks

Keywords

Kaggle benchmarks, write a benchmark, benchmark task, kbench, push task, run task.

Official Resources

Command Hierarchy

kaggle benchmarks (alias: kaggle b)
├── auth              — Fetch Model Proxy credentials
├── init              — Fetch credentials + setup local dev environment
└── tasks (alias: t)  — Manage benchmark tasks
    ├── push          — Upload a task from a .py file
    ├── run           — Run a task against model(s)
    ├── list          — List your benchmark tasks
    ├── status        — Show task details and per-model run status
    ├── download      — Download completed run outputs (and optionally source notebooks)
    ├── log (logs)    — Show execution logs for run(s) (streams live for RUNNING runs)
    ├── publish       — Make a task public (publishes the backing notebook by default)
    ├── models        — List available benchmark models
    └── delete        — Delete a task (not yet supported by server)

Setup

bash
# Full setup: credentials + .env + example_task.py + kaggle_benchmarks_reference.md
kaggle b init -y

# Credentials only (refresh MODEL_PROXY_* in .env)
kaggle b auth -y

Custom paths: --env-file <FILE> and --example-file <FILE> for init.

Env vars written by init:

  • MODEL_PROXY_URL
  • MODEL_PROXY_API_KEY
  • MODEL_PROXY_EXPIRY_TIME
  • LLM_DEFAULT
  • LLM_DEFAULT_EVAL
  • LLMS_AVAILABLE

Core workflow: Init → Write → Validate → Push → Run → Status → Download

Pacing — check in at every stage

Do NOT chain the full pipeline. Treat each numbered step below as a checkpoint:

  1. State what you are about to do for the current step (one sentence, including the exact command you intend to run).
  2. Wait for the user's go-ahead before executing — including for steps that look "obvious" like init or list.
  3. After the step completes, show the relevant output, then stop. Do not auto-advance to the next step.
  4. Ask the user how they want to proceed: continue to the next documented step, change parameters, or branch off.

If the user explicitly asks for "the whole pipeline" or "do everything", you may chain, but summarize the planned chain in advance and ask for one confirmation covering the lot, instead of skipping the per-step checkpoints silently.

0. Init (once per environment, re-run when creds expire)

init fetches Model Proxy credentials, writes .env, and drops an example_task.py + kaggle_benchmarks_reference.md next to it. Every later step depends on the MODEL_PROXY_* vars it writes, so run it before anything else — and re-run it any time python task.py or kaggle b t run fails with an auth error (the API key is short-lived).

bash
kaggle b init -y                      # first-time setup
kaggle b auth -y                      # creds-only refresh (no scaffolding)

1. Write a task file

A task file must:

  • Import kaggle_benchmarks as kbench
  • Define at least one function decorated with @kbench.task(...)
  • Call .run(kbench.llm) (or .evaluate(...)) on the task function — see Gotchas
  • Use # %% cell markers (jupytext percent format)
Minimal example:
python
# %%
import kaggle_benchmarks as kbench

# %%
@kbench.task(name="my-test-task")
def my_test_task(llm):
    response = llm.prompt("What is 2 + 2?")
    kbench.assertions.assert_in("4", response, expectation="Should contain 4")

my_test_task.run(kbench.llm)
LLM resolution precedence (highest → lowest):
  1. Explicit model in code: task.run(llm=kbench.llms["gemini-3.5-flash"])
  2. Default in code: task.run(llm=kbench.llm) (resolves to LLM_DEFAULT)
  3. Env vars from .env (LLM_DEFAULT, LLMS_AVAILABLE, MODEL_PROXY_*)

2. Validate locally

Run the task end-to-end before pushing. This catches the silent-no-op gotcha and broken prompts before the push → run → wait → download round-trip.

bash
kaggle b init -y                     # ensure .env is current
python task.py                       # run the task directly
ls -1 *.run.json                     # confirm a run file was produced

If python task.py exits cleanly and *.run.json appears, the task is safe to push. If validation fails, fix and re-run before proceeding to Step 3.

3. Push

bash
kaggle b t push my-task -f task.py --wait
kaggle b t push my-task -f task.py -d owner/dataset1 -d owner/dataset2   # attach datasets

--wait [TIMEOUT] blocks until server-side creation finishes (no arg = indefinite). --poll-interval <SECONDS> caps the polling interval (default 60s; polling starts at 5s and grows adaptively). Repeat -d/--kaggle-dataset once per dataset (do not space-separate; see the Gotchas).

4. Run

bash
# Interactive picker
kaggle b t run my-task

# Specific model
kaggle b t run my-task -m gemini-3.5-flash

# Multiple models (repeat -m, do NOT space-separate)
kaggle b t run my-task -m gemini-3.5-flash -m claude-haiku-4-5

# Wait for completion
kaggle b t run my-task -m gemini-3.5-flash --wait

List available models: kaggle b t models.

5. Status

bash
kaggle b t status my-task
kaggle b t status my-task -m gemini-3.5-flash

Prints task metadata (slug, version, state, created timestamp, public flag, task URL) and a per-model run table. Errored runs render their final exception line under an Errors: section.

6. Download

bash
kaggle b t download my-task                       # all terminal runs
kaggle b t download my-task -o ./results          # custom directory
kaggle b t download my-task -m gemini-3.5-flash
kaggle b t download my-task -s                    # also fetch source notebooks
kaggle b t download my-task -f                    # force re-download (overwrite)

Output layout: <output>/<task>/<version>/<model>/<run_id>/.... Already-downloaded runs are skipped unless --force/-f is passed. With --include-source/-s, each run's directory also contains __notebook__.ipynb and __notebook_source__.ipynb alongside the regular outputs (useful for debugging the kernel session).

7. Log

bash
kaggle b t log my-task                            # logs for every run of the task
kaggle b t log my-task -m gemini-3.5-flash # filter to one model
kaggle b t log my-task -m model-a -m model-b      # multiple models, sequential

RUNNING runs stream live via SSE; COMPLETED/ERRORED runs print the persisted log in one shot; QUEUED runs print (No logs available — server returned 404) and continue.

8. Publish

bash
kaggle b t publish my-task                              # publish task + backing notebook (default)
kaggle b t publish my-task --no-publish-backing-notebook  # publish task only, keep notebook private

Publishes both the task and the backing notebook by default. If the task is already public the command is a no-op for the task itself but will still publish the notebook unless --no-publish-backing-notebook is passed.

Quick Recipes

Reminder: these are reference snippets, not invocations to chain automatically. Per the "Pacing" section above, run them one at a time with user confirmation between each, unless the user explicitly asks you to chain them.

bash
# Push → run → download (run one command at a time, confirm between)
kaggle b t push my-task -f task.py --wait
kaggle b t run my-task -m gemini-3.5-flash --wait
kaggle b t download my-task -o ./results

# List tasks, filtered
kaggle b t list --name-regex "^math" --status errored

# Debug an errored run: pull logs first, then download source notebook
kaggle b t log my-task -m gemini-3.5-flash
kaggle b t download my-task -m gemini-3.5-flash -s -f

Gotchas

Most of these are silent failures the agent will not detect on its own — review before generating any task file or CLI invocation.

  • No .run() call → silent no-op. The push will succeed even if the file has no .run() (push validation only checks for @task decorators). The task will then execute on the server and produce no .run.json, so nothing is recorded. Every task function must end with task_fn.run(kbench.llm) (or .evaluate(...)).
  • MODEL_PROXY_API_KEY is short-lived. If python task.py fails with an auth error, re-run kaggle b auth -y (or kaggle b init -y) to refresh.
  • init / auth append to the env file. Loaded via dotenv so last-wins makes re-running safe, but the file accumulates duplicate entries over time.
  • Task slug must match a @task decorator. kaggle b t push <SLUG> -f file.py fails if <SLUG> doesn't match the slugified name of some @kbench.task(name=...) (or function name) in the file. Names are normalized: My Task → my-task, my_task → my-task.
  • Use bare canonical model slugs (e.g. gemini-3.5-flash, claude-haiku-4-5). The CLI auto-normalizes input by stripping any provider prefix (google/, anthropic/) and replacing @ with -, so google/gemini-3.5-flash, anthropic/claude-haiku-4-5@20251001, and claude-haiku-4-5-6@default all work — but tables, error logs, and download directories always display the canonical form (e.g. claude-haiku-4-5-20251001). Standardize on the bare slug everywhere to keep commands, output, and paths consistent.
  • Re-pushing without -d detaches previous datasets. If a prior version of a task had Kaggle datasets attached, re-pushing without repeating the -d flags prints a yellow warning to stderr and silently detaches them. Always repeat the full -d list on each push.
  • -f -s together to backfill source notebooks. If you originally downloaded without -s, a follow-up download -s will skip cached runs and print a tip. Re-run with -f -s to overwrite cached runs and fetch their source notebooks.
  • log is sequential, not interleaved. When multiple runs are active, the CLI blocks on the first run's stream until it terminates before moving to the next. This prevents log interleaving but means you'll wait on one run at a time.
  • delete is not implemented server-side. The command exists but currently prints Delete is not supported by the server yet.
  • Repeated flags, not space-separated. For multi-value flags (-m, -d/--kaggle-dataset), pass the flag once per value: -m a -m b, not -m a b. Space-separated form is not supported and will error.
  • CLI scope is tasks only, not benchmarks. A benchmark is a curated collection of tasks. The CLI lets you create, push, and run individual tasks, but creating or managing benchmarks (collections) must be done on the Kaggle web UI.

SDK features beyond the basics

These are higher-leverage kaggle_benchmarks patterns from the task-writing skill. Reach for them when the minimal example isn't enough — and consult the upstream skill for full worked code.

Task definition rules

  • @kbench.benchmark is an exact alias for @kbench.task. Use whichever reads better.
  • Return-type annotation is mandatory if the task returns a value. def score(llm) -> float: — without -> float / -> bool / -> dict etc., the run object's .result typing breaks.
  • store_task=False for sub-tasks. If a @kbench.task is called from inside another task (e.g. a per-row scorer in a dataset eval), set store_task=False on the inner one to avoid persisting it as a top-level run.

Run object

After run = task_fn.run(...):

  • run.passed — bool, True if the result and every assertion passed.
  • run.result — the returned value (typed by the task's return annotation).
  • run.assertion_results — list[AssertionResult], every recorded assertion.

Reasoning and temperature on llm.prompt()

python
response = llm.prompt("Solve: 127 * 53?", reasoning="high")   # "low" | "medium" | "high"
traces   = kbench.last_reasoning_traces()                     # str | None — may be None if disabled/unsupported
response = llm.prompt("Write a creative story.", temperature=0.7)   # default 0

Always null-check last_reasoning_traces() before using it.

Multimodal inputs

python
from kaggle_benchmarks.content_types import images, videos, audios

# Images: from_url / from_path / from_base64
img = images.from_url("https://example.com/cat.jpg")     # llm.prompt auto-downloads + base64-encodes
img = images.from_path("local/chart.png")                # read + base64 immediately
img = images.from_base64(b64_str, format="png")          # default format="jpeg"

# Videos: YouTube URLs only (no local files, no non-YouTube URLs); select Gemini models only
video = videos.from_url("https://www.youtube.com/watch?v=...")

# Audio
audio = audios.from_path("speech.mp3")

response = llm.prompt("Describe this", image=img)
  • llm.prompt(...) auto-downloads image URLs to base64 (safe for non-URL-capable models). user.send(...) passes the raw URL through — use it to test native URL fetching, but it'll fail on models that don't support it.
  • Video input is YouTube-only and limited to specific Gemini models; local files or non-YouTube URLs will error.

Branching and isolating chat histories

  • chats.fork("name") — copy current history into a temporary branch; the original chat is untouched on exit.
  • contexts.enter(chat=...) — low-level swap of the active chat for fully isolated agent histories. Use this only when ChatRoom doesn't fit (e.g. agents that must not see each other).

Multi-agent: ChatRoom + Participant (Pattern I.5)

For debate / hidden-role / negotiation flows, prefer kbench.ChatRoom over hand-rolled contexts.enter() wiring. Each participant sees a perspective-projected transcript; the same kbench.llm can back many participants.

python
room = kbench.ChatRoom(system_prompt="A structured 2-turn debate.")
pro  = room.add_participant(llm, name="Pro", system_prompt="Argue FOR.")
con  = room.add_participant(llm, name="Con", system_prompt="Argue AGAINST.")
pro.reply()
con.reply()

See docs/chatroom/rooms_walkthrough.md in the kaggle-benchmarks repo for a full walkthrough.

Custom assertions

  • @assertion_handler() — decorate a function to register it as a custom assertion (returns/raises an AssertionResult). Use @assertion_handler(raises_assertion_error=True) to fail loudly on mismatch.
  • kbench.assertions.assert_tool_was_invoked(fn) — verify the model actually called a registered tool during the prompt.

Frequently asked questions

What does the Write Kaggle Benchmarks AI skill do?

Write, push, run, publish, and manage Kaggle Benchmark tasks using the kaggle CLI and the kaggle-benchmarks Python SDK. Use when the user wants to create or push a benchmark task (optionally with attached Kaggle datasets), run benchmarks against LLM models, check task/run status, stream or fetch execution logs, download results and source notebooks, publish a task to make it public, or troubleshoot benchmark workflows.

Why use Write Kaggle Benchmarks on TypingMind?

Because you install it once and use it with any model. Write Kaggle Benchmarks is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Write Kaggle Benchmarks in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/Kaggle/kaggle-skills/tree/main/write-kaggle-benchmarks. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Write Kaggle Benchmarks?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Write Kaggle Benchmarks?

As many as you like. As long as a model supports skills, you can use Write Kaggle Benchmarks with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Write Kaggle Benchmarks AI skill free?

Yes. It is published on GitHub by Kaggle under the Apache-2.0 license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇