跳转到主要内容
文档参考最佳实践

最佳实践

何时用哪种步骤、如何写 idempotent、模块化、性能与成本调优 —— 工程化工作流的集体经验。

这一篇是"踩过的坑"汇总。写过 10 条以上工作流就能感同身受;没写过就先存着,碰到了翻回来看。

一、如何写一条"能上生产"的工作流

从模板起步

哪怕你的场景看起来很独特,240+ 个模板里总有一条"拆一半、改一半"能用的。从模板起步省掉大量从零搭骨架的时间。

从模板实例化 是大多数用户的第一步。

先做"最蠢版本",再做"聪明版本"

新工作流第一版:

  • 变量写死默认值
  • condition 都不加,全部都跑
  • 用平台统一的 LLM Key,不折腾 BYOK
  • 不挂 cron,手动跑

跑通后再逐个"精细化":变量化、分支、BYOK、cron、审批。这样每一步出问题都好定位。

每次改都先 dry-run

改了东西 → dry-run 看 DAG 结构和变量流 → 再真跑。dry-run 零成本,不要跳。

二、步骤类型的选择

优先级从上到下,遇到选择困难挑排得靠上的那个:

  1. code — 能用确定性逻辑就别用 LLM。快、便宜、可测试。
  2. classifier — 需要 LLM 但输出是一个类别时用;不要用 single 让 Agent 自由发挥。
  3. single — 大部分"摘要 / 抽取 / 改写"任务。
  4. sub_workflow — 同一段逻辑在多个 workflow 里复用,或单 workflow > 15 个 step。
  5. group_chat — 任务需要多个视角互相讨论时用;一个 Agent 能独立完成的用 single。
  6. agent_based — 任务有很强分支特征,每个分支都需要 LLM 判断派到哪里。
  7. state_machine — 有明确的状态转移,譬如多轮交互 / 工单生命周期。
  8. manual_approval — 影响线上 / 花钱 / 对外的步骤前都要加。
反模式:全部丢给 agent_based

把所有事情交给 orchestrator 动态派发,看起来灵活,实际是"让 LLM 做系统设计"—— 不可复现、难调试、token 成本高。agent_based 的 worker 数要清晰、少于 5 个。

三、变量与数据流

大字段先 extract 再传

上游 step 返回 100KB JSON 时,不要直接塞给下游 task。用 extract 把真正需要的字段挑出来:

yaml
- id: fetch_data
  type: code
  code: |
    // 返回一个很大的 JSON
    return await heavyFetch();
  extract:
    user_count: $.data.stats.total_users
    top_3: $.data.items[:3].name

用 | default(...) 兜底

引用可能为空的变量(被 condition 跳过的 step 的输出)时,加 default:

yaml
- id: summarize
  type: single
  agent: writer
  condition: "length({{steps.classify.categories}} | default([])) > 0"
  task: "{{steps.classify.output | default('无内容可摘要')}}"

condition 分支 vs on_failure

不要混用:

  • condition 控制"正常情况下走不走这一步"—— 跳过 = SKIPPED(不算失败)
  • on_failure 是"出错后的补偿动作"—— 发通知 / 降级到备用数据源

把 on_failure 当 try-catch 用,但不要把它当正常分支。业务正常逻辑用 condition。

四、Agent 与模型

tool_set 越小越好

默认 preset 给的工具多数 step 用不上。裁到 2–3 个 —— 成功率上升、token 消耗下降。

模型按任务挑

  • 推理 / 代码审阅 → Claude Opus 4 / GPT-5 / DeepSeek-Reasoning
  • 短摘要 / 分类 → Haiku / GPT-4.1-mini / DeepSeek-V3.5
  • 中文写作 → Claude Sonnet / Kimi K2
  • 长上下文(32K+)→ Kimi K2 / Claude 200K

temperature 按任务挑

  • 0.0 – 0.3 —— 推理 / 分类 / 抽取(要稳定)
  • 0.4 – 0.7 —— 摘要 / 改写(平衡)
  • 0.7 – 0.9 —— 创意写作 / 头脑风暴(要发散)

五、idempotent 与自动续跑

纯数据管道的 step 都加 idempotent: true —— 服务重启后可续跑。含副作用(发消息 / 下单)的 step 不要加。

详见 自动续跑

六、拆分与模块化

  1. 一个 workflow 超过 15 个 step —— 该拆。
  2. 同一段 3–5 步逻辑在另一个 workflow 里也要用 —— 该做成模块(sub_workflow)。
  3. 模块发布后,删 input / 改类型都是破坏兼容,要升 MAJOR 版本。

七、成本控制

  • 先 dry-run — 已说过,白跑一次真执行浪费的钱最多,这条最省。
  • 分类用便宜模型 — classifier 十有八九不需要 Opus / GPT-5。
  • 并发有上限 — 批处理用 sub_workflow + max_parallel 控制并发,别让 TPM 打爆。
  • 缓存 RAG index — 同一语料每次都 re-embedding 很贵,把结果持久化到产物。
  • 绑预算告警 — 在通知设置里加"单 execution cost > $1"或"当日累计 > $50"告警。

八、安全与合规

  • 永远不把 key 写进 YAML —— 用凭据中心。
  • code step 的 credentials: 列表要显式 —— 不给 step 它用不上的凭据。
  • 付款 / 对外通讯 / 写客户数据库前都加 manual_approval。
  • 涉及用户数据的 workflow 考虑开启 审批人列表,让合规团队进 approvers。
  • Webhook 用的 API Key(以及兼容模式的 signing secret)定期轮换。

九、测试与上线流程

  1. 新 workflow 先在测试工作流页 dry-run。
  2. code step 的脚本单独在本地 node / python 里跑一次看输出。
  3. Agent 行为用断点调试器 + 小样本跑 10 次看稳定性。
  4. 调度上线前用"立即触发一次"验证时区 / 参数预设。

十、协作与版本

  • 重要改动前先"导出 YAML"本地备份 —— 哪怕版本历史兜底,一份本地副本更踏实。
  • 多人编辑:一个人拿锁、改完保存、释放锁,再下一个人拿。并行改请拆成子工作流。
  • 大版本变更前和团队同步 —— 别人可能正在依赖你的模块。

十一、监控与告警

  • 关键 workflow 的 execution.failed 绑 Slack / 飞书通知 —— 失败了第一时间知道。
  • 定期查看数据看板 —— 哪条 workflow 最贵 / 最慢 / 最常失败?优化从它开始。
  • 每月看一次审计日志 —— 权限有没有异常 / 凭据被谁用过。

十二、我做完一条工作流的 checklist

  1. dry-run 通过
  2. 真跑一次成功
  3. 每个 step 的 idempotent / retry 策略已确认
  4. 对外副作用前有 manual_approval 或 condition 明确控制
  5. 所有凭据都从凭据中心解析,YAML 里没有 plaintext key
  6. cron / webhook 绑好并确认"下次触发时间"
  7. 失败通知配好(至少把 execution.failed 推到 Slack)
  8. YAML 导出一份到 git 做异地备份

推荐延伸阅读