YAML 契约格式:理解了语义规范体系后怎么写语义规则

本文是阶段二《设计师作为"语义翻译者"》的实操专题,回答一份 YAML 契约从空白文档到完整文件的写作过程。

阶段二的核心判断是:传统设计规范面向"人"阅读,机器无法消费,AI 生成内容时不受语义约束。Schema-As-Code 的解法是将设计意图形式化为 YAML 语义契约,在生成前预置边界与规则。

本文回答 YAML 语义契约怎么写。传统规范人读机器不读,Schema-As-Code 将其形式化为 YAML,预置生成边界。YAML 不是色值或文案,是语义令牌。

阶段一:组件语义快照与模式诊断:AI 生成界面的第一道检查

方法论总纲与开源仓库:把设计规范写成代码格式,是所有 AI 工具的上游约束方法论


一、YAML 契约的整体结构

一份 YAML 契约由 6 个顶层字段组成。你可以把它理解成一份"设计意图的身份证"------每个字段回答一个特定的问题。

yaml 复制代码
intent_id:          "我是谁?"
description:        "我解决什么问题?"
version:            "我是哪个版本?"
applicable_products: "我在哪些产品里生效?"
semantic_tokens:     "我定义了什么语义?"
immutable_boundaries: "我画了什么红线?"
llm_constraints:     "我对 AI 有什么强制要求?"

下面逐个拆解。


二、字段 1:intent_id ------ 契约的身份证号

设计意图

每个契约都需要一个唯一标识,就像设计稿的编号一样。当你和前端、AI 工程师沟通时,说"ERR-001"比说"那个错误状态分级的东西"要精确得多。

命名规范

yaml 复制代码
intent_id: "ERR-001"
# 格式:[领域缩写]-[三位序号]
# ERR = Error(错误状态)
# PRO = Process(过程状态)
# BND = Boundary(边界动作)
# ACT = Action(操作按钮)
# ALR = Alert(告警状态)

常见错误

❌ 用自然语言命名:intent_id: "错误状态分级"------不方便引用和版本管理

✅ 用结构化编号:intent_id: "ERR-001"------精确、可排序、可检索


三、字段 2:description ------ 一句话说清契约解决什么问题

设计意图

description 是给人类看的摘要。当你打开一份契约文件,第一眼就要知道"这份契约是干嘛的"。

写法

yaml 复制代码
description: "错误状态后果差异未分级:系统无法区分致命错误、网络抖动、限流提示和降级错误,导致用户无法判断后果严重程度。"

好 description 的标准

  • 包含问题现象(用户看到什么)
  • 包含根因(系统缺了什么)
  • 包含后果(用户因此遇到什么困扰)

❌ 不好的写法:description: "错误状态规范"------太笼统,不知道解决什么问题

✅ 好的写法:见上方示例------现象 + 根因 + 后果,一目了然


四、字段 3:version ------ 语义版本号

设计意图

设计规范会迭代,YAML 契约也会迭代。version 字段让你知道"这份契约是第几版",和代码的版本管理一样重要。

语义化版本规范

yaml 复制代码
version: "1.0.0"
# 格式:主版本.次版本.修订号
# 主版本:破坏性变更(如删除某个 severity 级别)
# 次版本:功能新增(如增加新的 visual_mapping)
# 修订号:bug 修复(如文案微调)

版本变更示例

yaml 复制代码
# v1.0.0:初始版本,包含 fatal/transient/retryable 三级
# v1.1.0:新增 degraded 级别(次版本升级)
# v1.1.1:修正 fatal 的文案描述(修订号升级)
# v2.0.0:删除 retryable 级别,合并到 transient(主版本升级,破坏性变更)

五、字段 4:applicable_products ------ 契约在哪些产品里生效

设计意图

不同产品可能有不同的设计规范。applicable_products 定义了这份契约的生效范围,避免"一刀切"。

写法

yaml 复制代码
applicable_products:
  - "ChatGPT"
  - "文心一言"
  - "通义千问"
  - "Kimi"
  - "豆包"
  - "DeepSeek"
  # 不生效的产品:Claude(因为 Claude 的错误状态设计不同)

作用域控制

yaml 复制代码
# 全局生效(所有产品)
applicable_products:
  - "*"

# 特定产品生效
applicable_products:
  - "ChatGPT"
  - "Kimi"

# 排除特定产品
applicable_products:
  - "*"
excluded_products:
  - "Claude"  # Claude 有自己的错误状态规范

六、字段 5:semantic_tokens ------ 契约的核心:语义令牌定义

设计意图

这是 YAML 契约最重要的字段。semantic_tokens 定义了"这个场景下有哪些语义级别,每个级别映射到什么视觉、文案和行动"。

结构拆解

yaml 复制代码
semantic_tokens:
  [语义令牌组名]:           # 如 error_severity、process_phase
    [级别名]:               # 如 fatal、transient、retryable
      description: "..."    # 这个级别的含义
      visual_mapping: {...} # 视觉映射(颜色、动效、图标)
      user_action: [...]     # 用户行动(按钮、操作)
      llm_constraints: [...] # 针对这个级别的 LLM 强制约束

ERR-001 完整示例

yaml 复制代码
semantic_tokens:
  error_severity:              # 语义令牌组:错误严重程度

    fatal:                     # 级别 1:致命错误
      description: "系统级故障,对话上下文可能丢失"

      visual_mapping:          # 视觉映射
        color_token: "status.critical"      # 颜色令牌:致命状态
        motion_token: "pulse.red.urgent"    # 动效令牌:红色脉冲
        icon_token: "alert.octagon"         # 图标令牌:八边形警告
        background: "red.500/10"             # 背景:10% 透明度红色

      user_action:             # 用户行动
        - label: "刷新页面"    # 主行动:刷新
          action: "refresh"
          priority: 1          # 优先级:1(最高)
        - label: "导出历史"    # 次行动:导出
          action: "export_history"
          priority: 2

      llm_constraints:         # LLM 强制约束
        - "必须明确告知用户对话上下文可能已丢失"
        - "禁止仅显示'出错了'等模糊文案"
        - "必须提供恢复路径(刷新或导出)"

    transient:                 # 级别 2:网络抖动
      description: "网络层故障,系统可自动恢复"

      visual_mapping:
        color_token: "status.neutral"       # 颜色令牌:中性状态
        motion_token: "spinner"             # 动效令牌:加载动画
        icon_token: "loader"              # 图标令牌:加载图标
        background: "neutral.800"          # 背景:深灰色

      user_action:
        - label: "等待自动恢复"  # 主行动:等待
          action: "wait"
          priority: 1
        - label: "手动重试"      # 次行动:重试
          action: "retry"
          priority: 2

      llm_constraints:
        - "必须显示自动重试进度"
        - "禁止使用红色背景(避免情绪过载)"
        - "必须说明预计恢复时间"

    retryable:                 # 级别 3:限流/流控
      description: "请求频率已达上限,用户可自助恢复"

      visual_mapping:
        color_token: "status.warning"       # 颜色令牌:警告状态
        motion_token: "none"              # 动效:无(不需要紧急感)
        icon_token: "clock"               # 图标令牌:时钟
        background: "amber.500/10"       # 背景:10% 透明度黄色

      user_action:
        - label: "等待倒计时"    # 主行动:等待
          action: "wait_countdown"
          countdown_field: "retry_after"  # 倒计时字段名
          priority: 1
        - label: "升级套餐"      # 次行动:升级
          action: "upgrade"
          priority: 2

      llm_constraints:
        - "必须显示剩余等待时间(秒/分钟)"
        - "必须提供升级/扩容路径"
        - "禁止使用红色(避免用户恐慌)"

    degraded:                  # 级别 4:部分可用
      description: "部分功能可用,可继续生成"

      visual_mapping:
        color_token: "status.info"          # 颜色令牌:信息状态
        motion_token: "none"              # 动效:无
        icon_token: "info.circle"         # 图标令牌:信息圆圈
        background: "blue.500/10"        # 背景:10% 透明度蓝色

      user_action:
        - label: "继续生成"      # 主行动:继续
          action: "continue"
          priority: 1
        - label: "简化问题重试"  # 次行动:简化重试
          action: "retry_simplified"
          priority: 2

      llm_constraints:
        - "必须说明哪些功能仍然可用"
        - "必须提供替代方案(如简化问题)"
        - "禁止显示纯技术错误码(如 500 Internal Error)"

关键设计原则

原则 说明 示例
令牌层与呈现层分离 color_token 是语义标识,color 是实际色值 color_token: status.criticalcolor: #EF4444
级别必须有明确区分 每个级别在视觉、文案、行动上都有差异 fatal(红脉冲)vs transient(灰加载)vs retryable (黄提示)vs degraded(蓝信息)
行动必须与后果匹配 用户行动由错误后果决定,不是随意给的 fatal → 刷新/导出(因为对话丢了),transient → 等待/重试(因为会自动恢复)
LLM 约束必须可执行 每条约束都能被机器校验 "禁止仅显示'出错了'" → 机器可以检查文案是否包含"出错了"

七、字段 6:immutable_boundaries ------ 不可突破的红线

设计意图

有些规则是"绝对不能违反"的,比如高危操作必须二次确认。immutable_boundaries 定义了这些红线,一旦违反,系统直接阻断。

结构

yaml 复制代码
immutable_boundaries:
  - boundary_type: "safety"           # 边界类型:安全
    constraint_rule_ref: "rules/destructive-action.yaml"  # 引用的规则文件
    violation_action: "block"          # 违反时的动作:阻断

  - boundary_type: "compliance"        # 边界类型:合规
    constraint_rule_ref: "rules/data-retention.yaml"
    violation_action: "escalate"       # 违反时的动作:升级人工审核

ERR-001 示例

yaml 复制代码
immutable_boundaries:
  - boundary_type: "safety"
    rule: "禁止直接执行删除操作而不显示二次确认"
    violation_action: "block"
    # 如果 AI 生成的代码里没有二次确认,直接阻断,不允许进入生产环境

  - boundary_type: "semantic"
    rule: "禁止将 fatal 错误显示为静态灰色(必须用红色脉冲)"
    violation_action: "block"
    # 如果 fatal 错误用了灰色静态背景,直接阻断

与 semantic_tokens 的区别

维度 semantic_tokens immutable_boundaries
性质 "应该怎么做"(推荐) "绝对不能怎么做"(强制)
违反后果 警告/提示 直接阻断/升级
灵活性 可调整(如颜色微调) 不可调整(如安全红线)
示例 "fatal 建议用红色脉冲" "destructive_action 必须二次确认"

八、字段 7:llm_constraints ------ 对 AI 的强制要求

设计意图

LLM 在生成内容时可能会"自由发挥",比如把 Critical 写成"严重",或者漏掉二次确认。llm_constraints 是给 AI 的"强制指令"------不是建议,是必须遵守。

写法

yaml 复制代码
llm_constraints:
  - "必须明确告知用户对话上下文可能已丢失"      # 信息完整性约束
  - "禁止仅显示'出错了'等模糊文案"              # 文案精度约束
  - "必须提供恢复路径(刷新或导出)"            # 行动完整性约束
  - "禁止将 fatal 错误显示为静态灰色"           # 视觉映射约束
  - "禁止在 retryable 场景使用红色背景"         # 场景匹配约束

约束的三种类型

类型 前缀 示例 机器校验方式
必须型 "必须..." "必须显示倒计时" 检查字段是否存在
禁止型 "禁止..." "禁止用'严重'代替'Critical'" 检查违禁词是否出现
限制型 "只能..." "只能使用 outline_danger 样式" 检查值是否在枚举范围内

九、完整契约示例:ERR-001(从头到尾)

yaml 复制代码
# 契约文件:intent/err-001.yaml
# 作者:设计师 [姓名]
# 创建日期:2026-06-30
# 最后更新:2026-06-30
# 变更记录:v1.0.0 初始版本,包含 fatal/transient/retryable/degraded 四级

intent_id: "ERR-001"
description: "错误状态后果差异未分级:系统无法区分致命错误、网络抖动、限流提示和降级错误,导致用户无法判断后果严重程度。"
version: "1.0.0"
applicable_products:
  - "ChatGPT"
  - "文心一言"
  - "通义千问"
  - "Kimi"
  - "豆包"
  - "DeepSeek"

semantic_tokens:
  error_severity:
    fatal:
      description: "系统级故障,对话上下文可能丢失"
      visual_mapping:
        color_token: "status.critical"
        motion_token: "pulse.red.urgent"
        icon_token: "alert.octagon"
        background: "red.500/10"
      user_action:
        - label: "刷新页面"
          action: "refresh"
          priority: 1
        - label: "导出历史"
          action: "export_history"
          priority: 2
      llm_constraints:
        - "必须明确告知用户对话上下文可能已丢失"
        - "禁止仅显示'出错了'等模糊文案"
        - "必须提供恢复路径"

    transient:
      description: "网络抖动,系统可自动恢复"
      visual_mapping:
        color_token: "status.neutral"
        motion_token: "spinner"
        icon_token: "loader"
        background: "neutral.800"
      user_action:
        - label: "等待自动恢复"
          action: "wait"
          priority: 1
        - label: "手动重试"
          action: "retry"
          priority: 2
      llm_constraints:
        - "必须显示自动重试进度"
        - "禁止使用红色背景"
        - "必须说明预计恢复时间"

    retryable:
      description: "请求频率已达上限"
      visual_mapping:
        color_token: "status.warning"
        motion_token: "none"
        icon_token: "clock"
        background: "amber.500/10"
      user_action:
        - label: "等待倒计时"
          action: "wait_countdown"
          countdown_field: "retry_after"
          priority: 1
        - label: "升级套餐"
          action: "upgrade"
          priority: 2
      llm_constraints:
        - "必须显示剩余等待时间"
        - "必须提供升级路径"
        - "禁止使用红色"

    degraded:
      description: "部分功能可用"
      visual_mapping:
        color_token: "status.info"
        motion_token: "none"
        icon_token: "info.circle"
        background: "blue.500/10"
      user_action:
        - label: "继续生成"
          action: "continue"
          priority: 1
        - label: "简化问题重试"
          action: "retry_simplified"
          priority: 2
      llm_constraints:
        - "必须说明哪些功能仍然可用"
        - "必须提供替代方案"
        - "禁止显示纯技术错误码"

immutable_boundaries:
  - boundary_type: "safety"
    rule: "禁止直接执行删除操作而不显示二次确认"
    violation_action: "block"
  - boundary_type: "semantic"
    rule: "禁止将 fatal 错误显示为静态灰色"
    violation_action: "block"

十、写作检查清单:写完一份契约后对照

markdown 复制代码
- [ ] intent_id 是否符合命名规范(领域缩写-三位序号)?
- [ ] description 是否包含现象 + 根因 + 后果?
- [ ] version 是否使用语义化版本(主.次.修)?
- [ ] applicable_products 是否明确了生效范围?
- [ ] semantic_tokens 是否每个级别都有 visual_mapping + user_action + llm_constraints?
- [ ] visual_mapping 是否使用了语义令牌(color_token)而非写死色值(color: #EF4444)?
- [ ] user_action 是否与后果严重程度匹配(fatal→刷新/导出,transient→等待/重试)?
- [ ] llm_constraints 是否每条都可被机器校验(有明确的"必须/禁止/只能")?
- [ ] immutable_boundaries 是否定义了不可突破的红线?
- [ ] 是否包含变更记录和作者信息?

十一、常见错误与修正

错误 1:写死色值,不用语义令牌

❌ 错误写法:

yaml 复制代码
visual_mapping:
  color: "#EF4444"          # 写死色值,设计系统更新时契约失效

✅ 正确写法:

yaml 复制代码
visual_mapping:
  color_token: "status.critical"  # 语义令牌,设计系统更新时映射关系自动同步

错误 2:用户行动与后果不匹配

❌ 错误写法:

yaml 复制代码
# fatal 错误(对话已丢)只给"重试"按钮
user_action:
  - label: "重试"
    action: "retry"

✅ 正确写法:

yaml 复制代码
# fatal 错误需要"刷新"或"导出",因为对话已丢,重试无效
user_action:
  - label: "刷新页面"
    action: "refresh"
  - label: "导出历史"
    action: "export_history"

错误 3:LLM 约束不可执行

❌ 错误写法:

yaml 复制代码
llm_constraints:
  - "文案要友好一点"          # 无法机器校验,什么叫"友好"?

✅ 正确写法:

yaml 复制代码
llm_constraints:
  - "禁止仅显示'出错了'等模糊文案"  # 可机器校验:检查文案是否包含"出错了"
  - "必须包含后果说明"              # 可机器校验:检查文案是否包含"可能已丢失"等后果词

十二、下一步:写完后怎么编译

写完 YAML 契约后,下一步是编译为消费格式。详见下一章《从契约到消费格式:编译》。

一份 ERR-001.yaml 会编译为:

  • Prompt 前缀:供 Claude Code / Cursor 使用
  • JSON Schema:供结构校验使用
  • Checklist:供设计师人工走查使用
  • CI 规则:供自动化流水线使用
相关推荐
不加辣椒1 小时前
第21章 内容创作领域的提示词工程
人工智能
sunneo1 小时前
S16.1第一性原理做产品(1):从《创新者的窘境》看AI颠覆——为什么大模型不是护城河
人工智能·产品运营·产品经理·ai编程·ai-native
EMBA寰球网1 小时前
互动展厅设计核心逻辑、实施路径与落地实施要点专业解析:名瑞展览展陈行业实践深度洞察
大数据·人工智能
aiqianji2 小时前
有哪些支持长文的AI生成短篇小说软件?
人工智能·python
lisw052 小时前
人-智能体协同的信任研究!
人工智能·机器学习·软件工程
ofoxcoding2 小时前
Codex Computer Use 完整指南:AI 自动操控 Mac 与 Windows 桌面实战详解
人工智能·windows·macos·ai
OpenCSG2 小时前
第三场黑客松!OpenCSG联合主办南京都市圈OPC超级个体挑战赛正式启动
人工智能·开源·开放传神
甄同学2 小时前
第十五篇:Stream Processor流式处理器,实时响应的幕后机制
人工智能
甲维斯2 小时前
太热闹了!gpt5.6来了,Codex无了,claude重置了!
人工智能
龙腾AI白云2 小时前
标注数据短缺对通用AI产业化的影响与对策
人工智能·pygame·dash