Skip to content

test(memory): a recall benchmark with a lexical baseline - #299

Merged
yusiwen merged 1 commit into
masterfrom
test/memory-bench
Oct 26, 2026
Merged

yusiwen merged 1 commit into
masterfrom
test/memory-bench

Conversation

@yusiwen

@yusiwen yusiwen commented Oct 26, 2026

Copy link
Copy Markdown
Owner

What changed

  • agent/testdata/memory-bench.json (new): 24 fixed facts and 20 queries in three groups — 10 that
    share a distinctive word with their fact, 6 English paraphrases that share none, 4 Chinese queries
    against English facts.
  • agent/memory_bench_test.go (new): the harness. Ranks at depth 10, reports hit@1/3/5 and MRR per
    group, and asserts what can be asserted deterministically — corpus hygiene (a paraphrase query must
    share no token with its target, or the lexical ranker could answer it), the local ranker's top-3
    floor, the metric arithmetic, and the counts the page quotes.
  • TestMemoryBenchRealEndpoint: gated on TINYCODE_MEMORY_BENCH_URL / _MODEL; embeds the corpus
    against a real endpoint, refuses to report if any fact failed to embed, and prints the same table for
    the semantic and lexical rankers.
  • make memory-bench with MEMORY_BENCH_* pass-through, documented in the target's comment.
  • docs/memory-bench.md (new): the corpus, the columns, the deterministic baseline, how to run, how to
    read (compare within a model; the cross-lingual column is a model property), and the explicit note
    that no semantic number is recorded yet.
  • Links: README's memory bullet and roadmap B3's Delivered note point at the instrument.
  • Test count 1224 → 1228 in the two places that state it.

Why

B3's PR said, in its own honest-scope section, that recall quality was unmeasured. "Semantic beats
lexical" is a claim; the next decision in this area — consolidation, quantisation, a cross-encoder, a
different model — should be made against a number. The benchmark is also the reason the claim stays
honest: the page carries the lexical baseline (deterministic, reproduced by CI) and an empty cell where
a model's numbers would go, rather than a sentence that implies one.

Verification

  • go test ./... -count=1 and -race: 16 packages ok; go vet and gofmt -l clean.
  • Baseline printed by the harness (deterministic, so exact):
    MEMBENCH ranker=lexical kind=lexical n=10 hit1=1.00 hit3=1.00 hit5=1.00 mrr=1.00,
    kind=paraphrase n=6 hit1=0.00 …, kind=crosslingual n=4 hit1=0.00 ….
  • Mutation check: the paraphrase query how do I cut a version changed to how do I cut a release version → TestMemoryBenchCorpusIsWellFormed fails with shares [release]; restored, it passes.
  • make memory-bench with no endpoint → --- SKIP: TestMemoryBenchRealEndpoint and exit 0, so an
    ordinary run never needs a model.
  • git log --format='%h %G? %s' → G.

Honest scope

  • The semantic column is not measured. No embedding endpoint was configured here; the doc says so
    in the section where the numbers would go.
  • The corpus is one person's idea of what a repository's memory looks like, 24 facts deep. It is a
    regression instrument, not a model evaluation.
  • The gated run needs a human with a model; CI only proves the harness, the hygiene rule and the
    lexical floor.

Follow-ups

Refs #297, #168

B3 shipped semantic recall and said its quality was unmeasured. This is the
instrument: 24 fixed facts, 20 queries in three groups (10 sharing a word with
their fact, 6 paraphrases that share none, 4 cross-lingual), ranked at depth 10
and reported as hit@1/3/5 and MRR per group.

What makes it a gate rather than a report:

- the corpus's hygiene is asserted: a paraphrase or cross-lingual query that
  shares a token with its target would let the lexical ranker answer it, and the
  column would stop meaning what it says;
- the local ranker's floor is asserted: every lexical query finds its fact in the
  top three — deterministic, so it cannot flake;
- the metrics are unit-tested on rankings with a known answer, so a wrong hit@k
  cannot look like a result;
- the counts the page quotes (24 facts, 20 queries, 10/6/4) are asserted, so
  docs/memory-bench.md cannot drift from the corpus.

The measured half is gated behind TINYCODE_MEMORY_BENCH_URL/_MODEL and
`make memory-bench`: it embeds the corpus against a real endpoint, refuses to
report if any fact failed to embed (a silent fallback would print lexical numbers
under a semantic heading), and prints the same table for both rankers. CI has no
model, so the page records the semantic numbers as not measured yet rather than
pretending; the deterministic baseline is 1.00/0.00/0.00 at hit@1.

Verified: go test ./... -count=1 and -race, 16 packages ok; go vet and gofmt
clean; the hygiene gate mutation-checked (a paraphrase query given a shared word
fails it, and passes when restored); `make memory-bench` without an endpoint
skips with its reason and exits 0.

Refs #297, #168
@yusiwen yusiwen added the tests Test coverage and test infrastructure label Oct 26, 2026
@yusiwen
yusiwen merged commit cd4cfbd into master Oct 26, 2026
9 checks passed
@yusiwen
yusiwen deleted the test/memory-bench branch October 26, 2026 09:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Test coverage and test infrastructure

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant