fix(lexicon): a phrase must contribute beyond its component words - #47
Closed
elecnix wants to merge 1 commit into
Closed
fix(lexicon): a phrase must contribute beyond its component words#47elecnix wants to merge 1 commit into
elecnix wants to merge 1 commit into
Conversation
Running the full corpus exposed a regression I introduced with phrase support.
At scale, phrases were 84% of all adjudications (65,792 of 78,437 entries) and
75% of all hits (28,179 against the word lexicon's 9,350) — and they were
overwhelmingly redundant. The most frequent were:
do not x563 is not x475 does not x268 with no x247
context no x289 it still x303 and stop x485
👍 on x285 with 👍 x285
Every one is an ordinary word sitting beside a word that already signals on its
own. `👍 on` is the clearest: 👍 is itself a praise term, so pairing it with
whichever word happened to follow manufactures a second hit each time. Flag rates
tell the same story — words 3.78% (healthy, matching the reference model),
phrases 6.66% on far more entries.
The failure was in validation, not just in code: phrases were checked against a
two-session slice that contained almost no bigrams, so the noise never appeared.
Adjacent words in running prose are simply not idioms, and `laisse tomber` was
drowning in `catch no` and `to dag`.
The rule that separates them is CONTRIBUTION. A phrase earns its place only when
it says something its parts do not. Enforced twice:
* Deterministically, at match time: a phrase hit is dropped when one of its
component words already fired on the same turn. This holds whichever model
judged the phrase, and needs no re-adjudication to take effect.
* In the prompt: a phrase must be a fixed expression whose meaning is not the
sum of its parts AND must carry something its words do not, with the failing
cases named outright and an explicit warning that almost every adjacent pair
is neutral.
`laisse tomber` still fires — neither part is a signal, so nothing suppresses it,
which is exactly the discriminator we want. Tests cover both directions: idioms
survive, redundant pairs do not, and two independent idioms in one turn both land.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
Author
|
Closing unmerged. The suppression rule in this PR cut phrase noise substantially (flag rate 6.66% → 1.65%, hits 28,179 → 1,525), but the phrases that survive are still not idioms: Three attempts — original, prompt tightening, deterministic suppression — and the output is still wrong in kind rather than merely in volume. The premise was flawed: adjacent word pairs in running prose are overwhelmingly not idioms, and per-pair LLM adjudication cannot reliably find the rare real ones among tens of thousands of candidates. Reverting the phrase feature instead. See #40, reopened with the measurements. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #45, which introduced the regression this fixes.
What the full corpus run exposed
At scale, phrases were 84% of all adjudications (65,792 of 78,437 entries) and 75% of all hits (28,179 against the word lexicon's 9,350) — and they were overwhelmingly redundant:
Every one is an ordinary word sitting beside a word that already signals on its own.
👍 onis the clearest: 👍 is itself a praise term, so pairing it with whichever word happened to follow manufactures a second hit each time.Flag rates tell the same story:
The failure was in validation as much as in code. Phrases were checked against a two-session slice containing almost no bigrams, so the noise never appeared. Adjacent words in running prose are simply not idioms —
laisse tomberwas real, but drowning incatch noandto dag.The rule: contribution
A phrase earns its place only when it says something its component words do not. Enforced in two places:
laisse tomberstill fires: neitherlaissenortomberis a signal, so nothing suppresses it. That is exactly the discriminator we want, and it is pinned by test.Versions
frustration-lexicon→ 1.3 (prompt),turn-frustration→ 1.2 (suppression). Existing word verdicts stay valid; only phrases need re-judging.Test plan
npm test— 444 passing. Newtests/component/phrase-redundancy.test.tscovers both directions: idioms survive, redundant pairs are dropped, an idiom and an independent word signal both land in one turn, and two independent idioms both land.node --import tsx test/integration/test-commands.ts— 21 passing.npx tsc --noEmitclean.🤖 Generated with Claude Code