mirror of
https://github.com/OpenBMB/ChatDev.git
synced 2026-04-25 11:18:06 +00:00
142 lines
8.0 KiB
Markdown
Executable File
142 lines
8.0 KiB
Markdown
Executable File
# Memory 模块指南
|
||
|
||
本文档解释 DevAll 的 Memory 体系:memory 列表配置、内置存储实现、Agent 节点如何引用记忆,以及排障建议。代码主要位于 `entity/configs/memory.py`、`node/agent/memory/*.py`。
|
||
|
||
## 1. 体系结构
|
||
1. **Memory Store**:在 YAML `memory[]` 中声明,包含 `name`、`type` 和 `config`。`type` 由 `register_memory_store()` 注册,并映射到具体实现。
|
||
2. **Memory Attachment**:在 Agent 节点(`AgentConfig.memories`)中引用 `MemoryAttachmentConfig`,指定读取/写入策略及检索阶段。
|
||
3. **MemoryManager**:运行期根据 Attachment+Store 构建 Memory 实例,负责 `load()`、`retrieve()`、`update()`、`save()`。
|
||
4. **Embedding**:`SimpleMemoryConfig`、`FileMemoryConfig` 可内嵌 `EmbeddingConfig`,由 `EmbeddingFactory` 创建 OpenAI 或本地向量模型。
|
||
|
||
## 2. Memory 配置示例
|
||
```yaml
|
||
memory:
|
||
- name: convo_cache
|
||
type: simple
|
||
config:
|
||
memory_path: WareHouse/shared/simple.json
|
||
embedding:
|
||
provider: openai
|
||
model: text-embedding-3-small
|
||
api_key: ${API_KEY}
|
||
- name: project_docs
|
||
type: file
|
||
config:
|
||
index_path: WareHouse/index/project_docs.json
|
||
file_sources:
|
||
- path: docs/
|
||
file_types: [".md", ".mdx"]
|
||
recursive: true
|
||
embedding:
|
||
provider: openai
|
||
model: text-embedding-3-small
|
||
```
|
||
|
||
### Mem0 Memory 配置
|
||
```yaml
|
||
memory:
|
||
- name: agent_memory
|
||
type: mem0
|
||
config:
|
||
api_key: ${MEM0_API_KEY}
|
||
agent_id: my-agent
|
||
```
|
||
|
||
## 3. 内置 Memory Store 对比
|
||
| 类型 | 路径 | 特点 | 适用场景 |
|
||
| --- | --- | --- | --- |
|
||
| `simple` | `node/agent/memory/simple_memory.py` | 运行结束后可选择落盘(JSON);使用向量搜索(FAISS)+语义重打分;支持读写 | 小规模对话记忆、快速原型 |
|
||
| `file` | `node/agent/memory/file_memory.py` | 将指定文件/目录切片为向量索引,只读;自动检测文件变更并更新索引 | 知识库、文档问答 |
|
||
| `blackboard` | `node/agent/memory/blackboard_memory.py` | 轻量附加日志,按时间/条数裁剪;不依赖向量检索 | 简易广播板、流水线调试 |
|
||
| `mem0` | `node/agent/memory/mem0_memory.py` | 由 Mem0 云端托管;支持语义搜索 + 图关系;无需本地 embedding 或持久化。需安装 `mem0ai` 包。 | 生产级记忆、跨会话持久化、多 Agent 记忆共享 |
|
||
|
||
> 所有内置 store 都会在 `register_memory_store()` 中注册,摘要可通过 `MemoryStoreConfig.field_specs()` 在 UI 中展示。
|
||
|
||
## 4. MemoryAttachmentConfig 说明
|
||
| 字段 | 说明 |
|
||
| --- | --- |
|
||
| `name` | 引用的 Memory Store 名称(需在 `stores[]` 中存在且唯一)。|
|
||
| `retrieve_stage` | 可选数组,限制检索发生的阶段(`AgentExecFlowStage`:`pre`, `plan`, `gen`, `critique` 等)。缺省表示所有阶段。|
|
||
| `top_k` | 每次检索返回的条数,默认 3。|
|
||
| `similarity_threshold` | 过滤相似度下限(-1 表示不限制)。|
|
||
| `read` / `write` | 是否允许在该节点读取/写回此记忆。|
|
||
|
||
Agent 节点示例:
|
||
```yaml
|
||
nodes:
|
||
- id: answer
|
||
type: agent
|
||
config:
|
||
provider: openai
|
||
model: gpt-4o-mini
|
||
prompt_template: answer_user
|
||
memories:
|
||
- name: convo_cache
|
||
retrieve_stage: ["gen"]
|
||
top_k: 5
|
||
read: true
|
||
write: true
|
||
- name: project_docs
|
||
read: true
|
||
write: false
|
||
```
|
||
执行顺序:
|
||
1. `MemoryManager` 在节点进入 `gen` 阶段时,遍历 Attachments。
|
||
2. 满足阶段与 `read=true` 的 Attachment 调用对应 Memory Store 的 `retrieve()`。
|
||
3. 结果格式化并拼接为“===== 相关记忆 =====”文本写入 Agent 输入上下文。
|
||
4. 节点完成后,`write=true` 的 Attachment 将调用 `update()` 并在必要时 `save()`。
|
||
|
||
## 5. Store 细节
|
||
所有 Memory Store 都持久化统一的 `MemoryItem` 结构:
|
||
- `content_summary`:用于检索的精简文本;
|
||
- `input_snapshot` / `output_snapshot`:序列化的消息块(含 base64 附件),确保多模态上下文不会丢失;
|
||
- `metadata`:记录角色、输入预览、附件 ID 等附加信息。
|
||
这使得 Memory 与 Thinking 模块可以共享多模态内容,无需额外适配。
|
||
### 5.1 SimpleMemory
|
||
- **路径**:`SimpleMemoryConfig.memory_path`(可为 `auto`),缺省仅驻留内存。
|
||
- **检索**:
|
||
1. 以 prompt 构建查询文本并做裁剪。
|
||
2. 调用 Embedding 生成向量 → FAISS `IndexFlatIP` 检索 → 语义重打分(Jaccard/LCS)。
|
||
- **写入**:`update()` 根据输入/输出生成 `MemoryContentSnapshot`,计算摘要哈希去重,再写入 embedding + snapshot + 附件元信息。
|
||
- **适配建议**:控制 `max_content_length` 避免爆 context;结合 `top_k`/`similarity_threshold` 防止无关内容。
|
||
|
||
### 5.2 FileMemory
|
||
- **配置**:至少一个 `file_sources`(路径、后缀过滤、递归、编码)。`index_path` 必填,方便增量更新。
|
||
- **索引流程**:扫描文件 → 切片(默认 500 字符、重叠 50)→ Embedding → 写入 JSON(包括 `file_metadata`)。
|
||
- **检索**:同样使用 FAISS 余弦相似度,只读,不支持 `update()`。
|
||
- **维护**:`load()` 时校验文件哈希,必要时重建索引;建议将 `index_path` 放在持久卷。
|
||
|
||
### 5.3 BlackboardMemory
|
||
- **配置**:`memory_path`(可 `auto`)、`max_items`。若路径不存在则在 Session 目录内创建。
|
||
- **检索**:直接返回最近 `top_k` 条,按时间排序。
|
||
- **写入**:`update()` 以 append 方式存储最新的输入/输出 snapshot(文本 + 块 + 附件信息),不生成向量,适合事件流或人工批注。
|
||
|
||
### 5.4 Mem0Memory
|
||
- **配置**:必须提供 `api_key`(从 [app.mem0.ai](https://app.mem0.ai) 获取)。可选参数 `user_id`、`agent_id`、`org_id`、`project_id` 用于记忆范围控制。
|
||
- **实体范围**:`user_id` 和 `agent_id` 是独立的维度,可在 `add()` 和 `search()` 调用中同时使用。若同时配置,检索时使用 OR 过滤器(`{"OR": [{"user_id": ...}, {"agent_id": ...}]}`)在一次 API 调用中搜索两个范围。写入时两个 ID 同时包含。
|
||
- **检索**:使用 Mem0 服务端语义搜索。通过 `MemoryAttachmentConfig` 中的 `top_k` 和 `similarity_threshold` 控制。
|
||
- **写入**:`update()` 仅将用户输入(`role: "user"` 消息)发送至 Mem0。不包含 Agent 输出,以避免 LLM 响应中的内容被提取为噪声记忆。
|
||
- **持久化**:完全由云端托管。`load()` 和 `save()` 为空操作(no-op)。记忆在不同运行和会话间自动持久化。
|
||
- **依赖**:需安装 `mem0ai` 包(`pip install mem0ai`)。
|
||
|
||
## 6. EmbeddingConfig 提示
|
||
- 字段:`provider`, `model`, `api_key`, `base_url`, `params`。
|
||
- `provider=openai` 时使用 `openai.OpenAI` 客户端,可配置 `base_url` 以兼容兼容层。
|
||
- `params` 支持 `use_chunking`, `chunk_strategy`, `max_length` 等自定义键。
|
||
- `provider=local` 时需提供 `params.model_path`,依赖 `sentence-transformers`。
|
||
|
||
## 7. 排错与最佳实践
|
||
- **重复命名**:内存列表会校验 `memory[]` 名称唯一;重复时抛出 `ConfigError`。
|
||
- **缺少 embedding**:`SimpleMemory`/`FileMemory` 若未提供 embedding,则仅能以追加方式工作(SimpleMemory)或抛出错误(FileMemory)。
|
||
- **权限**:确保 `memory_path`/`index_path` 所在目录可写;容器化部署应挂载卷。
|
||
- **性能**:
|
||
- 大型 FileMemory 建议离线构建索引并缓存。
|
||
- 通过 `retrieve_stage` 控制检索次数,减少模型输入冗余。
|
||
- 调整 `top_k`、`similarity_threshold` 以平衡召回与 token 成本。
|
||
|
||
## 8. 扩展自定义 Memory
|
||
1. 新建 Config + Store(继承 `MemoryBase`)。
|
||
2. 在 `node/agent/memory/registry.py` 中调用 `register_memory_store("my_store", config_cls=..., factory=..., summary="用途")`。
|
||
3. 补充 `FIELD_SPECS`,运行 `python -m tools.export_design_template ...` 以让前端获取新枚举。
|
||
4. 更新本指南或附带 README,说明新 store 的配置项与边界条件。
|