---
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 为空或 `*` 时走 list；search 失败时 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` 管理入口
