docs/behavioral-evals.md
This guide introduces the Eval Development Kit (EDK) and details how to write, validate, run, and report on behavioral evaluations in the Gemini CLI codebase.
Behavioral evaluations are automated tests designed to assert on the behavior of the Gemini CLI agent (e.g., verifying which tools are called, checking call ordering, or avoiding destructive commands) rather than checking the final prose output.
Evaluating agent behavior is critical because:
read_many_files instead of sequential read_file calls).All behavioral evaluations are stored under the evals/ directory.
The EDK provides CLI tools under scripts/ to help contributors audit, check,
and monitor evals.
npm run eval:inventoryScans all eval files under evals/, statically parses them, and provides a
structured overview of what exists in the repository.
npm run eval:inventory
npm run eval:inventory -- --json
npm run eval:inventory -- --root /path/to/other/repo
npm run eval:validateA lint-like checker that validates eval source files against standard structural guidelines and best practices.
npm run eval:validate
npm run eval:validate -- evals/my-test.eval.ts
| Rule ID | Severity | Description |
|---|---|---|
file-naming | Error | File must match *.eval.ts or *.eval.tsx naming conventions. |
valid-policy | Error | Policy must be one of ALWAYS_PASSES, USUALLY_PASSES, or USUALLY_FAILS. |
suite-metadata | Error | Both suiteName and suiteType must be present as static string literals. |
prompt-presence | Error | Every eval case must have a non-empty prompt string. |
case-name-static | Error | The case name must be a static string literal, not computed dynamically. |
invalid-tool-refs | Error | All tools referenced in assertions must match known built-in or legacy tools. |
positive-assertion | Error | Evaluation cases must assert on at least one tool call (e.g., check waitForToolCall has been invoked). |
workspace-setup | Error | Workspace behaviors (like file-system edits/reads) must set up a files object. |
new-evals-policy | Warning | New evals must not use ALWAYS_PASSES policy initially (they should be promoted after nightly data proves stability). |
Warnings (new-evals-policy) will be logged with ⚠ and will not cause
the CLI process to exit with status 1. Errors (✗) will block CI builds and
return exit status 1.
npm run eval:reportAggregates local vitest report.json artifacts, maps them against inventory
policies, and summarizes the pass rates per model.
npm run eval:report
evals/logs/ recursively for report.json files.npm run eval:report -- /path/to/logs
npm run eval:report -- --json
When writing a new behavioral evaluation, adhere to this workflow to ensure high-quality, non-flaky test runs.
web_fetch must be called).evals/<name>.eval.ts
naming it properly.files metadata field.assert block checks tool
interactions using rig.waitForToolCall or similar. Do not check final
prose.RUN_EVALS=true npx vitest run evals/my-test.eval.ts
npm run eval:validate to ensure no linting errors
are present..eval.ts or .eval.tsx.USUALLY_PASSES.suiteName and suiteType (e.g. 'behavioral') are
specified.rig.waitForToolCall or asserts tool arguments
explicitly.rig.testDir.settings.tools.core to limit
tools. Evals must run against the default toolset.expect(result).toContain('something') since
model wording is non-deterministic.integration-tests/.You can easily automate behavioral evaluations or compile dashboard data using EDK's JSON reporters.
Add a step in your PR checks or GitHub workflows to automatically lint new evals and block pull requests containing validation errors:
- name: Run Eval Validator
run: npm run eval:validate
To record nightly performance metrics across multiple models:
cross-env GEMINI_MODEL=gemini-2.5-pro npx vitest run --config evals/vitest.config.ts --reporter=json --outputFile="evals/logs/eval-logs-gemini-2.5-pro/report.json"
npm run eval:report -- evals/logs --json > aggregated_report.json
aggregated_report.json to your dashboard storage backend to
visualize pass rates over time.