函数里改数据
编辑函数用 ctx.edits 收集改动,由 Action 提交;规则与对象集参数做批量修改;Action 配置 webhook。

本课目标
读完这一课,你将能够
- 说出函数怎样改数据,以及改动什么时候才真正生效
- 分清什么时候规则就够、什么时候需要函数驱动的 Action
- 在 AIDC 里用规则与对象集参数做批量修改,并说清它和暂存写入的差别
函数怎样改数据
函数不直接写库。它返回一份「改动清单」:新建、修改、删除哪些对象,建立或解除哪些关系。这份清单只有被一个 Action 采用,才会真正生效。在开发环境里试跑一个改数据的函数,得到的只是清单,对象一点没变。
- 01函数计算读对象,算出要改什么
- 02返回改动清单新建、修改、删除、建关系
- 03Action 采用校验参数与提交条件
- 04事务写入全改成或都不改,并留记录
什么时候规则写不下?三种情形最常见:
- 要改的对象靠关系连着,个数运行时才知道,例如关掉一张订单下的全部工单;
- 要写的值得读好几个对象才算得出来,例如按各条产线的余量挑一条;
- 要一次新建几种对象,再把它们连起来。
这样的 Action 叫函数驱动的 Action。它依然受 Action 的上限约束(一次最多改 10,000 个对象、涉及 50 个对象类型),也受函数运行上限的约束。被批量触发时,函数默认按请求逐个调用;也可以让函数一次收到整批(入参是一个结构列表),更快,也少一些冲突。
Action 的 webhook 输入可引用参数、对象参数属性或字面量。规则和 side effect 还可用 $writeback.<输出名>。用函数计算 webhook 输入、用函数渲染通知正文仍待补,不能当成现有能力。
一个坑,和它的补救
坑:函数里改了对象,紧接着在同一个函数里搜索,搜到的还是旧数据。改动要等函数执行完才传到对象集接口;只有按主键取回你刚改的那个对象,才会看到新值。
补救:标准模型又提供了暂存写入(Beta):改动先暂存,函数里之后的读取都看得到,也就是先写后读;函数成功结束、Action 完成时才一起提交;中途出错,暂存的全部丢弃。
| 常规的改数据函数 | 暂存写入 | |
|---|---|---|
| 读得到自己刚写的吗 | 读不到,要等函数结束 | 读得到 |
| 返回值 | 必须是那份改动清单 | 可以返回别的信息,改动自动暂存 |
| 调用别的会改数据的函数 | 不支持 | 支持,改动一起暂存、一起提交 |
在 AIDC 里:规则、对象集参数、先预演
AIDC 已支持编辑函数。用 aidc semantic functions publish edits.js --api-name holdWorkOrders --version 1.0.0 --output '{"type":"integer"}' --edit-function 发布。函数用 ctx.edits 收集改动,由调用它的 Action 统一提交。简单的批量修改仍可用规则:一个 Action 的多条规则在同一事务提交。参数可以是对象集,一条 modifyObject 规则就修改命中的对象。下面的 eachIs 要求每张工单都满足提交条件:
{
"kind": "actionType",
"apiName": "hold-work-order",
"title": "Hold work orders",
"schema": {
"parameters": [
{ "name": "workOrders", "type": "objectSet", "objectType": "workOrder", "title": "Work orders", "required": true },
{ "name": "reason", "type": "string", "title": "Reason", "required": true, "maxLength": 200 }
],
"rules": [
{ "type": "modifyObject", "objectType": "workOrder", "object": "$workOrders", "values": { "status": "paused" } }
],
"submissionCriteria": [{
"condition": { "type": "comparison", "left": { "param": "workOrders", "property": "status" }, "operator": "eachIs", "right": { "literal": "running" } },
"failureMessage": "Only running work orders can be paused"
}],
"actionLog": true
}
}
「个数运行时才知道」这个问题,在 AIDC 里这样解决:调用方把「这条产线上运行中的工单」这个对象集本身交给 Action,Action 在执行的那一刻才把它展开成具体的对象。提交条件也按展开时对象的当前值判断:上面的 eachIs 会确认每一张都还在运行中,只要有一张不是,整批被拒绝,什么都不改。一次最多改 10,000 个对象;applyBatch 一次最多 20 个请求,同在一个事务里。
没有暂存写入,就用三样东西拿到相近的保护:
- 只校验(
$validateOnly):逐项看参数和提交条件的结果,什么都不写; - 工作流预演:读、算照跑,Action 只返回将要写入的计划;
- 草稿加批准:例如智能体起草一张采购订单,采购员用
approve-purchase-order批准。
要点
- 函数返回改动清单,要被一个 Action 采用才生效;试跑不会改对象。
- 个数运行时才知道,或要读多个对象才能算值,才需要函数驱动的 Action。
- 函数里搜不到自己刚改的数据;暂存写入提供先写后读,并在结束时一起提交。
- AIDC 里用多条规则加对象集参数做批量修改,提交条件按执行时的对象值判断,并用只校验、预演和草稿加批准把关。
练一练
用规则写「下达工单」
示例工厂的 release-work-order:把计划中的工单下达到一条产线。
参数:workOrder(对象)、line(productionLine 对象)。一条 modifyObject 规则:status 改为 released,lineCode 取 $line.lineCode。提交条件:工单当前状态必须是 planned,并写好失败信息。
用 aidc semantic apply release-work-order … --validate-only 试一张状态不是 planned 的工单,看退出码和失败信息。
「把一张订单下的全部工单设为 paused」「把一张工单改为 released」「按各产线余量自动选一条并下达」:哪些靠规则加对象集参数就写得下,哪些需要函数?差的那一块,智能体或工作流怎样补上?
小测
选一个答案,马上看解析。
Q1在开发环境里试跑一个改数据的函数,对象会变吗?
函数只描述要改什么;校验、写入和记录都是 Action 的事,所以在开发环境里放心试跑。
Q2在 AIDC 里一次暂停一条产线上运行中的十张工单,最合适的是?
一个 Action 一个事务,要么十张都暂停,要么都不改。分十次提交是十个事务。要改源系统,给 Action 配置 writeback webhook。
Q3函数里改了一个对象后马上搜索,为什么可能搜不到新值?
这是常规改数据函数的已知限制;暂存写入就是为了提供先写后读。