acp-ts 1.1.9 → 1.2.1
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/assets/topic-context-partitioning.md +871 -0
- package/dist/agentcp.d.ts +11 -10
- package/dist/agentcp.js +50 -34
- package/dist/group/client.js +26 -22
- package/dist/group/cursor_store.d.ts +9 -4
- package/dist/group/cursor_store.js +39 -10
- package/dist/group/events.d.ts +2 -2
- package/dist/group/events.js +0 -3
- package/dist/group/index.d.ts +1 -1
- package/dist/group/index.js +3 -2
- package/dist/group/message_store.d.ts +6 -5
- package/dist/group/message_store.js +66 -51
- package/dist/group/operations.d.ts +0 -1
- package/dist/group/operations.js +0 -8
- package/dist/group/types.d.ts +7 -1
- package/dist/group/types.js +5 -2
- package/dist/interfaces.d.ts +2 -2
- package/dist/server.js +51 -20
- package/package.json +1 -1
|
@@ -0,0 +1,871 @@
|
|
|
1
|
+
# 话题分流上下文管理架构(Topic-based Context Partitioning)
|
|
2
|
+
|
|
3
|
+
> 设计状态:方案探索阶段(v6)
|
|
4
|
+
> 创建日期:2026-02-16
|
|
5
|
+
> 更新日期:2026-02-17
|
|
6
|
+
|
|
7
|
+
## 1. 核心思想
|
|
8
|
+
|
|
9
|
+
跳出 RAG(检索增强生成)和精确索引两种现有范式,通过**大模型驱动的话题拆分**将单一会话拆分为多个独立话题上下文窗口,实现等效上下文窗口的数量级增长。
|
|
10
|
+
|
|
11
|
+
用户只看到一个会话,系统在背后维护多个"话题上下文",每个话题独占一个上下文窗口。
|
|
12
|
+
|
|
13
|
+
**关键概念:**
|
|
14
|
+
- **窗口(Window)**:一次大模型调用的上下文,是本架构的基本单元
|
|
15
|
+
- **会话(Session)**:用户主动拆分和管理的对话容器(现有主流方式)
|
|
16
|
+
- **话题(Topic)**:大模型自动识别、拆分和管理的语义单元
|
|
17
|
+
|
|
18
|
+
**核心设计:只使用一个会话窗口 + 多个话题窗口。**
|
|
19
|
+
|
|
20
|
+
## 2. 窗口类型
|
|
21
|
+
|
|
22
|
+
系统包含三种窗口:
|
|
23
|
+
|
|
24
|
+
| 窗口类型 | 职责 | 模型要求 | 上下文构成 |
|
|
25
|
+
|---------|------|---------|-----------|
|
|
26
|
+
| **主会话窗口** | 面向用户的实际对话推进 | 强模型 | 系统提示词 + 话题窗口返回的处理结果 + 未拆分消息(含最近20条) |
|
|
27
|
+
| **话题窗口** | 上下文准备层:提取与当前对话相关的话题内容 | 可用便宜模型 | 系统提示词(上下文提取)+ 已拆分进话题的消息 + 未拆分消息 |
|
|
28
|
+
| **话题索引窗口** | 搜索和激活休眠话题 | 可用便宜模型 | 最近激活话题简介 + 按需搜索的话题简介 + 时间索引 |
|
|
29
|
+
|
|
30
|
+
**关键设计:话题窗口是上下文准备层,不直接回答用户问题。** 话题窗口的职责是分析未拆分消息与话题内容的关联,提取相关内容,返回处理结果给主会话窗口。主会话窗口基于这些处理结果生成最终回复。
|
|
31
|
+
|
|
32
|
+
## 3. 架构概览
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
用户消息
|
|
36
|
+
│
|
|
37
|
+
▼
|
|
38
|
+
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|
39
|
+
│ 话题窗口A │ │ 话题窗口B │ │ 话题窗口C │ (并行调用,仅激活话题)
|
|
40
|
+
│(便宜模型)│ │(便宜模型)│ │(便宜模型)│
|
|
41
|
+
│ │ │ │ │ │
|
|
42
|
+
│ 输入: │ │ 输入: │ │ 输入: │
|
|
43
|
+
│ 系统提示词 │ │ 系统提示词 │ │ 系统提示词 │
|
|
44
|
+
│+已拆分消息│ │+已拆分消息│ │+已拆分消息│
|
|
45
|
+
│+未拆分消息│ │+未拆分消息│ │+未拆分消息│
|
|
46
|
+
│ │ │ │ │ │
|
|
47
|
+
│ 输出: │ │ 输出: │ │ 输出: │
|
|
48
|
+
│ 处理结果 │ │ 处理结果 │ │ 低分(0.1) │
|
|
49
|
+
└────┬─────┘ └────┬─────┘ └──────────┘
|
|
50
|
+
│ │
|
|
51
|
+
│ 收集处理结果 │
|
|
52
|
+
▼ ▼
|
|
53
|
+
┌────────────────────────────────────────────┐
|
|
54
|
+
│ 主会话窗口(强模型) │
|
|
55
|
+
│ │
|
|
56
|
+
│ 构成: │
|
|
57
|
+
│ ┌──────────────────────────────────────┐ │
|
|
58
|
+
│ │ 系统提示词 │ │
|
|
59
|
+
│ ├──────────────────────────────────────┤ │
|
|
60
|
+
│ │ 话题A 处理结果 + 引用信息 │ │
|
|
61
|
+
│ │ 话题B 处理结果 + 引用信息 │ │
|
|
62
|
+
│ ├──────────────────────────────────────┤ │
|
|
63
|
+
│ │ 未拆分到话题的对话消息 │ │
|
|
64
|
+
│ │ + 最近20条消息(无论是否已拆分) │ │
|
|
65
|
+
│ └──────────────────────────────────────┘ │
|
|
66
|
+
│ │
|
|
67
|
+
│ 职责: │
|
|
68
|
+
│ - 基于话题处理结果 + 未拆分消息,生成回复 │
|
|
69
|
+
│ - 判断是否需要激活其他话题 → MCP 工具 │
|
|
70
|
+
│ - 超限时触发话题拆分 │
|
|
71
|
+
└──────────┬─────────────────────────────────┘
|
|
72
|
+
│
|
|
73
|
+
│ 需要激活其他话题?→ 调用 MCP 工具
|
|
74
|
+
▼
|
|
75
|
+
┌────────────────────────────────────────────┐
|
|
76
|
+
│ 话题索引窗口(便宜模型) │
|
|
77
|
+
│ │
|
|
78
|
+
│ 构成: │
|
|
79
|
+
│ ┌──────────────────────────────────────┐ │
|
|
80
|
+
│ │ 最近一段时间激活过的话题简介 │ │
|
|
81
|
+
│ │ + 按需搜索的话题简介 │ │
|
|
82
|
+
│ │ + 时间索引 │ │
|
|
83
|
+
│ └──────────────────────────────────────┘ │
|
|
84
|
+
│ │
|
|
85
|
+
│ 职责: │
|
|
86
|
+
│ - 0 相关话题 → 搜索更多话题简介 │
|
|
87
|
+
│ - 找到匹配 → 激活话题 │
|
|
88
|
+
│ - 无匹配 → 确认为新话题 │
|
|
89
|
+
└────────────────────────────────────────────┘
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 4. 消息处理流程
|
|
93
|
+
|
|
94
|
+
### 4.1 新消息到达(完整时序)
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
新消息到达
|
|
98
|
+
│
|
|
99
|
+
│ 步骤0:预估上下文大小
|
|
100
|
+
│ (系统提示词 + 预估话题结果 + 未拆分消息 + 新消息)
|
|
101
|
+
│
|
|
102
|
+
├─ 超限(>70%)?
|
|
103
|
+
│ │
|
|
104
|
+
│ └─ 是 → 步骤1:话题拆分(强模型)
|
|
105
|
+
│ 对较早的未拆分消息进行拆分
|
|
106
|
+
│ 更新话题持久化文件 + 更新话题简介
|
|
107
|
+
│ 可能激活休眠话题 / 创建新话题
|
|
108
|
+
│ 未拆分消息集合更新
|
|
109
|
+
│
|
|
110
|
+
│ 步骤2:话题窗口并行处理(上下文准备)
|
|
111
|
+
│
|
|
112
|
+
├──→ 并行发送到所有激活的话题窗口
|
|
113
|
+
│ 输入 = 已拆分消息(可能刚被步骤1更新)+ 当前未拆分消息
|
|
114
|
+
│ 各话题窗口返回:灰度相关性分数(0-1)+ 处理结果
|
|
115
|
+
│
|
|
116
|
+
│ 步骤3:等待所有话题窗口返回
|
|
117
|
+
│
|
|
118
|
+
│ 步骤4:组装主会话窗口上下文
|
|
119
|
+
│ (话题处理结果按 relevance_score 降序排列)
|
|
120
|
+
│
|
|
121
|
+
└──→ 主会话窗口
|
|
122
|
+
上下文 = 系统提示词
|
|
123
|
+
+ 话题处理结果(按评分降序)
|
|
124
|
+
+ 未拆分消息
|
|
125
|
+
+ 最近20条消息
|
|
126
|
+
│
|
|
127
|
+
├─ 生成回复
|
|
128
|
+
│
|
|
129
|
+
└─ 需要激活其他话题?
|
|
130
|
+
│
|
|
131
|
+
├─ 不需要 → 返回回复给用户,结束
|
|
132
|
+
│
|
|
133
|
+
└─ 需要 → 步骤5:activate_topic 重执行流程
|
|
134
|
+
│
|
|
135
|
+
├─ 话题索引窗口查找并激活话题
|
|
136
|
+
│
|
|
137
|
+
├─ 对新激活的话题执行话题窗口调用
|
|
138
|
+
│ (之前已完成的话题窗口结果保留复用)
|
|
139
|
+
│
|
|
140
|
+
├─ 合并所有话题处理结果
|
|
141
|
+
│
|
|
142
|
+
├─ 重新组装主会话上下文
|
|
143
|
+
│
|
|
144
|
+
└─ 重新生成回复 → 返回给用户
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**关键时序决策:**
|
|
148
|
+
|
|
149
|
+
1. **先拆分,再评估**:拆分会改变"未拆分消息"集合和话题的"已拆分消息"。话题窗口必须基于最新状态做评估,所以拆分在前。
|
|
150
|
+
2. **话题处理结果按评分降序排列**:最相关的话题在主会话上下文中排在前面,对模型注意力分配更有利。
|
|
151
|
+
3. **activate_topic 时复用已有结果**:之前已完成的话题窗口结果仍然有效(各话题窗口独立运行),只需补充新激活话题的结果,合并后重新组装上下文、重新生成回复。废弃的是上一次主会话的回复,不是话题窗口的结果。
|
|
152
|
+
|
|
153
|
+
### 4.1.1 冷启动
|
|
154
|
+
|
|
155
|
+
系统刚启动时,没有任何话题存在:
|
|
156
|
+
|
|
157
|
+
- 所有消息都是"未拆分消息",直接进入主会话窗口
|
|
158
|
+
- 没有话题窗口被调用(没有激活话题)
|
|
159
|
+
- 行为与传统单会话模式完全一致
|
|
160
|
+
- 直到主会话窗口超限(70%),触发第一次话题拆分
|
|
161
|
+
- 第一次拆分后,话题系统开始运转
|
|
162
|
+
|
|
163
|
+
### 4.2 话题窗口的上下文构成与输出
|
|
164
|
+
|
|
165
|
+
**输入(上下文):**
|
|
166
|
+
- **系统提示词**:指导话题窗口进行内容提取和相关性判定
|
|
167
|
+
- **已拆分进话题的消息**:该话题的完整对话历史(持久化文件中的内容)
|
|
168
|
+
- **未拆分消息**:主会话中尚未归入任何话题的消息
|
|
169
|
+
|
|
170
|
+
**输出(返回给主会话窗口的处理结果,包含两部分):**
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
{
|
|
174
|
+
"relevance_score": 0.85,
|
|
175
|
+
"topic_ref": {
|
|
176
|
+
"name": "话题名称",
|
|
177
|
+
"summary": "话题简介",
|
|
178
|
+
"file": "topics/topic-xxx.jsonl"
|
|
179
|
+
},
|
|
180
|
+
"referenced_message_ids": ["msg-042", "msg-043", "msg-051"],
|
|
181
|
+
"summary": "对相关内容的总结性描述..."
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**灰度相关性评分(`relevance_score`):**
|
|
186
|
+
- 0.0 = 完全不相关
|
|
187
|
+
- 0.3 = 可能有微弱关联
|
|
188
|
+
- 0.5 = 中等相关,可能需要引用
|
|
189
|
+
- 0.7 = 明确相关,应该引用
|
|
190
|
+
- 1.0 = 高度相关,核心话题
|
|
191
|
+
|
|
192
|
+
评分决定话题的激活/休眠(详见 4.7 灰度激活机制)。当 `relevance_score` 足够高时,同时返回 `referenced_message_ids` 和 `summary`。
|
|
193
|
+
|
|
194
|
+
两部分的作用:
|
|
195
|
+
- **`referenced_message_ids`**:话题中与当前对话相关的消息 ID 列表。系统根据这些 ID 从话题持久化文件中提取原始消息,重构到主会话上下文中。保证信息零损失。
|
|
196
|
+
- **`summary`**:对相关内容的总结性输出。提供高层理解、决策脉络、因果关系等单看消息不易把握的上下文。作为软预算控制,总结部分建议不超过 2000 字。
|
|
197
|
+
|
|
198
|
+
两部分互补:消息 ID 提供精确原文,总结提供理解框架。主会话同时获得细节和全局视角。
|
|
199
|
+
|
|
200
|
+
低分时(如 < 0.3)可省略 `referenced_message_ids` 和 `summary`:
|
|
201
|
+
```json
|
|
202
|
+
{
|
|
203
|
+
"relevance_score": 0.1,
|
|
204
|
+
"topic_ref": {
|
|
205
|
+
"name": "话题名称",
|
|
206
|
+
"summary": "话题简介",
|
|
207
|
+
"file": "topics/topic-xxx.jsonl"
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**关键**:已拆分进话题的消息只在主会话超限触发拆分时才会增加。话题窗口中的"已拆分消息"部分是稳定的、追加式增长的,因此享受高缓存命中率。
|
|
213
|
+
|
|
214
|
+
### 4.3 消息 ID 与去重
|
|
215
|
+
|
|
216
|
+
- 每条消息有唯一 ID
|
|
217
|
+
- 当消息被拆分进话题后,消息 ID 记录在话题持久化文件中
|
|
218
|
+
- 主会话窗口组装上下文时:已拆分的消息从"未拆分消息"区移除(它们通过话题窗口的处理结果——引用消息 + 总结——间接体现)
|
|
219
|
+
- **最近 20 条消息始终保留在主会话窗口中**(无论是否已拆分到话题)
|
|
220
|
+
- 不存在冗余问题:主会话中载入的是话题窗口返回的**引用消息原文 + 总结**,与未拆分消息区是不同维度的内容
|
|
221
|
+
|
|
222
|
+
### 4.4 主会话窗口超限 → 话题拆分
|
|
223
|
+
|
|
224
|
+
拆分发生在新消息到达后、话题窗口评估前(详见 4.1 步骤1)。
|
|
225
|
+
|
|
226
|
+
```
|
|
227
|
+
预估上下文超限(>70%)
|
|
228
|
+
│
|
|
229
|
+
└─→ 触发话题拆分(强模型)
|
|
230
|
+
│
|
|
231
|
+
├─ 对较早的未拆分消息进行分析
|
|
232
|
+
│ 大模型判断每条消息属于哪个话题,三种结果:
|
|
233
|
+
│ ├─ 已激活的话题 → 追加到话题持久化文件
|
|
234
|
+
│ ├─ 已存在但未激活的话题 → 追加到话题持久化文件 + 激活该话题
|
|
235
|
+
│ └─ 新话题 → 创建新话题文件 + 生成话题简介 + 激活
|
|
236
|
+
│
|
|
237
|
+
├─ 被拆分的消息从未拆分区移除
|
|
238
|
+
│ (消息 ID 已在话题持久化文件中)
|
|
239
|
+
│
|
|
240
|
+
├─ 更新受影响话题的简介(追加消息后立即更新)
|
|
241
|
+
│
|
|
242
|
+
└─ 主会话窗口保留最近 20 条消息(无论是否已拆分)
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
**注意**:
|
|
246
|
+
- 拆分操作是唯一会向话题持久化文件追加消息的时机。
|
|
247
|
+
- 拆分发生在上下文已经充分讨论的时刻,话题语义明确,大模型完全有能力准确判断归属。
|
|
248
|
+
- 拆分完成后,后续的话题窗口评估使用更新后的状态(已拆分消息增加、未拆分消息减少)。
|
|
249
|
+
|
|
250
|
+
### 4.5 话题超限 → 话题拆分(非压缩)
|
|
251
|
+
|
|
252
|
+
**设计决策:在线使用时不使用分段压缩。** 当话题窗口接近上限时,应进行**话题拆分**(将大话题拆成子话题),而非话题压缩。
|
|
253
|
+
|
|
254
|
+
理由:
|
|
255
|
+
- 话题简介已经承担了"压缩摘要"的功能
|
|
256
|
+
- 拆分为子话题保留了完整信息,压缩则是有损的
|
|
257
|
+
- 子话题各自拥有独立上下文窗口,继续享受缓存优势
|
|
258
|
+
|
|
259
|
+
**注意:** 此处说的是话题在线使用时的策略。周期性回顾(4.8)中的归档压缩是另一回事——那是离线的遗忘策略,将不重要的话题压缩归档后不再参与正常激活流程。两者适用场景不同,不矛盾。
|
|
260
|
+
|
|
261
|
+
### 4.6 话题简介生成
|
|
262
|
+
|
|
263
|
+
- **触发时机**:每当话题追加新消息后,立即更新话题简介
|
|
264
|
+
- **简介目标**:指导判断新消息是否应该激活这个话题
|
|
265
|
+
- **简介大小**:约 1KB,1M 上下文的话题索引窗口可容纳约 1000 个话题简介
|
|
266
|
+
- **模型选择**:可用便宜模型生成
|
|
267
|
+
- 话题简介 = 话题的"激活指纹"
|
|
268
|
+
|
|
269
|
+
### 4.7 话题激活与休眠(灰度机制)
|
|
270
|
+
|
|
271
|
+
#### 灰度相关性评估
|
|
272
|
+
|
|
273
|
+
话题的激活/休眠不是二元判定,而是基于灰度相关性分数(0-1)的渐进式决策:
|
|
274
|
+
|
|
275
|
+
- 每轮话题窗口返回 `relevance_score`
|
|
276
|
+
- 系统维护每个话题的**滑动平均相关度**(如最近 5 轮的加权平均)
|
|
277
|
+
- 相关度逐步提升 → 话题稳固激活
|
|
278
|
+
- 相关度持续衰减 → 话题逐步进入休眠
|
|
279
|
+
|
|
280
|
+
#### 基于排名的动态激活
|
|
281
|
+
|
|
282
|
+
激活话题数量设定区间(可配置,默认 3-20,默认值 10)。
|
|
283
|
+
|
|
284
|
+
**核心机制:按评分排名,动态决定激活数量。**
|
|
285
|
+
|
|
286
|
+
话题激活不是简单的"超过阈值就激活",而是基于排名的动态决策:
|
|
287
|
+
|
|
288
|
+
1. 所有话题(已激活 + 候选)按 `relevance_score`(滑动平均)降序排列
|
|
289
|
+
2. 根据当前激活话题数量,决定从排名中取多少个:
|
|
290
|
+
- 激活话题少 → 多取(宽松,按排名顺序多激活几个)
|
|
291
|
+
- 激活话题多 → 少取(严格,只保留排名最靠前的)
|
|
292
|
+
3. 排名靠后、分数持续低的话题自然掉出激活范围 → 进入休眠
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
激活决策 = 按评分排名取 top N
|
|
296
|
+
|
|
297
|
+
N = f(当前激活话题数量, 区间上下限)
|
|
298
|
+
|
|
299
|
+
激活话题少 → N 偏大(宽松激活,多关联一些话题无害)
|
|
300
|
+
激活话题多 → N 偏小(严格激活,优先保留高相关话题)
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
同时设定最低激活阈值防止激活完全不相关的话题:
|
|
304
|
+
|
|
305
|
+
| 当前激活数 | 最低激活阈值 | 休眠阈值 | 说明 |
|
|
306
|
+
|-----------|------------|---------|------|
|
|
307
|
+
| 3(下限) | 0.2 | 0.1 | 非常宽松,几乎所有可能相关的都激活 |
|
|
308
|
+
| 10(默认)| 0.4 | 0.2 | 平衡状态 |
|
|
309
|
+
| 18(接近上限)| 0.7 | 0.4 | 严格,只保留高相关话题 |
|
|
310
|
+
|
|
311
|
+
激活尺度偏宽松是安全的:多激活几个话题的代价可控(多几个并行调用),而漏掉关键话题的代价很高(失忆)。不相关的话题会在后续轮次中因评分排名下滑自然休眠。
|
|
312
|
+
|
|
313
|
+
**话题索引窗口的排名激活:** 当主会话调用 `activate_topic` 触发话题索引窗口时,索引窗口返回候选话题的相关性排名。系统根据当前激活话题总数决定激活多少个:激活数少则多激活(按排名顺序),激活数多则少激活(只取排名最高的)。
|
|
314
|
+
|
|
315
|
+
#### 激活路径
|
|
316
|
+
|
|
317
|
+
**路径 1:话题窗口持续高分 → 保持激活**
|
|
318
|
+
- 话题窗口每轮返回 `relevance_score`,高分话题自然保持激活
|
|
319
|
+
|
|
320
|
+
**路径 2:主会话主动激活 → MCP 工具 → 话题索引窗口**
|
|
321
|
+
- 主会话模型判断需要更多话题上下文时,调用 `activate_topic` 工具
|
|
322
|
+
- 触发话题索引窗口搜索
|
|
323
|
+
|
|
324
|
+
**路径 3:失忆感知 → 自动深度检索**
|
|
325
|
+
- 当主会话模型感知到用户认为它"失忆"(如用户说"我之前跟你说过"、"你忘了吗"、"我们上次讨论的"),应**自动**进入话题索引窗口进行深度检索
|
|
326
|
+
- 此过程不需要与用户确认,内部静默完成
|
|
327
|
+
- 检索到匹配话题 → 激活,阈值放宽(宁可多激活)
|
|
328
|
+
- 检索结果模糊 → 可以像人类一样直接询问用户以明确:"你是指我们之前讨论的 XX 话题吗?"
|
|
329
|
+
|
|
330
|
+
这模拟了人类对话中的自然行为:意识到自己忘了某件事时,先尝试自己回忆,实在想不起来就直接问对方。
|
|
331
|
+
|
|
332
|
+
#### 休眠逻辑
|
|
333
|
+
|
|
334
|
+
- 话题的滑动平均相关度持续低于休眠阈值 → 进入休眠
|
|
335
|
+
- 休眠后仅保留简介在话题索引中,不消耗 LLM 调用
|
|
336
|
+
- 可被上述三条路径重新激活
|
|
337
|
+
|
|
338
|
+
### 4.8 话题周期性回顾与归档(离线遗忘策略)
|
|
339
|
+
|
|
340
|
+
**本节描述的是离线遗忘策略,与 4.5 的在线不压缩原则不矛盾。** 4.5 规定在线使用时不压缩话题内容(用子话题拆分代替);本节的归档压缩是离线的、针对不再活跃的话题的遗忘处理。
|
|
341
|
+
|
|
342
|
+
#### 周期性回顾
|
|
343
|
+
|
|
344
|
+
系统周期性(如每天定时)对话题进行回顾:
|
|
345
|
+
|
|
346
|
+
```
|
|
347
|
+
每日回顾任务(可配置时间,如凌晨)
|
|
348
|
+
│
|
|
349
|
+
├─ 回顾当天涉及的所有话题
|
|
350
|
+
│ │
|
|
351
|
+
│ ├─ 对每个话题进行进一步的总结压缩
|
|
352
|
+
│ │ (将完整消息历史压缩为更紧凑的总结)
|
|
353
|
+
│ │
|
|
354
|
+
│ ├─ 更新话题简介(基于压缩后的内容)
|
|
355
|
+
│ │
|
|
356
|
+
│ └─ 评估话题重要性
|
|
357
|
+
│
|
|
358
|
+
├─ 不重要的话题 → 归档
|
|
359
|
+
│
|
|
360
|
+
└─ 相关话题 → 考虑合并
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### 归档状态
|
|
364
|
+
|
|
365
|
+
归档是话题的最终生命周期阶段,低于休眠:
|
|
366
|
+
|
|
367
|
+
- **归档话题**按日期索引存储,可通过日期检索到
|
|
368
|
+
- **不会被正常的话题激活机制触发**(区别于休眠话题)
|
|
369
|
+
- 只有用户**主动要求检索**时才会被加载(如"帮我找一下上个月讨论的 XX")
|
|
370
|
+
- 归档话题保留压缩后的总结版本,不保留完整消息历史
|
|
371
|
+
|
|
372
|
+
#### 话题合并
|
|
373
|
+
|
|
374
|
+
回顾时发现高度相关的话题可以合并:
|
|
375
|
+
- 两个话题讨论的实质上是同一件事 → 合并为一个话题
|
|
376
|
+
- 合并后更新话题简介
|
|
377
|
+
- 释放多余的话题配额
|
|
378
|
+
|
|
379
|
+
#### 归档判定标准
|
|
380
|
+
|
|
381
|
+
- 话题已休眠且超过 N 天未被重新激活
|
|
382
|
+
- 话题内容与当前活跃讨论方向无关
|
|
383
|
+
- 话题是一次性的问答(如"XX 是什么意思"),没有持续讨论价值
|
|
384
|
+
|
|
385
|
+
## 5. 主会话窗口上下文组装规则
|
|
386
|
+
|
|
387
|
+
```
|
|
388
|
+
主会话窗口上下文 = {
|
|
389
|
+
系统提示词,
|
|
390
|
+
|
|
391
|
+
// 话题处理结果区(按 relevance_score 降序排列,最相关的排在最前面)
|
|
392
|
+
// 仅包含激活话题中返回了处理结果的(relevance_score >= 最低激活阈值)
|
|
393
|
+
for each 激活话题 sorted by relevance_score DESC {
|
|
394
|
+
话题引用信息(名称、简介、文件路径)
|
|
395
|
+
|
|
396
|
+
// 部分一:引用消息原文(根据 referenced_message_ids 从话题文件中提取)
|
|
397
|
+
for each msg_id in referenced_message_ids {
|
|
398
|
+
从话题持久化文件中读取消息原文
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// 部分二:总结
|
|
402
|
+
话题窗口返回的 summary
|
|
403
|
+
},
|
|
404
|
+
|
|
405
|
+
// 未拆分消息区(去除已拆分的)
|
|
406
|
+
for each 消息 in 对话历史 {
|
|
407
|
+
if 消息.id NOT IN 任何话题持久化文件 {
|
|
408
|
+
保留此消息
|
|
409
|
+
}
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
// 最近消息区(始终保留)
|
|
413
|
+
最近 20 条消息(无论是否已拆分到话题)
|
|
414
|
+
}
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
## 6. 系统提示词设计
|
|
418
|
+
|
|
419
|
+
### 6.1 话题窗口系统提示词
|
|
420
|
+
|
|
421
|
+
```markdown
|
|
422
|
+
# 角色
|
|
423
|
+
|
|
424
|
+
你是一个话题上下文分析器。你的任务不是回答用户问题,而是分析当前对话
|
|
425
|
+
是否需要引用本话题的内容,如果需要,提供相关消息引用和总结供主会话使用。
|
|
426
|
+
|
|
427
|
+
# 话题信息
|
|
428
|
+
|
|
429
|
+
- 话题名称:{{topic_name}}
|
|
430
|
+
- 话题简介:{{topic_summary}}
|
|
431
|
+
- 话题文件:{{topic_file}}
|
|
432
|
+
|
|
433
|
+
# 你的输入
|
|
434
|
+
|
|
435
|
+
1. **已拆分消息**:本话题中已有的完整对话历史(每条消息带有消息 ID)
|
|
436
|
+
2. **未拆分消息**:当前主会话中尚未归入任何话题的最新对话
|
|
437
|
+
|
|
438
|
+
# 你的任务
|
|
439
|
+
|
|
440
|
+
分析"未拆分消息"中的内容,判断回答这些消息是否需要引用本话题中的信息。
|
|
441
|
+
|
|
442
|
+
## 判断标准
|
|
443
|
+
|
|
444
|
+
- 未拆分消息中是否提到了本话题讨论过的概念、决策、结论?
|
|
445
|
+
- 回答未拆分消息中的问题,是否需要本话题中的背景知识?
|
|
446
|
+
- 未拆分消息是否是本话题的延续或后续?
|
|
447
|
+
|
|
448
|
+
## 输出格式
|
|
449
|
+
|
|
450
|
+
评估未拆分消息与本话题的相关程度,返回灰度相关性分数和处理结果。
|
|
451
|
+
|
|
452
|
+
如果有一定相关性(分数 >= 0.3),输出引用消息和总结:
|
|
453
|
+
|
|
454
|
+
<topic_result>
|
|
455
|
+
<relevance_score>0.85</relevance_score>
|
|
456
|
+
<referenced_messages>
|
|
457
|
+
列出与当前对话相关的消息 ID,每行一个:
|
|
458
|
+
msg-042
|
|
459
|
+
msg-043
|
|
460
|
+
msg-051
|
|
461
|
+
只列出真正相关的消息,不要列出整个话题的所有消息。
|
|
462
|
+
</referenced_messages>
|
|
463
|
+
<summary>
|
|
464
|
+
对相关内容的总结性描述。包括:
|
|
465
|
+
- 相关决策和结论的概括
|
|
466
|
+
- 讨论的因果脉络和演变过程
|
|
467
|
+
- 当前对话需要了解的背景要点
|
|
468
|
+
保持总结简洁但信息完整,建议不超过 2000 字。
|
|
469
|
+
不要逐条复述消息内容(原文会通过消息 ID 引用),
|
|
470
|
+
重点提供消息原文不易直接看出的上下文理解和关联。
|
|
471
|
+
</summary>
|
|
472
|
+
</topic_result>
|
|
473
|
+
|
|
474
|
+
如果相关性较低(分数 < 0.3),可省略引用和总结:
|
|
475
|
+
|
|
476
|
+
<topic_result>
|
|
477
|
+
<relevance_score>0.1</relevance_score>
|
|
478
|
+
</topic_result>
|
|
479
|
+
|
|
480
|
+
## 评分标准
|
|
481
|
+
|
|
482
|
+
- 0.0 = 完全不相关
|
|
483
|
+
- 0.3 = 可能有微弱关联
|
|
484
|
+
- 0.5 = 中等相关,可能需要引用
|
|
485
|
+
- 0.7 = 明确相关,应该引用
|
|
486
|
+
- 1.0 = 高度相关,核心话题
|
|
487
|
+
|
|
488
|
+
宁可给高一些的分数,也不要遗漏真正相关的话题。
|
|
489
|
+
多激活一个话题的代价远小于漏掉关键话题导致的"失忆"。
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
### 6.2 主会话窗口系统提示词
|
|
493
|
+
|
|
494
|
+
```markdown
|
|
495
|
+
# 角色
|
|
496
|
+
|
|
497
|
+
你是用户的 AI 助手。你基于以下信息回答用户的问题:
|
|
498
|
+
|
|
499
|
+
1. **话题上下文**:系统从相关话题中提取的内容(如果有的话)
|
|
500
|
+
2. **当前对话**:未拆分到话题的对话消息和最近消息
|
|
501
|
+
|
|
502
|
+
# 话题上下文
|
|
503
|
+
|
|
504
|
+
以下是与当前对话相关的话题内容。每个话题包含两部分:
|
|
505
|
+
引用的原始消息(提供精确细节)和总结(提供整体理解)。
|
|
506
|
+
|
|
507
|
+
{{#each active_topics}}
|
|
508
|
+
## 话题:{{name}}
|
|
509
|
+
简介:{{summary}}
|
|
510
|
+
文件:{{file}}
|
|
511
|
+
|
|
512
|
+
### 引用消息
|
|
513
|
+
{{#each referenced_messages}}
|
|
514
|
+
[{{id}}] {{role}}: {{content}}
|
|
515
|
+
{{/each}}
|
|
516
|
+
|
|
517
|
+
### 话题总结
|
|
518
|
+
{{topic_summary_output}}
|
|
519
|
+
|
|
520
|
+
---
|
|
521
|
+
{{/each}}
|
|
522
|
+
|
|
523
|
+
{{#if no_active_topics}}
|
|
524
|
+
(当前无激活话题)
|
|
525
|
+
{{/if}}
|
|
526
|
+
|
|
527
|
+
# 话题管理工具
|
|
528
|
+
|
|
529
|
+
如果你认为当前对话涉及之前讨论过的话题,但上方没有提供相关话题上下文,
|
|
530
|
+
请调用 `activate_topic` 工具来搜索和激活相关话题。
|
|
531
|
+
|
|
532
|
+
使用场景:
|
|
533
|
+
- 用户提到了之前讨论过的内容,但没有对应的话题上下文
|
|
534
|
+
- 用户要求回顾或引用之前的讨论
|
|
535
|
+
- 你感觉缺少必要的背景信息来准确回答
|
|
536
|
+
- **失忆感知**:用户表达"你忘了"、"我之前说过"、"我们上次讨论的"等暗示时,
|
|
537
|
+
必须立即调用此工具进行深度检索,不要等用户明确要求
|
|
538
|
+
|
|
539
|
+
如果检索后仍不确定用户指的是哪个话题,可以自然地询问用户:
|
|
540
|
+
"你是指我们之前讨论的 XX 吗?" 这是正常的对话行为。
|
|
541
|
+
|
|
542
|
+
# 注意事项
|
|
543
|
+
|
|
544
|
+
- 优先参考引用消息中的精确内容,用话题总结辅助理解整体脉络
|
|
545
|
+
- 不需要提及话题管理的内部机制,对用户来说这是透明的
|
|
546
|
+
- 回复风格应该自然,就像你一直记得这些内容一样
|
|
547
|
+
- 宁可多激活话题也不要冒"失忆"的风险
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
### 6.3 话题索引窗口系统提示词
|
|
551
|
+
|
|
552
|
+
```markdown
|
|
553
|
+
# 角色
|
|
554
|
+
|
|
555
|
+
你是话题路由器。你的任务是根据当前对话内容,在话题库中找到相关话题。
|
|
556
|
+
|
|
557
|
+
# 输入
|
|
558
|
+
|
|
559
|
+
1. **当前对话摘要**:用户最近的对话内容
|
|
560
|
+
2. **话题简介列表**:已有话题的简介
|
|
561
|
+
|
|
562
|
+
# 你的任务
|
|
563
|
+
|
|
564
|
+
分析当前对话内容,判断它与哪些已有话题相关。
|
|
565
|
+
|
|
566
|
+
## 输出格式
|
|
567
|
+
|
|
568
|
+
<topic_routing>
|
|
569
|
+
<matched_topics>
|
|
570
|
+
<topic id="xxx" relevance="high|medium|low">匹配理由</topic>
|
|
571
|
+
...
|
|
572
|
+
</matched_topics>
|
|
573
|
+
<no_match_reason>如果没有匹配,说明原因</no_match_reason>
|
|
574
|
+
</topic_routing>
|
|
575
|
+
|
|
576
|
+
## 判断标准
|
|
577
|
+
|
|
578
|
+
- 对话中是否提到了某个话题讨论过的关键词、概念、实体?
|
|
579
|
+
- 对话的意图是否与某个话题的方向一致?
|
|
580
|
+
- 优先匹配 high relevance 的话题,避免过度匹配
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### 6.4 话题拆分系统提示词
|
|
584
|
+
|
|
585
|
+
```markdown
|
|
586
|
+
# 角色
|
|
587
|
+
|
|
588
|
+
你是话题拆分器。主会话上下文即将超限,你需要将较早的未拆分消息归类到
|
|
589
|
+
话题中。
|
|
590
|
+
|
|
591
|
+
# 输入
|
|
592
|
+
|
|
593
|
+
1. **待拆分消息**:需要归类的消息列表(带消息 ID)
|
|
594
|
+
2. **已有话题列表**:当前所有话题的名称和简介
|
|
595
|
+
|
|
596
|
+
# 你的任务
|
|
597
|
+
|
|
598
|
+
为每条待拆分消息指定归属话题。可以归入已有话题,也可以创建新话题。
|
|
599
|
+
|
|
600
|
+
## 输出格式
|
|
601
|
+
|
|
602
|
+
<topic_split>
|
|
603
|
+
<assignment msg_id="msg-001" topic="existing_active" topic_id="topic-xxx">
|
|
604
|
+
归入理由(话题已激活,直接追加)
|
|
605
|
+
</assignment>
|
|
606
|
+
<assignment msg_id="msg-002" topic="existing_inactive" topic_id="topic-yyy">
|
|
607
|
+
归入理由(话题已存在但未激活,追加并激活)
|
|
608
|
+
</assignment>
|
|
609
|
+
<assignment msg_id="msg-003" topic="new" topic_name="新话题名称">
|
|
610
|
+
<summary>新话题的简介(约1KB)</summary>
|
|
611
|
+
创建理由
|
|
612
|
+
</assignment>
|
|
613
|
+
...
|
|
614
|
+
</topic_split>
|
|
615
|
+
|
|
616
|
+
## 原则
|
|
617
|
+
|
|
618
|
+
- 同一轮问答(用户消息 + 助手回复)应归入同一话题
|
|
619
|
+
- 如果一条消息明确属于多个话题,归入最主要的那个
|
|
620
|
+
- 新话题的简介要能指导后续的话题匹配
|
|
621
|
+
- 不确定的消息宁可创建新话题,也不要强行归入不匹配的话题
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
## 7. 话题生命周期
|
|
625
|
+
|
|
626
|
+
```
|
|
627
|
+
创建(拆分时产生)
|
|
628
|
+
│
|
|
629
|
+
▼
|
|
630
|
+
┌─────────┐ ┌─────────┐
|
|
631
|
+
│ 休眠 │ ◄─────► │ 激活 │
|
|
632
|
+
│ │ │ │
|
|
633
|
+
│ 仅简介 │ 相关度 │ 每轮调用 │
|
|
634
|
+
│ 在索引中 │ 持续衰减 │ 灰度评估 │
|
|
635
|
+
└────┬────┘ └────┬────┘
|
|
636
|
+
│ │
|
|
637
|
+
│ 周期性回顾 │ 话题超限
|
|
638
|
+
│ 长期未激活 │
|
|
639
|
+
▼ ▼
|
|
640
|
+
┌─────────┐ ┌─────────┐
|
|
641
|
+
│ 归档 │ │ 拆分为 │
|
|
642
|
+
│ │ │ 子话题 │
|
|
643
|
+
│ 按日期索引│ └─────────┘
|
|
644
|
+
│ 仅主动检索│
|
|
645
|
+
│ 可访问 │
|
|
646
|
+
└─────────┘
|
|
647
|
+
|
|
648
|
+
重新激活路径(休眠 → 激活):
|
|
649
|
+
1. 话题窗口评分回升
|
|
650
|
+
2. 主会话调用 activate_topic
|
|
651
|
+
3. 失忆感知 → 自动深度检索
|
|
652
|
+
|
|
653
|
+
归档检索路径(归档 → 激活):
|
|
654
|
+
仅用户主动要求检索时
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
**状态说明:**
|
|
658
|
+
- **激活**:每轮新消息触发话题窗口调用,返回灰度相关性分数和处理结果
|
|
659
|
+
- **休眠**:仅简介保留在话题索引中,不消耗 LLM 调用,可被三条路径重新激活
|
|
660
|
+
- **归档**:按日期索引存储,不参与正常激活流程,仅用户主动要求时可检索。保留压缩总结版本
|
|
661
|
+
- **拆分**:大话题拆为子话题,各子话题独立管理生命周期
|
|
662
|
+
|
|
663
|
+
## 8. 话题层级
|
|
664
|
+
|
|
665
|
+
话题可以有**子话题**,形成层级结构:
|
|
666
|
+
|
|
667
|
+
```
|
|
668
|
+
话题A:项目重构
|
|
669
|
+
├── 子话题A1:数据库 schema 设计
|
|
670
|
+
├── 子话题A2:API 接口调整
|
|
671
|
+
└── 子话题A3:前端适配
|
|
672
|
+
```
|
|
673
|
+
|
|
674
|
+
子话题与普通话题行为一致,拥有独立的上下文窗口和生命周期。
|
|
675
|
+
|
|
676
|
+
## 9. 持久化
|
|
677
|
+
|
|
678
|
+
话题持久化到文件系统:
|
|
679
|
+
- 每个话题一个持久化文件(如 `topics/topic-xxx.jsonl`)
|
|
680
|
+
- 包含:已拆分进话题的完整消息(带消息 ID)+ 话题简介
|
|
681
|
+
- 消息仅在主会话超限触发拆分时追加
|
|
682
|
+
- 话题简介在每次追加消息后立即更新
|
|
683
|
+
- 时间索引:每个时间段包含哪些话题
|
|
684
|
+
- 话题之间的引用关系
|
|
685
|
+
|
|
686
|
+
### 归档话题持久化
|
|
687
|
+
|
|
688
|
+
- 归档话题存储在独立目录(如 `topics/archived/YYYY-MM/`)
|
|
689
|
+
- 保留压缩总结版本,不保留完整消息历史
|
|
690
|
+
- 按日期索引,支持按时间范围检索
|
|
691
|
+
|
|
692
|
+
## 10. 规模分析
|
|
693
|
+
|
|
694
|
+
| 模型上下文 | 活跃话题数 | 等效上下文 | 用户感知 |
|
|
695
|
+
|-----------|-----------|-----------|---------|
|
|
696
|
+
| 200k | 5 | 1M | 明显改善 |
|
|
697
|
+
| 1M | 10 | 10M | 可能覆盖用户全部活跃话题 |
|
|
698
|
+
|
|
699
|
+
核心论点:10M 量级的等效上下文可能跨过用户体验阈值——人在一段时间内活跃讨论的话题数量和深度有限,系统能完整持有所有活跃话题的上下文时,用户可能永远感知不到"记忆丢失"。
|
|
700
|
+
|
|
701
|
+
话题索引容量:每个话题简介约 1KB,1M 上下文窗口可索引约 1000 个话题。通过周期性归档清理不重要的话题,索引容量在实际使用中不会成为瓶颈。
|
|
702
|
+
|
|
703
|
+
## 11. 与 RAG 的本质区别
|
|
704
|
+
|
|
705
|
+
| 维度 | 话题分流(本方案) | RAG(检索增强生成) |
|
|
706
|
+
|------|------------------|-------------------|
|
|
707
|
+
| 上下文获取 | 主动持有,按需激活 | 被动检索,按需装配 |
|
|
708
|
+
| 信息完整性 | 话题内完整因果链保留 | 返回片段,缺乏上下文连贯性 |
|
|
709
|
+
| 理解深度 | "看到"完整讨论过程后提取 | "搜索到片段后拼起来" |
|
|
710
|
+
| 上下文准备 | 大模型理解后提取相关内容 | 向量相似度机械匹配 |
|
|
711
|
+
| 类比 | 专家阅读完整卷宗后做摘要 | 关键词检索文档片段 |
|
|
712
|
+
| 缓存利用 | 追加式上下文,缓存命中率高 | 每次构造不同上下文,缓存命中率低 |
|
|
713
|
+
|
|
714
|
+
## 12. 缓存优势分析
|
|
715
|
+
|
|
716
|
+
### 话题窗口的缓存特性
|
|
717
|
+
|
|
718
|
+
话题窗口的上下文是追加式的:
|
|
719
|
+
- **系统提示词**:固定不变 → 100% 缓存命中
|
|
720
|
+
- **已拆分消息**:只在拆分操作时追加,大部分时间不变 → 接近 100% 缓存命中
|
|
721
|
+
- **未拆分消息**:每轮变化 → 不命中
|
|
722
|
+
|
|
723
|
+
假设话题窗口:系统提示词 2k + 已拆分消息 100k + 未拆分消息 5k
|
|
724
|
+
- 缓存命中:102k / 107k ≈ 95%
|
|
725
|
+
- 实际成本 ≈ 102k × 0.1 + 5k × 1 = 15.2k token 等效成本
|
|
726
|
+
|
|
727
|
+
### RAG 模式对比
|
|
728
|
+
|
|
729
|
+
每次查询构造的上下文不同:系统提示词 + 不同的检索片段 + 最近消息。
|
|
730
|
+
- 缓存命中仅限系统提示词部分 ≈ 5-8%
|
|
731
|
+
- **每次查询几乎全价计费**
|
|
732
|
+
|
|
733
|
+
### 结论
|
|
734
|
+
|
|
735
|
+
话题模式的缓存命中率(95%)是 RAG 模式(5-8%)的 12-19 倍。虽然话题模式每轮有 N 个并行调用,但单次调用的实际成本只有全价的 ~15%,综合成本可能低于 RAG。
|
|
736
|
+
|
|
737
|
+
## 13. 人类认知类比
|
|
738
|
+
|
|
739
|
+
本方案的设计更接近人类认知模式:
|
|
740
|
+
|
|
741
|
+
- 人维护若干个"活跃心智上下文"(工作项目、家庭事务、技术问题)
|
|
742
|
+
- 被提及时快速"加载"相关上下文,不是逐条搜索记忆
|
|
743
|
+
- 长期不活跃的话题被压缩为"大概印象"(= 话题简介)
|
|
744
|
+
- 需要时可以通过线索重新展开细节(= 话题激活)
|
|
745
|
+
- 每个话题内的连贯性很好
|
|
746
|
+
|
|
747
|
+
## 14. 成本控制策略
|
|
748
|
+
|
|
749
|
+
1. **话题通过索引窗口激活**:只有被激活的话题才消耗 LLM 调用
|
|
750
|
+
2. **灰度衰减自动休眠**:相关度持续低于动态阈值的话题逐步休眠
|
|
751
|
+
3. **动态激活数量控制**:激活话题区间 3-20(默认 10),激活越多阈值越严格
|
|
752
|
+
4. **利用 prompt caching**:话题上下文追加式增长,缓存命中率 ≈ 95%
|
|
753
|
+
5. **分层使用模型**:
|
|
754
|
+
- 话题窗口(上下文提取)→ 便宜模型(如 DeepSeek)
|
|
755
|
+
- 话题索引窗口(路由判断)→ 便宜模型
|
|
756
|
+
- 话题简介生成 → 便宜模型
|
|
757
|
+
- 话题拆分 → 强模型(准确性要求高)
|
|
758
|
+
- 主会话窗口(对话推进)→ 强模型
|
|
759
|
+
6. **话题简介即时更新**:追加消息后立即更新,确保索引窗口始终使用最新简介
|
|
760
|
+
7. **周期性归档**:每日回顾清理不重要的话题,减少激活话题池的噪音
|
|
761
|
+
|
|
762
|
+
## 15. 已确认的设计决策
|
|
763
|
+
|
|
764
|
+
### 15.1 主会话窗口载入内容(已确认)
|
|
765
|
+
|
|
766
|
+
主会话窗口载入的是**话题窗口的处理结果**,不是话题的完整消息记录。每个话题的处理结果包含:
|
|
767
|
+
- 话题引用信息(名称、简介、文件路径)
|
|
768
|
+
- 引用消息 ID 列表 → 系统据此从话题持久化文件提取原始消息原文,注入主会话
|
|
769
|
+
- 总结性输出 → 提供消息原文之上的理解框架(建议不超过 2000 字,软控制)
|
|
770
|
+
|
|
771
|
+
这解决了主会话窗口容量问题:只载入相关消息原文 + 简洁总结,远小于完整话题内容。
|
|
772
|
+
|
|
773
|
+
### 15.2 处理时序(已确认)
|
|
774
|
+
|
|
775
|
+
串行执行:先话题窗口(并行),等待全部返回,再主会话窗口。
|
|
776
|
+
话题窗口是上下文准备步骤,主会话依赖其返回结果。
|
|
777
|
+
|
|
778
|
+
### 15.3 消息冗余(已确认)
|
|
779
|
+
|
|
780
|
+
不存在冗余问题:
|
|
781
|
+
- 未拆分消息保留在主会话中
|
|
782
|
+
- 已拆分消息通过话题窗口的处理结果(引用消息原文 + 总结)间接呈现
|
|
783
|
+
- 最近 20 条消息始终保留(因为话题结果只包含部分引用消息,保留最近原始消息有助于对话连贯性)
|
|
784
|
+
|
|
785
|
+
### 15.4 话题拆分准确性(已确认)
|
|
786
|
+
|
|
787
|
+
**结论:拆分准确性不是问题。**
|
|
788
|
+
|
|
789
|
+
拆分发生在主会话上下文触发上限时,此时话题已经在上下文中被充分讨论,语义非常明确。大模型在这个时间点完全有能力准确判断消息归属。不需要额外的置信度机制或用户纠正流程。
|
|
790
|
+
|
|
791
|
+
拆分的三种结果:
|
|
792
|
+
1. 已激活的话题 → 直接追加
|
|
793
|
+
2. 已存在但未激活的话题 → 追加 + 激活
|
|
794
|
+
3. 新话题 → 创建 + 激活
|
|
795
|
+
|
|
796
|
+
### 15.5 激活话题数量(已确认)
|
|
797
|
+
|
|
798
|
+
**基于排名的动态激活:**
|
|
799
|
+
|
|
800
|
+
- 激活话题数量区间:3-20(可配置,默认 10)
|
|
801
|
+
- 所有话题按滑动平均评分排名,动态决定激活数量
|
|
802
|
+
- 激活话题越多 → 从排名中取的数量越少(严格)
|
|
803
|
+
- 激活话题越少 → 从排名中取的数量越多(宽松)
|
|
804
|
+
- 最低激活阈值防止激活完全不相关的话题
|
|
805
|
+
|
|
806
|
+
设计原则:**宁可多激活,不可遗漏**。多激活的代价是多几个并行调用(缓存命中率高,实际成本低);遗漏的代价是用户感知到失忆(体验损害大)。
|
|
807
|
+
|
|
808
|
+
### 15.6 相关性灰度评估(已确认)
|
|
809
|
+
|
|
810
|
+
**从二元判定改为灰度模式:**
|
|
811
|
+
|
|
812
|
+
- 话题窗口返回 `relevance_score`(0-1),不是 true/false
|
|
813
|
+
- 系统维护滑动平均相关度,渐进式决策
|
|
814
|
+
- 话题相关度经过多轮对话逐步提升或衰减,不会因单轮判断失误而立即休眠
|
|
815
|
+
- 激活判断偏宽松,休眠判断偏保守
|
|
816
|
+
|
|
817
|
+
### 15.7 失忆感知机制(已确认)
|
|
818
|
+
|
|
819
|
+
当大模型在对话中感知到用户认为它"失忆"时:
|
|
820
|
+
- **自动**进入话题索引窗口深度检索,不需要与用户确认
|
|
821
|
+
- 检索到匹配话题 → 激活(阈值放宽)
|
|
822
|
+
- 检索结果模糊 → 可以自然地询问用户以明确话题
|
|
823
|
+
- 模拟人类行为:先尝试自己回忆,想不起来就问对方
|
|
824
|
+
|
|
825
|
+
## 16. 待调优的参数(非架构问题)
|
|
826
|
+
|
|
827
|
+
以下问题本质上都是参数调优问题,不是架构问题。架构已经闭合。建议策略:先用最简参数跑起来,收集运行日志,再基于数据调优。
|
|
828
|
+
|
|
829
|
+
### 16.1 话题窗口输出质量
|
|
830
|
+
|
|
831
|
+
话题窗口返回的两部分内容质量直接影响主会话回复质量:
|
|
832
|
+
- **消息 ID 选择**:选择过少 → 主会话缺少关键细节;选择过多 → 主会话上下文膨胀
|
|
833
|
+
- **总结质量**:总结过于笼统 → 缺乏指导性;总结过于冗长 → 占用主会话空间
|
|
834
|
+
- 总结的软预算建议(不超过 2000 字)通过系统提示词控制,无需硬限制
|
|
835
|
+
|
|
836
|
+
**建议**:初始版本不设硬限制,观察实际运行中主会话窗口上下文占比(话题结果区 vs 未拆分消息区)。如果话题结果区经常超过主会话窗口的 40%,再考虑收紧引用消息数量的指引。
|
|
837
|
+
|
|
838
|
+
### 16.2 灰度参数调优
|
|
839
|
+
|
|
840
|
+
灰度机制引入了若干需要调优的参数。
|
|
841
|
+
|
|
842
|
+
**建议初始值:**
|
|
843
|
+
- 滑动窗口大小:最近 5 轮
|
|
844
|
+
- 最低激活阈值函数:线性,`最低阈值 = 0.2 + 0.03 × 当前激活数`
|
|
845
|
+
- 3 个话题时阈值 0.29(宽松)
|
|
846
|
+
- 10 个话题时阈值 0.5(平衡)
|
|
847
|
+
- 20 个话题时阈值 0.8(严格)
|
|
848
|
+
- 休眠阈值:`最低激活阈值 × 0.5`
|
|
849
|
+
- 激活话题数量区间:3-20,默认 10
|
|
850
|
+
|
|
851
|
+
**调优方法**:运行两周,收集日志(每轮的 relevance_score、激活/休眠事件),基于数据调整。重点关注:
|
|
852
|
+
- 用户感知到"失忆"的频率(说明激活阈值过高)
|
|
853
|
+
- 激活话题数经常打满上限(说明上限过低或休眠阈值过高)
|
|
854
|
+
- 话题窗口返回的引用消息平均数量(指导输出质量调优)
|
|
855
|
+
|
|
856
|
+
### 16.3 周期性回顾参数
|
|
857
|
+
|
|
858
|
+
- 回顾频率:建议每天一次
|
|
859
|
+
- 归档判定的"未激活天数"阈值:建议初始值 7 天
|
|
860
|
+
- 话题合并的相似度判定标准:需要实践确定
|
|
861
|
+
|
|
862
|
+
## 17. 与 Clawdbot 现有方案的关系
|
|
863
|
+
|
|
864
|
+
本方案不是替代现有 memory flush + RAG 方案,而是一种独立的新范式探索。
|
|
865
|
+
|
|
866
|
+
现有方案的核心是 **Write-ahead + Index + Retrieve**(写前记忆 + 索引 + 检索)。
|
|
867
|
+
本方案的核心是 **Partition + Cache + Activate**(分区 + 缓存 + 激活)。
|
|
868
|
+
|
|
869
|
+
两者可以互补:
|
|
870
|
+
- 话题简介本身可以作为 memory 文件被现有 memory search 索引
|
|
871
|
+
- 话题达到拆分极限后的归档内容,可以交给 RAG 索引作为最终降级方案
|