dsh-engram 0.3.7 → 0.5.0
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/README.md +166 -16
- package/README.zh.md +137 -13
- package/docs/ORACLE-ANALYSIS.zh.md +63 -0
- package/docs/PROPOSAL-resultpack.zh.md +139 -0
- package/docs/RELEASE-NOTES-v0.4.0.md +34 -0
- package/docs/RELEASE-NOTES-v0.5.0.md +58 -0
- package/lib/api.js +19 -6
- package/lib/boundary-prune.js +294 -0
- package/lib/client.js +17 -1
- package/lib/index-block.js +27 -5
- package/lib/index.js +199 -4
- package/lib/pack-telemetry.js +115 -0
- package/lib/preference.js +276 -0
- package/lib/result-pack.js +276 -0
- package/lib/settings.js +115 -31
- package/lib/store.js +1 -0
- package/lib/tools.js +2 -1
- package/package.json +8 -7
- package/scripts/prepublish-check.mjs +7 -4
package/README.md
CHANGED
|
@@ -23,6 +23,21 @@ with one goal: **save tokens**.
|
|
|
23
23
|
integration**: a completed or blocked goal (`goal/change` session event)
|
|
24
24
|
auto-sediments as a `handoff`/`error` memory (`tag:goal`), so the outcome of
|
|
25
25
|
a goal survives its session (see the `GET /api/dsh-engram/goals` read surface).
|
|
26
|
+
- **User-correction / preference learning (`autoCapturePreferences`, default on,
|
|
27
|
+
zero LLM)** — the lesson that "when the AI makes a mistake and gets corrected,
|
|
28
|
+
that lesson should persist" ([correx](https://github.com/ozoz5/correx),
|
|
29
|
+
[PAHF](https://arxiv.org/abs/2602.16173), Mem0 preference extraction): a
|
|
30
|
+
`session/event` listener watches `user/message` and turns deterministic
|
|
31
|
+
correction/preference cues into a dedicated `preference` memory kind —
|
|
32
|
+
Chinese (`不要用X`, `改用X`, `以后统一用X`…) and English (`don't use X`,
|
|
33
|
+
`switch to X`, `prefer X`, `never use X`…) patterns, three directions
|
|
34
|
+
(`avoid` / `switch-to` / `prefer`), with interrogative/one-shot-instruction/
|
|
35
|
+
memory-tool-meta-talk filters to keep false positives out. `preference`
|
|
36
|
+
memories outrank every other kind in the `[ENGRAM]` block (`[R]` prefix) so a
|
|
37
|
+
standing user rule is the first line the model sees each session; per-session
|
|
38
|
+
cap + recent-window dedup mirror the auto-capture discipline. Zero LLM, zero
|
|
39
|
+
embeddings, deterministic and pure — extracted clauses are bounded, and every
|
|
40
|
+
write still goes through the secret redactor.
|
|
26
41
|
- **Symbolic index + progressive disclosure** — a compact `[ENGRAM]` block (default
|
|
27
42
|
budget 700 chars ≈ 175 tokens; one line per memory) is injected at prompt
|
|
28
43
|
assembly and **frozen per session**, keeping the request prefix byte-stable for
|
|
@@ -51,6 +66,12 @@ with one goal: **save tokens**.
|
|
|
51
66
|
Pure rule, zero LLM, pure read (never bumps `hits`); superseded stale truth does
|
|
52
67
|
not occupy an injection slot (still fetchable via `engram_detail`); frozen per
|
|
53
68
|
session together with `[ENGRAM]` for prefix stability.
|
|
69
|
+
- **Read-path activation (D)** — a hit whose one-line preview is truncated
|
|
70
|
+
(>140 chars) carries a `…` marker and the block's trailing guidance names that
|
|
71
|
+
concrete id: `#<id> truncated — engram_detail <id> (full) · engram_recall <query>`.
|
|
72
|
+
So the model knows the full record is one deterministic `engram_detail` call
|
|
73
|
+
away instead of assuming the preview is the whole memory (proven gap in real
|
|
74
|
+
use: 66 sessions, zero `engram_detail` calls — the detail path was invisible).
|
|
54
75
|
- **Memory-to-memory semantics** — `engram_store` accepts optional
|
|
55
76
|
`supersedes` / `contradicts` memory ids (validated against the same
|
|
56
77
|
workspace). A superseded ("stale truth") memory is demoted to the tail of
|
|
@@ -238,7 +259,14 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
238
259
|
-d "{\"payload\": $(cat engram-backup.json), \"mode\": \"merge\"}"
|
|
239
260
|
```
|
|
240
261
|
|
|
241
|
-
##
|
|
262
|
+
## Compatibility
|
|
263
|
+
|
|
264
|
+
<!-- dsh-market compatibility block — keep labels bilingual and in sync with
|
|
265
|
+
docs/RELEASE-NOTES.TEMPLATE.md (market README convention) -->
|
|
266
|
+
|
|
267
|
+
- **DSH 版本 / DSH versions**: `>=0.1.2-alpha.2 <0.3.0-0` (本版 `0.5.0`; 已发布的 `0.3.7`、`0.4.0` 仍声明旧的 `0.1.x` 范围 `>=0.1.2-alpha.2 <0.2.0-0` — 见下方矩阵)
|
|
268
|
+
- **最后验证日期 / Last verified**: 2026-10-15 — 设置模型迁移(entry-id volatile Config,兼容 DSH `0.2.x`)落地,npm test 329/329 通过;真实 `dsh 0.2.0-rc.2` 隔离 profile 运行烟测通过(见下方“当前发布”)
|
|
269
|
+
- **安装方式已验证 / Verified install**: `dsh plugin --profile web add dsh-engram`
|
|
242
270
|
|
|
243
271
|
> **Short version.** Every **published** release (`0.2.0` … `0.3.6`) supports
|
|
244
272
|
> the **old** DSH API graph (`0.1.0-rc.7` / `0.1.1`, peers `^0.1.0-rc.7`)
|
|
@@ -250,7 +278,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
250
278
|
| dsh-engram release | Status | DSH support | Declared via |
|
|
251
279
|
| --- | --- | --- | --- |
|
|
252
280
|
| `0.2.0` … `0.3.6` (npm, GitHub v0.3.3–v0.3.6) | published | **old DSH only** — `0.1.0-rc.7` / `0.1.0-rc.8` / `0.1.1-rc.1` / `0.1.1-rc.2` | peers `@deepseek-ai/dsh-*@^0.1.0-rc.7` |
|
|
253
|
-
| `0.3.7`
|
|
281
|
+
| `0.3.7` / `0.4.0` (npm) | published | **new DSH, settings `installSection`** — `>=0.1.2-alpha.2 <0.2.0-0` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.2.0-0` |
|
|
282
|
+
| `0.5.0` (本期 / this release) | pre-release | **DSH `0.1.2-alpha.2` … `<0.3.0-0`** — 设置卡迁移到 entry-id volatile Config(`0.1.7+`/`0.2.x`),`≤0.1.5` 自动回退 `installSection` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
254
283
|
|
|
255
284
|
### Where the API family broke — `0.1.2-alpha.2`
|
|
256
285
|
|
|
@@ -275,36 +304,72 @@ HTTP route (`/api/dsh-engram/settings`, same-origin fetch like the memory
|
|
|
275
304
|
viewer), so the card is generation-agnostic on both sides of the
|
|
276
305
|
`0.1.2-alpha.2` boundary.
|
|
277
306
|
|
|
307
|
+
**One more settings break, at `0.1.7` / `0.2.0`** — and the reason `0.4.0` was
|
|
308
|
+
not actually loadable on the current DSH: `@deepseek-ai/dsh-settings` **removed
|
|
309
|
+
`settings.installSection` again** in `0.1.7-alpha.2` (and keeps it removed in
|
|
310
|
+
`0.2.x`). The new settings model is **entry-keyed**: editable fields are
|
|
311
|
+
`.volatile()` fields of the plugin's own `Config` (validated + hot-committed by
|
|
312
|
+
the loader), and the settings form is keyed by the profile entry id (`engram`),
|
|
313
|
+
so nothing needs "mounting". `0.5.0` feature-detects the two generations in
|
|
314
|
+
`installEngramSettings`:
|
|
315
|
+
|
|
316
|
+
- DSH `≥0.1.7` / `0.2.x` — the 27 GUI knobs are the volatile `Config` fields
|
|
317
|
+
(`lib/settings.js` `makeEngineConfigSchema`, exported as `Config` from
|
|
318
|
+
`lib/index.js`); the card reads/writes entry `engram` through the same
|
|
319
|
+
`/api/dsh-engram/settings` HTTP route, and the `service.settings` seam
|
|
320
|
+
re-syncs `resolved` on `loader/volatile-update` so card edits land live on
|
|
321
|
+
new sessions.
|
|
322
|
+
- DSH `≤0.1.5` — the legacy `settings.installSection` namespace (`dsh-engram`)
|
|
323
|
+
is registered as before; nothing changes.
|
|
324
|
+
|
|
325
|
+
The declared range `>=0.1.2-alpha.2 <0.3.0-0` covers both, and the HTTP wire
|
|
326
|
+
namespace stays `dsh-engram` on both generations (the seam's active namespace
|
|
327
|
+
drives mutations).
|
|
328
|
+
|
|
278
329
|
So: keep DSH on `0.1.1-rc.2` or older while running a release ≤ `0.3.6`, and
|
|
279
330
|
upgrade the plugin to `>=0.3.7` before moving DSH to `0.1.2-alpha.2`.
|
|
280
331
|
|
|
281
|
-
### Current release — `0.
|
|
332
|
+
### Current release — `0.5.0`
|
|
282
333
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
`
|
|
334
|
+
The published `0.4.0` declared `>=0.1.2-alpha.2 <0.2.0-0` — which the semver
|
|
335
|
+
gate **rejects on every DSH `0.2.0-0` prerelease** (`<0.2.0-0` excludes
|
|
336
|
+
`0.2.0-rc.x`), and its host settings half still called the `installSection`
|
|
337
|
+
API that `dsh-settings 0.1.7+` removed. `0.5.0` fixes **both**: the range
|
|
338
|
+
opens to `<0.3.0-0` (verified against DSH's own `includePrerelease` check, so
|
|
339
|
+
`0.2.0-rc.2` and the whole `0.2.x` line pass), and the settings card is
|
|
340
|
+
migrated onto the entry-id **volatile Config** model described above (with a
|
|
341
|
+
feature-detected legacy fallback).
|
|
286
342
|
|
|
287
343
|
| Component | Supported range |
|
|
288
344
|
| --- | --- |
|
|
289
|
-
| DSH runtime / host / client package family | `>=0.1.2-alpha.2 <0.
|
|
345
|
+
| DSH runtime / host / client package family | `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
290
346
|
| `@deepseek-ai/cordis` | `^4.0.2` |
|
|
291
347
|
| `@deepseek-ai/schemastery` | `^3.18.2` |
|
|
292
348
|
| Node.js | `>=22.19.0` |
|
|
293
349
|
|
|
294
|
-
`0.1.2-alpha.2` is the minimum version for this API family: host settings
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
`
|
|
299
|
-
|
|
300
|
-
|
|
350
|
+
`0.1.2-alpha.2` is the minimum version for this API family: host settings are
|
|
351
|
+
**feature-detected** — on DSH `≤0.1.5` they register the `dsh-engram`
|
|
352
|
+
namespace via `settings.installSection`; on `≥0.1.7` / `0.2.x` the form is the
|
|
353
|
+
plugin's `Config` with the 27 GUI knobs marked `.volatile()` (entry id
|
|
354
|
+
`engram`). The browser settings card reads and writes through the plugin's own
|
|
355
|
+
HTTP route (`/api/dsh-engram/settings`, see Route B above) on both. The full
|
|
356
|
+
regression suite (npm test 329/329, incl. the new settings-v2 coverage for the
|
|
357
|
+
volatile-Config model) passes against the DSH `0.2.0-rc.2` dependency set
|
|
358
|
+
(cordis 4.0.4 + schemastery 3.18.4 + cosmokit, matching the global DSH CLI).
|
|
359
|
+
The `.volatile()`/loader hot-commit path and the describe-side projection were
|
|
360
|
+
verified against the real `dsh-settings 0.2.0-rc.2` utilities, and a full
|
|
361
|
+
real-machine boot smoke on an isolated `dsh 0.2.0-rc.2` profile **passed**:
|
|
362
|
+
the plugin boots with no version-range denial, the settings card form is
|
|
363
|
+
served for entry `engram` (all 27 GUI knobs, incl. `trustedHosts`), and a
|
|
364
|
+
GET → PUT (`mutate` ops, revision 0→1) → unset round trip on
|
|
365
|
+
`/api/dsh-engram/settings` lands in the profile row and reads back. The older
|
|
301
366
|
`0.1.0-rc.7` and `0.1.1` API graphs are outside this release's compatibility
|
|
302
367
|
range.
|
|
303
368
|
|
|
304
369
|
To install the DSH version used for validation:
|
|
305
370
|
|
|
306
371
|
```sh
|
|
307
|
-
npm install --global @deepseek-ai/dsh@0.
|
|
372
|
+
npm install --global @deepseek-ai/dsh@0.2.0-rc.2
|
|
308
373
|
dsh --version
|
|
309
374
|
```
|
|
310
375
|
|
|
@@ -675,6 +740,82 @@ means that preset was customized (or has no compaction group) and was left untou
|
|
|
675
740
|
`dsh-compaction-basic unavailable` means the backend is missing and everything
|
|
676
741
|
falls back to the default compressor.
|
|
677
742
|
|
|
743
|
+
### BoundaryPrune (subtask-boundary pruning, default OFF)
|
|
744
|
+
|
|
745
|
+
Context GC owns *what a compaction summary says*; BoundaryPrune owns *when a
|
|
746
|
+
deterministic prune fires*: at todo-completion progress and goal terminal
|
|
747
|
+
events, it calls DSH's own `toolResultPruner` (deterministic surface-replace,
|
|
748
|
+
zero LLM) so long-stale over-threshold tool results stop replaying in every
|
|
749
|
+
later request. The two switches are independent.
|
|
750
|
+
|
|
751
|
+
- **Evidence chain** ([oracle analysis](docs/ORACLE-ANALYSIS.zh.md) +
|
|
752
|
+
[proposal](docs/PROPOSAL-resultpack.zh.md)): 97 real sessions measured —
|
|
753
|
+
2.77B–7.53B chars of tool-result replay exposure (~692M–1.88M tokens), 96%
|
|
754
|
+
of result bytes from bash/read/run_code; the counterfactual simulation says
|
|
755
|
+
todo boundaries cover 79% of that exposure and a repayment gate lifts
|
|
756
|
+
cache-aware net savings 12–32% on every threshold config.
|
|
757
|
+
- **Repayment gate**: a prune rewrites the prefix (one KV-cache break), so it
|
|
758
|
+
fires only while the session is still expected to run at least
|
|
759
|
+
`boundaryPruneMinRemaining` (default 50) more requests — expectation is a
|
|
760
|
+
workspace-history prior with ×2 growth projection past it, so long sessions
|
|
761
|
+
are never starved.
|
|
762
|
+
- **Honest activation surface**: sessions with no goal and no todo progress
|
|
763
|
+
simply never trigger (no boundary → no prune, zero side effects); the
|
|
764
|
+
corpus-wide dry run activates on 38% of sessions. If the pruner service is
|
|
765
|
+
absent the mechanism disables itself with one log line.
|
|
766
|
+
- **Boundary sources**: todo-progress completion and goal terminal events
|
|
767
|
+
(default), plus an optional **request-count cadence**
|
|
768
|
+
(`boundaryPruneIdleCadence`, default 0/off) — the "step idle" source that
|
|
769
|
+
covers the ~62% of sessions which never touch todo/goal (recon:
|
|
770
|
+
`eval/recon-idle-boundary.mjs`; +85% saved chars at cadence 50 in the
|
|
771
|
+
counterfactual `eval/simulate-idle-cadence.mjs`), still repayment-gated.
|
|
772
|
+
- **Threshold override**: `boundaryPruneThresholdChars` (default 0 → host's
|
|
773
|
+
8192). Set e.g. 2048 with smaller retained edges
|
|
774
|
+
(`boundaryPruneHeadChars`/`boundaryPruneTailChars`) to prune earlier —
|
|
775
|
+
T2048+small-edges lands 2.4× the first-prune savings of the host default on
|
|
776
|
+
the real corpus (10.14M vs 4.23M chars). Lowering the threshold is safe with
|
|
777
|
+
`resultPack` on, which archives the removed middles.
|
|
778
|
+
- Default **off**: `boundaryPrune: false`. When on, the log shows
|
|
779
|
+
`engram boundary-prune (todo @N reqs): pruned …`.
|
|
780
|
+
|
|
781
|
+
### ResultPack L2 (archive + `result_recall`, default OFF)
|
|
782
|
+
|
|
783
|
+
BoundaryPrune makes pruning lossless: the removed middle of every pruned
|
|
784
|
+
tool result is redacted (same rules as the memory write path) and archived to
|
|
785
|
+
`~/.dsh/engram/resultpack/<callId>.json`, and the pruned surface node gets a
|
|
786
|
+
tail handle — `[middle archived: result_recall(<callId>) 可取]` — so the model
|
|
787
|
+
knows the full result is one step away. `result_recall(callId, offset?)`
|
|
788
|
+
returns the archived middle in paged text blocks (progressive disclosure, the
|
|
789
|
+
same philosophy as `[ENGRAM]` → `engram_detail`, and the complete
|
|
790
|
+
ObservationPack pattern from SoL-Pi mechanism ③).
|
|
791
|
+
|
|
792
|
+
- **Lossless by construction**: L1 pruning shrinks the replay; L2 keeps the
|
|
793
|
+
original recoverable on demand — the "model rereads a pruned result" failure
|
|
794
|
+
mode goes to zero.
|
|
795
|
+
- **Scoped cost**: archives live outside the memory domain (big blobs never
|
|
796
|
+
bloat the domain JSON or the [ENGRAM] index); retention is a mtime sweep
|
|
797
|
+
(`resultPackRetentionDays`, default 7) riding the same GC cadence.
|
|
798
|
+
- **Self-disabling**: L2 without `boundaryPrune` has nothing to archive, so it
|
|
799
|
+
registers no tool and emits one warning.
|
|
800
|
+
- Default **off**: `resultPack: false` (must be on together with
|
|
801
|
+
`boundaryPrune: true`). When active the log shows
|
|
802
|
+
`engram result-pack enabled: result_recall(callId, offset) registered`.
|
|
803
|
+
|
|
804
|
+
### Activation telemetry (SoL-Pi M15/C13)
|
|
805
|
+
|
|
806
|
+
Mechanisms must be provably activating, and dormant ones are off by default.
|
|
807
|
+
`/api/dsh-engram/stats` (and the GUI overview) now answer
|
|
808
|
+
`activation: { boundaryPrune, recall }`:
|
|
809
|
+
|
|
810
|
+
- `boundaryPrune` — cumulative, durable record of real BoundaryPrune fires
|
|
811
|
+
(fires / prunedResults / charsRemoved / byKind todo|goal|step / lastFire),
|
|
812
|
+
written to `~/.dsh/engram/boundary-prune.status.json` on every landed prune,
|
|
813
|
+
independent of `resultPack`.
|
|
814
|
+
- `recall` — the injection leg of the recall funnel: how many `[RECALL]`
|
|
815
|
+
blocks actually made it into sessions (`recall-injections.json`), closing
|
|
816
|
+
the loop already measured from session logs (engram_recall queries → hits →
|
|
817
|
+
engram_detail follows) so you can see injection→query→detail activation.
|
|
818
|
+
|
|
678
819
|
## Auto-capture policy
|
|
679
820
|
|
|
680
821
|
Capture is deterministic and offline — it only sees tool *results*, never the
|
|
@@ -757,6 +898,15 @@ Defaults are token-conscious; override any key via the profile patch
|
|
|
757
898
|
- id: engram
|
|
758
899
|
config:
|
|
759
900
|
autoCapture: true # zero-LLM tool-result capture
|
|
901
|
+
autoCapturePreferences: true # zero-LLM user-correction/preference capture (prefer/avoid/switch-to cues)
|
|
902
|
+
preferenceCapturePerSession: 8 # per-session preference memory cap
|
|
903
|
+
boundaryPrune: false # ResultPack L1: prune stale over-threshold tool results at todo/goal boundaries (default OFF)
|
|
904
|
+
boundaryPruneThresholdChars: 0 # threshold override (0 = host 8192; e.g. 2048 prunes earlier)
|
|
905
|
+
boundaryPruneHeadChars: 0 # retained head under an override (0 = host 4096)
|
|
906
|
+
boundaryPruneTailChars: 0 # retained tail under an override (0 = host 1024)
|
|
907
|
+
boundaryPruneIdleCadence: 0 # request-count boundary for todo/goal-less sessions (0 = event-only)
|
|
908
|
+
resultPack: false # ResultPack L2: archive pruned middles + result_recall paged recall (default OFF; needs L1 on)
|
|
909
|
+
resultPackRetentionDays: 7 # archive retention days (mtime sweep on the GC cadence)
|
|
760
910
|
sessionSearch: true # engram_recall may also FTS past sessions
|
|
761
911
|
recallScope: workspace # recall scope: "workspace" (strict isolation, default) | "global" (opt-in cross-workspace recall with [W:<ws>] origin markers)
|
|
762
912
|
autoRecallOnStart: true # session-start auto recall (false = back to pure pull)
|
|
@@ -783,7 +933,7 @@ Defaults are token-conscious; override any key via the profile patch
|
|
|
783
933
|
## Development
|
|
784
934
|
|
|
785
935
|
```sh
|
|
786
|
-
npm test #
|
|
936
|
+
npm test # 291 tests: core + web API + GC + usage-observability + Context GC + ESR triggers + BoundaryPrune + preference learning (node:test)
|
|
787
937
|
npm run eval # offline recall + structure benchmark (deterministic)
|
|
788
938
|
npm run build:client
|
|
789
939
|
```
|
package/README.zh.md
CHANGED
|
@@ -17,6 +17,15 @@
|
|
|
17
17
|
+ 失败行)自动捕获为 `tags:["error","test"]`、信号上调。DSH **goal 域打通**:completed/blocked 的
|
|
18
18
|
goal(`goal/change` 会话事件)自动沉淀为 `handoff`/`error` 记忆(`tag:goal`),目标结局不随会话消散
|
|
19
19
|
(读取面见 `GET /api/dsh-engram/goals`)。
|
|
20
|
+
- **用户纠正/偏好学习(`autoCapturePreferences`,默认开,零 LLM)** — 「AI 犯错被纠正后,教训要留存」
|
|
21
|
+
([correx](https://github.com/ozoz5/correx)、[PAHF](https://arxiv.org/abs/2602.16173)、Mem0 偏好提取):
|
|
22
|
+
一个 `session/event` 监听器盯 `user/message`,用确定性纠正/偏好句式把用户话语沉淀为独立的
|
|
23
|
+
`preference` 记忆 kind——中文(`不要用X`、`改用X`、`以后统一用X`…)与英文(`don't use X`、
|
|
24
|
+
`switch to X`、`prefer X`、`never use X`…)模式,三种方向(`avoid` / `switch-to` / `prefer`),
|
|
25
|
+
并带疑问句 / 一次性操作指令 / 记忆工具元话语过滤器抑制误报。`preference` 记忆在 `[ENGRAM]`
|
|
26
|
+
块里**压过其它所有 kind**(`[R]` 前缀),让用户的长期规则成为每会话模型看到的第一行;
|
|
27
|
+
每会话上限 + 近期窗口去重与自动捕获同纪律。零 LLM、零向量、确定性纯函数——提取片段有界,
|
|
28
|
+
每条写入依旧先过密钥脱敏器。
|
|
20
29
|
- **符号索引 + 渐进披露** — 一个紧凑的 `[ENGRAM]` 块(默认预算 700 字符 ≈ 175 token;每条记忆一行)在
|
|
21
30
|
组装提示词时注入,并**按会话冻结**,让请求前缀字节稳定以复用 KV 缓存。模型需要细节时用
|
|
22
31
|
`engram_recall` / `engram_detail` 下钻,而不是把命中的原文灌进上下文。召回对内存池做
|
|
@@ -35,6 +44,10 @@
|
|
|
35
44
|
agentmemory 候选①)——相关记忆不依赖模型想起来就已在上下文里。纯规则、零 LLM、
|
|
36
45
|
纯读不 bump 命中;superseded 过期真相不占注入槽(仍可 `engram_detail` 重取);
|
|
37
46
|
与 `[ENGRAM]` 一起按会话冻结保持前缀稳定。
|
|
47
|
+
- **读路径激活(D)** — 命中条目的单行预览被截断(>140 字符)时带 `…` 标记,且块尾
|
|
48
|
+
引导行点名该具体 id:`#<id> truncated — engram_detail <id> (full) · engram_recall <query>`。
|
|
49
|
+
模型由此知道完整记录就在一次确定性 `engram_detail` 之后,而不是以为预览就是全文
|
|
50
|
+
(实证盲区:66 个会话 0 次 `engram_detail`——下钻路径此前对模型不可见)。
|
|
38
51
|
- **记忆间语义(supersede/contradict)** — `engram_store` 可选收 `supersedes` / `contradicts`
|
|
39
52
|
记忆 id(同工作区校验)。被 supersede 的「过期真相」在召回里**降级到尾部**、并从 `[ENGRAM]`
|
|
40
53
|
块中**剔除**(新陈述占行);被 contradicts 的记忆保留排序但标注 `· contradicted by <id>`。
|
|
@@ -151,6 +164,12 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
151
164
|
|
|
152
165
|
## 兼容性
|
|
153
166
|
|
|
167
|
+
<!-- dsh-market 兼容信息块 —— 与 docs/RELEASE-NOTES.TEMPLATE.md 的市场 README 公约保持一致 -->
|
|
168
|
+
|
|
169
|
+
- **DSH 版本**:`>=0.1.2-alpha.2 <0.3.0-0`(本版 `0.5.0`;已发布的 `0.3.7`、`0.4.0` 仍声明旧的 `0.1.x` 范围 `>=0.1.2-alpha.2 <0.2.0-0` —— 见下文矩阵)
|
|
170
|
+
- **最后验证日期**:2026-10-15 —— 设置模型迁移(entry-id volatile Config,兼容 DSH `0.2.x`)落地,npm test 329/329 通过;真实 `dsh 0.2.0-rc.2` 隔离 profile 运行烟测通过(见下文“当前发布”)
|
|
171
|
+
- **安装方式已验证**:`dsh plugin --profile web add dsh-engram`
|
|
172
|
+
|
|
154
173
|
> **一句话结论**:所有**已真正发布**的版本(`0.2.0` … `0.3.6`)**只支持旧版
|
|
155
174
|
> DSH**(`0.1.0-rc.7` / `0.1.1` API 图,peers `^0.1.0-rc.7`)。DSH
|
|
156
175
|
> `0.1.2-alpha.2` 及更新版本与它们**不兼容**——settings/client API 族在该版本
|
|
@@ -159,7 +178,8 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
159
178
|
| dsh-engram 发布版本 | 状态 | 支持的 DSH | 声明方式 |
|
|
160
179
|
| --- | --- | --- | --- |
|
|
161
180
|
| `0.2.0` … `0.3.6`(npm 全量 + GitHub v0.3.3–v0.3.6) | 已发布 | **仅旧版** —— `0.1.0-rc.7` / `0.1.0-rc.8` / `0.1.1-rc.1` / `0.1.1-rc.2` | peers `@deepseek-ai/dsh-*@^0.1.0-rc.7` |
|
|
162
|
-
| `0.3.7
|
|
181
|
+
| `0.3.7` / `0.4.0`(npm) | 已发布 | **新版 DSH,settings `installSection`** —— `>=0.1.2-alpha.2 <0.2.0-0` | `engines.dsh` + peers 同范围 |
|
|
182
|
+
| `0.5.0`(本期 / this release) | 预发布 | **DSH `0.1.2-alpha.2` … `<0.3.0-0`** —— 设置卡迁移到 entry-id volatile Config(`0.1.7+`/`0.2.x`),`≤0.1.5` 自动回退 `installSection` | `engines.dsh` + peers `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
163
183
|
|
|
164
184
|
### API 族断裂点:`0.1.2-alpha.2`
|
|
165
185
|
|
|
@@ -179,33 +199,59 @@ curl -s -X POST http://127.0.0.1:3080/api/dsh-engram/import \
|
|
|
179
199
|
HTTP 路由(`/api/dsh-engram/settings`,与记忆 viewer 同样的同源 fetch)读写
|
|
180
200
|
`dsh-engram` settings namespace,因此在 `0.1.2-alpha.2` 分界线两侧都是代际无关的。
|
|
181
201
|
|
|
202
|
+
**`0.1.7` / `0.2.0` 还有一次 settings 断裂**——`0.4.0` 在最新 DSH 上启动被拒的
|
|
203
|
+
真正原因:`@deepseek-ai/dsh-settings` 在 `0.1.7-alpha.2` **再次移除了
|
|
204
|
+
`settings.installSection`**(`0.2.x` 一路保留)。新设置模型是**条目式**的:可编辑字段
|
|
205
|
+
是插件自身 `Config` 的 `.volatile()` 字段(由 loader 校验并热提交),设置表单以
|
|
206
|
+
profile 条目 id(`engram`)为命名空间,不再需要任何“挂载”调用。`0.5.0`
|
|
207
|
+
在 `installEngramSettings` 里对两代际做特性检测:
|
|
208
|
+
|
|
209
|
+
- DSH `≥0.1.7` / `0.2.x` —— 27 个 GUI 旋钮即 `Config` 的 volatile 字段
|
|
210
|
+
(`lib/settings.js` `makeEngineConfigSchema`,由 `lib/index.js` 导出为
|
|
211
|
+
`Config`);卡片仍走同一 `/api/dsh-engram/settings` HTTP 路由读写条目 `engram`,
|
|
212
|
+
`service.settings` 接缝在 `loader/volatile-update` 事件上把 `resolved`
|
|
213
|
+
重新同步,卡片编辑对新会话即时生效。
|
|
214
|
+
- DSH `≤0.1.5` —— 照旧注册旧 `settings.installSection` 命名空间(`dsh-engram`)。
|
|
215
|
+
|
|
216
|
+
声明范围 `>=0.1.2-alpha.2 <0.3.0-0` 同时覆盖两代际;HTTP wire 命名空间在两代际都保持
|
|
217
|
+
`dsh-engram`(由接缝的活动命名空间驱动写入)。
|
|
218
|
+
|
|
182
219
|
所以:跑 ≤ `0.3.6` 的已发布版本时请把 DSH 保持在 `0.1.1-rc.2` 或更旧;升级
|
|
183
220
|
DSH 到 `0.1.2-alpha.2` 之前,先升级插件到 `>=0.3.7`。
|
|
184
221
|
|
|
185
|
-
### 当前发布版本 —— `0.
|
|
222
|
+
### 当前发布版本 —— `0.5.0`
|
|
186
223
|
|
|
187
|
-
|
|
188
|
-
`
|
|
224
|
+
已发布的 `0.4.0` 声明 `>=0.1.2-alpha.2 <0.2.0-0`——这个范围被 semver 门槛在
|
|
225
|
+
**所有 DSH `0.2.0-0` 预发布**上拒绝(`<0.2.0-0` 排除 `0.2.0-rc.x`),且其宿主设置端
|
|
226
|
+
仍在调用 `dsh-settings 0.1.7+` 已移除的 `installSection` API。`0.5.0`
|
|
227
|
+
**两处都修复**:范围放宽到 `<0.3.0-0`(用 DSH 自身的 `includePrerelease` 检查验证过,
|
|
228
|
+
`0.2.0-rc.2` 及整个 `0.2.x` 线都放行);设置卡迁移到上面描述的 entry-id **volatile
|
|
229
|
+
Config** 模型(并带特性检测的旧代际回退)。
|
|
189
230
|
|
|
190
231
|
| 组件 | 适配版本 |
|
|
191
232
|
| --- | --- |
|
|
192
|
-
| DSH runtime / host / client 包族 | `>=0.1.2-alpha.2 <0.
|
|
233
|
+
| DSH runtime / host / client 包族 | `>=0.1.2-alpha.2 <0.3.0-0` |
|
|
193
234
|
| `@deepseek-ai/cordis` | `^4.0.2` |
|
|
194
235
|
| `@deepseek-ai/schemastery` | `^3.18.2` |
|
|
195
236
|
| Node.js | `>=22.19.0` |
|
|
196
237
|
|
|
197
|
-
`0.1.2-alpha.2` 是这组 API
|
|
198
|
-
`settings.installSection
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
238
|
+
`0.1.2-alpha.2` 是这组 API 的最低版本:宿主设置注册按代际**特性检测**——DSH `≤0.1.5`
|
|
239
|
+
走 `settings.installSection` 注册 `dsh-engram` 命名空间;`≥0.1.7` / `0.2.x` 走插件
|
|
240
|
+
`Config`(27 个 GUI 旋钮标记为 `.volatile()`,条目 id `engram`)。浏览器设置卡在两代际
|
|
241
|
+
都经插件自有 HTTP 路由(`/api/dsh-engram/settings`,见上文 Route B)读写。完整回归
|
|
242
|
+
(npm test 329/329,含新增的 volatile-Config 模型 settings-v2 覆盖)在 DSH
|
|
243
|
+
`0.2.0-rc.2` 依赖集(cordis 4.0.4 + schemastery 3.18.4 + cosmokit,与全局 DSH CLI 同版本)
|
|
244
|
+
上通过;`.volatile()`/loader 热提交路径与 describe 侧投影已针对真实 `dsh-settings
|
|
245
|
+
0.2.0-rc.2` 工具函数验证;并在隔离的 `dsh 0.2.0-rc.2` profile 上完成了**真机启动烟测并
|
|
246
|
+
通过**:插件启动无版本范围拒绝、设置卡表单以条目 `engram` 对外提供(全部 27 个 GUI
|
|
247
|
+
旋钮,含 `trustedHosts`)、`/api/dsh-engram/settings` 的 GET → PUT(mutate ops,
|
|
248
|
+
revision 0→1)→ unset 往返落盘并读回。旧的 `0.1.0-rc.7` 与 `0.1.1` API 图不在
|
|
203
249
|
本发布版本的兼容范围内。
|
|
204
250
|
|
|
205
251
|
如需按验证版本安装 DSH:
|
|
206
252
|
|
|
207
253
|
```sh
|
|
208
|
-
npm install --global @deepseek-ai/dsh@0.
|
|
254
|
+
npm install --global @deepseek-ai/dsh@0.2.0-rc.2
|
|
209
255
|
dsh --version
|
|
210
256
|
```
|
|
211
257
|
|
|
@@ -327,10 +373,18 @@ npm run build:client
|
|
|
327
373
|
## 测试与评测
|
|
328
374
|
|
|
329
375
|
```sh
|
|
330
|
-
npm test #
|
|
376
|
+
npm test # 311 项单元测试(含 usage 滚动 / /stats 路由 / Context GC / ESR 触发 / BoundaryPrune)
|
|
331
377
|
npm run eval # 离线召回 + 结构基准(确定性语料,跑真实 store/recall 路径)
|
|
332
378
|
```
|
|
333
379
|
|
|
380
|
+
另有三个**会话语料分析工具**(零 LLM、确定性,读 `~/.dsh/sessions` 真实日志):
|
|
381
|
+
|
|
382
|
+
```sh
|
|
383
|
+
node eval/oracle-analysis.mjs # 浪费源量化:结果重放暴露 / 融合候选 / 机制激活率
|
|
384
|
+
node eval/simulate-boundary-prune.mjs # L0 反事实仿真:边界剪枝的预期节省与偿还门扫掠
|
|
385
|
+
node eval/dryrun-boundary-prune.mjs # BoundaryPrune 全量干跑:真实激活面与节省
|
|
386
|
+
```
|
|
387
|
+
|
|
334
388
|
`npm run eval` 的检索部分参照 LongMemEval 的问答式评测:受控语料(ASCII + CJK、标签/实体/时间戳已知),
|
|
335
389
|
对真实 `domain.recall()` 逐一校准 **Precision@k / Recall@k / MRR / Hit@1**(probe 覆盖 tag 精确、子串、
|
|
336
390
|
多词、CJK、短语唯一、标签排序、负样本无回);结构部分借鉴 StructMemEval:精确去重率(同文本存 3 次折叠为 1)、
|
|
@@ -487,6 +541,65 @@ Context GC 的装配在**两个平面**——web 现在**全部自动**,零配
|
|
|
487
541
|
- (若见 `… keeping the existing compaction service` 说明同域已有 provider、未替换成功;`web-provision … skipped (custom)`
|
|
488
542
|
说明某预设是自定义/无 compaction 布局、未被触碰;`dsh-compaction-basic unavailable` 说明环境缺依赖,自动回退默认压缩。)
|
|
489
543
|
|
|
544
|
+
### BoundaryPrune(子任务边界剪枝,默认关)
|
|
545
|
+
|
|
546
|
+
Context GC 管「压缩的摘要内容」,BoundaryPrune 管「确定性剪枝的触发时机」——
|
|
547
|
+
在 todo 完成推进 / goal 终态这些子任务边界,主动调用 DSH 自带的
|
|
548
|
+
`toolResultPruner`(确定性 surface-replace,零 LLM),把早已超阈值的旧工具
|
|
549
|
+
结果剪掉头尾保留,省掉它们在后续每个请求里的整段重放。两个开关互相独立。
|
|
550
|
+
|
|
551
|
+
- **证据链**([docs/ORACLE-ANALYSIS.zh.md](docs/ORACLE-ANALYSIS.zh.md) +
|
|
552
|
+
[docs/PROPOSAL-resultpack.zh.md](docs/PROPOSAL-resultpack.zh.md)):97 个真实
|
|
553
|
+
会话实测,工具结果重放暴露 2.77B–7.53B 字符(≈692M–1.88M token),96% 的
|
|
554
|
+
结果字节来自 bash/read/run_code;反事实仿真显示 todo 边界覆盖 79% 的暴露,
|
|
555
|
+
且偿还门在所有配置下提升净收益 12–32%。
|
|
556
|
+
- **偿还门**:剪枝会重写前缀(KV 缓存击穿一次),只有当会话预计还要跑
|
|
557
|
+
`boundaryPruneMinRemaining`(默认 50)个以上请求时才 fire——预计长度用
|
|
558
|
+
workspace 历史先验 + 超过后 ×2 外推(有界乐观),长会话不会被挡死。
|
|
559
|
+
- **诚实激活面**:goal=0 且无 todo 推进的会话天然不触发(无边界不剪,零副作用);
|
|
560
|
+
全量干跑 77 会话激活 38%。pruner 服务缺席即自动禁用并打一条日志。
|
|
561
|
+
- **边界源**:默认 todo 完成推进 / goal 终态事件;可选**空闲步数边界**
|
|
562
|
+
(`boundaryPruneIdleCadence`,默认 0=关)——覆盖约 62% 从不动 todo/goal 的
|
|
563
|
+
会话(侦察:`eval/recon-idle-boundary.mjs`;反事实:`eval/simulate-idle-cadence.mjs`
|
|
564
|
+
显示 cadence 50 时节省 +85%),仍受偿还门约束。
|
|
565
|
+
- **阈值覆盖**:`boundaryPruneThresholdChars`(默认 0=宿主 8192)。设为 2048
|
|
566
|
+
并配更小保留边缘(`boundaryPruneHeadChars`/`boundaryPruneTailChars`)可更早
|
|
567
|
+
开剪——T2048+小边缘在真实语料上首剪节省是宿主默认的 2.4 倍(10.14M vs 4.23M
|
|
568
|
+
字符)。降阈值在 `resultPack` 开启时安全(被剪中段有归档兜底)。
|
|
569
|
+
- 默认**关**:`boundaryPrune: false`。开启后启动日志出现
|
|
570
|
+
`engram boundary-prune (todo @N reqs): pruned …`。
|
|
571
|
+
|
|
572
|
+
### ResultPack L2(结果归档 + `result_recall`,默认关)
|
|
573
|
+
|
|
574
|
+
让 BoundaryPrune 剪枝**无损**:每个被剪工具结果的被移除中段,按与记忆写入
|
|
575
|
+
相同的规则脱敏后归档到 `~/.dsh/engram/resultpack/<callId>.json`,并在剪枝
|
|
576
|
+
节点尾部追加 handle——`[middle archived: result_recall(<callId>) 可取]`——
|
|
577
|
+
模型知道完整结果就在一步之遥。`result_recall(callId, offset?)` 按页返回
|
|
578
|
+
归档中段(渐进披露,与 `[ENGRAM]` → `engram_detail` 同一哲学,也是 SoL-Pi
|
|
579
|
+
机制③ ObservationPack 的完整形态)。
|
|
580
|
+
|
|
581
|
+
- **构造性无损**:L1 剪掉的是重放、L2 保留的是可随时取回的原文——「模型回头
|
|
582
|
+
找被剪结果」的失败模式归零。
|
|
583
|
+
- **成本受控**:归档在记忆域之外(大块内容永远不会撑大 domain JSON 或
|
|
584
|
+
[ENGRAM] 索引);保留期 `resultPackRetentionDays`(默认 7 天)按 mtime 清理,
|
|
585
|
+
搭 GC 同一节奏。
|
|
586
|
+
- **自我禁用**:只开 L2 不开 L1 将无内容可归档,故不注册工具并打一条警告。
|
|
587
|
+
- 默认**关**:`resultPack: false`(须与 `boundaryPrune: true` 同开)。开启后
|
|
588
|
+
启动日志出现 `engram result-pack enabled: result_recall(callId, offset) registered`。
|
|
589
|
+
|
|
590
|
+
### 激活遥测(SoL-Pi M15/C13)
|
|
591
|
+
|
|
592
|
+
机制必须可证明在激活,休眠机制默认关。`/api/dsh-engram/stats`(以及 GUI
|
|
593
|
+
overview)现在返回 `activation: { boundaryPrune, recall }`:
|
|
594
|
+
|
|
595
|
+
- `boundaryPrune`——BoundaryPrune 真实 fire 的累计持久记录(fires /
|
|
596
|
+
prunedResults / charsRemoved / byKind todo|goal|step / lastFire),每次剪枝
|
|
597
|
+
落盘到 `~/.dsh/engram/boundary-prune.status.json`,与 `resultPack` 无关。
|
|
598
|
+
- `recall`——召回漏斗的**注入腿**:实际进过会话的 `[RECALL]` 块数量
|
|
599
|
+
(`recall-injections.json`),与从 session log 已统计的另一端
|
|
600
|
+
(engram_recall 查询 → 命中 → engram_detail 下钻)闭合,可看到
|
|
601
|
+
注入→查询→下钻的完整激活。
|
|
602
|
+
|
|
490
603
|
## 自动捕获策略
|
|
491
604
|
|
|
492
605
|
捕获是确定性、离线的——只看到工具*结果*,从不看对话本身。什么会被记录成一条记忆:
|
|
@@ -557,6 +670,15 @@ promote: 2 pending todo(s) vs 1 ESR task(s) — esr_task(name="…") #suggest-pr
|
|
|
557
670
|
- id: engram
|
|
558
671
|
config:
|
|
559
672
|
autoCapture: true # 零 LLM 工具结果捕获
|
|
673
|
+
autoCapturePreferences: true # 零 LLM 用户纠正/偏好捕获(prefer/avoid/switch-to 句式)
|
|
674
|
+
preferenceCapturePerSession: 8 # 每会话偏好记忆条数上限
|
|
675
|
+
boundaryPrune: false # ResultPack L1:todo/goal 边界剪掉超阈值旧工具结果(默认关)
|
|
676
|
+
boundaryPruneThresholdChars: 0 # 阈值覆盖(0=宿主 8192;如 2048 可更早开剪)
|
|
677
|
+
boundaryPruneHeadChars: 0 # 覆盖时的保留头部(0=宿主 4096)
|
|
678
|
+
boundaryPruneTailChars: 0 # 覆盖时的保留尾部(0=宿主 1024)
|
|
679
|
+
boundaryPruneIdleCadence: 0 # 空闲步数边界(0=仅事件边界;覆盖无 todo/goal 会话)
|
|
680
|
+
resultPack: false # ResultPack L2:剪掉的中段脱敏归档 + result_recall 按页召回(默认关,须与 L1 同开)
|
|
681
|
+
resultPackRetentionDays: 7 # 归档保留天数(mtime 清理,走 GC 节奏)
|
|
560
682
|
sessionSearch: true # engram_recall 也可对历史会话 FTS
|
|
561
683
|
recallScope: workspace # 召回范围:workspace(严格工作区隔离,默认)| global(可选跨工作区召回,带 [W:<ws>] 来源标记)
|
|
562
684
|
autoRecallOnStart: true # 会话启动自动召回:按首条消息注入 [RECALL] 块(false=回到纯拉取)
|
|
@@ -575,6 +697,8 @@ promote: 2 pending todo(s) vs 1 ESR task(s) — esr_task(name="…") #suggest-pr
|
|
|
575
697
|
gcStableRetentionDays: 120 # 超过此天数的 stable 任务离开 [ESR]
|
|
576
698
|
gcReplacesCompaction: true # Context GC:接管 DSH 自动 compact(false=回退默认 LLM 压缩)
|
|
577
699
|
gcNarrative: true # 无锚轮次走 scoped LLM 叙事;false=纯机械(零 LLM)
|
|
700
|
+
boundaryPrune: false # BoundaryPrune:todo/goal 边界主动剪超阈值旧工具结果(默认关)
|
|
701
|
+
boundaryPruneMinRemaining: 50 # 偿还门:预计剩余请求数低于此值不剪
|
|
578
702
|
engramIndexOrder: 40 # systemPrompt section 顺序(位于 tools 段之前)
|
|
579
703
|
esrOrder: 41
|
|
580
704
|
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Oracle Analysis:真实会话 token 浪费源量化
|
|
2
|
+
|
|
3
|
+
> 方法论来自 [SoL-Pi](https://nvlabs.github.io/SoL-Pi/)(NVIDIA Labs):**动手造机制之前,先在真实轨迹上量化浪费源**("Oracle Analysis" / M6 "Use issue history and blind failure mining as proposal evidence" / M42 "Choose tasks with mechanism headroom before scaling")。
|
|
4
|
+
>
|
|
5
|
+
> 工具:`node eval/oracle-analysis.mjs`(流式解压 `~/.dsh/sessions`,零 LLM、确定性、约 90 秒跑完全量)。
|
|
6
|
+
|
|
7
|
+
## 语料
|
|
8
|
+
|
|
9
|
+
97 个真实会话日志(3 个 workspace 桶),13,900 次模型请求,15,020 次工具调用,65 轮 compaction,1,376 次会话中途 inbox splice。模型混合 local-vllm deepseek-v4-flash 为主,兼 glm-5.3 / qwen3.8-flash 等。
|
|
10
|
+
|
|
11
|
+
## M1 工具结果重放暴露(ObservationPack headroom,SoL-Pi C11/C23)
|
|
12
|
+
|
|
13
|
+
每个工具结果产生后,会在后续每个请求里重放(直到 compaction 改写历史)。exposure = Σ 结果字符 × 后续请求数:
|
|
14
|
+
|
|
15
|
+
| 口径 | 字符数 | ≈token(chars/4) |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| naive(无 compaction 截断,上界) | 7.53B | 1.88B |
|
|
18
|
+
| compaction 截断(下界) | 2.77B | 692M |
|
|
19
|
+
| 占「重放+固定开销」比重 | 57.6%(naive)– 21.2%(cut) | — |
|
|
20
|
+
|
|
21
|
+
- **top-10 结果占全会话结果字节的 46.1%(中位数)**——少数巨型输出承载了近一半的重放压力,正是 ObservationPack「归档载荷、留 handle+摘录」的靶子。
|
|
22
|
+
- 结果字节来源:**bash 14.2M + read 10.6M + run_code 6.1M ≈ 96%**。截断/归档机制只需覆盖这三个工具即可命中几乎全部暴露。
|
|
23
|
+
- 重放最重的会话(解析器开发,549–1,399 请求/会话)单会话重放高达 91–383Mc(23–96M token)——长时程会话正是 SoL-Pi 指出效率差异可测的场景。
|
|
24
|
+
|
|
25
|
+
**固定开销**(每个请求重发的 system+tools schema):全语料 436Mc ≈ 109M token,平均 ~7.8K token/请求;富预设(43 工具)单请求 schema 41.8Kc。**本插件自身 schema 仅 2.9Kc(≈730 token,占该预设 7%)——插件的开销主张成立。**
|
|
26
|
+
|
|
27
|
+
## M2 Action-Fusion headroom(SoL-Pi "Action Fusion")
|
|
28
|
+
|
|
29
|
+
编辑类调用(edit/write/str_replace_editor,共 1,993 次)之后**紧接着**由模型发起 bash(中间隔一次模型决策)的候选:607 次。
|
|
30
|
+
|
|
31
|
+
- 占全部工具调用 **4.0%**;占 bash 调用 **7.5%**;占步间转移 ~4.4%(SoL-Pi 在 Pi 上测得 12.3%,DSH 上 headroom 更小)。
|
|
32
|
+
- 结论:融合编辑+运行为单一工具调用是**上游 harness 的杠杆**,不是插件的;优先级排后。
|
|
33
|
+
|
|
34
|
+
## M3 engram 机制激活(SoL-Pi M15 "prove mechanism activation")
|
|
35
|
+
|
|
36
|
+
挂载插件的 66 个会话(全桶):
|
|
37
|
+
|
|
38
|
+
| 指标 | 值 |
|
|
39
|
+
|---|---|
|
|
40
|
+
| 有任何 engram/esr 工具调用 | 26/66(39.4%) |
|
|
41
|
+
| 显式 engram_recall | 6 会话(9.1%),共 8 次,命中 8/8 |
|
|
42
|
+
| engram_detail 下钻 | **0/66** |
|
|
43
|
+
| engram_store / esr_* | 76 / 38 次 |
|
|
44
|
+
|
|
45
|
+
**写路径激活良好,显式读路径近乎休眠**(autoRecallOnStart 的注入不走工具调用,本指标不可见——这本身就是个遥测缺口)。0 次 detail 说明渐进披露的第二层从未被用到:要么索引行已足够(设计成功,上下文成本仅 ~175 token/会话),要么模型从未想到下钻(机制休眠)。区分二者需要新增遥测:**记录每次 [ENGRAM] 注入后本会话是否发生 recall/detail,以及 recall 是否紧随索引覆盖的主题**。
|
|
46
|
+
|
|
47
|
+
## 副产品发现
|
|
48
|
+
|
|
49
|
+
- **1,376 次会话中途 splice**(agent/inbox/spliced)是 prompt 前缀抖动(C20)的主要来源,每次都可能击穿 KV 缓存、把重放从缓存价打回全价。
|
|
50
|
+
- 65 轮 compaction 集中在长会话;截断口径(naive vs cut)差异即来自它们。
|
|
51
|
+
|
|
52
|
+
## 下一个机制怎么选(按 headroom 排序)
|
|
53
|
+
|
|
54
|
+
1. **结果首插压缩(C11/C23)**:对 bash/read/run_code 输出在进入首个 prompt 前归档截断(保头保尾、留 handle、可分页召回)。靶子占结果字节 96%,且与 SoL-Pi 已在配对 A/B 中验证的 ObservationPack 同构。注意 KV 缓存折价与 1376 次 splice 击穿,收益按 token 占用与缓存击穿双口径核算。
|
|
55
|
+
2. **激活遥测(M15)**:给 /stats 增加「注入→下钻」漏斗计数,并做一次「仅索引 vs 索引+detail 工具」的 A/B,判定 detail 层是否该保留。
|
|
56
|
+
3. **Action Fusion**:作为上游 DSH 提案(4–7.5% headroom),不在本插件做。
|
|
57
|
+
|
|
58
|
+
## 口径与限制
|
|
59
|
+
|
|
60
|
+
- token 为 chars/4 估算(CJK 偏差存在,只用于量级)。
|
|
61
|
+
- KV 缓存未折价:重放 token 多数走缓存读价(约 1/10),但中途 splice/compaction 会击穿前缀,击穿部分按全价计——真实成本在两者之间。
|
|
62
|
+
- exposure 的真值介于 naive 与 cut 之间(compaction 摘要本身仍会重放,未计入)。
|
|
63
|
+
- 本机语料为单人三 workspace,非基准任务集;数字用于选机制,不宣称普适。
|