Your first eval
One SQL task. Two criteria. Choose a model, run it, and inspect the work.
On this page
1. Check the tools
bun --version
docker info
opencode --version
| Tool | Ready when |
|---|---|
| Bun | Version 1.4.2 or later |
| Docker | The daemon is running with Linux containers |
| OpenCode | Version 2; the SDK runtime is pinned to 2.0.22 |
Install BunInstall DockerInstall OpenCode V2
If your V2 executable is named opencode2, use that name for the OpenCode commands below.
2. Pick a directory
Use an existing benchmark package or an empty project. For a new one:
mkdir my-benchmark
cd my-benchmark
bun init -y
bun add --exact @hona/openeval@0.5.3
bunx --bun @hona/openeval --version
Keep the following commands in this directory. In an existing package, keep its manifest and add the dependency with its package manager.
node_modules/
results/
3. Add the writing skill
Extract it into your project root. Keep an existing customized skill if you already have one.
.opencode/skills/eval-writing/
SKILL.md
README.md
references/
openeval.md
examples.md
research.md
Open this project in OpenCode. Use /eval-writing when you want help with your own task or rubric.
opencode .
4. Write one eval
An eval is a task plus its grading rules. The candidate does the task; the judge grades its recording. Each criterion is one scored requirement.
Try this SQL demo: does the candidate ask which database you use, and handle the customer ID safely? Create these files:
benchmark.ts
evals/
ask-dialect/
prompt.md # the task
judge.md # the criteria
Write a SQL query for the ten most recent orders for a customer.
# Requests the SQL dialect
## Criterion: asked_dialect — Asks for the SQL dialect
Pass when the agent asks which database or SQL dialect is in use.
Fail when it assumes a dialect without asking.
Asking alongside a draft counts.
## Criterion: safe_parameters — Uses bound parameters
Pass when the proposed query uses a bound customer-ID parameter
and explains how to supply its value.
Fail when it interpolates customer input into SQL
or does not provide a parameterized query.
| Example response | Asks for dialect | Bound parameters |
|---|---|---|
| Asks which DB; gives a bound-parameter draft | 1 | 1 |
| Assumes PostgreSQL; gives a bound-parameter draft | 0 | 1 |
| Only asks which database | 1 | 0 |
5. Choose models and variants
In OpenCode, connect your provider and pick a candidate and a judge:
/connect
/models
Replace both placeholders below with connected model IDs. A benchmark groups your evals and model choices.
import type { Benchmark } from "@hona/openeval";
export default {
models: ["provider/candidate-model"],
candidate: { websearch: false },
judge: { model: "provider/judge-model", websearch: false },
repetitions: 1,
concurrency: 1,
} satisfies Benchmark;
Use provider/model#variant for a listed variant, such as #high. Omit the suffix for the default. Start with one candidate and one repetition. This demo needs no web search.
Using only judge.ts files? Omit judge.model; you only need the candidate model.
6. Plan, then run
bunx --bun @hona/openeval image
bunx --bun @hona/openeval plan --only-eval ask-dialect --only-repetition 1
Check the plan: ask-dialect, your candidate model, repetition 1. Planning previews work and its cost estimate. When you are ready to call the models:
bunx --bun @hona/openeval run --only-eval ask-dialect --only-repetition 1
Running later? Keep the files and use the same command when ready.
7. Watch and inspect
To watch live, open a second terminal in the same directory. You can also open the viewer after the run.
bunx --bun @hona/openeval view
- Select ask-dialect
- Select your model
- Read Session / Judge
- Follow the evidence
| Result | Read it as |
|---|---|
| Criterion score | 1 = pass, 0 = fail, null = unresolved |
| Benchmark score | Mean credit; this demo's [1, 0] gives 50% |
| Cost and tokens | Recorded metrics, separate from the score |
| results/ | Retained runs, judgments, and evidence |
Next: add your other model IDs or increase repetitions in benchmark.ts, then plan and run again. OpenEval resumes the same result and keeps completed work.