Ontology 即代码与测试

第 6 课 · 共 6 课 约 9 分钟

定义写成目录里的文件;在文件、分支、合并后三个层次各试一次;把检查放进流水线。

本课目标

读完这一课,你将能够

  • 把本体(Ontology)写成目录里的定义文件,并用 --dry-run 检查
  • 说出在文件、分支、合并后三个层次各能试什么
  • 把检查放进持续集成,并说清测试替身在 AIDC 里目前是什么状态

定义写成文件

本体就是一批定义,定义就是 JSON。把它们放进一个目录、放进 Git,本体就有了和代码一样的待遇:能对比,能评审,能回到某个提交,能重复建出一模一样的一份。这就是「即代码」。它有一个前提:真源只有一个。文件是真源,就别再在网页上手改同一批定义,否则下一次提交会把网页上的改动盖掉:定义是「有则改」,同名的会被覆盖。

ontology/
  value-types.json         # customerTier、orderStatus …
  object-work-order.json   # WorkOrder
  links.json               # lineWorkOrders、orderWorkOrders …
  actions.json             # hold-work-order、report-output …

新 Object Type 用 PascalCase,例如 WorkOrder。存量小写名仍兼容。定义有六种 kind:valueType、sharedPropertyType、interfaceType、objectType、linkType、actionType。一个目录就是一批,整批一起校验,批内互相引用算数;引用不闭合,一条也不写。下面是示例工厂里「暂停工单」的定义,它带着一条给智能体看的 toolDescription。

{
  "kind": "actionType",
  "apiName": "hold-work-order",
  "title": "暂停工单",
  "schema": {
    "parameters": [
      { "name": "workOrder", "type": "object", "objectType": "WorkOrder", "required": true },
      { "name": "reason", "type": "string", "maxLength": 200 }
    ],
    "rules": [
      { "type": "modifyObject", "objectType": "WorkOrder", "object": "$workOrder", "values": { "status": "paused" } }
    ],
    "actionLog": true,
    "toolDescription": "Pause a running work order when a quality or material problem stops the line."
  }
}

写之前先试跑

定义要改的是所有人共用的东西,所以每一层都留了一次不落库的演练。从近到远有三个层次:文件、分支、合并之后;分支这一层又分试跑和预览。

  1. 文件:define --dry-run

    只检查,不写。整批引用是否闭合,相对上一个语义版本有哪些破坏性变更:删类型、删属性、改类型、改主键、Action 删参数或新增必填参数。

  2. 分支:branch modify --dry-run

    先试跑,再真的放到分支上;--expected-version 让别人改过的分支不被你覆盖;branch validate 看合并检查,branch conflicts 看和 main 冲突的地方。

  3. 预览:读命令加 --branch

    用分支上的定义回答真实的问题,确认你要的东西读得出来。

  4. 合并之后:只校验与预演

    新 Action 合并后用 apply --validate-only 逐项校验;工作流和应用的 API 用 --preview,只算不写。

aidc semantic define ontology/ --dry-run
aidc semantic branch create add-hold
aidc semantic branch modify add-hold ontology/ --dry-run
aidc semantic branch modify add-hold ontology/ --expected-version 0
aidc semantic branch validate add-hold
aidc semantic action-types hold-work-order --branch add-hold
# 合并之后
aidc semantic apply hold-work-order --param workOrder=WO-1001 --validate-only

有一个界线要记住:分支上改的是定义,数据只有一份。所以一个只存在于分支上的新 Action 还不能被执行,它要合并进 main 才能用;在分支上你能验证的是定义本身,以及读得出来什么。

放进持续集成

这些命令都是非交互的,输出 JSON,退出码固定,所以直接放进流水线:任何一步退出码不是 0 就停。凭证用环境变量 AIDC_API_KEY,别把 Key 写进仓库。

set -e
export AIDC_API_KEY="$CI_AIDC_KEY"
aidc semantic define ontology/ --dry-run --json
aidc semantic branch create "$BRANCH" --json
trap 'aidc semantic branch discard "$BRANCH"' EXIT     # 临时分支:成功失败都清掉
aidc semantic branch modify "$BRANCH" ontology/ --expected-version 0 --dry-run --json
aidc semantic branch modify "$BRANCH" ontology/ --expected-version 0 --json
aidc semantic branch validate "$BRANCH" --json

分支不要一直挂着:35 天没有活动会转成 INACTIVE,再过 7 天,分支上的数据就删除。流水线里建的临时分支用完就 discard。人直接定义并合并之后,aidc semantic publish --notes "…" 发一个语义版本 vN,版本号只增,定义没变就不占号。

平台的合并检查已经替你做了一部分:引用闭合、名字唯一、主键规则、可编译、无冲突、破坏性已确认。团队自己的规则要自己加,比如「Action 名必须是 kebab-case」「每个 Action 必须写 toolDescription」:写成一个读定义目录的小脚本,放在这几步前面。

测试替身与种子数据

单元测试不该依赖网络和真实数据。常见的做法是测试替身:一个和真客户端长得一样的假客户端,你提前告诉它「被这样问,就这样答」,被测代码分不出真假。好的替身有三样:返回的对象和真的一个形状;能预设查询、聚合和 Action 的返回;还能让某一次调用失败,好测错误分支。服务端也有对应的做法:本地起一个假服务,装上种子数据。

  • 试跑:--dry-run 检查定义,不落库。
  • 只校验:$validateOnly 与 --validate-only,逐项看参数和提交条件。
  • 预演:工作流与应用的 API 用 --preview,只算不写。
  • 分支预览:读命令加 --branch,用分支上的定义读。
  • 种子数据:AIDC 自己的示例本体(命名空间 cell-demo,数据全是虚构的)把定义放一个目录、数据放另一个,用只含公开命令的脚本灌进一个空命名空间:define、publish、data import --layer source、apply-batch。

灌种子有一个坑:定义和对象导入可以重跑,链接和 Action 会再记一次账,所以重跑前先确认命名空间是空的。你需要一家只放虚构数据的测试公司,才能放心地反复灌。

要点

  • 定义就是 JSON,一个目录是一批,整批校验引用闭合;真源只留一个。
  • 三层试跑:文件(define --dry-run)、分支(branch modify --dry-run、validate、--branch 预览)、合并后(--validate-only、--preview)。
  • 分支上改的是定义,数据只有一份;--expected-version 防止覆盖别人的改动。
  • 命令非交互、退出码固定,能放进流水线;分支 35 天无活动转 INACTIVE,再 7 天删除。
  • 测试替身是概念:AIDC 目前还没有现成的模拟客户端,靠试跑、只校验、预演、分支预览和种子数据。

练一练

把示例工厂放进一个目录

纸上做即可;有一个测试命名空间的话,可以真的跑 --dry-run。

把 WorkOrder、ProductionLine 和 lineWorkOrders 放进三个定义文件,写出目录结构和每个文件的 kind。

小测

选一个答案,马上看解析。

Q1aidc semantic define ontology/ --dry-run 主要帮你确认什么?

Q2为什么不能在分支上检查一个只存在于分支的新 Action 的「只校验」?

Q3今天在 AIDC 里,怎样做到「不碰真数据也能测」?

延伸阅读