mcpField
B
building-workflows

building-workflows

github.com/posthog营销与增长95164 次安装今天更新
代码仓库

关于 building-workflows

这是一个通过 MCP 编写、测试、发布和监控 PostHog 工作流图的技能,强调遵循图结构规范,并要求在启用或发布前取得明确确认。

主要功能

  1. 01编写符合结构规范的工作流图
  2. 02创建草稿并逐步测试执行
  3. 03修改图结构和邮件内容
  4. 04审阅影响后发布暂存更改
  5. 05监控运行、日志和修订记录

适用场景

  1. 01构建并测试消息工作流
  2. 02修改线上工作流而不立即上线
  3. 03排查工作流步骤失败或跳过

MCP 相关

通过 PostHog MCP 工具创建、测试、编辑、发布、调度和监控工作流。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/ai-plugin --skill building-workflows

安装后在 Claude Code 中输入/building-workflows确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
graph-schema.md
lifecycle-and-debugging.md
onboarding.md

详细介绍

构建工作流

PostHog 工作流是一个有向图:由 操作节点(actions)构成的列表,通过 边(edges)连接,并且恰好有一个用于启动每次运行的 trigger 节点。你需要将此图编写为 JSON,并通过 MCP 发送。始终将其称为“工作流”。“Hog flow”是内部代码名称(HogFlow),不是面向用户的术语。

最常见的失败原因是图 JSON 的结构有误。后端会将 actions/config 作为宽松的 JSON 存储,但可视化编辑器会按照严格的架构解析每个节点,因此格式错误的节点虽然能够保存,却会导致整个工作流的编辑器视图出错。在编写或编辑任何图之前,请先阅读 references/graph-schema.md。这是必须遵守的规范;不要只根据这些示例自行推断节点结构。

创建第一个消息工作流之前

当用户要求设置工作流或消息功能,或要求在可能尚未启用发送功能的项目中创建电子邮件、SMS 或推送工作流时,请先调用 workflows-setup-status,再编写任何内容。它会指出哪些设置步骤尚未完成,并提供应用中各步骤的链接。引导用户完成未完成的步骤,设置发送规则,然后再提供建议的工作流。请阅读 references/onboarding.md,了解流程和建议采用的默认设置。

对于仅向 Slack 发布消息或调用 Webhook 的自动化,可跳过此步骤:它们无需设置电子邮件。如果 workflows-setup-status 不可用,请直接进入后续生命周期。

生命周期

按以下阶段完成工作流。不要直接跳到启用步骤。

  1. 编排图。 按照 references/graph-schema.md 构建 actions + edges。对于任何 function 节点,不要猜测模板:使用 cdp-function-templates-list 列出当前目录,并使用 cdp-function-templates-retrieve 查看其必需输入。
  2. 创建为草稿。 使用 workflows-create。每个工作流创建时都是 draft;此时不会执行。
  3. 测试运行。 workflows-test-run 每次只运行一个步骤。从第一步开始(省略 current_action_id,或将其指向触发器),并使用示例 globals({event, person, groups}),其结构应与触发器的真实载荷一致:event 触发器需要符合其筛选条件的事件;internal-event 触发器需要名称列在其 filters.events 中的事件(对于 Slack 触发器,需要包含 Slack 属性包的 $slack_message_received 事件),且不需要 person(参见 references/graph-schema.md)。结果为 status=skipped 表示此载荷不会触发该触发器:如果载荷是你构造的,就修正它,使其符合触发器的条件;如果载荷来自真实的过往运行(workflows-get-invocation),则有问题的是触发器的筛选条件,而非载荷。结果中包含下一步的 ID(nextActionId)。将其作为 current_action_id 传回并再次运行,逐步执行直至结束。跳过 delay 节点,直接跳到其后的操作(不会模拟延迟)。除非设置 mock_async_functions=false,否则异步副作用(HTTP/电子邮件/SMS/推送)会被模拟。阅读每一步的跟踪记录,确认执行路径。
  4. 迭代时查看日志。 workflows-logs 会显示每一步的执行跟踪记录(级别从 DEBUG 到 ERROR)。通过这些记录可以了解某一步为何被跳过、发生分支或出错。
  5. 编辑后重新测试。 使用 workflows-patch-graph 修补图(参见编辑草稿)。每次编辑都会使之前的测试失效——继续之前,请重新运行受影响的路径。对于草稿工作流,编辑会直接生效;对于已启用的工作流,编辑会暂存为草稿(参见更改运行中的工作流)。
  6. 启用(需要用户明确同意)。 workflows-enable 会将其切换为 active,此后,event/webhook/manual 触发器会在有符合条件的活动时触发。从那时起,工作流将在真实用户身上运行;每次变更都必须经过“草稿 → 测试 → 发布”流程才能生效——因此,请先完成测试,再取得用户明确同意后启用。不要擅自启用。
  7. 派发(仅限批次/定时工作流)。 batch 或 schedule 工作流不会仅因启用而触发。使用 workflows-run-batch 发送一次性广播,或使用 workflows-schedule-create 设置周期性定时任务。batch 触发器会向一组用户派发任务,因此为其设置定时任务时需要先通过 workflows-blast-radius 预览,并提供确认令牌;schedule 触发器则在每次定时发生时运行一次,不针对用户群,因此可直接设置定时任务。使用 workflows-get 确认 status=='active',并且其只读字段 schedules 中有一个处于启用状态的条目。
  8. 监控。 逐层深入查看:从 workflows-global-stats(哪些工作流运行失败)到 workflows-stats(单个工作流的趋势),再到 workflows-list-invocations(哪些用户遇到了失败),然后是 workflows-get-invocation(触发载荷),最后查看 workflows-logs(出错的步骤)。

完整工具目录按任务分类,见:references/lifecycle-and-debugging.md。

编辑草稿

打补丁,不要替换。 使用 workflows-patch-graph 编辑草稿:它接受一小组有序操作,这些操作通过 ID 定位(update_action、add_action、remove_action、add_edge、remove_edge、replace_action_edges)。update_action 会深度合并补丁,因此修改一封邮件的主题只需几行,而不是整个图。操作会在服务端以原子方式应用(读取、按顺序应用、验证,仅在有效时保存),响应会回显完整的更新后图,因此下次编辑前无需重新获取。这让每次往返的数据量都很小,无需重新传输每个操作和边。

workflows-update 仅用于更新图补丁无法表达的内容:顶层字段,例如 name、description、exit_condition、conversion、trigger_masking 和 variables。它会直接拒绝 actions/edges——部分列表会悄悄丢弃其中省略的每个步骤——因此所有图更改都必须通过 workflows-patch-graph 完成。

任何补丁应用后,都要重新测试你更改的路径(第 3 步)。补丁通过结构验证,并不代表路由方向正确。

邮件内容也遵循同样的规则。 function_email 步骤中的邮件应使用 workflows-patch-action-email 编辑:它采用与模板补丁相同的按 ID 定位的设计操作,另外还支持对主题、预标题、正文和收件人进行 email_patch 合并;HTML 会在服务端重新渲染,因此始终与设计一致。 编辑邮件内容时,优先使用它,而不是 workflows-patch-graph 的 update_action——通过 update_action 更改 design 会导致已存储的 html 过时。 应使用 workflows-patch-email-template 编辑库模板,而不是 workflows-update-email-template(后者会重新发送完整的设计 JSON)。 使用 designing-email-templates 技能编写和编辑邮件设计。

更改运行中的工作流

编辑活动工作流会暂存一份草稿,而不是更改正在运行的配置:发布之前,任何更改都不会影响真实用户。按以下流程操作:

  1. 编辑。 对活动工作流调用 workflows-patch-graph(或使用 workflows-update 修改内容字段)会将更改写入草稿——首次编辑会将实时图复制到草稿中,之后的编辑会在此基础上叠加。workflows-get 会在 draft 中显示暂存的草稿;实时配置仍保存在 actions/edges 中。元数据(名称、描述)会立即应用到实时配置。
  2. 测试草稿。 使用 use_draft=true 调用 workflows-test-run,会执行暂存的草稿,而不是实时配置。更改了哪些路径,就重新测试哪些路径。
  3. 谨慎发布。 调用 workflows-publish 时不带 confirm,会返回 in_flight_runs、confirm_token 和 impact 摘要:对每个已删除步骤,说明大约有多少人停留在此处,以及他们会转到哪个保留步骤(moves_to)或退出;empty_variables 列出可能在用户已越过新生产步骤、随后到达变量引用时显示为空的变量(这是结构性警告——即使所有进行中的用户都仍在生产步骤之前,也可能触发);schedule_conflicts 列出覆盖草稿中已移除变量的计划。向用户展示影响摘要并取得其同意,然后再次调用,并设置 confirm=true 和对应的 confirm_token。如果返回 409,表示预览后草稿已更改;如果返回 400,表示令牌已过期(15 分钟)——无论哪种情况,都应重新预览并再次确认。发布时会重新验证所有内容,因此无效草稿会被拒绝,实时配置不会受到影响。
  4. 或者放弃。 workflows-discard-draft 会丢弃暂存的草稿。

进行中的运行会遵循实时配置:发布后,流程进行到一半的用户会从新版本中的当前步骤继续。已通过的步骤不会重新运行;停留在发布时被删除的步骤上的用户会跳到下一个保留步骤(若无后续步骤则退出),与影响预览中的报告完全一致。

时间安排的更改会逐步应用于停留中的运行,而不会立即生效。发布缩短后的延迟(或移动后的等待时段)会通过限流扫描重新安排停留在该处的运行。已接近预定唤醒时间的运行会保留原先较早的唤醒时间;只有扫描将唤醒时间提前的运行会受到影响,这些运行会分散安排,且唤醒时间不会早于发布后几分钟(也不会晚于原定时间)。发布后短时间内仍有运行停留在该处是正常情况——请向用户说明这一点,不要重新发布或将其视为失败。

回滚

每次更改实时内容,都会向工作流的修订历史追加一份快照。workflows-list-revisions 会列出各个版本(按时间从新到旧);workflows-get-revision 会返回某个版本的完整内容。要回滚(或向前恢复),workflows-restore-revision 会将该版本的内容复制到草稿中——不会触及实时配置——之后按正常发布流程操作:使用 use_draft=true 进行测试、预览并确认。预览会显示此次回滚对进行中用户的确切影响,与任何一次发布相同。

如果已有打开的草稿,恢复操作会返回 409;请发布或丢弃该草稿,或者传入 overwrite=true 将其替换。回滚无法撤销以下两件事:较新版本运行期间,已经移动或退出的运行会保持原位(其副作用已经发生);发布缩短延迟后,停留中的运行的唤醒时间可能已被提前——回滚不会再将这些时间推迟回去。

服务端负责管理的内容,切勿发送

服务端会编译并管理以下内容。手动编写这些内容是导致工作流损坏的最快方法:

  • 任何过滤器、触发器、条件、转换或屏蔽规则中的 bytecode。由服务端根据人类可读的 properties/hash 编译。省略它;发送 filters: {...},而不是 bytecode。
  • 顶层的 trigger。根据 actions 中的 trigger 操作_派生_而来。只读。添加触发器节点来设置触发器,不要设置此字段。
  • billable_action_types、version、id、created_*。由系统计算或管理。

最简示例

事件触发,等待 1 天,发送邮件,然后退出。注意:恰好一个 trigger,每个非退出节点都有一条出边,且 edges 中引用的 id 保持一致;不会发送 bytecode。

{
  "name": "Nudge after signup",
  "description": "One day after signup, send a reminder.",
  "exit_condition": "exit_only_at_end",
  "actions": [
    {
      "id": "trigger_node",
      "name": "Signed up",
      "type": "trigger",
      "config": {
        "type": "event",
        "filters": { "events": [{ "id": "user signed up", "name": "user signed up", "type": "events", "order": 0 }] }
      }
    },
    {
      "id": "delay_1",
      "name": "Wait 1 day",
      "type": "delay",
      "config": { "delay_duration": "1d" }
    },
    {
      "id": "email_1",
      "name": "Reminder email",
      "type": "function_email",
      "config": {
        "template_id": "template-email",
        "template_uuid": "<uuid returned by workflows-create-email-template>",
        "message_category_type": "marketing",
        "inputs": {
          "email": {
            "value": {
              "to": { "email": "{person.properties.email}", "name": "" },
              "from": { "email": "[email protected]", "name": "Example" }
            }
          }
        }
      }
    },
    {
      "id": "exit_node",
      "name": "Exit",
      "type": "exit",
      "config": { "reason": "Done" }
    }
  ],
  "edges": [
    { "from": "trigger_node", "to": "delay_1", "type": "continue" },
    { "from": "delay_1", "to": "email_1", "type": "continue" },
    { "from": "email_1", "to": "exit_node", "type": "continue" }
  ]
}

邮件正文来自模板库,而非手写的 html:

  1. 优先复用。 使用 workflows-list-email-templates 列出模板库,并选择合适的模板。滴灌营销活动通常会让每个邮件步骤都引用同一个基础模板(例如带品牌标识的公告模板)。
  2. 仅在没有合适模板时才创建。 使用 designing-email-templates 技能,以设计为先创建新模板:编写 design,省略 html(服务端会根据设计生成 html)。
  3. 引用模板。 如上所示,将模板的 UUID 填入每个步骤的 config.template_uuid。保存时会将模板的主题、文本、html 和设计快照到步骤中。
  4. 分别定制每个步骤。 使用 workflows-patch-action-email 设计操作进行修改——每个步骤的快照都会独立编辑,因此,使用一个基础模板的 5 个步骤可以分别拥有各自的内容。

快照是单向的:之后编辑模板库中的模板,不会更改已引用它的步骤;修改步骤也不会影响模板库中的模板。如果用户以为编辑模板会同步到工作流,请纠正这一点——步骤保留的是各自的副本,每个步骤都需要通过 workflows-patch-action-email 单独更新。

务必在模板中为设计提供真实的纯文本 text:屏蔽富内容的客户端只会显示 text,因此像“占位符”这样的填充文字会直接进入真实收件箱。

必须告知用户的硬性限制,不要试图绕过

  • 不支持行为定向。 无法将“在过去 M 天内至少执行 N 次事件 X”表达为触发器或批次/计划受众。如果用户提出此类需求,应拒绝并说明原因;不要用有问题的过滤器近似实现。(后端会直接拒绝批次受众中的行为群组。)
  • 批次受众针对的是_一个人是谁_,而不是他们做过什么。 仅支持个人属性和/或静态/基于属性的群组。批次受众中的事件/操作过滤器会被静默丢弃,因此必须拒绝此类配置。
  • 优先重新评估受众。 对于批次,内联的个人属性条件或动态(基于过滤器的)群组会在用户符合条件时重新评估;静态群组是固定列表,仅在明确指定一组人时使用。

评论

支持 Markdown