Skip to main content
This is advanced content. For day-to-day evaluation you only need the single command in Quickstart. What’s covered here is the internal mechanism of the harness, useful for troubleshooting or understanding profile/task selection.
This is advanced Eval source/maintainer content. Ordinary users do not need to clone Comet, enter its eval/ directory, or run pytest manually; use the installed comet eval and the user-level %USERPROFILE%\\.comet\\eval\\.env / ~/.comet/eval/.env instead. Clone the source only when modifying the built-in harness, using --project, or reproducing low-level tasks.
The eval harness ships inside the npm package at a matching version. A normal comet eval uses that package’s eval/ directory. Comet repository development or a custom harness can pass --project <repository-root> explicitly. You do not need to clone the Comet repository merely to obtain the harness.

Harness lookup and error boundaries

The CLI checks the harness before it checks uv:

Harness Directory Structure

What It Wraps

comet eval does these things internally:
  • Launches the harness from the <project>/eval root directory (using uv run)
  • Converts --manifest or --skill-path into pytest parameters
  • Selects the default profile (generic) and task set (recommended, generic-skill-smoke, or generated tasks)
  • When no manifest task is available, generates and caches 2–4 bounded tasks from the Skill content
  • Generates a temporary report config on demand (when using --html)
  • Prints a set of execution info to help locate the report
Based on --suite, it ultimately calls:
You don’t need to remember this command — comet eval assembles it for you.

collect and run

comet eval is a single entry-point command, distinguishing two phases via --collect: Both share the same parameter-building logic (buildEvalArgs); the only difference is that collect adds --collect-only while normal execution adds -v. --suite local|langsmith|langfuse selects the backend; --report-config, --html, and --quick are for the real evaluation path.

skill-path mode (default entry)

When you pass a local Skill directory or SKILL.md, comet eval uses skill-path — no comet/eval.yaml needed:
This is the default entry point for evaluating any local Skill. Comet discovers comet/eval.yaml under the target directory when it exists. Without a manifest, a normal run generates and caches 2–4 bounded tasks from the Skill content; --quick explicitly selects generic-skill-smoke (verifying that “the Skill can be injected, invoked, and produce files”). The --skill-name is inferred from the directory name. You can also explicitly specify a task with --task, or override the profile with --profile.

manifest mode (evaluating a /comet-any full package)

--manifest is suitable for /comet-any artifacts, or any Skill bundle with a comet/eval.yaml:
The manifest is usually auto-generated by /comet-any (not hand-written) and contains the target Skill, profile, recommended tasks, expected artifacts, and interaction config. Engine-enabled artifacts default to the authoring-skill profile and the authoring-skill-smoke quick eval. Only this path’s results are valid evidence for publish readiness; the generic-skill-smoke skill-path smoke is just early validation and does not count as release evidence.

Generated manifest draft hash

When metadata.draftHash is <current-bundle-hash>, the CLI locates the enclosing bundle.yaml, calculates the current Bundle draft hash, resolves the Skill source, and writes a temporary runtime manifest. The temporary directory is removed after evaluation; the source manifest and Bundle are unchanged. The placeholder is valid only while the generated manifest remains inside its Bundle draft.

Execution Info

Before running, comet eval prints a set of execution info so you can locate the report and troubleshoot:
  • Eval root: which eval/ root directory is actually launched from
  • Mode: collect or run
  • Target: whether the current evaluation target is a manifest or a local Skill directory
  • Experiment: the experiment id for this run
  • Profile: the profile used in this evaluation
  • Task: the evaluation task
  • Report path: report location
  • Report config: the temporary report config used when --html is enabled
In run mode, it additionally reminds you: failure attribution will be recorded into the generated eval summary, categorized into four buckets: harness, workflow, task, and model.

Where the Report Is and What It Looks Like

Experiment ID

The actual on-disk experiment id format is <experiment_name>_<YYYYMMDD_HHMMSS>, for example comet_fix_median_20260620_143000. The experiment name comes from the task name of the first parameterized test (- converted to _). Report directory:

summary.md contains

  1. Header: Experiment ID, start/completion time.
  2. Results table: one row per treatment, with columns including Checks, Turns, Duration, Tools, Tokens, Cost, RubricAvg.
  3. Summary: total runs, checks passed X/Y (percentage).
  4. Treatment Details: detailed metrics for each run of each treatment, skills invoked, scripts used, passed and failed check lists.

report.json per run

Fields include: passed, checks_passed[], checks_failed[], events_summary (duration, turns, tool_calls, tokens, cost, files_created, skills_invoked, failure_attribution).

Inside a Single Evaluation: Docker Isolation + Dual Agent + Rubric

Understanding this section helps you judge whether an evaluation result is trustworthy. comet eval ... --html runs internally along treatment × task × reps, and each run does:

Little fish observing the subject Agent, user simulator Agent, and rubric evaluation scene outside the Docker isolation box

A real evaluation runs Agent interactions in an isolated environment, then records evidence via validators and rubric

Key points:
  • The model runs inside a Docker container, isolated from your working directory.
  • Dual-agent loop (auto_user mode): the subject Agent runs the Skill under test, and at each decision point a user simulator Agent replies (approves reasonable proposals, picks defaults, drives progress — never refuses, never writes code). The subject Agent continues the same session with --resume, up to max_turns outer round-trips (comet-workflow typically 12, authoring-skill typically 8), ending early when a “complete” signal is hit. The max_turns here is not the number of internal messages or tool calls of the Agent under test. This lets multi-stage workflows automatically run the entire chain. For the complete loop and decision-point detection, see Scoring Metrics and Dual-Agent Evaluation.
  • Rubric scoring runs after the validators and appends results as [RUBRIC] informational checks (comet-workflow rubric never produces a hard failure; generic/authoring produce hard failures for specific missing items).
  • The real pass/fail is determined by the task validators (expected artifacts exist + test_scripts pass); rubric scores and pass@k are diagnostic information.

Report Output Configuration

Report output is controlled by ReportOutputConfig, with priority:
  1. --report-config <path> (JSON or YAML)
  2. COMET_EVAL_REPORT_CONFIG environment variable
  3. Default (markdown only)
Config format (top-level or nested both accepted):
--html is equivalent to {"markdown": true, "html": true} and writes a temporary file passed to pytest.

Failure Attribution

The report helps distinguish sources of failure. The attribution logic (attribution.py) judges each failed check in this order: This attribution is used to decide whether to fix the Skill, fix the eval config, or rerun the environment. See Reading Evaluation Reports.

Environment Variable Reference

The LangSmith suite additionally requires LANGSMITH_API_KEY, LANGSMITH_TRACING=true, and TRACE_TO_LANGSMITH=true. The user-facing entry is comet eval <target> --suite langsmith; you do not need to enter eval/langsmith/ and invoke pytest manually. The Langfuse suite requires LANGFUSE_PUBLIC_KEY and LANGFUSE_SECRET_KEY. The user-facing entry is comet eval <target> --suite langfuse; it still writes the local report while synchronizing traces, scores, and experiment summaries to Langfuse. --collect --suite langfuse does not initialize the SDK or make network requests.

Authenticating with an Anthropic-compatible proxy

When ANTHROPIC_API_KEY is not set, the claude inside Docker switches to authenticating via an Anthropic-compatible proxy (BigModel / mimo / OpenRouter, etc.). Required variables: These variables have placeholder entries in the automatically generated user-level .env template. Ordinary users can edit %USERPROFILE%\\.comet\\eval\\.env / ~/.comet/eval/.env; only source maintainers debugging a harness selected with --project need to edit the checkout’s eval/.env.

Custom User Simulator Prompt

In auto_user mode evaluation, the user simulator Agent’s instructions are driven by a prompt file. It reads eval/simulator-instruction.md by default:
If you want to swap in a different user behavior (e.g. more demanding, asks for more clarification), write your version to a file and point BENCH_SIMULATOR_PROMPT_FILE to it:
Relative paths are resolved from eval/; the file is read only if it exists. The command-line --simulator-prompt "..." has the highest priority and overrides file contents. See Scoring Metrics and Dual-Agent Evaluation · User Simulator Agent Instructions.

Don’t Confuse the Harness with Runtime Check

comet eval and comet skill check have similar names but different purposes:
  • comet eval: evaluates a Skill bundle or comet/eval.yaml, answering “can this Skill, as a product capability, pass the evaluation”.
  • comet skill check: checks whether a specific Skill run is missing artifacts or state, answering “is this run complete”.
See Runtime check.

Next steps

Last modified on August 13, 2026