NocoBase 接 AI API:把“请求生成”和“结果写回”分开,避免更新字段再次触发

在 NocoBase 里给一条记录补 AI 摘要时,有个容易忽略的边界:工作流把摘要写回原记录,这次更新又可能成为下一次调用的触发条件。下面用工单摘要举一个配置方案。

利益关系说明:我参与 Tokatlas 多模型 API 平台。本文由 AI 辅助整理,讨论的是 NocoBase 侧的触发和写回设计,不依赖某个模型的效果。

1. 先把字段的职责分开

在工单表中准备:

字段 示例类型 用途
source_text 多行文本 需要摘要的原文
ai_requested 布尔,默认 false 用户明确请求生成
ai_status 单选 idle / processing / needs_review / failed
ai_draft 多行文本 候选摘要
ai_error 多行文本 经脱敏的错误原因

只允许授权用户修改 ai_requested;不要让模型返回值决定它,也不要把模型输出直接当成工单状态变更指令。

2. 只监听请求字段

新建“数据表事件”工作流,选择工单表:

  • 触发时机:记录更新后。
  • 发生变动的字段:只选 ai_requested,不留空。
  • 触发数据条件:ai_requested = true;ai_status 不等于 processing;source_text 不为空。

开始节点后,先按“主键 = 触发数据的主键”更新这一条工单:ai_requested=false、ai_status=processing。不要使用无筛选条件的更新节点。

这次写回虽然改变了 ai_requested,但新值为 false,不满足触发条件。之后写 ai_draft、ai_status、ai_error 时,也不应因为这些字段变化而启动新的生成请求。

这个设计是防止自己写回造成循环,并不是并发锁,也不保证 exactly-once。两个并发请求仍需要服务端原子领取任务或独立任务表去重。

3. 再接 HTTP 请求与结果处理

先用不含私人信息的样例,例如“订单 A-17 需要更换收件地址,请客服联系客户确认”,跑通数据流。HTTP 请求节点的 URL、鉴权、模型名和请求体,按实际使用的 API 文档配置;密钥留在服务端配置,不写进页面脚本或分享截图。

成功分支也要检查响应格式、摘要是否为空,以及是否包含原文没有的承诺。合格候选写入 ai_draft,状态设为 needs_review,由人决定是否采用。这里不自动发消息、不修改订单。

如果启用“忽略失败请求并继续”,必须在后续显式分支检查响应状态与内容,不能把错误正文写进 ai_draft。节点报错或超时可能直接终止执行,因此不要假定后面的 failed 写回节点一定会运行;为长期停在 processing 的记录准备独立核查与恢复路径。

4. 用这些动作检查触发边界

动作 预期行为
用户把 ai_requested 从 false 改为 true 启动一次生成流程
工作流重置 ai_requested=false 不因重置再次调用
只修改 ai_draft 或审核状态 不再次调用
HTTP 超时 查看执行历史,核查 processing 记录,不自动无限重试
两次并发请求 交给原子任务领取/去重机制,不靠布尔字段保证互斥

在 NocoBase 的执行历史中核对触发次数和失败节点。若改用批量更新、SQL 节点或直接数据库写入,不要假定它们和应用内单条更新有相同的事件行为。

参考:官方数据表事件文档。

你们会把 AI 任务状态放在业务记录上,还是拆成独立任务表?如果需要保留多次生成和人工修改的对照,独立任务表通常更容易区分每次输入与结果。