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

本课目标
读完这一课,你将能够
- 把本体(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."
}
}
写之前先试跑
定义要改的是所有人共用的东西,所以每一层都留了一次不落库的演练。从近到远有三个层次:文件、分支、合并之后;分支这一层又分试跑和预览。
- 文件:
define --dry-run只检查,不写。整批引用是否闭合,相对上一个语义版本有哪些破坏性变更:删类型、删属性、改类型、改主键、Action 删参数或新增必填参数。
- 分支:
branch modify --dry-run先试跑,再真的放到分支上;
--expected-version让别人改过的分支不被你覆盖;branch validate看合并检查,branch conflicts看和 main 冲突的地方。 - 预览:读命令加
--branch用分支上的定义回答真实的问题,确认你要的东西读得出来。
- 合并之后:只校验与预演
新 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。
写一个小脚本的伪代码:读 ontology/ 下所有 Action 定义,没有 toolDescription 的就以退出码 1 结束。
把这七步排成一条流水线:branch create、define --dry-run、branch modify、branch validate、branch modify --dry-run、action-types … --branch、branch discard;标出哪几步失败时要立刻停下。
小测
选一个答案,马上看解析。
Q1aidc semantic define ontology/ --dry-run 主要帮你确认什么?
试跑只检查定义本身:引用闭合与破坏性变更,不涉及数据,也不写任何东西。
Q2为什么不能在分支上检查一个只存在于分支的新 Action 的「只校验」?
分支上能验证的是定义和读得出来什么;执行与校验 Action 要等它合并进 main。
Q3今天在 AIDC 里,怎样做到「不碰真数据也能测」?
模拟客户端目前还没有;今天靠试跑、只校验、预演、分支预览,以及像示例本体那样的种子数据。