跳到主要内容

进阶案例一:技术研发封装复杂逻辑给业务运营使用

内容概述

基础文档展示了最简单的场景:用户说一句话,AI 自动创建需求。但 ToB 业务里大量操作远比单表增删改复杂——比如修改需求状态,必须同时更新主表、写入历史记录、通知相关人,缺一不可。

本案例以「需求状态变更」为例,展示:当业务逻辑涉及多表写入、状态流转校验、事务一致性时,技术团队如何开发函数接口,AI 加载 Skill 后一句话完成整个流程。


业务场景:为什么需要函数接口

在基础文档的例子里,AI 直接操作数据库就够了。但现实业务中,很多操作有更严格的要求:

强校验:状态必须按顺序流转(新建 → 指派 → 进行中 → 测试 → 完成 → 关闭),不能从新建直接跳到完成。

数据一致性:改状态时,必须同步记录谁改的、什么时候改的、从哪改到哪——主表和历史表必须同时更新,不能一张成功一张失败。

事务性:一个操作涉及多张表,任何一张表写失败都要回滚。

遇到上述场景,需要技术团队开发函数接口,封装校验逻辑和事务保证,注册到平台后供 AI 调用。业务人员不需要知道函数里写了什么 SQL、做了几次写入,只需要调用接口,数据一致性由技术保证。


技术实现:开发函数

注册路径

独立端点脚本(ENDPOINT),注册后通过以下路径访问:

POST /api/endpoint/{appCode}/{scriptName}

本案例使用:

  • 脚本名称: update_requirement_status
  • 应用: app-173e8652(启智云图)
  • 完整路径: POST /api/endpoint/app-173e8652/update_requirement_status

前置依赖

技术团队开发前需确认:

  • 应用 app-173e8652 已创建并拥有 yt_requirements(需求主表)和 yt_requirement_history(状态历史表)两个数据模型
  • 操作人有写入这两个模型的权限

函数代码

技术团队实现需求状态变更,同时完成主表更新和历史记录写入:

/**
* 需求状态变更(双写主表 + 历史表)
* 脚本名称: update_requirement_status
* 所属应用: app-173e8652
*/
export default async function updateRequirementStatus(params, context) {
const { id, new_status, operator_id, reason } = params;

// -------- 第一部分:查询校验 --------

// 1. 查询需求当前信息
const requirement = await context.client.models.yt_requirements.findOne({
id: id,
});

if (!requirement) {
throw new Error("需求不存在");
}

const oldStatus = requirement.status;

// 2. 校验状态流转是否合法
const validTransitions = {
new: ["assigned", "closed"],
assigned: ["in_progress", "closed"],
in_progress: ["testing", "closed"],
testing: ["completed", "in_progress"],
completed: ["closed"],
closed: [],
};

if (!validTransitions[oldStatus]?.includes(new_status)) {
throw new Error(
`状态不允许从 ${oldStatus} 直接变更为 ${new_status}`
);
}

// -------- 第二部分:双写(事务保证) --------
// 系统检测到写操作,自动开启 Best Effort 1PC 事务
// 无需手动 commit/rollback,脚本正常返回即提交,抛异常即回滚

// 3. 更新主表:需求状态
await context.client.models.yt_requirements.update({
id: id,
status: new_status,
});

// 4. 写入历史表:变更记录
await context.client.models.yt_requirement_history.create({
requirement_id: id,
user_id: operator_id,
field_name: "status",
old_value: oldStatus,
new_value: new_status,
created_at: new Date().toISOString(),
});

// -------- 第三部分:返回结果 --------
return {
success: true,
requirement_id: id,
old_status: oldStatus,
new_status: new_status,
operator_id: operator_id,
message: "状态变更成功,历史记录已同步",
};
}

事务机制说明

Lovrabet 平台采用 Best Effort 1PC 事务模型,技术团队无需手动管理事务:

时机行为
读操作(findOne / getList)不开启事务,不占连接
第一个写操作(update / create)自动开启事务
后续写操作自动加入同一事务
脚本正常返回自动提交所有事务
脚本抛出异常自动回滚所有事务

技术团队只需要按业务顺序编写逻辑,事务由平台自动管理。


Skill 封装:让业务人员一句话完成操作

函数接口开发完成后,业务人员如何使用?

把操作流程封装成 Skill,AI 加载后自动完成:确认需求存在 → 调用函数 → 通知相关人。

Skill 范本

---
name: update_requirement_status
version: 0.1.0
description: "需求状态变更。触发词:标记为已完成、把需求改为、变更需求状态。"
---

# 需求状态变更

## 第一步:确认需求存在

根据用户提供的需求 ID,查询该需求是否存在、当前状态是什么。如果不存在,告知用户并终止。

## 第二步:变更状态并记录历史

调用 update_requirement_status 接口,同时完成:
- 修改需求状态为用户指定的状态
- 在历史记录中新增一条状态变更记录(记录原状态、新状态、操作人、操作时间)

如果接口返回失败,告知用户失败原因,终止流程。

## 第三步:通知需求提出人

查询该需求的创建人,向其发送邮件或飞书消息,告知:
- 哪个需求的状态发生了变更
- 变更后的状态是什么

## 注意事项

- 状态值必须在合法范围内(new / assigned / in_progress / testing / completed / closed)
- 如果用户没有指定变更原因,询问后再继续
- 第三步的通知仅需告知结果,无需额外操作
- 禁止直接调用数据集原始接口

使用示例

用户输入

把需求 App主题根据用户手机壳颜色自动适配 标记为已完成

AI 自动完成

加载 Skill → 确认需求存在 → 调用函数接口(主表更新 + 历史表写入同时完成)→ 通知需求提出人

返回结果示例

✅ 状态更新完成
━━━━━━━━━━━━━━━━━━
需求 ID:305
标题:App主题根据用户手机壳颜色自动适配
状态:进行中 → 已完成
操作人:梓骞
变更历史:已记录
━━━━━━━━━━━━━━━━━━
通知:已发送邮件给需求提出人

常见问题

Q:开发函数接口需要自己搭基础设施吗?

不需要,在已有的 Lovrabet 应用下开发脚本并注册即可,事务、连接管理、权限控制都由平台提供。可以使用 Rabetbase CLI 开发者套件

Q:状态流转规则写在函数里会不会改起来麻烦?

比直接暴露数据库给 AI 安全得多。规则变更只需技术团队修改函数代码,Skill 和 AI Prompt 无需改动。

Q:函数接口报错怎么办?

检查返回的错误信息,常见原因包括:需求 ID 不存在、状态流转不合法、权限不足等。错误会直接透传给 AI,AI 会告知用户。

Q:业务人员需要了解状态值有哪些吗?

不需要,Skill 里已经定义好了合法状态值。业务人员只需要说「标记为已完成」,AI 自动映射到对应的状态码。

Q:后续要新增操作维度怎么办?比如加上优先级变更记录?

在函数里增加历史表字段即可,Skill 描述的是业务步骤,不涉及具体字段名。