|
| 1 | +# Evals |
| 2 | + |
| 3 | +Offline harnesses that decide things about Blurt's behavior before the decision reaches Swift. |
| 4 | +This is the repo's only Python, and **none of it ships in the app** — a run's output is a measured |
| 5 | +artifact (today: one instruction string) that a human copies into the engine. |
| 6 | + |
| 7 | +| Directory | What it decides | |
| 8 | +| --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 9 | +| [`dictation-prompt/`](./dictation-prompt/README.md) | The dictation API's server-side cleanup instruction — `config.llm.instruction`, the string `CleanupInstruction.text` carries. A DSPy/GEPA search over candidate instructions, scored on disfluent-to-clean transcript pairs. | |
| 10 | + |
| 11 | +Each harness documents its own defaults, corpora, and what its numbers can and cannot establish. |
| 12 | +Read that README before reading a result: the ceilings here are set by the corpus and by the fact |
| 13 | +that we score a stand-in model rather than the service's own rewrite model, and both READMEs say so |
| 14 | +where it matters. |
| 15 | + |
| 16 | +## It is gated like shipped code |
| 17 | + |
| 18 | +`scripts/check.sh` runs three checks over this directory, and CI runs the same ones: |
| 19 | + |
| 20 | +| Check | Scope | Fix | |
| 21 | +| --------------------- | ------------------------------------- | ------------------------- | |
| 22 | +| `ruff format --check` | `evals/` | `ruff format evals/` | |
| 23 | +| `ruff check` | `evals/` | `ruff check --fix evals/` | |
| 24 | +| `pytest -q` | `evals/dictation-prompt/test_eval.py` | fix the test or the code | |
| 25 | + |
| 26 | +All three are platform-independent, so they also run in `scripts/check.sh --portable` — an eval |
| 27 | +change can be verified off-Mac, unlike anything touching Swift. A harness whose own correctness is |
| 28 | +unchecked is a bad instrument, which is why non-shipping code is gated at all. |
| 29 | + |
| 30 | +Two things follow from how that gate is wired: |
| 31 | + |
| 32 | +- **`ruff.toml` is scoped to this directory**, not the repo root — Blurt is a Swift project that |
| 33 | + happens to contain some Python. Ruff finds it by walking up from each file, so `ruff check evals/` |
| 34 | + from the repo root picks it up. The config comments explain the line width and the `src` setting. |
| 35 | +- **The pytest step names one file.** A second harness's tests are not picked up by wildcard; add |
| 36 | + them to the `pytest` invocation in `scripts/check.sh` in the same commit that adds them, or they |
| 37 | + are decoration. |
| 38 | + |
| 39 | +## Running one |
| 40 | + |
| 41 | +The scripts carry [PEP 723](https://peps.python.org/pep-0723/) headers, so `uv run` installs their |
| 42 | +dependencies into a throwaway environment — nothing to set up, no repo-level lockfile or virtualenv: |
| 43 | + |
| 44 | +```bash |
| 45 | +uv run evals/dictation-prompt/optimize_cleanup_prompt.py --out results.json |
| 46 | +``` |
| 47 | + |
| 48 | +The tests and the `--dry-run` paths deliberately import nothing outside the standard library |
| 49 | +(`pytest` aside), so they stay runnable with plain `python3` and no API key. A real run costs paid |
| 50 | +model calls; each harness's README says how many and what the defaults commit you to. |
0 commit comments