| name | run-research-eval |
| description | Run the research quality eval (packages/research golden set) against the live pipeline and read the numbers. Use when asked to "run the eval", benchmark research grounding/recall, or take a before/after on a research change. Encodes the routing, cost, and safety guardrails so a run is not misconfigured. |
Run the research eval
Drives every company in a golden-set JSON file through the live research pipeline (real scraping + LLM calls) and reports grounding accuracy, field precision/recall, titled-contact recall, wrong-company rate, and empty rate. It is a billable, multi-hour, developer/CI tool — never a production path.
Full reference: eval/README.md. This skill is the run procedure and the guardrails.
Before you touch a command
- This spends real money and hours. One pass of the shipped golden set (~20 companies ×
--runs 3) is roughly $10–15 and 1–2.5h of live API calls, billed to the org's Firecrawl/LLM accounts. Confirm the user actually wants to spend it, and confirm scope: the current branch only ("after"), or a before/after pair against main too (doubles it).
- Worktree must be up:
pnpm cli worktree up (own DB + bucket), pnpm cli worktree doctor to confirm Postgres is reachable.
- Org/user are seeded with generated ids — resolve them from the local DB, don't hard-code:
psql "postgresql://batuda:batuda@localhost:5433/<worktree-db>" -tAc "SELECT id FROM organization WHERE slug='taller';"
psql "postgresql://batuda:batuda@localhost:5433/<worktree-db>" -tAc "SELECT id FROM \"user\" WHERE email='admin@taller.cat';"
The one rule that trips every run: routing ≠ keys
The keys being present does not mean the eval will run. The pipeline also needs the routing — RESEARCH_LLM_{AGENT,EXTRACT,WRITER}_PROVIDERS + _MODEL, and RESEARCH_PROVIDER_{SEARCH,SCRAPE,REGISTRY_GB}. If any are missing from the run environment, that provider silently falls back to stub and the run reports 100% empty over canned data.
Infra stays local, never cloud
DATABASE_URL and STORAGE_* must resolve to the worktree's own DB + bucket, never prod. The dev Infisical env carries neither, so a dev-env run gets both from the worktree .env automatically. If you run off an env that does carry them (e.g. prod), pin both back to local with a leading env DATABASE_URL=… STORAGE_ENDPOINT=… before pnpm (see eval/README.md).
Validate one company first, then the full pass
Always shake out the config on a single row before the billable run — a wrong vendor/model, an expired key, or a network-blocked provider fails in seconds as a 100% empty rate.
infisical run --env=<env> -- sh -c '<inline routing if not in env> \
pnpm cli research eval --org <org> --user <user> --golden <one-row>.json --runs 1 --out /tmp/one.json'
infisical run --env=<env> -- pnpm cli research eval --org <org> --user <user> --golden eval/golden.example.json --runs 3 --out report.json
Run the full pass in the background (it outlives the 2-minute foreground limit); read report.json when it lands.
Reading the result
eval/README.md §"Reading a change that targets under-filling" maps each number to the question it answers, and points at the research.phase2 span's research.enrichment.filled_{broad,rescued,kept} attributes (on the monitoring board) that separate "the model returned nothing" from "a guard removed it". For a before/after, grounding accuracy is the control — if it moved, the two sides reached different evidence and the comparison is void; rerun.