2.7 KiB
12. Remove n-gram clustering from pipeline
Date: 2026-07-04
Status: Accepted
Context
The pipeline grouped method sequences by shared n-gram call patterns before inference. The idea: methods in the same category (test, config, helper) would cluster together, and each cluster would get a cleaner, more specific grammar.
What Was Removed
cluster_methods()— built n-gram→method index from call tokens, assigned methods to shared-pattern clusters, dumped remainder to(other).cluster_methods_adaptive()— retried clustering at ngram=2 then ngram=1 when(other)exceeded 60% of methods._extract_call_tokens()import fromcode.py(still incode.pybut no longer called by the pipeline).--min-cluster-sizeand--ngram-sizeCLI flags.clusterparameter inanalyze_directory().- Per-cluster loop in
analyze_clusters()— metadata extraction (files, imports, arg patterns) now runs once across all methods.
Why Removed
-
No benefit for diverse codebases. On Kotlin SpringRAG (1581 methods), 21 named clusters formed (3-13 methods each) but 1254 landed in
(other). The named clusters were too small to produce better grammars than running inference once on the filtered set. -
Added complexity for zero signal gain. The n-gram labels (e.g.
locator → click → waitForTimeout) restated what CRX already outputs as(locator+click+waitForTimeout)+.per-cluster infer_ensemble call was redundant with the single-pass result. -
Slower. 22 extra BEX calls (one per named cluster) for grammars that would appear in the single-pass result anyway.
Pipeline After Removal
preprocess_by_method → frequency_filter(0.2) → infer_ensemble(0.8)
Single pass. Metadata extracted once.
How to Reintroduce
The removed code is preserved in the archive branch:
git archive/unreverted-25898c2
Files:
bex/tag_preprocessor/analyze.pycontainscluster_methods(),cluster_methods_adaptive(), and the per-cluster loop body.
To restore:
- Cherry-pick or copy the two function definitions.
- Re-add
_extract_call_tokensto the import fromcode.py. - Re-add the
--min-cluster-sizeand--ngram-sizeCLI flags. - Change
analyze_clusters()back to: cluster → per-cluster filter → per-cluster infer. - Restore the cluster parameter in
analyze_directory().
Performance Impact
| Metric | Before (with clustering) | After (single pass) |
|---|---|---|
| Pipeline time (460 .kt files) | ~42s | ~3s |
| Inference time per cluster | ~22s on (other) | ~0.1s total |
| Named clusters | 21 tiny + (other) | 1 group |
| Grammar quality | same assertEquals+ |
same assertEquals+ |