package evolve // SelfReflector 让 Agent 分析自身表现并自适应调整. // // 这是 C 方案最深层的能力: // - 分析每次会话的效率(轮次数,token 消耗,工具调用频率) // - 识别反复出现的模式(总是先搜索再编辑,某个工具总失败等) // - 生成自适应调整建议(优化提示词,调整工具优先级,预加载上下文等) // - 记录"教训",避免在未来会话中重复犯错 // // 反思产物持久化为 JSON,跨会话累积. // 长期来看,Agent 会变得越来越了解这个项目和用户的工作方式. import ( "context" "encoding/json" "errors" "fmt" "os" "path/filepath" "time" ) // SelfReflector 负责自我反思和自适应. type SelfReflector struct { store *EvolutionStore } // NewSelfReflector 创建自反思器. func NewSelfReflector(store *EvolutionStore) *SelfReflector { return &SelfReflector{store: store} } // Reflection 是一次反思记录. type Reflection struct { // ID 唯一标识 ID string `json:"id"` // SessionID 来源会话 SessionID string `json:"session_id"` // Type 反思类型 Type ReflectionType `json:"type"` // Summary 反思摘要 Summary string `json:"summary"` // Observations Agent 观察到的模式 Observations []Observation `json:"observations"` // Adjustments 建议的调整 Adjustments []Adjustment `json:"adjustments"` // Metrics 会话指标 Metrics *SessionMetrics `json:"metrics,omitempty"` // CreatedAt 创建时间 CreatedAt time.Time `json:"created_at"` } // ReflectionType 反思类型. type ReflectionType string const ( // ReflectPostSession 会话结束后的反思 ReflectPostSession ReflectionType = "post_session" // ReflectOnError 出错后的反思 ReflectOnError ReflectionType = "on_error" // ReflectPeriodic 周期性反思(每 N 次会话) ReflectPeriodic ReflectionType = "periodic" ) // Observation 是 Agent 观察到的一个模式. type Observation struct { // Pattern 模式描述 Pattern string `json:"pattern"` // Frequency 出现频率(次数或百分比描述) Frequency string `json:"frequency"` // Impact 影响评估 Impact string `json:"impact"` // Example 具体例子 Example string `json:"example,omitempty"` } // Adjustment 是一个自适应调整建议. type Adjustment struct { // Type 调整类型 Type AdjustmentType `json:"type"` // Description 调整描述 Description string `json:"description"` // Target 调整目标(工具名,提示词片段等) Target string `json:"target"` // Suggestion 具体建议 Suggestion string `json:"suggestion"` // Priority 优先级 1-5(5 最高) Priority int `json:"priority"` // Applied 是否已应用 Applied bool `json:"applied"` } // AdjustmentType 调整类型. type AdjustmentType string const ( // AdjustPrompt 调整系统提示词 AdjustPrompt AdjustmentType = "prompt" // AdjustToolPriority 调整工具优先级/偏好 AdjustToolPriority AdjustmentType = "tool_priority" // AdjustContext 调整上下文预加载策略 AdjustContext AdjustmentType = "context" // AdjustWorkflow 调整工作流程 AdjustWorkflow AdjustmentType = "workflow" // AdjustLesson 记录一个教训 AdjustLesson AdjustmentType = "lesson" ) // SessionMetrics 是会话指标. type SessionMetrics struct { TurnCount int `json:"turn_count"` TotalInputTokens int `json:"total_input_tokens"` TotalOutputTokens int `json:"total_output_tokens"` TotalCostUSD float64 `json:"total_cost_usd"` ToolUseCounts map[string]int `json:"tool_use_counts"` ErrorCount int `json:"error_count"` Duration time.Duration `json:"duration"` TaskCompleted bool `json:"task_completed"` } // Apply 执行自适应调整提案. func (sr *SelfReflector) Apply(ctx context.Context, proposal *EvolutionProposal) error { data, err := json.Marshal(proposal.Content) if err != nil { return fmt.Errorf("self_reflector: marshal content: %w", err) } var reflection Reflection if err := json.Unmarshal(data, &reflection); err != nil { return fmt.Errorf("self_reflector: unmarshal reflection: %w", err) } if reflection.CreatedAt.IsZero() { reflection.CreatedAt = time.Now() } return sr.save(&reflection) } // save 持久化反思记录. func (sr *SelfReflector) save(r *Reflection) error { data, err := json.MarshalIndent(r, "", " ") if err != nil { return err } filename := fmt.Sprintf("%s_%s.json", r.CreatedAt.Format("20060102_150405"), r.Type) path := filepath.Join(sr.store.dir, "reflections", filename) return os.WriteFile(path, data, 0644) } // LoadRecentReflections 加载最近的反思记录. // // 升华改进(ELEVATED): 返回 ([]*Reflection, []error) 双清单. // 与 SkillLearner.LoadAll 保持一致的契约:成功清单和失败清单并行返回, // 调用方可拿到所有可用反思,同时知道哪些文件损坏了,而不是被单一聚合 error 掩盖. func (sr *SelfReflector) LoadRecentReflections(limit int) ([]*Reflection, []error) { dir := filepath.Join(sr.store.dir, "reflections") entries, err := os.ReadDir(dir) if err != nil { if os.IsNotExist(err) { return nil, nil } return nil, []error{err} } var reflections []*Reflection var errs []error // 倒序遍历(文件名是时间戳前缀,所以自然排序就是时间序) start := len(entries) - limit if start < 0 { start = 0 } for i := len(entries) - 1; i >= start; i-- { entry := entries[i] if entry.IsDir() || filepath.Ext(entry.Name()) != ".json" { continue } data, err := os.ReadFile(filepath.Join(dir, entry.Name())) if err != nil { errs = append(errs, fmt.Errorf("read %s: %w", entry.Name(), err)) continue } var r Reflection if err := json.Unmarshal(data, &r); err != nil { errs = append(errs, fmt.Errorf("parse %s: %w", entry.Name(), err)) continue } reflections = append(reflections, &r) } return reflections, errs } // GetLessons 提取所有"教训"类型的调整建议. // 注入到系统提示中,让 Agent 避免重复犯错. func (sr *SelfReflector) GetLessons() ([]string, error) { reflections, errs := sr.LoadRecentReflections(50) // 部分损坏不阻断:能拿到多少教训就用多少. // 完全无反思记录时才上报聚合错误. if len(reflections) == 0 && len(errs) > 0 { return nil, errors.Join(errs...) } var lessons []string for _, r := range reflections { for _, adj := range r.Adjustments { if adj.Type == AdjustLesson && !adj.Applied { lessons = append(lessons, adj.Suggestion) } } } return lessons, nil } // FormatForSystemPrompt 将反思洞察格式化为系统提示词片段. func (sr *SelfReflector) FormatForSystemPrompt() (string, error) { lessons, err := sr.GetLessons() if err != nil { return "", err } if len(lessons) == 0 { return "", nil } result := "\n# Lessons from Previous Sessions\n\n" for i, lesson := range lessons { result += fmt.Sprintf("%d. %s\n", i+1, lesson) } return result, nil }