112 lines
5.0 KiB
Markdown
Raw Normal View History

2026-05-20 21:39:12 +08:00
---
title: 记忆系统
created: 2026-04-13
updated: 2026-04-26
type: entity
tags: [memory, agent]
sources: [packages/backend/src/modules/netaclaw/memory/, packages/backend/src/modules/netaclaw/service/memory_admin.ts, packages/backend/src/modules/netaclaw/service/memory_type.ts, packages/backend/src/modules/netaclaw/tools/builtin/memory.ts, packages/backend/src/modules/netaclaw/tools/builtin/memory_types.ts, packages/frontend/src/modules/agent/views/memory.vue]
---
# 记忆系统
Agent 的长期记忆存储支持跨会话知识积累。2026-04-26 后记忆系统从“对话开始静默预取”调整为“Prompt 强约束 + Agent 显式调用工具”并补齐了管理页面、类型管理、MySQL/SQLite 双后端分页和统计能力。
## 关键文件
| 文件 | 职责 |
|------|------|
| `memory/provider.ts` | 记忆提供商接口定义 |
| `memory/factory.ts` | 工厂函数MySQL/SQLite 切换) |
| `memory/registry.ts` | 按 Agent 缓存 MemoryProvider统一路由 MySQL/SQLite |
| `memory/mysql_provider.ts` | MySQL 实现 |
| `memory/sqlite_provider.ts` | SQLite 实现本地轻量含迁移、FTS、busy_timeout |
| `service/memory_admin.ts` | 管理端记忆分页、增删改查、统计 |
| `service/memory_type.ts` | 记忆类型 CRUD 和系统类型删除保护 |
| `tools/builtin/memory.ts` | `memory_save` / `memory_recall` 工具 |
| `tools/builtin/memory_types.ts` | `memory_list_types` / `memory_stats` 工具 |
| `views/memory.vue` | 前端记忆管理页 |
## 提供商接口
```typescript
interface MemoryProvider {
save(entry): Promise<MemoryEntry>;
update(id, partial): Promise<MemoryEntry>;
delete(id): Promise<void>;
search(query, opts): Promise<MemoryEntry[]>;
list(opts): Promise<MemoryEntry[]>;
getById(id): Promise<MemoryEntry | null>;
page(opts): Promise<MemoryPageResult>;
count(opts): Promise<number>;
}
```
`page``count` 是管理页与统计侧的关键接口;`userId` 在管理查询里可选,以支持跨用户检索。[[tool-governance]] 在解析工具时会根据 Agent 的 memory 配置注入记忆工具。
## 记忆类型
| 类型 | 用途 | 说明 |
|------|------|------|
| `user` | 用户画像和偏好 | 系统内置类型 |
| `project` | 项目知识和进展 | 系统内置类型 |
| `feedback` | 用户纠正/确认 | 系统内置类型 |
| `reference` | 外部资源链接 | 系统内置类型 |
| 自定义类型 | 业务扩展 | 存储在 `netaclaw_memory_type` |
`netaclaw_memory_type` 使用 `key/name/description/icon/isSystem` 描述类型。系统内置类型不可删除Agent 可通过 `memory_list_types` 查看当前可用类型。
## 工作流
```
Agent 执行前
→ AgentExecutor 检查 memory.enabled
→ MemoryProviderRegistry 按 Agent 选择 MySQL/SQLite provider
→ provider.count() 只判断是否已有记忆,不静默读取内容
→ prompt_builder 在 Layer 1.5 注入记忆行为指令
→ tool_resolver 强制注入 memory_save / memory_recall / memory_list_types / memory_stats
→ Agent 必须显式调用 memory_recall 后再使用或更新记忆
```
这条路径的设计目标是避免旧的静默 prefetch 把过期或不相关记忆塞进上下文。Prompt 会要求已有记忆时先 `memory_recall`,需要全量回忆时使用 `query="*"`,环境类记忆写入前要先检索,避免多设备/路径信息重复写入。
## 工具语义
| 工具 | 作用 | 关键约束 |
|------|------|---------|
| `memory_save` | create/update/delete 记忆 | create 时同 agent/user/type/name 已存在则幂等更新 |
| `memory_recall` | 按 query/type/id 检索 | query 为空或 `*` 时走 listsearch 失败时 fallback list |
| `memory_list_types` | 列出可用类型 | 优先读 DB 类型,失败回落内置类型 |
| `memory_stats` | 统计当前 Agent 记忆数量和类型分布 | 基于 provider.list |
## 数据表
`netaclaw_memory`
- `agentName`(索引)、`userId`(索引)
- `type`user/project/feedback/reference/自定义)
- `name`(标题)、`content`(正文)、`description`
- `metadata`(结构化元数据)
`netaclaw_memory_type`
- `key`(唯一类型标识)
- `name``description``icon`
- `isSystem`(系统类型删除保护)
## 管理页
`/agent/memory` 提供记忆管理 UI
- 左侧按 Agent 展示统计,并标识 MySQL/SQLite 后端。
- 右侧支持按 Agent、类型、关键词分页筛选。
- 支持新增、编辑、删除记忆;编辑时使用 `updatedAt` 做乐观锁。
- 类型管理弹窗可新增/删除自定义类型,系统类型不可删除。
管理 API 在 `/admin/netaclaw/memory/*``/admin/netaclaw/memory_type/*` 下,跨后端查询时 MySQL 直接分页SQLite Agent 通过 provider 聚合后排序分页。
## 相关页面
- [[netaclaw-module]] — 所属模块
- [[agent-runtime]] — 运行时注入记忆工具和 Prompt
- [[prompt-builder]] — 记忆行为指令所在的 Prompt 分层
- [[tool-system]] — memory_save/recall/list_types/stats 工具
- [[frontend-architecture]] — `/agent/memory` 管理入口