效果:动作、分析、通知与兜底

第 3 课 · 共 7 课 约 9 分钟

区分组织级效果与工作流步骤,设置通知去重,并处理失败对象的兜底。

本课目标

读完这一课,你将能够

  • 说出效果的种类,并对到 AIDC 的步骤上:use、compute、model、notify
  • 写出一个调用 Action 的 use 步骤,并说清提供方要登记与导出什么
  • 说出通知的去重、冷却与每日上限,并区分组织级兜底效果和应用工作流的失败处理

效果有哪几类

条件成立后,自动化执行一个或多个效果。组织级支持 Action、Function 和邮件通知。应用工作流用步骤调用能力、计算、模型分析和通知。

ACTION

提交 Action

对触发的对象执行 Action,可以一次给全部对象、按批、按分组或逐个执行。AIDC:use 步骤调用一个 kind: "action" 的能力。

MODEL

模型逻辑

让模型读数据、做判断、产出改动或提案。AIDC:model 步骤,按 output 声明的字段返回,它自己不写数据。

FUNCTION

执行 Function

执行代码写的 Function。组织级 function 效果运行已发布版本,使用隔离运行时;返回的对象编辑不生效。工作流 compute 只计算表达式,不等同 Function。

NOTIFY

通知

工作流 notify 支持邮件、企业微信和钉钉。组织级 notification 效果发邮件,收件人是 AIDC 账号。

步骤之间没有单独的「顺序」开关:表达式里引用了前面步骤的结果(如 steps.mat.row),就依赖它。平台按依赖分层,同一层的步骤并行;想强制先后,就写 after。一个工作流最多 40 个步骤。use 也用来读:调用 query、get、aggregate 类的能力,查到的行交给后面的步骤。

写一个 Action 效果

示例工厂的③:检验被判为不合格,就建缺陷、暂停工单、通知质量负责人。三件事互不依赖,放在同一层并行。下面是清单的关键部分:

{
  "slug": "inspection-failed",
  "semantic": { "types": ["inspection"], "actions": [] },
  "limits": { "notificationsPerDay": 20 },
  "workflow": {
    "input": {
      "inspection_id": { "type": "text", "required": true },
      "work_order_no": { "type": "text", "required": true }
    },
    "trigger": {
      "manual": { "roles": ["developer"], "preview": "members" },
      "change": {
        "type": "inspection",
        "when": "=object.result == 'fail'",
        "cooldown": "1d",
        "input": { "inspection_id": "=object.inspectionId", "work_order_no": "=object.workOrderNo" }
      }
    },
    "steps": [
      { "id": "defect", "kind": "use", "title": "Record the defect",
        "use": "factory-ops/flag_defect",
        "with": { "defect_id": "=concat('D-', input.inspection_id)", "inspection_id": "=input.inspection_id", "severity": "major" } },
      { "id": "hold", "kind": "use", "title": "Hold the work order",
        "use": "factory-ops/hold_work_order",
        "with": { "work_order_no": "=input.work_order_no", "reason": "=concat('Inspection ', input.inspection_id, ' failed')" } },
      { "id": "mail", "kind": "notify", "title": "Tell the quality lead",
        "to": ["quality.lead@example.com"],
        "subject": "Inspection {{ input.inspection_id }} failed on work order {{ input.work_order_no }}",
        "body": "The system is recording a defect and holding the work order. If either is missing, check the run record.",
        "dedupe": "=input.inspection_id", "cooldown": "1d" }
    ]
  }
}
  • use 写成「应用 slug/能力名」,with 是能力的输入。factory-ops 是另一个已发布的应用,它把 Action 导出成能力。
  • 缺陷编号由检验号派生(D- 加检验号),同一次检验重跑,不会出现第二条缺陷。第 5 课细讲。
  • 预演(preview)时,Action 只返回将要写入的计划,不落库;通知只给出内容,不发。

提供方先把 Action 登记进 semantic.actions。平台可自动提取为 <slug>/<Action> 能力。推荐用 exports 显式导出,定义输入和返回字段。下面把 kebab-case 的 Action 映射为 snake_case 的能力名:

"semantic": {
  "types": ["inspection", "workOrder", "defect"],
  "actions": ["flag-defect", "hold-work-order"]
},
"exports": [
  { "name": "flag_defect", "kind": "action", "title": "Record a defect", "action": "flag-defect",
    "input": {
      "defect_id": { "type": "text", "required": true },
      "inspection_id": { "type": "text", "required": true },
      "severity": { "type": "text", "required": true }
    },
    "params": { "defectId": "=input.defect_id", "inspectionId": "=input.inspection_id", "severity": "=input.severity" } },
  { "name": "hold_work_order", "kind": "action", "title": "Hold a work order", "action": "hold-work-order",
    "input": {
      "work_order_no": { "type": "text", "required": true },
      "reason": { "type": "text", "required": false }
    },
    "params": { "workOrder": "=input.work_order_no", "reason": "=input.reason" } }
]

能力不能超出提供方自己的登记:没登记的 Action,工作流碰不到。这也是后面几节做关口的基础。

通知效果:一件事只说一次

标准模型的通知可以发给固定的收件人,也可以按对象的属性算出收件人;多个对象同时触发时,可以合成一条,也可以按分组或逐个对象各发一条。

工作流 notify 的收件人写在清单里。邮件收件人必须是本组织账号,邮箱已验证;企业微信和钉钉目标写在 im 里。标题与正文用 {{ }} 插入前面步骤的结果。相同 dedupe 在 cooldown 内只认领一次;被拦下的记为「已拦下」,不算步骤失败。

5每个 notify 步骤的 to 最多 5 个邮箱;im 最多 5 个目标
6 小时同一个去重键的缺省冷却
20每个应用每天最多认领的通知条数(缺省);多人、多通道仍算一条

合并方式也对得上:input 映射到对象,一个对象一封邮件;input 留空,一批变化一封汇总邮件。③ 的邮件不引用写入步骤的输出,内容只写事实,不写「已经暂停」,所以写入失败时邮件照样发出。

兜底:组织级与工作流分别处理

标准模型给 Action、模型逻辑和函数效果配「兜底效果」:主效果遇到不可重试的失败,或重试用完之后,执行另一个效果。它拿得到原始输入和错误信息,可以报错、记账或走备用路径。有一条规矩:兜底成功,也不会让后面的效果继续。

  • 关键通知不要排在写入后面:③ 的邮件与写入同层,写入失败,邮件照发。
  • 让写入重跑无害,这样失败之后放心重新运行。
  • 用一个定时的「结果看门狗」,盯该发生却没发生的事。这两条第 5 课细讲。

要点

  • 组织级效果有 action、function 和邮件 notification。工作流用 use、compute、model、notify;compute 不等同 Function。
  • 工作流调用 Action,提供方先登记进 semantic.actions。平台可自动提取能力;推荐用 exports 显式定义输入和返回字段。
  • 同层步骤并行;一个步骤失败,同层其余步骤照跑,后面各层不再执行,已写入的不回滚。
  • 通知靠 dedupe、cooldown(缺省 6 小时)和每日上限(缺省 20 条)。一条发给多人、多个通道仍算一条。
  • 组织级用 fallbackEffects 处理重试后的失败对象。工作流把关键通知放在同层,写入要能重跑,并用结果看门狗补充检查。

练一练

读清单,再写一个效果

三个练习,前两个用示例工厂的 ③ 和 ④。

对着 ③ 的清单回答:如果 hold 步骤失败(工单已经完成,不能再暂停),缺陷记录和邮件会怎样?这次运行的状态是什么?

小测

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

Q1③ 里为什么把「建缺陷」「暂停工单」「通知」放在同一层,而不是一个接一个?

Q2推荐怎样为工作流显式导出 Action flag-defect?

Q3同一个物料一个上午被判了很多次,怎样避免通知变成邮件风暴?

延伸阅读