文档导航
文档 / Meta-Skill 编写指南

Meta-Skill 编写指南

本指南面向编写、校验和审阅 OpenSquilla MetaSkills 的作者与维护者。面向用户的指南请阅读 ../features/meta-skill-user-guide.md

MetaSkill 是什么

MetaSkill 是一个 SKILL.md 文件,包含:

  • kind: meta
  • 一个或多个自然语言的 triggers
  • 一个 composition: 块,定义步骤的有向无环图。

在运行时,模型可以调用:

meta_invoke(name="<meta-skill-name>")

随后 OpenSquilla 会按声明的 composition 逐步执行,并将最终结果返回给用户。模型选择 workflow,但运行时强制执行依赖顺序、模板渲染、风险元数据、递归防护、工具门禁、暂停以及最终文本选择。

运维人员可以在全局禁用模型可见的 MetaSkill 行为:

[meta_skill]
enabled = false

禁用后,MetaSkills 仍会被安装以便清点和历史运行查看,但不会被注入到 prompts,meta_invoke 也不会对模型可见,显式的 meta_invoke 调用会被拒绝。

何时使用 MetaSkill

当一项任务可重复并自然分解为一个小型 workflow 时,使用 MetaSkill,例如:

  • 对用户请求进行分类,然后路由到合适的专家 skill;
  • 运行两个独立的分析 skill,然后合并它们的输出;
  • 搜索或检查上下文,然后将其总结为面向用户的回答;
  • 执行一个确定性的、由 CLI 支撑的 skill,然后审阅或持久化结果;
  • 在继续之前暂停以收集结构化的用户输入。

不要将 MetaSkill 用于一次性指令、应当保持对话式的开放式规划,或需要任意递归的流程。MetaSkill 不能组合另一个 MetaSkill。

MetaSkill 的放置位置

对于本地管理的 skills,创建:

~/.opensquilla/skills/<skill-name>/SKILL.md

对于仓库内置的 skills,将该 skill 放在内置 skills 目录树下:

src/opensquilla/skills/bundled/<skill-name>/SKILL.md

生成的提案在安装前会被审阅。接受提案后,OpenSquilla 会将其提升到受管 skills 目录,并刷新在线 skill 加载器。

基本编写流程

  1. 定义任务契约:输入、输出、边界、误触发情形以及用户确认点。
  2. 编写保守的 namedescriptiontriggers
  3. 将 workflow 拆分为如 intake、collect、analyze、draft、audit、deliver 等步骤。
  4. 当某步骤需要前序步骤的输出时,加入 depends_on
  5. 在模板中过滤所有用户输入与前序步骤输出。
  6. 声明风险元数据与 capabilities。
  7. 运行确定性检查和软激活检查。
  8. 在接受或启用前,检查提案以及自动启用的审计输出。

用户可以通过两种方式激活 MetaSkill:

  • 软激活:自然提问,让模型选择正确的 meta_invoke 调用。
  • 显式激活:在调试或测试时按名称请求该 MetaSkill。

必需的 Frontmatter

每个 MetaSkill 都应声明:

---
name: short-stable-name
kind: meta
description: One sentence that tells the model when this workflow applies.
triggers:
  - short phrase users naturally type
meta_priority: 50
always: false
final_text_mode: auto
metadata:
  opensquilla:
    risk: low
    capabilities: []
composition:
  steps: []
---

各字段含义:

  • namemeta_invoke 使用的稳定标识符。
  • kind:必须是 meta
  • description:面向模型的描述,说明何时使用该 workflow。
  • triggers:用于确定性和模型辅助激活的短语。
  • meta_priority:当多个 MetaSkills 可能匹配时的排序键。
  • always:通常为 false;MetaSkills 不应被无条件注入。
  • final_text_mode:最终回答的派生方式。
  • metadata.opensquilla.risk:无人值守自动启用时所需的最高风险等级。
  • metadata.opensquilla.capabilities:显式声明的副作用 capabilities。
  • composition.steps:有序的 DAG 定义。

风险元数据

使用 metadata.opensquilla.risk 声明 workflow 所需的最高风险等级:

  • low:只读推理、分类、摘要或安全的本地检查。
  • medium:本地文件或 artifact 写入、确定性的文档生成或网络读取。
  • high:shell/进程控制、凭据使用、网络写入、外部副作用或可改变状态的直接工具调用。

使用 metadata.opensquilla.capabilities 显式标明副作用。常见的 capabilities 包括:

  • filesystem-write
  • artifact-write
  • document-export
  • network
  • network-read
  • network-write
  • external-side-effect
  • credential-use
  • process-control
  • shell

如果被引用的子 skill 缺少风险元数据,无人值守自动启用会对依赖做保守处理。新 skill 应声明 risk 和 capabilities,而不是依赖遗留兼容回退。

步骤类型

MetaSkill 步骤支持以下执行类型。

agent

agent 用于普通的、由 skill 支撑的 sub-agent turn。这是用户面向的推理和综合的最佳默认值。

- id: summarize
  kind: agent
  skill: summarize
  with:
    text: "{{ outputs.search | truncate(2000) }}"

llm_chat

llm_chat 用于一次有界、无工具循环的 LLM 生成步骤。适用于 intake 归一化、紧凑起草、最终 audit 和轻量综合。

- id: normalize
  kind: llm_chat
  with:
    system: "Extract the request fields. Do not ask a question."
    task: "{{ inputs.user_message | xml_escape | truncate(1000) }}"

llm_classify

当步骤应当从一个封闭集合中返回恰好一个值时使用 llm_classify。适用于路由、分诊和紧凑决策。

- id: classify
  kind: llm_classify
  output_choices: [BUG, FEATURE, QUESTION]
  with:
    text: "{{ inputs.user_message | xml_escape | truncate(512) }}"

user_input

当 workflow 应当暂停并从用户处收集结构化数据时使用 user_input。该步骤需要一个 clarify: schema。

- id: collect_project
  kind: user_input
  when: "'NEEDS_CLARIFICATION: yes' in outputs.intake"
  clarify:
    mode: form
    intro: "A few fields are needed before this workflow can continue."
    nl_extract: true
    fields:
      - name: topic
        type: string
        required: true
        prompt: "Topic"
        max_chars: 200

支持的字段类型为 stringenumintbool。当 intake 已有足够信息时,使用 skip_ifwhen 避免暂停。

tool_call

仅在确定性的直接工具执行时使用 tool_call。声明一个 tool_allowlist,保持参数收窄,并在工具可改变状态时将该 MetaSkill 标记为高风险。

- id: persist
  kind: tool_call
  tool: memory_save
  tool_allowlist: [memory_save]
  tool_args:
    text: "{{ outputs.summary | truncate(2000) }}"

skill_exec

对带有 entrypoint: manifest、应当作为子进程运行的 skill 使用 skill_exec。这适用于确定性的、由 CLI 支撑的 skill,例如文档转换或报告生成。

- id: render
  kind: skill_exec
  skill: html-to-pdf
  with:
    html: "{{ outputs.report | truncate(12000) }}"

步骤标签与进度

两个可选的步骤级字段驱动 WebUI 的运行进度条带 (参见 ../features/meta-skill-user-guide.md 中的”运行进度条带”):

  • label:步骤的简短、人类可读名称。条带会将其渲染为 chip 文本。 如果省略,WebUI 会将步骤 id 人性化处理(例如 intakeIntake)。
  • progress_emits:步骤的执行器是否可以向条带发布实时 status_text 更新。按类型的默认值:
    • agent / skill_exectrue
    • tool_callfalse
    • llm_chat / llm_classify / user_input:忽略

示例:

composition:
  steps:
    - id: intake
      kind: llm_chat
      label: 意图提取
      with: { ... }
    - id: search
      kind: agent
      skill: web-research
      label: 检索证据
      progress_emits: true
      with: { ... }

保持标签简短(中文 2-6 字,英文 1-2 个词)。过长的标签会在条带头部被截断。

依赖与并行

无依赖的步骤可以并行运行。带 depends_on 的步骤会等待所有命名步骤完成。

composition:
  steps:
    - id: inspect_code
      kind: agent
      skill: code-reviewer
      with:
        request: "{{ inputs.user_message | xml_escape | truncate(512) }}"

    - id: inspect_tests
      kind: agent
      skill: test-engineer
      with:
        request: "{{ inputs.user_message | xml_escape | truncate(512) }}"

    - id: merge
      kind: agent
      skill: summarize
      depends_on: [inspect_code, inspect_tests]
      with:
        text: |
          Code review:
          {{ outputs.inspect_code | truncate(2000) }}

          Test review:
          {{ outputs.inspect_tests | truncate(2000) }}

图必须是无环的。一个步骤只能依赖于同一 composition 中声明的步骤 id。

路由与失败处理

当一个 agentskill_exec 步骤应根据先前输出选择 skill 时,使用 route

- id: classify
  kind: llm_classify
  output_choices: [DOCS, BUG, SECURITY]
  with:
    text: "{{ inputs.user_message | xml_escape | truncate(512) }}"

- id: handle
  kind: agent
  skill: summarize
  depends_on: [classify]
  route:
    - when: "outputs.classify == 'DOCS'"
      to: writer
    - when: "outputs.classify == 'BUG'"
      to: debugger
    - when: "outputs.classify == 'SECURITY'"
      to: security-reviewer
  with:
    request: "{{ inputs.user_message | xml_escape | truncate(512) }}"

使用 on_failure 指定单个替代步骤。该替代步骤必须存在于同一计划中,不得有自己的依赖项,也不得有自己的 on_failure

Final Text 模式

使用 final_text_mode 控制面向用户的最终结果:

  • auto:默认。编排器将各步骤输出总结为一个简洁的最终回答。
  • raw:原样返回最后一个非替代步骤的输出。
  • step:<step_id>:原样返回某一指定步骤的输出。

示例:

final_text_mode: auto
final_text_mode: raw
final_text_mode: "step:summarize"

当某一个步骤就是预期交付物时,使用 step:<step_id>。当最终步骤已经格式化为完整报告时,使用 raw。当 workflow 产生若干中间输出,需要一个紧凑的面向用户的总结时,使用 auto

模板安全

模板使用 Jinja 表达式。将用户输入和先前步骤的输出视为不可信:

  • 对于用户文本,先用 xml_escapeslugify,然后用 truncate 限定边界。
  • 对于 outputs.<step_id>,始终使用 truncatexml_escapeslugifytojson 进行边界限定或编码。
  • 不要将原始 {{ inputs.user_message }} 传入下游步骤。
  • 不要将原始 {{ outputs.some_step }} 传入另一个步骤。
  • 保持 prompt 形状的字符串显式、简短且任务专属。

安全示例:

query: "{{ inputs.user_message | xml_escape | truncate(512) }}"
text: "{{ outputs.search | truncate(2000) }}"
slug: "{{ inputs.user_message | slugify | truncate(80) }}"
payload: "{{ outputs.plan | tojson }}"

不安全示例:

query: "{{ inputs.user_message }}"
text: "{{ outputs.search }}"

激活指南

在正常的产品使用中,MetaSkills 默认仅支持手动运行。用户通过 /meta <name> 启动它们,因此只有在你有意支持 meta_skill.auto_trigger = true 时,才需要 trigger 和软激活检查。

在维护自动触发兼容性时,将 triggers 写成用户会自然输入的短语:

  • 推荐:summarize recent history
  • 推荐:review current diff
  • 避免:run the internal OpenSquilla DAG composition meta skill

除非生产 workflow 有经过测试的理由,否则使用 2 到 5 个 triggers。避免与解释性问题冲突的 triggers,例如”how does this meta-skill work?”。当启用自动触发兼容性时,询问 MetaSkill 的用户不应意外地运行它。

description 设置为说明模型在自动触发模式下何时应选择该 workflow。不要只把关键约束藏在正文中;当启用自动触发时,模型主要看到的是 frontmatter 和注入的 skill 摘要。

校验清单

在分享或启用 MetaSkill 之前:

  1. 确认 frontmatter 可作为 YAML 解析。
  2. 确认存在 kind: metacomposition.steps
  3. 确认所有 depends_onroute.to 以及 on_failure 引用都指向有效的步骤或 skills。
  4. 确认图中无环。
  5. 确认所有用户输入和步骤输出都已过滤。
  6. 确认 metadata.opensquilla.riskmetadata.opensquilla.capabilities 真实反映 workflow 的副作用。
  7. 如果支持 meta_skill.auto_trigger = true,使用 scripts/meta_trigger_accuracy.py 运行确定性 trigger 检查。
  8. 如果支持 meta_skill.auto_trigger = true,使用 scripts/live_meta_soft_activation_e2e.py --env-file /path/to/.env 运行模型决策的软激活检查。
  9. 对于生成的 skills,在接受或启用前检查 Web UI 中的提案详情及其自动启用 audit。

排障

如果 MetaSkill 似乎未运行:

  • 检查 SKILL.md 是否位于已加载的 skill 目录下。
  • 如果 skill 是在提案接受流程之外添加的,刷新或重启 gateway。
  • 确认你在支持 MetaSkill 运行的形态上用 /meta <name> 运行了它。
  • 确认你希望模型调用的 MetaSkill 未设置 disable-model-invocation
  • 如果你期望自然语言自动触发,确认 meta_skill.auto_trigger = true
  • 确认该 skill 具有 kind: metacomposition.steps 列表非空。
  • 确认用户措辞与 triggers 或 description 相匹配。

如果解析失败:

  • 检查重复的步骤 id。
  • 检查未知的 kind 值。
  • 检查 agentskill_exec 步骤缺失 skill
  • 检查 llm_classify 缺失 output_choices
  • 检查 user_input 缺失 clarify.fields
  • 检查 tool_call 缺失 tooltool_args 非法或 tool_allowlist 不匹配。
  • 检查环以及未定义的 depends_on 引用。

如果自动启用被跳过:

  • 在 Web UI 中检查提案的自动启用 audit。
  • 为被引用的子 skills 补充缺失的风险元数据。
  • 降低 workflow 的副作用,或要求 medium/high 风险 workflow 通过人工审阅。

测试 Prompts

至少包含:

  • 英文正向 trigger;
  • 显式调用;
  • 粘贴历史的反例;
  • 邻近领域的反例;
  • 输出质量评判的 rubric。

使用真实的用户措辞,主体和目标清晰。避免使用用户不会自然输入的运维风格短语。


文档索引 · 产品指南 · 改进此页面 · 报告文档问题

在 GitHub 上编辑此页(英文原稿) OpenSquilla 文档 · 中文社区翻译