自动记忆捕获系统从对话和事件中自动生成记忆,支持标签(Tags)系统便于检索和分类。
pkg/memory/auto/
├── types.go # Memory, CaptureEvent, Tags 类型
├── capture.go # 自动捕获器
└── store_inmemory.go # 内存存储实现
type MemoryScope string
const (
ScopeGlobal MemoryScope = "global" // 全局记忆(用户级)
ScopeProject MemoryScope = "project" // 项目记忆
ScopeSession MemoryScope = "session" // 会话记忆
)
// Memory 自动捕获的记忆
type Memory struct {
ID string // 记忆 ID
Scope MemoryScope // 作用域
ProjectID string // 项目 ID
SessionID string // 会话 ID
Title string // 标题(简短描述)
Content string // 详细内容
Tags []string // 标签列表
Source MemorySource // 来源
Confidence float64 // 置信度 (0.0-1.0)
AccessCount int // 访问次数
LastAccessed time.Time // 最后访问时间
Metadata map[string]any
CreatedAt time.Time
UpdatedAt time.Time
}
// MemorySource 记忆来源
const (
SourceDialog MemorySource = "dialog" // 来自对话
SourceTool MemorySource = "tool" // 来自工具调用
SourceSystem MemorySource = "system" // 来自系统
SourceUser MemorySource = "user" // 来自用户显式操作
)
import "github.com/astercloud/aster/pkg/memory/auto"
// 创建内存存储
store := auto.NewInMemoryStore(nil)
// 创建捕获器
capturer := auto.NewCapturer(store, &auto.CapturerConfig{
MinConfidence: 0.5, // 最低置信度阈值
MaxMemoriesPerProject: 1000, // 每项目最大记忆数
AutoTagging: true, // 自动添加标签
DeduplicateWindow: time.Hour, // 去重时间窗口
})
ctx := context.Background()
// 从用户消息中自动捕获记忆
memory, err := capturer.CaptureFromDialog(ctx, projectID, sessionID, "user", userMessage)
if memory != nil {
fmt.Printf("捕获记忆: %s (tags: %v)\n", memory.Title, memory.Tags)
}
// 任务完成事件
memory, err := capturer.CaptureFromEvent(ctx, &auto.CaptureEvent{
Type: auto.EventTaskCompleted,
ProjectID: projectID,
Data: map[string]any{
"task": "实现用户认证模块",
"description": "完成了 JWT 认证和刷新 token 逻辑",
"tags": []string{"backend", "auth"},
},
Timestamp: time.Now(),
})
// 功能实现事件
capturer.CaptureFromEvent(ctx, &auto.CaptureEvent{
Type: auto.EventFeatureImplemented,
ProjectID: projectID,
Data: map[string]any{
"feature": "Visual Workflow Enhancement",
"tags": []string{"frontend", "vue"},
},
})
// 决策事件
capturer.CaptureFromEvent(ctx, &auto.CaptureEvent{
Type: auto.EventDecisionMade,
ProjectID: projectID,
Data: map[string]any{
"decision": "使用 PostgreSQL 而非 MySQL",
"description": "考虑到 JSON 支持和扩展性",
},
})
const (
EventTaskCompleted EventType = "task_completed" // 任务完成
EventFeatureImplemented EventType = "feature_implemented" // 功能实现
EventDecisionMade EventType = "decision_made" // 做出决策
EventPreferenceExpressed EventType = "preference_expressed" // 表达偏好
EventErrorResolved EventType = "error_resolved" // 错误解决
EventMilestoneReached EventType = "milestone_reached" // 达到里程碑
)
捕获器内置默认标签提取器,根据关键词自动添加标签:
// 默认关键词 -> 标签映射
"实现" / "implement" -> #implementation
"修复" / "fix" / "bug" -> #bugfix
"功能" / "feature" -> #feature
"优化" / "optimize" -> #optimization
"重构" / "refactor" -> #refactor
"测试" / "test" -> #testing
"文档" / "doc" -> #documentation
"完成" / "complete" / "done" -> #completed
"前端" / "frontend" -> #frontend
"后端" / "backend" -> #backend
"api" -> #api
"数据库" / "database" -> #database
type TagExtractor interface {
Extract(text string) []TagSuggestion
}
// 实现自定义提取器
type DomainTagExtractor struct {
domainKeywords map[string]string
}
func (e *DomainTagExtractor) Extract(text string) []auto.TagSuggestion {
var suggestions []auto.TagSuggestion
for keyword, tag := range e.domainKeywords {
if strings.Contains(strings.ToLower(text), keyword) {
suggestions = append(suggestions, auto.TagSuggestion{
Tag: tag,
Confidence: 0.8,
Reason: "domain keyword: " + keyword,
})
}
}
return suggestions
}
// 注册自定义提取器
capturer.RegisterTagExtractor(&DomainTagExtractor{
domainKeywords: map[string]string{
"machine learning": "ml",
"deep learning": "dl",
"neural network": "nn",
},
})
store := auto.NewInMemoryStore(&auto.InMemoryStoreConfig{
MaxMemories: 10000, // 最大记忆数
})
// 存储接口
type Store interface {
Save(ctx context.Context, memory *Memory) error
Load(ctx context.Context, id string) (*Memory, error)
List(ctx context.Context, scope MemoryScope, projectID string, limit int) ([]*Memory, error)
Search(ctx context.Context, query string, tags []string, limit int) ([]*Memory, error)
Delete(ctx context.Context, id string) error
}
// 按关键词搜索
memories, err := store.Search(ctx, "workflow", nil, 10)
// 按标签过滤
memories, err = store.Search(ctx, "", []string{"frontend", "vue"}, 10)
// 组合搜索
memories, err = store.Search(ctx, "实现", []string{"backend"}, 10)
stats := store.GetStats()
// {
// "total_memories": 150,
// "tag_counts": {"#implementation": 45, "#bugfix": 30, ...},
// "project_counts": {"project-1": 80, "project-2": 70}
// }
import (
"github.com/astercloud/aster/pkg/memory/auto"
"github.com/astercloud/aster/pkg/memory/project"
)
// 捕获记忆后同步到项目文件
memory, _ := capturer.CaptureFromDialog(ctx, projectID, sessionID, "user", message)
if memory != nil {
projectStore.AppendEntry(ctx, projectID, project.SectionPreferences, &project.Entry{
Content: memory.Content,
Source: "auto_capture",
})
}