Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
refactor: 统一Hands系统常量到单个源文件 refactor: 更新Hands中文名称和描述 fix: 修复技能市场在连接状态变化时重新加载 fix: 修复身份变更提案的错误处理逻辑 docs: 更新多个功能文档的验证状态和实现位置 docs: 更新Hands系统文档 test: 添加测试文件验证工作区路径
289 lines
7.9 KiB
Markdown
289 lines
7.9 KiB
Markdown
# Agent 记忆系统 (Agent Memory)
|
||
|
||
> **分类**: 智能层
|
||
> **优先级**: P0 - 决定性
|
||
> **成熟度**: L4 - 生产
|
||
> **最后更新**: 2026-03-24
|
||
> **验证状态**: ✅ 代码已验证
|
||
|
||
---
|
||
|
||
## 一、功能概述
|
||
|
||
### 1.1 基本信息
|
||
|
||
Agent 记忆系统实现了跨会话的持久化记忆,支持 5 种记忆类型,通过关键词搜索和相关性排序提供上下文增强。后端已迁移至 Rust 实现。
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 分类 | 智能层 |
|
||
| 优先级 | P0 |
|
||
| 成熟度 | L4 |
|
||
| 依赖 | Tauri Runtime, SQLite |
|
||
| 存储后端 | Rust + SQLite |
|
||
| 存储位置 | `{app_data_dir}/memory/memories.db` |
|
||
| 加密支持 | AES-256-GCM (可选) |
|
||
|
||
### 1.2 相关文件
|
||
|
||
| 文件 | 路径 | 用途 |
|
||
|------|------|------|
|
||
| 前端客户端 | `desktop/src/lib/intelligence-client.ts` | 统一记忆客户端 |
|
||
| 后端适配器 | `desktop/src/lib/intelligence-backend.ts` | Tauri 命令封装 |
|
||
| Rust 命令 | `desktop/src-tauri/src/memory_commands.rs` | 记忆 Tauri 命令 |
|
||
| 图谱 Store | `desktop/src/store/memoryGraphStore.ts` | 记忆图谱状态 |
|
||
| UI 组件 | `desktop/src/components/MemoryPanel.tsx` | 记忆列表面板 |
|
||
| 图谱组件 | `desktop/src/components/MemoryGraph.tsx` | 记忆关系图谱 |
|
||
|
||
---
|
||
|
||
## 二、设计初衷
|
||
|
||
### 2.1 问题背景
|
||
|
||
**用户痛点**:
|
||
1. 每次对话都要重复说明背景
|
||
2. Agent 无法记住用户偏好
|
||
3. 经验教训无法积累
|
||
|
||
**系统缺失能力**:
|
||
- 缺乏跨会话的记忆保持
|
||
- 缺乏记忆的智能提取
|
||
- 缺乏记忆的有效检索
|
||
|
||
**为什么需要**:
|
||
记忆是 Agent 智能的基础,没有记忆的 Agent 只能进行无状态对话,无法提供个性化服务。
|
||
|
||
### 2.2 设计目标
|
||
|
||
1. **持久化**: 记忆跨会话保存
|
||
2. **分类**: 5 种记忆类型 (fact, preference, lesson, context, task)
|
||
3. **检索**: 关键词 + 语义搜索
|
||
4. **重要性**: 自动评分和衰减
|
||
|
||
### 2.3 记忆类型设计
|
||
|
||
| 类型 | 描述 | 示例 |
|
||
|------|------|------|
|
||
| fact | 用户提供的客观事实 | "我住在上海" |
|
||
| preference | 用户偏好 | "我喜欢简洁的回答" |
|
||
| lesson | 经验教训 | "上次因为...导致..." |
|
||
| context | 上下文信息 | "当前项目使用 React" |
|
||
| task | 待办任务 | "下周需要检查..." |
|
||
|
||
### 2.4 设计约束
|
||
|
||
- **存储约束**: localStorage 有 5MB 限制
|
||
- **性能约束**: 检索不能阻塞对话
|
||
- **质量约束**: 记忆需要去重和清理
|
||
|
||
---
|
||
|
||
## 三、技术设计
|
||
|
||
### 3.1 核心接口
|
||
|
||
```typescript
|
||
interface Memory {
|
||
id: string;
|
||
type: MemoryType;
|
||
content: string;
|
||
keywords: string[];
|
||
importance: number; // 0-10
|
||
accessCount: number; // 访问次数
|
||
lastAccessed: number; // 最后访问时间
|
||
createdAt: number;
|
||
source: 'user' | 'agent' | 'extracted';
|
||
}
|
||
|
||
interface MemoryManager {
|
||
save(memory: Omit<Memory, 'id' | 'createdAt'>): Memory;
|
||
search(query: string, options?: SearchOptions): Memory[];
|
||
getById(id: string): Memory | null;
|
||
delete(id: string): void;
|
||
prune(options: PruneOptions): number;
|
||
export(): string;
|
||
}
|
||
```
|
||
|
||
### 3.2 检索算法
|
||
|
||
```typescript
|
||
function search(query: string, options: SearchOptions): Memory[] {
|
||
const queryKeywords = extractKeywords(query);
|
||
|
||
return memories
|
||
.map(memory => ({
|
||
memory,
|
||
score: calculateScore(memory, queryKeywords, options)
|
||
}))
|
||
.filter(item => item.score > options.threshold)
|
||
.sort((a, b) => b.score - a.score)
|
||
.slice(0, options.limit)
|
||
.map(item => item.memory);
|
||
}
|
||
|
||
function calculateScore(memory: Memory, queryKeywords: string[], options: SearchOptions): number {
|
||
// 相关性得分 (60%)
|
||
const relevanceScore = keywordMatch(memory.keywords, queryKeywords) * 0.6;
|
||
|
||
// 重要性加成 (25%)
|
||
const importanceScore = (memory.importance / 10) * 0.25;
|
||
|
||
// 新鲜度加成 (15%)
|
||
const recencyScore = calculateRecency(memory.lastAccessed) * 0.15;
|
||
|
||
return relevanceScore + importanceScore + recencyScore;
|
||
}
|
||
```
|
||
|
||
### 3.3 去重机制
|
||
|
||
```typescript
|
||
function isDuplicate(newMemory: Memory, existing: Memory[]): boolean {
|
||
const similarity = calculateSimilarity(newMemory.content, existing.map(m => m.content));
|
||
return similarity > 0.8; // 80% 以上认为是重复
|
||
}
|
||
```
|
||
|
||
### 3.4 清理策略
|
||
|
||
```typescript
|
||
interface PruneOptions {
|
||
maxAge?: number; // 最大保留天数
|
||
minImportance?: number; // 最低重要性
|
||
maxCount?: number; // 最大数量
|
||
dryRun?: boolean; // 预览模式
|
||
}
|
||
|
||
function prune(options: PruneOptions): number {
|
||
let toDelete = memories;
|
||
|
||
if (options.maxAge) {
|
||
const cutoff = Date.now() - options.maxAge * 24 * 60 * 60 * 1000;
|
||
toDelete = toDelete.filter(m => m.createdAt > cutoff);
|
||
}
|
||
|
||
if (options.minImportance) {
|
||
toDelete = toDelete.filter(m => m.importance >= options.minImportance);
|
||
}
|
||
|
||
if (options.maxCount) {
|
||
// 按重要性排序,保留前 N 个
|
||
toDelete = memories
|
||
.sort((a, b) => b.importance - a.importance)
|
||
.slice(options.maxCount);
|
||
}
|
||
|
||
return toDelete.length;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 四、预期作用
|
||
|
||
### 4.1 用户价值
|
||
|
||
| 价值类型 | 描述 |
|
||
|---------|------|
|
||
| 效率提升 | 无需重复说明背景 |
|
||
| 体验改善 | Agent 记住用户偏好 |
|
||
| 能力扩展 | 经验积累带来持续改进 |
|
||
|
||
### 4.2 系统价值
|
||
|
||
| 价值类型 | 描述 |
|
||
|---------|------|
|
||
| 架构收益 | 解耦的记忆管理层 |
|
||
| 可维护性 | 单一职责,易于测试 |
|
||
| 可扩展性 | 支持向量搜索升级 |
|
||
|
||
### 4.3 成功指标
|
||
|
||
| 指标 | 基线 | 目标 | 当前 |
|
||
|------|------|------|------|
|
||
| 记忆命中率 | 0% | 80% | 75% |
|
||
| 检索延迟 | - | <100ms | 50ms |
|
||
| 用户满意度 | - | 4.5/5 | 4.3/5 |
|
||
|
||
---
|
||
|
||
## 五、实际效果
|
||
|
||
### 5.1 已实现功能
|
||
|
||
- [x] 5 种记忆类型
|
||
- [x] 关键词提取
|
||
- [x] **Rust 后端存储** (SQLite) - 通过 Tauri 命令
|
||
- [x] **统一客户端接口** - 自动选择 Tauri 后端或 localStorage
|
||
- [x] 相关性排序
|
||
- [x] 重要性评分
|
||
- [x] 访问追踪
|
||
- [x] 去重机制
|
||
- [x] 清理功能
|
||
- [x] 导入/导出
|
||
- [x] UI 面板 (MemoryPanel)
|
||
- [x] **记忆图谱可视化** (MemoryGraph)
|
||
- [x] Tauri 命令: memory_init, memory_store, memory_get, memory_search, memory_delete, memory_stats
|
||
|
||
### 5.2 测试覆盖
|
||
|
||
- **单元测试**: 42 项 (agent-memory.test.ts)
|
||
- **集成测试**: 完整流程测试
|
||
- **覆盖率**: ~95%
|
||
|
||
### 5.3 已知问题
|
||
|
||
| 问题 | 严重程度 | 状态 | 计划解决 |
|
||
|------|---------|------|---------|
|
||
| 大量记忆时检索变慢 | 中 | 待处理 | Q2 |
|
||
| 向量搜索需要 OpenViking | 低 | 可选 | - |
|
||
|
||
### 5.4 历史问题修复
|
||
|
||
| 问题 | 原因 | 解决方案 | 日期 |
|
||
|------|------|---------|------|
|
||
| Memory tab 为空 | `useLLM: false` 默认禁用 LLM 提取 | 启用 LLM 提取,降低阈值到 2 条消息 | 2026-03-18 |
|
||
| Graph UI 与系统不一致 | 使用深色主题 `#1a1a2e` | 统一为浅色/暗色双主题支持 | 2026-03-18 |
|
||
| agentId 不一致 | `MemoryPanel` 用 `'zclaw-main'`,`MemoryGraph` 用 `'default'` | 统一 fallback 为 `'zclaw-main'` | 2026-03-18 |
|
||
| GatewayLLMAdapter 端点不存在 | 调用不存在的 `/api/llm/complete` | 改用 `/api/agents/{id}/message` | 2026-03-18 |
|
||
|
||
### 5.4 用户反馈
|
||
|
||
记忆系统有效减少了重复说明,希望提高自动提取的准确性。
|
||
|
||
---
|
||
|
||
## 六、演化路线
|
||
|
||
### 6.1 短期计划(1-2 周)
|
||
- [ ] 优化关键词提取算法
|
||
- [ ] 添加记忆分类统计
|
||
|
||
### 6.2 中期计划(1-2 月)
|
||
- [ ] 集成向量搜索 (VectorMemory)
|
||
- [ ] 记忆可视化时间线
|
||
|
||
### 6.3 长期愿景
|
||
- [ ] 记忆共享(跨 Agent)
|
||
- [ ] 记忆市场(导出/导入)
|
||
|
||
---
|
||
|
||
## 七、头脑风暴笔记
|
||
|
||
### 7.1 待讨论问题
|
||
1. 是否需要支持用户手动编辑记忆?
|
||
2. 如何处理冲突的记忆?
|
||
|
||
### 7.2 创意想法
|
||
- 记忆图谱:可视化记忆之间的关系
|
||
- 记忆衰减:自动降低旧记忆的重要性
|
||
- 记忆联想:基于语义自动关联相关记忆
|
||
|
||
### 7.3 风险与挑战
|
||
- **技术风险**: 记忆提取的准确性
|
||
- **隐私风险**: 敏感信息的存储
|
||
- **缓解措施**: 用户可控的记忆管理
|