后端引擎 backend/pkg/agentcli/(纯引擎库,零业务依赖,剥离 CLI/TUI 外壳): - llm: OpenAI 兼容客户端,复用 model.LLMConfig - tools: ssh_execute(复用 pkg/remoteexec)+ analyze_output + 风险评估黑名单 - safety: 三级安全模式 + 五级风险 + WebSocket 异步确认 - prompt: 五层 System Prompt - core: ReAct 16 轮循环 + 自适应检查点 + 循环检测 - evolver: 四层记忆 + 进化循环,data/agentcli/ 文件存储 集成层: - controller/agent_cli.go: WebSocket 控制器(事件流推流 + 高危确认 + 会话持久化) - model/agent_cli.go: agent_cli_sessions/messages 表 + AutoMigrate - 路由 /ws/agent-cli + /api/v1/aiops/agent-cli/sessions - seed 权限 aiops:agent-cli / aiops:llm-config 前端: - AgentCLI.tsx: 对话流 + 工具块 + 高危确认 + 四模块 tips 面板 - LLMConfig.tsx: 大模型设置独立页 - api/agentCli.ts + Sidebar/App 菜单路由 文档: - docs/agent/ 11 篇(opsxcli 同名文档适配改写 + 00-README 映射总览) 其他: - CLAUDE.md 补充 agent-cli 模块说明 - 修正 .gitignore 根级二进制规则(前导 /,避免误伤 frontend/src/components/aiops/) Co-Authored-By: Claude <noreply@anthropic.com>
516 lines
21 KiB
Markdown
516 lines
21 KiB
Markdown
# 08 - Evolver 自进化引擎
|
||
|
||
> 本文由 opsxcli 同名设计文档适配改写,结合 aiops Agent CLI 的 Web 实现(`backend/pkg/agentcli/evolver/`)。
|
||
> **保留**:四层记忆架构(经验/环境/事实/程序)+ 进化循环思想(OBSERVE → ... → PREDICT)+ 异步非阻塞 + 优雅降级。
|
||
> **精简**:opsxcli 13 步循环 + 3300 行精简为 6 步核心循环 + ~400 行;剥离反射评分、经验整合去重、自动 Skill 提炼等重型子流程。这是有意的精简适配,保留学习能力和注入机制。
|
||
|
||
## 包位置
|
||
|
||
```
|
||
backend/pkg/agentcli/evolver/
|
||
├── engine.go # 进化引擎核心(精简进化循环)
|
||
└── memory.go # 四层记忆 + JSONL/JSON 文件存储
|
||
```
|
||
|
||
## 设计哲学
|
||
|
||
> **让 Agent 越用越聪明** —— 每次任务完成后自动学习经验,优化后续表现。
|
||
|
||
Evolver 借鉴 opsxcli 的设计理念:通过经验积累、LLM 反射分析和环境自适应,实现 Agent 的持续自我优化。用户使用越多,Agent 越了解服务器环境、最佳工具组合和已知事实。
|
||
|
||
**精简原则**:保留「学习 → 存储 → 注入」的核心闭环,剥离重型分析(评分、整合、Skill 提炼)。精简后的 Evolver 仍是真正的自学习引擎,而非装饰品 —— 它真的会把上次任务的经验存下来,并在下次同类任务时注入 Prompt。
|
||
|
||
## 核心数据结构
|
||
|
||
### EvolverEngine
|
||
|
||
```go
|
||
// backend/pkg/agentcli/evolver/engine.go
|
||
|
||
type EvolverEngine struct {
|
||
mem *Memories // 四层记忆集合
|
||
llm llm.Client // 可选,用于提炼经验/事实(nil 时退化为规则学习)
|
||
memDir string // 记忆目录(默认 data/agentcli)
|
||
}
|
||
```
|
||
|
||
> 与 opsxcli 的差异:剥离了 `minSteps` / `simpleThresh` / `moderateThresh` / `onProgress` 等配置字段;剥离 `reflectionClient` 独立接口(直接用 `llm.Client`)。
|
||
|
||
### TaskExecution(任务执行记录)
|
||
|
||
每次任务完成后由 `core.Agent.triggerEvolve` 构造:
|
||
|
||
```go
|
||
type TaskExecution struct {
|
||
Query string // 用户原始查询
|
||
ToolCalls []ToolCallRecord // 工具调用序列
|
||
TotalSteps int // 总迭代步数
|
||
TotalTokens int // 消耗的 token 数
|
||
Duration time.Duration // 执行耗时
|
||
Success bool // 是否成功
|
||
FinalAnswer string // 最终回答
|
||
Timestamp time.Time // 执行时间
|
||
ServerHost string // 目标主机(用于环境记忆)
|
||
}
|
||
```
|
||
|
||
### ToolCallRecord / EvolveResult
|
||
|
||
```go
|
||
type ToolCallRecord struct {
|
||
ToolName string
|
||
Args map[string]interface{}
|
||
Output string
|
||
Duration time.Duration
|
||
Success bool
|
||
RiskLevel int
|
||
}
|
||
|
||
type EvolveResult struct {
|
||
TaskType string // 自动分类的任务类型
|
||
LearnedHint string // 学到的经验提示
|
||
ToolSequence []string // 工具序列
|
||
ExperienceAdded bool // 是否新增经验
|
||
Consolidated bool // 是否触发整合(aiops 版保留字段,未实现)
|
||
}
|
||
```
|
||
|
||
## 精简进化循环(6 步)
|
||
|
||
opsxcli 是 13 步(OBSERVE → EXTRACT → REFLECT → SCORE → COMPARE → LEARN → STORE → CONSOLIDATE → PREDICT → ADAPT → MEMORIZE → DISTILL → FEEDBACK),aiops 精简为 6 步核心:
|
||
|
||
```
|
||
┌─────────────────────────────────────────────┐
|
||
│ Evolve 6 步核心循环 │
|
||
├─────────────────────────────────────────────┤
|
||
│ │
|
||
│ Step 1: OBSERVE ── 观察工具序列 │
|
||
│ ↓ 提取 ToolSequence(如 ssh → analyze) │
|
||
│ │
|
||
│ Step 2: CLASSIFY ── 任务类型分类 │
|
||
│ ↓ 关键词规则匹配(11 类,无需 LLM) │
|
||
│ │
|
||
│ Step 3: LEARN ── 生成经验提示 │
|
||
│ ↓ LLM 优先提炼一句经验,失败降级规则生成 │
|
||
│ │
|
||
│ Step 4: STORE ── 存入经验 + 环境记忆 │
|
||
│ ↓ experience.jsonl + environment.json │
|
||
│ │
|
||
│ Step 5: MEMORIZE ── LLM 提炼持久事实 │
|
||
│ ↓ 异步,从 FinalAnswer 提炼事实存 factual │
|
||
│ │
|
||
│ Step 6: PREDICT ── 注入下次 Prompt │
|
||
│ ↓ GetContextForPrompt(下次任务开始时) │
|
||
│ │
|
||
└─────────────────────────────────────────────┘
|
||
```
|
||
|
||
### 各步骤详解
|
||
|
||
#### Step 1: OBSERVE(观察)
|
||
|
||
提取工具序列:
|
||
|
||
```go
|
||
for _, tc := range exec.ToolCalls {
|
||
result.ToolSequence = append(result.ToolSequence, tc.ToolName)
|
||
}
|
||
```
|
||
|
||
输出如 `["ssh_execute", "analyze_output", "ssh_execute"]`。
|
||
|
||
#### Step 2: CLASSIFY(任务分类)
|
||
|
||
关键词规则匹配(不调 LLM,零成本):
|
||
|
||
```go
|
||
func classifyTask(query string, calls []ToolCallRecord) string {
|
||
text := strings.ToLower(query)
|
||
for _, c := range calls {
|
||
if cmd, ok := c.Args["command"].(string); ok {
|
||
text += " " + strings.ToLower(cmd)
|
||
}
|
||
}
|
||
// 11 类规则匹配
|
||
rules := []struct{ typ string; kws []string }{
|
||
{"磁盘空间", []string{"disk", "空间", "df", "du", "inode", "磁盘", "满了"}},
|
||
{"网络", []string{"network", "网络", "ping", "netstat", "ss ", "端口", "tcp", "dns"}},
|
||
{"服务管理", []string{"service", "服务", "systemctl", "nginx", "mysql", "redis", "restart"}},
|
||
{"软件安装", []string{"install", "安装", "yum", "apt", "docker", "部署", "deploy"}},
|
||
{"进程排查", []string{"process", "进程", "ps ", "kill", "cpu", "top", "卡死"}},
|
||
{"内存排查", []string{"memory", "内存", "mem", "free", "oom", "swap"}},
|
||
{"日志排查", []string{"log", "日志", "journalctl", "tail", "grep"}},
|
||
{"权限问题", []string{"permission", "权限", "chmod", "chown", "denied", "拒绝"}},
|
||
{"性能调优", []string{"performance", "性能", "负载", "load", "慢", "slow"}},
|
||
{"配置管理", []string{"config", "配置", "conf", "vim", "sed"}},
|
||
}
|
||
// ... 命中即返回,否则 "通用运维"
|
||
}
|
||
```
|
||
|
||
**设计要点**:把 query + 实际命令拼起来分类,比单看 query 更准(用户问「检查 nginx」,实际命令可能是 `systemctl status nginx`,分类为「服务管理」更合理)。
|
||
|
||
#### Step 3: LEARN(生成经验提示)
|
||
|
||
LLM 优先,失败降级规则:
|
||
|
||
```go
|
||
func (e *EvolverEngine) learnHint(ctx context.Context, exec *TaskExecution, taskType string) string {
|
||
tools := strings.Join(uniqueStrings(resultToolNames(exec.ToolCalls)), " → ")
|
||
|
||
// 尝试用 LLM 提炼一句经验
|
||
if e.llm != nil {
|
||
if hint := e.llmLearnHint(ctx, exec, taskType, tools, exec.Success); hint != "" {
|
||
return hint
|
||
}
|
||
}
|
||
// 降级:规则生成
|
||
if exec.Success {
|
||
return fmt.Sprintf("完成「%s」类任务时,工具序列 %s 最终成功,可作为参考。", taskType, tools)
|
||
}
|
||
return fmt.Sprintf("尝试「%s」类任务时,工具序列 %s 未成功,下次可换用不同命令或思路。", taskType, tools)
|
||
}
|
||
```
|
||
|
||
LLM 提炼的 prompt(中文):
|
||
|
||
```
|
||
你是运维经验提炼器。根据以下任务执行记录,用一句中文(不超过80字)提炼经验提示,
|
||
说明下次做同类任务的关键要点或推荐工具顺序。只返回经验文本,不要多余解释。
|
||
任务: <query>
|
||
工具序列: <tools>
|
||
结果: 成功/失败
|
||
```
|
||
|
||
**降级策略**:LLM 不可用或超时 → 用规则模板生成(仍然有价值,只是不够精炼)。
|
||
|
||
#### Step 4: STORE(存储经验 + 环境记忆)
|
||
|
||
```go
|
||
exp := ExperienceEntry{
|
||
TaskType: result.TaskType,
|
||
Query: truncate(exec.Query, 200),
|
||
Hint: result.LearnedHint,
|
||
ToolSequence: result.ToolSequence,
|
||
Success: exec.Success,
|
||
Timestamp: exec.Timestamp.Unix(),
|
||
}
|
||
e.mem.AddExperience(exp)
|
||
if exec.ServerHost != "" {
|
||
e.mem.AddHost(exec.ServerHost) // 环境记忆
|
||
}
|
||
```
|
||
|
||
写入 `data/agentcli/experience.jsonl`(追加)和 `environment.json`(去重合并)。
|
||
|
||
#### Step 5: MEMORIZE(LLM 提炼持久事实)
|
||
|
||
仅在任务成功 + 有 FinalAnswer + LLM 可用时触发,**异步执行不阻塞**:
|
||
|
||
```go
|
||
if e.llm != nil && exec.Success && exec.FinalAnswer != "" {
|
||
go e.memorizeFact(ctx, exec) // 异步
|
||
}
|
||
```
|
||
|
||
LLM 提炼 prompt:
|
||
|
||
```
|
||
从以下运维任务记录中,提炼 1 条值得长期记住的事实(如某主机的固定配置、已知问题、约定)。
|
||
如果没有明显可沉淀的事实,回复「无」。只返回事实本身,一句话。
|
||
任务: <query>
|
||
结论: <final_answer>
|
||
```
|
||
|
||
提炼出的事实存入 `factual.jsonl`。
|
||
|
||
> 与 opsxcli 的差异:opsxcli 的 MEMORIZE 从执行过程中提取结构化事实(key-value),aiops 简化为让 LLM 自由提炼一句事实。更简单,覆盖面更广。
|
||
|
||
#### Step 6: PREDICT(注入下次 Prompt)
|
||
|
||
`GetContextForPrompt(query)` 在下次任务开始时被 `core.Agent.Run` 调用:
|
||
|
||
```go
|
||
evolveCtx := a.evolver.GetContextForPrompt(query)
|
||
systemPrompt := prompt.BuildSystemPrompt(serverInfo, toolDescs, evolveCtx)
|
||
```
|
||
|
||
注入内容会被放入 Prompt Layer 5(详见 [07 - Prompt 构建](07-Prompt构建与记忆注入.md))。
|
||
|
||
## 四层记忆系统
|
||
|
||
aiops 保留 opsxcli 的四层记忆架构:
|
||
|
||
```
|
||
┌──────────────────────────────────────────────────────────────┐
|
||
│ 四层记忆架构 │
|
||
├──────────────────────────────────────────────────────────────┤
|
||
│ │
|
||
│ Layer 1: ExperienceMemory(经验层) │
|
||
│ 任务完成后的经验,按 task_type 分类 │
|
||
│ 存储: data/agentcli/experience.jsonl │
|
||
│ │
|
||
│ Layer 2: EnvironmentMemory(环境层) │
|
||
│ 已知主机列表 │
|
||
│ 存储: data/agentcli/environment.json │
|
||
│ │
|
||
│ Layer 3: FactualMemory(事实层) │
|
||
│ LLM 提炼的持久事实 │
|
||
│ 存储: data/agentcli/factual.jsonl │
|
||
│ │
|
||
│ Layer 4: ProceduralMemory(程序层) │
|
||
│ 程序性知识(接口位,未实现自动 Skill 提炼) │
|
||
│ 存储: data/agentcli/procedural.jsonl │
|
||
│ │
|
||
└──────────────────────────────────────────────────────────────┘
|
||
```
|
||
|
||
### Memories 结构
|
||
|
||
```go
|
||
// backend/pkg/agentcli/evolver/memory.go
|
||
|
||
type Memories struct {
|
||
dir string
|
||
mu sync.Mutex
|
||
|
||
expPath string // experience.jsonl
|
||
facPath string // factual.jsonl
|
||
sklPath string // procedural.jsonl
|
||
envPath string // environment.json
|
||
}
|
||
```
|
||
|
||
### ExperienceEntry / FactEntry / SkillEntry
|
||
|
||
```go
|
||
type ExperienceEntry struct {
|
||
TaskType string `json:"task_type"`
|
||
Query string `json:"query"`
|
||
Hint string `json:"hint"`
|
||
ToolSequence []string `json:"tool_sequence"`
|
||
Success bool `json:"success"`
|
||
Timestamp int64 `json:"timestamp"`
|
||
}
|
||
|
||
type FactEntry struct {
|
||
Fact string `json:"fact"`
|
||
Source string `json:"source"`
|
||
Timestamp int64 `json:"timestamp"`
|
||
}
|
||
|
||
type SkillEntry struct {
|
||
Name string `json:"name"`
|
||
When string `json:"when"`
|
||
Steps []string `json:"steps"`
|
||
Timestamp int64 `json:"timestamp"`
|
||
}
|
||
```
|
||
|
||
> 与 opsxcli 的差异:
|
||
> - opsxcli 的 `Experience` 有 `SuccessRate` / `UsageCount` / `Tags`(用于整合去重),aiops 简化为 `Success` 布尔(剥离整合逻辑)
|
||
> - opsxcli 的 `FactEntry` 是 key-value(`Key` / `Value` / `Category`),aiops 简化为单字段 `Fact`(一句话)
|
||
> - opsxcli 的 `SkillEntry` 有完整的 ID/Version/Triggers/Pitfalls/SuccessRate,aiops 简化为 Name/When/Steps(接口位,未实际使用)
|
||
|
||
### 存储格式
|
||
|
||
#### experience.jsonl(追加写入)
|
||
|
||
```json
|
||
{"task_type":"磁盘空间","query":"检查磁盘空间","hint":"对于磁盘满问题,先检查大日志文件再清理","tool_sequence":["ssh_execute","analyze_output"],"success":true,"timestamp":1748000000}
|
||
```
|
||
|
||
#### environment.json(整体读写)
|
||
|
||
```json
|
||
{
|
||
"hosts": ["192.168.1.10", "192.168.1.11"]
|
||
}
|
||
```
|
||
|
||
#### factual.jsonl(追加写入)
|
||
|
||
```json
|
||
{"fact":"生产 nginx 日志目录是 /var/log/nginx","source":"检查 nginx 启动失败","timestamp":1748000000}
|
||
```
|
||
|
||
### 核心查询方法
|
||
|
||
| 方法 | 说明 |
|
||
|------|------|
|
||
| `AddExperience(e)` | 追加经验 |
|
||
| `FindExperiences(taskType, n)` | 按类型查找,**优先成功**,取最近 n 条 |
|
||
| `AddFact(f)` | 追加事实 |
|
||
| `RelevantFacts(query, n)` | 按 query 关键词匹配事实(双向 Contains) |
|
||
| `AddHost(host)` | 记录已知主机(去重) |
|
||
| `Hosts()` | 已知主机列表 |
|
||
| `CountStats()` | 各层条目数(供审计展示) |
|
||
|
||
**`FindExperiences` 的排序策略**:
|
||
|
||
```go
|
||
// 优先成功经验,按时间取最近 n 条
|
||
successFirst := ... // 过滤 success=true
|
||
others := ... // 过滤 success=false
|
||
out := append(pick(successFirst), pick(others)...)
|
||
```
|
||
|
||
让 LLM 优先看到成功的经验。
|
||
|
||
## 与 Agent 的集成
|
||
|
||
### 初始化与优雅降级
|
||
|
||
在 `agentcli.NewEngine` 中:
|
||
|
||
```go
|
||
ev, err := evolver.NewEvolverEngine(coreCfg.MemoryDir, client)
|
||
if err != nil {
|
||
ev = nil // 降级:无自学习,不影响主流程
|
||
}
|
||
agent := core.NewAgent(client, registry, coreCfg, sc, ev)
|
||
```
|
||
|
||
**降级场景**:
|
||
|
||
- 记忆目录无法创建(权限问题)→ `ev = nil`
|
||
- 此时 Agent 正常运行,只是 Layer 5 为空
|
||
|
||
### 异步进化流程
|
||
|
||
```
|
||
用户查询 → core.Agent.Run() ReAct 循环 → 任务完成
|
||
↓
|
||
triggerEvolve()(异步 goroutine)
|
||
↓
|
||
30s 超时上下文 + panic 恢复
|
||
↓
|
||
EvolverEngine.Evolve()
|
||
↓
|
||
存入 experience.jsonl / factual.jsonl
|
||
↓
|
||
下次 Run() → GetContextForPrompt() → 注入 Layer 5
|
||
```
|
||
|
||
**三层保护**:
|
||
|
||
1. **后台 goroutine**:不阻塞用户,答案立即返回
|
||
2. **30 秒超时**:`context.WithTimeout(ctx, 30*time.Second)`
|
||
3. **panic 恢复**:`defer func() { _ = recover() }()`
|
||
|
||
### 经验注入
|
||
|
||
下次任务开始时,`GetContextForPrompt(query)` 按 `task_type` 取相关经验注入 Layer 5:
|
||
|
||
```
|
||
【历史经验(来自自进化引擎)】
|
||
【磁盘空间 类历史经验】
|
||
- (成功) 对于磁盘满问题,先检查大日志文件再清理
|
||
- (成功) 完成「磁盘空间」类任务时,工具序列 ssh_execute → analyze_output 最终成功
|
||
【已知事实】
|
||
- 生产 nginx 日志目录是 /var/log/nginx
|
||
【已知主机】192.168.1.10, 192.168.1.11
|
||
```
|
||
|
||
## 任务分类系统(11 类)
|
||
|
||
`classifyTask` 把用户查询 + 实际命令分类为 11 类:
|
||
|
||
| 任务类型 | 关键词(部分) |
|
||
|----------|---------------|
|
||
| 磁盘空间 | disk / 空间 / df / du / inode / 磁盘 / 满了 |
|
||
| 网络 | network / 网络 / ping / netstat / ss / 端口 / tcp / dns |
|
||
| 服务管理 | service / 服务 / systemctl / nginx / mysql / redis / restart |
|
||
| 软件安装 | install / 安装 / yum / apt / docker / 部署 |
|
||
| 进程排查 | process / 进程 / ps / kill / cpu / top / 卡死 |
|
||
| 内存排查 | memory / 内存 / mem / free / oom / swap |
|
||
| 日志排查 | log / 日志 / journalctl / tail / grep |
|
||
| 权限问题 | permission / 权限 / chmod / chown / denied / 拒绝 |
|
||
| 性能调优 | performance / 性能 / 负载 / load / 慢 / slow |
|
||
| 配置管理 | config / 配置 / conf / vim / sed |
|
||
| 通用运维 | (兜底) |
|
||
|
||
## 创建方式
|
||
|
||
```go
|
||
// 基础引擎(无 LLM 提炼,纯规则学习)
|
||
engine, _ := evolver.NewEvolverEngine("data/agentcli", nil)
|
||
|
||
// 带 LLM 提炼的引擎(推荐)
|
||
engine, _ := evolver.NewEvolverEngine("data/agentcli", llmClient)
|
||
```
|
||
|
||
> 与 opsxcli 的差异:opsxcli 有 `NewEvolverEngine` 和 `NewEvolverEngineWithLLM` 两个工厂;aiops 合并为一个,通过 `client` 参数是否为 nil 区分。
|
||
|
||
## 统计与监控
|
||
|
||
```go
|
||
func (e *EvolverEngine) GetStats() map[string]interface{} {
|
||
return map[string]interface{}{
|
||
"enabled": true,
|
||
"memory": e.mem.CountStats(), // {experience: N, factual: N, skill: N, hosts: N}
|
||
}
|
||
}
|
||
```
|
||
|
||
由 `Engine.EvolveStats()` 暴露,供审计展示。
|
||
|
||
## 精简决策说明
|
||
|
||
### 剥离了什么
|
||
|
||
| opsxcli 步骤 | aiops 处理 | 原因 |
|
||
|--------------|-----------|------|
|
||
| Step 2.5 REFLECT(LLM 反射分析) | 合并进 Step 3 LEARN | 单次 LLM 调用同时做「分析 + 提炼」更高效 |
|
||
| Step 3 SCORE(效率评分) | 剥离 | 评分用于整合决策,aiops 不做整合 |
|
||
| Step 4 COMPARE(历史对比) | 简化为 `FindExperiences` 查询 | 不需要复杂相似度计算 |
|
||
| Step 7 CONSOLIDATE(经验整合) | 剥离 | JSONL 追加 + 查询时去重足够,不需要主动合并 |
|
||
| Step 9.7 DISTILL(自动 Skill 提炼) | 剥离 | Skill 提炼需要复杂条件判断 + 文件管理,价值/复杂比不高 |
|
||
| Step 10 FEEDBACK(用户反馈消息) | 剥离 | Web 场景下经验学习对用户透明,不需要弹消息 |
|
||
|
||
### 保留了什么
|
||
|
||
- **四层记忆架构** —— 思想完整保留,只是程序层未实际使用
|
||
- **OBSERVE → LEARN → STORE → MEMORIZE → PREDICT 闭环** —— 真正的学习与注入
|
||
- **LLM 提炼 + 规则降级** —— 学习质量有保障
|
||
- **异步非阻塞 + 优雅降级** —— 工程可靠性
|
||
- **按 task_type 分类注入** —— 避免无关污染
|
||
|
||
精简后的 Evolver 仍是「真正的自学习引擎」,而非装饰品。
|
||
|
||
## 设计亮点
|
||
|
||
1. **异步非阻塞**:进化在后台 goroutine,不增加用户等待
|
||
2. **优雅降级**:LLM 失败退化为规则学习,Evolver 初始化失败 Agent 正常运行
|
||
3. **四层记忆**:经验 + 环境 + 事实 + 程序,覆盖从瞬时到持久的认知链路
|
||
4. **会话级反馈**:上次任务的经验立即注入下次 Prompt
|
||
5. **线程安全**:`Memories.mu sync.Mutex` 保护文件读写
|
||
6. **零 DB 依赖**:纯文件存储,与引擎库「零业务依赖」原则一致
|
||
|
||
## 常见陷阱
|
||
|
||
| 陷阱 | 解决方案 |
|
||
|------|----------|
|
||
| 记忆目录权限不足 | `NewEvolverEngine` 返回 error,`NewEngine` 把 ev 设为 nil 降级 |
|
||
| LLM 提炼经验超时 | 30s 超时 + 降级为规则模板 |
|
||
| 经验注入污染上下文 | 按 `task_type` 匹配 + 条数限制(3 条) |
|
||
| 事实记忆累积过多无关项 | LLM prompt 明确「无明显事实回复『无』」+ 不写入 |
|
||
| 并发写入 JSONL 冲突 | `Memories.mu sync.Mutex` 串行化写入 |
|
||
| 程序层未实现却被引用 | 当前版本 `procedural.jsonl` 仅作为接口位,`GetContextForPrompt` 不读它 |
|
||
|
||
## 与 opsxcli 的差异总结
|
||
|
||
| 维度 | opsxcli | aiops |
|
||
|------|---------|-------|
|
||
| 进化步骤 | 13 步 | 6 步 |
|
||
| 代码规模 | ~3300 行 | ~400 行 |
|
||
| 记忆查询 | 复杂相似度 + 整合去重 | 简单 task_type 匹配 + 时间倒序 |
|
||
| 经验字段 | SuccessRate / UsageCount / Tags | Success(布尔) |
|
||
| Skill 提炼 | 自动(Step 9.7) | 未实现(接口位) |
|
||
| 反射分析 | 独立 Step + JSON 结构 | 合并进 LEARN |
|
||
| 用户反馈 | Step 10 弹消息 | 剥离(Web 透明) |
|
||
|
||
**核心思想保留度**:四层记忆 ✓ / 进化闭环 ✓ / 异步降级 ✓ / 经验注入 ✓。精简的是重型分析,不是学习能力本身。
|
||
|
||
> 作者:Logan.Li
|