Skill Wiki v0.1.0

文档 / spec / contracts

本页目录

组合契约

contract 块用来声明哪些原子必须(或绝不能)同时加载。 这样 agent 加载父原子时,拿到的一定是一个完整可用的集合。

为什么需要 contract

agent 可以自由组合原子,但不是每种组合都安全。一个 method 往往要靠某条 term 同时在场,指令才有意义; 或者它根本不能和对立的 anti-pattern 一起加载,否则模型只会胡说八道。 contract 就是把这类约束写成可声明、可校验的规则。

三种 contract 子句

子句含义运行时行为
must-include父原子一旦加载,这些原子也会被一起加载。自动并入 agent 的原子集合。
must-avoid这些原子不能与父原子共存。从候选里过滤掉;强行加载会触发警告。
conditionally-required满足条件时才必须加载。L3 阶段对照 IntentObject 求值。

contract 能挂在哪些 kind 上

contract 可以声明在下面这些 kind 上:

  • method:最常见。每一步都得有对应的 term / fact / source 撑着。
  • persona:定义这个姿态对应的 voice 和配套原子。
  • scope:声明一个排他子集(比如 "regulated-fintech-mode")。
  • collection:隐式约束,所有成员都视为 must-include

例子

method PanSauce {
  id: "@recipes/method-pan-sauce"
  version: "1.0.0"
  description: "Build a pan sauce from fond after searing."
  domain: cooking

  steps: [
    @recipes/step-deglaze,
    @recipes/step-reduce,
    @recipes/step-mount-with-butter,
  ]

  contract: {
    must-include: [
      @recipes/term-fond,
      @recipes/term-deglazing,
      @recipes/fact-water-evaporation-temp,
    ]
    must-avoid: [
      @recipes/anti-pattern-microwave-reduce,
    ]
    conditionally-required: [
      { when: "vegetarian:true", include: [@recipes/value-stock-vegetable] },
    ]
  }
}

运行时如何解析

当检索器把 method-pan-sauce 选为命中,运行时会顺着 contract 走一遍, 把 term-fondterm-deglazingfact-water-evaporation-temp 一并放进 agent 的原子集合,同时把 anti-pattern-microwave-reduce 标记为本轮不可加载。

agent 永远不会拿到一个只解析了一半的集合。少掉的 must-include 在编译期就会以 L3 错误的形式暴露, 所以运行时跑到 agent 面前的,一定是已经校验通过的 contract。

contract 与显式边的区别

contract 比 requires 边的承诺更硬。requires 这个 verb 表达的是 "加载 A 的时候,建议也加载 B";而 contract 的 must-include 表达的是 "协议层面保证:A 一旦加载,B 必然也加载"。只要正确性依赖于这种打包关系,就用 contract。