规则系统提供分层的规则管理,支持 Global(全局/用户级)和 Project(项目级)两个作用域。
pkg/memory/rules/
├── types.go # Rule, RuleSet, Scope 类型定义
└── manager.go # 规则管理器和加载器接口
type Scope string
const (
ScopeGlobal Scope = "global" // 全局规则(用户级,跨项目)
ScopeProject Scope = "project" // 项目规则(项目级)
)
// Rule 规则
type Rule struct {
ID string // 规则 ID
Scope Scope // 作用域
Title string // 标题
Content string // 规则内容
Source string // 来源(file/user/system)
SourcePath string // 来源路径
Priority int // 优先级(越大越高)
Enabled bool // 是否启用
Tags []string // 标签
Metadata map[string]any
CreatedAt time.Time
UpdatedAt time.Time
}
// RuleSet 规则集
type RuleSet struct {
GlobalRules []*Rule // 全局规则
ProjectRules map[string][]*Rule // 项目规则(key: projectID)
}
import "github.com/astercloud/aster/pkg/memory/rules"
// 使用默认配置
manager := rules.NewManager(nil)
// 或自定义配置
manager := rules.NewManager(&rules.ManagerConfig{
GlobalRulesPath: ".aster/rules.md", // 全局规则文件
ProjectBasePath: "workspaces", // 项目基础路径
ProjectRuleFile: "AGENTS.md", // 项目规则文件名
AutoReload: false, // 是否自动重载
})
ctx := context.Background()
// 加载全局规则
err := manager.LoadGlobalRules(ctx)
// 加载特定项目的规则
err = manager.LoadProjectRules(ctx, projectID)
// 获取项目的所有规则(包含全局规则)
allRules := manager.GetRulesForProject(projectID)
// 获取规则内容(用于注入 AI 上下文)
content := manager.GetRulesContent(projectID)
// 添加全局规则
globalRule := rules.NewRule(rules.ScopeGlobal, "写作风格", "保持专业、简洁的写作风格")
globalRule.Priority = 10
manager.AddGlobalRule(globalRule)
// 添加项目规则
projectRule := rules.NewRule(rules.ScopeProject, "受众定义", "目标读者是技术从业者")
manager.AddProjectRule(projectID, projectRule)
# 全局写作规则
## 风格指南
- 使用简洁明了的语言
- 避免过度使用被动语态
- 每段不超过 5 句话
## 格式要求
- 使用 Markdown 格式
- 代码块标注语言
- 图片添加 alt 文本
项目级规则通常嵌入在 AGENTS.md 文件中,作为项目上下文的一部分。
实现 Loader 接口可以从数据库或其他来源加载规则:
type Loader interface {
LoadGlobalRules(ctx context.Context) ([]*Rule, error)
LoadProjectRules(ctx context.Context, projectID string) ([]*Rule, error)
}
// 示例:数据库加载器
type DatabaseLoader struct {
db *sql.DB
}
func (l *DatabaseLoader) LoadGlobalRules(ctx context.Context) ([]*Rule, error) {
// 从数据库查询全局规则
rows, err := l.db.QueryContext(ctx,
"SELECT id, title, content, priority FROM rules WHERE scope = 'global' AND enabled = true")
// ...
}
func (l *DatabaseLoader) LoadProjectRules(ctx context.Context, projectID string) ([]*Rule, error) {
// 从数据库查询项目规则
rows, err := l.db.QueryContext(ctx,
"SELECT id, title, content, priority FROM rules WHERE project_id = ? AND enabled = true",
projectID)
// ...
}
// 注册自定义加载器
manager.RegisterLoader(&DatabaseLoader{db: db})
规则按以下顺序应用:
// 规则自动按优先级排序
rules := manager.GetRulesForProject(projectID)
// rules[0] 是优先级最高的规则
// 在构建 prompt 时注入规则
rulesContent := manager.GetRulesContent(projectID)
prompt := fmt.Sprintf(`
你是一个写作助手。请遵循以下规则:
%s
用户请求:%s
`, rulesContent, userRequest)