第 2 章 · 参考库 skills-ref 逐文件走读
本章把规范“翻译成代码”看一遍。
skills-ref是个故意做得很小的 Python 库(README 标明仅供演示,skills-ref/README.md:5-6),它把第 1 章的规范落成三个动作:解析 → 校验 → 生成 prompt。模块都在skills-ref/src/skills_ref/,依赖只有click(CLI)和strictyaml(YAML)(skills-ref/pyproject.toml:11-14)。
2.0 模块全景
6 个源文件,职责清晰(skills-ref/src/skills_ref/):
| 文件 | 职责 |
|---|---|
models.py | 数据类 SkillProperties:解析结果的结构 |
parser.py | 找到并解析 SKILL.md,抽出 frontmatter |
validator.py | 校验 frontmatter 是否合规 |
prompt.py | 把多个 skill 拼成 <available_skills> XML |
errors.py | 异常层级:SkillError → ParseError / ValidationError |
cli.py | validate / read-properties / to-prompt 三个子命令 |
一条数据流(从磁盘到模型):
skill 目录 产物
┌──────────┐ find_skill_md ┌───────────────┐ read_properties ┌─────────────────┐
│ SKILL.md │ ───────────────▶ │ parse_ │ ────────────────▶ │ SkillProperties │
└──────────┘ (大小写兜底) │ frontmatter │ │ (name/desc/...) │
└───────┬────────┘ └────────┬────────┘
│ metadata dict │
▼ ▼
validate_metadata to_prompt
(返回 error 列表) <available_skills> XML
2.1 models.py:解析结果的形状
SkillProperties 是个 dataclass,把 frontmatter 的字段一一对应(skills-ref/src/skills_ref/models.py:7-26)。两个必填 + 四个可选,metadata 默认空 dict。
一个细节值得看:to_dict() 序列化时剔除 None,且 allowed_tools 这个 Python 属性名要还原成带连字符的 allowed-tools key(skills-ref/src/skills_ref/models.py:28-39):
# 示意,非源码:to_dict 的核心逻辑
result = {"name": self.name, "description": self.description}
if self.allowed_tools is not None:
result["allowed-tools"] = self.allowed_tools # 注意 key 改回连字符
if self.metadata: # 空 dict 也省略
result["metadata"] = self.metadata
重点看:Python 标识符不能带连字符,所以内部叫 allowed_tools,输出 JSON 时手动改回 allowed-tools,保证和规范字段名一致。