Behavioral Evaluations & EDK Guide
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.
Overview
Section titled “Overview”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:
- Model responses are non-deterministic, making exact prose matching highly fragile.
- We must ensure the model utilizes the most efficient tools (e.g., batching
files via
read_many_filesinstead of sequentialread_filecalls). - We must enforce safety boundaries (e.g., preventing execution of raw shell commands when safe alternatives exist).
All behavioral evaluations are stored under the evals/ directory.
EDK Developer Commands
Section titled “EDK Developer Commands”The EDK provides CLI tools under scripts/ to help contributors audit, check,
and monitor evals.
1. npm run eval:inventory
Section titled “1. npm run eval:inventory”Scans all eval files under evals/, statically parses them, and provides a
structured overview of what exists in the repository.
- Usage:
Terminal window npm run eval:inventory - JSON Output: For CI integration or inventory indexing, generate a
machine-readable JSON report:
Terminal window npm run eval:inventory -- --json - Custom Root: Run against another directory or repository:
Terminal window npm run eval:inventory -- --root /path/to/other/repo
2. npm run eval:validate
Section titled “2. npm run eval:validate”A lint-like checker that validates eval source files against standard structural guidelines and best practices.
- Usage:
Terminal window npm run eval:validate - Custom Scopes: Validate a specific file:
Terminal window npm run eval:validate -- evals/my-test.eval.ts
Validation Rules & Severities
Section titled “Validation Rules & Severities”| 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.
3. npm run eval:report
Section titled “3. npm run eval:report”Aggregates local vitest report.json artifacts, maps them against inventory
policies, and summarizes the pass rates per model.
- Usage:
By default, it scans
Terminal window npm run eval:reportevals/logs/recursively forreport.jsonfiles. - Specifying Directory:
Terminal window npm run eval:report -- /path/to/logs - JSON Output:
Terminal window npm run eval:report -- --json
Contributor Workflow
Section titled “Contributor Workflow”When writing a new behavioral evaluation, adhere to this workflow to ensure high-quality, non-flaky test runs.
Step-by-Step Guide
Section titled “Step-by-Step Guide”- Identify the Target Behavior: Determine which tool calls need
verification (e.g.,
web_fetchmust be called). - Author the Eval File: Create your file under
evals/<name>.eval.tsnaming it properly. - Configure Workspace Files: If the eval reads or edits files, define them
inside the
filesmetadata field. - Assert Behavior, Not Prose: Ensure the
assertblock checks tool interactions usingrig.waitForToolCallor similar. Do not check final prose. - Run Locally:
Terminal window RUN_EVALS=true npx vitest run evals/my-test.eval.ts - Deflake: Run your eval at least 3 times locally to verify it does not fail due to model variance.
- Run Validation: Run
npm run eval:validateto ensure no linting errors are present.
Acceptance Criteria Checklist
Section titled “Acceptance Criteria Checklist”- Naming: File ends with
.eval.tsor.eval.tsx. - Policy: New evals start as
USUALLY_PASSES. - Metadata: Static
suiteNameandsuiteType(e.g.'behavioral') are specified. - Assertions: Uses
rig.waitForToolCallor asserts tool arguments explicitly. - Clean workspace: Does not write to files outside
rig.testDir.
Common Anti-Patterns to Avoid
Section titled “Common Anti-Patterns to Avoid”- Restricting core tools: Never override
settings.tools.coreto limit tools. Evals must run against the default toolset. - Checking model prose: Avoid
expect(result).toContain('something')since model wording is non-deterministic. - Integration-only testing: Evals that only write files without checking
realistic model prompts are integration tests and belong under
integration-tests/.
CI & Dashboard Integration
Section titled “CI & Dashboard Integration”You can easily automate behavioral evaluations or compile dashboard data using EDK’s JSON reporters.
CI Validation Block
Section titled “CI Validation Block”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:validatePublishing to a Dashboard
Section titled “Publishing to a Dashboard”To record nightly performance metrics across multiple models:
- Configure your workflow to run evaluations with the JSON reporter:
Terminal window 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" - Aggregate all test runs using the reporting tool:
Terminal window npm run eval:report -- evals/logs --json > aggregated_report.json - Upload
aggregated_report.jsonto your dashboard storage backend to visualize pass rates over time.