Ekko Agent Skill 创作指南:基于 skill-creator 的设计、创建、维护与验证全流程
2026/9/24 2:11:41 网站建设 项目流程
  • AI 应用
  • 人工智能
  • AI Agent
  • 本地部署
  • 前端
  • 后端
  • 工作流自动化

【免费下载链接】ekko-studio

Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.

项目地址:https://gitcode.com/gh_mirrors/he/ekko-studio
点击查看免费下载

Ekko Agent(位于本仓库 packages/ekko-agent)是一套本地优先的多智能体运行环境,它通过文件系统上的“Skills”为模型提供可复用的程序性记忆。本文以官方内置 Skill ——skill-creator(SKILL.md)为骨架,完整讲解一个可复用 Skill 从设计、创建、迭代维护到行为验证的完整闭环,并深入到 skills.ts 等源码与 skill-tools.test.ts 测试中,说明 frontmatter 校验、关键字匹配、读改写守卫、备份与归档等底层机制。读完本文,你将掌握“什么样的请求值得固化为 Skill”“如何用skill_manage安全地创建与修改”“如何让 Skill 被多语言意图稳定命中”以及“如何验证 Skill 真正生效”等实战能力。

什么时候才应该创建一个 Skill

skill-creator的核心判断标准只有一句话:Skill 必须提供可复用、非显而易见(non-obvious)的指导,能够改变 Ekko 处理某一类可识别请求的方式。反过来,一次性回答、临时性 workaround、与产品无关的个人偏好,都不应该被固化成永久 Skill。

在设计阶段需要遵守以下边界:

  • 保留用户请求的作用域、工具与授权边界:不要借 Skill 悄悄扩大权限或工具范围。
  • 假定模型已经具备通用推理能力:Skill 应补充的是领域知识、决策标准、易错流程或可复用自动化,而不是基础常识。
  • frontmatter 的description要简洁且有区分度,它是回退发现(fallback discovery)时的重要信号。
  • metadata.keywords保持精简,只放特定的英文短语,供宿主侧精确匹配使用;这些关键字不会注入模型,Ekko 只会把可用的 Skill 名称注入提示词,由主模型用任意语言把用户请求映射到某个名称后调用skill_view
  • 共享说明放在SKILL.md,条件性细节放进 references 并按需加载
  • 只有确定性重复执行比每次重新生成逻辑更可靠时,才添加脚本
  • 只引用目标 Ekko 环境中确实存在的工具和 Skill

只有当缺失的信息会实质改变 Skill 的用途、存放位置、副作用或所支持的工作流时,才需要向用户提问——其余情况应基于合理假设继续。

从源码看,这一“不把一次性内容写入 Skill”的约束同样被后台学习链路强化:SkillReviewService的评审提示词(review.ts)明确列出“不保存”清单——一次性任务叙述、具体 issue/PR 编号、临时环境故障、外部瞬时结果、以及“某个工具坏了”之类的笼统负面结论,都不允许沉淀为 Skill;同时禁止把密钥、凭据、原始对话记录和大量复制输出写入 Skill。

Ekko Skill 的目录结构

每个 Skill 的最低要求是一个目录加一个SKILL.md文件:

skill-name/ └── SKILL.md

skill_manage还支持四类可选文本资源(源码中以SUPPORT_DIRECTORIES常量定义,见 skills.ts):

目录用途
references/仅在特定模式下才需要的详细指导
templates/可复用的文本模板
scripts/Node.js、Python 或 shell 辅助脚本
assets/生成输出中使用的文本资源

创建时不要无中生有地生成空目录、占位示例、README、changelog 或重复的快速参考。skill_manage只会写 UTF-8 文本文件;二进制资源不能编码进文本。如果某个 Skill 确实需要二进制资产,应说明它需要通过合适的文件导入或 UI 流程引入,而不是塞进文本文件。

值得注意的是,当前仓库 packages/ekko-agent/skills/skill-creator 目录本身就严格遵循这一原则——它只包含一个SKILL.md,没有任何多余的装饰性文件。

创建 Skill 的完整流程

skill-creator给出的创建步骤共六步,每一步都对应skill_manage工具的具体动作:

  1. 先用skill_list做聚焦查询。如果已存在匹配的 Skill,应更新它而不是创建重复项。SkillListTool(skills.ts)支持可选query参数,对 Skill 名称、描述和维护中的关键字做大小写不敏感的检索。

  2. 选择名称:最多 64 个字符,只能使用小写字母、数字、连字符或下划线,且首尾必须是字母数字。源码中的SKILL_NAME_PATTERN = /^a-z0-9?$/(skills.ts)正是这一规则的落地。

  3. 准备完整的 SKILL.md 内容:包含标量的namedescription字段以及非空的关键字列表,模板如下:

    --- name: example-skill description: Handle a specific reusable workflow and state when it applies. metadata: keywords: - exact user phrase - specific workflow phrase --- # Example Skill Essential instructions.
  4. 调用skill_manage,使用action=create、精确的名称和完整内容。只有当用户明确要求、或 Profile 已经采用了有意义的单层分类时,才使用category参数。

  5. action=write_file添加必要的支持文件,路径必须位于references/templates/scripts/assets/之下。

  6. skill_list确认可发现性,再用skill_view加载结果,验证一切正常。

关键字:精确匹配的“宿主侧开关”

metadata.keywords是整个发现机制里最关键的设计点。从 skills.ts 的resolveSkillRouting可以看到,自动路由只使用两类输入:

  • Skill 名称(以及其去分隔符的空格形式,如image-genimage gen);
  • 当校验状态为valid时的显式metadata.keywords

长描述和 Skill 正文永远不会参与自动选择。匹配方式是硬匹配(hard-match):matchNormalizedTerm(skills.ts)对纯 ASCII 术语按单词边界做正则匹配,避免file命中file-upload这类误报。

因此关键字选取要遵守以下规则:

  • 足够具体,避免无关匹配;
  • 优选 3–5 个简短英文短语;
  • 只使用 ASCII 文本或技术标识符;
  • 避免filecodehelptool这类泛化单词;
  • Skill 名称本身会被单独匹配,除非其空格形式本身就是有用短语,否则不要重复;
  • 不要metadata.keywords里放翻译、穷举同义词、正则、描述或完整示例提示词——多语言路由属于主模型的工作(主模型基于注入的 Skill 名称完成)。

校验函数validateSkillContent(skills.ts)给出了更精确的边界:metadata.keywords至少 1 条、最多 8 条,每条不超过 80 字符,且必须全部为可打印 ASCII(/^[\x20-\x7e]+$/。测试用例 skill-tools.test.ts 也专门验证了“创作者维护的路由关键字必须保持精简英文 ASCII”,一旦混入本地化关键词即会被拒绝。

校验失败怎么办

skill_manage会校验必需的 frontmatter、与名称匹配的name、非空的metadata.keywordsdescription以及非空的 Markdown 正文。校验状态在发现结果中以validationStatus呈现,取值包括validneeds_metadata(关键字相关问题)和invalid(其余问题),参见SkillValidationStatus(skills.ts)。如果收到校验错误,应当修复错误而不是绕过受管工具——例如测试 skill-tools.test.ts 验证了缺少关键字时返回requires at least one non-empty metadata.keywords entry

更新既有 Skill:patch 优先,读改写守卫

更新 Skill 的首要纪律是:在同一轮运行中,先skill_list,再用skill_view读取目标,然后才允许任何变更。这是由SkillReadTracker(skills.ts)实现的“读改写守卫”(read-before-write guard):skill_view会把(runId, 文件路径) → 内容 sha256记录下来;任何写操作(patch/edit/write_file/remove_file/delete)在执行前都会调用currentViewedContent(skills.ts)检查——如果该文件在本轮没有被读过,直接报错;如果读过但磁盘内容哈希已经变化(说明已被并发修改),也会要求重新读取。

其余更新规则:

  • 优先action=patch做聚焦修改:提供唯一的oldString和替换newString。若oldString匹配多次且未设置replaceAll=true,工具会报错并要求补充上下文或显式开启replaceAll(参见 skills.ts)。空newString即表示删除该段文本。
  • 仅当需要大幅重写时才用action=edit,它会用content整体替换SKILL.md
  • Skill 支持的请求或边界变化时,同步复查并更新metadata.keywords;窄幅修改时应保留仍然有效的旧关键字。
  • 覆盖、patch 或删除既有支持文件前,先skill_view读取该文件
  • 每次成功变更后,再次skill_view再执行下一次变更——因为读改写标记会被消费(tracker.forget),守卫是一次性的。
  • 除非用户要求替换或删除,否则保留既有有用的指令与资源

备份、归档与内置 Skill 的保护

受管替换(managed replacements)会创建可恢复的备份:backupFile(skills.ts)把旧文件复制到技能根目录下的隐藏目录.ekko-backups/。测试 skill-tools.test.ts 断言 patch 之后.ekko-backups目录下恰好有一个备份。

删除操作有三个强制前提:明确的用户意图 + 同一轮内的skill_view+action=deleteconfirmed=true。并且 Ekko 不是物理删除,而是把技能目录rename进隐藏归档目录.ekko-archive/archiveSkill,skills.ts),测试 skill-tools.test.ts 验证了archived: true的结果。内置 Skill 不可删除——内置清单由.ekko-builtin-skills.json记录,owner必须为ekko-agent(skills.ts)。skill-creator本身正是内置 Skill 之一,在 README.md 的内置清单中可以确认。

另外,SkillManageTool还通过withSkillMutationLock(skills.ts)对同一技能根目录的写操作做串行化排队,避免并发变更互相覆盖。

验证 Skill 行为:从“能发现”到“真生效”

创建或修订之后,skill-creator要求按以下顺序验证:

  1. skill_list确认返回预期名称与有区分度的描述,再用skill_view检查内部关键字元数据。
  2. skill_view检查最终的SKILL.md以及每一个变更过的支持文件skill_view的返回内容带有sha256、字符数、baseDirectorymanagedByEkkobuiltIncategorysource等信息(见 skills.ts),方便核验落盘结果。
  3. terminal_exec在安全的代表性输入上执行新建或变更过的脚本。先检查依赖,且不要静默安装。
  4. 测试代表性的正反英文短语:预期精确短语应硬匹配命中,而相近但不相关的请求不应命中。对其他语言,验证主模型能够基于注入的 Skill 名称选中并调用skill_view。还应测试可观察的工作流不变量(observable workflow invariants),避免只断言标题或精确文案的脆弱测试。
  5. 汇报创建或变更的内容、任何校验限制,以及是否遗留外部依赖或二进制资产给用户。

同时,如果某个 Skill 在真实使用中暴露了缺陷,应当用能解决问题的最小修正去改进它,而不是为每一个孤立的例子堆砌普适规则。

Skill 生命周期背后的运行时机制

系统提示词中的 Skill 编排

buildSystemPrompt(system-prompt.ts)把 Skill 机制组织为两部分:

  • Skill Discovery(发现):把“Available Skill Names”以逗号分隔注入提示词,并指示模型先用自己的语言解读用户请求、与名称清单比对,命中时直接用skill_view加载指令;skill_list只在名称不明确时作为回退;若当前会话已包含同一 Skill 的完整skill_view结果则直接复用,避免重复读取。
  • Skill Evolution(进化):提示词引导模型在复杂工具任务、棘手修正或非平凡工作流之后,考虑用skill_manage沉淀持久方法;并重申“改前先读、小 patch 优先、只创建类级可复用 Skill、不写一次性任务日志/瞬时故障/密钥/单问题叙述”等纪律。这也解释了skill-creator的“Skill 是什么、何时创建”原则在运行时层面的呼应。

Profile 配置与外部目录

Skills 按 Profile 隔离。README 中的配置示例(README.md)展示了skills.enabledskills.reviewEveryToolCalls以及skills.profiles.<profile>.externalDirectories/disabled的用法:

{ "skills": { "enabled": true, "reviewEveryToolCalls": 0, "profiles": { "work": { "externalDirectories": ["~/shared-skills", "$TEAM_SKILLS"], "disabled": ["weather"] } } } }

外部目录是只读 Skill 源,不会被复制进 Ekko 存储,也不会被修改;disabled里的 Skill 名称会从提示词注入与自动路由中隐藏。本地 Skill 优先于同名外部 Skill(发现逻辑见discoverSkillsscanSkillDirectory,skills.ts)。

后台评审与 managedByEkko

Ekko 还提供后台“程序性学习”链路:SkillReviewService(review.ts)在每轮完成后以background-review身份、只持有skill_list/skill_view/skill_manage三个工具,判断本轮是否产生了可持久复用的改进。它只能修改managedByEkko=true的 Skill、禁止删除、同样遵循“改前先 skill_view、patch 优先”的纪律(对应EKKO_SKILL_REVIEW_PROMPT,review.ts)。managedByEkko标记来自技能目录下的.ekko-skill.json元数据(skills.ts),即由 Ekko 自己创建的 Skill 才允许后台自动演进。这个机制把skill-creator的“何时更新、更新顺序”原则程序化地固化到了运行时。

总结

从 skill-creator 出发,我们可以把 Ekko Agent 的 Skill 工程抽象成一条完整链路:用“可复用且非显而易见”标准过滤需求 → 用最小目录结构承载指令与条件性资源 → 用精炼的 frontmatter(名称/描述/3–5 个 ASCII 关键字)确保确定性的宿主侧硬匹配 → 用skill_manage的 create/patch/edit/write_file/remove_file/delete 六个动作安全变更 → 用“同轮先读后写”的守卫与备份归档机制防错 → 用正反短语与工作流不变量验证行为。这套设计同时兼顾了确定性(关键字精确匹配)与灵活性(多语言意图由主模型基于 Skill 名称路由),并有 skills.ts 的校验与锁机制、review.ts 的后台演进、skill-tools.test.ts 的回归测试共同兜底——掌握这些规则,你就可以在自己的 Profile 中安全地沉淀出高质量、可被稳定召回、可长期维护的 Ekko Agent Skills。

  • AI 应用
  • 人工智能
  • AI Agent
  • 本地部署
  • 前端
  • 后端
  • 工作流自动化

【免费下载链接】ekko-studio

Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.

项目地址:https://gitcode.com/gh_mirrors/he/ekko-studio
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询