@lark-apaas/coding-steering 0.1.42-alpha.20260827112854 → 0.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/steering/nestjs-react-fullstack/skills/plugin-guide/SKILL.md +9 -4
- package/steering/nestjs-react-fullstack/skills/plugin-guide/references/plugin-coding-guide.md +20 -9
- package/steering/nestjs-react-fullstack/skills_local/coding-guide/SKILL.md +5 -7
- package/steering/nestjs-react-fullstack/skills_local/plugin-guide/SKILL.md +6 -2
- package/steering/nestjs-react-fullstack/skills_local/plugin-guide/references/plugin-coding-guide.md +20 -9
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lark-apaas/coding-steering",
|
|
3
|
-
"version": "0.1.42
|
|
3
|
+
"version": "0.1.42",
|
|
4
4
|
"description": "Stack-specific steering content for miaoda-coding templates",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"steering"
|
|
8
8
|
],
|
|
9
|
-
"scripts": {
|
|
10
|
-
"lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
|
|
11
|
-
},
|
|
12
9
|
"devDependencies": {
|
|
13
10
|
"markdownlint-cli": "^0.47.0"
|
|
14
11
|
},
|
|
@@ -20,5 +17,8 @@
|
|
|
20
17
|
"miaoda",
|
|
21
18
|
"coding-steering"
|
|
22
19
|
],
|
|
23
|
-
"license": "MIT"
|
|
24
|
-
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"lint:md": "markdownlint 'steering/**/*.md' --ignore 'steering/**/skills/**' --ignore 'steering/**/skills_common/**' --ignore 'steering/**/skills_local/**'"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -20,6 +20,7 @@ gate-tools:
|
|
|
20
20
|
| 获取运行时投影 | 调用 `get_plugin_ai_json(pluginInstanceId)` |
|
|
21
21
|
| Client 侧调用 | `capabilityClient.load(id).call(actionKey, input)`(流式用 `callStream`) |
|
|
22
22
|
| Server 侧调用(仅兜底) | `capabilityService.load(id).call(actionKey, input)` |
|
|
23
|
+
| 长耗时 AI 结果 | 大体量/多字段/多份/多语言/文件或多模态串联等结构信号命中时,优先前端 `callStream` 渐进展示;需保存则流式结束后复用 CRUD 落库;仅在 Client 侧无法满足时使用后端任务记录 + 状态查询 + 结果读取;禁止单个 HTTP 请求等待完整结果后才返回 |
|
|
23
24
|
| capabilityClient 导入 | `import { capabilityClient } from '@lark-apaas/client-toolkit'` |
|
|
24
25
|
| CapabilityService 导入 | `import { CapabilityService } from '@lark-apaas/fullstack-nestjs-core';` |
|
|
25
26
|
|
|
@@ -70,6 +71,7 @@ gate-tools:
|
|
|
70
71
|
- 必须先调 `get_plugin_ai_json(pluginInstanceId)`,再产出 **Schema 摘录卡**(格式见 `references/plugin-coding-guide.md`);摘录卡字段缺失禁止编码,`output.fields` 必须完整列出且每个输出字段在代码中被消费(持久化或展示)
|
|
71
72
|
- 按 `actions[].key` 选 actionKey;严格按 `inputSchema` 构造入参(`type: array` 字段必须传数组)、按 `outputSchema` 解析出参——流式 chunk 是**对象**(按字段解构如 `chunk.content`,禁止当字符串拼接),非流式同理按字段名读取;**务必阅读并遵循 `readme`**
|
|
72
73
|
- 调用侧:优先 Client(`unary` → `call()`,`stream` → `callStream()`);触发器/定时任务、敏感凭证、强事务、结果需落库 → Server 侧
|
|
74
|
+
- 高耗时 AI capability 闸门:若运行时投影或功能设计显示输出规模大、输出字段多、需要多份结果、多语言/长文本、文件或多模态输入后继续生成、多个 capability 串联、或结果需后续查看/落库,禁止把完整生成放进一个同步 HTTP 请求等待;能由前端承接时优先 `callStream` 渐进展示,需保存则流式结束后复用 CRUD 落库;仅在 Client 侧无法满足时后端创建任务记录后快速返回、由前端短轮询状态/结果,或拆成多个独立小调用
|
|
73
75
|
4. **代码放置**:Client(默认,用户交互触发)→ `client/` 组件/hooks;Server(兜底)→ `server/` Service。
|
|
74
76
|
5. **真实调用冒烟(完成前必须)**:至少成功调用一次 `call()` 或 `callStream()`(按 outputSchema 读 chunk);失败日志含最小字段(字段清单见 `references/plugin-coding-guide.md`)。无冒烟结果不得宣告完成。
|
|
75
77
|
|
|
@@ -136,6 +138,9 @@ const structured = await capabilityClient
|
|
|
136
138
|
├── 输出包含多个独立字段(标题+正文+评分等)
|
|
137
139
|
│ → 拆成多个独立插件并行调用(⭐ 优先)或用 ai-text-to-json
|
|
138
140
|
│ → ⛔ 禁止用 ai-text-generate + 正则/split 解析多字段
|
|
141
|
+
├── 输出规模大(多份结果、多语言、长正文、多章节或批量对象)
|
|
142
|
+
│ → 优先拆分为多个独立生成单元;需要汇总持久化时使用任务状态模型承接
|
|
143
|
+
│ → ⛔ 禁止一个后端 HTTP 请求同步等待所有生成结果后才响应
|
|
139
144
|
└── 输出为单一文本(仅展示,不需解析)→ ai-text-generate
|
|
140
145
|
```
|
|
141
146
|
|
|
@@ -203,9 +208,9 @@ const structured = await capabilityClient
|
|
|
203
208
|
|
|
204
209
|
1. **禁止静默吞异常**:每个 `catch` 至少满足其一——向用户展示错误(toast/页面状态),或触发补偿机制(重试/降级/记录待处理列表)
|
|
205
210
|
2. **异步操作必须有终态**:不阻塞主流程的插件调用须在 DB 维护状态(pending → success/failed),前端必须展示 failed,不能永远 loading
|
|
206
|
-
3.
|
|
207
|
-
4.
|
|
208
|
-
5.
|
|
211
|
+
3. **长耗时 AI 生成不得同步等完**:大体量、多字段、多份、多语言、文件/多模态串联或需要持久化的 AI capability 调用,触发接口必须快速返回任务状态或采用前端流式展示;若 `api_request`、浏览器操作或页面请求出现超时/连接断开,不能只凭服务端最终日志或数据库最终写入宣告成功,必须证明用户侧存在可读取的终态结果
|
|
212
|
+
4. **通知类插件失败必须有补偿**:如 `send-feishu-message` 失败,至少记录"待发送"列表或 UI 提示"通知发送失败,请手动联系"
|
|
213
|
+
5. **配置完整性(load 前必查)**:`load(id)` 前确认实例已创建且 id 与代码完全匹配,否则抛 `CapabilityNotFoundError`(开发态 Top 错误);load/call 失败时停止后续请求避免放大错误;**缓存 load 结果**,同一 id 不重复 load
|
|
209
214
|
|
|
210
215
|
## 缓存与幂等性
|
|
211
216
|
|
|
@@ -240,7 +245,7 @@ const structured = await capabilityClient
|
|
|
240
245
|
|
|
241
246
|
### 通知接收人动态解析
|
|
242
247
|
|
|
243
|
-
接收人(`receiverUserList`/`receiverGroupList` 等)按角色/条件变化时,必须实时查询角色成员经 `input` 传入(角色/成员的运行时查询写法见 `authz-guide` 技能),禁止硬编码或凭经验拼装 ID。如引入缓存,必须提供显式失效手段(如角色变更时清缓存)并明示 TTL,禁止无失效手段的常驻缓存导致接收人信息过期。通知发送失败的补偿要求见上文「插件调用错误处理」第
|
|
248
|
+
接收人(`receiverUserList`/`receiverGroupList` 等)按角色/条件变化时,必须实时查询角色成员经 `input` 传入(角色/成员的运行时查询写法见 `authz-guide` 技能),禁止硬编码或凭经验拼装 ID。如引入缓存,必须提供显式失效手段(如角色变更时清缓存)并明示 TTL,禁止无失效手段的常驻缓存导致接收人信息过期。通知发送失败的补偿要求见上文「插件调用错误处理」第 4 条铁律,不重复展开。
|
|
244
249
|
|
|
245
250
|
## 飞书深链 URL 规范
|
|
246
251
|
|
package/steering/nestjs-react-fullstack/skills/plugin-guide/references/plugin-coding-guide.md
CHANGED
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
### 核心原则:根据场景选择调用侧
|
|
4
4
|
|
|
5
|
-
**默认优先在 Client 侧调用 capabilityClient
|
|
5
|
+
**默认优先在 Client 侧调用 capabilityClient;流式或高耗时 AI 生成优先 `callStream` 渐进展示。结果需要持久化时,优先在流式结束后通过已有后端接口保存;只有 Client 侧无法满足时才切到 Server 侧。**
|
|
6
|
+
|
|
7
|
+
**高耗时 AI capability 先判调用形态**:只要输出规模大、输出字段多、需要多份结果、多语言/长文本、文件或多模态输入后继续生成、多个 capability 串联、或结果需后续查看/落库,就不得把完整 AI 结果塞进一个同步 HTTP 请求等待。能由前端承接时,优先用前端 `callStream` 渐进展示,并在流式结束后按需复用已有 CRUD 接口保存结果;只有 Client 侧无法满足(触发器/敏感凭证/强事务/必须由后端保证落库一致性等)时,才采用后端任务记录 + 状态/结果查询,避免把后台任务作为默认方案。
|
|
8
|
+
|
|
6
9
|
**严禁** import { capabilityClient } from '@lark-apaas/client-capability'。
|
|
7
10
|
**唯一指定**的导入方式是 import { capabilityClient } from '@lark-apaas/client-toolkit';
|
|
8
11
|
|
|
9
12
|
| 优先级 | 场景 | 调用方式 |
|
|
10
13
|
|-------|------|---------|
|
|
11
|
-
| **首选** |
|
|
12
|
-
| **首选** |
|
|
13
|
-
|
|
|
14
|
+
| **首选** | 绝大多数即时展示场景 | `capabilityClient.load(id).call()` |
|
|
15
|
+
| **首选** | 流式输出,或高耗时但可由前端承接的 AI 生成 | `capabilityClient.load(id).callStream()`(流式结束后按需持久化) |
|
|
16
|
+
| **必要时** | 高耗时且 Client 侧无法满足:触发器、敏感凭证、强事务、必须由后端保证落库一致性 | 后端任务记录 + 后台调用 `CapabilityService.load(id).call()` + 前端短轮询状态/结果 |
|
|
17
|
+
| **兜底** | Client 侧无法满足且单次调用可在交互边界内完成 | `CapabilityService.load(id).call()` |
|
|
14
18
|
|
|
15
19
|
#### 什么情况下应使用 Server 侧?
|
|
16
20
|
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
1. **涉及敏感凭证**:调用需要服务端私密 token/secret,不适合暴露给前端
|
|
20
24
|
2. **必须后端编排**:多个插件调用之间有强事务依赖,需要后端统一编排
|
|
21
25
|
3. **触发器/定时任务场景**:没有前端上下文,只能由后端发起
|
|
22
|
-
4.
|
|
26
|
+
4. **插件结果需要持久化**:调用结果需要保存到数据库;能由前端承接时,优先前端 `callStream` 渐进展示并在结束后复用已有 CRUD 接口保存;只有 Client 侧无法满足或必须由后端保证落库一致性时,才在 Server 侧调用并落库。若此时输出规模大、字段多、结果多份或需多步能力串联,必须改为任务记录 + 后台执行 + 状态/结果查询,避免一个 HTTP 请求等待完整生成
|
|
23
27
|
|
|
24
28
|
> **提示**:如果插件结果不需要存储、仅用于即时展示(如流式生成文本、发送消息),优先在前端调用。但当结果需要保存到数据库时,不要回避使用 Server 侧。
|
|
25
29
|
|
|
@@ -42,9 +46,13 @@
|
|
|
42
46
|
|
|
43
47
|
```
|
|
44
48
|
插件结果是否需要持久化到数据库?
|
|
45
|
-
├──
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
├── 否(一次性即时展示)
|
|
50
|
+
│ ├── `outputMode=stream` 或内容生成较慢 → Client 侧 `callStream()` 渐进展示
|
|
51
|
+
│ └── 单次短输出 → Client 侧 `call()`(默认)
|
|
52
|
+
└── 是
|
|
53
|
+
├── `outputMode=stream` 且前端可承接 → 推荐方案 A:Client 侧 `callStream()` 渐进展示,成功后通过已有 CRUD 接口保存结果
|
|
54
|
+
├── 输出较小且可在交互边界内完成、且必须由后端保证一致性 → Server 侧调用并在同一方法中落库
|
|
55
|
+
└── Client 侧无法满足且输出规模大/多字段/多份/多语言/多步骤 → 方案 B:Server 侧创建任务记录,快速返回任务状态;后台调用插件并落库;前端短轮询状态/结果
|
|
48
56
|
```
|
|
49
57
|
|
|
50
58
|
| 应避免的做法 | 推荐做法 |
|
|
@@ -271,10 +279,11 @@ function MultiPluginStreamExample({ recordId }: { recordId: string }) {
|
|
|
271
279
|
2. 一个 `stream` action 的真实调用结果(chunk 按 `outputSchema` 字段读取)
|
|
272
280
|
3. 调用失败时的最小日志字段齐全
|
|
273
281
|
4. 若无法执行真实调用,必须明确写明阻塞原因,禁止直接标记“开发完成”
|
|
282
|
+
5. 若用户触发 AI 生成的请求超时、连接断开或工具返回超时,必须判定为验收失败;只有触发请求快速返回、随后能通过页面或接口读到明确完成或失败终态和结果,才允许标记通过
|
|
274
283
|
|
|
275
284
|
### Server 侧调用方式(仅兜底场景)
|
|
276
285
|
|
|
277
|
-
> 以下场景适合使用 Server
|
|
286
|
+
> 以下场景适合使用 Server 侧调用;若前端 `callStream` + 既有 CRUD 保存即可满足展示和持久化,不要优先引入后端后台任务。
|
|
278
287
|
|
|
279
288
|
#### 1. 何时适合用 Server 侧?
|
|
280
289
|
|
|
@@ -285,6 +294,7 @@ function MultiPluginStreamExample({ recordId }: { recordId: string }) {
|
|
|
285
294
|
| 敏感凭证调用 | 凭证不能暴露给前端 | 调用需要 admin token 的 API |
|
|
286
295
|
| 强事务编排 | 多步骤需要原子性 | 创建记录 → 发通知 → 更新状态必须全成功或全回滚 |
|
|
287
296
|
| 插件结果需持久化 | 调用结果需保存到数据库 | AI 分类/摘要结果需落库、文档解析的结构化数据需入库、图片识别结果需关联业务记录、语音转文字结果需存档等 |
|
|
297
|
+
| 高耗时 AI 生成需后续查看 | 请求不能长期占用用户交互链路 | 批量、多版本、多语言、长文本、多字段结构化生成,或文件/多模态分析后再生成内容 |
|
|
288
298
|
|
|
289
299
|
#### 2. NestJS 注入方式
|
|
290
300
|
|
|
@@ -328,6 +338,7 @@ try {
|
|
|
328
338
|
|
|
329
339
|
- PluginInstance 调用在 Server 侧通常属于 **外部依赖 / side-effect**
|
|
330
340
|
- 除非业务明确要求强一致性,**默认不应阻塞主业务流程**
|
|
341
|
+
- 已选择 Server 侧承接的高耗时 AI capability 必须有可观测状态:创建任务时记录处理进度、完成终态、失败终态、输入摘要、错误信息和结果引用;触发接口只返回任务标识与当前状态,前端通过短轮询读取进度和最终结果
|
|
331
342
|
|
|
332
343
|
推荐写法:异步触发 + catch 兜底:
|
|
333
344
|
|
|
@@ -443,7 +443,7 @@ NestJS 自己不读 env。直连 NestJS 端口 → header 缺失 → `req.userCo
|
|
|
443
443
|
|
|
444
444
|
- **框架**: React 19 + TypeScript
|
|
445
445
|
- **路由**: React Router DOM v6
|
|
446
|
-
- **样式**: tailwindcss(语义化 token
|
|
446
|
+
- **样式**: styled-jsx + tailwindcss(语义化 token)。styled-jsx 使用前提见下方"样式开发"
|
|
447
447
|
- **UI 组件库**: shadcn/ui — Use components for functionality, heavily style them
|
|
448
448
|
- **图表**: ReactECharts,**开发前必须调用 `/charts-skill`**
|
|
449
449
|
- **图标**: Lucide React(唯一图标库,禁止 Emoji 和其他图标库)
|
|
@@ -535,7 +535,7 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
|
|
|
535
535
|
```
|
|
536
536
|
需要写样式?
|
|
537
537
|
├─ 基础布局/间距/颜色 → Tailwind ✅
|
|
538
|
-
├─ 复杂动画/伪元素/高级CSS →
|
|
538
|
+
├─ 复杂动画/伪元素/高级CSS → styled-jsx ✅
|
|
539
539
|
└─ JS动态计算值 → 行内 style ✅
|
|
540
540
|
```
|
|
541
541
|
|
|
@@ -548,12 +548,10 @@ import { axiosForBackend } from '@lark-apaas/client-toolkit/utils/getAxiosForBac
|
|
|
548
548
|
- **arbitrary values 中空格用下划线**:`from-[hsl(215_60%_18%)]` 非 `from-[hsl(215 60% 18%)]`
|
|
549
549
|
- `tailwind-theme.css` 自定义属性用 `hsl(H, S%, L%)` 格式(非 `23 10% 23%`)
|
|
550
550
|
|
|
551
|
-
###
|
|
551
|
+
### styled-jsx 规范
|
|
552
552
|
|
|
553
|
-
-
|
|
554
|
-
-
|
|
555
|
-
- 类名用 camelCase,避免使用连字符(`styles.myClass` 而非 `styles['my-class']`)
|
|
556
|
-
- 全局样式(如动画 keyframes、CSS 变量)放在 `client/src/index.css` 或 `tailwind-theme.css`
|
|
553
|
+
- **技术栈一致性**:仅在已配置 styled-jsx 插件的项目中使用。`package.json` 无 `styled-jsx` 依赖则**禁用**,否则运行时 SyntaxError
|
|
554
|
+
- **禁止动态插值**:`<style jsx>` 内禁止 `${...}` 等表达式(会卡死)。动态值放 CSS 变量,用 `var(--xxx)` 引用
|
|
557
555
|
|
|
558
556
|
### 布局/排版
|
|
559
557
|
|
|
@@ -35,6 +35,7 @@ lark-cli apps --help 2>&1 | grep -q '+plugin-install' && echo "READY" || echo "M
|
|
|
35
35
|
| Client 侧非流式调用 | `capabilityClient.load(id).call(actionKey, input)` |
|
|
36
36
|
| Client 侧流式调用 | `capabilityClient.load(id).callStream(actionKey, input)` |
|
|
37
37
|
| Server 侧调用(仅兜底) | `capabilityService.load(id).call(actionKey, input)` |
|
|
38
|
+
| 长耗时 AI 结果 | 大体量/多字段/多份/多语言/文件或多模态串联等结构信号命中时,优先前端 `callStream` 渐进展示;需保存则流式结束后复用 CRUD 落库;仅在 Client 侧无法满足时使用后端任务记录 + 状态查询 + 结果读取;禁止单个 HTTP 请求等待完整结果后才返回 |
|
|
38
39
|
| capabilityClient 导入 | `import { capabilityClient } from '@lark-apaas/client-toolkit'` |
|
|
39
40
|
| CapabilityService 导入 | `import { CapabilityService } from '@lark-apaas/fullstack-nestjs-core';` |
|
|
40
41
|
| CapabilityService 注入 | `@Inject() private readonly capabilityService: CapabilityService` |
|
|
@@ -516,7 +517,9 @@ npx @lark-apaas/miaoda-cli plugin list --id <instance_id>
|
|
|
516
517
|
2. 结果供后续功能消费
|
|
517
518
|
3. 用户再次访问时需要看到结果
|
|
518
519
|
|
|
519
|
-
|
|
520
|
+
**推荐**:能由前端承接时,Client 侧 `callStream` 渐进展示,流式结束后调已有 CRUD 接口保存。**必要时**:敏感凭证、触发器、强事务或必须由后端保证落库一致性时,Server 侧 Service 调用插件并落库。
|
|
521
|
+
|
|
522
|
+
**高耗时 AI capability 闸门**:若插件输出定义或功能设计显示输出规模大、输出字段多、需要多份结果、多语言/长文本、文件或多模态输入后继续生成、多个 capability 串联、或结果需后续查看/落库,禁止把完整生成放进一个同步 HTTP 请求等待;能由前端承接时优先 `callStream` 渐进展示,需保存则流式结束后复用 CRUD 落库;仅在 Client 侧无法满足时后端创建任务记录后快速返回、由前端短轮询状态/结果,或拆成多个独立小调用。
|
|
520
523
|
|
|
521
524
|
### 生成代码
|
|
522
525
|
|
|
@@ -535,7 +538,8 @@ npx @lark-apaas/miaoda-cli plugin list --id <instance_id>
|
|
|
535
538
|
|
|
536
539
|
1. **禁止静默吞异常**:每个 `catch` 块必须向用户展示错误或触发补偿
|
|
537
540
|
2. **异步操作必须有终态**:DB 中维护状态(pending → success / failed)
|
|
538
|
-
3.
|
|
541
|
+
3. **长耗时 AI 生成不得同步等完**:大体量、多字段、多份、多语言、文件/多模态串联或需要持久化的 AI capability 调用,触发接口必须快速返回任务状态或采用前端流式展示;若接口请求、浏览器操作或页面请求出现超时/连接断开,不能只凭服务端最终日志或数据库最终写入宣告成功,必须证明用户侧存在可读取的终态结果
|
|
542
|
+
4. **插件失败必须有补偿**:至少记录到待处理列表或提示用户重试
|
|
539
543
|
|
|
540
544
|
## 缓存与幂等性
|
|
541
545
|
|
package/steering/nestjs-react-fullstack/skills_local/plugin-guide/references/plugin-coding-guide.md
CHANGED
|
@@ -2,15 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
### 核心原则:根据场景选择调用侧
|
|
4
4
|
|
|
5
|
-
**默认优先在 Client 侧调用 capabilityClient
|
|
5
|
+
**默认优先在 Client 侧调用 capabilityClient;流式或高耗时 AI 生成优先 `callStream` 渐进展示。结果需要持久化时,优先在流式结束后通过已有后端接口保存;只有 Client 侧无法满足时才切到 Server 侧。**
|
|
6
|
+
|
|
7
|
+
**高耗时 AI capability 先判调用形态**:只要输出规模大、输出字段多、需要多份结果、多语言/长文本、文件或多模态输入后继续生成、多个 capability 串联、或结果需后续查看/落库,就不得把完整 AI 结果塞进一个同步 HTTP 请求等待。能由前端承接时,优先用前端 `callStream` 渐进展示,并在流式结束后按需复用已有 CRUD 接口保存结果;只有 Client 侧无法满足(触发器/敏感凭证/强事务/必须由后端保证落库一致性等)时,才采用后端任务记录 + 状态/结果查询,避免把后台任务作为默认方案。
|
|
8
|
+
|
|
6
9
|
**严禁** import { capabilityClient } from '@lark-apaas/client-capability'。
|
|
7
10
|
**唯一指定**的导入方式是 import { capabilityClient } from '@lark-apaas/client-toolkit';
|
|
8
11
|
|
|
9
12
|
| 优先级 | 场景 | 调用方式 |
|
|
10
13
|
|-------|------|---------|
|
|
11
|
-
| **首选** |
|
|
12
|
-
| **首选** |
|
|
13
|
-
|
|
|
14
|
+
| **首选** | 绝大多数即时展示场景 | `capabilityClient.load(id).call()` |
|
|
15
|
+
| **首选** | 流式输出,或高耗时但可由前端承接的 AI 生成 | `capabilityClient.load(id).callStream()`(流式结束后按需持久化) |
|
|
16
|
+
| **必要时** | 高耗时且 Client 侧无法满足:触发器、敏感凭证、强事务、必须由后端保证落库一致性 | 后端任务记录 + 后台调用 `CapabilityService.load(id).call()` + 前端短轮询状态/结果 |
|
|
17
|
+
| **兜底** | Client 侧无法满足且单次调用可在交互边界内完成 | `CapabilityService.load(id).call()` |
|
|
14
18
|
|
|
15
19
|
#### 什么情况下应使用 Server 侧?
|
|
16
20
|
|
|
@@ -19,7 +23,7 @@
|
|
|
19
23
|
1. **涉及敏感凭证**:调用需要服务端私密 token/secret,不适合暴露给前端
|
|
20
24
|
2. **必须后端编排**:多个插件调用之间有强事务依赖,需要后端统一编排
|
|
21
25
|
3. **触发器/定时任务场景**:没有前端上下文,只能由后端发起
|
|
22
|
-
4.
|
|
26
|
+
4. **插件结果需要持久化**:调用结果需要保存到数据库;能由前端承接时,优先前端 `callStream` 渐进展示并在结束后复用已有 CRUD 接口保存;只有 Client 侧无法满足或必须由后端保证落库一致性时,才在 Server 侧调用并落库。若此时输出规模大、字段多、结果多份或需多步能力串联,必须改为任务记录 + 后台执行 + 状态/结果查询,避免一个 HTTP 请求等待完整生成
|
|
23
27
|
|
|
24
28
|
> **提示**:如果插件结果不需要存储、仅用于即时展示(如流式生成文本、发送消息),优先在前端调用。但当结果需要保存到数据库时,不要回避使用 Server 侧。
|
|
25
29
|
|
|
@@ -31,9 +35,13 @@
|
|
|
31
35
|
|
|
32
36
|
```
|
|
33
37
|
插件结果是否需要持久化到数据库?
|
|
34
|
-
├── 否
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
├── 否
|
|
39
|
+
│ ├── `outputMode=stream` 或内容生成较慢 → Client 侧 `callStream()` 渐进展示
|
|
40
|
+
│ └── 单次短输出 → Client 侧 `call()`(默认)
|
|
41
|
+
└── 是
|
|
42
|
+
├── `outputMode=stream` 且前端可承接 → 推荐方案 A:Client 侧 `callStream()` 渐进展示,成功后通过已有 CRUD 接口保存结果
|
|
43
|
+
├── 输出较小且可在交互边界内完成、且必须由后端保证一致性 → Server 侧调用并在同一方法中落库
|
|
44
|
+
└── Client 侧无法满足且输出规模大/多字段/多份/多语言/多步骤 → 方案 B:Server 侧创建任务记录,快速返回任务状态;后台调用插件并落库;前端短轮询状态/结果
|
|
37
45
|
```
|
|
38
46
|
|
|
39
47
|
| 应避免的做法 | 推荐做法 |
|
|
@@ -233,10 +241,11 @@ function MultiPluginStreamExample() {
|
|
|
233
241
|
2. 一个 `stream` action 的真实调用结果(chunk 按 `outputSchema` 字段读取)
|
|
234
242
|
3. 调用失败时的最小日志字段齐全
|
|
235
243
|
4. 若无法执行真实调用,必须明确写明阻塞原因,禁止直接标记"开发完成"
|
|
244
|
+
5. 若用户触发 AI 生成的请求超时、连接断开或工具返回超时,必须判定为验收失败;只有触发请求快速返回、随后能通过页面或接口读到明确完成或失败终态和结果,才允许标记通过
|
|
236
245
|
|
|
237
246
|
### Server 侧调用方式(仅兜底场景)
|
|
238
247
|
|
|
239
|
-
> 以下场景适合使用 Server
|
|
248
|
+
> 以下场景适合使用 Server 侧调用;若前端 `callStream` + 既有 CRUD 保存即可满足展示和持久化,不要优先引入后端后台任务。
|
|
240
249
|
|
|
241
250
|
#### 1. 何时适合用 Server 侧?
|
|
242
251
|
|
|
@@ -247,6 +256,7 @@ function MultiPluginStreamExample() {
|
|
|
247
256
|
| 敏感凭证调用 | 凭证不能暴露给前端 | 调用需要 admin token 的 API |
|
|
248
257
|
| 强事务编排 | 多步骤需要原子性 | 创建记录 → 发通知 → 更新状态必须全成功或全回滚 |
|
|
249
258
|
| 插件结果需持久化 | 调用结果需保存到数据库 | AI 分类/摘要结果需落库、文档解析的结构化数据需入库、图片识别结果需关联业务记录、语音转文字结果需存档等 |
|
|
259
|
+
| 高耗时 AI 生成需后续查看 | 请求不能长期占用用户交互链路 | 批量、多版本、多语言、长文本、多字段结构化生成,或文件/多模态分析后再生成内容 |
|
|
250
260
|
|
|
251
261
|
#### 2. NestJS 注入方式
|
|
252
262
|
|
|
@@ -290,6 +300,7 @@ try {
|
|
|
290
300
|
|
|
291
301
|
- PluginInstance 调用在 Server 侧通常属于 **外部依赖 / side-effect**
|
|
292
302
|
- 除非业务明确要求强一致性,**默认不应阻塞主业务流程**
|
|
303
|
+
- 已选择 Server 侧承接的高耗时 AI capability 必须有可观测状态:创建任务时记录处理进度、完成终态、失败终态、输入摘要、错误信息和结果引用;触发接口只返回任务标识与当前状态,前端通过短轮询读取进度和最终结果
|
|
293
304
|
|
|
294
305
|
推荐写法:异步触发 + catch 兜底:
|
|
295
306
|
|