Commit 5d7d7b1
committed
feat(kpi): a third query set — chat-shaped questions
`npm run kpi:questions`, and `kpi:search` now runs it too, so every future ranker change
is judged on all three sets rather than the two that happened to exist.
WHY IT HAD TO EXIST. The other two cover two query SHAPES and neither contains a single
question word: natural is Google-autocomplete keywords (2-5 words), artificial is
identifiers generated from the index. A whole spoken question is neither — and it is
what a developer types at an assistant, so it is what an assistant sends to search_docs.
That blindness had a measured cost. Moving @imqueue/mcp onto this ranker took recall@6
on the agent-shaped slice from 83.9% to 99.5% and left natural unmoved, while on
chat-shaped questions it scored 65.8% against the 73.3% of the ranker it replaced. Two
sets said "big win, no regression"; the truth was a transfer. It surfaced only because
the MCP server's smoke test happens to hard-code two such questions.
BASELINE, and it is not flattering: micro accuracy 64.1%, macro 61.1%, recall@6 66.1%
micro / 62.9% macro, and 19.1% of questions never found at all inside 50 results.
The weakest topics all point one way — every one is answered by an API symbol page,
which has no question-shaped text to compete with:
hardening 0.0% service definition 20.0%
caching 22.5% postgres 25.0%
observability 28.0%
The mechanism, already diagnosed: a long question is mostly words the corpus shares
(how, do, I, a, service, imqueue), so the ONE discriminating word has to carry it, and
when it does not, records whose headings are themselves questions win on the question
TEMPLATE. rpc.expose scores 1020 at #1 for `expose`, 258 at #9 for "expose a method on
a service", and 88 at #108 for "How do I expose a method on an @imqueue service?".
THIS IS LIVE ON IMQUEUE.ORG — the website and the MCP server share the ranker.
WHY THE LABELS CAN BE TRUSTED, which is the hard part of any generated set:
* written from the PAGE INVENTORY, never from a ranker's output — the rule
judge-natural.js states, because a label taken from what the ranker returned would
agree with the ranker by construction;
* VALIDATED: every `expect` URL must exist in the built index or questions.js exits 1.
Verified by breaking one. A renamed page is then a loud error instead of a permanent
zero that reads exactly like a ranking regression;
* COMMITTED, unlike artificial-queries.json — that set is reproducible from the index
plus a fixed seed, so committing it would duplicate its input. An assistant's
phrasings are not reproducible from anything, so the file IS the record;
* MACRO-AVERAGED over 18 topics, because `cli` alone has 16 queries and one area must
not be able to carry the score;
* no query reuses its target's title verbatim — that is the exact-match case and the
artificial set already owns it.
`--ref <commit>` reads a past ranker out of the submodule's history and prints the
per-query moves, not just the aggregate: 0 better / 0 worse / 115 unchanged against the
pinned commit, which is the check that the comparison path works at all.
Known limit, stated in the data file and the README: the harness scores `!hit.external`,
so a question answered on imqueue.com cannot score here and none are included. The
commercial half stays with check-search-ranking.js — three named queries that must reach
the commercial edition, which is the right shape for that risk rather than an average.1 parent 9586396 commit 5d7d7b1
4 files changed
Lines changed: 1219 additions & 8 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
40 | | - | |
| 40 | + | |
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
| 75 | + | |
| 76 | + | |
76 | 77 | | |
77 | 78 | | |
78 | 79 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
41 | 46 | | |
42 | 47 | | |
43 | 48 | | |
44 | 49 | | |
45 | 50 | | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
46 | 87 | | |
47 | 88 | | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
53 | 110 | | |
54 | 111 | | |
55 | 112 | | |
| |||
0 commit comments