topic-memory 0.1.0 → 0.1.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/README.zh-CN.md CHANGED
@@ -1,387 +1,132 @@
1
1
  # Topic Memory
2
2
 
3
- **给现有 LLM 应用加上一层可插拔的长期对话记忆。**
3
+ **按话题找回原始对话,让旧细节重新进入上下文。**
4
4
 
5
- [English](./README.md) · [详细接入指南](./docs/USAGE.zh-CN.md) · [架构与容量说明](./docs/ARCHITECTURE.zh-CN.md)
5
+ [English](./README.md) · [接入指南](./docs/USAGE.zh-CN.md) · [效果验证](./docs/EVALUATION.md) · [架构说明](./docs/ARCHITECTURE.zh-CN.md)
6
6
 
7
- Topic Memory 是一个独立的 TypeScript SDK。它解决的不是“让模型拥有更大的 context window”,而是另一个更实际的问题:**当一段对话持续几百、几千轮以后,怎样让模型在需要时找回旧信息,而不是每次都把完整聊天记录重新塞进 prompt。**
7
+ Topic Memory 是面向聊天应用和 AI Agent TypeScript SDK。它把历史对话整理成话题,根据新问题选择相关话题,再恢复当时的原始对话,交给你已有的主模型使用。
8
8
 
9
- 它会保留完整的 Canonical Transcript,把较早的 completed exchanges 按 topic 组织成可检索的长期记忆;新消息到来时,只打开与当前问题相关的旧 topic,最后把恢复出的上下文作为 `memoryContext` 交给你自己的 Main LLM。
9
+ 例如,用户曾决定去东京时住在**上野,每晚预算 14,000 日元**。之后聊过饮食、项目和天文学,当用户再次问起酒店计划时,SDK 可以重新打开那段对话,并保留可检查的原文依据。
10
10
 
11
- > **它是什么:** LLM 应用的长期记忆插件 / SDK。
12
- > **它不是什么:** 聊天机器人、模型供应商,也不会替代你的 Main LLM。
13
-
14
- ## 它可以用来做什么?
15
-
16
- 适合需要长期连续性的聊天、AI 朋友、Agent 或长期项目助手,例如记住:
17
-
18
- - 用户长期偏好、习惯、人物、地点和个人背景;
19
- - 几百甚至几千个 exchange 以前做过的决定;
20
- - 项目历史、需求变更、以前尝试过的方法和未完成事项;
21
- - 某次旧对话的具体措辞、事件顺序或时间信息;
22
- - 任何不适合永久占用 Main LLM context window、但未来可能需要重新找回的信息。
23
-
24
- 它和“只维护一份不断覆盖的聊天摘要”不同:Topic Memory 会保留原始 Canonical Transcript。检索命中一个 topic 后,可以根据这个 topic 保存的 transcript spans 重新打开当时的原始对话,而不是只能依赖一段已经压缩过的 summary。
25
-
26
- ## 先搞清楚三个角色
27
-
28
- 这是 v0.1 最容易被误解的地方。
29
-
30
- ### Topic Worker
31
-
32
- Topic Worker 不负责回复用户。
33
-
34
- 它在对话进行过程中整理已经完成的 exchanges,把属于同一个讨论主题的连续或相关对话归到一个 topic 下,并保存:
35
-
36
- - topic keywords;
37
- - retrieval terms;
38
- - 对应的原始 transcript spans;
39
- - topic status;
40
- - 时间信息。
41
-
42
- 它更像一个后台“记忆整理员”。
43
-
44
- ### Memory Selector
45
-
46
- Memory Selector 也不回复用户。
47
-
48
- 新消息到来时,它会看:
49
-
50
- - 当前用户消息;
51
- - 最近 5 个 completed exchanges;
52
- - Topic Directory。
53
-
54
- 然后最多选择 3 个可能相关的旧 topic。
55
-
56
- SDK 再根据 topic 保存的 spans 回到 Canonical Transcript,恢复当时的原始对话细节,并生成 `memoryContext`。
57
-
58
- ### 你的 Main LLM
59
-
60
- 真正给用户写回复的仍然是你自己的 **Main LLM**。
61
-
62
- **v0.1 默认可以只配置一个 Memory LLM,让同一个 Memory LLM 同时承担 Topic Worker 和 Memory Selector。这个 Memory LLM 不是 Main LLM。**
63
-
64
- 你当然也可以在自己的产品里让 Memory LLM 和 Main LLM 使用同一个底层模型供应商甚至同一个 model name,但在架构上它们的职责仍然分开:
65
-
66
- ```text
67
- Memory LLM
68
- ├─ Topic Worker:整理记忆
69
- └─ Memory Selector:寻找记忆
70
-
71
- Your Main LLM
72
- └─ 根据当前消息 + memoryContext 生成最终回复
73
- ```
74
-
75
- Topic Memory SDK 不会调用或接管你的 Main LLM。
76
-
77
- ## 工作原理
78
-
79
- v0.1 的流程可以理解成六步。
80
-
81
- ### 1. Canonical Transcript:先保存原始事实
82
-
83
- 每一轮对话都会先进入 Canonical Transcript,并处于:
84
-
85
- - `pending`
86
- - `completed`
87
- - `failed`
88
-
89
- 其中 completed exchange 才会被当作可靠的长期对话证据。
90
-
91
- ### 2. Topic Worker:把旧对话整理成“目录”
92
-
93
- 当至少存在 6 个 completed exchanges 后,Topic Worker 开始处理 active tail。
94
-
95
- 它不会简单地“一轮生成一个记忆”。它会把属于同一主题的多轮对话归为一个 topic,并记录这个 topic 对应原始对话的准确 span。
96
-
97
- ### 3. Topic Directory:只保留轻量索引
98
-
99
- 长期历史不会整段塞给 Selector。
100
-
101
- Selector 先看到的是 Topic Directory——类似一本书的目录:它告诉模型“过去聊过什么”,但不会先把几千轮原文全部加载进来。
102
-
103
- ### 4. Memory Selector:定位可能相关的旧 topic
104
-
105
- 用户发来新消息后,Selector 根据当前问题、最近 5 个 exchanges 和 Topic Directory,最多选择 3 个相关 topic IDs。
106
-
107
- ### 5. Opened Topic Packet:回到原始对话
108
-
109
- 选中 topic 后,SDK 根据它保存的 spans,从 Canonical Transcript 中恢复真正的原始 user / assistant 对话。
110
-
111
- 如果用户问“什么时候”“当时”“多久以前”之类的问题,还可以一起恢复时间元数据。
112
-
113
- ### 6. Main LLM:拿到恢复出的记忆再回复
114
-
115
- 最终 SDK 返回:
116
-
117
- ```ts
118
- retrieved.memoryContext
119
- ```
120
-
121
- 你的 Main LLM 可以把这段内容作为额外上下文使用。
11
+ ## 安装
122
12
 
123
- ```text
124
- Canonical Transcript
125
-
126
-
127
- Topic Worker
128
-
129
-
130
- Topic Store ─────→ Topic Directory
131
-
132
- 当前用户消息 ─────────────┤
133
- 最近 5 个 exchanges ──────┤
134
-
135
- Memory Selector
136
-
137
- 最多 3 个 topic
138
-
139
-
140
- Open Topic Packets
141
-
142
-
143
- memoryContext
144
-
145
-
146
- 你的 Main LLM
13
+ ```bash
14
+ npm install topic-memory
147
15
  ```
148
16
 
149
- 如果 Selector 出错,SDK 会安全降级为长期 `memoryContext` 为空,而不是让整个聊天流程崩掉。
17
+ 使用 ES modules。SDK 要求 Node.js 18+;下方真实模型示例使用 `--env-file`,要求 **Node.js 20.6+**。2026-09-13 已在全新 Node 24 项目中安装并运行公开的 `topic-memory@0.1.0`。
150
18
 
151
- ## 理论上能把“记忆跨度”提高多少?
152
-
153
- Topic Memory 并不会魔法般扩大模型本身的 context window。它做的是把:
154
-
155
- > **“总共保存了多少历史”**
156
-
157
-
158
-
159
- > **“这一次请求真正送进模型多少历史”**
160
-
161
- 拆开。
162
-
163
- 以一个说明性的 128k context 场景为例:如果给历史记录大约 120k tokens,每个 completed exchange 平均约 200 tokens,那么传统“完整历史全部塞回 prompt”的方案大约在 **600 exchanges** 左右就已经接近预算。
164
-
165
- 如果使用 Topic Memory,并假设:
166
-
167
- - 总历史:5,000 exchanges;
168
- - 平均 8 exchanges 被整理成一个 topic;
169
- - 每个 Topic Directory entry 平均约 60 tokens;
170
- - 最近上下文保留 5 exchanges;
171
- - 每次最多打开 3 个 topic;
172
-
173
- 那么这 5,000 exchanges 对应的 memory retrieval prompt,在这组假设下大约仍只有 **43k–45k tokens**。
174
-
175
- 也就是说,在这个示例模型里,能够被系统索引和按需恢复的历史跨度大约从 600 扩展到 5,000 exchanges,约 **8.3×**;同时不需要在每次回复时重放 5,000 exchanges 的全部原文。
176
-
177
- **这不是硬上限,也不是性能 benchmark。** 它只是根据 v0.1 当前数据结构做的容量推算。真实结果取决于消息长度、tokenizer、平均 topic 大小、模型 context window 和 Topic Directory 的增长速度。
178
-
179
- 实际上,5,000 也不是存储层的最大值。v0.1 更早遇到的扩展瓶颈通常会是 Topic Directory 随 topic 数量线性增长。详细公式、假设和相关 long-context memory 研究放在 [架构与容量说明](./docs/ARCHITECTURE.zh-CN.md),不会影响正常安装和使用。
180
-
181
- ## 安装
182
-
183
- 当前版本以源码形式公开,可 clone 使用,也可以通过 `npm pack` 生成 tarball。
19
+ ## 先试一下:不需要 API Key
184
20
 
185
21
  ```bash
186
- npm install
187
- npm run build
188
- npm pack
22
+ git clone https://github.com/ziningshu-code/memory-system-mvp.git
23
+ cd memory-system-mvp
24
+ npm ci
25
+ npm run demo
189
26
  ```
190
27
 
191
- ## 配置 Memory LLM
28
+ 示例载入 **24 轮虚构对话**,找回较早的酒店话题,并打印原始对话。它使用真实 SDK 和**预设的整理、选择响应**,用于展示流程,不代表真实模型的检索准确率。
192
29
 
193
- 内置 adapter 使用 OpenAI-compatible `/chat/completions` 协议:
30
+ 查看可切换中英文的网页演示:
194
31
 
195
32
  ```bash
196
- MEMORY_LLM_BASE_URL=https://your-openai-compatible-endpoint.example/v1
197
- MEMORY_LLM_API_KEY=replace-me
198
- MEMORY_LLM_MODEL=your-memory-model
33
+ npm run build:site
34
+ npm run preview
199
35
  ```
200
36
 
201
- 不要把付费 API Key 放进公开前端 bundle。生产环境建议通过自己的后端或可信代理调用。
37
+ 打开 `http://127.0.0.1:4173`,选择酒店、饮食、项目或未记录信息场景,检查选中的话题和找回的原文。这个预设演示完全在浏览器本地运行,不需要账号、API Key,也不调用模型。
38
+
39
+ ## 快速接入
202
40
 
203
- ## 5 分钟接入
41
+ 你的应用配置一个负责记忆的模型,同时保留自己原有的主模型。主模型应同时收到**最近对话**和**找回的旧证据**:
204
42
 
205
43
  ```ts
206
- import {
207
- createMemory,
208
- createOpenAICompatibleMemoryLlm,
209
- InMemoryStorage,
210
- } from 'topic-memory';
211
-
212
- const memoryLlm = createOpenAICompatibleMemoryLlm({
213
- baseUrl: process.env.MEMORY_LLM_BASE_URL!,
214
- apiKey: process.env.MEMORY_LLM_API_KEY,
215
- model: process.env.MEMORY_LLM_MODEL!,
216
- });
44
+ import { createMemory, createOpenAICompatibleMemoryLlm, InMemoryStorage } from 'topic-memory';
217
45
 
218
46
  const memory = createMemory({
219
47
  storage: new InMemoryStorage(),
220
- llm: memoryLlm,
48
+ llm: createOpenAICompatibleMemoryLlm({
49
+ baseUrl: process.env.MEMORY_LLM_BASE_URL!,
50
+ apiKey: process.env.MEMORY_LLM_API_KEY,
51
+ model: process.env.MEMORY_LLM_MODEL!,
52
+ }),
221
53
  });
222
54
 
223
- async function handleUserMessage(userMessage: string) {
224
- const pending = await memory.begin(userMessage);
225
-
226
- try {
227
- const retrieved = await memory.retrieve({ userMessage });
228
-
229
- // 这里是你自己原本就有的主聊天模型调用。
230
- const assistantReply = await myOwnMainLlm({
231
- userMessage,
232
- memoryContext: retrieved.memoryContext,
233
- recentContext: retrieved.recentContext,
234
- });
235
-
236
- await memory.completeExchange({
237
- exchangeId: pending.id,
238
- assistantText: assistantReply,
239
- });
240
-
241
- await memory.maybeRunTopicWorker();
242
- return assistantReply;
243
- } catch (error) {
244
- await memory.failExchange({
245
- exchangeId: pending.id,
246
- failureReason: error instanceof Error ? error.message : String(error),
247
- });
248
- throw error;
249
- }
250
- }
251
- ```
252
-
253
- SDK **不会**调用 `myOwnMainLlm`。这个函数只是代表你现有 App 里的 Main LLM 调用。
254
-
255
- 完整接法请看 [docs/USAGE.zh-CN.md](./docs/USAGE.zh-CN.md)。
256
-
257
- ## 正确调用顺序
258
-
259
- ```text
260
- 用户消息
261
- → memory.begin()
262
- → memory.retrieve()
263
- → 你的 Main LLM
264
- → memory.completeExchange()
265
- → memory.maybeRunTopicWorker()
266
- ```
267
-
268
- 如果 Main LLM 在 `begin()` 之后调用失败,使用 `memory.failExchange(...)`。
269
-
270
- ## 前 6 个 completed exchanges
271
-
272
- Topic Worker 在至少存在 **6 个 completed exchanges** 之前不会运行。
273
-
274
- 此时:
275
-
276
- - Canonical Transcript 仍然正常保存;
277
- - `recentContext` 仍然可用;
278
- - 因为还没有 topic,`memoryContext` 可能为空。
279
-
280
- 这是正常行为。
281
-
282
- ## Public API
283
-
284
- ```ts
285
- createMemory
286
- MemoryEngine
287
- InMemoryStorage
288
- IndexedDbMemoryStorage
289
- createOpenAICompatibleMemoryLlm
290
- ```
291
-
292
- 主要方法:
293
-
294
- ```ts
295
- begin
296
- beginExchange
297
- completeExchange
298
- failExchange
299
- maybeRunTopicWorker
300
- retrieve
301
- listExchanges
302
- listTopics
303
- getLatestTopicWorkerRun
304
- clear
55
+ const pending = await memory.begin(userMessage);
56
+ const context = await memory.retrieve({ userMessage });
57
+ // 你的主模型接收当前消息、context.recentContext、context.memoryContext。
58
+ const assistantReply = await yourMainModel(userMessage, context);
59
+ await memory.completeExchange({ exchangeId: pending.id, assistantText: assistantReply });
60
+ await memory.maybeRunTopicWorker();
305
61
  ```
306
62
 
307
- `retrieve()` 返回:
308
-
309
- ```ts
310
- {
311
- recentContext,
312
- topicDirectory,
313
- selectedTopicIds,
314
- openedTopicPackets,
315
- memoryContext,
316
- needsTimeMetadata,
317
- trace,
318
- }
319
- ```
63
+ 上面的 `yourMainModel` 代表应用自己的调用。**可以直接运行的完整实现**在 [examples/chat.mjs](./examples/chat.mjs) 和 [provider.mjs](./examples/provider.mjs),包含真实请求、最近上下文注入、失败处理和对话状态管理。
320
64
 
321
- ## 存储
65
+ ## 使用真实模型
322
66
 
323
- Demo / 测试:
67
+ 在克隆的项目中,把 `.env.example` 复制为 `.env`,填写支持 OpenAI-compatible 协议的服务地址、模型和 API Key。配置文件只保存在本地。示例会向你配置的服务发送对话,并可能消耗付费额度。
324
68
 
325
- ```ts
326
- new InMemoryStorage()
69
+ ```bash
70
+ npm run demo:chat
327
71
  ```
328
72
 
329
- 浏览器持久化:
73
+ 也可以先载入虚构对话,再直接提问酒店计划:
330
74
 
331
- ```ts
332
- new IndexedDbMemoryStorage()
75
+ ```bash
76
+ npm run demo:chat -- --seed
333
77
  ```
334
78
 
335
- 服务端生产环境可以实现导出的 `MemoryStorage` interface,接入自己的数据库。
79
+ 对话素材是虚构的;话题整理、选择和最终回答都使用**实际配置的模型**。输入 `/exit` 退出。示例使用内存存储,退出后数据清空。
336
80
 
337
- ## 高级配置
81
+ ## 现在验证到了哪一步?
338
82
 
339
- 默认只需要一个 Memory LLM:
83
+ | 检查 | 结果及含义 |
84
+ | --- | --- |
85
+ | npm 公开软件包 | 已在全新 Node 24 项目安装,并恢复旧对话 |
86
+ | SDK 状态、存储、适配器和检索 | 由 CI 自动检查 |
87
+ | 四个预设演示场景 | 检查原文恢复和信息不存在时的空记忆;[查看记录](./docs/evaluation/scripted.json) |
88
+ | 真实模型对照 | 已提供可运行的测试工具;**暂不声称有真实模型性能结论** |
340
89
 
341
- ```ts
342
- createMemory({ storage, llm: memoryLlm })
343
- ```
90
+ `npm run evaluate` 运行预设检查。`npm run evaluate:live` 使用同一个真实主模型,对比**最近五轮上下文**、**完整历史**和**话题检索**,记录原始回答、字面事实评分、请求耗时,以及服务实际返回的 token 用量。[查看方法和边界](./docs/EVALUATION.md)。
344
91
 
345
- 这个 Memory LLM 同时处理 Topic Worker 和 Selector
92
+ 此前的 **8.3 倍**是容量假设示例,**不是实测的准确率提升或有效记忆提升**。公式和前提保留在[架构与容量说明](./docs/ARCHITECTURE.zh-CN.md)
346
93
 
347
- 也可以拆成两个:
94
+ ## 工作流程
348
95
 
349
- ```ts
350
- createMemory({
351
- storage,
352
- topicWorker: topicWorkerLlm,
353
- selector: selectorLlm,
354
- });
96
+ ```text
97
+ 保存的对话 → 话题整理 → 话题目录
98
+ 新问题 + 最近对话 + 目录 → 选择器
99
+ 选中的话题 ID → 原始对话片段 → 你的主模型
355
100
  ```
356
101
 
357
- 无论哪种配置,都不会替代宿主应用自己的 Main LLM。
358
-
359
- ## 失败降级
102
+ 整理和选择可以使用同一个记忆模型,也支持分别配置。SDK 不生成最终回复,也不替换主模型,不要求 embedding 或向量数据库。
360
103
 
361
- - **Main LLM 调用失败:** 使用 `failExchange`;
362
- - **Topic Worker provider 失败:** 记录失败并保留已有 topics;
363
- - **Topic Worker 输出结构不合法:** 直接拒绝,不写入 Topic Store;
364
- - **Selector 失败:** 长期 `memoryContext` 降级为空;
365
- - **当前问题不需要旧记忆:** `memoryContext` 本来就应该为空。
104
+ ## 当前边界
366
105
 
367
- ## 验证
106
+ - 至少完成 **6 轮对话**才开始生成长期话题;之前最近上下文仍可使用。
107
+ - 每次最多选 **3 个话题**,可能漏掉证据,可检查 `retrieve().trace`。
108
+ - 选择器出错时返回空长期记忆;应用仍需处理请求超时和存储失败。
109
+ - `InMemoryStorage` 不持久化;浏览器可使用 `IndexedDbMemoryStorage`;后端数据库和用户/会话隔离需要实现 `MemoryStorage`。
110
+ - 同一个存储中的对话和整理任务应串行执行,SDK 没有协调并发写入。
111
+ - 目录会随历史增加;v0.1 没有总 token 预算限制。
112
+ - 历史内容应作为不可信的证据处理,不能提升为系统指令。
368
113
 
369
- 仓库 CI 会按真实第三方项目的使用方式验证 package:
114
+ ## 开发检查
370
115
 
371
116
  ```bash
117
+ npm ci
372
118
  npm run build
373
119
  npm run typecheck
374
120
  npm test
375
- npm pack --dry-run
376
121
  npm run smoke:consumer
122
+ npm run evaluate
123
+ npm run build:site
377
124
  ```
378
125
 
379
- `smoke:consumer` 会把 SDK 打包,安装进一个全新的临时 Node 项目,只通过 public package exports 导入,然后运行完整 memory pipeline,并验证模拟的宿主 Main LLM 最终收到非空 `memoryContext`。
380
-
381
- ## 非目标
126
+ ## 参与试用
382
127
 
383
- v0.1 不管理 Persona、Big Five、Relationship、Proactive Messaging、UI、embedding、vector database,也不管理宿主应用的 Main LLM。
128
+ 在自己的开发场景中试一个对话,再[反馈体验](https://github.com/ziningshu-code/memory-system-mvp/issues/new?template=try-it.yml):希望记住什么、安装是否顺利、哪里帮上了忙或第一次失败。公开反馈前请去掉密钥和私人对话。
384
129
 
385
130
  ## License
386
131
 
387
- MIT
132
+ MIT
@@ -0,0 +1,65 @@
1
+ # Evaluation / 效果验证
2
+
3
+ ## Current evidence
4
+
5
+ On 2026-09-13, the public `topic-memory@0.1.0` package was installed into a fresh Node 24 project and used to retrieve an old hotel exchange with a scripted model adapter. The source build, 14 existing SDK tests and fresh-consumer tarball test passed locally on Windows. See CI for checks against the latest revision.
6
+
7
+ The checked-in [scripted result](./evaluation/scripted.json) covers four cases: Tokyo hotel details, a food allergy, a project decision, and an unknown passport number. The three positive facts occur outside the most recent five exchanges.
8
+
9
+ **These checks demonstrate mechanics. They do not establish real-model accuracy, latency, token savings, production readiness, or performance on long conversations.** No real-model result is published here yet.
10
+
11
+ 中文:已验证公开包的安装和预设响应下的原文恢复。预设测试不等于真实模型效果;目前还没有发布真实模型的准确率、速度或费用结论。
12
+
13
+ ## Reproduce the scripted checks
14
+
15
+ ```bash
16
+ npm ci
17
+ npm run evaluate
18
+ ```
19
+
20
+ The SDK ingests a public, synthetic, 24-exchange conversation. Its actual topic validation and span recovery run normally. Worker topic boundaries and selector choices are scripted. This makes the walkthrough stable and useful for debugging the integration, while explicitly removing model quality from the test.
21
+
22
+ For the missing fact, the scripted selector chooses no topic and the SDK returns an empty `memoryContext`. This does not prove that an arbitrary main model will abstain.
23
+
24
+ ## Run the real-model comparison
25
+
26
+ Requires Node 20.6+. Copy `.env.example` to `.env`, configure your provider, then run:
27
+
28
+ ```bash
29
+ npm run evaluate:live
30
+ ```
31
+
32
+ The command makes real provider requests and may incur charges. It sends only the checked-in synthetic dataset and questions, not private chat history. The API key stays in the request header and is not written into the report. Output is saved locally to the ignored `benchmark-results/live.json` file.
33
+
34
+ The small comparison uses the **same final-answer model, system instruction and question** for:
35
+
36
+ 1. **Recent five:** only the latest five exchanges.
37
+ 2. **Full transcript:** all 24 exchanges.
38
+ 3. **Topic memory:** the latest five exchanges plus SDK-retrieved original topic packets.
39
+
40
+ The live worker constructs topics in one batch over the archive. The selector uses the actual model for each question. Questions are independent: their answers are not added back into the archive. Expected answers and scoring rules are never included in the model's input.
41
+
42
+ The run normally makes 1 worker request, 4 selector requests and 12 main-model requests (17 total). If topic construction fails, the report records this and the memory method can fall back to recent context; it is not silently counted as success.
43
+
44
+ ## What the report measures
45
+
46
+ - Raw model answers for each question and method.
47
+ - A transparent literal check for the expected facts. For the unknown fact, a conservative English abstention pattern is checked. Read the answers: this is not a semantic judge and may score a valid paraphrase incorrectly or miss a contradiction.
48
+ - Selected topic IDs, recovered source text, expected evidence sequence numbers, and selector errors.
49
+ - Per-request elapsed milliseconds, including network latency.
50
+ - Input and output token usage **only when the provider reports it**. Missing usage is `null`, not zero.
51
+
52
+ For a fair total token comparison, count the one-time worker construction cost, all selector requests and all topic-memory main-model requests. Show construction separately if amortizing it across later queries. Do not compare the topic method's main-model tokens alone against a baseline's total spend. Prices are not hard-coded; apply the provider's actual rates to recorded usage if you need a monetary estimate.
53
+
54
+ The `memoryCharacters` and `selectorInputCharacters` fields are string lengths, **not token estimates**.
55
+
56
+ ## Limits and next experiments
57
+
58
+ Four hand-written questions over 24 synthetic exchanges are a small integration evaluation. They are not representative of hundreds or thousands of turns. There is one run per method, no confidence interval, no summary/vector-search baseline, and no continuous-ingestion measurement.
59
+
60
+ Before making performance claims, add held-out conversation sets with updates to facts, interleaved topics, similar names, time questions, irrelevant questions, and materially longer archives. Repeat runs and disclose the models, prompts, failures and complete provider usage. Compare against a rolling-summary or retrieval baseline appropriate to the host application.
61
+
62
+ ## The earlier 8.3× figure
63
+
64
+ The [architecture appendix](./ARCHITECTURE.md) contains a capacity calculation under assumed message and topic sizes. It is not an empirical result and must not be presented as measured memory accuracy or capacity improvement.
65
+
package/docs/TRYOUT.md ADDED
@@ -0,0 +1,24 @@
1
+ # First-user try-out
2
+
3
+ Ask 5–10 developers who are already building a chat app or agent to try one task. This is a proposed recruitment plan, not a claim that users have already tested the project.
4
+
5
+ 1. Give them the README and demo link without explaining the architecture first.
6
+ 2. Ask what they think the SDK does and whether it fits a problem they already have.
7
+ 3. Let them install and run the no-key example.
8
+ 4. If relevant, let them connect their own provider and try a sanitized conversation.
9
+ 5. Record the first confusing step, time to first successful retrieval, and whether they would use it again.
10
+
11
+ Use the repository's first-use feedback issue form for voluntary public feedback. Keep private conversations and credentials out of issues. Outreach messages are provided below for the maintainer to send to people they choose; none have been sent automatically.
12
+
13
+ ## Invitation / 邀请文案
14
+
15
+ I'm testing Topic Memory, a small TypeScript SDK that finds older conversation topics and reopens the original messages for an existing chat model. There's a no-key walkthrough and a runnable real-model example. If you're building a chat app or agent, would you try one conversation and tell me the first point that feels confusing or fails? I'm looking for usability and retrieval feedback, not a Star exchange.
16
+
17
+ 我做了一个 TypeScript 记忆 SDK:从旧对话中找到相关话题,再把当时的原文交给已有的聊天模型。现在有无需 API Key 的演示和可以接入真实模型的例子。如果你正在做聊天应用或 Agent,想请你试一个对话,告诉我第一个让你困惑或失败的地方。我主要想了解它是否好接入、能否找回你需要的信息。
18
+
19
+ ## What to record
20
+
21
+ | Date | Relevant use case | Install succeeded | First retrieval succeeded | Main obstacle | Would use again |
22
+ | --- | --- | --- | --- | --- | --- |
23
+
24
+ Read repository Traffic as a separate funnel signal. Low traffic suggests investigating discovery; visitors who fail installation suggest onboarding work; successful trials that do not help suggest product/effectiveness work. Stars are a secondary signal and do not establish any of these alone.