mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-27 22:15:33 +00:00
docs(skillopt): hands-on tutorial for auto-improving a skill + discoverability
There was no tutorial for skillopt — only a reference guide
(docs/guides/skillopt.md) that opens at --bootstrap-from-routing and
assumes you already understand benchmarks, and an agent-facing SKILL.md.
README had ZERO skillopt mention. The one thing a user must hand-author
(the benchmark JSONL) was taught nowhere with a worked example.
New: docs/tutorials/improving-skills-with-skillopt.md — Diataxis tutorial
(learning-oriented), copy-pasteable end to end:
1. mental model in two sentences (SKILL.md is the trainable param, the
agent is frozen)
2. write your first benchmark from scratch — a complete 15-task rule-judge
starter you paste and run, with the full check-op table
(contains/regex/section_present/max_chars/min_citations/tool_called/
tool_not_called)
3. --dry-run cost preview (and that it exits 2 by convention, not failure)
4. real run + reading accepted(0)/no_improvement(1)/aborted(2) with the
actual stderr output shape
5. where output lands (best.md, versions/, history.json, rejected.json,
audit jsonl)
6. accept/reject — bundled vs user skills, --no-mutate vs
--allow-mutate-bundled
7. iterate by sharpening the benchmark
The load-bearing fix the tutorial makes that the reference guide got wrong:
the DEFAULT --split 4:1:5 needs ~50 tasks before it runs (sel = N/10, floor
5). A first-time author writing 10-15 tasks hits `D_sel has N task(s)
(need >=5)` and bounces. The tutorial ships 15 tasks + `--split 1:1:1`
(clean 5/5/5) so the copy-paste path actually works. Verified against the
real loadBenchmark + splitBench: the exact shipped block parses 15 unique
tasks and splits 5/5/5 with sel>=5; the system's own error message confirms
"need ~50 total for 4:1:5".
Discoverability (Diataxis cross-linking):
- README.md tutorials section: new entry (was zero skillopt mention)
- docs/tutorials/README.md: added under ## Shipped
- docs/guides/skillopt.md: "New to this? Start with the tutorial" callout
Every claim devex-verified against source: exit-code map from
skillopt.ts (accepted:0/no_improvement:1/aborted:2/errored:2), stderr
format from skillopt.ts:286-292, check ops from score.ts, output paths
from SKILL.md, split math from benchmark.ts.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
c807fbe91b
commit
c39dbdb1ec
@@ -208,6 +208,7 @@ Step-by-step walkthroughs for getting the most out of GBrain. Each one takes you
|
|||||||
|
|
||||||
- [**Set up your personal AI agent + brain from zero**](docs/tutorials/personal-brain.md) — the canonical full-stack install. Two GitHub repos, a Telegram bot, AlphaClaw on Render, OpenClaw + GBrain + Supabase. End-to-end in about 2 hours.
|
- [**Set up your personal AI agent + brain from zero**](docs/tutorials/personal-brain.md) — the canonical full-stack install. Two GitHub repos, a Telegram bot, AlphaClaw on Render, OpenClaw + GBrain + Supabase. End-to-end in about 2 hours.
|
||||||
- [**Set up GBrain as your company brain**](docs/tutorials/company-brain.md) — federated, multi-user, OAuth-scoped institutional memory for a 10-50 person team. About 90 minutes end-to-end.
|
- [**Set up GBrain as your company brain**](docs/tutorials/company-brain.md) — federated, multi-user, OAuth-scoped institutional memory for a 10-50 person team. About 90 minutes end-to-end.
|
||||||
|
- [**Auto-improve a skill with `gbrain skillopt`**](docs/tutorials/improving-skills-with-skillopt.md) — treat a `SKILL.md` as a trainable parameter. Write a benchmark of realistic tasks, watch the optimizer propose edits and keep only the ones that measurably score higher. ~20 minutes, ~$1 in API calls. Flag + cost + safety reference: [`docs/guides/skillopt.md`](docs/guides/skillopt.md).
|
||||||
|
|
||||||
More walkthroughs in progress: connecting an existing agent (Claude Code, Cursor, OpenClaw, Hermes) to a GBrain memory layer; setting up GBrain for VC dealflow with founder scorecards and meeting prep; migrating an existing Notion or Obsidian vault; indexing a codebase as a queryable code brain. Full tutorial index: [`docs/tutorials/`](docs/tutorials/).
|
More walkthroughs in progress: connecting an existing agent (Claude Code, Cursor, OpenClaw, Hermes) to a GBrain memory layer; setting up GBrain for VC dealflow with founder scorecards and meeting prep; migrating an existing Notion or Obsidian vault; indexing a codebase as a queryable code brain. Full tutorial index: [`docs/tutorials/`](docs/tutorials/).
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,12 @@ that measurably improve the score.
|
|||||||
Based on [SkillOpt](https://arxiv.org/abs/2605.23904) (Microsoft Research,
|
Based on [SkillOpt](https://arxiv.org/abs/2605.23904) (Microsoft Research,
|
||||||
May 2026).
|
May 2026).
|
||||||
|
|
||||||
|
> **New to this?** Start with the hands-on tutorial:
|
||||||
|
> [Auto-improve a skill with `gbrain skillopt`](../tutorials/improving-skills-with-skillopt.md).
|
||||||
|
> It walks you from "I have a skill" to "I accepted a measurably better version"
|
||||||
|
> in ~20 minutes, including how to write your first benchmark. This page is the
|
||||||
|
> reference — flags, exit codes, cost model, safety guards.
|
||||||
|
|
||||||
## The 30-second pitch
|
## The 30-second pitch
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ Step-by-step walkthroughs that take you from zero to a working outcome. Concrete
|
|||||||
|
|
||||||
- [**Set up your personal AI agent + brain from zero**](personal-brain.md) — the canonical solo install. Two GitHub repos, a Telegram bot, AlphaClaw on Render, OpenClaw + GBrain + Supabase. End-to-end in about 2 hours; about $100 to $150 a month sustained. The full-stack install I'd run today.
|
- [**Set up your personal AI agent + brain from zero**](personal-brain.md) — the canonical solo install. Two GitHub repos, a Telegram bot, AlphaClaw on Render, OpenClaw + GBrain + Supabase. End-to-end in about 2 hours; about $100 to $150 a month sustained. The full-stack install I'd run today.
|
||||||
- [**Set up GBrain as your company brain**](company-brain.md) — federated, multi-user, OAuth-scoped institutional memory for a 10-50 person team. Three sources (shared / customers / internal-only), per-user scope, first synthesized query as a teammate. About 90 minutes end-to-end, about $5 in API calls for the demo, under $100 a month sustained for a 25-person company.
|
- [**Set up GBrain as your company brain**](company-brain.md) — federated, multi-user, OAuth-scoped institutional memory for a 10-50 person team. Three sources (shared / customers / internal-only), per-user scope, first synthesized query as a teammate. About 90 minutes end-to-end, about $5 in API calls for the demo, under $100 a month sustained for a 25-person company.
|
||||||
|
- [**Auto-improve a skill with `gbrain skillopt`**](improving-skills-with-skillopt.md) — treat a `SKILL.md` as the trainable parameter of a frozen agent. Write your first benchmark from scratch (the part everyone gets stuck on), preview the cost, run the optimizer, read accepted vs no_improvement vs aborted, and accept a measurably better skill. About 20 minutes, about $1 in API calls. Reference: [`../guides/skillopt.md`](../guides/skillopt.md).
|
||||||
|
|
||||||
## In progress
|
## In progress
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,250 @@
|
|||||||
|
# Auto-improve a skill with `gbrain skillopt`
|
||||||
|
|
||||||
|
You have a `SKILL.md`. Sometimes the agent following it does a great job, sometimes
|
||||||
|
it forgets a step or pads the output. This tutorial takes you from that skill to a
|
||||||
|
measurably better version of it, in one session, without you hand-editing the
|
||||||
|
prose. By the end you'll have written your first benchmark, watched the optimizer
|
||||||
|
propose and test edits, and accepted an improvement that actually scored higher.
|
||||||
|
|
||||||
|
Time: ~20 minutes. Cost: ~$1 in API calls for the worked example.
|
||||||
|
|
||||||
|
Based on [SkillOpt](https://arxiv.org/abs/2605.23904) (Microsoft Research, May 2026).
|
||||||
|
|
||||||
|
## The mental model (two sentences)
|
||||||
|
|
||||||
|
Your `SKILL.md` is the trainable parameter; the agent that reads it never changes.
|
||||||
|
SkillOpt runs the agent against a benchmark of realistic tasks, proposes specific
|
||||||
|
edits to the skill body, re-tests, and keeps a change **only when it measurably
|
||||||
|
beats the current version** on a held-out slice.
|
||||||
|
|
||||||
|
That's the whole idea. The benchmark is how "better" gets defined — which is why
|
||||||
|
writing it is the one part you can't skip. Everything else is mechanical.
|
||||||
|
|
||||||
|
## What you'll need
|
||||||
|
|
||||||
|
- `gbrain` installed and a brain initialized (`gbrain --version` works).
|
||||||
|
- One embedding/chat provider configured. SkillOpt makes real LLM calls.
|
||||||
|
`gbrain models doctor` should show at least one reachable chat model.
|
||||||
|
- A skill you want to improve, living at `skills/<name>/SKILL.md`. This tutorial
|
||||||
|
uses a skill called `meeting-prep` — substitute your own name everywhere.
|
||||||
|
- A clean git working tree for that skill file (SkillOpt refuses to run over
|
||||||
|
uncommitted changes so it can never clobber your edits; `--force` overrides).
|
||||||
|
|
||||||
|
If you don't have a skill yet, scaffold one first:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gbrain skillify scaffold meeting-prep
|
||||||
|
```
|
||||||
|
|
||||||
|
## Step 1: Write your first benchmark
|
||||||
|
|
||||||
|
This is the crux. A benchmark is a `.jsonl` file — **one JSON object per line** —
|
||||||
|
where each line is a task plus a way to score the agent's answer.
|
||||||
|
|
||||||
|
Paste this complete 15-task starter so the rest of the tutorial runs verbatim.
|
||||||
|
It's deliberately generic — once you've seen the loop work, **replace these tasks
|
||||||
|
with your skill's real cases** (that's Step 6):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat > skills/meeting-prep/skillopt-benchmark.jsonl <<'EOF'
|
||||||
|
{"task_id":"mp-001","task":"Prep me for a 1:1 with a direct report I haven't met with in 3 weeks.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"agenda"},{"op":"contains","arg":"follow-up"}]}}
|
||||||
|
{"task_id":"mp-002","task":"Prep me for a first sales call with a company I know nothing about.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"company"},{"op":"min_citations","arg":1}]}}
|
||||||
|
{"task_id":"mp-003","task":"Prep me for a board meeting where I present the quarterly numbers.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"metric"}]}}
|
||||||
|
{"task_id":"mp-004","task":"Prep me for a performance review I'm giving to an underperformer.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"example"}]}}
|
||||||
|
{"task_id":"mp-005","task":"Prep me for a candidate interview for a senior backend role.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"question"}]}}
|
||||||
|
{"task_id":"mp-006","task":"Prep me for a vendor renewal negotiation where I want a discount.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"leverage"}]}}
|
||||||
|
{"task_id":"mp-007","task":"Prep me for a kickoff with a new cross-functional project team.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"goal"},{"op":"contains","arg":"owner"}]}}
|
||||||
|
{"task_id":"mp-008","task":"Prep me for a difficult conversation about a missed deadline.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"impact"}]}}
|
||||||
|
{"task_id":"mp-009","task":"Prep me for an investor update call after a flat quarter.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"metric"},{"op":"min_citations","arg":1}]}}
|
||||||
|
{"task_id":"mp-010","task":"Prep me for a skip-level with someone two reports below me.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"question"}]}}
|
||||||
|
{"task_id":"mp-011","task":"Prep me for a customer escalation call after an outage.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"timeline"}]}}
|
||||||
|
{"task_id":"mp-012","task":"Prep me for a partnership exploration call with a competitor-adjacent company.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"company"},{"op":"min_citations","arg":1}]}}
|
||||||
|
{"task_id":"mp-013","task":"Prep me for a sprint retro where morale has been low.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"action"}]}}
|
||||||
|
{"task_id":"mp-014","task":"Prep me for a salary negotiation a report initiated.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"market"}]}}
|
||||||
|
{"task_id":"mp-015","task":"Prep me for an all-hands where I announce a reorg.","judge":{"kind":"rule","checks":[{"op":"max_chars","arg":1800},{"op":"contains","arg":"why"}]}}
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
Each line has three fields:
|
||||||
|
|
||||||
|
- `task_id` — a unique label. Anything; you'll see it in the audit trail.
|
||||||
|
- `task` — the prompt the agent gets, exactly as a user would phrase it.
|
||||||
|
- `judge` — how the answer is scored. `kind: "rule"` is deterministic and **free**
|
||||||
|
(no LLM call): it runs a list of `checks`, and the task's score is the fraction
|
||||||
|
that pass.
|
||||||
|
|
||||||
|
The rule checks you can use:
|
||||||
|
|
||||||
|
| `op` | `arg` | Passes when the agent's answer… |
|
||||||
|
|---|---|---|
|
||||||
|
| `contains` | string | includes that substring |
|
||||||
|
| `regex` | string | matches that regex (multiline) |
|
||||||
|
| `section_present` | heading text | has a markdown heading with that text |
|
||||||
|
| `max_chars` | number | is at most that many characters (punishes padding) |
|
||||||
|
| `min_citations` | number | has at least N citations (markdown links, `wiki/…` refs, `[1]` footnotes) |
|
||||||
|
| `tool_called` | tool name | the agent called that tool during the rollout |
|
||||||
|
| `tool_not_called` | tool name | the agent did NOT call that tool |
|
||||||
|
|
||||||
|
Rule judges are the right place to start. They're free, deterministic, and they
|
||||||
|
force you to say concretely what a good answer looks like. (`judge.kind` can also
|
||||||
|
be `"llm"` with a rubric, or `"qrels"` for retrieval tasks — see the
|
||||||
|
[reference guide](../guides/skillopt.md) once you outgrow rules.)
|
||||||
|
|
||||||
|
### The one gotcha: how many tasks you need
|
||||||
|
|
||||||
|
SkillOpt splits your benchmark three ways — **train** (propose edits against),
|
||||||
|
**sel** (the held-out gate that decides accept/reject), and **test** (final
|
||||||
|
score). The sel slice must have **at least 5 tasks** or the run refuses, so noise
|
||||||
|
can't masquerade as improvement.
|
||||||
|
|
||||||
|
The default split is `4:1:5`, which means sel is 1/10th of your tasks — so the
|
||||||
|
default needs **~50 tasks** before it'll run. That's too many for a first
|
||||||
|
benchmark, which is why every command below passes `--split 1:1:1`: with the
|
||||||
|
15-task starter that's a clean **5 train / 5 sel / 5 test**, and sel hits the
|
||||||
|
floor exactly.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 15 tasks + --split 1:1:1 → 5 train / 5 sel / 5 test
|
||||||
|
gbrain skillopt meeting-prep --split 1:1:1
|
||||||
|
```
|
||||||
|
|
||||||
|
If you ever see `D_sel has N task(s) after split (need >=5)`, you either added
|
||||||
|
fewer than 15 tasks or used a split whose middle number is too small a share.
|
||||||
|
`--split 1:1:1` on 15+ tasks is the simplest thing that works.
|
||||||
|
|
||||||
|
> When you swap in your own tasks (Step 6), keep at least 15 and cover the boring
|
||||||
|
> middle, not just the edge cases. The benchmark IS your definition of quality;
|
||||||
|
> a thin benchmark optimizes for a thin definition.
|
||||||
|
|
||||||
|
## Step 2: Preview the cost (dry run)
|
||||||
|
|
||||||
|
Before spending anything, see what the run will cost:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gbrain skillopt meeting-prep --split 1:1:1 --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
This makes **zero LLM calls** — it just prints the plan and the cost estimate.
|
||||||
|
A ~15-task benchmark with defaults runs around $0.70–$1.00. The preflight refuses
|
||||||
|
to start a real run whose estimate exceeds `--max-cost-usd` (default $5.00), so
|
||||||
|
you can't get surprise-billed mid-run.
|
||||||
|
|
||||||
|
> `--dry-run` exits with code **2** ("aborted"). That's the convention for "did
|
||||||
|
> not run the optimization," not a failure. The cost line is what you came for.
|
||||||
|
|
||||||
|
## Step 3: Run it for real
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gbrain skillopt meeting-prep --split 1:1:1
|
||||||
|
```
|
||||||
|
|
||||||
|
You'll watch it work: a baseline eval to set the bar, then per-step forward passes
|
||||||
|
(run the skill), backward passes (propose edits), and a validation gate that
|
||||||
|
runs each sel task's judge 3 times and takes the median — accepting only if the
|
||||||
|
median beats the current best by more than 0.05.
|
||||||
|
|
||||||
|
When it finishes, the last lines tell you everything:
|
||||||
|
|
||||||
|
```
|
||||||
|
[skillopt] Outcome: accepted
|
||||||
|
[skillopt] Best sel-score: 0.840
|
||||||
|
[skillopt] Final cost: $0.71
|
||||||
|
[skillopt] SKILL.md rewritten with 6 optimization steps.
|
||||||
|
```
|
||||||
|
|
||||||
|
### Reading the outcome
|
||||||
|
|
||||||
|
| Outcome | Exit code | What it means | What to do |
|
||||||
|
|---|---|---|---|
|
||||||
|
| `accepted` | 0 | A candidate beat the baseline. SKILL.md was rewritten (or a proposed file written — see Step 5). | Review the diff, keep it. |
|
||||||
|
| `no_improvement` | 1 | Nothing cleared the gate. Your skill is already good, or the benchmark can't tell good from bad. | Strengthen the benchmark (Step 6) or stop. |
|
||||||
|
| `aborted` | 2 | A gate stopped it: dirty working tree, over budget, `D_sel < 5`, or `--dry-run`. | Read the message — it names the gate. |
|
||||||
|
|
||||||
|
`no_improvement` is not a failure. It's the gate doing its job: it would rather
|
||||||
|
keep your known-good skill than accept a change it can't prove is better.
|
||||||
|
|
||||||
|
## Step 4: See what changed
|
||||||
|
|
||||||
|
The optimizer leaves a full audit trail under the skill:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls skills/meeting-prep/skillopt/
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
best.md ← the current winning version (== SKILL.md when accepted)
|
||||||
|
versions/
|
||||||
|
v0001_e1_s1.md ← every step's candidate, so you can diff any of them
|
||||||
|
v0002_e1_s2.md
|
||||||
|
...
|
||||||
|
history.json ← append-only record of every accept/reject + scores
|
||||||
|
rejected.json ← edits that were tried and didn't help (so it won't retry them)
|
||||||
|
```
|
||||||
|
|
||||||
|
The actual change to your skill is a normal git diff:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git diff skills/meeting-prep/SKILL.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Run-level events (cost, model, scores per run) also land in the rotating audit
|
||||||
|
log at `~/.gbrain/audit/skillopt-YYYY-Www.jsonl`.
|
||||||
|
|
||||||
|
## Step 5: Accept or reject — and the bundled-skill rule
|
||||||
|
|
||||||
|
**For a skill you own** (your own `skills/` dir): an `accepted` run rewrites
|
||||||
|
`SKILL.md` in place. It's already a git diff — review it, then `git commit` to
|
||||||
|
keep it or `git checkout` to throw it away. Nothing is committed for you.
|
||||||
|
|
||||||
|
**For a skill that ships with gbrain** (anything under the gbrain repo's own
|
||||||
|
`skills/`): SkillOpt refuses to overwrite it by default and writes the winner to
|
||||||
|
`skills/<name>/skillopt/best.md` instead, so an optimization pass can never
|
||||||
|
silently mutate a skill other people depend on. Two ways to handle that:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See the proposed improvement without touching SKILL.md (works for ANY skill):
|
||||||
|
gbrain skillopt meeting-prep --split 1:1:1 --no-mutate
|
||||||
|
# → writes skills/meeting-prep/skillopt/best.md, prints its path. Copy what you want.
|
||||||
|
|
||||||
|
# Actually rewrite a bundled skill (explicit opt-in):
|
||||||
|
gbrain skillopt brain-ops --split 1:1:1 --allow-mutate-bundled
|
||||||
|
```
|
||||||
|
|
||||||
|
Rule of thumb: `--no-mutate` when you want to read the diff before trusting it;
|
||||||
|
`--allow-mutate-bundled` only when you intend to commit a change to a shared skill.
|
||||||
|
|
||||||
|
## Step 6: Iterate
|
||||||
|
|
||||||
|
The loop that actually makes skills better:
|
||||||
|
|
||||||
|
1. Run it. If `no_improvement`, the benchmark probably can't distinguish good
|
||||||
|
from bad yet.
|
||||||
|
2. Add tasks that capture what you wish the skill did differently. Saw the agent
|
||||||
|
skip citations? Add `{"op":"min_citations","arg":2}`. Saw it ramble? Tighten
|
||||||
|
`max_chars`.
|
||||||
|
3. Re-run. A sharper benchmark gives the optimizer a real gradient to climb.
|
||||||
|
4. When a run lands `accepted`, read the diff, commit it, and bank the win.
|
||||||
|
|
||||||
|
The skill you ship gets better every time the benchmark gets sharper. That's the
|
||||||
|
whole game: you're not editing prose, you're improving the definition of done and
|
||||||
|
letting the optimizer chase it.
|
||||||
|
|
||||||
|
## What you built
|
||||||
|
|
||||||
|
You wrote a benchmark that encodes what "good" means for one skill, previewed the
|
||||||
|
cost, ran the optimizer, and either accepted a measurably better skill or learned
|
||||||
|
your benchmark needs sharpening. Same loop scales to every skill you own — and
|
||||||
|
`gbrain skillopt --all` runs it across every skill that has a benchmark, under a
|
||||||
|
brain-wide cost cap.
|
||||||
|
|
||||||
|
## Where to go next
|
||||||
|
|
||||||
|
- **Full flag + exit-code reference, cost model, safety guards:**
|
||||||
|
[`docs/guides/skillopt.md`](../guides/skillopt.md)
|
||||||
|
- **Every flag inline:** `gbrain skillopt --help`
|
||||||
|
- **Batch + fleet + background runs** (`--all`, `--target-models`, `--background`),
|
||||||
|
**LLM and qrels judges**, **held-out test sets**, and **resume after a crash**
|
||||||
|
(`--resume <run-id>`): all in the reference guide above.
|
||||||
|
- **Bootstrap a benchmark from existing routing fixtures** instead of hand-writing
|
||||||
|
it: `gbrain skillopt <name> --bootstrap-from-routing` (then review + delete the
|
||||||
|
sentinel + re-run with `--bootstrap-reviewed`).
|
||||||
Reference in New Issue
Block a user