mem8-fs 0.2.0__tar.gz
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.
- mem8_fs-0.2.0/.gitignore +40 -0
- mem8_fs-0.2.0/LICENSE +21 -0
- mem8_fs-0.2.0/PKG-INFO +367 -0
- mem8_fs-0.2.0/README.md +305 -0
- mem8_fs-0.2.0/mem8/__init__.py +29 -0
- mem8_fs-0.2.0/mem8/api.py +480 -0
- mem8_fs-0.2.0/mem8/application/__init__.py +1 -0
- mem8_fs-0.2.0/mem8/application/check.py +725 -0
- mem8_fs-0.2.0/mem8/application/ports.py +167 -0
- mem8_fs-0.2.0/mem8/application/prompts.py +240 -0
- mem8_fs-0.2.0/mem8/application/query.py +42 -0
- mem8_fs-0.2.0/mem8/application/retrieve.py +171 -0
- mem8_fs-0.2.0/mem8/application/update.py +910 -0
- mem8_fs-0.2.0/mem8/cli.py +471 -0
- mem8_fs-0.2.0/mem8/config.py +135 -0
- mem8_fs-0.2.0/mem8/domain/__init__.py +1 -0
- mem8_fs-0.2.0/mem8/domain/card.py +37 -0
- mem8_fs-0.2.0/mem8/domain/check_report.py +40 -0
- mem8_fs-0.2.0/mem8/domain/eval_run.py +33 -0
- mem8_fs-0.2.0/mem8/domain/exceptions.py +51 -0
- mem8_fs-0.2.0/mem8/domain/knowledge.py +20 -0
- mem8_fs-0.2.0/mem8/domain/link.py +100 -0
- mem8_fs-0.2.0/mem8/domain/message.py +72 -0
- mem8_fs-0.2.0/mem8/domain/retrieval_result.py +25 -0
- mem8_fs-0.2.0/mem8/domain/update_report.py +25 -0
- mem8_fs-0.2.0/mem8/infrastructure/__init__.py +1 -0
- mem8_fs-0.2.0/mem8/infrastructure/anthropic_llm.py +71 -0
- mem8_fs-0.2.0/mem8/infrastructure/embedding_providers/__init__.py +1 -0
- mem8_fs-0.2.0/mem8/infrastructure/embedding_providers/local_provider.py +43 -0
- mem8_fs-0.2.0/mem8/infrastructure/embedding_providers/openai_provider.py +39 -0
- mem8_fs-0.2.0/mem8/infrastructure/embedding_providers/voyage_provider.py +39 -0
- mem8_fs-0.2.0/mem8/infrastructure/filesystem.py +105 -0
- mem8_fs-0.2.0/mem8/infrastructure/fts5_index.py +73 -0
- mem8_fs-0.2.0/mem8/infrastructure/migrations/__init__.py +3 -0
- mem8_fs-0.2.0/mem8/infrastructure/migrations/v001_init.sql +39 -0
- mem8_fs-0.2.0/mem8/infrastructure/migrations/v002_fts.sql +13 -0
- mem8_fs-0.2.0/mem8/infrastructure/migrations/v003_evals.sql +18 -0
- mem8_fs-0.2.0/mem8/infrastructure/migrations/v004_workspace_state.sql +19 -0
- mem8_fs-0.2.0/mem8/infrastructure/rrf.py +40 -0
- mem8_fs-0.2.0/mem8/infrastructure/sqlite_migrator.py +87 -0
- mem8_fs-0.2.0/mem8/infrastructure/sqlite_storage.py +331 -0
- mem8_fs-0.2.0/mem8/infrastructure/sqlite_vec_index.py +64 -0
- mem8_fs-0.2.0/mem8/infrastructure/tokenizer.py +33 -0
- mem8_fs-0.2.0/mem8/infrastructure/toml_writer.py +80 -0
- mem8_fs-0.2.0/mem8/infrastructure/workspace_lock.py +77 -0
- mem8_fs-0.2.0/pyproject.toml +109 -0
mem8_fs-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.so
|
|
6
|
+
.Python
|
|
7
|
+
build/
|
|
8
|
+
dist/
|
|
9
|
+
*.egg-info/
|
|
10
|
+
*.egg
|
|
11
|
+
|
|
12
|
+
# Virtual environments
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
env/
|
|
16
|
+
|
|
17
|
+
# uv
|
|
18
|
+
.uv-cache/
|
|
19
|
+
|
|
20
|
+
# IDE
|
|
21
|
+
.idea/
|
|
22
|
+
.vscode/
|
|
23
|
+
*.swp
|
|
24
|
+
|
|
25
|
+
# OS
|
|
26
|
+
.DS_Store
|
|
27
|
+
Thumbs.db
|
|
28
|
+
|
|
29
|
+
# Test / coverage
|
|
30
|
+
.pytest_cache/
|
|
31
|
+
.coverage
|
|
32
|
+
htmlcov/
|
|
33
|
+
.mypy_cache/
|
|
34
|
+
.ruff_cache/
|
|
35
|
+
|
|
36
|
+
# mem8 runtime artifacts (do not ignore docs/)
|
|
37
|
+
*.mem8.db
|
|
38
|
+
|
|
39
|
+
.claude/
|
|
40
|
+
.superpowers/
|
mem8_fs-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 mem8 contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
mem8_fs-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: mem8-fs
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Agent memory framework: md-based, sqlite-indexed, RRF-fused retrieval
|
|
5
|
+
Author: mem8 contributors
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 mem8 contributors
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Keywords: agent,ai,llm,memory,semantic-search,sqlite
|
|
29
|
+
Classifier: Development Status :: 3 - Alpha
|
|
30
|
+
Classifier: Intended Audience :: Developers
|
|
31
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
32
|
+
Classifier: Operating System :: OS Independent
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
36
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
37
|
+
Requires-Python: >=3.11
|
|
38
|
+
Requires-Dist: anthropic-tokenizer>=0.1
|
|
39
|
+
Requires-Dist: anthropic>=0.40
|
|
40
|
+
Requires-Dist: click>=8.1
|
|
41
|
+
Requires-Dist: numpy>=1.26
|
|
42
|
+
Requires-Dist: pydantic-settings>=2.0
|
|
43
|
+
Requires-Dist: pydantic>=2.6
|
|
44
|
+
Requires-Dist: sqlite-vec>=0.1.6
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
47
|
+
Requires-Dist: pytest-cov>=5; extra == 'dev'
|
|
48
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
49
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
50
|
+
Provides-Extra: evals
|
|
51
|
+
Requires-Dist: pytest>=8.0; extra == 'evals'
|
|
52
|
+
Requires-Dist: pyyaml>=6; extra == 'evals'
|
|
53
|
+
Requires-Dist: rich>=13; extra == 'evals'
|
|
54
|
+
Provides-Extra: local
|
|
55
|
+
Requires-Dist: onnxruntime>=1.17; extra == 'local'
|
|
56
|
+
Requires-Dist: sentence-transformers>=3.0; extra == 'local'
|
|
57
|
+
Provides-Extra: openai
|
|
58
|
+
Requires-Dist: openai>=1.40; extra == 'openai'
|
|
59
|
+
Provides-Extra: voyage
|
|
60
|
+
Requires-Dist: voyageai>=0.2; extra == 'voyage'
|
|
61
|
+
Description-Content-Type: text/markdown
|
|
62
|
+
|
|
63
|
+
# mem8
|
|
64
|
+
|
|
65
|
+
## mem8 0.2: structured messages and dual update APIs
|
|
66
|
+
|
|
67
|
+
String message content remains backwards compatible. Rich transcripts can use
|
|
68
|
+
vendor-neutral `text`, `thinking`, `tool_call`, `tool_result`, and
|
|
69
|
+
`attachment_text` parts:
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from mem8 import (
|
|
73
|
+
AttachmentTextPart,
|
|
74
|
+
Memory,
|
|
75
|
+
Message,
|
|
76
|
+
TextPart,
|
|
77
|
+
ThinkingPart,
|
|
78
|
+
ToolCallPart,
|
|
79
|
+
ToolResultPart,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
messages = [Message(role="assistant", content=[
|
|
83
|
+
ThinkingPart(text="private reasoning"),
|
|
84
|
+
ToolCallPart(call_id="call-1", name="python_version"),
|
|
85
|
+
ToolResultPart(call_id="call-1", content="Python 3.12"),
|
|
86
|
+
AttachmentTextPart(text="project requires Python 3.12", filename="README.txt"),
|
|
87
|
+
TextPart(text="The project uses Python 3.12."),
|
|
88
|
+
])]
|
|
89
|
+
|
|
90
|
+
with Memory.open() as memory:
|
|
91
|
+
memory.update(messages) # extracts Knowledge, then builds memory
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
During extraction, `thinking`, `tool_call`, and failed `tool_result` parts are
|
|
95
|
+
excluded by default. Text, successful textual tool results, and extracted
|
|
96
|
+
attachment text can be used as evidence. Binary attachments are not accepted.
|
|
97
|
+
|
|
98
|
+
When an external LLM has already summarized the knowledge, skip compression
|
|
99
|
+
and directly reuse mem8's deduplication, decision, and write-back pipeline:
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from mem8 import Knowledge, Memory
|
|
103
|
+
|
|
104
|
+
knowledges = [Knowledge(
|
|
105
|
+
claim="The user prefers concise answers.",
|
|
106
|
+
scope="communication preferences",
|
|
107
|
+
evidence=["Please keep answers concise."],
|
|
108
|
+
confidence=1.0,
|
|
109
|
+
suggested_tags=["preference", "style"],
|
|
110
|
+
)]
|
|
111
|
+
|
|
112
|
+
with Memory.open() as memory:
|
|
113
|
+
report = memory.update_from_knowledge(
|
|
114
|
+
knowledges,
|
|
115
|
+
operation_key="memory-intent:example-1",
|
|
116
|
+
expected_generation=memory.generation,
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
- `Memory.update(messages)` remains the transcript-driven API for future dream
|
|
121
|
+
workflows.
|
|
122
|
+
- `Memory.update_from_knowledge(knowledges)` is the preferred API for knowledge
|
|
123
|
+
already summarized by an external LLM; it accepts 1 to 10 items per call.
|
|
124
|
+
- Both modes share write logic, locking, operation receipts, and optimistic
|
|
125
|
+
generation checks. Read-only workspaces reject both modes.
|
|
126
|
+
- mem8 has no MCP, agent_runner, admgraiindustry, or vendor transcript SDK
|
|
127
|
+
dependency. Hosts map SDK events into mem8's generic message parts.
|
|
128
|
+
|
|
129
|
+
CLI equivalents:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
uv run mem8 update --messages messages.jsonl
|
|
133
|
+
uv run mem8 update-knowledge --knowledge-file knowledges.json
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Installation from PyPI
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pip install mem8-fs
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
The distribution name is `mem8-fs`; the Python import package remains `mem8`:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
from mem8.api import Memory
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
mem8 是一个面向 AI Agent 的本地优先长期记忆 Python 包。Markdown 是记忆正文的事实来源;SQLite 保存元数据、链接和评估记录,并通过 FTS5 BM25、sqlite-vec 向量检索及 RRF 融合提供混合检索。LLM 负责从对话中提炼、判断和更新记忆,也用于检查并修复断链。
|
|
149
|
+
|
|
150
|
+
当前版本为 `0.2.0`,支持本地 Markdown 记忆、核心记忆注入、按 ID 或路径查询、BM25 与向量混合检索、对话驱动或结构化知识驱动的记忆更新、断链检查修复,以及 retrieval、update、check 评估。默认记忆根目录是当前工作目录下的 `.mem8`。
|
|
151
|
+
|
|
152
|
+
## 环境要求
|
|
153
|
+
|
|
154
|
+
- Python 3.11 或更高版本。
|
|
155
|
+
- 使用 [uv](https://docs.astral.sh/uv/) 管理依赖、虚拟环境和命令。
|
|
156
|
+
- 默认 LLM 为 Anthropic,需要配置 `ANTHROPIC_API_KEY`。
|
|
157
|
+
- 至少安装一种 Embedding Provider:Local、OpenAI 或 Voyage。
|
|
158
|
+
- Local Embedding 首次加载模型时可能需要联网下载模型文件。
|
|
159
|
+
|
|
160
|
+
当前内置 LLM 实现仅支持 Anthropic。`openai` extra 目前只提供 OpenAI Embedding,不提供 OpenAI LLM。
|
|
161
|
+
|
|
162
|
+
## 安装与初始化
|
|
163
|
+
|
|
164
|
+
### 安装项目
|
|
165
|
+
|
|
166
|
+
安装开发、评估和默认 Local Embedding 依赖:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
uv sync --extra dev --extra evals --extra local
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
也可以按需选择 Embedding Provider:
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
uv sync --extra local # 本地 sentence-transformers,默认配置
|
|
176
|
+
uv sync --extra openai # OpenAI Embedding
|
|
177
|
+
uv sync --extra voyage # Voyage Embedding
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 初始化记忆目录
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
uv run mem8 init
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
初始化后,mem8 使用以下目录结构:
|
|
187
|
+
|
|
188
|
+
```text
|
|
189
|
+
.mem8/
|
|
190
|
+
├── core/ # 用户注入的只读核心记忆,首次注入时创建
|
|
191
|
+
├── notes/ # Agent 创建和维护的普通记忆,首次写入时创建
|
|
192
|
+
├── mem8.db # SQLite 数据库及索引
|
|
193
|
+
└── mem8.toml # Provider 与存储配置
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
所有卡片路径都相对于记忆根目录,例如 `notes/context.md`。所有 CLI 命令均可通过 `--memory-root PATH` 指定其他完整记忆根目录;Python API 则通过 `Memory.open(memory_root=...)` 指定。mem8 不会在自定义根目录中再创建第二层 `.mem8`。
|
|
197
|
+
|
|
198
|
+
打开旧工作区时,如果存在 `<memory_root>/.mem8/mem8.toml` 或 `<memory_root>/.mem8/mem8.db`,且根目录不存在同名文件,mem8 会自动将其迁移到根目录。新旧位置同时存在同名文件时会停止迁移,要求人工处理冲突。
|
|
199
|
+
|
|
200
|
+
`journal/` 属于后续恢复机制设计,当前版本不会创建或使用该目录。
|
|
201
|
+
|
|
202
|
+
## CLI 使用
|
|
203
|
+
|
|
204
|
+
### 初始化、迁移与配置
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# 初始化工作区;重复执行是安全的
|
|
208
|
+
uv run mem8 init
|
|
209
|
+
|
|
210
|
+
# 单独执行幂等数据库迁移
|
|
211
|
+
uv run mem8 migrate
|
|
212
|
+
|
|
213
|
+
# 修改配置
|
|
214
|
+
uv run mem8 config set llm.model claude-sonnet-4-6
|
|
215
|
+
uv run mem8 config set llm.max_tokens 4096
|
|
216
|
+
uv run mem8 config set embedding.provider local
|
|
217
|
+
uv run mem8 config set embedding.model all-MiniLM-L6-v2
|
|
218
|
+
uv run mem8 config set embedding.dim 384
|
|
219
|
+
uv run mem8 config set storage.db_filename mem8.db
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
配置保存在 `<memory-root>/mem8.toml`,也可以使用环境变量覆盖:
|
|
223
|
+
|
|
224
|
+
- `MEM8_LLM__MODEL`
|
|
225
|
+
- `MEM8_LLM__MAX_TOKENS`
|
|
226
|
+
- `MEM8_EMBEDDING__PROVIDER`
|
|
227
|
+
- `MEM8_EMBEDDING__MODEL`
|
|
228
|
+
- `MEM8_EMBEDDING__DIM`
|
|
229
|
+
- `MEM8_STORAGE__DB_FILENAME`
|
|
230
|
+
|
|
231
|
+
### 核心记忆、检索与查询
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
# 注入核心记忆,仅接受 Markdown 文件
|
|
235
|
+
uv run mem8 core inject ./seed.md
|
|
236
|
+
|
|
237
|
+
# BM25 + Vector + RRF 混合检索
|
|
238
|
+
uv run mem8 retrieve "context overflow" --topk 5 --similarity 0.55
|
|
239
|
+
|
|
240
|
+
# 按 ID 或相对路径查询,二者必须且只能提供一个
|
|
241
|
+
uv run mem8 query --card-id 1
|
|
242
|
+
uv run mem8 query --path notes/context.md
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
### 更新与检查
|
|
246
|
+
|
|
247
|
+
更新命令接收 JSONL 历史对话:
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
uv run mem8 update --messages messages.jsonl
|
|
251
|
+
uv run mem8 check
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
`messages.jsonl` 的每个非空行必须包含 `role` 和 `content`:
|
|
255
|
+
|
|
256
|
+
```json
|
|
257
|
+
{"role":"user","content":"I prefer concise answers."}
|
|
258
|
+
{"role":"assistant","content":"Understood."}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
`update` 执行“压缩 → 决策 → 写回”流程;`check` 扫描并尝试修复断链。
|
|
262
|
+
|
|
263
|
+
### 评估
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
uv run mem8 eval --suite retrieval
|
|
267
|
+
uv run mem8 eval --suite update --record
|
|
268
|
+
uv run mem8 eval --suite check --baseline
|
|
269
|
+
uv run mem8 eval --suite all --record
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`--record` 只持久化普通评估运行,不会自动将其设为基线。`--baseline` 仅在数据库已有 `is_baseline=True` 的显式基线时计算相对差值;门禁指标下降超过 5% 时命令返回非零状态。当前 CLI 尚未提供设置基线的命令,可以通过 Python API 写入基线。
|
|
273
|
+
|
|
274
|
+
## Python API
|
|
275
|
+
|
|
276
|
+
### 打开与使用记忆
|
|
277
|
+
|
|
278
|
+
```python
|
|
279
|
+
from mem8 import Memory
|
|
280
|
+
from mem8.domain.message import Message
|
|
281
|
+
|
|
282
|
+
with Memory.open() as memory:
|
|
283
|
+
results = memory.retrieve(
|
|
284
|
+
"how should context overflow be handled?",
|
|
285
|
+
topk=5,
|
|
286
|
+
similarity=0.55,
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
if results:
|
|
290
|
+
card = memory.query(card_id=results[0].card_id)
|
|
291
|
+
|
|
292
|
+
update_report = memory.update([
|
|
293
|
+
Message(role="user", content="I prefer concise answers."),
|
|
294
|
+
Message(role="assistant", content="Understood."),
|
|
295
|
+
])
|
|
296
|
+
|
|
297
|
+
check_report = memory.check()
|
|
298
|
+
core_card_id = memory.inject_core_card("seed.md")
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`Memory.open` 支持注入自定义组件,便于测试或替换 Provider:
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
memory = Memory.open(
|
|
305
|
+
memory_root="/path/to/memory",
|
|
306
|
+
llm=my_llm,
|
|
307
|
+
embedding=my_embedding,
|
|
308
|
+
tokenizer=my_tokenizer,
|
|
309
|
+
settings=my_settings,
|
|
310
|
+
)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### 公开方法
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
Memory.retrieve(prompt, topk, similarity) -> list[RetrievalResult]
|
|
317
|
+
Memory.query(card_id=..., path=...) -> RetrievalResult
|
|
318
|
+
Memory.update(messages) -> UpdateReport
|
|
319
|
+
Memory.check() -> CheckReport
|
|
320
|
+
Memory.inject_core_card(source_md_path) -> int
|
|
321
|
+
Memory.record_eval_run(run) -> int
|
|
322
|
+
Memory.list_eval_runs(eval_name) -> list[EvalRun]
|
|
323
|
+
Memory.get_baseline_eval_run(eval_name) -> EvalRun | None
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
`retrieve` 要求 prompt 非空、`topk > 0`,且 `similarity` 位于 `[0, 1]`。`query` 必须且只能提供 `card_id` 或 `path` 之一。
|
|
327
|
+
|
|
328
|
+
如需创建评估基线,可构造 `is_baseline=True` 的 `EvalRun`:
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
from mem8.domain.eval_run import EvalRun
|
|
332
|
+
|
|
333
|
+
memory.record_eval_run(EvalRun(..., is_baseline=True))
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### 写入约束
|
|
337
|
+
|
|
338
|
+
- Agent 新卡只能写入 `notes/`。
|
|
339
|
+
- 核心记忆只能通过 `inject_core_card` 或 `core inject` 注入,更新流程不得修改核心卡。
|
|
340
|
+
- 路径必须是安全的根目录相对 Markdown 路径;绝对路径、反斜杠和目录穿越会被拒绝。
|
|
341
|
+
- 创建卡片时禁止覆盖已有路径。
|
|
342
|
+
- 每张卡片最多 4096 token、最多 8 个 Markdown 出链;链接按 1 token 计数。
|
|
343
|
+
- 修改链接前会重新检查来源卡和目标卡的 token 与出链限制。
|
|
344
|
+
- 混合检索中任一路结果足够强即可进入 RRF 候选,避免单路弱分误杀结果。
|
|
345
|
+
|
|
346
|
+
## 开发指南
|
|
347
|
+
|
|
348
|
+
### 质量检查
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
uv run pytest
|
|
352
|
+
uv run ruff check mem8 evals tests
|
|
353
|
+
uv run mypy mem8 evals
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
测试覆盖单元、集成和端到端场景。提交代码前应确保 pytest、Ruff 和 mypy 全部通过。
|
|
357
|
+
|
|
358
|
+
### 项目文档
|
|
359
|
+
|
|
360
|
+
- [产品需求](docs/v1/prd.md)
|
|
361
|
+
- [开发设计](docs/v1/dev.md)
|
|
362
|
+
|
|
363
|
+
`prd.md` 是产品要求基线;`dev.md` 包含当前实现梳理与后续演进设计。README 以当前仓库中实际可运行的公开能力为准。
|
|
364
|
+
|
|
365
|
+
### 当前边界
|
|
366
|
+
|
|
367
|
+
`dev.md` 中的 audit/repair 分离、sync、reindex、recover、journal 恢复和 OpenAI LLM 等属于后续设计目标,当前公开 API 与 CLI 尚未提供这些入口。
|