2026-05-20 21:39:12 +08:00

112 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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` 管理入口