@easynet/agent-memory 1.0.46 → 1.0.48
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 +73 -195
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,92 +1,20 @@
|
|
|
1
1
|
# @easynet/agent-memory
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
默认入口:`createAgentMemory()`。
|
|
3
|
+
## Introduction
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
`@easynet/agent-memory` adds memory storage and recall for agents. It supports common scopes such as `thread`, `cross_thread`, and `knowledge`, and registers the memory client into the default `AgentContext`.
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
import { createAgentMemory } from "@easynet/agent-memory";
|
|
7
|
+
## API Reference
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
| API | What it does | Minimal usage |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `createAgentMemory` | Create a memory client and register it into `AgentContext`. | `const memory = await createAgentMemory({ configPath: "./memory.yaml" })` |
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
await memory.memorize({
|
|
15
|
-
namespace: "user:alice",
|
|
16
|
-
type: "cross_thread",
|
|
17
|
-
content: "用户偏好中文回答,尽量简洁。",
|
|
18
|
-
});
|
|
13
|
+
## Usage
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
const { injectedText } = await memory.recall({
|
|
22
|
-
namespace: "user:alice",
|
|
23
|
-
query: "用户偏好",
|
|
24
|
-
topK: 5,
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
console.log(injectedText);
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Memory Type 关键字
|
|
31
|
-
|
|
32
|
-
- Canonical keyword:`thread`、`cross_thread`、`knowledge`
|
|
33
|
-
- 推荐始终写 canonical keyword
|
|
34
|
-
|
|
35
|
-
可选能力:
|
|
36
|
-
- `memorize({ url })`:直接摄入本地/远程 PDF、txt、HTML、图片(写入 `knowledge`)
|
|
37
|
-
|
|
38
|
-
## 最简单示例(带详细注释)
|
|
39
|
-
|
|
40
|
-
```ts
|
|
41
|
-
import { createAgentMemory } from "@easynet/agent-memory";
|
|
42
|
-
|
|
43
|
-
async function main() {
|
|
44
|
-
// 1) 创建 memory 实例:
|
|
45
|
-
// - 不传参数时,会尝试读取 ./config/memory.yaml
|
|
46
|
-
// - 如果文件不存在,自动退回内存版 in_memory provider
|
|
47
|
-
const memory = await createAgentMemory();
|
|
48
|
-
|
|
49
|
-
// 2) 写入长期偏好(cross_thread):
|
|
50
|
-
// namespace 是逻辑隔离维度,建议固定命名规范(如 user:{id})
|
|
51
|
-
await memory.memorize({
|
|
52
|
-
namespace: "user:alice",
|
|
53
|
-
type: "cross_thread",
|
|
54
|
-
content: "用户希望所有输出优先中文。",
|
|
55
|
-
metadata: {
|
|
56
|
-
source: "chat",
|
|
57
|
-
tags: ["preference", "language"],
|
|
58
|
-
},
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
// 3) 写入知识(knowledge):
|
|
62
|
-
await memory.memorize({
|
|
63
|
-
namespace: "project:demo",
|
|
64
|
-
type: "knowledge",
|
|
65
|
-
content: "Demo API 统一使用 Bearer Token 鉴权。",
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
// 4) 检索上下文:
|
|
69
|
-
// recall 会返回可直接拼进 prompt 的 injectedText
|
|
70
|
-
const result = await memory.recall({
|
|
71
|
-
namespace: "project:demo",
|
|
72
|
-
query: "这个项目如何鉴权?",
|
|
73
|
-
topK: 3,
|
|
74
|
-
budgetTokens: 400,
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
console.log("traceId:", result.traceId);
|
|
78
|
-
console.log("context:\\n", result.injectedText);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
main().catch(console.error);
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## 最简单 YAML(推荐先用这个)
|
|
85
|
-
|
|
86
|
-
`config/memory.yaml`
|
|
15
|
+
Create `config/memory.yaml`:
|
|
87
16
|
|
|
88
17
|
```yaml
|
|
89
|
-
# 最小配置:单一 in_memory provider(进程内存,重启后数据丢失)
|
|
90
18
|
providers:
|
|
91
19
|
- id: default
|
|
92
20
|
type: in_memory
|
|
@@ -97,132 +25,82 @@ memoryTypes:
|
|
|
97
25
|
thread: { providerId: default, allowWrite: true, maxItems: 20 }
|
|
98
26
|
cross_thread: { providerId: default, allowWrite: true, maxItems: 20 }
|
|
99
27
|
knowledge: { providerId: default, allowWrite: true, maxItems: 20 }
|
|
100
|
-
|
|
101
|
-
observability:
|
|
102
|
-
# 是否记录 recall trace(建议开发期开,生产按需)
|
|
103
|
-
trace: false
|
|
104
|
-
|
|
105
|
-
privacy:
|
|
106
|
-
# 写入前移除敏感 metadata 字段
|
|
107
|
-
forbiddenMetadataKeys: [password, api_key, secret, token]
|
|
108
28
|
```
|
|
109
29
|
|
|
110
|
-
|
|
30
|
+
Initialize and use memory:
|
|
111
31
|
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
- id: default
|
|
115
|
-
type: sqlite
|
|
116
|
-
options:
|
|
117
|
-
# SQLite 文件路径;相对路径以该 YAML 所在目录为基准
|
|
118
|
-
dbPath: ./data/agent-memory.db
|
|
119
|
-
|
|
120
|
-
defaultProvider: default
|
|
121
|
-
|
|
122
|
-
memoryTypes:
|
|
123
|
-
thread: { providerId: default, allowWrite: true, maxItems: 50 }
|
|
124
|
-
cross_thread: { providerId: default, allowWrite: true, maxItems: 50 }
|
|
125
|
-
knowledge: { providerId: default, allowWrite: true, maxItems: 50 }
|
|
126
|
-
|
|
127
|
-
observability:
|
|
128
|
-
trace: true
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## 分层配置(按 memory type)
|
|
132
|
-
|
|
133
|
-
当你希望 `thread / cross_thread / knowledge` 各自有独立设置时,推荐使用 `memoryTypes`:
|
|
134
|
-
|
|
135
|
-
```yaml
|
|
136
|
-
providers:
|
|
137
|
-
- id: default
|
|
138
|
-
type: in_memory
|
|
139
|
-
- id: docs
|
|
140
|
-
type: sqlite
|
|
141
|
-
options:
|
|
142
|
-
dbPath: ./data/docs.db
|
|
143
|
-
|
|
144
|
-
defaultProvider: default
|
|
145
|
-
|
|
146
|
-
memoryTypes:
|
|
147
|
-
thread:
|
|
148
|
-
allowWrite: false
|
|
149
|
-
cross_thread:
|
|
150
|
-
maxItems: 20
|
|
151
|
-
budgetTokens: 500
|
|
152
|
-
knowledge:
|
|
153
|
-
providerId: docs
|
|
154
|
-
maxItems: 8
|
|
155
|
-
budgetTokens: 900
|
|
156
|
-
```
|
|
32
|
+
```ts
|
|
33
|
+
import { createAgentMemory } from "@easynet/agent-memory";
|
|
157
34
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
- `memoryTypes.*.maxItems / budgetTokens` 控制该类型召回裁剪预算
|
|
35
|
+
const memory = await createAgentMemory({
|
|
36
|
+
configPath: "./config/memory.yaml",
|
|
37
|
+
});
|
|
162
38
|
|
|
163
|
-
|
|
39
|
+
await memory.memorize("user:alice", "cross_thread", "Prefers concise English answers.");
|
|
164
40
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
- id: longterm
|
|
171
|
-
type: sqlite_vec
|
|
172
|
-
options:
|
|
173
|
-
dbPath: ./data/long-term.sqlite
|
|
174
|
-
dimensions: 1024
|
|
175
|
-
|
|
176
|
-
defaultProvider: knowledge
|
|
41
|
+
const result = await memory.recall({
|
|
42
|
+
namespace: "user:alice",
|
|
43
|
+
query: "language preference",
|
|
44
|
+
topK: 5,
|
|
45
|
+
});
|
|
177
46
|
|
|
178
|
-
|
|
179
|
-
thread:
|
|
180
|
-
providerId: knowledge
|
|
181
|
-
cross_thread:
|
|
182
|
-
providerId: longterm
|
|
183
|
-
knowledge:
|
|
184
|
-
providerId: knowledge
|
|
47
|
+
console.log(result.injectedText);
|
|
185
48
|
```
|
|
186
49
|
|
|
187
|
-
|
|
188
|
-
- `type: sqlite` 需要安装 `better-sqlite3`
|
|
189
|
-
- `type: sqlite_vec` 需要安装 `better-sqlite3`,并提供 provider ctor(推荐:`overrides.providerCtors.sqliteVec`,或在 `stores[].config` 设置 `package` + `exportName`)
|
|
190
|
-
- `type: llamaindex` 需要安装 `llamaindex`,并提供 provider ctor(推荐:`overrides.providerCtors.llamaindex`,或在 `stores[].config` 设置 `package` + `exportName`)
|
|
191
|
-
- URL 摄入 PDF 需要安装 `pdf-parse`
|
|
192
|
-
- `type: mem0` 需要安装 `mem0ai`
|
|
193
|
-
|
|
194
|
-
## 扩展 Provider(extension)
|
|
50
|
+
### YAML config
|
|
195
51
|
|
|
196
|
-
|
|
197
|
-
也可以直接复用 `@easynet/agent-memory` 已导出的 provider(如 `InMemoryStoreProvider` / `SqliteStoreProvider` / `RAGProvider` / `Mem0Provider`)。
|
|
52
|
+
Example `config/memory.yaml`:
|
|
198
53
|
|
|
199
54
|
```yaml
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
55
|
+
apiVersion: easynet.world/v1
|
|
56
|
+
kind: MemoryConfig
|
|
57
|
+
metadata:
|
|
58
|
+
name: agent-memory-default
|
|
59
|
+
spec:
|
|
60
|
+
memory:
|
|
61
|
+
thread:
|
|
62
|
+
store:
|
|
63
|
+
type: in_memory
|
|
64
|
+
allowWrite: true
|
|
65
|
+
maxItems: 20
|
|
66
|
+
sessionCompaction:
|
|
67
|
+
enabled: true
|
|
68
|
+
maxTokens: 3000
|
|
69
|
+
keepRecentTurns: 12
|
|
70
|
+
summaryKey: __session_summary__
|
|
71
|
+
checkEveryTurns: 3
|
|
72
|
+
|
|
73
|
+
cross_thread:
|
|
74
|
+
store:
|
|
75
|
+
type: in_memory
|
|
76
|
+
allowWrite: true
|
|
77
|
+
maxItems: 20
|
|
78
|
+
|
|
79
|
+
knowledge:
|
|
80
|
+
store:
|
|
81
|
+
type: in_memory
|
|
82
|
+
allowWrite: true
|
|
83
|
+
maxItems: 20
|
|
84
|
+
|
|
85
|
+
observability:
|
|
86
|
+
trace: false
|
|
87
|
+
|
|
88
|
+
privacy:
|
|
89
|
+
forbiddenMetadataKeys:
|
|
90
|
+
- password
|
|
91
|
+
- api_key
|
|
92
|
+
- secret
|
|
93
|
+
- token
|
|
223
94
|
```
|
|
224
95
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
-
|
|
228
|
-
-
|
|
96
|
+
Explanation:
|
|
97
|
+
|
|
98
|
+
- `spec.memory.thread`: short-term conversational memory.
|
|
99
|
+
- `spec.memory.cross_thread`: long-term user or session memory across conversations.
|
|
100
|
+
- `spec.memory.knowledge`: knowledge storage for reusable facts and documents.
|
|
101
|
+
- `store.type`: backend type, such as `in_memory`.
|
|
102
|
+
- `allowWrite`: whether this memory scope can accept writes.
|
|
103
|
+
- `maxItems`: maximum number of recalled items kept per scope.
|
|
104
|
+
- `sessionCompaction`: optional summarization of long thread history.
|
|
105
|
+
- `observability.trace`: enable recall tracing for debugging.
|
|
106
|
+
- `privacy.forbiddenMetadataKeys`: metadata keys that should be stripped before storage.
|