@a9i5k4/dsh-auto-memory 2.2.1 → 2.2.3
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/A3-RISK-ASSESSMENT-20260830.md +61 -0
- package/docs/COT-WATCH-RFC.md +88 -0
- package/docs/DUAL-TIER-RATIFICATION-PROMPT.md +71 -0
- package/docs/HANDOFF-HARNESS.md +78 -0
- package/docs/HANDOFF-M8-M9-M10.md +203 -0
- package/docs/HY4-TOUR-LOGO-HANDOFF-2.md +60 -0
- package/docs/HY4-TOUR-LOGO-HANDOFF.md +100 -0
- package/docs/ISSUE-REPLY-UNATTENDED.md +31 -0
- package/docs/K3-LANDING-HANDOFF.md +76 -0
- package/docs/LANDING-OUTLINE.md +85 -0
- package/docs/M-CM-PLAN.md +166 -0
- package/docs/M-CM-STATE.md +64 -0
- package/docs/M3B-CONTRACT.md +461 -0
- package/docs/M4-CONTRACT.md +1207 -0
- package/docs/M5-CONTRACT.md +383 -0
- package/docs/M6-CONTRACT.md +342 -0
- package/docs/M7-ACTIVATION-ALGO-REFERENCES.md +104 -0
- package/docs/M7-ACTIVATION-CALIBRATION.md +144 -0
- package/docs/M7-ACTIVATION-FEATURE-AGENT-PROMPT.md +79 -0
- package/docs/M7-ACTIVATION-FEATURE-CALIBRATION.md +58 -0
- package/docs/M7-ACTIVATION-FEATURE-DESIGN.md +124 -0
- package/docs/M7-ACTIVATION-V2-CONTROLLED-SHADOW.md +127 -0
- package/docs/M7-ACTIVATION-V2-HANDOFF.md +132 -0
- package/docs/M7-ACTIVATION-V2-HOLDEDOUT-EVAL.md +94 -0
- package/docs/M7-ACTIVATION-V2-HOLDEDOUT-SHADOW.md +60 -0
- package/docs/M7-ACTIVATION-V2-LIVE-SHADOW-PLAN.md +85 -0
- package/docs/M7-ACTIVATION-V2-PAPER.md +303 -0
- package/docs/M7-AGENT-HANDOFF-PROMPT.md +63 -0
- package/docs/M7-ALGORITHM-DECISION.md +174 -0
- package/docs/M7-AUTONOMOUS-STATE.md +252 -0
- package/docs/M7-BENCHMARK-PLAN.md +78 -0
- package/docs/M7-CLOSED-LOOP-WIRING.md +110 -0
- package/docs/M7-EMBEDDING-BENCHMARK.md +164 -0
- package/docs/M7-INTERFACE-DIGEST.md +144 -0
- package/docs/M7-LABEL-REVIEW-REPORT.md +107 -0
- package/docs/M7-LEXICAL-TUNING.md +58 -0
- package/docs/M7-LIVE-SHADOW-SCRIPT.md +30 -0
- package/docs/M7-PYTHON-IMPLEMENTATION-REPORT.md +92 -0
- package/docs/M7-RESEARCH-PAPER.md +442 -0
- package/docs/M7-TASKSET-DISPATCH.md +213 -0
- package/docs/M8-MEMORY-HUB.md +105 -0
- package/docs/MEMORY-SYSTEMS-SURVEY-2026-09.md +166 -0
- package/docs/NEXT-MAJOR-PROMO.md +363 -0
- package/docs/NEXT-MAJOR-README-DRAFT.zh.md +205 -0
- package/docs/NEXT-MAJOR-VISION.md +112 -0
- package/docs/PREVIEW-NEXT-STEPS.md +229 -0
- package/docs/PROJECT-FREEZE-AND-ROADMAP.md +200 -0
- package/docs/PROMO-STYLE-GUIDE.md +84 -0
- package/docs/PYTHON-SIDECAR-CONTRACT.md +539 -0
- package/docs/R2-POLICY-PLUMBING-BLUEPRINT.md +99 -0
- package/docs/RELEASE-READINESS-PLAN.md +91 -0
- package/docs/RELEASE-SEMANTIC-OPTION.md +181 -0
- package/docs/S1-SCIENTIFIC-RIGOR.md +269 -0
- package/docs/S2-DEEP-ABSORPTION.md +259 -0
- package/docs/S3-TARGET-ARCHITECTURE.md +172 -0
- package/docs/USER-GUIDE.zh-CN.md +98 -0
- package/docs/banner.jpg +0 -0
- package/docs/implementation-handoff-context.zh-CN.md +429 -0
- package/docs/landing/index.html +1745 -0
- package/docs/paper-figures/fig1_model_quality.png +0 -0
- package/docs/paper-figures/fig2_chunk_reversal.png +0 -0
- package/docs/paper-figures/fig3_latency.png +0 -0
- package/docs/paper-figures/fig4_hybrid.png +0 -0
- package/docs/paper-figures/fig5_rerank_tradeoff.png +0 -0
- package/docs/paper-figures/fig6_cluster_sweep.png +0 -0
- package/docs/paper-figures/fig7_resource.png +0 -0
- package/docs/paper-figures-v2/fig1_echo_trap.png +0 -0
- package/docs/paper-figures-v2/fig2_pr_paths.png +0 -0
- package/docs/paper-figures-v2/fig3_coefficients.png +0 -0
- package/docs/paper-figures-v2/fig4_calibration.png +0 -0
- package/docs/paper-figures-v2/fig5_order_ablation.png +0 -0
- package/docs/paper-figures-v2/fig6_containment.png +0 -0
- package/docs/proactive-associative-memory-architecture.html +659 -0
- package/docs/proactive-associative-memory-meta-code.html +1058 -0
- package/docs/proactive-associative-memory-research-report.zh-CN.md +685 -0
- package/docs/proactive-associative-memory-system-map.html +1580 -0
- package/docs/promo/first-run-guide.html +397 -0
- package/docs/promo/homepage.html +384 -0
- package/docs/screenshots/calendar-en.png +0 -0
- package/docs/screenshots/calendar-zh.png +0 -0
- package/docs/screenshots/connect-en.png +0 -0
- package/docs/screenshots/connect-zh.png +0 -0
- package/docs/screenshots/main-connect-en.png +0 -0
- package/docs/screenshots/main-connect-zh.png +0 -0
- package/docs/screenshots/overview-en.png +0 -0
- package/docs/screenshots/overview-zh.png +0 -0
- package/docs/screenshots/panel-hub.png +0 -0
- package/docs/screenshots/panel-overview.png +0 -0
- package/docs/screenshots/panel-refine.png +0 -0
- package/docs/screenshots/promo/promo-0-banner-v2.png +0 -0
- package/docs/screenshots/promo/promo-1-hero.png +0 -0
- package/docs/screenshots/promo/promo-2-tour.png +0 -0
- package/docs/screenshots/promo/promo-3-recall.png +0 -0
- package/docs/screenshots/promo/promo-4-unattended.png +0 -0
- package/docs/screenshots/promo/promo-5-external.png +0 -0
- package/docs/screenshots/promo/promo-6-greeting.png +0 -0
- package/docs/screenshots/reflections-en.png +0 -0
- package/docs/screenshots/search-zh.png +0 -0
- package/docs/screenshots/settings-2-zh.png +0 -0
- package/docs/screenshots/settings-debug-zh.png +0 -0
- package/docs/screenshots/settings-en.png +0 -0
- package/docs/screenshots/settings-zh.png +0 -0
- package/docs/screenshots/tour-core.png +0 -0
- package/docs/screenshots/tour-external.png +0 -0
- package/docs/screenshots/tour-toggles.png +0 -0
- package/docs/screenshots/tour-welcome.png +0 -0
- package/docs/screenshots/workspace-map-zh.png +0 -0
- package/docs/social-preview.png +0 -0
- package/lib/client.js +207 -4
- package/lib/index.js +25 -5
- package/package.json +3 -1
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
# S1:科学性补强与跨项目借鉴规划
|
|
2
|
+
|
|
3
|
+
> 写于 2026-09-06。上位文档:[NEXT-MAJOR-VISION.md](NEXT-MAJOR-VISION.md)(愿景权威)、[M-CM-PLAN.md](M-CM-PLAN.md)(当前大版本实施蓝图)。
|
|
4
|
+
> **本文件是并行线,不打断 M-CM1..4。** 定位:把 M7 已有的工程严谨度升级为可对外发表、可横向比较的科研产出。
|
|
5
|
+
> 对标对象:OpenViking(volcengine,AGPLv3,35.7k★)、Hindsight(vectorize-io,MIT,22.7k★,ACL 2026 Demo)。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 0. 许可证:务实分级(2026-09-06 修订,取代此前"禁读源码"的保守立场)
|
|
10
|
+
|
|
11
|
+
> **修订说明**:初版写"禁止阅读源码"过于保守,会因噎废食——照做只能临摹个样子,拿不到真正的质量。以下为务实分级。
|
|
12
|
+
|
|
13
|
+
### 法律事实(不是法律意见,建议重大决策前咨询律师)
|
|
14
|
+
|
|
15
|
+
- 版权保护**表达**,不保护**思想、程序、方法、系统、算法**。AGPLv3 约束的是"衍生作品",不是"知识"。
|
|
16
|
+
- 真正的红线不是"能不能读",而是"**你的实现是不是它的衍生作品**"。
|
|
17
|
+
- AGPLv3 的传染性触发于**分发/提供网络服务**时的衍生作品;**阅读本身不构成侵权**(无 NDA/EULA 禁止反向工程的前提下)。
|
|
18
|
+
|
|
19
|
+
### 三档操作边界
|
|
20
|
+
|
|
21
|
+
| 档 | 行为 | 风险 | 说明 |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| **绿区** | 读源码理解原理;学算法思想;学参数选择(BM25 k1=1.2 是行业默认值,非其独创);**学它踩过的坑与实测数据**(issue #3956 / #3250 / 线程池 benchmark) | **无** | 经验知识不受版权保护。**且这恰恰是最值钱的部分** |
|
|
24
|
+
| **黄区** | 对齐数据结构字段名;照搬 prompt 模板措辞 | **中** | prompt 具独创性,接近"表达";字段名对齐会成为"接触+实质相似"的佐证 |
|
|
25
|
+
| **红区** | 复制代码块;逐行翻译式改写;fork 后改 | **高** | 明确构成衍生作品 |
|
|
26
|
+
|
|
27
|
+
### 结论:合规与高质量不矛盾
|
|
28
|
+
|
|
29
|
+
**质量的来源是理解深度,不是复制粘贴。** 真正拉开差距的是他们踩过的坑(RRF 加权为何崩、长查询 BM25 为何超时、中文时间解析为何要单开 86KB 规则文件)——这些是纯经验知识,全部落在绿区,且比代码本身更值钱。
|
|
30
|
+
|
|
31
|
+
### 优先级策略
|
|
32
|
+
|
|
33
|
+
1. **Hindsight(MIT)优先深挖** —— 协议风险低,实现深度最高(`consolidator.py` 157KB + 测试 138KB)。
|
|
34
|
+
2. **OpenViking(AGPLv3)取架构不取代码** —— 其核心卖点(文件系统隐喻、L0/L1/L2、目录递归检索)在论文 VikingMem arXiv:2605.29640 与公开 README 中已完整描述,无需读源码即可获得架构层价值。
|
|
35
|
+
3. 实现纪律:**用不同的数据结构与代码组织独立实现,不复制任何片段**。黄区行为(照搬 prompt 措辞)一律避免——改写成我们自己的表达。
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
## 1. 诊断:别妄自菲薄,你已经有四件硬资产
|
|
40
|
+
|
|
41
|
+
你的自评是"科学性欠缺",但对账下来,**M7 的 rigor 已经超过大多数 ACL/EMNLP 投稿**:
|
|
42
|
+
|
|
43
|
+
| 资产 | 已有证据 | 学术圈怎么看 |
|
|
44
|
+
|------|---------|-------------|
|
|
45
|
+
| **预注册** | `M7-BENCHMARK-PLAN.md` 冻结版:研究问题先写、决策规则先写、阈值先定、事后**零重调参** | 这是很多论文做不到的。叫 preregistration,是可写进 method 的加分项 |
|
|
46
|
+
| **人工金标 held-out** | 69 条 proposed 全部人工审核,含 2 条 override 如实转写、2 条 deferred 明示不计 | 比"合成标签冒名 gold"强得多,而你已经主动废弃了那份 |
|
|
47
|
+
| **统计 rigor** | actPrecision 0.917,CI95 [0.727, 1.0],**pairId 聚类 bootstrap B=2000** | 聚类 bootstrap 是对的(样本非独立),多数记忆系统论文只报点估计 |
|
|
48
|
+
| **分层报告 + 泄漏覆盖披露** | 9 个分层,主动声明"本批无 harmful 专项样本,由训练侧重放覆盖" | 主动披露覆盖缺口,这是诚实性加分 |
|
|
49
|
+
|
|
50
|
+
**真正的 gap 只有三个,且都不在"态度"而在"可比较性":**
|
|
51
|
+
|
|
52
|
+
1. **没有对外可比的数字** —— 外界只看到"内部 67 条 held-out 上 0.917",无法与 Hindsight 的 LongMemEval 91.4%、OpenViking 的 LoCoMo 82.08% 放到同一张表上。
|
|
53
|
+
2. **没有消融实验(ablation)** —— 证明不了"每个组件各自贡献多少"。审稿人第一问就是这个。
|
|
54
|
+
3. **检索层缺时间维度** —— `shadow-retrieval-pre.js` 里有 lexical(32 处)/ recency(5 处),但 **temporal=0、graph=0、rrf=0**。而时序推理恰是 LongMemEval 最难的一类,也是 MetaMem 论文里收益最大的一类。
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 2. 取 Hindsight:记忆结构与检索(补第 3 个 gap)
|
|
59
|
+
|
|
60
|
+
### 2.1 【P0】时间检索臂 —— 最高优先级
|
|
61
|
+
|
|
62
|
+
**缺口**:`fact-store-pre.js` 有 `confidence`(17 处)/ `supersede`(11 处),**无 `occurredAt`/`eventDate` 类字段**;检索侧无时间臂。
|
|
63
|
+
|
|
64
|
+
**取什么**(来自论文 arXiv:2512.12818 与公开文档,非源码):
|
|
65
|
+
|
|
66
|
+
- 事实抽取增加 **时间三元组**:`occurredStart` / `occurredEnd` / `mentionedAt`
|
|
67
|
+
- 事实文本拼**日期上下文后再嵌入**("把日期拼进文本"是 Hindsight 的关键细节,对时序检索命中率影响很大)
|
|
68
|
+
- 检索加第四臂:**时间窗过滤 → 时间邻近加权**
|
|
69
|
+
|
|
70
|
+
**落点**:
|
|
71
|
+
- schema:`fact-store-pre.js` / `episodic-store-pre.js`
|
|
72
|
+
- 抽取 prompt:`python/worker_semantic_pre_v1.py`(事实抽取侧)
|
|
73
|
+
- 检索:`shadow-retrieval-pre.js`(在 lexical + 语义 + recency 之外加 temporal 臂)
|
|
74
|
+
- 索引同步:`index-sync-pre.js` / `m7-index-sync-host-pre.js`
|
|
75
|
+
|
|
76
|
+
**验收**:在现有 67 条 held-out 上,时序类子集 Recall@5 提升且有 bootstrap CI 不重叠(B=2000,同上口径)。
|
|
77
|
+
|
|
78
|
+
### 2.2 【P1】supersede 改为"时间标记双态",不覆盖
|
|
79
|
+
|
|
80
|
+
**缺口**:现有 `supersede` 需确认是否为物理覆盖。
|
|
81
|
+
|
|
82
|
+
**取什么**:矛盾不覆盖,存成"used to X, now Y",保留双态历史。Hindsight 的 consolidation 规则:冗余→UPDATE;**矛盾→时间标记双态**;不同人/主题不合并。
|
|
83
|
+
|
|
84
|
+
**为什么对我们更值钱**:我们的场景是长期陪伴 + 代码演进,"上周用 A 方案,本周换 B"是常态,覆盖会丢掉"为什么换"这条最有价值的信息。且这与 §2.4 的 30 天蒸馏"绝不丢信息"原则同源。
|
|
85
|
+
|
|
86
|
+
**落点**:`fact-store-pre.js` supersede 语义 + 蒸馏泵(`memory-writer-pre.js`)。
|
|
87
|
+
|
|
88
|
+
### 2.3 【P1】轻量链接结构(**不要上图数据库**)
|
|
89
|
+
|
|
90
|
+
**缺口**:`graph` 出现 0 次。
|
|
91
|
+
|
|
92
|
+
**取什么**:Hindsight 建四类链接——entity / temporal(24h 窗口共现加权)/ semantic(top-5 近邻 ≥0.7)/ causal(LLM 抽取)。
|
|
93
|
+
|
|
94
|
+
**我们的克制版**(零依赖约束下):
|
|
95
|
+
- 用**倒排索引**代替图:`entity → [memoryId]`,存在 `memory-index-pre.js` 已有的索引结构旁
|
|
96
|
+
- 先做 **entity link + temporal link** 两类;causal 交给现有子代理在固化时顺带抽(不新增链路)
|
|
97
|
+
- semantic link 用现有向量近邻即可,不必单独存
|
|
98
|
+
|
|
99
|
+
**明确不做**:不引 Neo4j / Kuzu / 任何图 DB。我们有"0GB 词法保底 → 130MB → 563MB"的分级承诺,图 DB 会直接摧毁这个卖点。
|
|
100
|
+
|
|
101
|
+
### 2.4 【P1】RRF 对照融合 —— 既是改进也是一篇消融
|
|
102
|
+
|
|
103
|
+
**缺口**:`rrf`/`reciprocal`/`fusion` 均为 0,现为 D6 **加权融合**。
|
|
104
|
+
|
|
105
|
+
**判断**:加权融合在有标定数据时通常**优于** RRF(RRF 不调参、更鲁棒但不利用标定)。所以**不要直接换**,要做**对照实验**:
|
|
106
|
+
|
|
107
|
+
- 加一条 RRF(k=60) 融合分支,与现有加权融合在**同一 held-out 同一指标**上对照
|
|
108
|
+
- 结论无论谁赢都是有效结果:加权赢 = 证明标定融合的价值;RRF 赢 = 证明免调参的鲁棒性
|
|
109
|
+
- 这正是审稿人要的消融
|
|
110
|
+
|
|
111
|
+
**落点**:`shadow-retrieval-pre.js` 增加可切换融合策略(复用"一切皆开关"的设置页机制)。
|
|
112
|
+
|
|
113
|
+
### 2.5 【P2】consolidation 趋势分类
|
|
114
|
+
|
|
115
|
+
**取什么**:Hindsight 给 observation 打趋势标签——`STABLE` / `STRENGTHENING` / `WEAKENING` / `NEW` / `STALE`(按证据时间戳计算),STALE 的可降权或归档。
|
|
116
|
+
|
|
117
|
+
**我们的映射**:现有"90 天未用自动归档"(技能固化)已是 STALE 的粗糙版,可以统一成一套趋势字段,交给记忆中枢页签展示。
|
|
118
|
+
|
|
119
|
+
**落点**:`memory-writer-pre.js` / `storage-manage-pre.js` + 记忆中枢页签。
|
|
120
|
+
|
|
121
|
+
### 2.6 【不取】opinion 网络
|
|
122
|
+
|
|
123
|
+
Hindsight 论文描述了 world / experience / observation / opinion 四个网络,但**其当前代码库 `VALID_RECALL_FACT_TYPES` 只剩三个,opinion 已通过 Alembic 迁移删除**。这是他们自己验证失败的方向,我们不取。
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## 3. 取 OpenViking:上下文经济与可观测
|
|
128
|
+
|
|
129
|
+
### 3.1 【P0】L0/L1/L2 分层 + **token 账本**
|
|
130
|
+
|
|
131
|
+
**现状**:我们已有注入形态三级(checklist / excerpt / hint,高风险自动降级 hint)——**思想上已经对了,缺的是量化**。
|
|
132
|
+
|
|
133
|
+
**取什么**(公开 README 口径,非源码):
|
|
134
|
+
- 每条记忆生成 **L0 摘要(~100 token)/ L1 概览(~2k token)/ L2 原文** 三层
|
|
135
|
+
- 注入时先用 L0 判断相关性,命中才升级读 L1/L2
|
|
136
|
+
- 目录/分组本身也带 L0/L1,读全文前先判断这个分组值不值得钻
|
|
137
|
+
|
|
138
|
+
**我们最该抄的是它的对外指标**:OpenViking 敢报"输入 token 减少 34.3–91.0%",因为有账本。
|
|
139
|
+
|
|
140
|
+
**落地**:建立 **token 账本**——每次注入记录:候选记忆数、L0 筛选前/后 token、实际注入 token、若无分层的朴素注入 token(反事实基线)。产出我们自己的"token 节省率 + 区间"。
|
|
141
|
+
|
|
142
|
+
**为什么这是最高性价比的一项**:它把我们已经做对的事变成**一个对外可引用的数字**,直接补上 §1 的 gap 1。
|
|
143
|
+
|
|
144
|
+
**落点**:`context-host-pre.js`(注入侧,`:1936` renderMemoryDynamic 附近)、新增 `lib/inject-ledger-pre.js`(账本落 JSONL)。
|
|
145
|
+
|
|
146
|
+
### 3.2 【P1】记忆 URI 命名空间
|
|
147
|
+
|
|
148
|
+
**取什么**:OpenViking 用 `viking://resources/...`、`viking://user/{id}/memories/...` 让每个上下文有唯一 URI。
|
|
149
|
+
|
|
150
|
+
**我们的映射**:`dsh://ws/{workspace}/memories/{id}`、`dsh://ws/{ws}/handoff/{ts}`、`dsh://user/prefs/{key}`。
|
|
151
|
+
|
|
152
|
+
**为什么现在做最划算**:M-CM2 要扩展 `memory_recall` 的 scope(notes/logs/reflections/handoff/sessions),M-CM3 要给会话帧加 provenance——**两者都需要稳定的引用标识**。URI 不是新功能,是给 M-CM 打地基。
|
|
153
|
+
|
|
154
|
+
**落点**:与 M-CM2/3 同批,复用到 M5 cite 规范。
|
|
155
|
+
|
|
156
|
+
### 3.3 【P2】检索轨迹结构化落盘
|
|
157
|
+
|
|
158
|
+
**现状**:已有 evidence 链 + 唤起回顾页(A/P/S/H/E 五档复核)——**已经比 OpenViking 强**,他们只是可视化目录浏览轨迹。
|
|
159
|
+
|
|
160
|
+
**补什么**:把每次激活决策的完整路径落成 JSONL——各臂命中与分数、阈值、margin、echo veto 是否触发、最终决策。
|
|
161
|
+
|
|
162
|
+
**双重收益**:① 可观测性;② **它就是消融实验的数据源**(§4.2 直接消费)。
|
|
163
|
+
|
|
164
|
+
**落点**:`activation-host-pre.js` 决策出口。
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## 4. 科学性补强(补 §1 的 gap 1 和 gap 2)
|
|
169
|
+
|
|
170
|
+
### 4.1 标准基准对齐 —— **对齐分类法,不是换数据集**
|
|
171
|
+
|
|
172
|
+
**误区**:不要去跑 LongMemEval 原始数据。它是英文、通用对话场景,与我们的"中文 + 代码 + 跨工作区 + 主动注入"场景不匹配,硬跑只会得到一个不好看也不说明问题的数字。
|
|
173
|
+
|
|
174
|
+
**正确做法**:自建基准,但**任务分类法对齐 LongMemEval**:
|
|
175
|
+
|
|
176
|
+
| LongMemEval 类别 | 我们的对应构造 |
|
|
177
|
+
|---|---|
|
|
178
|
+
| 信息抽取(single-session) | 单会话事实回忆 |
|
|
179
|
+
| 多会话推理 | 跨工作区/跨会话整合 |
|
|
180
|
+
| **时序推理** | "上周 vs 本周"、方案演进顺序 ← **我们有真实数据优势** |
|
|
181
|
+
| 知识更新 | supersede 后的正确答案 |
|
|
182
|
+
| 弃权(abstention) | 该不该注入(**这是他们没有的维度**) |
|
|
183
|
+
|
|
184
|
+
然后可以说:"在时序推理这一类上我们 X%,Hindsight 公开数字 Y%"——**分类法对齐,数字才可比**。
|
|
185
|
+
|
|
186
|
+
**额外加分项**:LongMemEval 没有"主动注入"这一维度。我们的基准里应单列 **proactive lane**(这正是 §5 的论文卖点)。
|
|
187
|
+
|
|
188
|
+
### 4.2 消融矩阵 —— 现在最缺的一项
|
|
189
|
+
|
|
190
|
+
**我们的天然优势**:README 主打"一切皆开关"。**每个开关就是一次消融。** 学术项目要改代码才能做消融,我们改配置就行。
|
|
191
|
+
|
|
192
|
+
必做消融(逐个关闭,测 Δ):
|
|
193
|
+
|
|
194
|
+
| 消融项 | 预期发现 |
|
|
195
|
+
|---|---|
|
|
196
|
+
| 关词法臂(仅语义) | 代码/错误码/专名场景崩塌 → 证明 BM25 不可替代 |
|
|
197
|
+
| 关语义臂(仅词法) | 跨语言、同义改写崩塌 |
|
|
198
|
+
| 关 recency 加权 | 时效类查询退化 |
|
|
199
|
+
| 关时间臂(新增后) | 时序推理退化 ← 证明 §2.1 的价值 |
|
|
200
|
+
| 关 echo veto | 误激活率上升 ← 证明我们的原创发现 |
|
|
201
|
+
| 关巩固/蒸馏 | 长期一致性退化 |
|
|
202
|
+
| 加权融合 vs RRF | 见 §2.4 |
|
|
203
|
+
|
|
204
|
+
**输出形态**:一张 Δ 表 + 每个 Δ 的 bootstrap CI。这就是论文 Table 3。
|
|
205
|
+
|
|
206
|
+
### 4.3 统计 rigor 补强
|
|
207
|
+
|
|
208
|
+
已有:聚类 bootstrap(B=2000)、CI95、分层报告、泄漏披露。补:
|
|
209
|
+
|
|
210
|
+
- **配对显著性**:同一 held-out 上两版策略逐条对比,用 McNemar 检验或差值 bootstrap CI(比"两个 CI 不重叠"更严谨)
|
|
211
|
+
- **效应量**:不只报 p,报 Cohen's h 或 Δ 绝对值
|
|
212
|
+
- **多重比较校正**:9 个分层 × 多个指标,需 Benjamini-Hochberg 控制 FDR
|
|
213
|
+
- **样本量论证(power analysis)**:67 条能检出多大的效应?诚实写出 MDE(最小可检出效应)。这一条会直接回应"样本是不是太小"的质疑——**主动承认边界比被问出来强**
|
|
214
|
+
|
|
215
|
+
### 4.4 预注册 —— 你已经在做,要显式命名
|
|
216
|
+
|
|
217
|
+
`M7-BENCHMARK-PLAN.md` 的"冻结版 + 决策规则先写 + 零重调参"就是预注册。补两件事让它在论文里站得住:
|
|
218
|
+
|
|
219
|
+
1. held-out 数据**冻结时间戳 + 内容 hash** 写入报告,防事后数据污染质疑
|
|
220
|
+
2. 任何"事后发现→改策略"必须新开版本号,旧结论保留不覆盖(我们已有 `configHash` 机制,直接复用)
|
|
221
|
+
|
|
222
|
+
### 4.5 外部可复现包
|
|
223
|
+
|
|
224
|
+
现在复现依赖 3080 与用户本机数据。建议出一个 **fixture-only 公开复现包**:不联网、不含用户数据、纯 Node 可跑(M7-2 已有 CI fixture vectors,扩展即可)。
|
|
225
|
+
|
|
226
|
+
**收益**:审稿人/用户能一键复现我们的核心数字,这是可信度的分水岭。
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 5. 你的独门武器(他们都没有,这是论文定位)
|
|
231
|
+
|
|
232
|
+
| 我们的资产 | OpenViking | Hindsight | 说明 |
|
|
233
|
+
|---|---|---|---|
|
|
234
|
+
| **主动联想零指令注入** | ✗ 被动检索 | ✗ 被动检索 | 他们在"模型决定去查",我们在"模型开口前注入" |
|
|
235
|
+
| **前缀缓存字节级稳定** | ✗ | ✗ | 已发请求不可改写——工程上极难,是硬约束下的设计胜利 |
|
|
236
|
+
| **注入时机决策(whether to inject)** | ✗ | ✗ | 他们只做 **what to retrieve**,我们做 **whether to inject** |
|
|
237
|
+
| **echo veto** | ✗ | ✗ | **原创发现**:20 条含 echo 样本零误激活,双臂 veto 在未见数据上成立 |
|
|
238
|
+
| **写入卫生闸门** | ✗ | ✗ | GBK 乱码 34 特征、复读退化、脏 token 扫描——生产级信任 |
|
|
239
|
+
| **本地优先 + 模型无关 + 跨宿主继承** | 部分 | 部分 | 我们 BSD-3 + 零依赖 + 三店本地 |
|
|
240
|
+
|
|
241
|
+
### 论文定位建议
|
|
242
|
+
|
|
243
|
+
**题目方向:《When to Inject, Not Just What to Retrieve》**
|
|
244
|
+
|
|
245
|
+
核心论点:现有记忆系统(OpenViking / Hindsight / Mem0 / Zep)全部优化的是**检索质量**(给定查询,找对内容);而宿主内插件面对的真实问题是**注入决策**——在没有显式查询时,是否该打断模型、注入什么、注入多少,且受"前缀缓存不可失效"的硬约束。我们形式化这个问题,给出特征-策略-门禁三级结构,并在人工金标 held-out 上验证。
|
|
246
|
+
|
|
247
|
+
**目标venue**:ACL/EMNLP Findings(短文)、CCL(中文)、或 CHI 的 HCI 侧(我们有真实用户可审计界面 + 白板外化认知,这块 CHI 很吃)。
|
|
248
|
+
|
|
249
|
+
**M7-RESEARCH-PAPER.md / M7-ACTIVATION-V2-PAPER.md 已是雏形**,按本文档 §4 补齐消融与基准对齐即可投稿。
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 6. 分期路线(不打断 M-CM)
|
|
254
|
+
|
|
255
|
+
| 期 | 内容 | 依赖 | 与 M-CM 关系 |
|
|
256
|
+
|---|---|---|---|
|
|
257
|
+
| **S1-a** | token 账本(§3.1)+ 检索轨迹落盘(§3.3) | 无 | 纯增量,不冲突 |
|
|
258
|
+
| **S1-b** | 时间检索臂(§2.1)+ 时间三元组 schema | 无 | 可与 M-CM3 会话帧索引共享 provenance 设计 |
|
|
259
|
+
| **S1-c** | 消融矩阵跑通(§4.2) | S1-a/b | 复用现有开关 |
|
|
260
|
+
| **S1-d** | 基准分类法对齐 + 公开复现包(§4.1/§4.5) | S1-c | 与 M-CM2 的 scope 扩展协同 |
|
|
261
|
+
| **S1-e** | 统计 rigor 补强 + 投稿(§4.3/§4.4) | S1-d | 大版本宣传可引用论文 |
|
|
262
|
+
|
|
263
|
+
**建议插入点**:M-CM1(交接笔记)完成后、M-CM2 开工前插入 S1-a——因为账本和轨迹都是观测性改动,零风险,且能在 M-CM2 改动检索路径前建立**改动前基线**。这个顺序很关键,事后再补基线就来不及了。
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## 7. 一句话
|
|
268
|
+
|
|
269
|
+
**他们的强项是"检索得准",我们的强项是"知道该不该说、什么时候说、说完还能审计"。前者是他们的论文,后者是我们的。** 科学性补强不是去追他们的数字,是把我们独有的那个问题——**注入决策**——用他们那套 rigor 标准证明出来。
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# S2:深度吸收 —— 从 Hindsight / OpenViking 源码挖出的实现细节
|
|
2
|
+
|
|
3
|
+
> 写于 2026-09-06。上位:[S1-SCIENTIFIC-RIGOR.md](S1-SCIENTIFIC-RIGOR.md)(含许可证分级)。
|
|
4
|
+
> **本文性质**:全部内容来自**实读源码**(非文档复述),标注了文件与行号。每条都附"他们踩过什么坑",因为**教训比代码更值钱**。
|
|
5
|
+
> 许可证纪律:Hindsight(MIT)可放心深挖;OpenViking(AGPLv3)只取论文/公开文档中的架构层结论,不读其源码。
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. 先说你的代码:不是"浅",是**分层不均**
|
|
10
|
+
|
|
11
|
+
实读 `lib/shadow-retrieval-pre.js`(673 行)后的判断:**你的决策层设计比 Hindsight 精细,基础设施层比他们薄。**
|
|
12
|
+
|
|
13
|
+
### 你做得比他们好的
|
|
14
|
+
|
|
15
|
+
| 你的实现 | 位置 | 对比 |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| 门控三级:硬抑制顺序 → 权重滞回 → cooldown | `gatePreV1` §347-395 | Hindsight 没有"是否该检索"这一层,它假设查询已存在 |
|
|
18
|
+
| 滞回防抖(hysteresisOn 0.65 / hysteresisOff 0.42) | §382 | 避免阈值抖动,Hindsight 无对应机制 |
|
|
19
|
+
| `DROP_REASONS` 版本化枚举,禁止自由文本驱动逻辑 | §85-101 | **比 Hindsight 严格**——他们用 Python 异常和日志字符串 |
|
|
20
|
+
| 真 Okapi BM25(idf + k1=1.2 饱和 + b=0.75 长度归一) | §519-524 | 很多人只做词频,你做对了 |
|
|
21
|
+
| 确定性重放(retrievalId/candidateId 全 sha256,可逐字段复现) | §404-414 | Hindsight 依赖数据库状态,重放困难 |
|
|
22
|
+
| 哈工大停用词表 + CJK 2-gram + NFKC + locale 无关 lowercase | §171-210 | 中文处理是对的 |
|
|
23
|
+
|
|
24
|
+
**结论**:Decision Layer 你已经赢了。差距在底下三层。
|
|
25
|
+
|
|
26
|
+
### 三个真实问题(读代码发现,非文档推测)
|
|
27
|
+
|
|
28
|
+
#### 问题 1:`queryTerms` 按**字典序**截断 —— 系统性丢词
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
// shadow-retrieval-pre.js:246
|
|
32
|
+
const terms = [...seenTerms.values()].sort((a, b) => (a.term < b.term ? -1 : a.term > b.term ? 1 : 0))
|
|
33
|
+
// :248
|
|
34
|
+
if (terms.length > SHADOW_LEXICAL_BUDGET_PRE_V1.queryTerms) {
|
|
35
|
+
terms.length = SHADOW_LEXICAL_BUDGET_PRE_V1.queryTerms // ← 保留字典序最小的 32 个
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
按字典序排序是为了确定性(对),但**截断也按字典序**就错了:保留的是 a-z 靠前的词,而**专有名词、错误码、版本号、中文 2-gram 往往排在后面**。长查询下会系统性丢掉最高信号的词。
|
|
39
|
+
|
|
40
|
+
→ **修法见 §2.2**(Hindsight 的 df-selective 选择),而且**你的 DF 已经算好了**(`:485-491`),直接复用即可,零额外成本。
|
|
41
|
+
|
|
42
|
+
#### 问题 2:BM25 无倒排,每次查询全量 tokenize
|
|
43
|
+
|
|
44
|
+
```js
|
|
45
|
+
// :486-492 —— 每次 lexicalSearch 都遍历全部 records 重新 tokenize 算 df
|
|
46
|
+
for (const rec of records) {
|
|
47
|
+
const toks = tokenize((rec.heading ? rec.heading + ' ' : '') + String(rec.text || ''))
|
|
48
|
+
totalTokens += toks.length; docTokensList.push(toks)
|
|
49
|
+
for (const tk of new Set(toks)) DF.set(tk, (DF.get(tk) || 0) + 1)
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`corpusRecords: 512` 意味着每次检索 tokenize 512 条全文。你设了 `deadlineCoreMs: 50`,规模一大必然超。
|
|
54
|
+
→ 增量倒排(term → posting list)+ 持久化 df,写入时更新而非查询时重算。
|
|
55
|
+
|
|
56
|
+
#### 问题 3:`recency` 只认 `workspace-log`,其他一律 0.5
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
// :537-547
|
|
60
|
+
let recency = 0.5
|
|
61
|
+
if (/workspace-log/.test(srcRef)) { /* 用文件名日期算 2^(-ageDays/30) */ }
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
项目笔记、用户级记忆、技能、反思**全部拿固定 0.5**。等于时间维度在这些层完全不存在。
|
|
65
|
+
|
|
66
|
+
> 注:`:549` 的 `0.72/0.15/0.08/0.05` 是 **M4 shadow 纯核心**(评估通路)的加权;**生产通路的融合在别处**,见下。
|
|
67
|
+
|
|
68
|
+
#### 问题 4(关键):生产融合层用 minmax 归一化,分数丧失绝对性
|
|
69
|
+
|
|
70
|
+
`lib/semantic-js-pre.js:33-63` `fuseD6Pre()` 是 C2 生产通路的融合:
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
const normOf = (v, arm) => { /* ... */ return (v - a.lo) / (a.hi - a.lo) } // minmax
|
|
74
|
+
fused = 0.7 * denseN + 0.3 * lexN
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
设候选集 $C$,原始分数 $d_i$(dense)/ $l_i$(lexical),归一化后 $\hat d_i = (d_i - d_{\min})/(d_{\max} - d_{\min})$。三个结构性缺陷:
|
|
78
|
+
|
|
79
|
+
1. **估计量依赖样本构成(non-stationary)**:$\hat d_i$ 是 $C$ 的函数而非 $d_i$ 的函数。同一条记忆在不同候选集中取值不同 → 门控阈值 $\tau$ 在 $\hat d$ 空间上**不具备跨查询稳定性**。
|
|
80
|
+
2. **矮子里拔将军(rank-preserving, relevance-destroying)**:当 $\max_C d$ 本身低于语义相关下界时,$\hat d_{\max}$ 仍为 1.0。一组全不相关的候选仍会被拉满至 $[0,1]$,绝对相关性信息被完全抹除。
|
|
81
|
+
3. **退化条件(degenerate case)**:$|C| \le 1$ 或极差为 0 时走 `flat` 分支记 0.5(`:48`),此时 $\forall i,\ \text{fused}_i = 0.7\times0.5 + 0.3\times0.5 = 0.5$,**排序完全失效**。
|
|
82
|
+
|
|
83
|
+
**为何对本插件尤其致命**:我们的核心命题是**注入决策(whether to inject)**,决策依赖分数与阈值的比较。若分数是相对量,则阈值只能表示"在本批候选中相对靠前",无法表达"确实相关"。这会直接腐蚀 M7 门控的语义基础,并使 held-out 上的阈值标定不可迁移。
|
|
84
|
+
|
|
85
|
+
**对照组**:Hindsight 在融合中**保留原始 cosine 相似度**(绝对量),仅在秩空间做 RRF(见 §2.1),再由 cross-encoder 给出绝对相关性分数量供重排与截断——三层均不破坏绝对性。
|
|
86
|
+
|
|
87
|
+
**建议解法**(按推荐度):
|
|
88
|
+
- **决策与排序解耦**:门控/截断用**绝对分数 + 校准阈值**(如 $\text{cosine} \ge \tau_{\text{abs}}$),融合分数仅用于批内排序。
|
|
89
|
+
- 若必须归一化,改用**对离群值稳健且不依赖批构成**的映射(如基于历史分数分布的分位数校准,或固定尺度 sigmoid)。
|
|
90
|
+
- 增补 $|C| < 3$ 的专门分支(当前会退化)。
|
|
91
|
+
- 验证:在既有 67 条 held-out 上,比较"minmax 融合 + 现阈值"与"绝对分数 + 校准阈值"的 precision / recall,配对 bootstrap(B=2000)给差值 CI。
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## 2. Hindsight 深挖:六项可吸收的实现细节
|
|
96
|
+
|
|
97
|
+
### 2.1 RRF 的陷阱 —— **修正我上一轮的错误建议**
|
|
98
|
+
|
|
99
|
+
我在 S1 里说"加权融合通常优于 RRF,做对照即可"。实读后要更正:**他们踩过一个更深的坑,值得直接吸收。**
|
|
100
|
+
|
|
101
|
+
`engine/search/recall_boost.py` 模块 docstring 完整记录了这个决策:
|
|
102
|
+
|
|
103
|
+
> **问题**:加权 RRF(score space)在 `k=60` 时会崩。RRF 分数在 300 候选窗口内只跨 `1/61 → 1/360`,**动态范围仅 5.9 倍**。任何 `w > 5.9` 的权重都超过秩项的全部动态范围,排序退化为**字典序**——被加权的臂填满全部槽位。
|
|
104
|
+
> **实测(issue #3956)**:`recall@20` 从 **0.97 掉到 0.40**。
|
|
105
|
+
|
|
106
|
+
**正确做法(rank-space boost)**:不要 `w * 1/(k+rank)`,改为 `1/(k + rank/divisor)`。
|
|
107
|
+
|
|
108
|
+
原因是代数上的:分数空间位移 `r_max = w*(k+s) - k`,头部被常数 `w*k` 支配,被加权臂的第 360 名能压过另一臂的第 1 名。改成除秩后 **k 项被消掉**,位移变成严格比例(`r < divisor*s`),永不反转头部,且**不依赖候选池大小**。
|
|
109
|
+
|
|
110
|
+
他们的分级(含模拟验证):
|
|
111
|
+
|
|
112
|
+
| level | rank_divisor | additive | 效果 |
|
|
113
|
+
|---|---|---|---|
|
|
114
|
+
| low | 2.0 | 0.05 | 留 100 槽给其他臂,被加权臂保护到 rank 200 |
|
|
115
|
+
| medium | 4.0 | 0.2 | 留 60 槽,保护到 rank 240 |
|
|
116
|
+
| high | 8.0 | 0.5 | 留 33 槽,保护到 rank 267 |
|
|
117
|
+
|
|
118
|
+
**对你的直接意义**:
|
|
119
|
+
- 你现在是**加权分数融合**(`0.72*term + 0.15*heading + 0.08*phrase + 0.05*recency`,`:549`),**不是**加权 RRF,所以不崩。
|
|
120
|
+
- 但权重有真问题:四个特征量纲不同(coverage 是 [0,1]、phraseMatch 是 0/1、recency 是指数衰减),`0.72/0.15/0.08/0.05` 缺乏标定依据,且 recency 0.05 太小。
|
|
121
|
+
- **吸收点**:若将来引入多臂(语义/图/时间),**必须用 rank-space boost,绝不能用 score-space 加权**。这个坑你现在知道,可以一次做对。
|
|
122
|
+
|
|
123
|
+
### 2.2 长查询 BM25:保留 df 最低的词,不是前 N 个
|
|
124
|
+
|
|
125
|
+
`engine/search/bm25_term_selection.py` 的 docstring:
|
|
126
|
+
|
|
127
|
+
> 长查询 tokenize 后 OR 连接成一个 `tsquery`,`@@` 门会命中库中很大一部分,`ts_rank_cd` 无 IDF 且非索引支撑,**必须对每个命中行计算**,`ORDER BY ... LIMIT` 无法在排序前剪枝 → **生产环境 +60s 超时**。
|
|
128
|
+
> 盲目前 N 截断是错的切法:保留的往往是常见低信号词(正是它们驱动发散),丢掉的恰是有判别力的词。
|
|
129
|
+
> 正解:保留 **df 最低(最有选择性)** 的 N 个 token —— 这正是 BM25 的 IDF 所偏好的。
|
|
130
|
+
|
|
131
|
+
巧思在 df 的来源:**直接从 `pg_stats.most_common_elems` 读**,PostgreSQL 的 `ANALYZE` 免费维护,无需新表、无需改索引、无需重建。
|
|
132
|
+
|
|
133
|
+
降级设计也干净:读不到统计(新表/权限/目录形状异常)→ 退回前 N,**绝不让统计问题阻塞召回**。
|
|
134
|
+
|
|
135
|
+
**对你的落地(直接修问题 1)**:
|
|
136
|
+
```js
|
|
137
|
+
// 现状:terms 按字典序排 → 截前 32
|
|
138
|
+
// 改:按 DF 升序排(df 低=有选择性),取前 32,再按字典序排回以保证确定性
|
|
139
|
+
// DF 已在 :485-491 算好,零额外成本
|
|
140
|
+
```
|
|
141
|
+
注意保留"确定性"这个你已有的好性质:先按 df 选,再按字典序稳定输出。
|
|
142
|
+
|
|
143
|
+
### 2.3 时间的**三价语义** —— 最重要的一项
|
|
144
|
+
|
|
145
|
+
`engine/consolidation/prompts.py` 里对字段的定义,是整个 Hindsight 时间设计的精髓:
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
occurred_start / occurred_end:所描述的事件何时发生。
|
|
149
|
+
这可以远早于事实被陈述的时间 —— 今天记录的事实可能描述 2019 年的事件。
|
|
150
|
+
mentioned_at:陈述该事实的源材料何时被写下。
|
|
151
|
+
这是事实的"新鲜度":陈述有多新,而不是它何时入库。
|
|
152
|
+
从旧文档提取的事实,即使刚刚才被处理,也保留其旧的 mentioned_at。
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**三个不同的时间轴**:事件发生时间 / 陈述时间 / 入库时间。混用会出真 bug——比如"用户 2019 年毕业"这条昨天才入库的记忆,按入库时间算"很新"是错的,按 mentioned_at 算才对。
|
|
156
|
+
|
|
157
|
+
**对你的落地**(当前完全缺失,`fact-store-pre.js` 无任何 occurredAt 类字段):
|
|
158
|
+
|
|
159
|
+
| 字段 | 含义 | 你已有 | 建议 |
|
|
160
|
+
|---|---|---|---|
|
|
161
|
+
| `occurredStart/End` | 事件实际发生时间 | ✗ | 抽取时抓,抽不到留空 |
|
|
162
|
+
| `mentionedAt` | 陈述时间(=新鲜度) | 部分(日志文件名日期) | 全记忆层统一 |
|
|
163
|
+
| `ingestedAt` | 入库时间 | 有 | 保留,但**不用于新鲜度** |
|
|
164
|
+
|
|
165
|
+
配套的,他们有独立迁移 `b3c4d5e6f7g8_add_temporal_date_indexes.py`——**时间字段要建索引**,否则时间臂检索全表扫。
|
|
166
|
+
|
|
167
|
+
### 2.4 巩固引擎的 9 条规则(157KB 代码 + 138KB 测试的浓缩)
|
|
168
|
+
|
|
169
|
+
`engine/consolidation/prompts.py` 的 `_PROCESSING_RULES`,每一条背后都是一个真实 bug:
|
|
170
|
+
|
|
171
|
+
| # | 规则 | 它在防什么 |
|
|
172
|
+
|---|---|---|
|
|
173
|
+
| 1 | **PREFER UPDATE OVER CREATE** | 近重复兄弟条目爆炸。"一条规范化观察挂多个源事实,永远优于多个兄弟各挂一条" |
|
|
174
|
+
| 2 | **ONE OBSERVATION PER DISTINCT FACET** | 把不相关侧面揉进一条("有 3 个东西"+"有只叫 Rex 的狗"不该合并) |
|
|
175
|
+
| 3 | **MATCH BY ENTITY/FACET, NOT TOPIC** | 按主题泛匹配导致错误更新 |
|
|
176
|
+
| 4 | **STATE CHANGES — UPDATE CONCISELY** | 状态变化(卖掉/去世/搬家)要更新并带日期 |
|
|
177
|
+
| 5 | **CASCADE TO ALL AFFECTED OBSERVATIONS** | 实体从组里移除时,**个体观察和列表观察都要更新**(只改一个是经典 bug) |
|
|
178
|
+
| 6 | **RESOLVE REFERENCES** | 新事实给模糊占位符赋具体值("祖国"→"瑞典")时回填 |
|
|
179
|
+
| 7 | **PRESERVE HISTORY** | 重要历史事件**永不删除**;只在同一事实被完全重写或真正无意义时才删 |
|
|
180
|
+
| 8 | **NO COMPUTATION** ⭐ | **绝不计算、推导、调整数值**。用户说"我有 2 只狗"+"有只狗叫 Rex" → **不能更新成 3**(不知道 Rex 是不是那 2 只之一)。说"我卖掉了 X" → **不能递减计数**。只在用户明确说出新数值时才更新 |
|
|
181
|
+
| 9 | **KEEP DISTINCT TOPICS DISTINCT** | 不同人/实体的观察不合并 |
|
|
182
|
+
|
|
183
|
+
**第 8 条是防幻觉的命门**,值得单独说:LLM 巩固最大的失败模式就是"自作聪明做算术"。你的自动沉淀子代理如果有类似行为,会在用户记忆里种下编造的数字。建议立刻检查你的固化 prompt。
|
|
184
|
+
|
|
185
|
+
**语言规则**(同一文件 `_DEFAULT_LANGUAGE_RULE`)也很实用:
|
|
186
|
+
> 每条观察用它自己源事实的语言,绝不翻译(按观察粒度,不是按批次)。
|
|
187
|
+
> 当现有观察与新事实语言不同时,**不要就地编辑措辞**——那会产生"英文句子上接一个中文细节"。丢弃旧措辞,用新事实的语言从头重组。
|
|
188
|
+
|
|
189
|
+
这条说明他们遇到过"多语言模型漂移:中文源事实间歇性产出英文观察"。
|
|
190
|
+
|
|
191
|
+
### 2.5 中文时间解析要单开规则文件
|
|
192
|
+
|
|
193
|
+
`engine/chinese_temporal_periods.py` **86KB**,独立成文件。原因写在 `temporal_periods.py` docstring:
|
|
194
|
+
|
|
195
|
+
> 中文规则集**大得多**,且与基于空格的语言有**不同的边界行为**。
|
|
196
|
+
|
|
197
|
+
踩过的坑(issue #3250,注释里有):
|
|
198
|
+
> 孤立的四位数字是歧义的——dateparser 把每个孤立整数都当年份,于是**端口号和工单号变成了时间约束**("port 2019")。
|
|
199
|
+
> 消除歧义的是**引导词**:"in 2019" 是年份,"port 2019" 不是。dateparser 无法做这个判断(两者返回相同的 span "2019"),所以规则必须写在**还能拿到完整 query** 的地方。
|
|
200
|
+
> 且**刻意排除 "since"/"from"**——它们开启的是截止到现在的区间,而非闭合区间。
|
|
201
|
+
|
|
202
|
+
**对你的意义**:你要做时间检索,中文时间解析("上周三""前天下午""上个月底""春节前")是绕不开的硬活,而且**必须用规则而非纯 LLM**(成本+确定性)。这是 86KB 的工作量,但可以先覆盖高频 20% 表达式。
|
|
203
|
+
|
|
204
|
+
### 2.6 一个反直觉的性能实测:线程池 1 个 worker 最快
|
|
205
|
+
|
|
206
|
+
`engine/search/temporal_extraction.py` 的注释里有完整 benchmark:
|
|
207
|
+
|
|
208
|
+
```
|
|
209
|
+
16 个并发提取,文档规模文本:
|
|
210
|
+
inline total= 1318ms loop stall max=1318ms
|
|
211
|
+
max_workers=1 total= 1438ms loop stall max= 2.8ms
|
|
212
|
+
max_workers=2 total= 2091ms loop stall max= 4.5ms
|
|
213
|
+
max_workers=4 total= 4751ms loop stall max= 6.3ms
|
|
214
|
+
unbounded total=16688ms loop stall max= 33.8ms
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
原因:工作是纯 Python、持 GIL,加宽线程池**不增加并行度,只增加 GIL 争抢**。1 个 worker 吞吐 +9%,事件循环停顿改善 **470 倍**。
|
|
218
|
+
|
|
219
|
+
**对你的意义**:你的 Python sidecar(`worker_semantic_pre_v1.py`)如果在做 CPU 密集的 embedding/解析,**不要盲目加并发**。另外:纯 CPU 工作必须移出 asyncio 事件循环,否则会 stall 整个进程(他们实测 1.3 秒只有一次调度 tick)。
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 3. OpenViking:取架构,不取代码
|
|
224
|
+
|
|
225
|
+
按 S1 §0 的纪律,AGPLv3 项目不读源码。但其架构价值在**论文与公开文档**中已完整可得:
|
|
226
|
+
|
|
227
|
+
| 机制 | 公开可得的结论 | 我们的映射 |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| L0/L1/L2 分层 | L0 ~100 tok / L1 ~2k / L2 原文;目录本身也带 L0/L1 | 已有 checklist/excerpt/hint 三级,**缺 token 账本量化** |
|
|
230
|
+
| 目录递归检索 | 向量先定位目录 → 逐层下钻;结果自带周围上下文 | 我们的 scope 分层可借鉴"先定位分组再下钻" |
|
|
231
|
+
| 检索轨迹可观测 | 保留完整目录浏览轨迹,错了可回溯 | **我们已有更强的 evidence 链 + 五档复核** |
|
|
232
|
+
| session → memory 异步抽取 | commit 后异步抽取,可按用户配 `memory_policy` | 已有自动沉淀子代理;缺"按类型限定抽取"的策略层 |
|
|
233
|
+
| Context Compilation | LLM Wiki / 知识图谱 / 日报 / 知识蒸馏等复用工作流 | 与我们的每日反思、30 天蒸馏同源 |
|
|
234
|
+
|
|
235
|
+
**结论**:OpenViking 对我们最有价值的是 **token 账本这个指标口径**(把分层节省量化成可对外引用的数字),其余我们基本已有或更强。
|
|
236
|
+
|
|
237
|
+
---
|
|
238
|
+
|
|
239
|
+
## 4. 落地优先级(按 ROI 排序)
|
|
240
|
+
|
|
241
|
+
| # | 事项 | 依据 | 成本 | 依赖 |
|
|
242
|
+
|---|---|---|---|---|
|
|
243
|
+
| **1** | **检查固化 prompt 是否违反 NO COMPUTATION**(§2.4#8) | 防幻觉,错了会污染用户记忆 | 极低 | 无 |
|
|
244
|
+
| **2** | **修 queryTerms 字典序截断 → df-selective**(§2.2) | DF 已算好,改动约 10 行 | 极低 | 无 |
|
|
245
|
+
| **3** | **融合层绝对性**:先加 $\|C\|<3$ 退化分支(防御性,立即),再做绝对阈值标定(§1 问题 4) | 门控阈值建立在相对量上,标定不可迁移 | 低 → 中 | 无 |
|
|
246
|
+
| **4** | **建 token 账本**(S1 §3.1) | 把已做对的事变成可对外引用的数字 | 低 | 无 |
|
|
247
|
+
| **4** | **时间三价字段**(§2.3) occurredStart/End + mentionedAt + 索引 | 时间维度是一切时序推理的地基 | 中 | 无 |
|
|
248
|
+
| **5** | **增量倒排索引**(§1 问题 2) | 规模一大会超 50ms deadline | 中 | 无 |
|
|
249
|
+
| **6** | **巩固规则吸收**(§2.4 九条,改写为我们自己的表达) | 直接提升记忆质量 | 中 | 4 |
|
|
250
|
+
| **7** | **中文时间解析**(§2.5,先覆盖高频 20%) | 硬活,但无它时间检索是空谈 | 高 | 4 |
|
|
251
|
+
| **8** | **多臂融合**(引入时用 rank-space boost,§2.1) | 现在做会踩坑,等有多臂再做 | 高 | 4/5 |
|
|
252
|
+
|
|
253
|
+
**1 和 2 今天就该做**——都是几十行改动,一个是防灾难,一个是修系统性 bug。
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## 5. 一句话
|
|
258
|
+
|
|
259
|
+
**他们的深度不在算法,在"踩过的坑都写进了注释"。** issue #3956 的 recall@20 崩塌、#3250 的 port 2019、GIL 线程池的 470 倍差距、NO COMPUTATION 的算术幻觉——这些是免费的经验,且全部不受版权保护。**把这些吸收了,比抄一万行代码值钱。**
|