@theseus-whale/dsh-continuity 0.0.0-stage → 4.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +25 -0
- package/PANEL.md +92 -0
- package/README.md +286 -2
- package/RELEASE-NOTES.md +732 -0
- package/bin/bc-acceptance-full.mjs +91 -0
- package/bin/bc-acceptance-tight.mjs +66 -0
- package/bin/bc-acceptance.mjs +22 -0
- package/bin/bc-add-keywords.mjs +21 -0
- package/bin/bc-demo.mjs +47 -0
- package/bin/bc-expand-hint.mjs +179 -0
- package/bin/bc-ingest-index.mjs +35 -0
- package/bin/bc-ingest.mjs +31 -0
- package/bin/bc-label-demo.mjs +18 -0
- package/bin/bc-relabel.mjs +150 -0
- package/bin/bc-sessionize.mjs +59 -0
- package/bin/coref_pipeline.py +47 -0
- package/bin/coref_service.py +57 -0
- package/bin/debug_ckip.py +16 -0
- package/bin/debug_ner_zh.py +18 -0
- package/bin/doctor.mjs +275 -0
- package/bin/en_ner_error_audit.py +33 -0
- package/bin/eval-label-rules.mjs +342 -0
- package/bin/export-turns.py +68 -0
- package/bin/extract-user-paragraph.mjs +14 -0
- package/bin/extraction-composite-smoke.mjs +28 -0
- package/bin/extraction-latency.mjs +58 -0
- package/bin/extraction-user-smoke.mjs +28 -0
- package/bin/extraction_service.py +164 -0
- package/bin/facet-active-experiment.mjs +110 -0
- package/bin/facet-covid.mjs +8 -0
- package/bin/facet-curve.mjs +27 -0
- package/bin/facet-embedding-train.mjs +20 -0
- package/bin/facet-embedding-validate.mjs +83 -0
- package/bin/facet-eval-roleplay.mjs +42 -0
- package/bin/facet-eval.mjs +38 -0
- package/bin/facet-fold.mjs +31 -0
- package/bin/facet-load.mjs +16 -0
- package/bin/facet-mlp-scan.mjs +45 -0
- package/bin/facet-mvp.mjs +34 -0
- package/bin/facet-online-experiments.mjs +78 -0
- package/bin/facet-online-race.mjs +99 -0
- package/bin/facet-online-validate.mjs +51 -0
- package/bin/facet-panel.mjs +22 -0
- package/bin/facet-passage.mjs +41 -0
- package/bin/facet-random-validate.mjs +48 -0
- package/bin/facet-roleplay.mjs +33 -0
- package/bin/facet-scan.mjs +56 -0
- package/bin/facet-segment.mjs +34 -0
- package/bin/facet-train.mjs +19 -0
- package/bin/facet-validate.mjs +103 -0
- package/bin/facet-zeroshot.mjs +14 -0
- package/bin/install-templates.mjs +72 -0
- package/bin/memory-bench.mjs +53 -0
- package/bin/memory-build-summary.mjs +43 -0
- package/bin/memory-build-vector.mjs +31 -0
- package/bin/memory-build.mjs +41 -0
- package/bin/memory-calibration.mjs +70 -0
- package/bin/memory-closed-loop.mjs +119 -0
- package/bin/memory-dry-run.mjs +70 -0
- package/bin/memory-eval.mjs +104 -0
- package/bin/memory-event-alias-test.mjs +89 -0
- package/bin/memory-extraction-bench.mjs +58 -0
- package/bin/memory-load-gate-replay.mjs +137 -0
- package/bin/memory-loop-test.mjs +90 -0
- package/bin/memory-pre-turn-harness.mjs +63 -0
- package/bin/memory-query.mjs +39 -0
- package/bin/memory-replay-hints.mjs +84 -0
- package/bin/memory-scale.mjs +58 -0
- package/bin/memory-scenario-test.mjs +146 -0
- package/bin/memory-user-loop.mjs +95 -0
- package/bin/ner_bench_tiny_zh.py +59 -0
- package/bin/ner_bench_zh.py +60 -0
- package/bin/ner_conll_en.py +139 -0
- package/bin/ner_direct_en.py +123 -0
- package/bin/ner_direct_zh.py +100 -0
- package/bin/ner_pipeline.py +208 -0
- package/bin/noise-selfcheck.mjs +50 -0
- package/bin/pack-integrity.mjs +47 -0
- package/bin/panel-check.mjs +57 -0
- package/bin/plugin-integrity.mjs +74 -0
- package/bin/preview-live.mjs +13 -0
- package/bin/public-install-check.mjs +222 -0
- package/bin/relabel-apply.mjs +272 -0
- package/bin/relabel-dry-run.mjs +381 -0
- package/bin/relik_pipeline.py +39 -0
- package/bin/relik_service.py +52 -0
- package/bin/srl_pipeline.py +55 -0
- package/bin/srl_service.py +68 -0
- package/bin/summary-index.mjs +151 -0
- package/bin/summary-query.mjs +79 -0
- package/bin/vec-check.mjs +27 -0
- package/bin/zh_ner_error_audit.py +36 -0
- package/bin/zh_ner_slot_eval.py +38 -0
- package/client.js +760 -0
- package/cordis.patch.yml +378 -0
- package/docs/API-NOTES.md +1743 -0
- package/docs/ARCHITECTURE.md +355 -0
- package/docs/CACHE.md +253 -0
- package/docs/CONDUCT.md +30 -0
- package/docs/CREATOR-HANDOFF.md +102 -0
- package/docs/EXPERIMENT.md +136 -0
- package/docs/FACET-MVP-REPORT.md +473 -0
- package/docs/GUIDE-0.4.66.md +195 -0
- package/docs/GUIDE.md +127 -0
- package/docs/MECHANISM.md +243 -0
- package/docs/NEW-INSTANCE-HANDOFF.md +219 -0
- package/docs/README.md +37 -0
- package/docs/SESSION-LAYOUT.md +151 -0
- package/docs/history-map.md +249 -0
- package/docs/relabel-migration-wiring.md +366 -0
- package/guides/00-READ-FIRST.md +206 -0
- package/guides/01-INSTALL.md +207 -0
- package/guides/02-TABLES.md +225 -0
- package/guides/03-AUDIT.md +201 -0
- package/guides/04-REBUILD.md +306 -0
- package/guides/05-FIRST-RUN.md +191 -0
- package/guides/06-EMBEDDING.md +146 -0
- package/guides/07-PTC-AND-ASSETS.md +221 -0
- package/icon.svg +7 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/models/README.md +13 -0
- package/models/Xenova/bge-small-zh-v1.5/config.json +31 -0
- package/models/Xenova/bge-small-zh-v1.5/onnx/model_quantized.onnx +0 -0
- package/models/Xenova/bge-small-zh-v1.5/tokenizer.json +21278 -0
- package/models/Xenova/bge-small-zh-v1.5/tokenizer_config.json +15 -0
- package/package.json +139 -4
- package/src/asset-tool.mjs +237 -0
- package/src/assets.mjs +244 -0
- package/src/backfill.mjs +74 -0
- package/src/backup.mjs +80 -0
- package/src/deadend.mjs +95 -0
- package/src/deleted-store.mjs +35 -0
- package/src/engine.mjs +3831 -0
- package/src/facets/classifier.mjs +146 -0
- package/src/facets/embedding-service.mjs +53 -0
- package/src/facets/embedding-worker.mjs +27 -0
- package/src/facets/embedding.mjs +163 -0
- package/src/facets/extract.mjs +80 -0
- package/src/facets/fold-plan.mjs +84 -0
- package/src/facets/hybrid.mjs +29 -0
- package/src/facets/index.mjs +113 -0
- package/src/facets/linear-probe.mjs +43 -0
- package/src/facets/load.mjs +37 -0
- package/src/facets/mlp-probe.mjs +54 -0
- package/src/facets/mlp-service.mjs +53 -0
- package/src/facets/mlp-worker.mjs +26 -0
- package/src/facets/online-knn.mjs +58 -0
- package/src/facets/online-models.mjs +227 -0
- package/src/facets/panel-state.mjs +23 -0
- package/src/facets/panel.mjs +73 -0
- package/src/facets/random.mjs +26 -0
- package/src/facets/scanner.mjs +35 -0
- package/src/facets/schema.mjs +75 -0
- package/src/facets/seed-examples.mjs +58 -0
- package/src/facets/sensitivity.mjs +98 -0
- package/src/facets/service.mjs +53 -0
- package/src/facets/store.mjs +39 -0
- package/src/facets/worker.mjs +23 -0
- package/src/folds-store.mjs +109 -0
- package/src/groups.mjs +167 -0
- package/src/handoff-tool.mjs +51 -0
- package/src/handoff.mjs +127 -0
- package/src/index.mjs +649 -0
- package/src/inject-policy.mjs +17 -0
- package/src/learning.mjs +88 -0
- package/src/memory/alias-proposal.mjs +40 -0
- package/src/memory/bc-audit.mjs +245 -0
- package/src/memory/bc-index-updater.mjs +404 -0
- package/src/memory/bc-index.mjs +48 -0
- package/src/memory/bc-label.mjs +220 -0
- package/src/memory/bc-panel-state.mjs +107 -0
- package/src/memory/bc-pre-step.mjs +463 -0
- package/src/memory/bc-recall.mjs +470 -0
- package/src/memory/bc-shift.mjs +123 -0
- package/src/memory/bc-store.mjs +41 -0
- package/src/memory/bm25.mjs +112 -0
- package/src/memory/calibration.mjs +54 -0
- package/src/memory/chatter.mjs +29 -0
- package/src/memory/cmap-file.mjs +107 -0
- package/src/memory/concepts-file.mjs +41 -0
- package/src/memory/coref-slots.mjs +40 -0
- package/src/memory/event-alias-ledger.mjs +87 -0
- package/src/memory/event-log.mjs +95 -0
- package/src/memory/event-model.mjs +132 -0
- package/src/memory/event-segmenter.mjs +36 -0
- package/src/memory/event-summary-tree.mjs +122 -0
- package/src/memory/extraction-adapter.mjs +76 -0
- package/src/memory/extraction-composite.mjs +75 -0
- package/src/memory/extraction-core.mjs +76 -0
- package/src/memory/extraction-pre-step.mjs +161 -0
- package/src/memory/extraction-provider.mjs +300 -0
- package/src/memory/extraction-score.mjs +36 -0
- package/src/memory/facet-stabilizer.mjs +59 -0
- package/src/memory/history-map.mjs +139 -0
- package/src/memory/language-router.mjs +30 -0
- package/src/memory/load-gate.mjs +161 -0
- package/src/memory/mechanical-note.mjs +104 -0
- package/src/memory/onboarding.mjs +163 -0
- package/src/memory/persona.mjs +78 -0
- package/src/memory/planner.mjs +249 -0
- package/src/memory/pre-turn.mjs +80 -0
- package/src/memory/query-aliases.mjs +39 -0
- package/src/memory/recall-cue.mjs +43 -0
- package/src/memory/recall.mjs +65 -0
- package/src/memory/referent-candidates.mjs +55 -0
- package/src/memory/referent-ledger.mjs +86 -0
- package/src/memory/relabel-migrate.mjs +376 -0
- package/src/memory/relik-adapter.mjs +25 -0
- package/src/memory/special-keywords.mjs +60 -0
- package/src/memory/structured-adapters.mjs +75 -0
- package/src/memory/summary-index.mjs +335 -0
- package/src/memory/summary-tree.mjs +110 -0
- package/src/memory/term-extractor.mjs +44 -0
- package/src/memory/tokenize.mjs +9 -0
- package/src/memory/vector-index.mjs +54 -0
- package/src/memory/window-summary.mjs +133 -0
- package/src/mood.mjs +133 -0
- package/src/peer-tool.mjs +63 -0
- package/src/peer.mjs +144 -0
- package/src/policy.mjs +170 -0
- package/src/preflight.mjs +113 -0
- package/src/provenance.mjs +94 -0
- package/src/range.mjs +75 -0
- package/src/recall-exact-tool.mjs +267 -0
- package/src/recall-tool.mjs +521 -0
- package/src/recheck.mjs +99 -0
- package/src/save-start.mjs +29 -0
- package/src/session-guard.mjs +140 -0
- package/src/session-log-tool.mjs +322 -0
- package/src/session-log.mjs +606 -0
- package/src/skills.mjs +111 -0
- package/src/split-range.mjs +115 -0
- package/src/state.mjs +198 -0
- package/src/t0.mjs +149 -0
- package/src/tag-confirm.mjs +78 -0
- package/src/tag-detect.mjs +42 -0
- package/src/tag-maintenance.mjs +285 -0
- package/src/tag-reject.mjs +73 -0
- package/src/tags-store.mjs +94 -0
- package/src/tags.mjs +692 -0
- package/src/threads-backend.mjs +26 -0
- package/src/threads-core.mjs +1887 -0
- package/src/threads-store.mjs +207 -0
- package/src/threads-tool.mjs +522 -0
- package/src/threads.mjs +929 -0
- package/src/tool-preview.mjs +427 -0
- package/src/topic.mjs +63 -0
- package/src/training.mjs +75 -0
- package/src/turn-tag.mjs +62 -0
- package/src/user-turn.mjs +39 -0
- package/templates/cmap.md +11 -0
- package/templates/concepts.md +12 -0
- package/templates/habits.md +40 -0
- package/templates/keywords.md +6 -0
- package/templates/rebuild.md +134 -0
- package/templates/rules-safe.md +184 -0
- package/templates/rules.md +177 -0
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# Handoff to the Creator-mode instance
|
|
2
|
+
|
|
3
|
+
> **Historical.** This was the handoff that started the compaction work. Current operating
|
|
4
|
+
> contract is `docs/NEW-INSTANCE-HANDOFF.md`; current mechanism is `docs/ARCHITECTURE.md`.
|
|
5
|
+
|
|
6
|
+
You are picking this up because the standard-mode session that wrote it could not inspect or
|
|
7
|
+
replace `ctx.compaction`. That session's context ends here; this file is the record. You are not
|
|
8
|
+
obliged to continue it — but if you do, these are the exact gaps.
|
|
9
|
+
|
|
10
|
+
## What is already decided
|
|
11
|
+
|
|
12
|
+
- Goal: replace the threshold-and-cliff compaction with a **band controller**: keep a verbatim
|
|
13
|
+
recent window, remove a small oldest slice per pass, never fold into the protected tail.
|
|
14
|
+
- The pure policy is implemented and tested in `src/policy.mjs` (9 tests). Do not redesign it
|
|
15
|
+
before running the tests.
|
|
16
|
+
- The adapter must **extend** `BasicCompactionEngine`, not reimplement the transaction.
|
|
17
|
+
- **One engine per context.** The existing `compaction-basic` entry must be replaced, not
|
|
18
|
+
accompanied by a second engine.
|
|
19
|
+
- First experiment should be **config-only** (see `docs/API-NOTES.md` "Config-only quick win"):
|
|
20
|
+
override `thresholdRatio: 0.92`, `retainRatio: 0.5` on the existing entry. If that already
|
|
21
|
+
gives the desired feel, the custom engine may not be worth its cost.
|
|
22
|
+
|
|
23
|
+
## What you need to inspect (in this order)
|
|
24
|
+
|
|
25
|
+
1. `cordis_inspect_list` — enumerate providers.
|
|
26
|
+
2. `cordis_inspect_query` on the `Config` provider — find the loader entry whose name is
|
|
27
|
+
`@deepseek-ai/dsh-compaction-basic`. Record:
|
|
28
|
+
- its loader id and tree id (the id a patch must target),
|
|
29
|
+
- its current `config` (thresholdRatio / retainRatio / headroomTokens),
|
|
30
|
+
- whether any modelPolicies already exist.
|
|
31
|
+
3. `cordis_inspect_query` on the token-meter provider — record the exact method names/signatures
|
|
32
|
+
for "used tokens" and "window tokens" for a routed request.
|
|
33
|
+
4. `cordis_inspect_query` on the session provider — record how to enumerate surface nodes
|
|
34
|
+
(`seq`, node kind, role), and how to get the first/last node for a range.
|
|
35
|
+
5. Check the exports of `@deepseek-ai/dsh-compaction` actually present in the runtime:
|
|
36
|
+
`toolPairingBalancedBefore` / `toolPairingBalancedAfter`.
|
|
37
|
+
|
|
38
|
+
Write the answers into `docs/API-NOTES.md` under a new "Measured at runtime" section. Do not rely
|
|
39
|
+
on the npm types alone; the app may be a newer `0.2.x`.
|
|
40
|
+
|
|
41
|
+
## Provenance is part of the policy
|
|
42
|
+
|
|
43
|
+
`src/provenance.mjs` is already written and tested. Wire it in **before** removing the checkpoint
|
|
44
|
+
preamble:
|
|
45
|
+
|
|
46
|
+
1. In `compactIfNeeded`, after selecting `{ start, end, count }`, set
|
|
47
|
+
`this.pendingHeader = gistHeader({ sessionId, startSeq, endSeq, count })`.
|
|
48
|
+
2. Override `summarize()`: call `super.summarize(...)`, then
|
|
49
|
+
`annotateSummary(base.summary, header)` (confirm the field name).
|
|
50
|
+
3. Add `SYSTEM_CONVENTION` as **one** system-prompt section. It must not be inside the compacted
|
|
51
|
+
range, or it will be folded away.
|
|
52
|
+
4. Leave the fixed checkpoint preamble in place for the first version. Removing it means writing
|
|
53
|
+
the replacement transaction yourself — do that only after the gist labels and the standing
|
|
54
|
+
convention are verified.
|
|
55
|
+
|
|
56
|
+
The target model experience is not "a checkpoint happened"; it is:
|
|
57
|
+
|
|
58
|
+
> I have the gist of that stretch. Exact details: `log:…#seq=…`. If the original is gone, say I
|
|
59
|
+
> only remember the gist.
|
|
60
|
+
|
|
61
|
+
## Then fill `src/engine.mjs`
|
|
62
|
+
|
|
63
|
+
Only two methods are missing:
|
|
64
|
+
|
|
65
|
+
- `measure(agent)` → `{ estTokens, windowTokens }`.
|
|
66
|
+
- `oldestRange(agent, budget)` → `{ start, end }` or `null`.
|
|
67
|
+
|
|
68
|
+
Rules for `oldestRange`:
|
|
69
|
+
|
|
70
|
+
- never start at surface position 0 if it is the system message;
|
|
71
|
+
- inclusive span, both edges balanced (`toolPairingBalancedBefore` / `After`);
|
|
72
|
+
- stop before the protected tail;
|
|
73
|
+
- if no balanced range fits `budget`, return `null` (the caller falls back to the base backend).
|
|
74
|
+
|
|
75
|
+
Keep `compactIfNeeded`'s overflow branch delegating to `super.compactIfNeeded(...)`.
|
|
76
|
+
|
|
77
|
+
## Acceptance
|
|
78
|
+
|
|
79
|
+
1. `node test/policy.test.mjs` — 9/9.
|
|
80
|
+
2. Scratch profile loads the plugin inert (`enabled: false`) and logs once.
|
|
81
|
+
3. Enable it; run a disposable conversation long enough to cross 65%.
|
|
82
|
+
4. Observe: passes are small (≤ `maxPerBatch`), recent messages stay verbatim, `/compact` still
|
|
83
|
+
works, overflow still recovers.
|
|
84
|
+
5. Ask about a detail that exists only in a compacted range. Expected: it cites the `[gist]`
|
|
85
|
+
header / pointer and says it only has the gist (or retrieves), not a confident fabrication.
|
|
86
|
+
6. Compare against `../sim/results.json`: event count per 100 turns, median drop, p90 drop.
|
|
87
|
+
7. Keep the previous entry id and config in the handoff so rollback is one line.
|
|
88
|
+
|
|
89
|
+
## Do not
|
|
90
|
+
|
|
91
|
+
- Do not insert a second `compaction-basic` row.
|
|
92
|
+
- Do not patch the desktop profile first.
|
|
93
|
+
- Do not claim "continuous self"; the seam is policy, not personhood.
|
|
94
|
+
- Do not delete the raw/archived transcript before verifying the summary and the new ranges.
|
|
95
|
+
|
|
96
|
+
## Files
|
|
97
|
+
|
|
98
|
+
- `src/policy.mjs` — pure controller; do not change without updating tests.
|
|
99
|
+
- `src/engine.mjs` — the two TODOs.
|
|
100
|
+
- `docs/API-NOTES.md` — contract, config-only quick win, constraints.
|
|
101
|
+
- `../sim/` — the simulator and its numbers.
|
|
102
|
+
- `../README.md` — the Coopanion-side patch this mirrors.
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# Config-only experiment — `thresholdRatio 0.92` / `retainRatio 0.5`
|
|
2
|
+
|
|
3
|
+
> **Historical.** The experiment is preserved for the record. Current band policy and reachable
|
|
4
|
+
> floor are in `docs/ARCHITECTURE.md` and `src/policy.mjs`.
|
|
5
|
+
|
|
6
|
+
This is the first experiment from `CREATOR-HANDOFF.md` (“Config-only quick win”): change the
|
|
7
|
+
shipped compaction backend's policy without changing engine code, and see whether a 50% verbatim
|
|
8
|
+
tail and a 92% cap already feel like the band.
|
|
9
|
+
|
|
10
|
+
## Where it lives
|
|
11
|
+
|
|
12
|
+
A patch **cannot** target the live engine on this profile. The effective `compaction-basic` is a
|
|
13
|
+
child of the `standard` preset:
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
include:preset-standard
|
|
17
|
+
└─ group "compaction" isolate: { compaction: true, toolResultPruner: true }
|
|
18
|
+
└─ child "compaction-basic"
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`Config.listConfigs` addresses top-level rows only, and the nested id
|
|
22
|
+
`include:preset-standard:compaction:compaction-basic` is not a loader entry. Overriding
|
|
23
|
+
`preset-standard` would change the default backend for every new session, which the handoff
|
|
24
|
+
explicitly says not to do first.
|
|
25
|
+
|
|
26
|
+
So the experiment is shipped as a **copy of the standard preset** whose only difference is the
|
|
27
|
+
compaction child's `config`:
|
|
28
|
+
|
|
29
|
+
| Item | Value |
|
|
30
|
+
|---|---|
|
|
31
|
+
| Loader row id | `include:preset-band` |
|
|
32
|
+
| Declaration `config.id` | `band` |
|
|
33
|
+
| Display name | `Band (config-only)` |
|
|
34
|
+
| Order | 20 |
|
|
35
|
+
| Shipped `preset-standard` | untouched |
|
|
36
|
+
| Rollback | pick another preset, or remove the `dsh-continuity` bundle |
|
|
37
|
+
|
|
38
|
+
The exact override, inside the copied `compaction` group:
|
|
39
|
+
|
|
40
|
+
```yaml
|
|
41
|
+
- id: compaction-basic
|
|
42
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
43
|
+
config:
|
|
44
|
+
thresholdRatio: 0.92
|
|
45
|
+
retainRatio: 0.5
|
|
46
|
+
# headroomTokens omitted: the shipped default 65536 applies and the
|
|
47
|
+
# resolved threshold is min(W × 0.92, W − O − 65536).
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Nothing else in the 22-plugin preset list changes. `command-compact` and `tool-result-pruner` stay.
|
|
51
|
+
|
|
52
|
+
## Resolved numbers (live model route)
|
|
53
|
+
|
|
54
|
+
`cordis_inspect_query` / `ctx.llm.resolveModelInfo('deepseek-official', 'deepseek-flash')`:
|
|
55
|
+
|
|
56
|
+
| Input | Value |
|
|
57
|
+
|---|---|
|
|
58
|
+
| `contextWindow` | 1,048,576 |
|
|
59
|
+
| reserved completion tokens (header `maxTokens`) | 256,000 |
|
|
60
|
+
| `messageBudget = W − O` | 792,576 |
|
|
61
|
+
| `headroomTokens` | 65,536 |
|
|
62
|
+
|
|
63
|
+
Reported by the panel's projection and computed with the base backend's own formulas:
|
|
64
|
+
|
|
65
|
+
| Config | `thresholdTokens` | `retainTokens` | one pass at the threshold |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| shipped `0.8 / 0.16` | 727,040 | 126,812 | 600,228 |
|
|
68
|
+
| **experiment `0.92 / 0.5`** | **727,040** | **396,288** | **330,752** |
|
|
69
|
+
| band engine (reference) | triggers at 515,174 | protects 221,921 | small slices, ≤ 8,000 |
|
|
70
|
+
|
|
71
|
+
The 92% ratio is not the binding cap: `0.92 × 1,048,576 = 964,690`, but
|
|
72
|
+
`1,048,576 − 256,000 − 65,536 = 727,040`. The experiment halves the retained tail (126,812 →
|
|
73
|
+
396,288) but keeps the same trigger point, so each cut is still one large cliff (~331k tokens).
|
|
74
|
+
|
|
75
|
+
## Why that still matters
|
|
76
|
+
|
|
77
|
+
Seven real summary compactions found in the local session logs (read-only scan; see
|
|
78
|
+
`docs/API-NOTES.md` §6) shadowed:
|
|
79
|
+
|
|
80
|
+
| session | shadowed tokens | shadowed surface nodes | summary maxTokens |
|
|
81
|
+
|---|---:|---:|---:|
|
|
82
|
+
| `session-2f831fa2…` | 363,912 | 1,259 | 65,536 |
|
|
83
|
+
| `session-2f831fa2…` | 354,500 | 1,166 | 65,536 |
|
|
84
|
+
| `session-2f831fa2…` | 342,756 | 1,000 | 65,536 |
|
|
85
|
+
| `session-4185b80f…` | 425,772 | 804 | 8,192 |
|
|
86
|
+
| `session-f1ac062b…` | 442,443 | 587 | 65,536 |
|
|
87
|
+
|
|
88
|
+
Full record for the first one:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
compactionId b57ba840-1892-4175-b652-06c7e30b8609
|
|
92
|
+
start seq 8255
|
|
93
|
+
summary seq 8257 shadowedRange 4424–7043 363,912 tokens
|
|
94
|
+
replace seq 8258 surfaceOp replace 4424–7043
|
|
95
|
+
end seq 8259
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The experiment changes *how much recent history survives* the cliff; it does not remove the cliff.
|
|
99
|
+
If the 50% tail already feels right, the custom engine is not worth its cost. If the single 331k
|
|
100
|
+
drop is still too disruptive, the `continuity` preset is the next step.
|
|
101
|
+
|
|
102
|
+
## How to run it
|
|
103
|
+
|
|
104
|
+
1. Start a **new** session (existing sessions keep the preset revision they started with).
|
|
105
|
+
2. Pick the preset **`Band (config-only)`**. It appears beside `standard` in the preset control.
|
|
106
|
+
3. Work normally until the session crosses the threshold. Automatic compaction happens at a step
|
|
107
|
+
boundary; the conversation shows the usual compaction row.
|
|
108
|
+
4. To see the numbers rather than feel them, open the **Continuity** sidebar panel: the
|
|
109
|
+
“Config-only projection” card recomputes the table above from the live route and model.
|
|
110
|
+
5. Compare a `Band` session's compaction row against a `standard` session's row (template below).
|
|
111
|
+
|
|
112
|
+
The panel's “Recent passes” list only observes the **continuity engine**, not the shipped backend;
|
|
113
|
+
a Band pass is visible in the session's compaction row and its log (`compaction/start`,
|
|
114
|
+
`compaction/summary`, replacement `user/message`, `compaction/end`).
|
|
115
|
+
|
|
116
|
+
## Decision gate
|
|
117
|
+
|
|
118
|
+
- **Feels acceptable** → keep using `band`; the custom engine is optional. Rollback to `standard`
|
|
119
|
+
is one preset selection.
|
|
120
|
+
- **Still a cliff** → use `continuity`: same preset list, but `dsh-continuity/engine` replaces
|
|
121
|
+
`compaction-basic`, labels every pass with a gist pointer, and (since the cache-first update)
|
|
122
|
+
does one ~190k drain per high crossing instead of many small passes.
|
|
123
|
+
- **Something breaks** → remove the bundle (`plugin_manager` `remove_bundle`, target
|
|
124
|
+
`dsh-continuity`) and select `standard`. `preset-standard` and its compaction backend were never
|
|
125
|
+
modified, so no session needs repair.
|
|
126
|
+
|
|
127
|
+
## Status
|
|
128
|
+
|
|
129
|
+
- 2026-10-26: `include:preset-band` registered and active on the desktop profile; the resolved
|
|
130
|
+
arithmetic is valid (`396,288 < 727,040`).
|
|
131
|
+
- No session has crossed the band threshold yet. The `compactionId` of the first Band pass will be
|
|
132
|
+
recorded here (or in `docs/API-NOTES.md`) once it happens.
|
|
133
|
+
- 2026-10-26 (later): the `continuity` engine's old policy produced 53 passes in
|
|
134
|
+
`session-0b094f6e…` (698,108 tokens total, 34 one-node passes) and repeatedly wiped the suffix
|
|
135
|
+
cache. `continuity` now uses `CACHE_FIRST_POLICY` (86/62, 190k per pass, 30% protected); see
|
|
136
|
+
`docs/CACHE.md`. The config-only `band` preset in this document is unchanged.
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
# Facet MVP 报告
|
|
2
|
+
|
|
3
|
+
## 已完成
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
src/facets/schema.mjs 固定 6 槽 facet 词表 + alias 表
|
|
7
|
+
src/facets/extract.mjs 规则/词典回退提取器
|
|
8
|
+
src/facets/index.mjs 每 turn facet 索引、idf、alias 查询、seq 排序
|
|
9
|
+
src/facets/scanner.mjs 增量 seq 扫描器 + residual 队列
|
|
10
|
+
bin/facet-mvp.mjs CLI
|
|
11
|
+
test/facets.test.mjs 4 个测试
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 模块
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
buildFacetIndex(rows) rows -> entries + idf
|
|
18
|
+
queryFacets(index, alias) alias -> facet 集合 -> 排序 -> ranges
|
|
19
|
+
indexStats(index) 分布/unknown 统计
|
|
20
|
+
scanRows(rows, cursor) 从 cursor.lastSeq 往后扫,unknown 进 residual,不阻塞
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## 第 100 轮真实快照测试
|
|
24
|
+
|
|
25
|
+
数据:Continuity 1381–1480 的 100 个 turn;facet 由模型只读正文产生(不是规则提取器)。
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
查询 跑团 → 54 matches
|
|
29
|
+
查询 调试 → 19 matches
|
|
30
|
+
查询 测试 → 20 matches
|
|
31
|
+
unknown → 0
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
跑团命中的 seq 段示例:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
56006–56051 (turn 1381–1386)
|
|
38
|
+
56069–56141 (1389–1396)
|
|
39
|
+
56159–56186 (1399–1401)
|
|
40
|
+
56224–56305 (1408–1413)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## 测试
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
node test/facets.test.mjs 4 pass
|
|
47
|
+
npm test 全部通过
|
|
48
|
+
npm run check 通过
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 规则提取器 vs 模型 facet(同一批 100 turn)
|
|
52
|
+
|
|
53
|
+
规则/词典提取器(`extract.mjs`):
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
unknown 41 / 100
|
|
57
|
+
activity 跑团 4 / 54
|
|
58
|
+
查询“跑团” matches 0
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
模型 facet(只读正文,作为索引输入):
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
unknown 0 / 100
|
|
65
|
+
activity 跑团 54 / 54
|
|
66
|
+
查询“跑团” matches 54
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
结论:**索引/查询层已经可用;提取层是瓶颈。**
|
|
70
|
+
规则词典只能做 v0 fallback,真正可用必须接小模型/embedding 分类器。
|
|
71
|
+
|
|
72
|
+
## ONNX/embedding 小模型
|
|
73
|
+
|
|
74
|
+
`src/facets/embedding.mjs`:
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
@huggingface/transformers
|
|
78
|
+
Xenova/bge-small-zh-v1.5
|
|
79
|
+
ONNX/WASM,本地缓存
|
|
80
|
+
hf-mirror 只用于首次下载
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
分层 holdout,train 52 / test 48:
|
|
84
|
+
|
|
85
|
+
### embedding only
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
activity 91.4% coverage 72.9%
|
|
89
|
+
interaction 93.9% coverage 68.8%
|
|
90
|
+
participants 70.2% coverage 97.9%
|
|
91
|
+
medium 87.0% coverage 95.8%
|
|
92
|
+
topic 94.3% coverage 72.9%
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### embedding + NB fallback
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
activity 83.3% coverage 100%
|
|
99
|
+
interaction 83.3% coverage 100%
|
|
100
|
+
participants 68.8% coverage 100%
|
|
101
|
+
medium 87.5% coverage 100%
|
|
102
|
+
topic 85.4% coverage 100%
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### slot-aware fusion(embedding 只赢 4 个槽,participants 留给 NB)
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
activity 83.3% coverage 100%
|
|
109
|
+
interaction 83.3% coverage 100%
|
|
110
|
+
participants 83.3% coverage 100%
|
|
111
|
+
medium 87.5% coverage 100%
|
|
112
|
+
topic 85.4% coverage 100%
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
结论:embedding 在“敢答”时更准,但 coverage 低;按槽融合后 coverage 100%,participants 回到 83.3%。
|
|
116
|
+
0.9.2 使用 slot-aware fusion。
|
|
117
|
+
|
|
118
|
+
### embedding worker
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
src/facets/embedding-worker.mjs
|
|
122
|
+
src/facets/embedding-service.mjs
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
worker 同时加载:
|
|
126
|
+
|
|
127
|
+
```text
|
|
128
|
+
prototypes JSON
|
|
129
|
+
可选 NB model JSON
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
返回 fused facets;模型推理不在主线程。
|
|
133
|
+
|
|
134
|
+
验证文件:
|
|
135
|
+
|
|
136
|
+
```text
|
|
137
|
+
last100/FACET-EMBEDDING-VALIDATION.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## 敏感度曲线与折叠优先级
|
|
141
|
+
|
|
142
|
+
`src/facets/sensitivity.mjs`:
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
IDF 加权 cosine
|
|
146
|
+
coverage² 惩罚
|
|
147
|
+
减去全语料 baseline
|
|
148
|
+
3 窗 EMA(0.5/0.3/0.2)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
last100 查询“跑团”:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
跑团段平均 smoothed:0.275
|
|
155
|
+
技术段平均 smoothed:0.0048
|
|
156
|
+
≈ 57 倍分离
|
|
157
|
+
最高:0.316(1381)
|
|
158
|
+
最低:0(技术段)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
CLI:
|
|
162
|
+
|
|
163
|
+
```powershell
|
|
164
|
+
node bin/facet-curve.mjs --input rows.jsonl --query 跑团 --out series.json
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
同一模块的 `foldPriority()` 用 `(1-score)×age` 排序,先折低相关老段,保护高相关当前话题。
|
|
168
|
+
|
|
169
|
+
验证文件:
|
|
170
|
+
|
|
171
|
+
```text
|
|
172
|
+
last100/FACET-CURVE.json
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## 面板快照与 load 提示
|
|
176
|
+
|
|
177
|
+
`src/facets/panel.mjs`:
|
|
178
|
+
|
|
179
|
+
```text
|
|
180
|
+
buildFacetPanel()
|
|
181
|
+
totalTurns / unknown / facetSum
|
|
182
|
+
每槽计数
|
|
183
|
+
当前 alias → facet pairs(含挂载 turn 数)
|
|
184
|
+
sensitivity curve
|
|
185
|
+
|
|
186
|
+
buildLoadHint()
|
|
187
|
+
只在该话题最近窗口没有出现时返回一行 [回忆?]
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
last100 面板:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
总 turn:100
|
|
194
|
+
facet 计数和:600(6 槽 × 100)
|
|
195
|
+
unknown:0
|
|
196
|
+
当前话题:跑团
|
|
197
|
+
pairs:activity 跑团 54 / interaction 回合制 54 / random 有 0 /
|
|
198
|
+
participants 协作 89 / medium 文字 84 / topic 剧情 47
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
`random 有 0` 是故意暴露的异常项:alias 声明了“随机”,但 last100 里没有机制词,
|
|
202
|
+
用户可以据此指出 alias 不合理;面板不替用户掩盖。
|
|
203
|
+
|
|
204
|
+
输出:
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
last100/FACET-PANEL.json
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 面板接线(0.9.x 预演)
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
host: /dsh-continuity/facets.json
|
|
214
|
+
file: ~/.dsh/continuity/facet-panel.json
|
|
215
|
+
client: 有 facet 快照时显示 facet 视图;没有时回退 T 列表
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
生成快照(显式 opt-in,不自动写 live):
|
|
219
|
+
|
|
220
|
+
```powershell
|
|
221
|
+
node bin/facet-panel.mjs --input rows.jsonl --out $HOME\.dsh\continuity\facet-panel.json --alias 跑团
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
面板显示:
|
|
225
|
+
|
|
226
|
+
```text
|
|
227
|
+
当前话题 + alias-facet pairs
|
|
228
|
+
facet 总计数 / unknown
|
|
229
|
+
敏感度曲线
|
|
230
|
+
显示 T 列表(回退)
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### facet load 查询
|
|
234
|
+
|
|
235
|
+
```powershell
|
|
236
|
+
node bin/facet-load.mjs --index facet-index.json --query 跑团 --top 5
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
输出:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
alias → facet 集合
|
|
243
|
+
ranges
|
|
244
|
+
seqs(可直接给 continuity.load 的 seqs)
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
这是“引导模型 load”的第一步:模型不再需要知道 T,只需要 query。
|
|
248
|
+
|
|
249
|
+
### continuity.load({query})
|
|
250
|
+
|
|
251
|
+
`load` 新增可选 `query`:
|
|
252
|
+
|
|
253
|
+
```text
|
|
254
|
+
continuity.load({ action: "load", query: "跑团" })
|
|
255
|
+
→ facet-index.json → seqs → 正常 load
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
不要求模型知道 T;返回里带 `facetQuery` 的 ranges/seqs 数。
|
|
259
|
+
没有 index/没有命中时返回 `facet-no-match`,不会静默切 T。
|
|
260
|
+
|
|
261
|
+
## high 触发折叠计划
|
|
262
|
+
|
|
263
|
+
`src/facets/fold-plan.mjs`:
|
|
264
|
+
|
|
265
|
+
```text
|
|
266
|
+
planFacetFold(entries, {query, idf, budgetTokens, recentTurns})
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
行为:
|
|
270
|
+
|
|
271
|
+
```text
|
|
272
|
+
最近窗口 → protected
|
|
273
|
+
高 relevance 当前话题 → protected
|
|
274
|
+
老的低 relevance → 按 (1-score)×age 排序
|
|
275
|
+
按 token budget 取低相关 seq ranges
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
这是 high trigger 的候选计划;引擎已能在 `config.facetFold` 存在时,
|
|
279
|
+
于 `band-high` / `emergency` 分支优先使用它,并检查:
|
|
280
|
+
|
|
281
|
+
```text
|
|
282
|
+
active tool pin
|
|
283
|
+
tool pairing before/after
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
不满足时回退原来的 oldestRange。引擎默认读取:
|
|
287
|
+
|
|
288
|
+
```text
|
|
289
|
+
~/.dsh/continuity/facet-fold.json
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
存在时自动用于 `band-high` / `emergency`;不存在时行为不变。生成:
|
|
293
|
+
|
|
294
|
+
```powershell
|
|
295
|
+
node bin/facet-fold.mjs --input rows.jsonl --out $HOME\.dsh\continuity\facet-fold.json --query 跑团
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## facetNative(T 降为 alias 的过渡开关)
|
|
299
|
+
|
|
300
|
+
引擎配置:
|
|
301
|
+
|
|
302
|
+
```text
|
|
303
|
+
facetNative: true
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
行为:
|
|
307
|
+
|
|
308
|
+
```text
|
|
309
|
+
跳过 turn-stopping 的 TAG 补标催办
|
|
310
|
+
facet/load/query 仍可用
|
|
311
|
+
T 仍作为 save/load 的 alias 存在,但不再强制每轮打标
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
默认 `false`;显式开启才改变回合闸。
|
|
315
|
+
|
|
316
|
+
## random facet 修复
|
|
317
|
+
|
|
318
|
+
`src/facets/random.mjs` 只认显式机制词:
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
掷骰 / 骰子 / 骰 / D20 / 检定 / 抽卡
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
全历史 1474 turn 验证(正例标签由同一组机制词生成,因此这是规则校准,不是人工 gold):
|
|
325
|
+
|
|
326
|
+
```text
|
|
327
|
+
positive:73
|
|
328
|
+
recall:1.00
|
|
329
|
+
falsePositive:0
|
|
330
|
+
precision:1.00
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
说明:last100 里这组机制词命中为 0,所以那 100 轮的 `random=无` 现在 **不是退化,而是输入里确实没有机制信号**。
|
|
334
|
+
全历史里有 73 轮会被标成 `random=有`。
|
|
335
|
+
|
|
336
|
+
## 本地 worker
|
|
337
|
+
|
|
338
|
+
```text
|
|
339
|
+
src/facets/worker.mjs 加载 model JSON,消息循环
|
|
340
|
+
src/facets/service.mjs 主线程 client,超时/关闭
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
测试:
|
|
344
|
+
|
|
345
|
+
```text
|
|
346
|
+
facet worker extracts off-thread from a serialized model ✔ 45ms
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
宿主主线程不再直接跑分类推理。
|
|
350
|
+
|
|
351
|
+
worker 端到端跑 last100(模型在全部 100 上训练,仅验证链路,不是泛化指标):
|
|
352
|
+
|
|
353
|
+
```text
|
|
354
|
+
index entries:100
|
|
355
|
+
unknown:0
|
|
356
|
+
查询“跑团”:52 matches
|
|
357
|
+
真实跑团:54
|
|
358
|
+
true positive:52
|
|
359
|
+
precision:1.00
|
|
360
|
+
recall:0.963
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
## 闭环验证
|
|
364
|
+
|
|
365
|
+
`bin/facet-validate.mjs`:分层 holdout → 训练本地 NB → hybrid extract → 建索引 → alias 查询。
|
|
366
|
+
|
|
367
|
+
最近 100 turn,train 52 / test 48:
|
|
368
|
+
|
|
369
|
+
```text
|
|
370
|
+
activity 81.3%
|
|
371
|
+
interaction 81.3%
|
|
372
|
+
participants 83.3%
|
|
373
|
+
medium 85.4%
|
|
374
|
+
topic 83.3%
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
查询“跑团”:
|
|
378
|
+
|
|
379
|
+
```text
|
|
380
|
+
test 中真实跑团 turn:27
|
|
381
|
+
命中:26
|
|
382
|
+
precision:1.00
|
|
383
|
+
recall:0.963
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
唯一漏掉的是 27 个中的 1 个。
|
|
387
|
+
输出在:
|
|
388
|
+
|
|
389
|
+
```text
|
|
390
|
+
coopanion-continuity/backups/continuity-tags-20261031/last100/FACET-VALIDATION.json
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
结论:**raw text → 本地提取 → 索引 → alias 查询 → seq 范围,这条闭环成立。**
|
|
394
|
+
|
|
395
|
+
## CLI 增量扫描验证
|
|
396
|
+
|
|
397
|
+
```text
|
|
398
|
+
node bin/facet-scan.mjs --input rows-a.jsonl --dir facet-state --query 跑团
|
|
399
|
+
node bin/facet-scan.mjs --input rows-b.jsonl --dir facet-state --query 跑团
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
结果:
|
|
403
|
+
|
|
404
|
+
```text
|
|
405
|
+
第一次 scanned: 50
|
|
406
|
+
第二次 scanned: 50
|
|
407
|
+
facet-index entries: 100
|
|
408
|
+
facet-cursor.lastSeq: 56460
|
|
409
|
+
residual: 0
|
|
410
|
+
查询“跑团”: 54 matches(topK 以内)
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
## 本地 Naive Bayes 学生模型
|
|
414
|
+
|
|
415
|
+
`src/facets/classifier.mjs`:字符 bigram + 多项式朴素贝叶斯,无外部依赖。
|
|
416
|
+
|
|
417
|
+
### 按时间切分(前 50 训练 / 后 50 测试)
|
|
418
|
+
|
|
419
|
+
```text
|
|
420
|
+
activity accuracy 8% coverage 100%
|
|
421
|
+
interaction accuracy 8% coverage 100%
|
|
422
|
+
random accuracy 100% coverage 100%(全预测“无”)
|
|
423
|
+
participants accuracy 78% coverage 100%
|
|
424
|
+
medium accuracy 68% coverage 100%
|
|
425
|
+
topic accuracy 44% coverage 100%
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
这是**分布偏移**:前 50 轮几乎全是跑团,后 50 轮几乎全是技术工作。8% 不代表模型本身。
|
|
429
|
+
|
|
430
|
+
### 分层切分(每个 activity 交替进 train/test)
|
|
431
|
+
|
|
432
|
+
```text
|
|
433
|
+
train 52 / test 48
|
|
434
|
+
activity 81.3%
|
|
435
|
+
interaction 81.3%
|
|
436
|
+
random 100.0%(仍全是“无”)
|
|
437
|
+
participants 83.3%
|
|
438
|
+
medium 85.4%
|
|
439
|
+
topic 83.3%
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
结论:**同样的 Naive Bayes,在代表性训练集上可以到 81%**;
|
|
443
|
+
真正的问题不是模型类型,而是**类别分布**和 `random` 特征退化。
|
|
444
|
+
|
|
445
|
+
### 可持久化模型
|
|
446
|
+
|
|
447
|
+
```text
|
|
448
|
+
node bin/facet-train.mjs --input rows.jsonl --out facet-model.json
|
|
449
|
+
node bin/facet-scan.mjs --input rows.jsonl --model facet-model.json --dir .facet --query 跑团
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
模型是普通 JSON;换 ONNX 时只替换 `classifierExtractor`,索引/查询不变。
|
|
453
|
+
|
|
454
|
+
## 已知限制
|
|
455
|
+
|
|
456
|
+
1. `extract.mjs` 只是词典回退,不是小模型;对“掷骰”等能命中,对隐含语义不行。
|
|
457
|
+
2. 模型 facet 输出有质量问题:最近 100 轮 `random` 全是“无”,漏了掷骰。
|
|
458
|
+
3. 没有接大模型 residual 命名,也没有接 ONNX 小模型。
|
|
459
|
+
4. 没有写进 Continuity 的 load 工具;目前是独立模块/CLI。
|
|
460
|
+
5. 查询没有做“所有 facet 必须同时命中”的严格 AND;当前按覆盖度 >= 0.6。
|
|
461
|
+
|
|
462
|
+
## 下一步
|
|
463
|
+
|
|
464
|
+
```text
|
|
465
|
+
1. 用规则提取器跑 last100,比较它与模型 facet 的差异
|
|
466
|
+
2. 把 facet-index 接入 continuity load 的 query 分支
|
|
467
|
+
3. residual 聚类 + 大模型命名(离线命令)
|
|
468
|
+
4. ONNX 小模型 worker
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
## 数据安全
|
|
472
|
+
|
|
473
|
+
没有修改 `~/.dsh/continuity` 的任何文件;测试只读 last100 快照。
|