cd /news/ai-tools/skillgrade-unit-tests-for-your-agent… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-54748] src=github.com β†— pub= topic=ai-tools verified=true sentiment=Β· neutral

Skillgrade: "Unit tests" for your agent skills

Skillgrade, a new open-source tool, enables developers to create and run unit tests for AI agent skills, ensuring agents correctly discover and use custom skills. The tool supports multiple AI agents including Gemini, Claude, and Codex, and provides features like smoke testing, regression testing, and CI integration.

read8 min views1 publishedJul 10, 2026
Skillgrade: "Unit tests" for your agent skills
Image: source

The easiest way to evaluate your Agent Skills. Tests that AI agents correctly discover and use your skills.

See examples/ β€” superlint (simple) and angular-modern (TypeScript grader).

Prerequisites: Node.js 20+, Docker

npm i -g skillgrade

1. Initialize β€” go to your skill directory (must have SKILL.md

) and scaffold:

cd my-skill/
GEMINI_API_KEY=your-key skillgrade init    # or ANTHROPIC_API_KEY / OPENAI_API_KEY

Generates eval.yaml

with AI-powered tasks and graders. Without an API key, creates a well-commented template.

2. Edit β€” customize eval.yaml

for your skill (see eval.yaml Reference).

3. Run:

GEMINI_API_KEY=your-key skillgrade --smoke

The agent is auto-detected from your API key: GEMINI_API_KEY

β†’ Gemini, ANTHROPIC_API_KEY

β†’ Claude, OPENAI_API_KEY

β†’ Codex. Override with --agent=claude

.

4. Review:

skillgrade preview          # CLI report
skillgrade preview browser  # web UI β†’ http://localhost:3847

Reports are saved to $TMPDIR/skillgrade/<skill-name>/results/

. Override with --output=DIR

.

Flag Trials Use Case
--smoke
5 Quick capability check
--reliable
15 Reliable pass rate estimate
--regression
30 High-confidence regression detection
Flag Description
--eval=NAME[,NAME]
Run specific evals by name (comma-separated)
--grader=TYPE
Run only graders of a type (deterministic or llm_rubric )
--trials=N
Override trial count
--parallel=N
Run trials concurrently
`--agent=gemini claude
Override agent (default: auto-detect from API key)
`--provider=docker local`
Override provider
--acp-command=CMD
ACP agent command (e.g., gemini --acp )
--command=CMD
Command to run for the command agent (e.g., node mycli.js )
--opencode-agent=NAME
OpenCode agent (build plan
--opencode-model=MODEL
OpenCode model (provider/model format)
--output=DIR
Output directory (default: $TMPDIR/skillgrade )
--validate
Verify graders using reference solutions
--ci
CI mode: exit non-zero if below threshold
--threshold=0.8
Pass rate threshold for CI mode
--preview
Show CLI results after running
version: "1"


defaults:
  agent: gemini          # gemini | claude | codex | acp | opencode | command
  provider: docker       # docker | local
  trials: 5
  timeout: 300           # seconds
  threshold: 0.8         # for --ci mode
  grader_model: gemini-3-flash-preview  # default LLM grader model
  grader_provider: gemini               # default LLM grader provider: gemini | anthropic | openai
  command: node mycli.js # command to run when agent is 'command' (see Custom Command Agent)
  acp:                   # ACP agent configuration (optional)
    command: gemini --acp  # command to start ACP-compatible agent
    env:                  # optional environment variables
      DEBUG: "1"
  docker:
    base: node:20-slim
    setup: |             # extra commands run during image build
      apt-get update && apt-get install -y jq
  environment:           # container resource limits
    cpus: 2
    memory_mb: 2048

tasks:
  - name: fix-linting-errors
    instruction: |
      Use the superlint tool to fix coding standard violations in app.js.

    workspace:                           # files copied into the container
      - src: fixtures/broken-app.js
        dest: app.js
      - src: bin/superlint
        dest: /usr/local/bin/superlint
        chmod: "+x"

    graders:
      - type: deterministic
        setup: npm install typescript    # grader-specific deps (optional)
        run: npx ts-node graders/check.ts
        weight: 0.7
      - type: llm_rubric
        rubric: |
          Did the agent follow the check β†’ fix β†’ verify workflow?
        provider: gemini                 # optional: gemini (default) | anthropic | openai
        model: gemini-2.0-flash          # optional model override
        weight: 0.3

    agent: claude
    grader_provider: anthropic   # override default LLM grader provider
    trials: 10
    timeout: 600

String values (instruction

, rubric

, run

) support file references β€” if the value is a valid file path, its contents are read automatically:

instruction: instructions/fix-linting.md
rubric: rubrics/workflow-quality.md

Runs a command and parses JSON from stdout:

- type: deterministic
  run: bash graders/check.sh
  weight: 0.7

Output format:

{
  "score": 0.67,
  "details": "2/3 checks passed",
  "checks": [
    {"name": "file-created", "passed": true, "message": "Output file exists"},
    {"name": "content-correct", "passed": false, "message": "Missing expected output"}
  ]
}

score

(0.0–1.0) and details

are required. checks

is optional.

Bash example:

#!/bin/bash
passed=0; total=2
c1_pass=false c1_msg="File missing"
c2_pass=false c2_msg="Content wrong"

if test -f output.txt; then
  passed=$((passed + 1)); c1_pass=true; c1_msg="File exists"
fi
if grep -q "expected" output.txt 2>/dev/null; then
  passed=$((passed + 1)); c2_pass=true; c2_msg="Content correct"
fi

score=$(awk "BEGIN {printf \"%.2f\", $passed/$total}")
echo "{\"score\":$score,\"details\":\"$passed/$total passed\",\"checks\":[{\"name\":\"file\",\"passed\":$c1_pass,\"message\":\"$c1_msg\"},{\"name\":\"content\",\"passed\":$c2_pass,\"message\":\"$c2_msg\"}]}"

Use

awk

for arithmetic β€”bc

is not available innode:20-slim

.

Evaluates the agent's session transcript against qualitative criteria:

- type: llm_rubric
  rubric: |
    Workflow Compliance (0-0.5):
    - Did the agent follow the mandatory 3-step workflow?

    Efficiency (0-0.5):
    - Completed in ≀5 commands?
  weight: 0.3
  provider: gemini           # gemini (default) | anthropic | openai
  model: gemini-2.0-flash    # optional, auto-detected from API key

The provider

field selects which LLM API to call:

Provider API Key Env Var Base URL Env Var (optional) Default Model
gemini
GEMINI_API_KEY
  • | gemini-3-flash-preview | anthropic | ANTHROPIC_API_KEY | ANTHROPIC_BASE_URL | claude-sonnet-4-20250514 | openai | OPENAI_API_KEY | OPENAI_BASE_URL | gpt-4o |

ANTHROPIC_BASE_URL

and OPENAI_BASE_URL

enable custom/self-hosted endpoints (Ollama, vLLM, etc.).

graders:
  - type: deterministic
    run: bash graders/check.sh
    weight: 0.7      # 70% β€” did it work?
  - type: llm_rubric
    rubric: rubrics/quality.md
    weight: 0.3      # 30% β€” was the approach good?

Final reward = Ξ£ (grader_score Γ— weight) / Ξ£ weight

Use --provider=local

in CI β€” the runner is already an ephemeral sandbox, so Docker adds overhead without benefit.

- run: |
    npm i -g skillgrade
    cd skills/superlint
    GEMINI_API_KEY=${{ secrets.GEMINI_API_KEY }} skillgrade --regression --ci --provider=local

Exits with code 1 if pass rate falls below --threshold

(default: 0.8).

Tip: Usedocker

(the default) for local development to protect your machine. In CI,local

is faster and simpler.

Variable Used by
GEMINI_API_KEY
Agent execution, LLM grading (provider: gemini ), skillgrade init
ANTHROPIC_API_KEY
Agent execution, LLM grading (provider: anthropic ), skillgrade init
OPENAI_API_KEY
Agent execution (Codex), LLM grading (provider: openai ), skillgrade init
ANTHROPIC_BASE_URL
LLM grading (provider: anthropic ) β€” custom Anthropic-compatible endpoint
OPENAI_BASE_URL
LLM grading (provider: openai ) β€” custom OpenAI-compatible endpoint (Ollama, vLLM, etc.)

Variables are also loaded from .env

in the skill directory. Shell values override .env

. All values are redacted from persisted session logs.

Bring your own agent. The built-in adapters (gemini

, claude

, codex

, ...) cover the popular CLIs, but you can point skillgrade at any command β€” a custom script, a deepagents loop, or a small orchestrator over the Claude/OpenAI SDKs β€” without forking the package or implementing an ACP server.

skillgrade --agent=command --command="node mycli.js"

Or in eval.yaml

:

defaults:
  agent: command
  command: "node mycli.js"
  provider: local        # run on the host; or use docker + docker.setup to install your CLI

command

can also be set per task to override the default.

The task instruction is piped to your command's stdin (skillgrade writes it to /tmp/.prompt.md

, then runs cat /tmp/.prompt.md | <command>

inside the workspace directory). If your CLI takes the prompt as an argument instead, wrap it in a one-line script that reads stdin.

Your command runs in the workspace and is free to read/edit files there β€” graders score the resulting workspace state (and any live checks), not your command's stdout, so any agent slots in cleanly.

is the simplest fit for a custom agent: your command runs on the host with your tools already installed.provider: local

still works β€” skillgrade doesprovider: docker

not auto-install anything for thecommand

agent, so install your CLI and dependencies viadocker.setup

:

defaults:
  agent: command
  command: "mycli run"
  docker:
    base: node:20-slim
    setup: "npm install -g my-cli-package"

OpenCode is an AI coding agent that supports multiple AI models and specialized subagents.

skillgrade --agent=opencode

skillgrade --agent=opencode --opencode-agent=build

skillgrade --agent=opencode --opencode-agent=build --opencode-model=anthropic/claude-sonnet-4-20250514
Agent Description
build
Default primary agent with full tool access
plan
Read-only planning/analysis agent
explore
Fast codebase exploration agent

Models are specified in provider/model

format:

Model Format
Claude Sonnet 4 anthropic/claude-sonnet-4-20250514
GPT 5.1 Codex opencode/gpt-5.1-codex
Flag Description
--agent=opencode
Use OpenCode agent
--opencode-agent=NAME
OpenCode agent (build plan
--opencode-model=MODEL
OpenCode model (provider/model format)
  • skillgrade invokes OpenCode CLI with opencode run

  • Passes instruction via temp file to avoid shell escaping issues

  • Supports both agent and model specification

  • Works with --provider=docker

or--provider=local

Agent Client Protocol (ACP) is an open protocol that standardizes communication between AI coding agents and clients. Using an ACP-compatible agent allows you to evaluate skills without managing API keys directly.

skillgrade --agent=acp --acp-command="gemini --acp"

defaults:
  agent: acp
  acp:
    command: gemini --acp

Any agent that supports the ACP protocol can be used:

Agent Command
Gemini CLI gemini --acp
Other ACP agents Check agent documentation
  • skillgrade starts the ACP agent as a subprocess
  • Communication happens via JSON-RPC 2.0 over stdio
  • No API key required β€” authentication is handled by the ACP agent
  • Works best with --provider=local

since the ACP agent needs to be available in your environment

Flag Description
--agent=acp
Use ACP-compatible agent
--acp-command=CMD
Command to start the ACP agent

The --acp-command

can also be set in eval.yaml

under defaults.acp.command

.

Grade outcomes, not steps. Check that the file was fixed, not that the agent ran a specific command.Instructions must name output files. If the grader checks foroutput.html

, the instruction must tell the agent to save asoutput.html

.Validate graders first. Use--validate

with a reference solution before running real evals.Start small. 3–5 well-designed tasks beat 50 noisy ones.

For a comprehensive guide on writing high-quality skills, check out skills-best-practices. You can also install the skill creator skill to help author skills:

npx skills add mgechev/skills-best-practices

MIT

Inspired by SkillsBench and Demystifying Evals for AI Agents.

── more in #ai-tools 4 stories Β· sorted by recency
── more on @skillgrade 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/skillgrade-unit-test…] indexed:0 read:8min 2026-07-10 Β· β€”