Skill 的输入输出契约:用 Schema 把不确定性关进笼子

为什么“契约”是 Skill 的起点

Skill 的目标不是“回答得像人”,而是“交付得像组件”:可被调用、可被组合、可被测试。

真正让 Skill 变稳的,不是更长的提示词,而是:

  • 输入契约:你允许什么、默认什么、拒绝什么
  • 输出契约:你保证什么结构、哪些字段必有、排序与单位是什么
  • 失败契约:失败时返回什么、是否重试、是否需要人类确认

先定义边界:这个 Skill 不做什么

工程化的第一条规则是:先写清楚“不做什么”。

例如「PR 摘要 Skill」可以明确:

  • 只总结改动与风险,不做代码风格争论
  • 不做部署决策(可以给建议,但不下结论)
  • 不访问任何外部私密系统,除非显式授权并走工具调用

写“不做什么”,比写“我很强”更能提升稳定性。

输入契约(Input Contract)模板

你至少要列出:

  • 字段名
  • 类型(string/number/enum/list/object)
  • 必填/可选
  • 默认值
  • 合法范围
  • 例子

下面是一个“最小可用”的输入 schema(用 JSON 表达):

{
  "skill": "pr_summary",
  "version": "1.0.0",
  "input": {
    "repo": "string",
    "pull_number": "number",
    "audience": "enum(dev|pm|qa)",
    "risk_level": "enum(low|medium|high)",
    "max_words": "number"
  },
  "defaults": {
    "audience": "dev",
    "risk_level": "medium",
    "max_words": 300
  }
}

输出契约(Output Contract)模板

输出尽量结构化,尤其当它会被后续步骤消费(写评论、生成变更日志、触发发布)。

{
  "output": {
    "summary": "string",
    "changes": [
      {
        "area": "string",
        "description": "string"
      }
    ],
    "risks": [
      {
        "severity": "enum(low|medium|high)",
        "reason": "string",
        "mitigation": "string"
      }
    ],
    "followups": ["string"]
  }
}

如果你必须输出 Markdown,也建议把结构固定成小节,并保证顺序一致(可测试、可 diff)。

失败契约:把“失败类型”写成枚举

不要用“失败了”这种描述。你需要可观测、可统计、可回归的失败类别:

  • INVALID_INPUT:参数缺失/非法
  • TOOL_AUTH_REQUIRED:需要授权或权限不足
  • TOOL_TIMEOUT:外部系统超时
  • TOOL_RATE_LIMIT:被限流
  • MODEL_REFUSAL:模型拒绝执行(安全策略)
  • LOW_CONFIDENCE:置信度不足(触发人类确认)

输出时建议把失败信息也结构化:

{
  "ok": false,
  "error": {
    "type": "TOOL_TIMEOUT",
    "message": "GitHub API timeout",
    "retryable": true,
    "suggested_action": "Retry with backoff or switch to cached diff"
  }
}

动手做:把契约落到“校验 + 提示 + 工具层”

契约不是写在文档里就结束,至少要落到三层:

  • 校验层:进入 Skill 前校验输入(必填、范围、类型)
  • 提示层:提示词里明确要求输出结构(字段名、顺序、允许为空)
  • 工具层:工具调用返回也要映射到错误枚举(而不是裸字符串)

工程化清单(你做完就能上线 50%)

  • 输入:必填/默认/范围/拒绝项齐全
  • 输出:固定结构或固定小节顺序
  • 失败:枚举化,可统计
  • 降级:至少一种 fallback(缓存、摘要、人工确认)

常见坑

  • 把 schema 当作文档:不做校验,等于没写
  • 输出契约太大:字段越多越容易漂移,先做最小可用
  • 没有失败枚举:后续做不了监控和回归

下一篇:Skill 的工程化目录与文档规范

← 返回博客列表