GPU_GUARD_MONOREPO/docs/superpowers/specs/2026-04-13-skill-evolution-design.md
2026-05-20 21:39:12 +08:00

14 KiB
Raw Permalink Blame History

Skill 自进化系统设计

日期: 2026-04-13 模块: netaclaw/skill-evolution 状态: 设计阶段 依赖: P0 长期记忆系统(共享 background review 模式)

1. 目标

为 NetaClaw Agent 添加 Skill 自进化能力Agent 在对话中积累经验后,后台 review agent 自动提炼可复用的方法论为 Skill或更新已有 Skill。同时提供 skill_manage 工具允许 Agent 在对话中主动创建/编辑 Skill。所有 Agent 创建的 Skill 经过安全扫描后才写入文件系统。

2. 核心决策

决策项 选择 理由
Review 触发方式 迭代计数(默认每 10 轮工具调用) Hermes 验证过的模式,平衡频率和成本
Review Agent 模型 复用主 Agent 同模型 保证提炼质量
安全校验 完整正则扫描(~84 条规则) Agent 创建内容需要严格审查
Skill 存储 文件系统 + DB 元数据 与现有架构一致
Review 执行方式 异步不阻塞主对话 不影响用户体验

3. 系统架构

[Agent 对话循环 (attempt.ts)]
    ↓ toolCallCount 累计 >= N
[chat.ts 检测触发条件]
    ↓ 异步(不阻塞响应)
[spawnSkillReview()] → 独立 runAgent() 调用
    ↓ review agent 拥有 skill_manage + skill_list 工具
[skill_manage 工具]
    ↓ 写入前
[SkillGuard 安全扫描]
    ↓ 通过 → 原子写入
[文件系统 skills/{name}/SKILL.md] + [DB netaclaw_skill]
    ↓ 写入后
[SkillLoader.reloadSkill()] → 热更新内存缓存
    ↓ 下次对话
[system prompt 自动包含新 skill]

关键约束:

  • Review agent 是一次性的spawn → 分析 → 写入 → 结束
  • Review agent 禁用自身的 nudge interval防止递归 review
  • Review agent 最多 8 轮工具调用
  • Skill 写入是原子的:先写临时文件,扫描通过后 rename
  • Review agent 不产生用户可见输出

4. Skill Manager 工具

4.1 skill_manage 工具

// tools/builtin/skill_manage.ts
interface SkillManageParams {
  action: 'create' | 'edit' | 'patch' | 'delete' | 'write_file' | 'remove_file';
  name: string;                    // skill 名称
  content?: string;                // SKILL.md 完整内容create/edit
  old_string?: string;             // patch: 要替换的文本
  new_string?: string;             // patch: 替换后的文本
  replace_all?: boolean;           // patch: 替换所有匹配
  category?: string;               // 可选分类目录
  file_path?: string;              // 支持文件路径write_file/remove_file
  file_content?: string;           // 支持文件内容write_file
}
action 用途 必需参数
create 创建新 skill name, content
edit 完整重写 SKILL.md name, content
patch 局部替换 name, old_string, new_string
delete 删除 skill 目录 name
write_file 写入支持文件 name, file_path, file_content
remove_file 删除支持文件 name, file_path

4.2 skill_list 工具

// 只读工具,返回已有 skill 列表
interface SkillListParams {
  category?: string;  // 可选:按分类过滤
}
// 返回: [{ name, description, category }]

4.3 验证规则

规则 限制
name 最长 64 字符,/^[a-z0-9][a-z0-9._-]*$/
category 单层目录,同 name 命名规则
SKILL.md content 最大 100,000 字符
支持文件 最大 1MB/文件
支持文件目录 references/, templates/, scripts/, assets/
frontmatter 必须包含 namedescription 字段
description 最长 1024 字符
总文件数 每个 skill 最多 50 个文件
总大小 每个 skill 最大 1MB

4.4 原子写入流程

1. 验证参数 → 失败则返回错误
2. 写入临时文件 skills/{name}/.tmp_SKILL.md
3. 调用 SkillGuard.scan() 扫描临时文件
4. 如果 verdict === 'dangerous' → 删除临时文件,返回错误
5. rename 临时文件 → SKILL.md
6. 同步 DB 元数据netaclaw_skill 表)
7. 调用 SkillLoader.reloadSkill(name) 热更新缓存
8. 清除 skill prompt 缓存

5. Skill Guard 安全扫描

5.1 威胁模式分类

参考 Hermes skills_guard.py 的 84 条正则规则,按类别组织:

类别 规则数 severity 示例模式
数据泄露 (exfiltration) 18 critical process\.env, \.ssh/, credentials, DNS exfil
提示注入 (prompt_injection) 16 critical ignore.*instructions, you are now, system prompt
破坏性操作 (destructive) 8 critical rm\s+-rf\s+/, mkfs, dd\s+if=, chmod\s+777
持久化 (persistence) 10 high crontab, authorized_keys, systemd, sudoers
网络 (network) 9 high reverse shells, tunnels, hardcoded IPs
混淆 (obfuscation) 14 high eval\(, Buffer\.from.*base64, hex encoding
代码执行 (execution) 6 high child_process, exec\(, spawn\(
路径穿越 (path_traversal) 5 high \.\.\/, /etc/passwd, /proc/
加密挖矿 (crypto_mining) 2 critical stratum+tcp, xmrig
供应链 (supply_chain) 6 critical curl.*|.*bash, unpinned deps
权限提升 (privilege_escalation) 5 high sudo, setuid, NOPASSWD
凭证暴露 (credential_exposure) 5 critical hardcoded secrets, private keys

5.2 扫描接口

// skill_evolution/guard.ts
interface ScanFinding {
  category: string;
  severity: 'critical' | 'high' | 'medium';
  pattern: string;
  match: string;
  file: string;
  line: number;
}

interface ScanResult {
  verdict: 'safe' | 'caution' | 'dangerous';
  findings: ScanFinding[];
  summary: string;
}

function scanSkill(skillPath: string): ScanResult;

5.3 判定逻辑

findings 中有 critical → verdict = 'dangerous'
findings 中有 high → verdict = 'caution'
无 findings → verdict = 'safe'

Agent 创建的 skill 策略:

  • safe → 允许
  • caution → 允许(记录日志)
  • dangerous → 阻止,回滚,返回错误信息给 agent

5.4 二进制文件拦截

禁止的文件扩展名:.exe, .dll, .so, .dylib, .bin, .dat, .com, .msi, .dmg, .app, .deb, .rpm

6. Background Review 机制

6.1 触发条件

controller/chat.ts 中,runAgent() 返回后:

// 从 Agent 配置读取
const evoConfig = agentEntity?.config?.skillEvolution;
const skillEvolutionEnabled = evoConfig?.enabled ?? false;
const nudgeInterval = evoConfig?.nudgeInterval ?? 10;

// 累计工具调用计数(跨同一会话的多次请求)
const totalCalls = (sessionMeta.toolCallsSinceReview ?? 0) + result.toolCallCount;

const shouldReview = (
  skillEvolutionEnabled &&
  totalCalls >= nudgeInterval &&
  result.toolCallCount > 0
);

if (shouldReview) {
  sessionMeta.toolCallsSinceReview = 0;
  // 异步触发,不阻塞响应
  spawnSkillReview({
    conversationHistory: history,
    parentAgentConfig: agentConfig,
    skillLoader: this.skillLoader,
    linkedSkills: agentEntity?.skills ?? [],
    allowOptimize: evoConfig?.allowOptimizeLinked ?? true,
    allowCreateNew: evoConfig?.allowCreateNew ?? true,
  }).catch(err => logger.warn('Skill review failed:', err));
} else {
  sessionMeta.toolCallsSinceReview = totalCalls;
}

6.2 Review Agent 配置

// skill_evolution/review.ts
interface SkillReviewContext {
  conversationHistory: LLMMessage[];
  parentAgentConfig: AgentConfig;
  skillLoader: SkillLoaderService;
  skillRepo: Repository<NetaClawSkillEntity>;   // DB 同步用
  agentRepo: Repository<NetaClawAgentEntity>;   // 自动关联新 skill 用
  agentName: string;                             // 当前 Agent 名称
  linkedSkills: string[];           // Agent 已勾选的 skill 名称
  allowOptimize: boolean;
  allowCreateNew: boolean;
}

async function spawnSkillReview(ctx: SkillReviewContext): Promise<void> {
  const reviewPrompt = buildSkillReviewPrompt(
    ctx.linkedSkills, ctx.allowOptimize, ctx.allowCreateNew,
  );

  const reviewConfig: AgentConfig = {
    ...ctx.parentAgentConfig,
    name: `${ctx.parentAgentConfig.name}_skill_reviewer`,
    systemPrompt: SKILL_REVIEW_SYSTEM_PROMPT,
    maxToolRounds: 8,
  };

  // skill_manage 工具接收 SkillWriter 实例(非 SkillLoader
  const writer = new SkillWriter(ctx.skillLoader.getSkillsDir(), ctx.skillRepo, ctx.skillLoader);
  const tools = [
    createSkillManageTool(writer, {
      allowedEditSkills: ctx.allowOptimize ? ctx.linkedSkills : [],
      allowCreateNew: ctx.allowCreateNew,
    }),
    createSkillListTool(ctx.skillLoader),
  ];

  await runAgent({
    agentConfig: reviewConfig,
    tools,
    userMessage: reviewPrompt,
    history: ctx.conversationHistory,
  });
}

6.3 Review Prompt

Review prompt 是动态生成的,根据 Agent 的 skillEvolution 配置和已勾选 skill 列表拼接:

function buildSkillReviewPrompt(
  linkedSkills: string[],       // Agent 已勾选的 skill 名称列表
  allowOptimize: boolean,
  allowCreateNew: boolean,
): string {
  let prompt = '回顾上面的对话,考虑是否需要保存或更新 skill。\n\n';
  prompt += '关注:\n';
  prompt += '1. 是否使用了非显而易见的方法来完成任务?\n';
  prompt += '2. 是否经历了试错或因实际发现而改变了方案?\n';
  prompt += '3. 用户是否期望或希望不同的方法或结果?\n\n';

  if (allowOptimize && linkedSkills.length > 0) {
    prompt += `当前 Agent 已关联以下 skill${linkedSkills.join(', ')}\n`;
    prompt += '请优先检查这些已有 skill 是否可以根据本次对话的经验进行优化(用 patch 更新)。\n\n';
  }

  if (allowCreateNew) {
    prompt += '如果发现了全新的可复用方法论且没有相关 skill请创建新 skill。\n\n';
  }

  prompt += '操作指南:\n';
  prompt += '- 先用 skill_list 查看已有 skill避免重复创建\n';
  prompt += '- 优化已有 skill 时优先用 patch局部替换避免 edit 全量重写\n';
  prompt += '- Skill 内容应聚焦于可复用的方法论,而非具体的业务数据\n';
  prompt += '- 如果没有值得保存的内容,直接说"无需保存"并停止\n';
  return prompt;
}

### 6.4 Review System Prompt

你是一个 Skill 提炼专家。你的任务是分析对话历史,提取可复用的方法论并保存为 Skill。

Skill 格式要求:

  • SKILL.md 必须包含 YAML frontmattername + description
  • 正文用 Markdown包含触发条件、工作流程、规则约束
  • name 使用小写字母、数字、连字符(如 nginx-deploy-config
  • description 一句话描述 skill 的用途

你只有 8 轮工具调用机会,请高效行动。


## 7. Agent 配置扩展

### 7.1 AgentEntity.config 扩展

```typescript
interface AgentConfig {
  // ...现有字段
  skillEvolution?: {
    enabled: boolean;
    nudgeInterval?: number;       // 触发 review 的工具调用间隔,默认 10
    allowOptimizeLinked?: boolean; // 是否允许优化已勾选的 skill默认 true
    allowCreateNew?: boolean;     // 是否允许创建全新 skill默认 true
  };
}

7.2 Skill 进化范围

Agent 的 skill 进化有两种模式,均可在 Agent 编辑页面独立开关:

模式 1优化已勾选 SkillallowOptimizeLinked

  • Agent 配置中已关联的 skillagent.skills[] 列表)可以被 review agent 通过 patch/edit 更新
  • 适用场景:电商运营 Agent 反复执行"上架商品"skill在实践中发现更好的标题写法或定价策略自动优化该 skill
  • Review agent 在分析对话时,优先检查已勾选 skill 是否有改进空间

模式 2创建全新 SkillallowCreateNew

  • Review agent 可以发现对话中的新方法论并创建全新 skill
  • 新创建的 skill 自动关联到当前 Agent加入 agent.skills[]
  • 适用场景:投流 Agent 在实践中摸索出一套新的出价策略,提炼为独立 skill

7.3 多 Agent 协作场景考虑

电商运营系统中多个 Agent 各司其职上架、下架、投流、产品管理等skill 进化需要考虑:

  • Skill 共享:一个 Agent 优化的 skill 如果被其他 Agent 也勾选了,优化会自动生效(因为 skill 存在文件系统,所有 Agent 共享同一份)
  • 写入冲突:多个 Agent 同时优化同一个 skill 时用文件锁lockfile保证原子性后写入的 patch 基于最新内容
  • 进化隔离:如果某个 Agent 的场景特殊,不希望它的优化影响其他 Agent可以关闭 allowOptimizeLinked,只允许 allowCreateNew(新 skill 只关联到自己)

7.4 Agent 编辑页面配置

在 Agent 编辑页面新增"Skill 进化"配置区域:

  • 总开关:启用/禁用 Skill 进化
  • 子开关:允许优化已勾选 Skill默认开
  • 子开关:允许创建新 Skill默认开
  • 数字输入Review 触发间隔(高级选项,默认 10

7.5 SkillLoader 扩展

新增方法:

// 热更新单个 skillskill_manage 写入后调用)
async reloadSkill(name: string): Promise<void>;

// 获取 skill 列表摘要(给 review agent 用)
getSkillSummaries(): { name: string; description: string; category?: string }[];

8. 新增文件清单

src/modules/netaclaw/
├── skill_evolution/
│   ├── guard.ts              # SkillGuard 安全扫描(正则模式匹配)
│   ├── guard_patterns.ts     # 威胁模式定义84 条规则)
│   ├── review.ts             # spawnSkillReview() 后台 review 逻辑
│   └── skill_writer.ts       # 原子写入 + 验证 + DB 同步
├── tools/builtin/
│   ├── skill_manage.ts       # skill_manage 工具
│   └── skill_list.ts         # skill_list 工具

9. 修改文件清单

文件 修改内容
controller/chat.ts runAgent 返回后检测触发条件,异步调用 spawnSkillReview通过 sessionRepo 直接更新 metadata
service/skill_loader.ts 新增 reloadSkill()、getSkillSummaries()、getSkillsDir() 方法

10. 依赖

无新增外部依赖。安全扫描用纯正则实现skill 文件读写用 Node.js fs 模块。