add-bench-scenario
Use when adding a new scenario to remindb's benchmark suite — symptoms include "compare X tool against grep/cat", "add a token-savings benchmark for Y", "extend `internal/bench/scenarios.go`", "wire a new scenario into `bench.Run`", or any task that adds a row to the `scenario / naive (tok) / remindb (tok) / saved` output table. Distinct from Go `testing.B` benchmarks in `*_bench_test.go`.
pinned to #977b31cupdated 2 weeks ago
Ask your AI client: “install skills/add-bench-scenario”.
Requires the metahub MCP server installed in your client. Set up MCP.
mh install skills/add-bench-scenariometahub onboarded this repo on the author's behalf.
If you own github.com/radimsem/remindb on GitHub, claim the listing to take over publishing. Your claim preserves the existing eval history and badges; only the curator label is replaced with verified-publisher on your next publish.
Stars
121
Last commit
2 weeks ago
Latest release
published
- #agent-memory
- #ai-agents
- #ast
- #claude-code
- #cli
- #codex
- #developer-tools
- #fts5
- #gemini-cli
- #golang
- #knowledge-base
- #llm-tool
- #mcp
- #mcp-server
- #model-context-protocol
- #openclaw
- #opencode
- #sqlite
- #token-efficiency
About this skill
Pulled from SKILL.md at publish time.
`internal/bench/` is remindb's external-facing benchmark — it compares "how many tokens does an agent consume to do X via remindb tools" against "how many would they consume doing X with `grep` / `cat` / `find`". The output is a token-savings table rendered via `text/tabwriter`. It's invoked from the `remindb bench` CLI subcommand and exercised end-to-end by `scripts/bench-agents.sh`.
Evaluation report
WarningsAutomated checks the publisher passed at publish time — structure, docs, safety, and whether the artifact behaves as claimed.977b31c· 2 weeks ago
Kind-specific
31Skill: SKILL.md present
found at .claude/skills/add-bench-scenario/SKILL.md · frontmatter source: SKILL.md
Skill: body content present
934 words · 6,444 chars · 8 sections · 4 code blocks
Skill: triggers declaredwarn
No `trigger` phrases in SKILL.md frontmatter
Add `trigger:` lines so Claude knows when to activate this skill — e.g. `when building MCP servers` or `for diagram creation`.
Skill: allowed-tools scope
no allowed-tools restriction (Claude may use anything)
Release history
1- releasecurrent977b31cwarn2 weeks ago
Contents
Add a benchmark scenario
internal/bench/ is remindb's external-facing benchmark — it compares "how many tokens does an agent consume to do X via remindb tools" against "how many would they consume doing X with grep / cat / find". The output is a token-savings table rendered via text/tabwriter. It's invoked from the remindb bench CLI subcommand and exercised end-to-end by scripts/bench-agents.sh.
This is not the Go testing.B benchmark surface — those live as Benchmark* functions inside pkg/*/bench_test.go and have their own discipline.
Where it lands
Two files for a typical scenario, three if it needs CLI flag plumbing.
| File | What changes |
|---|---|
internal/bench/scenarios.go | New benchXxx(ctx, session, srcDir, ...) (scenarioResult, error) function |
internal/bench/bench.go | Wire the new scenario into Run, append to results |
cmd/remindb/... (only if new flag needed) | Surface a new flag on the bench subcommand and pass it into bench.Config |
The scenario function shape
Every scenario implements the same contract: produce one (or more) scenarioResult{name, naiveTok, remindbTok} by measuring two paths to the same answer — the naive path (token count of what an agent would have to read using shell tools) and the remindb path (token count of the tool's response).
Mirror benchTree, benchSearch, or benchFetch in scenarios.go:
func benchExample(ctx context.Context, s *gomcp.ClientSession, srcDir string, budget int) (scenarioResult, error) {
// Naive path: what the agent would read using shell tools.
naive := tokens.Estimate(naiveContent(srcDir))
// remindb path: call the tool and count its response.
text, err := callTool(ctx, s, "MemoryExample", map[string]any{
"budget": budget,
})
if err != nil {
return scenarioResult{}, err
}
return scenarioResult{
name: "example",
naiveTok: naive,
remindbTok: tokens.Estimate(text),
}, nil
}
A scenario that runs over multiple inputs (like benchSearch over a query list) returns []scenarioResult instead — one row per input, named with the input as suffix ("search:rate-limit").
Three contracts the function must honor:
- Use
tokens.Estimate(string)for both sides. Apples-to-apples comparison only works if the same tokenizer measures both. - Compare to a believable naive baseline. "What would the agent actually do without remindb?" —
find+cat *for tree (notwc -c),grep+cat <matches>for search (not justgrep). The naive must reflect the real alternative. - Use
callTool(ctx, s, name, args)(the package helper inscenarios.go), not raws.CallTool. It strips the*mcp.CallToolResultboilerplate and returns the text content directly.
Wiring into Run
bench.go:Run calls each scenario in sequence and appends to results. Add your call in the natural sequence — Tree first (orientation), then Search, then Fetch, then Delta, then your scenario:
r, err = benchExample(ctx, session, stage.srcDir, cfg.Budget)
if err != nil {
return err
}
results = append(results, r)
Or for a multi-result scenario:
rs, err := benchExample(ctx, session, stage.srcDir, cfg.Budget)
if err != nil {
return err
}
results = append(results, rs...)
The renderer handles the rest — the table column count and total-row computation are static.
Naming rows
The name field becomes the leftmost column. Use lowercase, hyphenated, prefixed by the tool category if the scenario family has multiple rows:
tree(single)search:rate-limit(one of many search queries)fetch(single)delta(single)
Stay under ~30 chars; shorten(s, 30) is the existing helper used by benchSearch.
When to add a new flag
Most scenarios reuse cfg.Budget and cfg.Queries. Add a new field to bench.Config only when the scenario needs an input that isn't already there — and even then, default it sensibly so existing bench-agents.sh runs don't break.
Quick reference
1. internal/bench/scenarios.go (benchXxx function with naive + remindb paths)
2. internal/bench/bench.go (call site in Run, append to results)
3. (optional) cmd/remindb/... (new flag on the bench subcommand)
4. go build ./... && ./remindb bench --db <path> --dir <path>
5. scripts/bench-agents.sh (full suite — confirms the new row appears for every agent)
Common mistakes
- Comparing to a trivial naive baseline. "remindb tree returns 200 tokens, naive
lsreturns 50 tokens — we're 4x worse" misses the point. The naive is what the agent actually does:find . -type f+ reading every file. Use the existing helpers (listDirFiles,countDirTokens,grepDir,sumFileTokens). - Using a different tokenizer for one side. Both sides must go through
tokens.Estimate. Counting bytes, lines, or words on one side breaks the comparison. - Forgetting
tokens.Estimateis over astring, not[]byte. Convert byte slices first; mixing produces a confusing compile error sincetokens.Estimateis overloaded by neither Go nor remindb. - Failing the entire bench on one scenario error. The current contract is fail-fast —
Runreturns the first error. If your scenario has expected partial-failure modes (skipped queries, missing fixtures), handle them inside the scenario and emit ascenarioResult{name: "example:skipped", ...}instead of returning err. - Running benches against the live DB.
stageBenchcopies the DB and source tree to/tmpbefore running so the user's real DB isn't touched. If you reach forcfg.DBPathdirectly inside a scenario, you're operating on the original — passstage.dbPathinstead. - Not updating
bench-agents.shquery lists. New scenarios that take per-agent inputs won't be exercised by the CI-style script unless the per-agent map gets entries. For non-input scenarios (like a new fetch variant), no script change is needed.
Cross-references
.claude/rules/go-concise.md— error wrapping, named locals (naive,remindbTok).claude/skills/add-mcp-tool/SKILL.md— when adding a tool that should be benchmarked, do that skill first; the bench scenario consumes the tool you wiredinternal/bench/render.go— the table renderer; rarely needs changes but read it once if you're adding a column rather than a row
Reviews
No reviews yet. Be the first.
Related
orchestration-patterns
>
migration-patterns
>
deployment-sop
>
mh install skills/add-bench-scenario