@thinkingai/ae-cli 1.0.1
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/README.md +229 -0
- package/bin/ae-cli.js +2 -0
- package/dist/auth-JXELJNDS.js +19 -0
- package/dist/auth-L3G3A74I.js +67 -0
- package/dist/chunk-3GM5LJZR.js +145 -0
- package/dist/chunk-JD5DXMKL.js +172 -0
- package/dist/chunk-KM57HI5B.js +107 -0
- package/dist/chunk-OVQOK35G.js +108 -0
- package/dist/chunk-RJNLN3KQ.js +217 -0
- package/dist/client-5QSQBBDB.js +16 -0
- package/dist/community-GMALVSRF.js +684 -0
- package/dist/config-Q7J3Z7Z2.js +242 -0
- package/dist/index.js +277 -0
- package/dist/raw-ZNVURYMR.js +59 -0
- package/dist/te-analysis-7NN3SY3I.js +871 -0
- package/dist/te-audience-P43BWMHM.js +350 -0
- package/dist/te-common-H3IPTI2I.js +144 -0
- package/dist/te-dataops-WCGDBJLF.js +1853 -0
- package/dist/te-engage-UTRVNTGU.js +1470 -0
- package/dist/te-meta-HGYNXVGF.js +479 -0
- package/package.json +53 -0
- package/skills/te-analysis/SKILL.md +107 -0
- package/skills/te-analysis/references/build-entity-details-sql.md +58 -0
- package/skills/te-analysis/references/build-event-details-sql.md +61 -0
- package/skills/te-analysis/references/create-alert.md +47 -0
- package/skills/te-analysis/references/create-dashboard.md +49 -0
- package/skills/te-analysis/references/create-or-update-dashboard-note.md +39 -0
- package/skills/te-analysis/references/create-public-access-link.md +43 -0
- package/skills/te-analysis/references/create-report.md +60 -0
- package/skills/te-analysis/references/create-result-cluster.md +73 -0
- package/skills/te-analysis/references/drilldown-user-events.md +72 -0
- package/skills/te-analysis/references/drilldown-users.md +75 -0
- package/skills/te-analysis/references/get-alert-definition-schema.md +32 -0
- package/skills/te-analysis/references/get-alert.md +31 -0
- package/skills/te-analysis/references/get-analysis-query-schema.md +36 -0
- package/skills/te-analysis/references/get-filter-schema.md +33 -0
- package/skills/te-analysis/references/get-groupby-schema.md +33 -0
- package/skills/te-analysis/references/get-report-definition.md +33 -0
- package/skills/te-analysis/references/get-table-columns.md +38 -0
- package/skills/te-analysis/references/list-alerts.md +33 -0
- package/skills/te-analysis/references/list-dashboards.md +33 -0
- package/skills/te-analysis/references/list-public-access-links.md +31 -0
- package/skills/te-analysis/references/list-reports.md +33 -0
- package/skills/te-analysis/references/load-filters.md +44 -0
- package/skills/te-analysis/references/query-adhoc.md +71 -0
- package/skills/te-analysis/references/query-dashboard-detail.md +35 -0
- package/skills/te-analysis/references/query-dashboard-report-data.md +60 -0
- package/skills/te-analysis/references/query-entity-details.md +60 -0
- package/skills/te-analysis/references/query-event-details.md +63 -0
- package/skills/te-analysis/references/query-report-data.md +65 -0
- package/skills/te-analysis/references/update-alert.md +49 -0
- package/skills/te-analysis/references/update-dashboard.md +45 -0
- package/skills/te-analysis/references/update-public-access-link.md +41 -0
- package/skills/te-audience/SKILL.md +63 -0
- package/skills/te-audience/references/create-cluster.md +65 -0
- package/skills/te-audience/references/create-tag.md +60 -0
- package/skills/te-audience/references/get-cluster-definition-schema.md +37 -0
- package/skills/te-audience/references/get-clusters-by-name.md +32 -0
- package/skills/te-audience/references/get-tag-definition-schema.md +32 -0
- package/skills/te-audience/references/get-tags-by-name.md +32 -0
- package/skills/te-audience/references/list-cluster-members.md +35 -0
- package/skills/te-audience/references/list-clusters.md +32 -0
- package/skills/te-audience/references/list-tag-members.md +36 -0
- package/skills/te-audience/references/list-tags.md +32 -0
- package/skills/te-audience/references/refresh-cluster.md +31 -0
- package/skills/te-audience/references/refresh-tag.md +31 -0
- package/skills/te-audience/references/update-cluster.md +59 -0
- package/skills/te-audience/references/update-tag.md +60 -0
- package/skills/te-common/SKILL.md +135 -0
- package/skills/te-common/references/get-resource-url.md +32 -0
- package/skills/te-common/references/list-projects.md +37 -0
- package/skills/te-community/SKILL.md +133 -0
- package/skills/te-community/references/community-activity-analysis.md +68 -0
- package/skills/te-community/references/community-analyzing-official-content.md +72 -0
- package/skills/te-community/references/community-analyzing-theme-comment.md +124 -0
- package/skills/te-community/references/community-character-analysis.md +71 -0
- package/skills/te-community/references/community-daily-report.md +82 -0
- package/skills/te-community/references/community-hottopic-insight.md +120 -0
- package/skills/te-community/references/community-release-analysis.md +79 -0
- package/skills/te-community/references/community-weekly-report.md +84 -0
- package/skills/te-community/references/get_channel_info.md +21 -0
- package/skills/te-community/references/get_comment_tag_analysis.md +30 -0
- package/skills/te-community/references/get_comments_summary.md +33 -0
- package/skills/te-community/references/get_corpus_tags.md +21 -0
- package/skills/te-community/references/get_daily_summary.md +23 -0
- package/skills/te-community/references/get_hot_topics.md +26 -0
- package/skills/te-community/references/get_livestream_analysis.md +23 -0
- package/skills/te-community/references/get_livestream_detail.md +34 -0
- package/skills/te-community/references/get_livestream_list.md +26 -0
- package/skills/te-community/references/get_livestream_overview.md +25 -0
- package/skills/te-community/references/get_livestream_room_metrics.md +26 -0
- package/skills/te-community/references/get_livestream_rooms.md +26 -0
- package/skills/te-community/references/get_overview_metrics.md +26 -0
- package/skills/te-community/references/get_post_detail.md +38 -0
- package/skills/te-community/references/get_risk_content.md +43 -0
- package/skills/te-community/references/get_sentiment_overview.md +34 -0
- package/skills/te-community/references/get_tag_trends.md +28 -0
- package/skills/te-community/references/get_topic_detail.md +27 -0
- package/skills/te-community/references/search_posts.md +48 -0
- package/skills/te-dataops/SKILL.md +645 -0
- package/skills/te-dataops/references/dataops-flow-create.md +163 -0
- package/skills/te-dataops/references/dataops-flow-monitor.md +118 -0
- package/skills/te-dataops/references/dataops-integration.md +246 -0
- package/skills/te-dataops/references/dataops-operations.md +107 -0
- package/skills/te-dataops/references/dataops-query.md +111 -0
- package/skills/te-dataops/references/dataops-table.md +122 -0
- package/skills/te-engage/SKILL.md +211 -0
- package/skills/te-engage/references/add-approver.md +24 -0
- package/skills/te-engage/references/add-channel.md +74 -0
- package/skills/te-engage/references/approver-list.md +19 -0
- package/skills/te-engage/references/cancel-query-by-request-id.md +23 -0
- package/skills/te-engage/references/channel-detail.md +52 -0
- package/skills/te-engage/references/channel-list.md +41 -0
- package/skills/te-engage/references/config-channel-detail.md +32 -0
- package/skills/te-engage/references/config-channel-list.md +27 -0
- package/skills/te-engage/references/config-item-analysis-report.md +34 -0
- package/skills/te-engage/references/config-item-detail.md +30 -0
- package/skills/te-engage/references/config-item-list.md +19 -0
- package/skills/te-engage/references/config-item-strategy-comparison.md +25 -0
- package/skills/te-engage/references/config-item-trigger-report.md +42 -0
- package/skills/te-engage/references/copy-config-template.md +29 -0
- package/skills/te-engage/references/delete-channel.md +24 -0
- package/skills/te-engage/references/delete-config-channel.md +24 -0
- package/skills/te-engage/references/delete-config-item.md +25 -0
- package/skills/te-engage/references/delete-flow.md +24 -0
- package/skills/te-engage/references/flow-ab-split-node-report.md +54 -0
- package/skills/te-engage/references/flow-detail.md +79 -0
- package/skills/te-engage/references/flow-list.md +19 -0
- package/skills/te-engage/references/flow-node-config-schema.md +44 -0
- package/skills/te-engage/references/flow-node-detail-report.md +55 -0
- package/skills/te-engage/references/flow-node-overview-report.md +52 -0
- package/skills/te-engage/references/flow-process-report.md +59 -0
- package/skills/te-engage/references/manage-flow.md +94 -0
- package/skills/te-engage/references/manage-strategy.md +74 -0
- package/skills/te-engage/references/manage-task.md +37 -0
- package/skills/te-engage/references/modify-flow-base-info.md +27 -0
- package/skills/te-engage/references/save-flow.md +870 -0
- package/skills/te-engage/references/strategy-detail.md +73 -0
- package/skills/te-engage/references/strategy-list.md +21 -0
- package/skills/te-engage/references/task-data-detail.md +81 -0
- package/skills/te-engage/references/task-data-overview.md +48 -0
- package/skills/te-engage/references/task-detail.md +61 -0
- package/skills/te-engage/references/task-experiment-report.md +51 -0
- package/skills/te-engage/references/task-list.md +91 -0
- package/skills/te-engage/references/task-metric-detail.md +56 -0
- package/skills/te-engage/references/task-stats.md +89 -0
- package/skills/te-engage/references/update-channel-status.md +32 -0
- package/skills/te-engage/references/update-config-channel-status.md +32 -0
- package/skills/te-engage/references/validate-flow-node-config.md +52 -0
- package/skills/te-engage/references/whitelist-list.md +19 -0
- package/skills/te-meta/SKILL.md +71 -0
- package/skills/te-meta/references/batch-create-metadata.md +37 -0
- package/skills/te-meta/references/batch-edit-metadata.md +36 -0
- package/skills/te-meta/references/create-metric.md +62 -0
- package/skills/te-meta/references/create-project-mark-time.md +38 -0
- package/skills/te-meta/references/create-virtual-event.md +64 -0
- package/skills/te-meta/references/create-virtual-property.md +69 -0
- package/skills/te-meta/references/delete-project-mark-times.md +34 -0
- package/skills/te-meta/references/delete-track-items.md +35 -0
- package/skills/te-meta/references/get-metric.md +32 -0
- package/skills/te-meta/references/get-project-config.md +32 -0
- package/skills/te-meta/references/get-track-program.md +31 -0
- package/skills/te-meta/references/list-entities.md +34 -0
- package/skills/te-meta/references/list-events.md +33 -0
- package/skills/te-meta/references/list-metrics.md +33 -0
- package/skills/te-meta/references/list-project-mark-times.md +33 -0
- package/skills/te-meta/references/list-project-users.md +32 -0
- package/skills/te-meta/references/list-properties.md +35 -0
- package/skills/te-meta/references/save-track-items.md +34 -0
- package/skills/te-meta/references/update-metric.md +61 -0
- package/skills/te-meta/references/update-project-mark-time.md +39 -0
- package/skills/te-shared/SKILL.md +115 -0
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
# te-engage `+save-flow`
|
|
2
|
+
|
|
3
|
+
创建或更新流程画布草稿。
|
|
4
|
+
|
|
5
|
+
映射命令:`te-cli te-engage +save-flow`
|
|
6
|
+
|
|
7
|
+
这份文档目标不是只解释 `save_flow` 接口本身,而是提供一条**从用户需求到 CLI 入参**的完整路径:
|
|
8
|
+
|
|
9
|
+
1. 先做意图识别
|
|
10
|
+
2. 再把意图映射成流程画布 `req`
|
|
11
|
+
3. 最后调用 CLI 提交
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. 总原则
|
|
16
|
+
|
|
17
|
+
`+save-flow` 直接接收的不是自然语言,也不是模糊业务描述,而是**最终可提交的流程画布请求体**。
|
|
18
|
+
|
|
19
|
+
因此,必须先把用户需求整理成一个统一的中间意图结构,再根据映射规则生成:
|
|
20
|
+
|
|
21
|
+
- `flowName`
|
|
22
|
+
- `flowDesc`
|
|
23
|
+
- `nodeList`
|
|
24
|
+
- `edgeList`
|
|
25
|
+
- 以及可选的 `groupId`、`tzOffset`、`flowUuid`、`parentFlowUuid`、`versionType`
|
|
26
|
+
|
|
27
|
+
最终再用 CLI 调用:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
te-cli te-engage +save-flow --project-id <projectId> --req '<req-json>'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. 工作流
|
|
36
|
+
|
|
37
|
+
推荐按下面 5 步执行:
|
|
38
|
+
|
|
39
|
+
1. 从用户输入中识别流程意图,生成统一的意图 JSON。
|
|
40
|
+
2. 调用 `te-cli te_audience +get_cluster_definition_schema --cluster_type condition`,拿到 condition cluster definition schema,用于后续拼装条件相关字段。
|
|
41
|
+
3. 调用 `te-cli te-engage +channel-list --project-id <projectId>`,拿到项目下可用通道,为触达节点匹配真实 `channelId`。
|
|
42
|
+
4. 将意图 JSON 映射成最终 `req`:`flowName`、`flowDesc`、`nodeList`、`edgeList`。
|
|
43
|
+
5. 调用 `te-cli te-engage +save-flow --project-id <projectId> --req '<req-json>'` 提交。
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 3. 第一步:意图识别
|
|
48
|
+
|
|
49
|
+
### 3.1 必须先确认的信息
|
|
50
|
+
|
|
51
|
+
在生成任何 `req` 之前,至少要确认这 4 类信息:
|
|
52
|
+
|
|
53
|
+
| 信息 | 说明 |
|
|
54
|
+
|---|---|
|
|
55
|
+
| 业务场景 | 这是一个什么流程,比如新用户激活、流失召回、付费转化 |
|
|
56
|
+
| 目标用户 | 谁能进入流程,比如最近 14 天未登录用户、今日注册用户 |
|
|
57
|
+
| 触达方式 | 用什么渠道触达,比如 Push、微信订阅、Webhook |
|
|
58
|
+
| 分流条件 | 是否需要分组处理;如果需要,要知道按什么条件分组 |
|
|
59
|
+
|
|
60
|
+
如果这 4 类信息有缺失,不要直接构建 `req`。
|
|
61
|
+
|
|
62
|
+
### 3.2 意图识别输出格式
|
|
63
|
+
|
|
64
|
+
先把用户需求整理成如下意图 JSON。这个 JSON 是中间表示,不是最终 `save_flow.req`。
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
{
|
|
68
|
+
"flow_type": "<string>",
|
|
69
|
+
"flow_name": "<string>",
|
|
70
|
+
"flow_desc": "<string>",
|
|
71
|
+
"entry": {
|
|
72
|
+
"type": "<single_trigger|repeat_trigger|event_trigger>",
|
|
73
|
+
"segment": "<string|null>",
|
|
74
|
+
"schedule": "<string|null>",
|
|
75
|
+
"start_date": "<YYYY-MM-DD|YYYY-MM-DD HH:mm|null>",
|
|
76
|
+
"end_date": "<YYYY-MM-DD|YYYY-MM-DD HH:mm|null>",
|
|
77
|
+
"trigger_event": {
|
|
78
|
+
"event": "<string|null>",
|
|
79
|
+
"op": "<string|null>",
|
|
80
|
+
"count": "<number|null>",
|
|
81
|
+
"property_filter": "<object|null>",
|
|
82
|
+
"time_window": "<string|null>"
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"nodes": [
|
|
86
|
+
{
|
|
87
|
+
"nid": "n1",
|
|
88
|
+
"node_type": "<split|judge|action|wait|end>",
|
|
89
|
+
"type": "<具体节点语义类型>",
|
|
90
|
+
"name": "<string|null>",
|
|
91
|
+
"content": "<string|null>",
|
|
92
|
+
"channel_name": "<string|null>",
|
|
93
|
+
"languages": ["default"],
|
|
94
|
+
"condition": "<object|null>",
|
|
95
|
+
"event": "<object|null>",
|
|
96
|
+
"wait_time": "<string|null>",
|
|
97
|
+
"duration": "<string|null>",
|
|
98
|
+
"split_flow_type": "<1|2|null>",
|
|
99
|
+
"branches": [
|
|
100
|
+
{
|
|
101
|
+
"bid": "b1",
|
|
102
|
+
"label": "<string>",
|
|
103
|
+
"condition": "<object|null>",
|
|
104
|
+
"time_limit": "<string|null>",
|
|
105
|
+
"percentage": "<number|null>"
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"edges": [
|
|
111
|
+
{
|
|
112
|
+
"source": "n1",
|
|
113
|
+
"target": "n2",
|
|
114
|
+
"branch": "<branch label|null>"
|
|
115
|
+
}
|
|
116
|
+
]
|
|
117
|
+
}
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 3.3 字段含义
|
|
121
|
+
|
|
122
|
+
- `entry`
|
|
123
|
+
描述用户如何进入流程。
|
|
124
|
+
- `nodes`
|
|
125
|
+
描述业务语义节点,还不是最终画布节点。
|
|
126
|
+
- `edges`
|
|
127
|
+
描述业务语义上的连接关系。
|
|
128
|
+
- `channel_name`
|
|
129
|
+
先保留为语义字段,后面再去项目通道列表里匹配真实 `channelId`。
|
|
130
|
+
- `branches`
|
|
131
|
+
只描述分支语义;后面落地到 `node.config.branchList` 和 `edge.sourceBranchId`。
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## 4. 第二步:前置 CLI 查询
|
|
136
|
+
|
|
137
|
+
### 4.1 查询 cluster definition schema
|
|
138
|
+
|
|
139
|
+
调用:
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
te-cli te_audience +get_cluster_definition_schema --cluster_type condition
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
作用:
|
|
146
|
+
- 为条件节点、分群节点、入口节点准备 QP 构造依据
|
|
147
|
+
- 帮助生成 `targetClusterQp`
|
|
148
|
+
- 帮助生成 `triggerRule.events`
|
|
149
|
+
|
|
150
|
+
这一步不是直接返回最终节点,而是提供“怎样把条件表达成 QP / 事件条件”的规则基础。
|
|
151
|
+
|
|
152
|
+
### 4.2 查询项目通道
|
|
153
|
+
|
|
154
|
+
调用:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
te-cli te-engage +channel-list --project-id <projectId>
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
作用:
|
|
161
|
+
- 获取项目下可用通道
|
|
162
|
+
- 根据意图中的 `channel_name` 为触达节点匹配真实 `channelId`
|
|
163
|
+
- 根据通道类型判断是 `message_push`、`wechat_push` 还是 `webhook_push`
|
|
164
|
+
|
|
165
|
+
如果 `channel_name` 没有精确匹配,应优先:
|
|
166
|
+
|
|
167
|
+
1. 名称精确匹配
|
|
168
|
+
2. 名称关键词匹配
|
|
169
|
+
3. 按节点类型兜底匹配通道类型
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 5. 第三步:把意图映射成 `req`
|
|
174
|
+
|
|
175
|
+
### 5.1 `req` 顶层结构
|
|
176
|
+
|
|
177
|
+
最终传给 `--req` 的对象结构如下:
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"flowName": "<string>",
|
|
182
|
+
"flowDesc": "<string>",
|
|
183
|
+
"groupId": 0,
|
|
184
|
+
"tzOffset": 8,
|
|
185
|
+
"flowUuid": "<string, optional>",
|
|
186
|
+
"parentFlowUuid": "<string, optional>",
|
|
187
|
+
"versionType": 1,
|
|
188
|
+
"nodeList": [],
|
|
189
|
+
"edgeList": []
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
说明:
|
|
194
|
+
- `projectId` 不需要手写进 `--req`,CLI 会从 `--project-id` 自动注入
|
|
195
|
+
- `flowUuid` 和 `parentFlowUuid` 互斥
|
|
196
|
+
- 创建新草稿时,这两个字段都不传
|
|
197
|
+
|
|
198
|
+
### 5.2 顶层字段来源
|
|
199
|
+
|
|
200
|
+
| `req` 字段 | 来源 |
|
|
201
|
+
|---|---|
|
|
202
|
+
| `flowName` | 意图 `flow_name` |
|
|
203
|
+
| `flowDesc` | 意图 `flow_desc`,没有就给空串或简短描述 |
|
|
204
|
+
| `groupId` | 默认 `0`,除非业务要求指定分组 |
|
|
205
|
+
| `tzOffset` | 用户时区或项目默认时区,常见为 `8` |
|
|
206
|
+
| `nodeList` | 由意图 `entry` + `nodes` 映射生成 |
|
|
207
|
+
| `edgeList` | 由意图 `edges` 和分支结构生成 |
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## 6. 第四步:意图节点到画布节点的映射
|
|
212
|
+
|
|
213
|
+
### 6.1 入口节点映射
|
|
214
|
+
|
|
215
|
+
| 意图 `entry.type` | 画布节点 `type` |
|
|
216
|
+
|---|---|
|
|
217
|
+
| `single_trigger` | `single_trigger` |
|
|
218
|
+
| `repeat_trigger` | `repeat_trigger` |
|
|
219
|
+
| `event_trigger` | `event_trigger` |
|
|
220
|
+
|
|
221
|
+
入口节点始终要成为 `nodeList` 中唯一的入口节点。
|
|
222
|
+
|
|
223
|
+
### 6.2 业务节点映射
|
|
224
|
+
|
|
225
|
+
| 意图节点语义 | 画布节点 `type` |
|
|
226
|
+
|---|---|
|
|
227
|
+
| 行为分流 | `event_split_flow` |
|
|
228
|
+
| 特征分流 | `feature_split_flow` |
|
|
229
|
+
| A/B 分流 | `ab_split_flow` |
|
|
230
|
+
| 行为判断 | `event_judge` |
|
|
231
|
+
| 特征判断 | `feature_judge` |
|
|
232
|
+
| Push 触达 | `message_push` |
|
|
233
|
+
| 微信触达 | `wechat_push` |
|
|
234
|
+
| Webhook / 其他外部触达 | `webhook_push` |
|
|
235
|
+
| 等待 | `time_control` |
|
|
236
|
+
| 结束 | `exit_flow` |
|
|
237
|
+
|
|
238
|
+
### 6.3 条件字段映射
|
|
239
|
+
|
|
240
|
+
条件类语义不能直接原样放进 `req`,要按下面方式落地:
|
|
241
|
+
|
|
242
|
+
| 语义类型 | 目标字段 |
|
|
243
|
+
|---|---|
|
|
244
|
+
| 受众分群条件 | `targetClusterQp` |
|
|
245
|
+
| 特征判断条件 | `targetClusterQp` |
|
|
246
|
+
| 特征分流分支条件 | `targetClusterQp` |
|
|
247
|
+
| 事件触发条件 | `triggerRule[].events[]` |
|
|
248
|
+
| 行为判断条件 | `triggerRule[].events[]` |
|
|
249
|
+
| 行为分流分支条件 | `triggerRule[].events[]` |
|
|
250
|
+
|
|
251
|
+
简单理解:
|
|
252
|
+
- “按人群 / 属性判断”的,多数落到 `targetClusterQp`
|
|
253
|
+
- “按事件是否发生 / 发生几次判断”的,多数落到 `triggerRule.events`
|
|
254
|
+
|
|
255
|
+
### 6.4 触达节点映射
|
|
256
|
+
|
|
257
|
+
动作语义节点里的这些字段:
|
|
258
|
+
|
|
259
|
+
- `channel_name`
|
|
260
|
+
- `content`
|
|
261
|
+
- `languages`
|
|
262
|
+
|
|
263
|
+
需要落地到 push 节点 `config`:
|
|
264
|
+
|
|
265
|
+
- `channel_name` -> 匹配成真实 `channelId`
|
|
266
|
+
- `content` -> 放进 `contentList`
|
|
267
|
+
- `languages` -> 决定是否生成多语言 `contentList`
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## 7. 第五步:`nodeList` 怎么写
|
|
272
|
+
|
|
273
|
+
`nodeList` 中每一项结构如下:
|
|
274
|
+
|
|
275
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
276
|
+
|---|---|---|---|
|
|
277
|
+
| `id` | string | 是 | 请求内唯一节点 ID |
|
|
278
|
+
| `name` | string | 是 | 节点显示名 |
|
|
279
|
+
| `type` | string | 是 | 节点类型 |
|
|
280
|
+
| `config` | string | 是 | **JSON 字符串**,顶层必须是 JSON 对象 |
|
|
281
|
+
| `desc` | string | 否 | 节点描述 |
|
|
282
|
+
|
|
283
|
+
### 7.1 最关键的规则
|
|
284
|
+
|
|
285
|
+
1. `config` 必须是字符串,不是对象。
|
|
286
|
+
2. `node.id` 必须唯一。
|
|
287
|
+
3. 分支节点、判断节点里会被 `edge.sourceBranchId` 用到的 branchId,必须先定义在 `config` 里。
|
|
288
|
+
4. 所有路径最终都要落到 `exit_flow`。
|
|
289
|
+
|
|
290
|
+
### 7.2 常见节点类型
|
|
291
|
+
|
|
292
|
+
- `single_trigger`
|
|
293
|
+
- `repeat_trigger`
|
|
294
|
+
- `event_trigger`
|
|
295
|
+
- `event_split_flow`
|
|
296
|
+
- `feature_split_flow`
|
|
297
|
+
- `ab_split_flow`
|
|
298
|
+
- `event_judge`
|
|
299
|
+
- `feature_judge`
|
|
300
|
+
- `message_push`
|
|
301
|
+
- `wechat_push`
|
|
302
|
+
- `webhook_push`
|
|
303
|
+
- `time_control`
|
|
304
|
+
- `exit_flow`
|
|
305
|
+
|
|
306
|
+
### 7.3 示例:最简单节点
|
|
307
|
+
|
|
308
|
+
```json
|
|
309
|
+
{
|
|
310
|
+
"id": "node_1",
|
|
311
|
+
"name": "定时单次进入",
|
|
312
|
+
"type": "single_trigger",
|
|
313
|
+
"config": {
|
|
314
|
+
"triggerTime": "2026-04-10 06:35",
|
|
315
|
+
"flowEndDate": "2026-04-11 06:35"
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### 7.4 常用 `config` 模板
|
|
321
|
+
|
|
322
|
+
下面这些模板是“直接拼 `req`”时最该优先参考的部分。使用时先按对象构造,再整体 `JSON.stringify` 放进 `nodeList[].config`。
|
|
323
|
+
|
|
324
|
+
#### `repeat_trigger`
|
|
325
|
+
|
|
326
|
+
```json
|
|
327
|
+
{
|
|
328
|
+
"targetUserType": 1,
|
|
329
|
+
"startDate": "<YYYY-MM-DD>",
|
|
330
|
+
"endDate": "<YYYY-MM-DD>",
|
|
331
|
+
"flowEndDate": "<YYYY-MM-DD HH:mm>",
|
|
332
|
+
"crontab": "0 00 09 * * ?",
|
|
333
|
+
"entryControlLimits": {
|
|
334
|
+
"enableMultEntry": false,
|
|
335
|
+
"disableConcurrentEntry": false
|
|
336
|
+
},
|
|
337
|
+
"targetClusterName": null,
|
|
338
|
+
"clusterPredictCount": null,
|
|
339
|
+
"clusterPredictTime": "<YYYY-MM-DD HH:mm:ss>",
|
|
340
|
+
"targetClusterQp": "<JSON.stringify(qp)>"
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
规则:
|
|
345
|
+
- `entry.segment` -> `targetClusterQp`
|
|
346
|
+
- `entry.schedule` -> `crontab`
|
|
347
|
+
- 常见默认值可用 `0 00 09 * * ?`
|
|
348
|
+
|
|
349
|
+
#### `event_trigger`
|
|
350
|
+
|
|
351
|
+
```json
|
|
352
|
+
{
|
|
353
|
+
"triggerType": 3,
|
|
354
|
+
"targetUserType": 1,
|
|
355
|
+
"realtime": 0,
|
|
356
|
+
"clusterRefresh": 12,
|
|
357
|
+
"clusterRefreshTime": null,
|
|
358
|
+
"startDate": "<YYYY-MM-DD HH:mm>",
|
|
359
|
+
"endDate": "<YYYY-MM-DD HH:mm>",
|
|
360
|
+
"flowEndDate": "<YYYY-MM-DD HH:mm>",
|
|
361
|
+
"clusterPredictCount": null,
|
|
362
|
+
"clusterPredictTime": "<YYYY-MM-DD HH:mm:ss>",
|
|
363
|
+
"triggerRule": [
|
|
364
|
+
{
|
|
365
|
+
"periodStart": "<startDate>",
|
|
366
|
+
"periodEnd": "<endDate>",
|
|
367
|
+
"periodTimeSymbol": "TS02",
|
|
368
|
+
"dayStartTime": null,
|
|
369
|
+
"startDay": null,
|
|
370
|
+
"eventTriggerType": 0,
|
|
371
|
+
"zoneoffset": 8,
|
|
372
|
+
"events": []
|
|
373
|
+
}
|
|
374
|
+
],
|
|
375
|
+
"entryControlLimits": {
|
|
376
|
+
"enableMultEntry": false,
|
|
377
|
+
"disableConcurrentEntry": false
|
|
378
|
+
},
|
|
379
|
+
"targetClusterQp": "<JSON.stringify(qp) 或 null>"
|
|
380
|
+
}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
规则:
|
|
384
|
+
- `entry.trigger_event` -> `triggerRule[0].events`
|
|
385
|
+
- `entry.segment` 存在时再生成 `targetClusterQp`
|
|
386
|
+
- 没有 `segment` 时,`targetClusterQp` 可为 `null`
|
|
387
|
+
|
|
388
|
+
#### `event_split_flow`
|
|
389
|
+
|
|
390
|
+
```json
|
|
391
|
+
{
|
|
392
|
+
"splitFlowType": 1,
|
|
393
|
+
"branchList": [
|
|
394
|
+
{
|
|
395
|
+
"branchId": "<branchId>",
|
|
396
|
+
"branchName": "<label>",
|
|
397
|
+
"branchType": 1,
|
|
398
|
+
"triggerRule": [
|
|
399
|
+
{
|
|
400
|
+
"delayTimeSymbol": "<minute|hour|day>",
|
|
401
|
+
"delayTime": "<number>",
|
|
402
|
+
"eventTriggerType": "<0 或 -1>",
|
|
403
|
+
"zoneoffset": 8,
|
|
404
|
+
"events": []
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
]
|
|
409
|
+
}
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
规则:
|
|
413
|
+
- `branch.condition` 是行为条件时,落到 `triggerRule[].events[]`
|
|
414
|
+
- `time_limit` -> `delayTimeSymbol` + `delayTime`
|
|
415
|
+
- “发生”用 `0`,“未发生”用 `-1`
|
|
416
|
+
- 兜底分支只保留:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"branchId": "<branchId>",
|
|
421
|
+
"branchType": 2
|
|
422
|
+
}
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
#### `feature_split_flow`
|
|
426
|
+
|
|
427
|
+
```json
|
|
428
|
+
{
|
|
429
|
+
"splitFlowType": 1,
|
|
430
|
+
"branchList": [
|
|
431
|
+
{
|
|
432
|
+
"branchId": "<branchId>",
|
|
433
|
+
"branchName": "<label>",
|
|
434
|
+
"branchType": 1,
|
|
435
|
+
"realtime": 0,
|
|
436
|
+
"clusterRefresh": 12,
|
|
437
|
+
"clusterPredictCount": null,
|
|
438
|
+
"clusterPredictTime": "<YYYY-MM-DD HH:mm:ss>",
|
|
439
|
+
"targetClusterQp": "<JSON.stringify(qp)>"
|
|
440
|
+
}
|
|
441
|
+
]
|
|
442
|
+
}
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
规则:
|
|
446
|
+
- 属性 / 标签条件 -> `targetClusterQp`
|
|
447
|
+
- 兜底分支同样只保留 `branchId` + `branchType: 2`
|
|
448
|
+
|
|
449
|
+
#### `ab_split_flow`
|
|
450
|
+
|
|
451
|
+
```json
|
|
452
|
+
{
|
|
453
|
+
"branchList": [
|
|
454
|
+
{
|
|
455
|
+
"branchId": "<branchId>",
|
|
456
|
+
"branchName": "对照组",
|
|
457
|
+
"branchType": 1,
|
|
458
|
+
"order": 1,
|
|
459
|
+
"percentageInExperiment": 34
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"branchId": "<branchId>",
|
|
463
|
+
"branchName": "实验组 A",
|
|
464
|
+
"branchType": 2,
|
|
465
|
+
"order": 2,
|
|
466
|
+
"percentageInExperiment": 33
|
|
467
|
+
}
|
|
468
|
+
],
|
|
469
|
+
"indicatorsDef": [],
|
|
470
|
+
"activateIndicatorsDef": null
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
规则:
|
|
475
|
+
- 用户没给比例时可均分
|
|
476
|
+
- 3 组时可用 `34/33/33`
|
|
477
|
+
|
|
478
|
+
#### `event_judge`
|
|
479
|
+
|
|
480
|
+
```json
|
|
481
|
+
{
|
|
482
|
+
"transferType": 1,
|
|
483
|
+
"meetBranchId": "<meetBranchId>",
|
|
484
|
+
"notMeetBranchId": "<notMeetBranchId>",
|
|
485
|
+
"triggerRule": [
|
|
486
|
+
{
|
|
487
|
+
"delayTimeSymbol": "<minute|hour|day>",
|
|
488
|
+
"delayTime": "<number>",
|
|
489
|
+
"eventTriggerType": 0,
|
|
490
|
+
"zoneoffset": 8,
|
|
491
|
+
"events": []
|
|
492
|
+
}
|
|
493
|
+
]
|
|
494
|
+
}
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
规则:
|
|
498
|
+
- `node.event` -> `triggerRule[].events[]`
|
|
499
|
+
- `wait_time` -> `delayTimeSymbol` + `delayTime`
|
|
500
|
+
- 未指定等待时长时,可默认 `30 minute`
|
|
501
|
+
|
|
502
|
+
#### `feature_judge`
|
|
503
|
+
|
|
504
|
+
```json
|
|
505
|
+
{
|
|
506
|
+
"transferType": 1,
|
|
507
|
+
"meetBranchId": "<meetBranchId>",
|
|
508
|
+
"notMeetBranchId": "<notMeetBranchId>",
|
|
509
|
+
"clusterPredictCount": null,
|
|
510
|
+
"clusterPredictTime": "",
|
|
511
|
+
"targetClusterQp": "<JSON.stringify(qp)>"
|
|
512
|
+
}
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
#### `message_push` / `webhook_push`
|
|
516
|
+
|
|
517
|
+
```json
|
|
518
|
+
{
|
|
519
|
+
"channelId": "<matched channelId>",
|
|
520
|
+
"channelType": "<matched channelType>",
|
|
521
|
+
"enableChannelTouchLimits": false,
|
|
522
|
+
"isOccasionUp": false,
|
|
523
|
+
"contentList": [
|
|
524
|
+
{
|
|
525
|
+
"pushLanguageCode": "default",
|
|
526
|
+
"content": []
|
|
527
|
+
}
|
|
528
|
+
],
|
|
529
|
+
"processType": 1
|
|
530
|
+
}
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
规则:
|
|
534
|
+
- `channel_name` -> 匹配真实 `channelId`
|
|
535
|
+
- `content` -> 优先填入最像“正文 / 内容 / 消息”的参数
|
|
536
|
+
- 当参数 `type = TEXT` 时,额外补:
|
|
537
|
+
|
|
538
|
+
```json
|
|
539
|
+
{
|
|
540
|
+
"config": "[{\"type\":\"paragraph\",\"children\":[{\"text\":\"<与 value 相同>\"}]}]"
|
|
541
|
+
}
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
多语言规则:
|
|
545
|
+
- 第一条始终是 `"pushLanguageCode": "default"`
|
|
546
|
+
- 后续按 `languages` 生成其他语言版本
|
|
547
|
+
- 每种语言的 `content[]` 结构相同,只替换 `value`
|
|
548
|
+
|
|
549
|
+
#### `wechat_push`
|
|
550
|
+
|
|
551
|
+
```json
|
|
552
|
+
{
|
|
553
|
+
"channelId": "<matched channelId>",
|
|
554
|
+
"enableChannelTouchLimits": false,
|
|
555
|
+
"isOccasionUp": false,
|
|
556
|
+
"contentList": [
|
|
557
|
+
{
|
|
558
|
+
"pushLanguageCode": "default",
|
|
559
|
+
"content": [
|
|
560
|
+
{
|
|
561
|
+
"key": "lang",
|
|
562
|
+
"type": "STRING",
|
|
563
|
+
"required": true,
|
|
564
|
+
"paramType": 2,
|
|
565
|
+
"name": "语言",
|
|
566
|
+
"value": "default"
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"key": "page",
|
|
570
|
+
"type": "STRING",
|
|
571
|
+
"required": true,
|
|
572
|
+
"paramType": 2,
|
|
573
|
+
"name": "跳转页面",
|
|
574
|
+
"value": ""
|
|
575
|
+
},
|
|
576
|
+
{
|
|
577
|
+
"key": "miniprogramState",
|
|
578
|
+
"type": "STRING",
|
|
579
|
+
"required": true,
|
|
580
|
+
"paramType": 2,
|
|
581
|
+
"name": "版本",
|
|
582
|
+
"value": ""
|
|
583
|
+
}
|
|
584
|
+
]
|
|
585
|
+
}
|
|
586
|
+
],
|
|
587
|
+
"processType": 1
|
|
588
|
+
}
|
|
589
|
+
```
|
|
590
|
+
|
|
591
|
+
#### `time_control`
|
|
592
|
+
|
|
593
|
+
```json
|
|
594
|
+
{
|
|
595
|
+
"controlType": 1,
|
|
596
|
+
"timeUnit": "<minute|hour|day>",
|
|
597
|
+
"timeUnitNum": "<number>"
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
常见解析:
|
|
602
|
+
- `30分钟` -> `minute` + `30`
|
|
603
|
+
- `2小时` -> `hour` + `2`
|
|
604
|
+
- `1天` -> `day` + `1`
|
|
605
|
+
|
|
606
|
+
#### `exit_flow`
|
|
607
|
+
|
|
608
|
+
最小可用 `config`:
|
|
609
|
+
|
|
610
|
+
```json
|
|
611
|
+
{}
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
---
|
|
615
|
+
|
|
616
|
+
## 8. 第六步:`edgeList` 怎么写
|
|
617
|
+
|
|
618
|
+
`edgeList` 中每一项结构如下:
|
|
619
|
+
|
|
620
|
+
| 字段 | 类型 | 必填 | 说明 |
|
|
621
|
+
|---|---|---|---|
|
|
622
|
+
| `source` | string | 是 | 上游节点 ID |
|
|
623
|
+
| `target` | string | 是 | 下游节点 ID |
|
|
624
|
+
| `edgeId` | string | 否 | 连线 ID |
|
|
625
|
+
| `sourceBranchId` | string | 否 | 分支/判断节点出边时使用 |
|
|
626
|
+
| `config` | string | 否 | JSON 字符串 |
|
|
627
|
+
|
|
628
|
+
### 8.1 普通连线
|
|
629
|
+
|
|
630
|
+
```json
|
|
631
|
+
{
|
|
632
|
+
"source": "node_1",
|
|
633
|
+
"target": "node_2"
|
|
634
|
+
}
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### 8.2 分支连线
|
|
638
|
+
|
|
639
|
+
```json
|
|
640
|
+
{
|
|
641
|
+
"source": "node_split",
|
|
642
|
+
"target": "node_a",
|
|
643
|
+
"sourceBranchId": "branch_a"
|
|
644
|
+
}
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### 8.3 最关键的规则
|
|
648
|
+
|
|
649
|
+
1. `source` 和 `target` 必须引用真实存在的 `node.id`
|
|
650
|
+
2. 只有分支节点 / 判断节点的出边才需要 `sourceBranchId`
|
|
651
|
+
3. 图必须是 DAG,不能有环
|
|
652
|
+
4. 分支节点的 `sourceBranchId` 必须来自对应节点 `config` 里已经声明过的 branchId
|
|
653
|
+
|
|
654
|
+
### 8.4 标准出边规则
|
|
655
|
+
|
|
656
|
+
| 节点类型 | 出边数 | `sourceBranchId` 规则 |
|
|
657
|
+
|---|---|---|
|
|
658
|
+
| `single_trigger` / `repeat_trigger` / `event_trigger` | 1 | 不传 |
|
|
659
|
+
| `event_split_flow` / `feature_split_flow` / `ab_split_flow` | 每分支 1 条 | 对应 `branchList[].branchId` |
|
|
660
|
+
| `event_judge` / `feature_judge` | 2 | 分别使用 `meetBranchId` / `notMeetBranchId` |
|
|
661
|
+
| `message_push` / `wechat_push` / `webhook_push` / `time_control` | 1 | 不传 |
|
|
662
|
+
| `exit_flow` | 0 | 不传 |
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
## 9. 第七步:图约束检查
|
|
667
|
+
|
|
668
|
+
在提交前必须自检:
|
|
669
|
+
|
|
670
|
+
1. `nodeList` 非空
|
|
671
|
+
2. 入口节点必须且只能有一个
|
|
672
|
+
3. 至少有一个 `exit_flow`
|
|
673
|
+
4. 每个 `exit_flow` 恰好一条入边,且没有出边
|
|
674
|
+
5. 每个 `node.id` 唯一
|
|
675
|
+
6. 每条边引用的节点都存在
|
|
676
|
+
7. 整张图无环
|
|
677
|
+
|
|
678
|
+
如果分流节点使用 `splitFlowType = 2`,还要额外保证:
|
|
679
|
+
- 不同分支后续路径不要再次汇合到同一个节点
|
|
680
|
+
- 每条分支应独立走到自己的 `exit_flow`
|
|
681
|
+
|
|
682
|
+
---
|
|
683
|
+
|
|
684
|
+
## 10. 第八步:CLI 提交
|
|
685
|
+
|
|
686
|
+
### 10.1 顶层 flags
|
|
687
|
+
|
|
688
|
+
| Flag | 类型 | 必填 | 说明 |
|
|
689
|
+
|---|---|---|---|
|
|
690
|
+
| `--project-id` / `-p` | number | 是 | 项目 ID |
|
|
691
|
+
| `--req` | json | 是 | 最终请求体对象 |
|
|
692
|
+
|
|
693
|
+
### 10.2 CLI 实际提交结构
|
|
694
|
+
|
|
695
|
+
CLI 会把输入整理成:
|
|
696
|
+
|
|
697
|
+
```json
|
|
698
|
+
{
|
|
699
|
+
"projectId": 1,
|
|
700
|
+
"req": {
|
|
701
|
+
"projectId": 1,
|
|
702
|
+
"...": "..."
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
也就是说:
|
|
708
|
+
- 顶层 `projectId` 来自 `--project-id`
|
|
709
|
+
- `req.projectId` 也会由 CLI 自动注入
|
|
710
|
+
|
|
711
|
+
### 10.3 最小可用示例
|
|
712
|
+
|
|
713
|
+
```bash
|
|
714
|
+
te-cli te-engage +save-flow \
|
|
715
|
+
--project-id 1 \
|
|
716
|
+
--req '{
|
|
717
|
+
"flowName": "Welcome Flow",
|
|
718
|
+
"flowDesc": "New user welcome flow",
|
|
719
|
+
"groupId": 0,
|
|
720
|
+
"tzOffset": 8,
|
|
721
|
+
"nodeList": [
|
|
722
|
+
{
|
|
723
|
+
"id": "node_1",
|
|
724
|
+
"name": "进入流程",
|
|
725
|
+
"type": "single_trigger",
|
|
726
|
+
"config": "{}"
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
"id": "node_2",
|
|
730
|
+
"name": "结束",
|
|
731
|
+
"type": "exit_flow",
|
|
732
|
+
"config": "{}"
|
|
733
|
+
}
|
|
734
|
+
],
|
|
735
|
+
"edgeList": [
|
|
736
|
+
{
|
|
737
|
+
"source": "node_1",
|
|
738
|
+
"target": "node_2"
|
|
739
|
+
}
|
|
740
|
+
]
|
|
741
|
+
}'
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
### 10.4 创建成功后的输出要求
|
|
745
|
+
|
|
746
|
+
前置条件:
|
|
747
|
+
- 创建流程画布成功,返回了新创建的流程画布 `flowUuid`
|
|
748
|
+
|
|
749
|
+
成功时必须:
|
|
750
|
+
- 向用户展示创建结果,至少包含画布名称等关键信息
|
|
751
|
+
- 必须输出一个**可点击的 Markdown 链接**
|
|
752
|
+
|
|
753
|
+
链接生成规则:
|
|
754
|
+
- 使用标准 Markdown 链接语法,禁止放在代码块中
|
|
755
|
+
- URL 必须以 `/#/` 开头,禁止添加域名或任何域名占位符
|
|
756
|
+
- 将 `save_flow` 返回的 `flowUuid` 和本次创建使用的 `projectId` 替换到 URL 中
|
|
757
|
+
|
|
758
|
+
输出模板:
|
|
759
|
+
|
|
760
|
+
[点击查看画布](/#/hermes/flow/detail?flowUuid=<替换为实际flowUuid>¤tProjectId=<替换为实际projectId>)
|
|
761
|
+
|
|
762
|
+
正确示例:
|
|
763
|
+
|
|
764
|
+
[点击查看画布](/#/hermes/flow/detail?flowUuid=0006_831135755¤tProjectId=1)
|
|
765
|
+
|
|
766
|
+
常见错误:
|
|
767
|
+
- `❌ {域名}/#/hermes/flow/...`:不要加域名占位符
|
|
768
|
+
- `❌` 把链接放在代码块 ````` 中:代码块内的链接不可点击
|
|
769
|
+
- `❌ /#/hermes/flow/detail?flowUuid=...`:不要输出纯文本 URL,必须使用 `[文字](URL)` 格式
|
|
770
|
+
|
|
771
|
+
### 10.5 创建失败后的输出要求
|
|
772
|
+
|
|
773
|
+
失败时必须:
|
|
774
|
+
- 输出完整请求体 JSON,供用户调试
|
|
775
|
+
- 明确说明失败原因
|
|
776
|
+
|
|
777
|
+
建议输出结构:
|
|
778
|
+
|
|
779
|
+
```json
|
|
780
|
+
{
|
|
781
|
+
"projectId": "<实际 projectId>",
|
|
782
|
+
"req": {
|
|
783
|
+
"...": "完整 save_flow 请求体"
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
---
|
|
789
|
+
|
|
790
|
+
## 11. 最容易写错的地方
|
|
791
|
+
|
|
792
|
+
### 11.1 `--req` 是对象,但 `node.config` / `edge.config` 是字符串
|
|
793
|
+
|
|
794
|
+
正确:
|
|
795
|
+
|
|
796
|
+
```json
|
|
797
|
+
{
|
|
798
|
+
"id": "node_1",
|
|
799
|
+
"name": "entry",
|
|
800
|
+
"type": "single_trigger",
|
|
801
|
+
"config": "{}"
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
错误:
|
|
806
|
+
|
|
807
|
+
```json
|
|
808
|
+
{
|
|
809
|
+
"id": "node_1",
|
|
810
|
+
"name": "entry",
|
|
811
|
+
"type": "single_trigger",
|
|
812
|
+
"config": {}
|
|
813
|
+
}
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### 11.2 时间单位必须小写
|
|
817
|
+
|
|
818
|
+
像 `time_control` 里,应使用:
|
|
819
|
+
|
|
820
|
+
- `day`
|
|
821
|
+
- `hour`
|
|
822
|
+
- `minute`
|
|
823
|
+
- `week`
|
|
824
|
+
- `month`
|
|
825
|
+
|
|
826
|
+
不要写成 `DAY`、`HOUR`、`MINUTE`。
|
|
827
|
+
|
|
828
|
+
### 11.3 不要凭空写 `channelId`
|
|
829
|
+
|
|
830
|
+
`message_push`、`wechat_push`、`webhook_push` 这类节点的 `channelId`,必须来自:
|
|
831
|
+
|
|
832
|
+
```bash
|
|
833
|
+
te-cli te-engage +channel-list --project-id <projectId>
|
|
834
|
+
```
|
|
835
|
+
|
|
836
|
+
### 11.4 分支 ID 必须先定义再引用
|
|
837
|
+
|
|
838
|
+
如果某条边用了:
|
|
839
|
+
|
|
840
|
+
```json
|
|
841
|
+
{ "sourceBranchId": "branch_a" }
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
那么 `"branch_a"` 必须已经存在于对应上游节点的 `config` 中。
|
|
845
|
+
|
|
846
|
+
### 11.5 `targetClusterQp` 本身通常也是字符串
|
|
847
|
+
|
|
848
|
+
虽然 `targetClusterQp` 出现在节点 `config` 的 JSON 对象里,但它的值通常也不是原始对象,而是 QP 对象再做一次 `JSON.stringify` 后的字符串。
|
|
849
|
+
|
|
850
|
+
示意:
|
|
851
|
+
|
|
852
|
+
```json
|
|
853
|
+
{ "targetClusterQp": "{\"totalCFilter\":{\"relation\":\"1\",\"filts\":[]}}" }
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
### 11.6 `TEXT` 参数的富文本 `config` 也必须是字符串
|
|
857
|
+
|
|
858
|
+
push 参数如果是 `TEXT`,它内部那个富文本 `config` 不是对象,而是字符串化 JSON。这个点很容易漏。
|
|
859
|
+
|
|
860
|
+
### 11.7 `splitFlowType = 2` 时不要让分支重新汇合
|
|
861
|
+
|
|
862
|
+
“满足条件即进入”表示用户可能同时进入多个分支,这时后续路径不要共用同一个节点,否则语义容易冲突。
|
|
863
|
+
|
|
864
|
+
---
|
|
865
|
+
|
|
866
|
+
## 12. 一句话总结
|
|
867
|
+
|
|
868
|
+
要稳定构建 `+save-flow` 的入参,不能直接从自然语言跳到 `req`,而应该遵循这条链路:
|
|
869
|
+
|
|
870
|
+
**用户需求 -> 意图 JSON -> schema / 通道补全 -> `nodeList` / `edgeList` -> `te-cli te-engage +save-flow`。**
|