Skill生命周期管理与触发条件体系
文档归属:Hermes Agent自进化智能体高阶实战 / 组织结构深度分析节点 文档版本:v1.0.0 文档状态:正式发布 编写时间:2026-07-07 | 编写者:风云再起
目录
- 第一章 Skill系统总览与架构设计
- 第二章 Skill定义与结构规范
- 第三章 四种触发条件深度机制
- 第四章 Skill生成全流程
- 第五章 三级验证体系
- 第六章 Skill生命周期状态机
- 第七章 Skill质量评估与淘汰机制
- 第八章 Skill与记忆系统交互及竞品对比
第一章 Skill系统总览与架构设计
1.1 概述
Hermes Agent的Skill(技能)系统是其自进化能力的核心载体。与传统的插件系统或工具集成不同,Skill系统具备自动发现、自动生成、自动验证、自动注册的完整闭环能力,使得Agent能够在与用户的交互过程中持续积累可复用的操作模式,逐步从"通用助手"进化为"个性化专家"。
Skill系统的设计哲学可以概括为三个核心原则:
1.2 Skill系统的核心价值
| 技能获取方式 | 无 | 用户手动编写 | 自动发现 + 手动创建 |
| 技能积累速度 | 不支持 | 慢(依赖用户主动性) | 快(自动积累) |
| 技能质量保证 | N/A | 依赖用户水平 | 三级验证 + 质量评估 |
| 技能淘汰机制 | N/A | 无 | 自动淘汰 + 手动删除 |
| 技能复用率 | N/A | 低(缺乏索引) | 高(按需加载 + 语义索引) |
| 个性化程度 | 低 | 中 | 高(适应用户行为模式) |
| 维护成本 | N/A | 高(全手动) | 低(自动化管理) |
1.3 系统架构总览
┌─────────────────────────────────────────────────────────────────────────────┐
│ Hermes Agent Skill System Architecture │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ 频次触发引擎 │ │ 自修复触发引擎 │ │ 用户纠正触发 │ │
│ │ FrequencyTrig │ │ SelfHealTrig │ │ UserCorrectTrig│ │
│ └────────┬────────┘ └────────┬────────┘ └────────┬────────┘ │
│ │ │ │ │
│ └────────────┬───────┴────────────┬───────┘ │
│ │ │ │
│ ┌────▼────┐ ┌────▼────┐ │
│ │ 手动创建 │ │ 触发调度 │ │
│ │ Manual │ │ Trigger │ │
│ │ Create │ │ Router │ │
│ └────┬────┘ └────┬────┘ │
│ │ │ │
│ └───────┬───────────┘ │
│ │ │
│ ┌───────▼───────┐ │
│ │ Skill生成引擎 │ │
│ │ SkillGenerator │ │
│ └───────┬───────┘ │
│ │ │
│ ┌──────────────┼──────────────┐ │
│ │ │ │ │
│ ┌──────▼──────┐ ┌────▼────┐ ┌──────▼──────┐ │
│ │ 语法验证器 │ │行为验证 │ │ 安全验证器 │ │
│ │ SyntaxValid │ │Behavior │ │SecurityValid│ │
│ └──────┬──────┘ └────┬────┘ └──────┬──────┘ │
│ └─────────────┼─────────────┘ │
│ ┌──────▼──────┐ │
│ │ Skill注册器 │ │
│ │ SkillRegistr│ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ Skill存储层 │ │
│ │ L4 Skill Mem│ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │
│ │ 按需加载器 │ │
│ │ OnDemandLoad│ │
│ └─────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 生命周期管理器 LifecycleManager │ │
│ │ 草稿 → 验证中 → 激活 → 休眠 → 淘汰 → 归档 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ 质量评估器 QualityAssessor │ │
│ │ 调用成功率 | 用户满意度 | 执行效率 | 复用频率 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
1.4 Skill系统的设计目标
1.4.1 零配置技能积累
用户无需任何额外操作,Agent在日常交互中自动识别可复用的操作模式,并将其沉淀为Skill。这一过程对用户完全透明,只有在Skill被成功创建并激活时,系统才会以轻量提示告知用户。
1.4.2 安全的技能进化
所有自动生成的Skill在激活前必须通过三级验证:
- 语法验证:确保SKILL.md格式正确、参数定义合法
- 行为验证:在沙箱环境中执行,验证行为符合预期
- 安全验证:检查权限声明、资源访问范围、潜在风险
1.4.3 自然的技能淘汰
Skill不是永久存在的。当一个Skill长期不被调用(低频淘汰)、与另一个Skill功能重叠(冲突合并)、或被更高版本的Skill替代(版本升级)时,系统会自动将其淘汰或归档,保持技能库的精简和高效。
1.4.4 高效的技能检索
Skill存储在L4技能记忆层,采用"索引 + 按需加载"的架构。Agent在执行任务时,通过语义检索从索引中找到匹配的Skill,然后按需加载完整的Skill定义,避免一次性加载所有Skill导致的上下文膨胀。
1.5 Skill系统在Hermes Agent架构中的定位
┌─────────────────────────────────────────────────────────────────────────────┐
│ Hermes Agent 五层记忆架构 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ L1 – 工作记忆层 (Working Memory) │ │
│ │ 当前对话上下文、临时变量、活跃的推理链 │ │
│ │ 生命周期: 单次对话 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ L2 – 短期记忆层 (Short-term Memory) │ │
│ │ 近期对话历史、临时决策记录、待办事项 │ │
│ │ 生命周期: 数小时 ~ 数天 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ L3 – 长期记忆层 (Long-term Memory) │ │
│ │ 用户画像、长期偏好、历史决策、项目知识库 │ │
│ │ 生命周期: 永久(除非用户删除) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ L4 – 技能记忆层 (Skill Memory) ★ 本文档焦点 │ │
│ │ Skill定义、执行脚本、参数模式、验证结果、质量指标 │ │
│ │ 生命周期: 永久(除非被淘汰/归档/删除) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ L5 – 元认知层 (Meta-cognitive Memory) │ │
│ │ 跨Skill的策略知识、Skill间组合规则、进化策略 │ │
│ │ 生命周期: 永久 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
Skill系统位于L4技能记忆层,它向上为L1工作记忆层提供按需加载的Skill定义,向下从L2/L3记忆层中提取可沉淀的操作模式。L5元认知层则负责管理Skill之间的组合策略和进化方向。
1.6 核心概念定义
| Skill | 一段可复用的操作模式,包含SKILL.md定义、执行脚本和元数据 | format_json(JSON格式化技能) |
| 触发条件 | 系统判定某个操作模式应该被沉淀为Skill的条件 | 频次触发(5次同类操作) |
| 生命周期状态 | Skill在其存在周期中所处的阶段 | 草稿、验证中、激活、休眠、淘汰、归档 |
| 质量评分 | 对Skill质量的综合量化评估 | 0.85(基于成功率、满意度等) |
| Skill索引 | 存储在L4层的轻量级Skill元数据,用于快速检索 | {name, desc, tags, path, status} |
| 按需加载 | Agent在需要时才加载完整Skill定义的机制 | 通过skill_load加载SKILL.md |
| 淘汰机制 | 将不再有用的Skill从激活状态移除的流程 | 低频淘汰(30天未调用) |
1.7 Skill系统的运行时上下文
Skill系统在Hermes Agent运行时中的上下文关系如下:
用户输入 → 意图理解 → [Skill索引检索] → 命中Skill?
│ │
否 是
│ │
正常推理执行 加载Skill定义
│ │
│ 按Skill执行
│ │
└───────┬────────┘
│
执行结果反馈
│
┌───────────────┼───────────────┐
│ │ │
触发检测引擎 质量评估器 生命周期管理器
(检测是否满足 (更新质量指标) (检查状态迁移)
触发条件)
│
满足触发条件?
│
是 → 生成Skill
否 → 继续监控
1.8 本章小结
本章从宏观视角介绍了Hermes Agent Skill系统的设计哲学、核心价值、系统架构和在五层记忆模型中的定位。Skill系统的核心创新在于将"技能获取"从纯手动模式提升为"自动发现 + 手动创建"的混合模式,并通过完整的生命周期管理和三级验证体系确保技能的安全性和质量。后续章节将逐步深入每个子系统的实现细节。
第二章 Skill定义与结构规范
2.1 SKILL.md格式规范
每个Skill的核心定义文件为SKILL.md,采用Markdown格式编写,结合YAML前置元数据块和Markdown正文。这种设计使得Skill定义既具有机器可解析的结构化元数据,又具有人类可读的说明文档。
2.1.1 SKILL.md整体结构
—
# ═══════════════════════════════════════════════════════════
# YAML Front Matter – 元数据块
# ═══════════════════════════════════════════════════════════
name: format_json # Skill唯一标识符
display_name: JSON格式化 # 用户可见的显示名称
version: 1.2.0 # 语义化版本号
author: auto-generated # 作者:auto-generated / 用户名
created_at: 2026-06-15T10:30:00+08:00 # 创建时间
updated_at: 2026-07-01T14:22:00+08:00 # 最后更新时间
status: active # 生命周期状态
trigger_source: frequency # 触发来源
trigger_count: 8 # 触发次数统计
quality_score: 0.92 # 质量评分(0.0~1.0)
# ═══════════════════════════════════════════════════════════
# 工具定义
# ═══════════════════════════════════════════════════════════
tools:
– name: format_json
description: 将输入的JSON字符串格式化为带缩进的可读形式
parameters:
– name: input
type: string
required: true
description: 需要格式化的JSON字符串
– name: indent
type: integer
required: false
default: 2
description: 缩进空格数
– name: sort_keys
type: boolean
required: false
default: false
description: 是否按键名排序
returns:
type: string
description: 格式化后的JSON字符串
# ═══════════════════════════════════════════════════════════
# 权限声明
# ═══════════════════════════════════════════════════════════
permissions:
filesystem:
read: []
write: []
network:
allowed: false
shell:
allowed: false
memory:
read_layers: [L1, L2]
write_layers: [L1]
# ═══════════════════════════════════════════════════════════
# 约束声明
# ═══════════════════════════════════════════════════════════
constraints:
max_execution_time: 5000
max_memory_usage: 50
rate_limit: 100
retry_policy:
max_retries: 3
backoff: exponential
initial_delay: 1000
# ═══════════════════════════════════════════════════════════
# 依赖声明
# ═══════════════════════════════════════════════════════════
dependencies:
skills: []
packages:
– python: json
min_agent_version: 2.0.0
# ═══════════════════════════════════════════════════════════
# 标签与分类
# ═══════════════════════════════════════════════════════════
tags: [json, formatting, data-processing]
category: data-manipulation
priority: normal
—
# JSON格式化技能
## 功能描述
将输入的JSON字符串格式化为带缩进的可读形式。
## 使用场景
– 用户粘贴一段压缩的JSON需要美化
– API响应数据需要格式化查看
## 执行逻辑
1. 解析输入字符串为JSON对象
2. 如果解析失败,返回错误信息
3. 按指定参数重新序列化JSON
4. 返回格式化后的字符串
## 错误处理
– 输入不是有效JSON → 返回解析错误及位置信息
– 输入为空 → 返回提示信息
2.1.2 YAML前置元数据块规范
基础信息字段
| name | string | 是 | Skill唯一标识符,仅限小写字母、数字、下划线,最长64字符 |
| display_name | string | 否 | 用户可见的显示名称,默认与name相同 |
| version | string | 是 | 语义化版本号,格式为MAJOR.MINOR.PATCH |
| author | string | 是 | 作者标识,auto-generated表示自动生成 |
| created_at | datetime | 是 | 创建时间,RFC3339格式 |
| updated_at | datetime | 是 | 最后更新时间,RFC3339格式 |
| status | enum | 是 | 生命周期状态:draft/validating/active/dormant/deprecated/archived |
| trigger_source | enum | 是 | 触发来源:frequency/self_heal/user_correction/manual |
| trigger_count | integer | 否 | 触发次数统计,自动生成时填写 |
| quality_score | float | 否 | 质量评分,0.0~1.0,初始为null |
工具定义字段(tools)
tools:
– name: tool_name # 工具名称,全局唯一
description: 工具描述 # 简洁的功能描述
parameters: # 参数列表
– name: param_name # 参数名
type: string # 类型: string/integer/float/boolean/array/object
required: true # 是否必填
default: null # 默认值(可选)
description: 参数描述 # 参数说明
enum: [a, b, c] # 枚举值(可选)
pattern: "^[a-z]+$" # 正则约束(可选)
min: 0 # 最小值(数值类型可选)
max: 100 # 最大值(数值类型可选)
returns: # 返回值定义
type: string
description: 返回值描述
errors: # 可能的错误
– code: PARSE_ERROR
message: JSON解析失败
http_status: 400
权限声明字段(permissions)
权限声明采用白名单模式,未明确授权的资源均不可访问:
permissions:
filesystem:
read:
– "/app/data/**"
write:
– "/app/data/output/**"
delete: []
network:
allowed: true
domains:
– "api.example.com"
– "cdn.example.com"
shell:
allowed: false
commands: []
memory:
read_layers: [L1, L2, L3]
write_layers: [L1, L2]
env_vars:
read: ["HOME", "PATH"]
write: []
2.2 元数据模型详解
2.2.1 元数据模型ER图
┌─────────────────────────────────────────────────────────────────────────┐
│ Skill 元数据模型 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌────────────────┐ │
│ │ SkillMetadata │ │ ToolDefinition │ │ ParameterDef │ │
│ ├──────────────────┤ ├──────────────────┤ ├────────────────┤ │
│ │ – name: str │1───n│ – name: str │1───n│ – name: str │ │
│ │ – display_name │ │ – description │ │ – type: enum │ │
│ │ – version: str │ │ – parameters[] │─────│ – required │ │
│ │ – author: str │ │ – returns │ │ – default │ │
│ │ – created_at │ │ – errors[] │ │ – description │ │
│ │ – updated_at │ └──────────────────┘ │ – enum[] │ │
│ │ – status: enum │ │ – pattern │ │
│ │ – trigger_source │ ┌──────────────────┐ │ – min/max │ │
│ │ – trigger_count │1───1│ PermissionSet │ └────────────────┘ │
│ │ – quality_score │ ├──────────────────┤ │
│ │ – tags[] │ │ – filesystem │ ┌────────────────┐ │
│ │ – category │ │ – network │ │ ConstraintSet │ │
│ │ – priority │ │ – shell │ ├────────────────┤ │
│ └──────────────────┘ │ – memory │ │ – max_exec_time│ │
│ │ – env_vars │ │ – max_memory │ │
│ ┌──────────────────┐ └──────────────────┘ │ – rate_limit │ │
│ │ DependencySet │ │ – retry_policy │ │
│ ├──────────────────┤ ┌──────────────────┐ └────────────────┘ │
│ │ – skills[] │ │ QualityMetrics │ │
│ │ – packages[] │1───1│ ├──────────────────┤ │
│ │ – min_agent_ver │ │ – success_rate │ │
│ └──────────────────┘ │ – satisfaction │ │
│ │ – efficiency │ │
│ │ – reuse_freq │ │
│ │ – total_calls │ │
│ │ – last_called │ │
│ └──────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
2.2.2 元数据序列化格式
元数据在L4技能记忆层中以JSON格式存储,便于检索和加载:
{
"skill_id": "format_json_v1.2.0",
"name": "format_json",
"display_name": "JSON格式化",
"version": "1.2.0",
"author": "auto-generated",
"created_at": "2026-06-15T10:30:00+08:00",
"updated_at": "2026-07-01T14:22:00+08:00",
"status": "active",
"trigger_source": "frequency",
"trigger_count": 8,
"quality_score": 0.92,
"quality_metrics": {
"success_rate": 0.95,
"satisfaction": 0.88,
"efficiency": 0.96,
"reuse_freq": 0.90,
"total_calls": 42,
"last_called": "2026-07-05T09:15:00+08:00"
},
"tools": [
{
"name": "format_json",
"description": "将输入的JSON字符串格式化为带缩进的可读形式",
"parameters": [
{
"name": "input",
"type": "string",
"required": true,
"description": "需要格式化的JSON字符串"
},
{
"name": "indent",
"type": "integer",
"required": false,
"default": 2,
"description": "缩进空格数",
"min": 0,
"max": 8
}
],
"returns": {
"type": "string",
"description": "格式化后的JSON字符串"
}
}
],
"permissions": {
"filesystem": { "read": [], "write": [] },
"network": { "allowed": false },
"shell": { "allowed": false },
"memory": {
"read_layers": ["L1", "L2"],
"write_layers": ["L1"]
}
},
"constraints": {
"max_execution_time": 5000,
"max_memory_usage": 50,
"rate_limit": 100
},
"dependencies": {
"skills": [],
"packages": [{"python": "json"}],
"min_agent_version": "2.0.0"
},
"tags": ["json", "formatting", "data-processing"],
"category": "data-manipulation",
"priority": "normal",
"skill_file_path": "/app/data/skills/format_json/SKILL.md",
"script_file_path": "/app/data/skills/format_json/scripts/format_json.py"
}
2.3 工具定义规范
2.3.1 参数类型系统
| string | 字符串类型 | "hello" | {"type": "string"} |
| integer | 整数类型 | 42 | {"type": "integer"} |
| float | 浮点数类型 | 3.14 | {"type": "number"} |
| boolean | 布尔类型 | true | {"type": "boolean"} |
| array | 数组类型 | [1, 2, 3] | {"type": "array"} |
| object | 对象类型 | {"a": 1} | {"type": "object"} |
| file | 文件路径类型 | "/path/to/file" | {"type": "string", "format": "file-path"} |
| enum | 枚举类型 | "option_a" | {"enum": […]} |
2.3.2 参数约束规范
parameters:
– name: output_format
type: enum
required: true
enum: [json, yaml, xml, csv]
default: json
description: 输出格式
– name: max_results
type: integer
required: false
min: 1
max: 1000
default: 50
description: 最大返回结果数
– name: file_pattern
type: string
required: true
pattern: "^[a-zA-Z0-9_\\\\-/.]+$"
min_length: 1
max_length: 255
description: 文件匹配模式
– name: options
type: object
required: false
properties:
verbose:
type: boolean
default: false
timeout:
type: integer
default: 30
description: 高级选项
2.3.3 返回值规范
returns:
type: object
description: 格式化结果
properties:
success:
type: boolean
description: 是否成功
formatted_text:
type: string
description: 格式化后的文本
error:
type: string
description: 错误信息(success为false时存在)
warnings:
type: array
items:
type: string
description: 警告信息列表
2.4 权限声明详解
2.4.1 权限层级模型
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 权限层级模型 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ Level 0: 无权限(默认) │
│ ├── 无文件系统访问 │
│ ├── 无网络访问 │
│ ├── 无Shell执行 │
│ └── 仅可访问L1工作记忆 │
│ │
│ Level 1: 只读权限 │
│ ├── 文件系统:指定路径只读 │
│ ├── 网络:指定域名GET请求 │
│ ├── Shell:禁止 │
│ └── 记忆:L1读写 + L2/L3只读 │
│ │
│ Level 2: 标准权限 │
│ ├── 文件系统:指定路径读写 │
│ ├── 网络:指定域名全方法 │
│ ├── Shell:指定命令列表 │
│ └── 记忆:L1/L2读写 + L3只读 │
│ │
│ Level 3: 高权限(需用户确认) │
│ ├── 文件系统:全路径读写 │
│ ├── 网络:无限制 │
│ ├── Shell:全命令执行 │
│ └── 记忆:L1/L2/L3读写 + L4只读 │
│ │
│ Level 4: 系统权限(需用户确认 + 管理员审批) │
│ ├── 所有Level 3权限 │
│ ├── 记忆:L1~L5全层读写 │
│ ├── Skill管理:可创建/修改/删除其他Skill │
│ └── 系统配置:可修改Agent配置 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
2.4.2 权限自动推断
当Skill由系统自动生成时,权限声明会根据触发场景自动推断:
# 权限自动推断逻辑(伪代码)
def infer_permissions(trigger_source: str, operation_history: list) –> PermissionSet:
"""根据触发来源和操作历史推断所需权限"""
permissions = PermissionSet()
# 分析操作历史中实际使用的资源
used_paths_read = set()
used_paths_write = set()
used_network = False
used_shell = False
used_memory_layers = set()
for op in operation_history:
if op.type == "file_read":
used_paths_read.add(op.path)
elif op.type == "file_write":
used_paths_write.add(op.path)
elif op.type == "network_request":
used_network = True
elif op.type == "shell_exec":
used_shell = True
elif op.type == "memory_access":
used_memory_layers.add(op.layer)
# 最小权限原则:仅授予实际使用过的权限
permissions.filesystem.read = minimize_paths(used_paths_read)
permissions.filesystem.write = minimize_paths(used_paths_write)
permissions.network.allowed = used_network
permissions.shell.allowed = used_shell
permissions.memory.read_layers = list(used_memory_layers)
permissions.memory.write_layers = ["L1"]
# 频次触发的Skill默认降低权限级别
if trigger_source == "frequency":
permissions = apply_security_downgrade(permissions, max_level=2)
elif trigger_source == "self_heal":
permissions = apply_security_downgrade(permissions, max_level=2)
elif trigger_source == "user_correction":
permissions = apply_security_downgrade(permissions, max_level=1)
elif trigger_source == "manual":
pass # 使用用户显式声明的权限
return permissions
def minimize_paths(paths: set) –> list:
"""将具体路径归纳为通配模式,减少权限粒度"""
minimized = []
for path in paths:
parts = path.split("/")
if len(parts) > 4:
minimized.append("/".join(parts[:4]) + "/**")
else:
minimized.append(path)
return list(set(minimized))
2.5 Skill目录结构
每个Skill在文件系统中以独立目录的形式存在:
/app/data/skills/
├── format_json/ # Skill名称作为目录名
│ ├── SKILL.md # Skill定义文件(必需)
│ ├── metadata.json # 序列化的元数据(自动生成)
│ ├── scripts/ # 执行脚本目录
│ │ ├── format_json.py # 主执行脚本
│ │ └── utils.py # 辅助脚本
│ ├── references/ # 参考资料目录
│ │ ├── examples.md # 使用示例
│ │ └── edge_cases.md # 边界情况说明
│ ├── tests/ # 测试用例目录
│ │ ├── test_basic.py # 基础测试
│ │ ├── test_edge.py # 边界测试
│ │ └── test_security.py # 安全测试
│ ├── validation/ # 验证结果目录
│ │ ├── syntax_report.json # 语法验证报告
│ │ ├── behavior_report.json # 行为验证报告
│ │ └── security_report.json # 安全验证报告
│ └── quality/ # 质量指标目录
│ ├── metrics.json # 质量指标数据
│ └── history.json # 调用历史记录
│
├── api_error_handler/ # 另一个Skill
│ ├── SKILL.md
│ ├── scripts/
│ │ └── retry_handler.py
│ └── …
│
└── daily_report_generator/ # 手动创建的Skill
├── SKILL.md
├── scripts/
│ ├── generate_report.py
│ └── send_email.py
└── …
2.6 Skill索引文件
L4技能记忆层维护一个全局Skill索引文件,用于快速检索:
{
"index_version": "1.0.0",
"last_updated": "2026-07-05T18:00:00+08:00",
"total_skills": 27,
"active_skills": 22,
"dormant_skills": 3,
"deprecated_skills": 2,
"skills": [
{
"skill_id": "format_json_v1.2.0",
"name": "format_json",
"display_name": "JSON格式化",
"version": "1.2.0",
"status": "active",
"category": "data-manipulation",
"tags": ["json", "formatting", "data-processing"],
"trigger_source": "frequency",
"quality_score": 0.92,
"last_called": "2026-07-05T09:15:00+08:00",
"call_count_30d": 18,
"skill_path": "/app/data/skills/format_json/SKILL.md",
"semantic_embedding": [0.123, –0.456, 0.789],
"description_summary": "将JSON字符串格式化为带缩进的可读形式"
},
{
"skill_id": "api_error_handler_v1.0.3",
"name": "api_error_handler",
"display_name": "API错误处理器",
"version": "1.0.3",
"status": "active",
"category": "error-handling",
"tags": ["api", "error", "retry", "self-heal"],
"trigger_source": "self_heal",
"quality_score": 0.87,
"last_called": "2026-07-04T16:30:00+08:00",
"call_count_30d": 7,
"skill_path": "/app/data/skills/api_error_handler/SKILL.md",
"semantic_embedding": [0.234, –0.567, 0.890],
"description_summary": "处理API调用失败,自动重试和错误恢复"
}
]
}
2.7 本章小结
本章详细定义了Skill的结构规范,包括SKILL.md的完整格式、YAML前置元数据块的所有字段、工具定义的参数类型系统、权限声明的层级模型以及Skill在文件系统中的目录结构。这些规范构成了Skill系统的基础,后续章节中的触发机制、生成流程、验证体系和生命周期管理都建立在这些结构定义之上。
第三章 四种触发条件深度机制
3.1 触发条件体系总览
Hermes Agent的Skill系统定义了四种触发条件,每种触发条件对应一种不同的Skill发现模式。这四种触发条件共同构成了一个完整的"技能发现矩阵",覆盖了从被动观察到主动创建的全部场景。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 触发条件决策树 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─ 用户主动编写Skill? │
│ │ │ │
│ │ 是 → [手动创建触发] │
│ │ │ │
│ │ 否 ↓ │
│ │ │
│ ├─ Agent出错后自行修复成功? │
│ │ │ │
│ │ 是 → [自修复触发] │
│ │ │ │
│ │ 否 ↓ │
│ │ │
│ ├─ 用户明确纠正Agent行为? │
│ │ │ │
│ │ 是 → [用户纠正触发] │
│ │ │ │
│ │ 否 ↓ │
│ │ │
│ ├─ 同类操作被调用≥5次? │
│ │ │ │
│ │ 是 → [频次触发] │
│ │ │ │
│ │ 否 → 继续监控,不触发 │
│ │ │
│ └──────────────────────────────── │
│ │
│ 触发优先级: 手动创建 > 自修复 > 用户纠正 > 频次触发 │
│ (高优先级触发条件先检查,满足则不再检查低优先级) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
3.2 四种触发条件对比
| 触发主体 | 系统(自动) | Agent(自动) | 用户(被动) | 用户(主动) |
| 触发条件 | 同类操作≥5次 | 出错→自修复成功 | 用户纠正Agent行为 | 用户主动编写 |
| 发现方式 | 模式匹配 | 错误-恢复链路 | 语义分析 | 显式声明 |
| 自动化程度 | 完全自动 | 完全自动 | 半自动 | 完全手动 |
| 典型场景 | 反复格式化JSON | API失败重试成功 | “用中文回复” | “每日报告生成” |
| 生成速度 | 中(需积累5次) | 快(单次即触发) | 快(单次即触发) | 慢(用户编写时间) |
| 初始质量 | 中(基于历史模式) | 高(已验证可用) | 中(基于纠正内容) | 取决于用户 |
| 权限级别 | Level 1-2 | Level 2 | Level 1 | 用户声明 |
| 验证严格度 | 标准 | 放宽(已验证) | 标准 | 严格 |
| 用户感知 | 轻量提示 | 轻量提示 | 轻量提示 | 用户主导 |
| 可覆盖性 | 可被高优先级覆盖 | 可被高优先级覆盖 | 可被高优先级覆盖 | 不可覆盖 |
| 淘汰阈值 | 30天未调用 | 60天未调用 | 45天未调用 | 用户手动 |
3.3 频次触发深度机制
3.3.1 频次检测算法
频次触发是四种触发条件中最复杂的一种,其核心挑战在于"同类操作"的判定。系统需要在不干扰正常交互的前提下,实时检测操作模式的重复性。
操作模式抽取
每次Agent执行操作时,系统会抽取一个"操作模式签名"(Operation Pattern Signature),用于后续的相似性比较:
class OperationPatternExtractor:
"""操作模式抽取器"""
def extract_pattern(self, operation: Operation) –> OperationPattern:
"""
从一次操作中抽取操作模式
操作模式包含以下维度:
1. 意图类别 – 操作的目标类型
2. 输入类型 – 输入数据的类型特征
3. 输出类型 – 输出数据的类型特征
4. 工具链 – 使用的工具序列
5. 参数模式 – 关键参数的取值模式
6. 上下文标签 – 执行上下文的语义标签
"""
pattern = OperationPattern()
# 1. 意图类别抽取
pattern.intent = self._classify_intent(operation.description)
# 例如: "帮我把这段JSON格式化" → intent = "format_data"
# 2. 输入类型特征
pattern.input_types = self._extract_type_features(operation.inputs)
# 例如: 输入是字符串, 包含{}和:, 判定为JSON格式
# 3. 输出类型特征
pattern.output_types = self._extract_type_features(operation.outputs)
# 例如: 输出是字符串, 带缩进, 判定为格式化文本
# 4. 工具链序列
pattern.tool_chain = [t.name for t in operation.tools_used]
# 例如: ["python_executor"]
# 5. 参数模式
pattern.param_patterns = self._extract_param_patterns(operation.parameters)
# 例如: {indent: 2, sort_keys: false}
# 6. 上下文语义标签
pattern.context_tags = self._extract_context_tags(operation.context)
# 例如: ["data_processing", "formatting"]
# 生成模式签名
pattern.signature = self._generate_signature(pattern)
return pattern
def _classify_intent(self, description: str) –> str:
"""使用语义模型分类操作意图"""
intent_categories = [
"format_data", # 数据格式化
"parse_data", # 数据解析
"transform_data", # 数据转换
"validate_data", # 数据验证
"search_information", # 信息搜索
"generate_content", # 内容生成
"send_communication", # 发送通信
"file_operation", # 文件操作
"api_call", # API调用
"error_handling", # 错误处理
"data_analysis", # 数据分析
"report_generation", # 报告生成
"code_execution", # 代码执行
"workflow_automation", # 工作流自动化
"other" # 其他
]
# 使用嵌入向量相似度进行分类
...
def _generate_signature(self, pattern: OperationPattern) –> str:
"""生成操作模式的唯一签名"""
signature_input = f"{pattern.intent}|{pattern.input_types}|" \\
f"{pattern.output_types}|{pattern.tool_chain}|" \\
f"{pattern.param_patterns}"
return hashlib.md5(signature_input.encode()).hexdigest()
频次检测引擎
class FrequencyTriggerEngine:
"""频次触发引擎"""
FREQUENCY_THRESHOLD = 5 # 频次触发阈值
TIME_WINDOW = 7 * 24 * 3600 # 时间窗口:7天(秒)
MIN_TIME_INTERVAL = 3600 # 最小时间间隔:1小时
def __init__(self):
self.pattern_store = PatternStore()
self.skill_registry = SkillRegistry()
def check_trigger(self, current_operation: Operation) –> TriggerResult:
"""
检查当前操作是否满足频次触发条件
"""
# 1. 抽取当前操作的模式
current_pattern = self.pattern_extractor.extract_pattern(current_operation)
# 2. 检查是否已有覆盖此模式的Skill
existing_skill = self.skill_registry.find_by_pattern(current_pattern)
if existing_skill:
self.skill_registry.increment_call_count(existing_skill.skill_id)
return TriggerResult(triggered=False, reason="existing_skill_covers")
# 3. 在时间窗口内查找相似模式
similar_patterns = self.pattern_store.find_similar(
pattern=current_pattern,
time_window=self.TIME_WINDOW,
similarity_threshold=0.85
)
# 4. 过滤掉时间间隔过短的模式
filtered_patterns = self._filter_by_time_interval(similar_patterns)
# 5. 检查是否达到频次阈值
if len(filtered_patterns) >= self.FREQUENCY_THRESHOLD:
return TriggerResult(
triggered=True,
trigger_source="frequency",
pattern=current_pattern,
similar_patterns=filtered_patterns,
trigger_count=len(filtered_patterns)
)
else:
self.pattern_store.store(current_pattern)
return TriggerResult(
triggered=False,
reason="below_threshold",
current_count=len(filtered_patterns),
threshold=self.FREQUENCY_THRESHOLD
)
def _filter_by_time_interval(self, patterns: list) –> list:
"""过滤时间间隔过短的模式"""
if not patterns:
return []
filtered = [patterns[0]]
for p in patterns[1:]:
time_diff = (p.timestamp – filtered[–1].timestamp).total_seconds()
if time_diff >= self.MIN_TIME_INTERVAL:
filtered.append(p)
return filtered
3.3.2 频次触发的具体示例
时间线示例:频次触发 format_json Skill
Day 1 10:30 用户: "帮我把这段JSON格式化" → Agent执行格式化操作
模式签名: format_data|json_string|formatted_string|[python]|
频次计数: 1/5 → 未触发
Day 2 14:20 用户: "这个JSON太乱了,帮我整理一下" → Agent执行格式化操作
模式签名: format_data|json_string|formatted_string|[python]|
频次计数: 2/5 → 未触发
Day 3 09:15 用户: "格式化这个配置文件" → Agent执行格式化操作
模式签名: format_data|json_string|formatted_string|[python]|
频次计数: 3/5 → 未触发
Day 4 16:45 用户: "帮我美化这段JSON数据" → Agent执行格式化操作
模式签名: format_data|json_string|formatted_string|[python]|
频次计数: 4/5 → 未触发
Day 5 11:00 用户: "这段JSON能不能格式化一下" → Agent执行格式化操作
模式签名: format_data|json_string|formatted_string|[python]|
频次计数: 5/5 → ★ 频次触发!
→ Skill生成引擎启动
→ 从5次操作中提炼通用模式
→ 生成 format_json Skill
→ 进入验证流程
3.3.3 模式相似度计算
class PatternSimilarityCalculator:
"""操作模式相似度计算器"""
def calculate(self, pattern_a: OperationPattern,
pattern_b: OperationPattern) –> float:
"""
计算两个操作模式之间的相似度
返回0.0~1.0的相似度分数
"""
weights = {
"intent": 0.30,
"input_types": 0.20,
"output_types": 0.15,
"tool_chain": 0.15,
"param_patterns": 0.10,
"context_tags": 0.10
}
scores = {}
scores["intent"] = self._intent_similarity(
pattern_a.intent, pattern_b.intent
)
scores["input_types"] = self._type_similarity(
pattern_a.input_types, pattern_b.input_types
)
scores["output_types"] = self._type_similarity(
pattern_a.output_types, pattern_b.output_types
)
scores["tool_chain"] = self._jaccard_similarity(
set(pattern_a.tool_chain), set(pattern_b.tool_chain)
)
scores["param_patterns"] = self._param_similarity(
pattern_a.param_patterns, pattern_b.param_patterns
)
scores["context_tags"] = self._jaccard_similarity(
set(pattern_a.context_tags), set(pattern_b.context_tags)
)
total_score = sum(
scores[dim] * weights[dim] for dim in weights
)
return total_score
def _intent_similarity(self, intent_a: str, intent_b: str) –> float:
"""意图相似度计算"""
if intent_a == intent_b:
return 1.0
similarity_matrix = {
("format_data", "transform_data"): 0.7,
("parse_data", "validate_data"): 0.6,
("search_information", "data_analysis"): 0.5,
("generate_content", "report_generation"): 0.7,
}
key = tuple(sorted([intent_a, intent_b]))
return similarity_matrix.get(key, 0.0)
def _jaccard_similarity(self, set_a: set, set_b: set) –> float:
"""Jaccard相似度"""
if not set_a and not set_b:
return 1.0
intersection = set_a & set_b
union = set_a | set_b
return len(intersection) / len(union) if union else 0.0
3.3.4 频次触发的防抖机制
为了避免因短时间内的大量相似操作导致误触发,频次触发引擎内置了防抖机制:
class FrequencyDebouncer:
"""频次触发防抖器"""
def __init__(self):
self.recent_triggers = {}
self.cooldown_period = 3600 * 24 # 冷却期:24小时
self.confirmation_window = {}
def should_trigger(self, pattern_signature: str,
current_count: int) –> bool:
"""
判断是否应该真正触发Skill生成
防抖规则:
1. 同一模式签名在冷却期内只触发一次
2. 超过阈值后不立即触发,等待一个确认窗口
3. 确认窗口内如果模式继续出现,则触发
"""
now = datetime.now()
# 规则1:冷却期检查
last_trigger = self.recent_triggers.get(pattern_signature)
if last_trigger:
time_since_last = (now – last_trigger).total_seconds()
if time_since_last < self.cooldown_period:
return False
# 规则2:确认窗口检查
if current_count == 5: # FREQUENCY_THRESHOLD
self.confirmation_window[pattern_signature] = {
"start_time": now,
"confirmations": 0,
"required": 2
}
return False
# 规则3:确认窗口内的计数
if pattern_signature in self.confirmation_window:
window = self.confirmation_window[pattern_signature]
window["confirmations"] += 1
if window["confirmations"] >= window["required"]:
del self.confirmation_window[pattern_signature]
self.recent_triggers[pattern_signature] = now
return True
else:
return False
return False
3.4 自修复触发深度机制
3.4.1 自修复识别逻辑
自修复触发是Skill系统中最具智能性的触发条件。当Agent在执行任务时遇到错误,通过自身的推理和重试成功解决了问题后,系统会将这个"错误→修复"的链路提取为一个可复用的Skill。
┌─────────────────────────────────────────────────────────────────────────────┐
│ 自修复触发识别流程 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Agent执行任务│ │
│ └──────┬──────┘ │
│ │ │
│ ┌────▼────┐ │
│ │ 执行成功?│ │
│ └────┬────┘ │
│ 是 │ 否 │
│ │ └──────┐ │
│ │ │ │
│ │ ┌──────▼──────┐ │
│ │ │ Agent自行排查 │ │
│ │ │ – 分析错误 │ │
│ │ │ – 查找原因 │ │
│ │ │ – 尝试修复 │ │
│ │ └──────┬──────┘ │
│ │ │ │
│ │ ┌────▼────┐ │
│ │ │ 修复成功?│ │
│ │ └────┬────┘ │
│ │ 是 │ 否 │
│ │ │ └──────→ 请求用户帮助(不触发) │
│ │ │ │ │
│ │ ┌─────────▼───────▼──┐ │
│ │ │ 自修复识别器检查 │ │
│ │ │ │ │
│ │ │ 1. 错误是否可复现? │──→ 否 → 不触发(偶发错误不值得沉淀) │
│ │ │ │ │
│ │ │ 2. 修复是否通用? │──→ 否 → 不触发(过于特定的修复) │
│ │ │ │ │
│ │ │ 3. 修复是否安全? │──→ 否 → 不触发(不安全的修复方式) │
│ │ │ │ │
│ │ │ 4. 是否已有同类 │──→ 是 → 更新已有Skill(不新建) │
│ │ │ Skill? │ │
│ │ │ │ │
│ │ │ 5. 修复链路是否 │──→ 否 → 不触发(修复过于复杂,不适合沉淀) │
│ │ │ 可抽象? │ │
│ │ └────────┬───────────┘ │
│ │ │ │
│ │ 通过所有检查 │
│ │ │ │
│ │ ┌─────▼─────┐ │
│ │ │ ★ 触发 │ │
│ │ │ 自修复触发 │ │
│ │ │ Skill生成 │ │
│ │ └───────────┘ │
│ │ │
│ └──→ 正常完成,无触发 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
3.4.2 自修复识别器实现
class SelfHealTriggerDetector:
"""自修复触发检测器"""
def __init__(self):
self.error_recovery_store = ErrorRecoveryStore()
self.skill_registry = SkillRegistry()
self.safety_checker = SafetyChecker()
def detect_self_heal_trigger(self,
task_context: TaskContext) –> TriggerResult:
"""
检测任务执行过程中是否存在可触发的自修复链路
"""
# 1. 检查是否存在错误-修复链路
error_recovery_chain = self._extract_error_recovery_chain(task_context)
if not error_recovery_chain:
return TriggerResult(triggered=False, reason="no_error_recovery_chain")
# 2. 检查1: 错误是否可复现
if not self._is_error_reproducible(error_recovery_chain.error):
return TriggerResult(triggered=False, reason="error_not_reproducible")
# 3. 检查2: 修复是否具有通用性
generality_score = self._assess_generality(error_recovery_chain)
if generality_score < 0.6:
return TriggerResult(
triggered=False, reason="fix_not_general_enough",
generality_score=generality_score
)
# 4. 检查3: 修复方式是否安全
safety_result = self.safety_checker.check_fix_safety(
error_recovery_chain.recovery_actions
)
if not safety_result.is_safe:
return TriggerResult(
triggered=False, reason="fix_not_safe",
safety_issues=safety_result.issues
)
# 5. 检查4: 是否已有覆盖此错误场景的Skill
existing_skill = self.skill_registry.find_by_error_pattern(
error_recovery_chain.error
)
if existing_skill:
return TriggerResult(
triggered=True, trigger_source="self_heal",
action="update_existing", target_skill=existing_skill.skill_id,
error_recovery_chain=error_recovery_chain
)
# 6. 检查5: 修复链路是否可以抽象为通用Skill
abstraction_result = self._attempt_abstraction(error_recovery_chain)
if not abstraction_result.success:
return TriggerResult(
triggered=False, reason="cannot_abstract",
abstraction_issues=abstraction_result.issues
)
# 7. 所有检查通过,触发Skill生成
return TriggerResult(
triggered=True, trigger_source="self_heal",
action="create_new",
error_recovery_chain=error_recovery_chain,
abstraction=abstraction_result,
generality_score=generality_score
)
def _is_error_reproducible(self, error: ErrorInfo) –> bool:
"""判断错误是否可复现(排除偶发错误)"""
reproducible_error_types = {
"api_authentication_error",
"invalid_parameter_error",
"file_not_found_error",
"permission_denied_error",
"data_format_error",
"api_rate_limit_error",
"api_connection_timeout",
"json_parse_error",
}
return error.type in reproducible_error_types
def _assess_generality(self, chain: ErrorRecoveryChain) –> float:
"""评估修复的通用性"""
score = 0.0
# 维度1: 错误类型常见程度
common_errors = {
"api_connection_timeout": 0.25,
"api_authentication_error": 0.20,
"api_rate_limit_error": 0.25,
"json_parse_error": 0.30,
"file_not_found_error": 0.20,
"permission_denied_error": 0.15,
}
score += common_errors.get(chain.error.type, 0.1)
# 维度2: 修复策略可复用性
reusable_strategies = {
"exponential_backoff_retry": 0.30,
"fallback_to_cache": 0.25,
"switch_to_alternative_api": 0.20,
"refresh_token_and_retry": 0.25,
"sanitize_and_reparse": 0.28,
}
score += reusable_strategies.get(chain.fix_strategy, 0.10)
# 维度3: 修复步骤抽象程度
abstraction_level = self._measure_abstraction(chain.recovery_actions)
score += abstraction_level * 0.20
# 维度4: 上下文依赖程度(反向评分)
context_dependency = self._measure_context_dependency(chain)
score += (1.0 – context_dependency) * 0.20
return min(score, 1.0)
3.4.3 自修复触发示例
自修复触发示例:生成 api_retry_handler Skill
场景: Agent调用外部API时遇到超时错误
时间线:
1. Agent调用 https://api.example.com/data → 连接超时
2. Agent分析错误: "ConnectionTimeoutError"
3. Agent推理: "可能是网络临时问题,尝试重试"
4. Agent执行: 等待1秒 → 重试 → 仍然超时
5. Agent推理: "连续超时,使用指数退避策略"
6. Agent执行: 等待2秒 → 重试 → 超时
7. Agent执行: 等待4秒 → 重试 → 成功!
自修复识别器检查:
✓ 错误可复现: api_connection_timeout 是常见可复现错误
✓ 修复具有通用性: 指数退避重试策略通用性评分 0.85
✓ 修复安全: 仅涉及重试,无危险操作
✓ 无同类Skill: 系统中不存在api_retry_handler
✓ 可抽象: 修复链路可抽象为通用的API重试Skill
→ 触发自修复触发
→ 生成 api_retry_handler Skill
– 名称: api_retry_handler
– 触发来源: self_heal
– 功能: API调用失败时自动执行指数退避重试
– 参数: url, method, params, max_retries, initial_delay
– 策略: exponential backoff (1s, 2s, 4s, 8s, 16s)
3.5 用户纠正触发深度机制
3.5.1 用户纠正语义分析
用户纠正触发发生在用户明确纠正Agent行为的场景。系统需要从用户的纠正语句中提取出可沉淀的偏好规则,并将其转化为Skill。
class UserCorrectionAnalyzer:
"""用户纠正语义分析器"""
CORRECTION_TYPES = {
"language_preference": {
"patterns": [
r"用中文", r"说中文", r"用英文", r"用日语",
r"please (use|reply in) (english|chinese)",
r"回答.*请用.*语"
],
"skill_category": "language",
"generality": "permanent"
},
"format_preference": {
"patterns": [
r"用表格", r"用列表", r"用 markdown",
r"不要用.*格式", r"换成.*格式",
r"用.*排版", r"简洁一点", r"详细一点"
],
"skill_category": "formatting",
"generality": "persistent"
},
"behavior_correction": {
"patterns": [
r"不要.*这样", r"应该.*才对", r"不对",
r"错了", r"不是.*是", r"应该先.*再"
],
"skill_category": "behavior",
"generality": "contextual"
},
"tone_adjustment": {
"patterns": [
r"正式一点", r"随意一点", r"专业一点",
r"简单说", r"详细解释", r"给个例子"
],
"skill_category": "communication_style",
"generality": "persistent"
},
"workflow_correction": {
"patterns": [
r"步骤.*不对", r"顺序.*错了", r"应该先.*后",
r"漏了.*步骤", r"多了一步"
],
"skill_category": "workflow",
"generality": "persistent"
}
}
def analyze_correction(self, user_input: str,
agent_behavior: AgentBehavior) –> CorrectionAnalysis:
"""分析用户纠正语句"""
analysis = CorrectionAnalysis()
# 1. 判断是否为纠正语句
is_correction, correction_type = self._detect_correction_type(user_input)
if not is_correction:
return CorrectionAnalysis(is_correction=False)
analysis.correction_type = correction_type
analysis.correction_config = self.CORRECTION_TYPES[correction_type]
# 2. 提取纠正的规则
analysis.rule = self._extract_correction_rule(
user_input, agent_behavior, correction_type
)
# 3. 评估规则的通用性
analysis.generality_score = self._evaluate_generality(
analysis.rule, analysis.correction_config["generality"]
)
# 4. 检查是否已有同类Skill
analysis.existing_skill = self._find_overlapping_skill(
analysis.rule, analysis.correction_config["skill_category"]
)
# 5. 生成Skill草案
if analysis.generality_score >= 0.5:
analysis.skill_draft = self._generate_skill_draft(
analysis.rule, correction_type, agent_behavior
)
analysis.should_trigger = True
else:
analysis.should_trigger = False
analysis.reason = "low_generality"
return analysis
3.5.2 用户纠正触发示例
用户纠正触发示例:生成 language_preference_zh Skill
场景: Agent使用英文回复,用户要求使用中文
时间线:
1. 用户: "分析一下这段代码的性能瓶颈"
2. Agent: "Based on my analysis, the main performance bottleneck
is in the nested loop at line 42…" (英文回复)
3. 用户: "用中文回复"
用户纠正分析器处理:
– 纠正类型: language_preference
– 规则: response_language = "zh-CN"
– 通用性评分: 0.95 (永久偏好,高通用性)
– 是否已有同类Skill: 否
– should_trigger: True
→ 触发用户纠正触发
→ 生成 language_preference_zh Skill
– 名称: language_preference_zh
– 触发来源: user_correction
– 功能: 确保Agent始终使用简体中文回复
– 纠正类型: language_preference
– 通用性: permanent (永久)
– 执行方式: 在Agent生成回复前注入语言偏好约束
3.5.3 纠正类型的通用性分级
| 语言偏好 | 永久 | 所有对话 | 不淘汰 | “用中文回复” |
| 格式偏好 | 持久 | 特定场景 | 90天未使用 | “用表格展示” |
| 语气调整 | 持久 | 特定场景 | 90天未使用 | “简洁一点” |
| 行为纠正 | 上下文相关 | 特定上下文 | 45天未使用 | “不要直接给代码” |
| 工作流纠正 | 持久 | 特定工作流 | 60天未使用 | “应该先测试再部署” |
3.6 手动创建流程
3.6.1 手动创建的交互流程
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 手动创建流程 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 用户: "帮我创建一个每日报告生成的Skill" │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Step 1: 需求理解 │ │
│ │ Agent: "好的,我来帮你创建每日报告生成Skill。请告诉我以下信息: │ │
│ │ 1. 报告内容包含哪些部分? │ │
│ │ 2. 数据来源是什么? │ │
│ │ 3. 报告格式要求? │ │
│ │ 4. 生成时间和频率? │ │
│ │ 5. 是否需要自动发送?发送给谁?" │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ 用户: "报告包含项目进度、待办事项、风险预警三部分。数据从飞书文档 │
│ 读取。Markdown格式。每天早上9点生成。发送到我的邮箱。" │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Step 2: Skill草案生成 │ │
│ │ Agent: "我理解了你的需求,下面是我生成的Skill草案,请确认: │ │
│ │ 名称: daily_report_generator │ │
│ │ 功能: 每日从飞书文档读取项目数据,生成Markdown格式报告 │ │
│ │ 触发: 每日09:00 │ │
│ │ 输出: Markdown报告 → 邮件发送 │ │
│ │ 权限: 飞书文档读取 + 邮件发送 │ │
│ │ 是否需要调整?" │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ 用户: "没问题,就这样" │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Step 3: SKILL.md生成 │ │
│ │ – 生成完整的SKILL.md文件 │ │
│ │ – 生成执行脚本 │ │
│ │ – 生成测试用例 │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Step 4: 验证 │ │
│ │ – 语法验证 ✓ │ │
│ │ – 行为验证(沙箱测试运行)✓ │ │
│ │ – 安全验证(权限审查)✓ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Step 5: 注册与激活 │ │
│ │ – 注册到Skill索引 │ │
│ │ – 设置定时触发 │ │
│ │ – 状态: draft → validating → active │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
│ Agent: "✅ daily_report_generator Skill已创建并激活。 │
│ 每天早上9点将自动生成报告并发送到你的邮箱。" │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
3.6.2 手动创建的Skill定义示例
—
name: daily_report_generator
display_name: 每日报告生成器
version: 1.0.0
author: user
created_at: 2026-07-05T15:00:00+08:00
updated_at: 2026-07-05T15:00:00+08:00
status: active
trigger_source: manual
trigger_count: 0
quality_score: null
tools:
– name: generate_daily_report
description: 从飞书文档读取项目数据,生成每日Markdown格式报告
parameters:
– name: report_date
type: string
required: false
default: "today"
description: 报告日期,默认为今天
– name: sections
type: array
required: false
default: ["project_progress", "todo_items", "risk_alert"]
description: 报告包含的部分
items:
type: enum
enum: [project_progress, todo_items, risk_alert, meeting_notes]
– name: output_format
type: enum
required: false
default: markdown
enum: [markdown, html, pdf]
description: 输出格式
returns:
type: object
properties:
report_content:
type: string
description: 报告内容
report_path:
type: string
description: 报告文件路径
sent:
type: boolean
description: 是否已发送邮件
– name: send_report_email
description: 将报告通过邮件发送
parameters:
– name: report_content
type: string
required: true
description: 报告内容
– name: recipient
type: string
required: true
description: 收件人邮箱
– name: subject
type: string
required: false
default: "每日项目报告 – {date}"
description: 邮件主题
permissions:
filesystem:
read: ["/app/data/reports/**"]
write: ["/app/data/reports/**"]
network:
allowed: true
domains: ["open.feishu.cn", "smtp.example.com"]
shell:
allowed: false
memory:
read_layers: [L1, L2, L3]
write_layers: [L1, L2]
constraints:
max_execution_time: 120000
max_memory_usage: 200
rate_limit: 1
schedule:
type: cron
expression: "0 9 * * *"
timezone: "Asia/Shanghai"
dependencies:
skills: []
packages:
– python: requests
– python: jinja2
– python: smtplib
min_agent_version: 2.0.0
tags: [report, daily, automation, feishu, email]
category: workflow–automation
priority: high
—
# 每日报告生成器
## 功能描述
每日定时从飞书文档读取项目数据,生成包含项目进度、待办事项和风险预警
的Markdown格式报告,并通过邮件发送给指定收件人。
## 使用场景
– 每日项目进度跟踪
– 团队晨会数据准备
– 管理层日报自动化
## 执行逻辑
1. 连接飞书API,读取项目文档数据
2. 解析项目进度、待办事项、风险信息
3. 使用Jinja2模板引擎生成Markdown报告
4. 保存报告到本地文件系统
5. 通过SMTP发送报告邮件
## 错误处理
– 飞书API不可用 → 使用缓存数据 + 标注"数据可能不是最新"
– 邮件发送失败 → 保存报告到本地 + 通知用户手动发送
– 文档解析失败 → 跳过该部分 + 在报告中标注"解析失败"
3.7 触发条件调度器
四种触发条件由统一的调度器管理,确保触发逻辑的有序执行:
class TriggerDispatcher:
"""触发条件调度器"""
def __init__(self):
self.frequency_engine = FrequencyTriggerEngine()
self.self_heal_detector = SelfHealTriggerDetector()
self.correction_analyzer = UserCorrectionAnalyzer()
self.manual_creator = ManualSkillCreator()
self.trigger_queue = TriggerQueue()
def evaluate_triggers(self, event: AgentEvent) –> list:
"""
评估所有触发条件,返回触发的Skill生成任务列表
触发优先级:
1. 手动创建(用户显式请求)
2. 自修复触发(错误恢复链路)
3. 用户纠正触发(纠正语句)
4. 频次触发(操作模式重复)
"""
triggers = []
# 1. 检查手动创建
if event.type == EventType.USER_REQUEST_SKILL_CREATION:
manual_trigger = self.manual_creator.process_request(event)
if manual_trigger:
triggers.append(manual_trigger)
return triggers # 手动创建优先级最高,直接返回
# 2. 检查自修复触发
if event.type == EventType.TASK_COMPLETED:
self_heal_trigger = self.self_heal_detector.detect_self_heal_trigger(
event.task_context
)
if self_heal_trigger.triggered:
triggers.append(self_heal_trigger)
# 3. 检查用户纠正触发
if event.type == EventType.USER_INPUT:
correction = self.correction_analyzer.analyze_correction(
event.user_input, event.agent_behavior
)
if correction.should_trigger:
triggers.append(correction)
# 4. 检查频次触发
if event.type == EventType.OPERATION_COMPLETED:
freq_trigger = self.frequency_engine.check_trigger(event.operation)
if freq_trigger.triggered:
triggers.append(freq_trigger)
for trigger in triggers:
self.trigger_queue.enqueue(trigger)
return triggers
3.8 本章小结
本章深入分析了四种触发条件的实现机制:频次触发通过操作模式签名和相似度计算实现重复模式检测;自修复触发通过错误-修复链路提取和通用性评估实现智能技能沉淀;用户纠正触发通过语义分析将用户纠正转化为可复用的偏好规则;手动创建提供了用户主动定义Skill的完整交互流程。四种触发条件由统一的调度器管理,按优先级有序执行,共同构成了Skill系统的技能发现矩阵。
第四章 Skill生成全流程
4.1 生成流程总览
当触发条件满足后,系统启动Skill生成引擎,将检测到的操作模式或修复链路转化为一个完整的、可验证的Skill定义。整个生成流程分为六个阶段:发现 → 提炼 → 定义格式 → 验证 → 注册 → 激活。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 生成全流程图 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ 触发条件 │ │
│ │ 满足 │ │
│ └────┬─────┘ │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段1: 发现 │ │
│ │ – 收集操作历史/错误链路/纠正内容 │ │
│ │ – 提取操作模式签名 │ │
│ │ – 确定Skill的目标功能 │ │
│ └────┬──────────────────────────────────────────┘ │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段2: 提炼 │ │
│ │ – 从多次操作中提炼通用模式 │ │
│ │ – 抽象参数和返回值 │ │
│ │ – 确定执行步骤序列 │ │
│ │ – 识别错误处理逻辑 │ │
│ └────┬──────────────────────────────────────────┘ │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段3: 定义格式 │ │
│ │ – 生成SKILL.md文件 │ │
│ │ – 填写YAML前置元数据 │ │
│ │ – 编写Markdown正文 │ │
│ │ – 生成执行脚本 │ │
│ │ – 生成测试用例 │ │
│ └────┬──────────────────────────────────────────┘ │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段4: 验证 │ │
│ │ – 语法验证: SKILL.md格式检查 │ │
│ │ – 行为验证: 沙箱执行测试 │ │
│ │ – 安全验证: 权限和安全审查 │ │
│ └────┬──────────────────────────────────────────┘ │
│ │ │
│ ├── 验证失败 → 返回阶段3修正 → 重新验证(最多3次) │
│ │ │
│ ├── 验证失败3次 → 标记为草稿,等待手动修正 │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段5: 注册 │ │
│ │ – 将Skill注册到全局索引 │ │
│ │ – 生成语义嵌入向量 │ │
│ │ – 建立分类和标签关联 │ │
│ └────┬──────────────────────────────────────────┘ │
│ │ │
│ ┌────▼──────────────────────────────────────────┐ │
│ │ 阶段6: 激活 │ │
│ │ – 状态变更为active │ │
│ │ – 初始化质量指标 │ │
│ │ – 通知用户(轻量提示) │ │
│ └────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
4.2 阶段一:发现
发现阶段是Skill生成的起点,其核心任务是从触发事件中收集足够的信息,为后续的提炼阶段提供原始材料。
class SkillDiscoveryPhase:
"""Skill生成 – 发现阶段"""
def discover(self, trigger_result: TriggerResult) –> DiscoveryResult:
"""从触发结果中发现可沉淀的Skill信息"""
result = DiscoveryResult()
result.trigger_source = trigger_result.trigger_source
if trigger_result.trigger_source == "frequency":
result.operations = self._collect_operations(
trigger_result.similar_patterns
)
result.pattern_summary = self._summarize_pattern(
trigger_result.pattern, result.operations
)
elif trigger_result.trigger_source == "self_heal":
result.error_recovery_chain = trigger_result.error_recovery_chain
result.abstraction = trigger_result.abstraction
result.operations = self._extract_operations_from_chain(
trigger_result.error_recovery_chain
)
elif trigger_result.trigger_source == "user_correction":
result.correction_rule = trigger_result.rule
result.agent_behavior = trigger_result.agent_behavior
elif trigger_result.trigger_source == "manual":
result.user_requirement = trigger_result.user_requirement
result.operations = []
result.context = trigger_result.context
result.timestamp = datetime.now()
return result
发现阶段信息汇总示例(频次触发 format_json):
输入信息:
– 触发来源: frequency
– 触发次数: 5
– 操作模式: format_data | json_string | formatted_string | [python]
收集的5次操作详情:
操作1: "帮我把这段JSON格式化"
– 输入: '{"name":"test","value":123}'
– 输出: '{\\n "name": "test",\\n "value": 123\\n}'
– 工具: python_executor, 参数: {indent: 2}
– 成功: true, 耗时: 120ms
操作2: "这个JSON太乱了,帮我整理一下"
– 输入: '{"a":1,"b":[2,3],"c":{"d":4}}'
– 输出: 格式化后的JSON
– 工具: python_executor, 参数: {indent: 2}
– 成功: true, 耗时: 95ms
… (操作3-5类似)
模式摘要:
– 意图: format_data (数据格式化)
– 输入类型: JSON字符串
– 输出类型: 格式化的JSON字符串
– 核心步骤: parse_json → serialize_with_indent
– 关键参数: indent (默认2)
– 成功率: 5/5 = 100%, 平均耗时: 108ms
4.3 阶段二:提炼
提炼阶段是Skill生成的核心环节,其任务是从发现阶段收集的原始信息中提炼出通用的、可复用的操作模式。
class SkillDistillationPhase:
"""Skill生成 – 提炼阶段"""
def distill(self, discovery: DiscoveryResult) –> DistillationResult:
"""从发现的信息中提炼通用Skill模式"""
result = DistillationResult()
# 1. 提炼Skill名称和描述
result.name = self._generate_skill_name(discovery)
result.display_name = self._generate_display_name(discovery)
result.description = self._generate_description(discovery)
# 2. 提炼参数模式
result.parameters = self._distill_parameters(discovery.operations)
# 3. 提炼执行步骤
result.execution_steps = self._distill_execution_steps(discovery.operations)
# 4. 提炼返回值结构
result.returns = self._distill_returns(discovery.operations)
# 5. 提炼错误处理逻辑
result.error_handling = self._distill_error_handling(discovery.operations)
# 6. 提炼权限需求
result.permissions = self._distill_permissions(discovery)
# 7. 提炼约束条件
result.constraints = self._distill_constraints(discovery.operations)
# 8. 生成标签和分类
result.tags = self._generate_tags(discovery)
result.category = self._classify_category(discovery)
return result
def _distill_parameters(self, operations: list) –> list:
"""
从多次操作中提炼通用参数模式
策略:
1. 收集所有操作中出现的参数
2. 统计每个参数的出现频率
3. 高频参数(>=80%)标记为required
4. 推断参数类型和默认值
"""
param_stats = {}
for op in operations:
for param_name, param_value in op.get("parameters", {}).items():
if param_name not in param_stats:
param_stats[param_name] = {
"count": 0, "types": set(),
"values": [], "total_ops": len(operations)
}
param_stats[param_name]["count"] += 1
param_stats[param_name]["types"].add(type(param_value).__name__)
param_stats[param_name]["values"].append(param_value)
parameters = []
for param_name, stats in param_stats.items():
frequency = stats["count"] / stats["total_ops"]
param_def = {
"name": param_name,
"type": self._infer_type(stats["types"]),
"required": frequency >= 0.8,
"description": self._infer_description(param_name, stats),
}
if not param_def["required"]:
param_def["default"] = self._infer_default(stats["values"])
parameters.append(param_def)
return parameters
提炼示例(频次触发 format_json):
1. 名称提炼:
– 关键词: "格式化", "JSON", "整理"
– Skill名称: format_json, 显示名称: JSON格式化
2. 参数提炼:
– input: 5/5出现 → required=true, type=string
– indent: 4/5出现 → required=false, type=integer, default=2
– sort_keys: 1/5出现 → required=false, type=boolean, default=false
3. 执行步骤提炼:
Step 1: parse_json(${param:input}) → json_object
Step 2: serialize_json(json_object, ${param:indent}, ${param:sort_keys}) → output
Step 3: return output
4. 错误处理提炼:
– 输入不是有效JSON → 返回解析错误
– 输入为空 → 返回提示信息
5. 权限提炼: Level 0 (最低, 无文件/网络/Shell访问)
6. 约束提炼: max_execution_time=5000ms, max_memory=50MB, rate_limit=100/min
4.4 阶段三:定义格式
定义格式阶段将提炼结果转化为符合规范的SKILL.md文件和配套脚本。
class SkillDefinitionGenerator:
"""Skill定义格式生成器"""
def generate(self, distillation, discovery) –> SkillDefinition:
# 1. 生成YAML前置元数据
yaml_metadata = self._generate_yaml_metadata(distillation, discovery)
# 2. 生成Markdown正文
markdown_body = self._generate_markdown_body(distillation, discovery)
# 3. 合并为SKILL.md
skill_md = f"—\\n{yaml_metadata}\\n—\\n\\n{markdown_body}"
# 4. 生成执行脚本
script = self._generate_script(distillation)
# 5. 生成测试用例
tests = self._generate_tests(distillation, discovery)
return SkillDefinition(
skill_md=skill_md, script=script,
tests=tests, metadata=distillation
)
4.5 阶段四:验证
验证阶段是Skill生成流程中的安全屏障,所有自动生成的Skill必须通过三级验证才能进入注册阶段。
class SkillValidationPhase:
"""Skill生成 – 验证阶段"""
MAX_RETRY = 3
def validate(self, skill_def) –> ValidationResult:
result = ValidationResult()
retry_count = 0
while retry_count < self.MAX_RETRY:
# Level 1: 语法验证
syntax_result = self.syntax_validator.validate(skill_def)
if not syntax_result.passed:
skill_def = self._attempt_syntax_fix(skill_def, syntax_result)
retry_count += 1
continue
# Level 2: 行为验证
behavior_result = self.behavior_validator.validate(skill_def)
if not behavior_result.passed:
skill_def = self._attempt_behavior_fix(skill_def, behavior_result)
retry_count += 1
continue
# Level 3: 安全验证
security_result = self.security_validator.validate(skill_def)
if not security_result.passed:
result.passed = False
result.reason = "security_validation_failed"
return result
result.passed = True
result.validated_skill = skill_def
return result
result.passed = False
result.reason = "max_retry_exceeded"
return result
4.6 阶段五:注册
注册阶段将验证通过的Skill添加到全局Skill索引中,使其可被检索和加载。
class SkillRegistrationPhase:
"""Skill生成 – 注册阶段"""
def register(self, skill_def, validation) –> RegistrationResult:
# 1. 生成Skill ID
skill_id = f"{skill_def.name}_v{skill_def.version}"
# 2. 检查ID冲突
if self.skill_index.exists(skill_id):
return RegistrationResult(success=False, reason="skill_id_conflict")
# 3. 生成语义嵌入向量
embedding = self.embedding_generator.generate(
f"{skill_def.name} {skill_def.description} {skill_def.tags}"
)
# 4. 构建并写入索引条目
index_entry = {
"skill_id": skill_id,
"name": skill_def.name,
"display_name": skill_def.display_name,
"version": skill_def.version,
"status": "validating",
"category": skill_def.category,
"tags": skill_def.tags,
"trigger_source": skill_def.trigger_source,
"quality_score": None,
"last_called": None,
"call_count_30d": 0,
"skill_path": skill_def.skill_md_path,
"semantic_embedding": embedding,
"description_summary": skill_def.description[:200],
}
self.skill_index.add(index_entry)
self.file_store.save_skill(skill_def)
return RegistrationResult(success=True, skill_id=skill_id)
4.7 阶段六:激活
激活阶段是Skill生成流程的最后一步,将Skill状态从"验证中"变更为"激活",并初始化质量监控。
class SkillActivationPhase:
"""Skill生成 – 激活阶段"""
def activate(self, skill_id: str) –> ActivationResult:
skill_entry = self.skill_index.get(skill_id)
if not skill_entry:
return ActivationResult(success=False, reason="skill_not_found")
if skill_entry["status"] != "validating":
return ActivationResult(success=False, reason="invalid_status")
# 状态变更: validating → active
self.skill_index.update_status(skill_id, "active")
# 初始化质量指标
initial_metrics = {
"success_rate": 1.0,
"satisfaction": None,
"efficiency": None,
"reuse_freq": 0.0,
"total_calls": 0,
"last_called": None,
"quality_score": 0.5,
"metrics_history": []
}
self.quality_store.init_metrics(skill_id, initial_metrics)
# 设置定时触发
if skill_entry.get("schedule"):
self.scheduler.add_job(skill_id, skill_entry["schedule"])
notification = self._generate_notification(skill_entry)
return ActivationResult(
success=True, skill_id=skill_id,
status="active", notification=notification
)
def _generate_notification(self, skill_entry: dict) –> str:
trigger_desc = {
"frequency": "检测到你多次执行相同操作",
"self_heal": "检测到错误自修复成功",
"user_correction": "根据你的反馈",
"manual": "根据你的要求"
}
source = trigger_desc.get(skill_entry["trigger_source"], "自动检测")
return (
f"✅ 新Skill已创建: {skill_entry['display_name']}\\n"
f" {source},已自动生成「{skill_entry['display_name']}」技能。\\n"
f" 下次遇到类似场景将自动使用此技能。"
)
4.8 生成流程的状态追踪
# Skill生成状态追踪记录示例
generation_tracker:
skill_id: "format_json_v1.0.0"
trigger_source: "frequency"
started_at: "2026-07-05T11:00:05+08:00"
phases:
discovery:
status: completed
duration_ms: 3000
details:
operations_collected: 5
distillation:
status: completed
duration_ms: 7000
details:
parameters_distilled: 3
execution_steps: 3
definition:
status: completed
duration_ms: 7000
details:
skill_md_generated: true
script_generated: true
tests_generated: true
validation:
status: completed
duration_ms: 13000
retry_count: 1
details:
syntax_validation: passed
behavior_validation: passed (after 1 retry)
security_validation: passed
registration:
status: completed
duration_ms: 2000
details:
skill_id_assigned: "format_json_v1.0.0"
activation:
status: completed
duration_ms: 1000
details:
status_changed_to: active
user_notified: true
total_duration_ms: 33000
final_status: active
4.9 本章小结
本章详细描述了Skill生成的六个阶段:发现阶段收集原始操作数据,提炼阶段从中抽取通用模式,定义格式阶段生成SKILL.md和执行脚本,验证阶段执行三级安全检查,注册阶段将Skill添加到全局索引,激活阶段完成状态变更和质量监控初始化。整个流程支持失败重试(最多3次),并在每个阶段记录详细的追踪信息,确保生成过程的可追溯性。
第五章 三级验证体系
5.1 验证体系架构
Skill的三级验证体系是确保自动生成Skill安全性和可靠性的核心保障。每一级验证聚焦不同的验证维度,形成层层递进的安全屏障。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 三级验证体系架构图 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ Level 1: 语法验证层 │ │
│ │ SyntaxValidator │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ YAML格式 │ │ 字段完整性 │ │ 类型正确性 │ │ │
│ │ │ 检查器 │ │ 检查器 │ │ 检查器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 命名规范 │ │ 版本号格式 │ │ 参数约束 │ │ │
│ │ │ 检查器 │ │ 检查器 │ │ 检查器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────┬───────────────────────────────────────┘ │
│ │ 通过 │
│ ┌───────────────────────────▼───────────────────────────────────────┐ │
│ │ Level 2: 行为验证层 │ │
│ │ BehaviorValidator │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 沙箱环境 │ │ 测试用例 │ │ 边界条件 │ │ │
│ │ │ 执行器 │ │ 运行器 │ │ 测试器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 超时检测 │ │ 资源监控 │ │ 输出验证 │ │ │
│ │ │ 器 │ │ 器 │ │ 器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────┬───────────────────────────────────────┘ │
│ │ 通过 │
│ ┌───────────────────────────▼───────────────────────────────────────┐ │
│ │ Level 3: 安全验证层 │ │
│ │ SecurityValidator │ │
│ ├───────────────────────────────────────────────────────────────────┤ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 权限边界 │ │ 资源访问 │ │ 恶意代码 │ │ │
│ │ │ 检查器 │ │ 审计器 │ │ 扫描器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ 注入攻击 │ │ 敏感信息 │ │ 依赖安全 │ │ │
│ │ │ 检测器 │ │ 泄露检测 │ │ 检查器 │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ └───────────────────────────┬───────────────────────────────────────┘ │
│ │ 通过 │
│ ┌───────────────────────────▼───────────────────────────────────────┐ │
│ │ 验证通过 → 进入注册阶段 │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
5.2 验证层级对比
| 验证目标 | SKILL.md格式正确性 | Skill执行行为正确性 | Skill安全性 |
| 验证方式 | 静态分析 | 沙箱动态执行 | 安全规则匹配 + 代码审计 |
| 验证内容 | YAML格式、字段完整性、类型正确性 | 测试用例通过、边界条件、超时 | 权限边界、恶意代码、注入攻击 |
| 失败处理 | 自动修复(最多3次) | 自动修复(最多3次) | 不修复,直接拒绝 |
| 验证速度 | 快(<100ms) | 中(1-10秒) | 中(500ms-5秒) |
| 验证环境 | 无需执行环境 | 隔离沙箱 | 静态分析 + 规则引擎 |
| 关键指标 | 格式合规率 | 测试通过率 | 安全违规数 |
| 通过标准 | 100%合规 | 所有测试通过 | 0个高危违规 |
5.3 Level 1: 语法验证
5.3.1 语法验证器实现
class SyntaxValidator:
"""Level 1 语法验证器"""
def validate(self, skill_def: SkillDefinition) –> SyntaxValidationResult:
"""执行语法验证"""
result = SyntaxValidationResult()
issues = []
# 1. YAML格式验证
yaml_issues = self._validate_yaml_format(skill_def.yaml_metadata)
issues.extend(yaml_issues)
# 2. 字段完整性验证
field_issues = self._validate_field_completeness(skill_def)
issues.extend(field_issues)
# 3. 类型正确性验证
type_issues = self._validate_type_correctness(skill_def)
issues.extend(type_issues)
# 4. 命名规范验证
naming_issues = self._validate_naming_convention(skill_def)
issues.extend(naming_issues)
# 5. 版本号格式验证
version_issues = self._validate_version_format(skill_def)
issues.extend(version_issues)
# 6. 参数约束验证
param_issues = self._validate_parameter_constraints(skill_def)
issues.extend(param_issues)
result.issues = issues
result.passed = len([i for i in issues if i.severity == "error"]) == 0
result.warnings = [i for i in issues if i.severity == "warning"]
result.errors = [i for i in issues if i.severity == "error"]
return result
def _validate_yaml_format(self, yaml_str: str) –> list:
"""验证YAML格式"""
issues = []
try:
metadata = yaml.safe_load(yaml_str)
if not isinstance(metadata, dict):
issues.append(ValidationIssue(
severity="error", field="yaml",
message="YAML内容必须是字典类型"
))
except yaml.YAMLError as e:
issues.append(ValidationIssue(
severity="error", field="yaml",
message=f"YAML解析错误: {str(e)}"
))
return issues
def _validate_field_completeness(self, skill_def) –> list:
"""验证字段完整性"""
issues = []
required_fields = [
"name", "version", "author", "created_at",
"updated_at", "status", "trigger_source", "tools"
]
for field in required_fields:
if not hasattr(skill_def, field) or getattr(skill_def, field) is None:
issues.append(ValidationIssue(
severity="error", field=field,
message=f"必填字段缺失: {field}"
))
if not skill_def.tools or len(skill_def.tools) == 0:
issues.append(ValidationIssue(
severity="error", field="tools",
message="至少需要定义一个工具"
))
return issues
def _validate_type_correctness(self, skill_def) –> list:
"""验证类型正确性"""
issues = []
valid_types = {"string", "integer", "float", "boolean",
"array", "object", "file", "enum"}
for tool in skill_def.tools:
for param in tool.parameters:
if param.type not in valid_types:
issues.append(ValidationIssue(
severity="error",
field=f"tools.{tool.name}.parameters.{param.name}.type",
message=f"无效的参数类型: {param.type}"
))
if param.type == "enum" and not param.enum_values:
issues.append(ValidationIssue(
severity="error",
field=f"tools.{tool.name}.parameters.{param.name}",
message="enum类型参数必须定义enum值列表"
))
if param.type in ("integer", "float"):
if param.min is not None and param.max is not None:
if param.min > param.max:
issues.append(ValidationIssue(
severity="error",
field=f"tools.{tool.name}.parameters.{param.name}",
message=f"min({param.min})不能大于max({param.max})"
))
return issues
def _validate_naming_convention(self, skill_def) –> list:
"""验证命名规范"""
issues = []
import re
name_pattern = r'^[a-z][a-z0-9_]{0,63}$'
if not re.match(name_pattern, skill_def.name):
issues.append(ValidationIssue(
severity="error", field="name",
message="名称必须以小写字母开头,仅含小写字母/数字/下划线,最长64字符"
))
return issues
def _validate_version_format(self, skill_def) –> list:
"""验证版本号格式"""
issues = []
import re
version_pattern = r'^\\d+\\.\\d+\\.\\d+$'
if not re.match(version_pattern, skill_def.version):
issues.append(ValidationIssue(
severity="error", field="version",
message="版本号必须符合语义化版本格式: MAJOR.MINOR.PATCH"
))
return issues
def _validate_parameter_constraints(self, skill_def) –> list:
"""验证参数约束"""
issues = []
for tool in skill_def.tools:
for param in tool.parameters:
if param.required and param.default is not None:
issues.append(ValidationIssue(
severity="warning",
field=f"tools.{tool.name}.parameters.{param.name}",
message="必填参数不应设置默认值"
))
if not param.required and param.default is None:
if param.type != "enum":
issues.append(ValidationIssue(
severity="warning",
field=f"tools.{tool.name}.parameters.{param.name}",
message="非必填参数建议设置默认值"
))
return issues
5.3.2 语法验证报告示例
{
"validation_level": "syntax",
"skill_id": "format_json_v1.0.0",
"timestamp": "2026-07-05T11:00:22+08:00",
"passed": true,
"duration_ms": 45,
"checks_performed": 6,
"issues": [
{
"severity": "warning",
"field": "tools.format_json.parameters.sort_keys",
"message": "非必填参数建议设置默认值"
}
],
"errors": [],
"warnings_count": 1,
"errors_count": 0,
"details": {
"yaml_format": "passed",
"field_completeness": "passed",
"type_correctness": "passed",
"naming_convention": "passed",
"version_format": "passed",
"parameter_constraints": "passed (1 warning)"
}
}
5.4 Level 2: 行为验证
5.4.1 行为验证器实现
class BehaviorValidator:
"""Level 2 行为验证器"""
SANDBOX_TIMEOUT = 10000 # 沙箱超时: 10秒
MAX_MEMORY_MB = 200 # 最大内存: 200MB
def validate(self, skill_def: SkillDefinition) –> BehaviorValidationResult:
"""执行行为验证"""
result = BehaviorValidationResult()
issues = []
# 1. 准备测试用例
test_cases = self._prepare_test_cases(skill_def)
# 2. 在沙箱中执行测试
for test_case in test_cases:
test_result = self._run_in_sandbox(skill_def, test_case)
if not test_result.passed:
issues.append(ValidationIssue(
severity="error",
field=f"test_case.{test_case.name}",
message=test_result.error_message
))
# 3. 边界条件测试
boundary_tests = self._generate_boundary_tests(skill_def)
for test in boundary_tests:
test_result = self._run_in_sandbox(skill_def, test)
if not test_result.passed:
issues.append(ValidationIssue(
severity="error",
field=f"boundary_test.{test.name}",
message=test_result.error_message
))
# 4. 超时检测
timeout_result = self._check_timeout_behavior(skill_def)
if not timeout_result.passed:
issues.append(ValidationIssue(
severity="error", field="timeout",
message=f"Skill执行超时: {timeout_result.actual_time}ms"
))
# 5. 资源使用检测
resource_result = self._check_resource_usage(skill_def)
if resource_result.memory_used > self.MAX_MEMORY_MB:
issues.append(ValidationIssue(
severity="error", field="memory",
message=f"内存使用超限: {resource_result.memory_used}MB"
))
result.issues = issues
result.passed = len([i for i in issues if i.severity == "error"]) == 0
return result
def _run_in_sandbox(self, skill_def, test_case) –> SandboxTestResult:
"""在隔离沙箱中执行测试"""
sandbox = Sandbox(
timeout=self.SANDBOX_TIMEOUT,
max_memory=self.MAX_MEMORY_MB,
allowed_paths=skill_def.permissions.filesystem,
allowed_domains=skill_def.permissions.network.domains,
disabled_shell=not skill_def.permissions.shell.allowed
)
try:
result = sandbox.execute(
script=skill_def.script,
entry_point=skill_def.tools[0].name,
parameters=test_case.parameters
)
if test_case.expected_output is not None:
if not self._compare_output(result.output, test_case.expected_output):
return SandboxTestResult(
passed=False,
error_message=f"输出不匹配: 期望 {test_case.expected_output}, "
f"实际 {result.output}"
)
return SandboxTestResult(
passed=True,
output=result.output,
execution_time_ms=result.execution_time,
memory_used_mb=result.memory_used
)
except TimeoutError:
return SandboxTestResult(
passed=False,
error_message=f"执行超时({self.SANDBOX_TIMEOUT}ms)"
)
except Exception as e:
return SandboxTestResult(
passed=False,
error_message=f"执行异常: {str(e)}"
)
def _generate_boundary_tests(self, skill_def) –> list:
"""生成边界条件测试用例"""
tests = []
for tool in skill_def.tools:
for param in tool.parameters:
if param.type in ("integer", "float"):
if param.min is not None:
tests.append(TestCase(
name=f"{param.name}_min_boundary",
parameters={param.name: param.min}
))
if param.max is not None:
tests.append(TestCase(
name=f"{param.name}_max_boundary",
parameters={param.name: param.max}
))
elif param.type == "string":
tests.append(TestCase(
name=f"{param.name}_empty",
parameters={param.name: ""}
))
tests.append(TestCase(
name=f"{param.name}_very_long",
parameters={param.name: "x" * 10000}
))
return tests
5.4.2 行为验证报告示例
{
"validation_level": "behavior",
"skill_id": "format_json_v1.0.0",
"timestamp": "2026-07-05T11:00:28+08:00",
"passed": true,
"duration_ms": 3200,
"sandbox_config": {
"timeout_ms": 10000,
"max_memory_mb": 200,
"isolation": "container"
},
"test_results": [
{
"test_name": "basic_format",
"passed": true,
"execution_time_ms": 45,
"memory_used_mb": 12
},
{
"test_name": "nested_json",
"passed": true,
"execution_time_ms": 52,
"memory_used_mb": 15
},
{
"test_name": "empty_input",
"passed": true,
"execution_time_ms": 8,
"memory_used_mb": 8,
"note": "正确处理空输入,返回提示信息"
}
],
"boundary_results": [
{
"test_name": "indent_min_boundary",
"passed": true,
"note": "indent=0 正确处理"
},
{
"test_name": "indent_max_boundary",
"passed": true,
"note": "indent=8 正确处理"
},
{
"test_name": "input_very_long",
"passed": true,
"execution_time_ms": 320,
"memory_used_mb": 45,
"note": "10000字符JSON正确处理"
}
],
"timeout_check": "passed (max 320ms / limit 10000ms)",
"resource_check": "passed (max 45MB / limit 200MB)",
"issues": []
}
5.5 Level 3: 安全验证
5.5.1 安全验证器实现
class SecurityValidator:
"""Level 3 安全验证器"""
DANGEROUS_SHELL_PATTERNS = [
r"rm\\s+-rf\\s+/",
r"chmod\\s+777",
r"curl\\s+.*\\|\\s*sh",
r"wget\\s+.*\\|\\s*bash",
r"eval\\s*\\(",
r"exec\\s*\\(",
r"subprocess\\.(call|run|Popen)\\s*\\(.*shell=True",
r"os\\.system\\s*\\(",
r"__import__\\s*\\(['\\"]os['\\"]\\)",
]
SENSITIVE_DATA_PATTERNS = [
r"(?i)password\\s*=\\s*['\\"][^'\\"]+['\\"]",
r"(?i)api[_-]?key\\s*=\\s*['\\"][^'\\"]+['\\"]",
r"(?i)secret\\s*=\\s*['\\"][^'\\"]+['\\"]",
r"(?i)token\\s*=\\s*['\\"][^'\\"]+['\\"]",
r"—–BEGIN\\s+(RSA\\s+)?PRIVATE\\s+KEY—–",
r"sk-[a-zA-Z0-9]{20,}",
]
INJECTION_PATTERNS = [
r";\\s*(rm|del|drop|truncate)\\s",
r"–\\s*$",
r"';\\s*DROP\\s+TABLE",
r"<script[^>]*>",
r"javascript:",
r"on\\w+\\s*=\\s*['\\"]",
]
def validate(self, skill_def: SkillDefinition) –> SecurityValidationResult:
"""执行安全验证"""
result = SecurityValidationResult()
issues = []
# 1. 权限边界检查
issues.extend(self._check_permission_boundaries(skill_def))
# 2. 资源访问审计
issues.extend(self._audit_resource_access(skill_def))
# 3. 恶意代码扫描
issues.extend(self._scan_malicious_code(skill_def))
# 4. 注入攻击检测
issues.extend(self._detect_injection_attacks(skill_def))
# 5. 敏感信息泄露检测
issues.extend(self._detect_sensitive_data_leak(skill_def))
# 6. 依赖安全检查
issues.extend(self._check_dependency_security(skill_def))
result.issues = issues
result.passed = len([i for i in issues if i.severity == "error"]) == 0
result.critical_issues = [i for i in issues if i.severity == "critical"]
return result
def _check_permission_boundaries(self, skill_def) –> list:
"""检查权限边界"""
issues = []
max_permissions = {
"frequency": 2,
"self_heal": 2,
"user_correction": 1,
"manual": 4,
}
max_level = max_permissions.get(skill_def.trigger_source, 1)
actual_level = self._calculate_permission_level(skill_def.permissions)
if actual_level > max_level:
issues.append(ValidationIssue(
severity="error", field="permissions",
message=f"权限级别(Level {actual_level})超出触发来源"
f"({skill_def.trigger_source})允许的最大级别(Level {max_level})"
))
for path in skill_def.permissions.filesystem.get("read", []):
if path in ("/**", "/*"):
issues.append(ValidationIssue(
severity="error", field="permissions.filesystem.read",
message=f"不允许使用全局通配符路径: {path}"
))
if skill_def.permissions.shell.allowed and skill_def.trigger_source != "manual":
issues.append(ValidationIssue(
severity="error", field="permissions.shell",
message="非手动创建的Skill不允许Shell执行权限"
))
return issues
def _scan_malicious_code(self, skill_def) –> list:
"""扫描恶意代码"""
issues = []
script_content = skill_def.script
for pattern in self.DANGEROUS_SHELL_PATTERNS:
matches = re.finditer(pattern, script_content, re.IGNORECASE)
for match in matches:
issues.append(ValidationIssue(
severity="critical", field="script",
message=f"检测到危险代码模式: {pattern}"
))
return issues
def _detect_injection_attacks(self, skill_def) –> list:
"""检测注入攻击"""
issues = []
all_content = skill_def.script + "\\n" + skill_def.skill_md
for pattern in self.INJECTION_PATTERNS:
matches = re.finditer(pattern, all_content, re.IGNORECASE)
for match in matches:
issues.append(ValidationIssue(
severity="error", field="content",
message=f"检测到潜在注入攻击模式: {pattern[:30]}"
))
return issues
def _detect_sensitive_data_leak(self, skill_def) –> list:
"""检测敏感信息泄露"""
issues = []
all_content = skill_def.script + "\\n" + skill_def.skill_md
for pattern in self.SENSITIVE_DATA_PATTERNS:
matches = re.finditer(pattern, all_content)
for match in matches:
issues.append(ValidationIssue(
severity="error", field="content",
message=f"检测到潜在敏感信息泄露"
))
return issues
def _check_dependency_security(self, skill_def) –> list:
"""检查依赖安全性"""
issues = []
for dep in skill_def.dependencies.get("packages", []):
package_name = list(dep.values())[0]
if package_name in self.KNOWN_VULNERABLE_PACKAGES:
issues.append(ValidationIssue(
severity="warning", field="dependencies",
message=f"依赖包 {package_name} 存在已知漏洞"
))
return issues
def _calculate_permission_level(self, permissions) –> int:
"""计算权限级别"""
level = 0
if permissions.filesystem.get("read") or permissions.filesystem.get("write"):
level = max(level, 1)
if permissions.filesystem.get("write"):
level = max(level, 2)
if permissions.network.get("allowed"):
level = max(level, 2)
if permissions.shell.get("allowed"):
level = max(level, 3)
if "L4" in permissions.memory.get("read_layers", []):
level = max(level, 4)
return level
5.5.2 安全验证报告示例
{
"validation_level": "security",
"skill_id": "format_json_v1.0.0",
"timestamp": "2026-07-05T11:00:33+08:00",
"passed": true,
"duration_ms": 850,
"checks_performed": 6,
"critical_issues": [],
"issues": [],
"details": {
"permission_boundaries": "passed (Level 0, max allowed Level 2 for frequency)",
"resource_access_audit": "passed (no resource access required)",
"malicious_code_scan": "passed (0 patterns detected)",
"injection_attack_detection": "passed (0 patterns detected)",
"sensitive_data_leak": "passed (0 patterns detected)",
"dependency_security": "passed (only stdlib dependency: json)"
}
}
5.6 验证流程的自动修复
当Level 1或Level 2验证失败时,系统会尝试自动修复问题:
class AutoFixer:
"""验证自动修复器"""
def fix_syntax_issues(self, skill_def, issues: list) –> SkillDefinition:
"""修复语法问题"""
for issue in issues:
if issue.severity != "error":
continue
if issue.field == "yaml":
skill_def.yaml_metadata = self._fix_yaml(skill_def.yaml_metadata)
elif issue.field == "name":
skill_def.name = self._fix_name(skill_def.name)
elif issue.field == "version":
skill_def.version = "1.0.0"
return skill_def
def fix_behavior_issues(self, skill_def, issues: list) –> SkillDefinition:
"""修复行为问题"""
for issue in issues:
if issue.severity != "error":
continue
if "timeout" in issue.field:
skill_def.constraints.max_execution_time *= 2
elif "memory" in issue.field:
skill_def.script = self._optimize_memory_usage(skill_def.script)
elif "test_case" in issue.field:
skill_def.script = self._fix_execution_logic(skill_def.script, issue)
return skill_def
def _fix_name(self, name: str) –> str:
"""修复名称"""
import re
name = name.lower()
name = re.sub(r'[^a-z0-9_]', '_', name)
if name and name[0].isdigit():
name = 's_' + name
return name[:64]
5.7 验证体系配置
# 验证体系全局配置
validation_config:
level_1_syntax:
enabled: true
auto_fix: true
max_fix_retries: 3
level_2_behavior:
enabled: true
auto_fix: true
max_fix_retries: 3
sandbox:
type: container
timeout_ms: 10000
max_memory_mb: 200
network_isolated: true
filesystem_isolated: true
level_3_security:
enabled: true
auto_fix: false
critical_block: true
permission_limits:
frequency: 2
self_heal: 2
user_correction: 1
manual: 4
dangerous_patterns:
update_interval: 7d
sensitive_data:
scan_depth: full
custom_patterns: []
overall:
max_total_retries: 3
timeout_ms: 30000
parallel: false
5.8 本章小结
本章详细阐述了Skill三级验证体系的架构和实现。Level 1语法验证通过静态分析确保SKILL.md的格式合规性;Level 2行为验证通过沙箱执行确保Skill的运行时行为正确性;Level 3安全验证通过多维度扫描确保Skill不会对系统安全构成威胁。三级验证层层递进,前两级支持自动修复(最多3次重试),第三级安全问题直接阻断不可修复,共同构成了Skill安全生成的坚实屏障。
第六章 Skill生命周期状态机
6.1 生命周期状态总览
每个Skill从创建到消亡经历一系列状态变迁,这些状态构成了一个完整的状态机。Skill生命周期管理器(LifecycleManager)负责监控和驱动这些状态变迁,确保Skill在每个状态下都处于正确的运行模式。
6.2 生命周期状态机图
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 生命周期状态机 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────┐ │
│ 创建 ──────→ │ 草稿 │ │
│ │ DRAFT │ │
│ └─────┬─────┘ │
│ │ 提交验证 │
│ ┌─────▼─────┐ │
│ │ 验证中 │ │
│ │ VALIDATING│ │
│ └─────┬─────┘ │
│ │ │
│ ┌────────────┼────────────┐ │
│ │ │ │ │
│ 验证失败 验证通过 验证超时 │
│ │ │ │ │
│ ▼ │ ▼ │
│ ┌─────────┐ │ ┌─────────┐ │
│ │ 草稿 │ │ │ 草稿 │ │
│ │ (返回) │ │ │ (超时) │ │
│ └─────────┘ │ └─────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ 激活 │ ←──── 重新激活 │
│ │ ACTIVE │ │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ │ │ │ │
│ 长期未调用 用户手动休眠 质量过低 │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ └───────────┴───────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ 休眠 │ ───── 被调用 ─────→ 回到 [激活] │
│ │ DORMANT │ │
│ └─────┬─────┘ │
│ │ │
│ ┌───────────┼───────────┐ │
│ │ │ │ │
│ 长期休眠 用户手动淘汰 冲突合并 │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ └───────────┴───────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ 淘汰 │ │
│ │ DEPRECATED│ │
│ └─────┬─────┘ │
│ │ 宽限期结束 │
│ ┌─────▼─────┐ │
│ │ 归档 │ │
│ │ ARCHIVED │ │
│ └───────────┘ │
│ │
│ 特殊转换: │
│ [任意状态] → [归档] (用户手动删除) │
│ [任意状态] → [激活] (用户手动恢复,仅限休眠/淘汰状态) │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
6.3 生命周期状态对比
| 草稿 | DRAFT | 初始状态,尚未验证 | 否 | 否 | 否 | 否 | 低 |
| 验证中 | VALIDATING | 正在通过三级验证 | 否 | 否 | 否 | 否 | 中 |
| 激活 | ACTIVE | 验证通过,正常使用 | 是 | 是 | 是 | 是 | 高 |
| 休眠 | DORMANT | 长期未调用,暂停使用 | 否 | 是(低优先级) | 是(低频) | 否 | 低 |
| 淘汰 | DEPRECATED | 标记为淘汰,宽限期 | 否 | 否 | 否 | 否 | 极低 |
| 归档 | ARCHIVED | 永久归档,不可恢复 | 否 | 否(仅历史查询) | 否 | 否 | 极低 |
6.4 状态转换条件详解
6.4.1 草稿 → 验证中
transition:
from: draft
to: validating
trigger: submit_for_validation
conditions:
– skill_md_generated: true
– script_generated: true
– tests_generated: true
actions:
– 启动三级验证流程
– 记录验证开始时间
6.4.2 验证中 → 激活
transition:
from: validating
to: active
trigger: validation_passed
conditions:
– syntax_validation: passed
– behavior_validation: passed
– security_validation: passed
actions:
– 注册到全局Skill索引
– 初始化质量指标
– 设置定时触发(如有配置)
– 发送用户通知
6.4.3 激活 → 休眠
transition:
from: active
to: dormant
trigger: dormancy_check
conditions:
# 以下任一条件满足即触发休眠
– condition_1:
type: long_unused
description: "超过休眠阈值未被调用"
threshold_days: 30 # 频次触发: 30天, 自修复: 60天, 纠正: 45天
– condition_2:
type: user_manual
description: "用户手动设置休眠"
– condition_3:
type: low_quality
description: "质量评分持续低于0.3超过14天"
actions:
– 暂停定时触发
– 降低索引优先级
– 记录休眠原因和时间
– 轻量通知用户
6.4.4 休眠 → 激活
transition:
from: dormant
to: active
trigger: reactivation
conditions:
– condition_1:
type: skill_called
description: "休眠状态的Skill被用户或Agent调用"
– condition_2:
type: user_manual
description: "用户手动恢复激活"
actions:
– 恢复定时触发
– 提升索引优先级
– 重置休眠计时器
– 重置质量评分(乘以0.8的衰减系数)
6.4.5 休眠 → 淘汰
transition:
from: dormant
to: deprecated
trigger: deprecation_check
conditions:
– condition_1:
type: long_dormant
description: "休眠状态超过宽限期"
threshold_days: 90 # 休眠后90天未恢复
– condition_2:
type: conflict_merge
description: "被更高版本的Skill替代"
– condition_3:
type: user_manual
description: "用户手动淘汰"
actions:
– 标记为淘汰
– 设置宽限期(30天)
– 通知用户
– 检查是否有依赖此Skill的其他Skill
6.4.6 淘汰 → 归档
transition:
from: deprecated
to: archived
trigger: archive_check
conditions:
– condition_1:
type: grace_period_expired
description: "淘汰宽限期结束(30天)"
– condition_2:
type: user_manual
description: "用户手动归档"
actions:
– 将Skill文件移动到归档目录
– 从活跃索引中移除
– 添加到归档索引
– 保留质量历史数据
– 释放定时触发资源
6.5 生命周期管理器实现
class LifecycleManager:
"""Skill生命周期管理器"""
# 各触发来源的休眠阈值(天)
DORMANCY_THRESHOLDS = {
"frequency": 30,
"self_heal": 60,
"user_correction": 45,
"manual": 90, # 手动创建的Skill休眠阈值更宽松
}
# 休眠后淘汰的宽限期(天)
DEPRECATION_GRACE_PERIOD = 90
# 淘汰后归档的宽限期(天)
ARCHIVE_GRACE_PERIOD = 30
def __init__(self):
self.skill_index = SkillIndex()
self.quality_store = QualityStore()
self.scheduler = Scheduler()
self.notifier = Notifier()
def check_transitions(self):
"""
定期检查所有Skill的状态转换条件
建议执行频率: 每小时一次
"""
all_skills = self.skill_index.get_all()
for skill in all_skills:
current_status = skill["status"]
if current_status == "active":
self._check_dormancy(skill)
elif current_status == "dormant":
self._check_deprecation(skill)
elif current_status == "deprecated":
self._check_archive(skill)
def _check_dormancy(self, skill: dict):
"""检查激活状态的Skill是否应该休眠"""
trigger_source = skill["trigger_source"]
threshold_days = self.DORMANCY_THRESHOLDS.get(trigger_source, 30)
last_called = skill.get("last_called")
if last_called:
days_since_last_call = (
datetime.now() – datetime.fromisoformat(last_called)
).days
if days_since_last_call >= threshold_days:
self._transition_to_dormant(skill["skill_id"], "long_unused")
return
# 检查质量评分
metrics = self.quality_store.get_metrics(skill["skill_id"])
if metrics and metrics.get("quality_score") is not None:
if metrics["quality_score"] < 0.3:
# 检查低质量持续时间
low_quality_days = self._count_low_quality_days(
skill["skill_id"], threshold=0.3
)
if low_quality_days >= 14:
self._transition_to_dormant(skill["skill_id"], "low_quality")
def _check_deprecation(self, skill: dict):
"""检查休眠状态的Skill是否应该淘汰"""
dormant_since = skill.get("dormant_since")
if dormant_since:
days_dormant = (
datetime.now() – datetime.fromisoformat(dormant_since)
).days
if days_dormant >= self.DEPRECATION_GRACE_PERIOD:
self._transition_to_deprecated(skill["skill_id"], "long_dormant")
return
# 检查是否被更高版本的Skill替代
newer_version = self.skill_index.find_newer_version(skill["skill_id"])
if newer_version:
self._transition_to_deprecated(
skill["skill_id"], "version_upgrade",
replacement=newer_version
)
def _check_archive(self, skill: dict):
"""检查淘汰状态的Skill是否应该归档"""
deprecated_since = skill.get("deprecated_since")
if deprecated_since:
days_deprecated = (
datetime.now() – datetime.fromisoformat(deprecated_since)
).days
if days_deprecated >= self.ARCHIVE_GRACE_PERIOD:
self._transition_to_archived(skill["skill_id"])
def _transition_to_dormant(self, skill_id: str, reason: str):
"""状态转换: active → dormant"""
self.skill_index.update_status(skill_id, "dormant")
self.skill_index.update_field(skill_id, "dormant_since",
datetime.now().isoformat())
self.skill_index.update_field(skill_id, "dormancy_reason", reason)
# 暂停定时触发
self.scheduler.pause_job(skill_id)
# 通知用户
self.notifier.notify(
f"💡 Skill「{skill_id}」已进入休眠状态(原因: {reason})。"
f"下次需要时将自动重新激活。"
)
def _transition_to_deprecated(self, skill_id: str, reason: str,
replacement: str = None):
"""状态转换: dormant → deprecated"""
self.skill_index.update_status(skill_id, "deprecated")
self.skill_index.update_field(skill_id, "deprecated_since",
datetime.now().isoformat())
self.skill_index.update_field(skill_id, "deprecation_reason", reason)
if replacement:
self.skill_index.update_field(skill_id, "replaced_by", replacement)
self.notifier.notify(
f"⚠️ Skill「{skill_id}」已被标记为淘汰(原因: {reason})。"
f"将在30天后归档。如需保留,请手动恢复。"
)
def _transition_to_archived(self, skill_id: str):
"""状态转换: deprecated → archived"""
self.skill_index.update_status(skill_id, "archived")
self.skill_index.update_field(skill_id, "archived_since",
datetime.now().isoformat())
# 移动文件到归档目录
self.file_store.archive_skill(skill_id)
# 从活跃索引移除,添加到归档索引
self.skill_index.move_to_archive(skill_id)
def reactivate(self, skill_id: str) –> bool:
"""手动重新激活Skill"""
skill = self.skill_index.get(skill_id)
if not skill:
return False
if skill["status"] not in ("dormant", "deprecated"):
return False
self.skill_index.update_status(skill_id, "active")
self.skill_index.update_field(skill_id, "dormant_since", None)
self.skill_index.update_field(skill_id, "deprecated_since", None)
# 恢复定时触发
if skill.get("schedule"):
self.scheduler.resume_job(skill_id)
# 质量评分衰减
metrics = self.quality_store.get_metrics(skill_id)
if metrics and metrics.get("quality_score"):
metrics["quality_score"] *= 0.8
self.quality_store.update_metrics(skill_id, metrics)
return True
6.6 生命周期状态转换日志
# Skill生命周期状态转换日志示例
lifecycle_log:
skill_id: "format_json_v1.0.0"
transitions:
– transition_id: trans_001
from: draft
to: validating
timestamp: "2026-07-05T11:00:22+08:00"
trigger: submit_for_validation
details:
validation_started: true
– transition_id: trans_002
from: validating
to: active
timestamp: "2026-07-05T11:00:38+08:00"
trigger: validation_passed
details:
syntax_validation: passed
behavior_validation: passed
security_validation: passed
quality_metrics_initialized: true
– transition_id: trans_003
from: active
to: dormant
timestamp: "2026-08-15T10:00:00+08:00"
trigger: dormancy_check
details:
reason: long_unused
days_since_last_call: 31
threshold: 30
scheduler_paused: true
– transition_id: trans_004
from: dormant
to: active
timestamp: "2026-08-20T14:30:00+08:00"
trigger: reactivation
details:
reason: skill_called
quality_score_adjusted: 0.92 → 0.736
scheduler_resumed: true
6.7 特殊生命周期场景
6.7.1 版本升级场景
当一个Skill的新版本被创建并激活时,旧版本自动进入淘汰流程:
场景: format_json 从 v1.0.0 升级到 v1.1.0
1. 新版本 v1.1.0 通过验证,状态变更为 active
2. 系统检测到 v1.0.0 和 v1.1.0 功能重叠
3. v1.0.0 自动转换: active → deprecated
– deprecation_reason: version_upgrade
– replaced_by: format_json_v1.1.0
4. v1.0.0 进入30天宽限期
5. 宽限期结束后: deprecated → archived
6. 所有调用自动路由到 v1.1.0
6.7.2 冲突合并场景
当两个功能重叠的Skill被检测到时,系统会自动合并:
场景: format_json 和 pretty_print_json 功能重叠
1. 冲突检测器发现两个Skill的语义相似度 > 0.90
2. 质量评估:
– format_json: quality_score = 0.92, calls = 42
– pretty_print_json: quality_score = 0.75, calls = 8
3. 决策: 保留 format_json(质量更高、调用更多)
4. pretty_print_json 转换: active → deprecated
– deprecation_reason: conflict_merge
– merged_into: format_json
5. pretty_print_json 的独特功能(如自定义颜色)合并到 format_json
6. format_json 版本升级: v1.2.0 → v1.3.0
6.8 本章小结
本章详细描述了Skill生命周期的六个状态(草稿、验证中、激活、休眠、淘汰、归档)及其之间的转换条件。生命周期管理器通过定期检查自动驱动状态转换,确保活跃的Skill库保持精简高效。特殊的版本升级和冲突合并场景通过自动化流程处理,减少了用户的手动干预需求。每个状态转换都记录详细的日志,确保生命周期管理的可追溯性。
第七章 Skill质量评估与淘汰机制
7.1 质量评估模型
Skill质量评估模型从四个维度对Skill进行综合量化评估,形成0.0~1.0的质量评分。该评分直接影响Skill的生命周期决策(是否休眠、是否淘汰)和检索优先级。
7.2 质量评估模型架构图
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 质量评估模型 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 调用成功率 │ │ 用户满意度 │ │ 执行效率 │ │ 复用频率 │ │
│ │ SuccessRate │ │ Satisfaction │ │ Efficiency │ │ ReuseFreq │ │
│ ├─────────────┤ ├─────────────┤ ├─────────────┤ ├─────────────┤ │
│ │ 权重: 0.35 │ │ 权重: 0.25 │ │ 权重: 0.20 │ │ 权重: 0.20 │ │
│ │ │ │ │ │ │ │ │ │
│ │ 成功调用次数 │ │ 用户反馈 │ │ 平均执行 │ │ 30天调用 │ │
│ │ / 总调用次数 │ │ 满意/不满意 │ │ 时间 vs │ │ 次数趋势 │ │
│ │ │ │ 比率 │ │ 基准时间 │ │ │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ └────────────────┴────────┬───────┴────────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 加权综合评分 │ │
│ │ Quality Score │ │
│ │ 0.0 ~ 1.0 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌──────────────┼──────────────┐ │
│ │ │ │ │
│ ≥ 0.8: 优秀 0.5~0.8: 正常 < 0.5: 需关注 │
│ 保持激活 保持激活 触发质量警告 │
│ │
│ < 0.3 持续14天 → 触发休眠 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
7.3 质量评估维度详解
7.3.1 调用成功率(权重0.35)
class SuccessRateCalculator:
"""调用成功率计算器"""
def calculate(self, skill_id: str) –> float:
"""
计算Skill的调用成功率
成功率 = 成功调用次数 / 总调用次数
特殊处理:
– 总调用次数 < 5时,成功率设为1.0(数据不足,给初始信任)
– 考虑时间衰减:近期调用权重更高
"""
call_history = self.history_store.get_calls(skill_id, days=30)
if len(call_history) < 5:
return 1.0 # 数据不足,给予初始信任
# 时间加权成功率
weighted_success = 0.0
weighted_total = 0.0
for call in call_history:
days_ago = (datetime.now() – call.timestamp).days
weight = max(0.1, 1.0 – days_ago * 0.03) # 时间衰减权重
weighted_total += weight
if call.success:
weighted_success += weight
return weighted_success / weighted_total if weighted_total > 0 else 0.0
7.3.2 用户满意度(权重0.25)
class SatisfactionCalculator:
"""用户满意度计算器"""
def calculate(self, skill_id: str) –> float:
"""
计算Skill的用户满意度
满意度信号来源:
1. 显式反馈: 用户对Skill执行结果的满意/不满意标记
2. 隐式信号:
– Skill执行后用户继续对话(满意)
– Skill执行后用户立即要求重新执行(不满意)
– Skill执行后用户修改结果(部分满意)
"""
explicit_feedback = self.feedback_store.get_feedback(skill_id, days=30)
implicit_signals = self.signal_store.get_signals(skill_id, days=30)
# 显式反馈
if explicit_feedback:
satisfied = sum(1 for f in explicit_feedback if f.satisfied)
explicit_score = satisfied / len(explicit_feedback)
else:
explicit_score = None
# 隐式信号
if implicit_signals:
positive_signals = sum(1 for s in implicit_signals
if s.type == "positive")
negative_signals = sum(1 for s in implicit_signals
if s.type == "negative")
neutral_signals = sum(1 for s in implicit_signals
if s.type == "neutral")
total = len(implicit_signals)
implicit_score = (
(positive_signals + 0.5 * neutral_signals) / total
if total > 0 else 0.5
)
else:
implicit_score = None
# 综合评分
if explicit_score is not None and implicit_score is not None:
return 0.6 * explicit_score + 0.4 * implicit_score
elif explicit_score is not None:
return explicit_score
elif implicit_score is not None:
return implicit_score
else:
return 0.5 # 无数据时中性评分
7.3.3 执行效率(权重0.20)
class EfficiencyCalculator:
"""执行效率计算器"""
def calculate(self, skill_id: str) –> float:
"""
计算Skill的执行效率
效率评分 = 基准时间 / 实际平均执行时间
评分限制在0.0~1.0之间
"""
call_history = self.history_store.get_calls(skill_id, days=30)
if not call_history:
return 0.5
# 计算平均执行时间
avg_time = sum(c.duration_ms for c in call_history) / len(call_history)
# 获取基准时间(Skill定义中的max_execution_time)
skill_def = self.skill_store.get_definition(skill_id)
benchmark_time = skill_def.constraints.max_execution_time
# 效率评分
efficiency = benchmark_time / avg_time if avg_time > 0 else 1.0
# 限制在0.0~1.0
return min(max(efficiency, 0.0), 1.0)
7.3.4 复用频率(权重0.20)
class ReuseFrequencyCalculator:
"""复用频率计算器"""
def calculate(self, skill_id: str) –> float:
"""
计算Skill的复用频率
复用频率评分基于:
1. 30天调用次数
2. 调用趋势(上升/稳定/下降)
3. 调用间隔的规律性
"""
call_history = self.history_store.get_calls(skill_id, days=30)
if not call_history:
return 0.0
# 维度1: 调用次数评分
call_count = len(call_history)
count_score = min(call_count / 30, 1.0) # 30次/月为满分
# 维度2: 趋势评分
recent_7_days = [c for c in call_history
if (datetime.now() – c.timestamp).days <= 7]
previous_7_days = [c for c in call_history
if 7 < (datetime.now() – c.timestamp).days <= 14]
recent_count = len(recent_7_days)
previous_count = len(previous_7_days)
if previous_count == 0:
trend_score = 1.0 if recent_count > 0 else 0.0
else:
ratio = recent_count / previous_count
if ratio >= 1.0:
trend_score = min(ratio, 1.5) / 1.5 # 上升趋势
else:
trend_score = ratio * 0.8 # 下降趋势,打折扣
# 维度3: 规律性评分
if len(call_history) >= 5:
intervals = []
sorted_calls = sorted(call_history, key=lambda c: c.timestamp)
for i in range(1, len(sorted_calls)):
interval = (sorted_calls[i].timestamp –
sorted_calls[i–1].timestamp).total_seconds()
intervals.append(interval)
avg_interval = sum(intervals) / len(intervals)
variance = sum((i – avg_interval) ** 2 for i in intervals) / len(intervals)
std_dev = variance ** 0.5
if avg_interval > 0:
cv = std_dev / avg_interval # 变异系数
regularity_score = max(0.0, 1.0 – cv)
else:
regularity_score = 0.5
else:
regularity_score = 0.5
# 加权综合
return (0.5 * count_score + 0.3 * trend_score + 0.2 * regularity_score)
7.4 综合质量评分
class QualityAssessor:
"""Skill质量综合评估器"""
WEIGHTS = {
"success_rate": 0.35,
"satisfaction": 0.25,
"efficiency": 0.20,
"reuse_freq": 0.20
}
def assess(self, skill_id: str) –> QualityAssessment:
"""执行综合质量评估"""
# 计算各维度评分
scores = {
"success_rate": self.success_calc.calculate(skill_id),
"satisfaction": self.satisfaction_calc.calculate(skill_id),
"efficiency": self.efficiency_calc.calculate(skill_id),
"reuse_freq": self.reuse_calc.calculate(skill_id)
}
# 加权综合
quality_score = sum(
scores[dim] * self.WEIGHTS[dim] for dim in self.WEIGHTS
)
# 质量等级
if quality_score >= 0.8:
grade = "excellent"
elif quality_score >= 0.6:
grade = "good"
elif quality_score >= 0.4:
grade = "fair"
elif quality_score >= 0.2:
grade = "poor"
else:
grade = "critical"
# 记录评估历史
assessment = QualityAssessment(
skill_id=skill_id,
timestamp=datetime.now(),
scores=scores,
quality_score=quality_score,
grade=grade
)
self.quality_store.record_assessment(assessment)
return assessment
7.5 质量评估报告示例
{
"skill_id": "format_json_v1.2.0",
"assessment_timestamp": "2026-07-05T18:00:00+08:00",
"quality_score": 0.92,
"grade": "excellent",
"dimension_scores": {
"success_rate": {
"score": 0.95,
"weight": 0.35,
"weighted": 0.3325,
"details": {
"total_calls_30d": 18,
"successful_calls": 17,
"failed_calls": 1,
"failure_reason": "invalid_json_input",
"time_weighted": true
}
},
"satisfaction": {
"score": 0.88,
"weight": 0.25,
"weighted": 0.22,
"details": {
"explicit_feedback": 5,
"satisfied": 4,
"dissatisfied": 1,
"implicit_positive": 8,
"implicit_negative": 1,
"implicit_neutral": 4
}
},
"efficiency": {
"score": 0.96,
"weight": 0.20,
"weighted": 0.192,
"details": {
"avg_execution_ms": 108,
"benchmark_ms": 5000,
"p50_ms": 95,
"p95_ms": 180,
"p99_ms": 250
}
},
"reuse_freq": {
"score": 0.90,
"weight": 0.20,
"weighted": 0.18,
"details": {
"calls_30d": 18,
"calls_7d": 5,
"calls_prev_7d": 4,
"trend": "increasing",
"trend_ratio": 1.25,
"regularity_cv": 0.35
}
}
},
"recommendation": "keep_active",
"alerts": []
}
7.6 Skill淘汰机制
7.6.1 淘汰机制总览
| 低频淘汰 | 30天未调用(频次触发)/ 60天(自修复)/ 45天(纠正) | active → dormant → deprecated → archived | 90+30天 | 是(归档前) |
| 冲突合并 | 与另一Skill语义相似度>0.90 | 质量低的淘汰,功能合并到质量高的 | 30天 | 是(归档前) |
| 版本升级 | 同名Skill更高版本被激活 | 旧版本自动淘汰 | 30天 | 否 |
| 质量淘汰 | 质量评分<0.3持续14天 | active → dormant → deprecated | 90+30天 | 是(归档前) |
| 用户删除 | 用户手动删除 | 直接归档 | 无 | 否 |
7.6.2 冲突检测与合并
class ConflictDetector:
"""Skill冲突检测器"""
SIMILARITY_THRESHOLD = 0.90
def detect_conflicts(self) –> list:
"""检测所有Skill之间的冲突"""
all_skills = self.skill_index.get_all_active()
conflicts = []
for i, skill_a in enumerate(all_skills):
for skill_b in all_skills[i+1:]:
similarity = self._calculate_similarity(skill_a, skill_b)
if similarity >= self.SIMILARITY_THRESHOLD:
conflicts.append(Conflict(
skill_a=skill_a,
skill_b=skill_b,
similarity=similarity,
resolution=self._determine_resolution(skill_a, skill_b)
))
return conflicts
def _calculate_similarity(self, skill_a: dict, skill_b: dict) –> float:
"""计算两个Skill之间的相似度"""
# 1. 语义嵌入向量余弦相似度(权重0.5)
embedding_sim = self._cosine_similarity(
skill_a["semantic_embedding"],
skill_b["semantic_embedding"]
)
# 2. 标签重叠度(权重0.2)
tag_sim = len(set(skill_a["tags"]) & set(skill_b["tags"])) / \\
len(set(skill_a["tags"]) | set(skill_b["tags"]))
# 3. 分类一致性(权重0.15)
category_sim = 1.0 if skill_a["category"] == skill_b["category"] else 0.0
# 4. 工具名称相似度(权重0.15)
tool_name_sim = self._name_similarity(
skill_a["name"], skill_b["name"]
)
return (0.5 * embedding_sim + 0.2 * tag_sim +
0.15 * category_sim + 0.15 * tool_name_sim)
def _determine_resolution(self, skill_a: dict, skill_b: dict) –> dict:
"""确定冲突解决策略"""
# 比较质量评分
score_a = skill_a.get("quality_score") or 0.5
score_b = skill_b.get("quality_score") or 0.5
# 比较调用次数
calls_a = skill_a.get("call_count_30d", 0)
calls_b = skill_b.get("call_count_30d", 0)
# 综合决策
composite_a = 0.6 * score_a + 0.4 * min(calls_a / 30, 1.0)
composite_b = 0.6 * score_b + 0.4 * min(calls_b / 30, 1.0)
if composite_a >= composite_b:
return {
"keep": skill_a["skill_id"],
"deprecate": skill_b["skill_id"],
"reason": "higher_quality_and_usage"
}
else:
return {
"keep": skill_b["skill_id"],
"deprecate": skill_a["skill_id"],
"reason": "higher_quality_and_usage"
}
7.6.3 版本升级机制
class VersionUpgrader:
"""Skill版本升级管理器"""
def check_and_upgrade(self, new_skill: SkillDefinition) –> UpgradeResult:
"""检查新Skill是否是已有Skill的升级版本"""
# 查找同名Skill
existing = self.skill_index.find_by_name(new_skill.name)
if not existing:
return UpgradeResult(action="create_new")
# 比较版本号
if self._version_compare(new_skill.version, existing["version"]) <= 0:
return UpgradeResult(
action="reject",
reason="version_not_higher"
)
# 确定升级类型
upgrade_type = self._determine_upgrade_type(
existing["version"], new_skill.version
)
# 执行升级
if upgrade_type == "patch":
# 补丁升级:仅小修复,直接替换
self._replace_skill(existing, new_skill)
elif upgrade_type == "minor":
# 次要升级:新功能,旧版本进入淘汰
self._deprecate_old(existing, new_skill)
elif upgrade_type == "major":
# 主要升级:重大变更,需要用户确认
return UpgradeResult(
action="require_user_confirmation",
old_version=existing["version"],
new_version=new_skill.version
)
return UpgradeResult(
action="upgraded",
old_version=existing["version"],
new_version=new_skill.version,
upgrade_type=upgrade_type
)
def _determine_upgrade_type(self, old_ver: str, new_ver: str) –> str:
"""确定升级类型"""
old_parts = [int(x) for x in old_ver.split(".")]
new_parts = [int(x) for x in new_ver.split(".")]
if new_parts[0] > old_parts[0]:
return "major"
elif new_parts[1] > old_parts[1]:
return "minor"
else:
return "patch"
7.7 淘汰决策配置
# Skill淘汰机制配置
deprecation_config:
low_frequency:
enabled: true
thresholds:
frequency: 30 # 频次触发Skill: 30天未调用
self_heal: 60 # 自修复触发Skill: 60天未调用
user_correction: 45 # 用户纠正触发Skill: 45天未调用
manual: 90 # 手动创建Skill: 90天未调用
action: dormant
low_quality:
enabled: true
threshold: 0.3
duration_days: 14
action: dormant
conflict_merge:
enabled: true
similarity_threshold: 0.90
resolution: auto # auto / manual
action: deprecate
version_upgrade:
enabled: true
patch: replace # 补丁升级: 直接替换
minor: deprecate # 次要升级: 旧版淘汰
major: confirm # 主要升级: 需用户确认
action: deprecate
user_delete:
enabled: true
action: archive_immediately
grace_periods:
dormant_to_deprecated: 90 # 休眠90天后淘汰
deprecated_to_archived: 30 # 淘汰30天后归档
recovery:
allow_recovery: true
recovery_before: archived # 归档前可恢复
quality_decay: 0.8 # 恢复时质量评分乘以0.8
7.8 质量监控看板数据
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 质量监控看板(示例) │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 总览统计: │
│ ┌────────────┬────────────┬────────────┬────────────┐ │
│ │ 总Skill数 │ 激活Skill │ 休眠Skill │ 淘汰/归档 │ │
│ │ 27 │ 22 │ 3 │ 2 │ │
│ └────────────┴────────────┴────────────┴────────────┘ │
│ │
│ 质量分布: │
│ 优秀(≥0.8): ████████████████ 14个 (63.6%) │
│ 良好(0.6~0.8): ████████ 6个 (27.3%) │
│ 一般(0.4~0.6): ██ 2个 (9.1%) │
│ 较差(<0.4): 0个 (0.0%) │
│ │
│ Top 5 高质量Skill: │
│ 1. format_json | 0.92 | 调用42次 | 频次触发 │
│ 2. code_review | 0.89 | 调用28次 | 频次触发 │
│ 3. api_retry_handler | 0.87 | 调用15次 | 自修复触发 │
│ 4. daily_report_gen | 0.85 | 调用30次 | 手动创建 │
│ 5. language_pref_zh | 0.83 | 调用∞次 | 用户纠正触发 │
│ │
│ 质量警告: │
│ ⚠️ csv_parser | 质量评分 0.35 | 成功率 0.60 | 建议检查 │
│ │
│ 待处理淘汰: │
│ 📋 old_json_formatter | 休眠95天 | 即将淘汰 │
│ 📋 temp_data_cleaner | 休眠88天 | 接近淘汰阈值 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
7.9 本章小结
本章详细阐述了Skill质量评估模型的四个维度(调用成功率、用户满意度、执行效率、复用频率)及其加权计算方法,并描述了五种淘汰机制(低频淘汰、冲突合并、版本升级、质量淘汰、用户删除)的触发条件和处理流程。质量评估和淘汰机制共同确保了Skill库的持续健康——高质量Skill保持活跃,低质量Skill自然淘汰,功能重叠的Skill自动合并,形成了一个自我进化的技能生态系统。
第八章 Skill与记忆系统交互及竞品对比
8.1 Skill与记忆系统的交互架构
Skill系统作为Hermes Agent五层记忆架构中的L4技能记忆层,与其它记忆层之间存在着密切的交互关系。这种交互不是简单的数据存取,而是一个动态的、双向的信息流动过程。
┌─────────────────────────────────────────────────────────────────────────────┐
│ Skill 与记忆系统交互架构 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────────────┐ │
│ │ L1 工作记忆层 │ │
│ │ ┌─────────────────────────────────────────────────────┐ │ │
│ │ │ • 当前对话上下文 │ │ │
│ │ │ • 活跃的Skill定义副本(按需加载) │ │ │
│ │ │ • Skill执行中间状态 │ │ │
│ │ └──────────────────────┬──────────────────────────────┘ │ │
│ │ ↑ 加载Skill ↑ 写入执行状态 │ │
│ └───────────┼─────────────┼─────────────────────────────────────────┘ │
│ │ │ │
│ ┌───────────┼─────────────┼─────────────────────────────────────────┐ │
│ │ L2 短期记忆层 │ │ │
│ │ ┌──────────────────────▼──────────────────────────────┐ │ │
│ │ │ • 近期Skill调用历史(7天) │ │ │
│ │ │ • 操作模式临时存储(等待频次检测) │ │ │
│ │ │ • 错误-修复链路临时存储(等待自修复检测) │ │ │
│ │ │ • 用户纠正语句临时存储(等待语义分析) │ │ │
│ │ └──────────────────────┬──────────────────────────────┘ │ │
│ │ ↑ 写入模式数据 ↑ 读取历史调用 │ │
│ └───────────┼─────────────┼─────────────────────────────────────────┘ │
│ │ │ │
│ ┌───────────┼─────────────┼─────────────────────────────────────────┐ │
│ │ L3 长期记忆层 │ │ │
│ │ ┌──────────────────────▼──────────────────────────────┐ │ │
│ │ │ • 用户画像(影响Skill个性化) │ │ │
│ │ │ • 长期偏好(用户纠正触发的规则来源) │ │ │
│ │ │ • 项目知识库(Skill执行的数据来源) │ │ │
│ │ │ • 历史决策记录(Skill版本升级参考) │ │ │
│ │ └──────────────────────┬──────────────────────────────┘ │ │
│ │ ↑ 读取用户偏好 ↑ 写入Skill决策 │ │
│ └───────────┼─────────────┼─────────────────────────────────────────┘ │
│ │ │ │
│ ┌───────────┼─────────────┼─────────────────────────────────────────┐ │
│ │ L4 技能记忆层 ★ │ │ │
│ │ ┌──────────────────────▼──────────────────────────────┐ │ │
│ │ │ • Skill全局索引 │ │ │
│ │ │ • SKILL.md文件 │ │ │
│ │ │ • 执行脚本 │ │ │
│ │ │ • 测试用例 │ │ │
│ │ │ • 验证报告 │ │ │
│ │ │ • 质量指标数据 │ │ │
│ │ │ • 调用历史记录 │ │ │
│ │ │ • 生命周期状态 │ │ │
│ │ └──────────────────────┬──────────────────────────────┘ │ │
│ │ ↑ 存储Skill ↑ 加载Skill │ │
│ └───────────┼─────────────┼─────────────────────────────────────────┘ │
│ │ │ │
│ ┌───────────┼─────────────┼─────────────────────────────────────────┐ │
│ │ L5 元认知层 │ │ │
│ │ ┌──────────────────────▼──────────────────────────────┐ │ │
│ │ │ • Skill组合策略(多个Skill如何协作) │ │ │
│ │ │ • 进化策略(Skill系统整体的进化方向) │ │ │
│ │ │ • 跨Skill知识迁移规则 │ │ │
│ │ │ • Skill系统元规则(何时创建/淘汰/合并) │ │ │
│ │ └─────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
8.2 L4技能记忆层的存储设计
8.2.1 Skill索引设计
L4层的核心数据结构是Skill全局索引,它支持高效的语义检索和状态过滤:
class SkillIndex:
"""L4技能记忆层 – Skill全局索引"""
INDEX_SCHEMA = {
# 主键
"skill_id": "string (PK)",
# 基本信息
"name": "string (indexed)",
"display_name": "string",
"version": "string (indexed)",
"description_summary": "string (full-text indexed)",
# 状态信息
"status": "enum (indexed)",
"trigger_source": "enum (indexed)",
"category": "string (indexed)",
"tags": "array<string> (indexed)",
"priority": "enum (indexed)",
# 质量信息
"quality_score": "float (indexed, sortable)",
"call_count_30d": "integer (sortable)",
"last_called": "datetime (indexed, sortable)",
# 语义检索
"semantic_embedding": "vector<float, 768> (vector indexed)",
# 文件路径
"skill_path": "string",
"script_path": "string",
"metadata_path": "string",
# 生命周期
"created_at": "datetime",
"updated_at": "datetime",
"dormant_since": "datetime (nullable)",
"deprecated_since": "datetime (nullable)",
"archived_since": "datetime (nullable)",
# 关系
"replaced_by": "string (nullable)",
"merged_into": "string (nullable)",
"depends_on": "array<string> (nullable)"
}
def search(self, query: str,
filters: dict = None,
top_k: int = 5) –> list:
"""
语义搜索Skill
参数:
query: 自然语言查询
filters: 过滤条件(状态、分类、标签等)
top_k: 返回结果数量
"""
# 1. 生成查询的语义嵌入
query_embedding = self.embedding_model.encode(query)
# 2. 构建过滤条件
base_filter = {"status": "active"} # 默认只搜索活跃Skill
if filters:
base_filter.update(filters)
# 3. 向量检索 + 条件过滤
results = self.vector_store.search(
embedding=query_embedding,
filter=base_filter,
top_k=top_k * 2 # 多取一些用于重排序
)
# 4. 重排序:综合语义相似度和质量评分
for result in results:
result.final_score = (
0.7 * result.similarity_score +
0.3 * (result.quality_score or 0.5)
)
results.sort(key=lambda r: r.final_score, reverse=True)
return results[:top_k]
8.2.2 按需加载机制
class OnDemandLoader:
"""Skill按需加载器"""
MAX_LOADED_SKILLS = 5 # L1工作记忆中最多同时加载5个Skill
def __init__(self):
self.skill_index = SkillIndex()
self.loaded_skills = OrderedDict() # LRU缓存
def load(self, skill_id: str) –> SkillDefinition:
"""按需加载Skill定义到L1工作记忆"""
# 检查是否已加载
if skill_id in self.loaded_skills:
self.loaded_skills.move_to_end(skill_id)
return self.loaded_skills[skill_id]
# 从L4加载
skill_entry = self.skill_index.get(skill_id)
if not skill_entry:
raise SkillNotFoundError(skill_id)
if skill_entry["status"] != "active":
raise SkillNotActiveError(skill_id, skill_entry["status"])
# 加载SKILL.md
skill_md = self.file_store.read(skill_entry["skill_path"])
# 加载执行脚本
script = self.file_store.read(skill_entry["script_path"])
# 解析Skill定义
skill_def = self.parser.parse(skill_md, script)
# 存入LRU缓存
self.loaded_skills[skill_id] = skill_def
# LRU淘汰
while len(self.loaded_skills) > self.MAX_LOADED_SKILLS:
evicted_id, _ = self.loaded_skills.popitem(last=False)
logger.info(f"Evicted skill from L1: {evicted_id}")
return skill_def
def unload(self, skill_id: str):
"""从L1工作记忆中卸载Skill"""
if skill_id in self.loaded_skills:
del self.loaded_skills[skill_id]
8.3 跨记忆层交互流程
8.3.1 Skill执行时的记忆交互
Skill执行时的记忆交互流程:
1. 用户输入 → L1工作记忆
"帮我格式化这段JSON"
2. L1 → L4: 语义检索Skill
查询: "JSON格式化"
L4返回: format_json (相似度0.95, 质量评分0.92)
3. L4 → L1: 按需加载Skill
加载format_json的SKILL.md和执行脚本到L1
4. L1 → L3: 读取用户偏好
检查用户是否有格式偏好(如indent=4)
L3返回: 用户偏好 indent=4
5. L1: 执行Skill
使用format_json执行,参数: input=用户JSON, indent=4
6. L1 → L2: 记录调用
记录: format_json被调用, 成功, 耗时85ms
7. L1 → L4: 更新质量指标
更新: call_count++, last_called=now, success=true
8. L1 → L4: 检查触发条件
检查: 是否有新的操作模式需要沉淀为Skill
9. L1: 返回结果给用户
8.3.2 Skill生成时的记忆交互
Skill生成时的记忆交互流程(频次触发):
1. L2 → 触发检测: 操作模式达到频次阈值
L2中存储的5次操作模式签名匹配
2. 触发检测 → L4: 查询是否已有同类Skill
L4返回: 无同类Skill
3. L2 → 发现阶段: 收集操作历史
从L2读取5次操作的详细信息
4. L3 → 提炼阶段: 读取用户画像
检查用户偏好,影响Skill参数默认值
5. L4 → 注册阶段: 写入Skill索引
将新Skill的元数据写入L4索引
6. L4 → 激活阶段: 初始化质量指标
在L4中创建质量指标记录
7. L5 → 元认知更新: 记录Skill创建策略
L5记录: 频次触发创建format_json, 策略有效
8. L1 → 用户通知
轻量提示用户新Skill已创建
8.4 Skill索引的性能优化
# L4 Skill索引性能优化配置
index_optimization:
# 向量索引
vector_index:
type: hnsw # 近似最近邻搜索
m: 16 # 连接数
ef_construction: 200
ef_search: 50
dimensions: 768
# 缓存策略
cache:
l1_loaded_skills:
max_size: 5
eviction: lru
l4_index_cache:
max_size: 100
ttl: 3600
# 索引分片
sharding:
strategy: by_category # 按分类分片
shard_count: 8
# 定期维护
maintenance:
rebuild_index: 7d # 每7天重建索引
compact_storage: 3d # 每3天压缩存储
update_embeddings: 30d # 每30天更新语义嵌入
8.5 竞品对比
8.5.1 与Claude Code无Skill系统的对比
| 技能积累 | 自动发现 + 手动创建 | 不支持 |
| 触发机制 | 四种自动触发 + 手动 | N/A |
| 技能复用 | 语义检索 + 按需加载 | 每次重新推理 |
| 验证体系 | 三级验证 | N/A |
| 生命周期管理 | 完整状态机 | N/A |
| 质量评估 | 四维模型 | N/A |
| 淘汰机制 | 自动淘汰 | N/A |
| 记忆层集成 | L4技能记忆层 | N/A |
| 个性化 | 基于用户行为模式 | 无 |
| 推理效率 | 高(复用已有Skill) | 低(每次重新推理) |
| 优势 | 自进化、高效率、个性化 | 简单、无管理开销 |
| 劣势 | 系统复杂度高 | 无法积累经验、效率低 |
深度分析:Claude Code作为Anthropic的代码助手,其设计哲学侧重于"每次交互都是独立的推理过程",不积累可复用的操作模式。这种设计的优势在于简单——无需管理Skill的生命周期和质量,但也意味着Claude Code无法从用户的重复操作中学习,每次执行相同任务都需要完整的推理链路。Hermes Agent的Skill系统通过将重复操作沉淀为Skill,显著降低了推理开销,同时通过完整的验证和淘汰机制确保了Skill库的质量。
8.5.2 与Cursor无Skill系统的对比
| 技能积累 | 自动发现 + 手动创建 | 不支持(依赖代码库上下文) |
| 触发机制 | 四种自动触发 + 手动 | N/A |
| 技能复用 | 语义检索 + 按需加载 | 依赖代码索引和上下文窗口 |
| 验证体系 | 三级验证 | N/A |
| 生命周期管理 | 完整状态机 | N/A |
| 质量评估 | 四维模型 | N/A |
| 淘汰机制 | 自动淘汰 | N/A |
| 记忆层集成 | L4技能记忆层 | 无独立记忆层 |
| 个性化 | 基于用户行为模式 | 基于项目上下文 |
| 推理效率 | 高(Skill复用) | 中(依赖上下文窗口大小) |
| 优势 | 自进化、跨项目复用 | 项目内上下文丰富 |
| 劣势 | 系统复杂度高 | 无法跨项目积累经验 |
深度分析:Cursor作为AI代码编辑器,其优势在于对当前项目代码库的深度理解——通过代码索引和上下文窗口提供精准的代码补全和编辑建议。然而Cursor缺乏跨项目的技能积累能力,每次切换项目都需要重新建立上下文。Hermes Agent的Skill系统通过L4技能记忆层实现了跨项目的技能复用,一个在项目A中沉淀的Skill(如代码格式化、API测试模板)可以在项目B中直接使用。
8.5.3 与OpenClaw手动Skill系统的对比
| 技能积累 | 自动发现 + 手动创建 | 仅手动创建 |
| 触发机制 | 四种自动触发 + 手动 | 仅手动触发 |
| 技能复用 | 语义检索 + 按需加载 | 手动调用或@引用 |
| 验证体系 | 三级验证(语法+行为+安全) | 基本格式检查 |
| 生命周期管理 | 完整状态机(6个状态) | 简单(启用/禁用) |
| 质量评估 | 四维模型(自动评估) | 无自动评估 |
| 淘汰机制 | 自动淘汰(5种机制) | 仅手动删除 |
| 记忆层集成 | L4技能记忆层 | 文件系统存储 |
| 个性化 | 自动适应用户行为 | 取决于用户编写质量 |
| 推理效率 | 高(自动匹配+复用) | 中(需用户知道使用哪个Skill) |
| 优势 | 全自动化、自进化 | 用户完全控制 |
| 劣势 | 系统复杂、需要信任自动生成 | 依赖用户主动性、积累慢 |
深度分析:OpenClaw的手动Skill系统代表了"用户完全控制"的设计哲学——用户需要显式编写每个Skill,显式决定何时使用哪个Skill。这种设计的优势在于用户对系统行为有完全的可控性和可预测性,但劣势也很明显:技能积累速度极慢(完全依赖用户主动性),缺乏质量保证(用户编写的Skill可能存在错误或安全风险),且无法适应用户行为的变化。Hermes Agent的Skill系统通过四种自动触发机制大幅提升了技能积累速度,同时通过三级验证确保了自动生成Skill的质量和安全性。
8.5.4 综合对比表
| 技能获取 | 自动+手动 | 无 | 无 | 仅手动 |
| 触发条件数 | 4种 | 0 | 0 | 1种(手动) |
| 验证层级 | 3级 | N/A | N/A | 1级(基本) |
| 生命周期状态 | 6个 | N/A | N/A | 2个 |
| 质量评估维度 | 4个 | N/A | N/A | 0 |
| 淘汰机制数 | 5种 | N/A | N/A | 1种(手动) |
| 记忆层集成 | L4(5层架构) | 无 | 无 | 文件系统 |
| 语义检索 | 支持 | N/A | N/A | 不支持 |
| 按需加载 | 支持 | N/A | N/A | 全量加载 |
| 自进化能力 | 有 | 无 | 无 | 无 |
| 个性化程度 | 高 | 低 | 中 | 低 |
| 系统复杂度 | 高 | 低 | 低 | 中 |
| 用户控制度 | 中(可干预) | N/A | N/A | 高 |
| 安全性 | 高(三级验证) | N/A | N/A | 中(基本检查) |
8.6 Hermes Agent Skill系统的创新点总结
┌─────────────────────────────────────────────────────────────────────────────┐
│ Hermes Agent Skill系统创新点总结 │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 四维触发条件体系(创新度: ★★★★★) │
│ ├── 频次触发:基于操作模式签名的重复检测 │
│ ├── 自修复触发:基于错误-修复链路的自动提取 │
│ ├── 用户纠正触发:基于语义分析的偏好规则提取 │
│ └── 手动创建:完整的交互式Skill创建流程 │
│ → 竞品最多只有手动创建,Hermes实现了全场景覆盖 │
│ │
│ 2. 三级验证体系(创新度: ★★★★☆) │
│ ├── 语法验证 + 自动修复 │
│ ├── 行为验证(沙箱执行)+ 自动修复 │
│ └── 安全验证(不修复,直接阻断) │
│ → 竞品最多只有基本格式检查 │
│ │
│ 3. 完整生命周期状态机(创新度: ★★★★★) │
│ ├── 6个状态:草稿→验证中→激活→休眠→淘汰→归档 │
│ ├── 自动状态转换(无需用户干预) │
│ └── 特殊场景处理(版本升级、冲突合并) │
│ → 竞品最多只有启用/禁用两个状态 │
│ │
│ 4. 四维质量评估模型(创新度: ★★★★☆) │
│ ├── 调用成功率(时间加权) │
│ ├── 用户满意度(显式+隐式信号) │
│ ├── 执行效率(基准对比) │
│ └── 复用频率(趋势分析) │
│ → 竞品无自动质量评估机制 │
│ │
│ 5. 五种淘汰机制(创新度: ★★★★★) │
│ ├── 低频淘汰(自适应阈值) │
│ ├── 冲突合并(语义相似度检测) │
│ ├── 版本升级(自动旧版淘汰) │
│ ├── 质量淘汰(持续低质量检测) │
│ └── 用户删除 │
│ → 竞品最多只有手动删除 │
│ │
│ 6. L4技能记忆层集成(创新度: ★★★★☆) │
│ ├── 五层记忆架构中的独立技能层 │
│ ├── 语义索引 + 按需加载 │
│ ├── 跨记忆层双向交互 │
│ └── LRU缓存策略 │
│ → 竞品无记忆层架构 │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
8.7 本章小结
本章从两个维度完成了Skill系统的深度分析:首先,详细描述了Skill系统与五层记忆架构的交互关系,包括L4技能记忆层的存储设计、按需加载机制和跨记忆层的信息流动流程;其次,将Hermes Agent的Skill系统与Claude Code、Cursor和OpenClaw三个竞品进行了全面对比,凸显了Hermes在自动触发、三级验证、生命周期管理、质量评估和淘汰机制方面的创新优势。Hermes Agent的Skill系统通过六个核心创新点,构建了一个完整的自进化技能管理生态,使其在AI Agent领域具备显著的技术领先性。
文档总结
核心内容回顾
本文档系统性地阐述了Hermes Agent Skill生命周期管理与触发条件体系的完整技术方案,涵盖八个核心章节:
关键技术指标
| 触发条件类型 | 4种 |
| 验证层级 | 3级 |
| 生命周期状态 | 6个 |
| 质量评估维度 | 4个 |
| 淘汰机制类型 | 5种 |
| 权限层级 | 5级 (Level 0-4) |
| 记忆层集成 | L4 (五层架构) |
| 参数类型 | 8种 |
| 最大验证重试 | 3次 |
| L1缓存Skill数 | 5个 (LRU) |



