Skip to main content
comet eval works out of the box to evaluate built-in tasks and any local Skill — evaluating your own Skill takes just one command, comet eval ./your-skill --html (see Quickstart). If you only need stable acceptance conditions for a local Skill, prefer declaring an inline task in that Skill package’s comet/eval.yaml, or reference a package-local task with source. Only create and register a task under eval/local/tasks/ when you are extending Comet’s built-in harness. This article walks you through the complete customization path: defining a task, configuring an evaluation profile, and running a report.
This article is advanced customization. If you just want to evaluate an existing Skill, you don’t need to read it — just use comet eval ./your-skill —html. For a Skill-specific inline task, edit comet/eval.yaml under the Skill root. This article assumes you can already run comet eval ./your-skill —collect successfully.
The eval/local/tasks/, pytest, Dockerfile, and registration workflow in this page are advanced source-maintainer content and require a Comet source checkout to reproduce. Ordinary users only need an inline task in the Skill’s comet/eval.yaml, or the comet eval command in Quickstart.

The Big Picture of Eval Configuration

A complete eval is assembled from three parts, and understanding their division of labor is the foundation of customization:

Little fish placing Task, Treatment and Profile configuration cards into the run tray, and organizing score, report and failure attribution outputs

Task decides what to test, Treatment decides what to inject, Profile and Rubric decide how to score

Let’s explain each one below.

Define a Task

Each task is a directory under local/tasks/ containing four files:
local/tasks/my-task/
task.toml
instruction.md
environment/
Dockerfile
validation/
test_my_task.py
For an ordinary local Skill, put inline tasks in comet/eval.yaml under that Skill’s root, or use source for a task package stored in the Skill package. The directory convention in this section comes from the eval harness (eval/), not your business repo: tasks under eval/local/tasks/ are for extending the Comet repository’s built-in harness and must be registered in eval/local/tasks/index.yaml.

1. Write task.toml

task.toml is the core configuration of a task, divided into four sections:
The role of each section:

Key fields in [evaluation]

These fields directly determine the scoring result and deserve separate explanation:
require_skill_invocation: true is useful but use it with caution: it requires the agent to have actually invoked the specified Skill (read from Claude Code events, not inferred from artifacts). If your Skill name is misspelled or not injected, every run will hard-fail.

2. Write instruction.md

This is the task instruction for the agent, supporting template variables like {run_id}:

3. Write the validation script

The validation script runs inside Docker and writes results to _test_results.json. This is the source of truth for “did this run get it right”:
The definition of a “pass” for a run is clear: the failed list reported by the validation script is empty. Both pass@k and pass^k are based on this judgment.

4. Write the Dockerfile

The Dockerfile provides the runtime and dependencies needed for validation. A minimal example:
The code produced by the agent and your validation script run inside the built image.

5. Register the task

Finally, register it in local/tasks/index.yaml:
Once registered, you can run it with --task my-task.

Configure Treatment

Treatment answers “which Skills to inject in this run”. Located at local/treatments/:
The standard approach for a comparative experiment is CONTROL (no Skill) vs your Skill treatment. The difference between the two is the gain your Skill brings.

Choose a Profile

The profile determines which rubric to score with. Choosing the wrong profile makes the dimension scores meaningless:
Profile resolution priority: —profile override > manifest’s skill.profile > task’s evaluation.profile > generic. Comet-type tasks (category = “comet”) are automatically inferred as comet-workflow.
For the dimensions, weights and checking logic of the three rubrics, see Scoring Metrics and Dual-Agent Evaluation.

Configure LLM-as-judge

LLM-as-judge is an optional quality coverage layer. It does not replace rule-based [RUBRIC] scores and does not directly change weighted_score. It lets an independent judge model read the run artifacts and append [RUBRIC-JUDGE] scores, helping you catch cases where rule checks miss whether the artifact has real substance. Use it when:
  • You evaluate documents, plans, code explanations, designs, or other artifacts that are hard to judge completely with scripts.
  • You already have validation scripts, but want to know whether the artifact is empty, shallow, or template-like.
  • You want comparison reports to show the gap between rule scores and judge scores.
Judge configuration is isolated from the subject Agent configuration. The subject Agent can keep using ANTHROPIC_MODEL, ANTHROPIC_BASE_URL, and its own token. The judge must explicitly set BENCH_JUDGE_MODEL so the same configuration does not silently act as both contestant and judge.

1. Enable judge in eval/.env

Add judge variables to the Comet repository’s eval/.env:
BENCH_LLM_JUDGE=1 is the switch. BENCH_JUDGE_MODEL is required. If you enable the switch without setting a model, the report records a skipped status:

2. Choose judge authentication

If the local host claude CLI is already authenticated, you can set only BENCH_JUDGE_MODEL. The harness calls the host claude CLI for judge runs. If you want the judge to use an independent Anthropic-compatible proxy, configure a dedicated endpoint and token:
You can also use an API key:
Priority:
If both BENCH_JUDGE_AUTH_TOKEN and BENCH_JUDGE_API_KEY are set, the auth token wins. The judge subprocess clears inherited main ANTHROPIC_* provider variables before mapping BENCH_JUDGE_*, so do not expect it to reuse the subject Agent provider configuration automatically.

3. Add custom judge criteria for generic tasks

Generic Skills (generic / authoring-skill) make the judge output three default dimensions: If your task has task-specific quality criteria, put them in [evaluation] in task.toml:
These criteria are emitted as additional judge dimensions named custom_0, custom_1. They only affect the [RUBRIC-JUDGE] coverage layer and do not replace your validation scripts. The comet-workflow profile uses a different judge dimension set: artifact_quality, spec_drift, and main_flow. These dimensions review workflow artifact depth, whether the spec drifted, and whether the five-phase main flow completed.

4. Run and confirm judge output

First use --collect to confirm tasks, manifests, and paths can be discovered:
Then run the real evaluation:
Open the report printed in Report path and look for [RUBRIC-JUDGE] lines in each run’s checks. A successful run looks like this:
If you only see skipped or failed, use this table:

Multi-turn interaction: auto_user mode

A single-turn task (mode: none) runs only once, suitable for simple scenarios of “give an instruction and see the result”. But workflow-type Skills need to pause at decision points, ask the user, and continue after receiving a reply — single-turn can’t test this. auto_user mode solves this: it uses two Agents interacting automatically — one runs the Skill under test (subject), the other simulates the user replying at decision points (simulator). The simulator’s behavior is controlled by a prompt file. It reads eval/simulator-instruction.md by default, and you can point BENCH_SIMULATOR_PROMPT_FILE to your own version to simulate “a more demanding user” or “a user who asks for clarification”:
max_turns controls the loop limit (comet-workflow typically 12 outer round-trips, authoring-skill typically 8 outer round-trips). It is not the number of internal messages or tool calls of the Agent under test; one outer round-trip means the Agent under test reaches a decision point, the user simulator replies, and the Agent under test continues with --resume. Hitting a “complete” signal (such as archive complete) ends the loop early.

A complete custom evaluation from scratch

Putting the above steps together, to evaluate your own Skill from scratch:
In the report, focus on three things:
  1. pass@1 and pass^k: capability ceiling vs reliability floor. See Scoring Metrics.
  2. Rubric dimension scores: which dimension dragged you down?
  3. Failure attribution (harness/workflow/task/model): is the failure a Skill problem, or a task/environment problem?

Evaluating /comet-any generated bundles

A Skill bundle generated by /comet-any comes with its own comet/eval.yaml manifest, so you don’t need to hand-write a task.toml. Just run with the manifest:
The manifest automatically selects the authoring-skill profile, injects recommended tasks and quality gates. For the complete manifest format, see Evaluation System Overview.

Next steps

Last modified on August 13, 2026