首页
/ openinterpreter ZCode Harness:skill-creator 技能规范与"创建-测试-迭代"工作流深度解析

openinterpreter ZCode Harness:skill-creator 技能规范与"创建-测试-迭代"工作流深度解析

2026-09-06 11:32:34作者:郁楠烈Hubert

skill-creator 是 openinterpreter 仓库 ZCode harness 内置的一个"造技能的技能"(skill for authoring skills)。本篇基于仓库中的技能定义文件 zcode_skill_creator.md 展开,完整继承其中的技能创建循环、SKILL.md 结构规范、渐进式披露(progressive disclosure)机制与迭代改进方法论,并结合 handle_zcode_skill 处理器ZCode 请求构建器 等源码,说明该技能如何被编译进二进制、如何被 Skill 工具按需加载,读者可据此掌握在本地编码 Agent 中编写、触发与持续优化可复用技能的完整方法。

一、技能定位:一个编译进二进制的内置技能

从源码结构看,skill-creator 不是放在磁盘上等待发现的普通技能,而是以 Rust include_str! 宏直接嵌入 codex-core 编译产物的内置资源:

  • 技能正文即 zcode_skill_creator.md,文件头带有 YAML frontmatter(name: skill-creator 与一段用于触发的 description);
  • harness_aliases.rs 中将其声明为常量 ZCODE_SKILL_CREATOR_MD,并配套版本常量 ZCODE_SKILL_CREATOR_VERSION: &str = "0.1.0"
  • zcode.rs 的 builtin_zcode_skills_message 会在会话的内置技能清单中向模型宣告 skill-creator:skill-creator 的存在及其用途摘要,并给出"可加载路径"(官方插件缓存目录下的 SKILL.md 路径)。

这条链路解释了文档开头那句 "A skill for authoring and iteratively improving local ZCode skills" 的工程含义:模型先通过元数据感知到技能存在,随后调用 Skill 工具触发加载,处理器再把正文注入上下文。

Skill 工具如何交付正文

handle_zcode_skill 的处理逻辑与文档中"三层加载"的说法直接对应:

  1. 解析 Skill 工具调用参数,取 skill 字段;
  2. 当值为 skill-creator 时,剥离 frontmatter(strip_prefix("---\n") 后再按 \n---\n 切分),只保留 markdown 正文;
  3. 组装返回文本:以 <skill_content name="skill-creator"> 包裹正文,并附加 "Base directory for this skill: ...",该 base directory 由 OPEN_INTERPRETER_HOME / INTERPRETER_HOME / CODEX_HOME 环境变量(缺省 ~)拼接到 .zcode/cli/plugins/cache/zcode-plugins-official/skill-creator/0.1.0/skills/skill-creator
  4. 若请求的是其他技能名,则返回 "Skill {skill} is not available through the native ZCode harness yet" 的失败提示。

也就是说,文档承诺的"元数据常駐上下文、正文按需加载"这一渐进式披露第一层到第二层的跨越,正是由这段处理器代码实现的。

二、核心循环:定位用户处于哪一环

文档开宗明义给出了工作流总纲,这也是使用该技能时最应先内化的部分。技能加载后,Agent 的职责是判断用户处于循环的哪个阶段并帮助其推进——用户说 "I want a skill for X" 就从最顶端开始;用户已持有草稿则直接跳到评估/迭代环节。文档特别强调灵活性:如果用户说 "just vibe with me, no formal evaluation",就按用户节奏来,不强行执行完整评估。

循环本体(文档 "At a high level, the loop is" 一节):

  • 弄清技能要做什么、大致怎么做(Capture intent);
  • 写出技能草稿(Write a draft);
  • 用 2–3 个贴近真实的测试 prompt 试跑(Try the skill on 2–3 realistic test prompts);
  • 与用户一起阅读输出并修改(Read the outputs with the user and revise);
  • 重复直至技能足够好(Repeat until the skill is good enough)。

文档 "The core loop, one more time" 一节再次收束为六步:搞清楚技能主题 → 起草 → 跑 2–3 个真实测试 prompt → 与用户共读结果 → 改进 → 重复直到用户满意或改进不再奏效。两端呼应是为了防止迭代过程中偏离主线。

关于与用户的沟通方式,文档还有一条常被忽视的操作准则:使用者从资深技能作者到新手都有,出现术语不确定时应简短解释而非假设对方熟悉——例如 "an eval prompt is just a test message you'd send the model to see how the skill behaves"。这条准则本质上是把"技能文档的读者"与"技能使用者的水平差异"做了显式处理。

三、创建技能:从意图捕获到 SKILL.md 结构

3.1 Capture intent(意图捕获)

文档建议:如果当前会话本身已经展示了一个值得固化的工作流(比如用户同一件事手动做了多次后说 "turn this into a skill"),应优先从会话历史中抽取答案——用过哪些工具、步骤顺序、用户做过哪些纠正、输入/输出格式——然后再就缺口向用户确认。

文档给出的四个标准问题应作为访谈清单完整保留:

  1. What should this skill enable the model to do?(这个技能要让模型能做什么?)
  2. When should it trigger? What user phrasings or contexts?(何时触发?哪些用户措辞或上下文?)
  3. What's the expected output format?(期望的输出格式是什么?)
  4. Are there example inputs/outputs to lock the behavior down?(有无可锁定行为的示例输入/输出?)

3.2 技能目录与优先级(Where skills live)

ZCode 按以下优先级(从高到低)发现技能:

<project>/.zcode/skills/<name>/SKILL.md
<project>/.agents/skills/<name>/SKILL.md
~/.zcode/skills/<name>/SKILL.md
~/.agents/skills/<name>/SKILL.md

文档给出的选型规则是:

  • 新技能默认放在 .agents/skills/ —— 这是跨工具(cross-tool)标准位置;
  • .zcode/skills 在发现阶段仍然优先:同名技能两处都存在时,.zcode/skills 副本胜出,因此 .zcode/skills 是**覆盖(override)**已存在技能的地方;
  • 只对当前仓库有意义的技能选 <project> 路径;希望处处可用的个人技能选 ~/(用户级)路径。

这一优先级模型与仓库中 session_skills.rs 解析 <skills_instructions> 块的方式相互印证:模型侧看到的可用技能清单是 - name: description (file: path) 形式,path 可为绝对路径,也可能在预算压力下呈现为 rN/... 别名路径(见该文件 L16-L26 注释与测试用例),说明发现阶段的路径解析确实发生在 harness 之下的统一 skills 层。

3.3 SKILL.md 的必备结构

每个技能是一个目录,核心是带 YAML frontmatter 的 SKILL.md

my-skill/
├── SKILL.md          (required)
└── (optional)
    ├── references/   (extra docs the model reads on demand)
    ├── scripts/      (helper scripts the model can invoke)
    └── assets/       (templates, fixtures, etc.)

frontmatter 必填字段及其约束:

  • name —— 技能标识符。小写 kebab-case,1–64 个字符,必须与目录名一致
  • description —— 技能何时触发、做什么。文档明确指出这是首要触发信号:技能"做什么"和"在什么上下文下"都应写进 description 而不是正文。还给出了一条关键反直觉经验:模型倾向于触发不足(under-trigger),所以 description 应该写得"稍微强势一点"(a little bit pushy)。文档给出的对照改写示例值得保留:
    • 弱:"How to build a dashboard for internal data"
    • 强:"How to build a fast dashboard for internal data. Use whenever the user mentions dashboards, data visualization, internal metrics, or wants to display any company data — even if they don't explicitly say 'dashboard'."

可选(预留)字段以 ZCode 技能规范为准;对多数技能,name + description 两项即够。

3.4 渐进式披露(Progressive disclosure)

ZCode 分三层加载技能,token 预算控制思路清晰:

层级 内容 加载时机 预算约束
1. 元数据 name + description 常驻上下文 必须短小
2. SKILL.md 正文 完整指令 技能被触发时 目标 500 行以内
3. 打包文件 references/scripts/assets/ 按需读取 原则上无大小限制

当正文变长时,文档给出的拆分模式是把领域细节移入 reference 文件,并让 SKILL.md 明确指示"何时去读它们":

cloud-deploy/
├── SKILL.md            (workflow + selection)
└── references/
    ├── aws.md
    ├── gcp.md
    └── azure.md

SKILL.md 中相应地写一句 "if the target is AWS, read references/aws.md before proceeding"。这套"目录即路由表"的设计正是三层加载在实操中的落法:正文充当调度器,细节延迟到确定需要时才进入上下文。

3.5 写作风格(Writing style)

文档给出四条可执行准则:

  1. 用祈使句("Read the file before editing");
  2. 解释 why:当规则不显然时说明原因——现代模型在理解理由后对指引的遵循度更高;
  3. 警惕全大写 MUST/NEVER:如果你发现自己在写一堆全大写的 MUST 和 NEVER,通常说明规则需要更好的解释,而不是更响亮的强制语气;
  4. 示例胜过规则:若技能产生结构化输出,直接给一个字面格式示例;若应使用特定工具,直接展示调用。

四、测试:2–3 个真实 prompt 的评估循环

文档对测试阶段的要求非常具体:

  • 写完草稿后,自己先想好 2–3 个真实感测试 prompt——像用户会真的输入的那样:带具体文件路径、列名、随意的措辞,甚至可以有错别字;
  • 先与用户分享:"Here are a few cases I want to try. Anything to add or change?";
  • 然后逐条执行:加载草稿技能,把测试 prompt 交给模型,检查实际发生什么。文档特别注明当前 ZCode 不会派生并行评估子代理(does not currently spawn parallel evaluation subagents),因此一次跑一个 prompt,并与用户共同查看每个结果。

"Reviewing the draft" 一节给出每条 prompt 的标准操作:

  1. 确保草稿技能已落在上文四个可发现目录之一;
  2. 在一个全新的 ZCode 会话轮次中给出测试 prompt——要么让 description 自然触发技能,要么用 /skill <name> <prompt> 强制加载;
  3. 与用户一起看结果:技能触发了吗?输出符合预期吗?哪里跑偏了?

这里还有一个关键的分析视角——同时观察结果与轨迹(trace):如果技能导致模型做了大量"忙活"(busywork),比如反复重读同一批文件、写一次性脚本、原地打转,那通常意味着技能过度规定(over-prescribing)或表述不清。文档的结论是:这是"该删"的信号,而不是"该加更多规则"的信号。这一条与后文 "Keep the prompt lean" 首尾呼应,构成该技能方法论中最重要的反直觉点之一。

五、改进:循环的心脏

"Improving the skill" 是文档自认的"heart of the loop",四条改进思路应完整保留:

  1. 从反馈中泛化(Generalize from feedback):你和用户是在用少量例子快速迭代,但技能必须对双方都没见过的输入有效。如果某个顽固问题抗拒针对性修改,尝试换一种框架(framing)或隐喻,而不是层层叠加约束。零碎的过拟合规则与压迫性的 MUST 会随时间让技能变差;
  2. 保持 prompt 精简(Keep the prompt lean):删掉没有贡献的东西。如果模型在忙活上浪费 token,而忙活正是技能鼓励的,直接删掉那条指引再观察;
  3. 解释 why:现在的模型在有上下文时推理得很好。即便用户反馈简短甚至带着情绪,也要先弄清其真实诉求,再把这种理解转写进指令。重构(reframing)通常优于加码强制;
  4. 寻找重复劳动(Look for repeated work):如果每次测试都独立写出了同一个辅助脚本、或走了同样的多步流程,就把脚本打包进 scripts/ 让技能直接指向它——"写一次,而不是让模型每次重新发明"。

随后进入再循环:应用改进 → 重跑测试 prompt → 向用户展示新输出 → 持续到用户满意或进一步修改不再带来收益。

六、更新已安装技能

当目标是更新一个已安装技能而非新建时,文档规定三条规则:

  • 保留原 name 与目录名:已安装技能叫 research-helper,更新版仍然叫 research-helper,而不是 research-helper-v2
  • 只读路径的覆盖策略:如果已安装技能路径只读(例如随官方插件缓存分发),把技能复制到可写的用户位置(如 ~/.agents/skills/<name>/),在那里编辑,并让用户级优先级发现覆盖原版;
  • 同名不同路径是不同安装身份:不同路径下的同名技能作为各自独立的已安装技能存在,路径(path)才是安装身份。

这与 builtin_zcode_skills_message 中内置技能声明"官方插件缓存"路径(~/.zcode/cli/plugins/cache/zcode-plugins-official/...)的做法一致——内置与插件缓存分发物落在该目录,用户侧覆盖则走上文的用户级目录,两条路径各司其职。

七、与 harness 集成的实现视角

把文档声明与源码对齐,可以得到完整的运行时图景:

  • 发现层:skills 加载逻辑位于 codex-rs/core-skills,统一以 SKILL.md 为文件名常量(SKILLS_FILENAME),解析 frontmatter 元数据并做 fail-open 处理(元数据解析失败不阻断 SKILL.md 加载,见 loader.rs L467 附近);
  • 宣告层session_skills.rs 将运行时组装好的 <skills_instructions> developer 块解析为 SessionSkill { name, description, path } 列表,各 harness 按自己最接近的形态重新渲染——这正是"元数据常驻上下文"的实现基础;
  • 触发层Skill 工具由 HarnessAliasHandler 统一承接,ZCode 分支的 handle_zcode_skill 负责把 frontmatter 剥离后的正文以 <skill_content> 标签交付给模型,并附 base directory,使技能内相对路径(如 references/aws.mdscripts/)有据可依。

对技能作者的实操含义是:/skill <name> <prompt> 强制加载路径与 description 自然触发路径最终都汇入同一份正文,因此 description 的质量同时决定"自然触发率"与"被宣告时的可读性"——这与文档"write descriptions a little bit pushy"的建议在实现上完全自洽。

八、可复制的最小实践清单

综合文档与源码,落地一个新技能可遵循以下检查清单:

  1. 用四个标准问题固化意图,优先从会话历史抽取已验证的步骤与纠正;
  2. .agents/skills/<name>/(个人跨项目)或项目级对应目录创建 SKILL.mdname 与目录名一致(kebab-case,1–64 字符);
  3. description 写足"做什么 + 何时触发",措辞适度主动以对抗 under-trigger;
  4. 正文控制在 500 行以内,祈使句 + 解释 why + 字面示例;超过预算的领域细节移入 references/ 并在正文写明读取时机;
  5. 设计 2–3 个含具体路径、列名、口语化措辞的测试 prompt,新会话中逐条执行;
  6. 共读结果与 trace,识别 busywork 信号,以删除和重构替代加规则;
  7. 重复直到收敛;更新旧技能时不改名,只读路径走用户级目录覆盖。

以上流程全部以 zcode_skill_creator.md 为唯一规范来源,并可与 Skill 处理器内置技能宣告skills 加载器 对照阅读验证。

登录后查看全文
热门项目推荐
相关项目推荐