Coze 工作流进阶:从单 Bot 到复杂业务编排
深入掌握 Coze 工作流的节点编排、变量传递、循环控制、调试技巧,从玩具级 Bot 升级到生产级业务自动化。
概述
如果你已经按 《Coze 入门》 跑通了第一个 Bot,可能很快就遇到这些问题:
- 系统提示词越写越长,模型开始"忘事"
- 想让 Bot 先搜索、再总结、再翻译,串起来就掉链子
- 需要根据用户意图走不同分支,单 Prompt 控制不住
- 想批量处理(比如一次分析 10 篇文章),单次调用搞不定
这些问题的答案都是同一个:用工作流(Workflow)替代单 Bot。
单 Bot vs 工作流
| 维度 | 单 Bot | 工作流 | |------|--------|--------| | 适合任务 | 单步对话、QA | 多步骤、有逻辑分支 | | 可控性 | 全靠 Prompt | 节点级显式控制 | | 调试 | 黑盒 | 每个节点可看输入输出 | | 复用 | Prompt 复制粘贴 | 子工作流模块化 | | 性能 | 单次 LLM 调用 | 可并行 + 缓存 |
简单说:单 Bot 像一个聊天员工,工作流像一条流水线。当任务复杂到需要 SOP,就该换工作流。
本文你将掌握
- 5 类核心节点的精细化用法
- 变量系统与数据流转的最佳实践
- 循环、分支、并发的工程化处理
- 两个完整实战案例(选品助手 + 写作流水线)
- 调试、优化、发布的全套技巧
快速开始
进入工作流编辑器
画布初始有两个固定节点:
- 开始节点(Start):定义工作流的入参
- 结束节点(End):定义工作流的出参
中间的所有处理逻辑由你编排。
一个最简工作流
目标:输入一段中文,返回它的英文翻译 + 字数。
节点设计:
[开始: text] → [LLM 翻译] → [代码: 数字数] → [结束: en, count]
步骤:
- 开始节点:添加输入参数
text(String) - LLM 节点:
- 模型选 GPT-4o-mini 或豆包
- User Prompt:
将以下文本翻译成英文,只输出译文,不加任何解释:\n{{text}} - 输出变量:
en(String)
- 代码节点(IDE,JS):
async function main({ params }) { return { count: params.text.length }; } - 结束节点:输出
en、count
试运行:右上角 试运行 → 输入 text → 查看每个节点的输出。
5 分钟跑通了,下面进入正题。
详细步骤
一、5 类核心节点深度讲解
1. LLM 节点
工作流里最常用的节点,但用好了不容易。
模型选择策略:
| 任务类型 | 推荐模型 | 原因 | |---------|---------|------| | 简单分类、抽取 | 豆包 lite / GPT-4o-mini | 便宜、快 | | 长文本理解 | 豆包 pro / GPT-4o | 上下文充足 | | 创意写作 | GPT-4o / Claude | 文笔自然 | | 代码生成 | Claude / DeepSeek | 代码能力顶尖 | | 中文场景 | 豆包 / Qwen | 中文优化 |
关键参数:
- Temperature:分类抽取用 0-0.3,对话用 0.5-0.7,创作用 0.8+
- Top P:通常保持 0.9,与 Temperature 二选一调
- Max Tokens:留够缓冲,避免输出截断
- JSON 模式:开启后强制输出合法 JSON,强烈推荐用于下游需要解析的场景
Prompt 写法 3 个技巧:
技巧 1:用 XML 标签包裹用户输入
请翻译下面的内容:
<input>
{{user_text}}
</input>
只输出译文,不加引号。
避免用户输入中混入指令污染(间接 Prompt 注入)。
技巧 2:明确输出 JSON Schema
分析下面的产品评论,输出 JSON:
{
"sentiment": "positive" | "negative" | "neutral",
"key_points": [string, string, string],
"score": 0-10 的整数
}
评论:{{review}}
只输出 JSON,不加 ```json 标记。
技巧 3:用 Few-shot 锁定格式
复杂任务前面给 1-2 个示例,输出稳定性翻倍。
2. 代码节点(Code)
代码节点是工作流的"瑞士军刀"。当节点连线变得复杂、或需要做数据格式转换时,写几行代码比连十个节点更清爽。
支持语言:JavaScript、Python(部分版本)
入参与出参:
async function main({ params }) {
// params 是上游所有输入变量的集合
const { text, count } = params;
// 必须返回一个对象,键就是输出变量名
return {
upper: text.toUpperCase(),
is_long: count > 100
};
}
实用模板 1:数组聚合
async function main({ params }) {
const items = params.list; // 假设是数组
return {
total: items.length,
summary: items.map(i => `- ${i.title}`).join("\n"),
top3: items.slice(0, 3)
};
}
实用模板 2:JSON 容错解析
LLM 偶尔会返回带 json 包裹或额外解释的内容,需要做容错:
async function main({ params }) {
let raw = params.llm_output.trim();
// 去除 markdown 代码块标记
raw = raw.replace(/^```json\s*/i, "").replace(/```$/, "");
try {
const data = JSON.parse(raw);
return { data, success: true };
} catch (e) {
return { data: null, success: false, error: e.message };
}
}
实用模板 3:日期时间处理
async function main({ params }) {
const now = new Date();
return {
today: now.toISOString().split("T")[0],
timestamp: now.getTime(),
weekday: ["日","一","二","三","四","五","六"][now.getDay()]
};
}
注意事项:
- 代码节点有执行超时限制(通常 60 秒)
- 不能引入第三方 npm 包(沙箱环境)
- 网络请求功能受限,复杂 API 调用建议用 HTTP 节点或插件
3. 插件节点(Plugin)
调用 Coze 商店中的插件或自定义插件。
何时使用插件:
- 联网搜索(必应、Google 搜索插件)
- 图片生成(DALL-E、Stable Diffusion)
- 工具类(计算器、汇率、天气)
- 自定义业务 API(接入你公司系统)
参数映射注意点:
插件节点的入参可以来自:
- 直接填值(静态)
- 引用上游变量(动态)
- 表达式拼接(
{{user_name}} 的搜索结果)
自定义插件的简易做法:
- 工作空间 → 插件 → 创建插件
- 选择"以 OpenAPI 创建"
- 上传你的接口 OpenAPI Schema
- 配置鉴权(API Key / OAuth)
- 测试每个工具
- 发布到当前空间
之后这个插件就能在所有工作流的插件节点里使用。
4. 选择器节点(条件判断)
让工作流走分支,对应代码里的 if-else。
配置方式:
条件 1: {{intent}} == "购买咨询"
→ 走分支 A(接产品介绍 LLM)
条件 2: {{intent}} == "售后投诉"
→ 走分支 B(接转人工节点)
否则 → 走默认分支(兜底回复)
常用判断表达式:
| 类型 | 写法示例 |
|------|---------|
| 等于 | {{x}} == "value" |
| 不等于 | {{x}} != "value" |
| 数值比较 | {{score}} >= 80 |
| 包含 | {{text}} contains "退款" |
| 长度判断 | length({{list}}) > 0 |
| 逻辑组合 | {{a}} > 0 AND {{b}} == "ok" |
多条件组合的最佳实践:
- 条件不要超过 5 个分支,更多用意图识别节点替代
- 把高频路径放在前面,提升评估效率
- 每个分支留一句"备注",便于团队协作维护
5. 循环节点(Loop / Batch)
批处理利器。Coze 有两种循环模式:
模式 A:循环器(Loop)
固定循环次数,比如"重试 3 次"、"生成 5 个候选标题"。
循环次数: 5
循环体: [LLM 节点:生成一个标题]
输出: titles(自动收集所有循环结果到数组)
模式 B:批处理(Batch)
对一个数组的每个元素执行相同操作,相当于 array.map()。
输入数组: {{articles}} (假设是 10 篇文章对象)
循环体: [LLM 节点:总结当前文章 {{item.content}}]
输出: summaries(10 条总结的数组)
循环节点的关键控制:
- 并发数:默认串行,可设为 5-10 提速。注意模型 RPM 限制
- 错误策略:单条失败时是中断、跳过、还是重试
- 最大次数:循环器要设硬上限,防止失控
二、变量系统全解
工作流的"血液"是变量,理解变量传递机制至关重要。
变量来源
| 来源 | 引用语法 | 示例 |
|------|---------|------|
| 开始节点输入 | {{变量名}} | {{user_question}} |
| 上游节点输出 | {{节点名.字段}} | {{LLM_1.output}} |
| 系统变量 | {{$系统名}} | {{$user_id}} |
| 嵌套对象 | {{节点.对象.字段}} | {{api_call.data.user.name}} |
| 数组元素 | {{节点.list[0]}} | {{search.results[0].title}} |
类型系统
工作流支持的变量类型:
- String:文本
- Integer / Number:整数 / 浮点
- Boolean:布尔
- Object:JSON 对象
Array<T>:数组(必须指定元素类型)- File:文件(图片、文档)
类型不匹配是新手最常见的错误。比如 LLM 返回的 JSON 字符串想当 Object 用,必须先用代码节点 JSON.parse。
变量调试技巧
- 试运行后,点击每个节点能看到 输入 和 输出 的实际值
- 在代码节点里
console.log也能在调试面板看到 - 变量为
null/undefined时下游节点会报错,养成"判空"的习惯
三、控制流的工程化技巧
并发优化
很多工作流之所以慢,是因为顺序执行了本可以并行的节点。
串行写法(慢):
[查产品信息] → [查用户信息] → [查订单信息] → [汇总]
并行写法(快 3 倍):
┌→ [查产品信息] ┐
[开始]→├→ [查用户信息] ├→ [汇总]
└→ [查订单信息] ┘
做法:从同一个上游节点拉出多条线到不同节点,下游用一个汇总节点(代码节点或 LLM 节点)合并所有上游输出。
缓存与去重
某些 LLM 调用结果短期内不会变(比如查产品介绍),可以:
- 在代码节点里加一层 KV 存储(Coze 数据库节点)
- 命中缓存直接返回,否则调用 LLM 后写入缓存
- 设置 TTL(24 小时通常够)
成本能省 50% 以上。
兜底与降级
任何外部依赖都可能失败。在关键节点后加错误分支:
[调用三方 API]
├ 成功 → [继续主流程]
└ 失败 → [降级到 LLM 直接回答 + 标记需人工跟进]
具体做法:
- 选择器节点判断 API 返回的
status字段 - 或在代码节点里 try/catch,根据
success字段分支
四、子工作流(Sub-Workflow)
当一个工作流超过 20 个节点,维护就变得痛苦。子工作流是模块化救星。
何时拆子工作流:
- 有可复用的逻辑块(比如"内容审核"被多个主流程调用)
- 单一职责的子流程(比如"生成图片"独立成一个工作流)
- 主流程超过 15 个节点
调用方式:
主工作流中加 工作流节点,选择已发布的子工作流,配置入参映射即可。子工作流的输出会作为这个节点的输出供下游使用。
最佳实践:
- 子工作流命名带前缀,如
sub_审核_文本 - 每个子工作流写清楚 README(描述、入参、出参)
- 子工作流单独维护版本,主流程升级前回归测试
实战案例 1:智能选品助手
场景:跨境电商团队每天需要从竞品热销榜中筛选潜在选品,原本人工要花 2 小时。
目标:输入类目关键词 → 自动采集 → 多维评分 → 输出 Markdown 报告。
工作流设计
[开始: keyword]
↓
[插件: 商品搜索] → 返回 50 条商品
↓
[代码: 数据清洗] → 过滤无效数据,保留 20 条
↓
[批处理 Batch]
├ 每条商品并发执行:
│ [LLM: 选品打分] → 输出 5 个维度分数 + 理由
└ 收集所有打分结果
↓
[代码: 综合排序] → 按总分排序,取 Top 10
↓
[LLM: 生成报告] → Markdown 报告
↓
[结束: report]
关键节点配置
节点:商品搜索(插件)
- 选择"亚马逊商品搜索"插件
- 入参:
keyword = {{keyword}},limit = 50 - 输出:
products(Array<Object>)
节点:数据清洗(代码)
async function main({ params }) {
const products = params.products || [];
const filtered = products
.filter(p => p.price && p.rating >= 4.0 && p.reviews >= 100)
.slice(0, 20)
.map(p => ({
asin: p.asin,
title: p.title,
price: p.price,
rating: p.rating,
reviews: p.reviews,
bsr: p.bsr || 99999
}));
return { filtered };
}
节点:选品打分(LLM,在 Batch 内)
- 入参:
{{item}}(当前批次的商品对象) - Prompt:
你是资深选品分析师。对以下商品从 5 个维度打分(0-10):
商品信息:
- 标题:{{item.title}}
- 价格:${{item.price}}
- 评分:{{item.rating}}
- 评论数:{{item.reviews}}
- BSR 排名:{{item.bsr}}
5 个维度:
1. market_demand:市场需求
2. competition:竞争激烈度(10 分代表蓝海)
3. profit_margin:利润空间
4. operation_difficulty:运营难度(10 分代表简单)
5. trend:趋势上升性
输出 JSON:
{
"asin": "{{item.asin}}",
"scores": {
"market_demand": 0,
"competition": 0,
"profit_margin": 0,
"operation_difficulty": 0,
"trend": 0
},
"total": 0,
"reason": "30 字内核心理由"
}
- 开启 JSON 模式
- 输出:
scoring(Object)
节点:综合排序(代码)
async function main({ params }) {
const list = params.scoring_list;
const sorted = list
.sort((a, b) => b.total - a.total)
.slice(0, 10);
return { top10: sorted };
}
节点:生成报告(LLM)
基于以下选品数据,生成 Markdown 格式的选品周报:
数据:{{top10}}
要求:
1. 标题:## 本周选品推荐 Top 10
2. 表格列出 ASIN、标题、价格、总分、推荐理由
3. 末尾给出 3 条整体洞察
上线效果
- 单次执行:约 90 秒(并发 10 时)
- 单次成本:约 ¥0.3(豆包 lite)
- 替代人工 2 小时工作
实战案例 2:自动化写作流水线
场景:内容团队需要每天产出 5 篇行业资讯文章,覆盖大纲、撰写、配图、发布。
工作流设计
[开始: topic, target_length, style]
↓
[LLM: 大纲生成] → 5-7 个章节大纲
↓
[代码: 拆分章节] → 章节数组
↓
[Batch: 分章撰写]
├ 每章并发:[LLM: 撰写本章]
└ 收集所有章节内容
↓
[代码: 拼接文章] → 完整 Markdown
↓
┌→ [LLM: 标题优化] → 3 个候选标题
├→ [LLM: 摘要生成] → 150 字摘要
└→ [LLM: 配图 Prompt] → DALL-E 提示词
↓
[插件: 图片生成] → cover_url
↓
[LLM: 校对] → 修正错别字、语病
↓
[结束: title, summary, content, cover_url]
关键节点要点
大纲节点的 Prompt 要明确章节数:
为主题"{{topic}}"生成{{section_count}}个章节大纲,目标字数 {{target_length}}。
输出 JSON:
{
"sections": [
{"title": "...", "key_points": ["...", "..."]}
]
}
分章撰写要带"上下文":
每个章节生成时,传入"前一章节摘要"避免割裂感:
你正在撰写文章《{{topic}}》的第 {{index}} 章:{{section.title}}。
前面章节已写:
{{prev_summary}}
本章要点:
{{section.key_points}}
风格:{{style}}
本章字数:约 {{words_per_section}} 字。
并行节点提速:
标题、摘要、配图 Prompt 三个 LLM 调用互不依赖,从同一节点拉三条线并发。
数据回流
发布后用 HTTP 节点把数据写回 Notion 或飞书多维表格:
- 文章 ID、标题、字数、生成时长、Token 消耗
- 后续点击数据可以反哺选题模型
最佳实践
1. 设计原则
- 节点单一职责:一个节点只干一件事,方便调试
- 变量命名规范:用蛇形
snake_case,避免中文变量名 - 关键节点加备注:右键节点 → 添加备注,写清楚意图
- 结构清晰:从左到右流动,避免线交叉过多
2. 调试三件套
单步执行:
每个节点右键 → "从此节点执行",可以隔离测试。
变量面板:
试运行后切换到"变量"标签,查看运行时所有变量的实际值。
Mock 数据:
某节点输出依赖外部 API 时,可以临时用代码节点写死 Mock 数据,专注调试下游逻辑。
3. 性能优化清单
- 能并行的节点都并行
- 高频调用结果走缓存
- LLM 调用选最便宜能用的模型
- 长 Prompt 拆分到 System / User
- 批处理设置合理并发数(5-10)
- 不必要的 LLM 节点用代码节点替代
4. 错误处理
节点级:
- 选择器节点判断上游成功标志
- 代码节点 try/catch
- 插件节点配置重试次数
工作流级:
- 关键节点后加"失败兜底"分支
- 把异常写入日志(HTTP 调用日志服务)
- 失败时通知(钉钉、飞书机器人)
5. 发布与版本管理
发布前自检清单:
- 所有节点都试运行通过
- 边界情况测试(空输入、超长输入、特殊字符)
- 错误分支验证
- 成本预估(单次 Token + 调用次数)
- README 文档(入参、出参、限制)
发布:
工作流右上角 发布 → 选择发布到当前空间 / Bot 中调用 / API 调用。
版本管理:
- Coze 自动保存历史版本,可回滚
- 重大改动前手动打"快照"
- 生产用稳定版本,开发用最新版本(同一工作流复制两份)
6. 接入到 Bot
工作流不只是独立运行,更常见的是嵌入到 Bot 中:
- 进入 Bot 编辑页 → 工作流 标签 → 添加你的工作流
- 在 Prompt 中明确告诉 Bot 何时调用:
你是选品助手。当用户询问类目商品推荐时,调用 product_selector 工作流,
并基于其返回结果用通俗语言总结给用户。
- Bot 会根据用户意图自动决定调用时机和参数
7. 用 API 触发工作流
工作流也可以发布为 API,从外部系统调用:
curl -X POST 'https://api.coze.cn/v1/workflow/run' \
-H "Authorization: Bearer YOUR_PAT" \
-H "Content-Type: application/json" \
-d '{
"workflow_id": "xxxxx",
"parameters": {
"topic": "AI 自动化"
}
}'
适合接入到飞书机器人、网站后端、定时任务等场景。
常见问题
Q:为什么工作流执行越来越慢?
A:常见原因:① 节点数过多(>30);② 大量串行 LLM 调用;③ 输入数据量过大。优化:拆子工作流、并行化、缩减 Prompt。
Q:变量在节点间消失怎么办?
A:检查节点输出是否正确定义。LLM 节点要在"输出"配置里显式声明变量。
Q:Batch 循环里能调用工作流节点吗?
A:可以。批处理 + 子工作流是处理复杂集合的黄金搭配。
Q:工作流和 Bot 哪个更适合做客服?
A:单纯 FAQ 用 Bot+知识库即可;如果客服需要查工单、转人工、写工单,必须用工作流编排。
Q:开发版和发布版有什么区别?
A:编辑器里改的是开发版,必须点"发布"才会生效到线上调用。这个机制可以避免改一半的工作流影响生产。
下一步
更多 Coze 实战案例与模板持续更新于 aidz.fun。