作者:Tomoko Tanaka

排版:Alan Wang

如果你能把自己的工作流程清晰地描述下来,就可以将其自动化。以下就是我为支持 GitHub 亚太地区市场团队所做的实践。

在这里插入图片描述

我负责 GitHub 在日本和韩国的市场营销,而活动是其中的核心:面向企业开发者的系列线上研讨会、东京的开发者社区线下聚会、首尔的定向高管闭门交流会。这个市场的开发者现在真正需要什么?哪些主题值得他们花一个小时参加?应该邀请哪些人到场?这些问题,我可以乐此不疲地研究一整天。

但做完这些决策之后,还有另一回事。一旦活动获批,一套固定流程就会启动:

  • 在我们的活动平台上复制一个落地页。

  • 生成一组带 UTM 参数的链接:每个渠道一个,并且严格按照规定的格式生成。

  • 撰写邀请邮件,并向负责发送邮件的团队提交请求。

  • 将活动添加到两个项目看板中。

  • 活动开始前,每天早上下载报名者名单、清理数据,并向利益相关方发布状态更新。

  • 活动结束后:导出参会者名单,按照 CRM 上传所需的格式重新整理,给相应记录添加标签,并撰写活动报告。

这些任务单独来看都不难,但其中任何一个环节都可能出现问题:粘贴了错误的链接、漏掉一天的更新,或者把一个市场活动名称拼错,而这个名称可能会被下游的 15 份报告所依赖。

事情是这样的:我以前是一名工程师。我的第一份职业是在 Linux 服务器上维护数据库,为企业客户提供支持。虽然现在写代码已经有些生疏了,但我依然能看出一条流程正等待着被自动化。这正是我开始使用 GitHub Copilot 的地方,你也可以将这种方式用到自己的工作中。

所以,我没有自己编写代码。我只是把自己的操作手册写下来,交给 GitHub Copilot,然后通过对话不断完善自动化流程。如今,一个过去需要我花上几天手动搭建的活动,只需要创建一个 GitHub Issue 就能自动完成准备工作;系统每天早上会自动筛选报名者,并在活动结束后自动完成后续收尾工作。

本文将介绍这一套流程是如何运作的,以及为什么我认为,只要你的工作涉及多个工具之间的重复性操作,而这些工具又提供某种可编程的入口(API,甚至只是 CLI),你都可以采用同样的方法。

一个活动,就是一个 Issue

这个基础理念并不是我首创的。GitHub 的市场营销团队原本就有为每个项目创建一个 GitHub Issue 的习惯。这样一来,计划、讨论和状态都可以集中在同一个地方。Issue 本来就是我们的工作单元,而我所做的,就是让 Issue 真正开始“干活”。

整个系统依靠三个 GitHub 基础功能:

  • Issue 表单就是申请表。 不再是一个空白文本框,Issue 表单 会提供结构化字段,例如活动标题、日期、地区、市场活动名称和目标受众。我们针对不同类型的活动分别设置表单,例如线上研讨会和线下活动,但它们最终都进入同一套自动化机制。

  • 标签就是开关。event-setup 这样的标签并不只是一个普通标签,而是一个触发器。每个自动化工作流都会先判断:“只有存在这个标签时才运行。”

  • Actions 就是执行引擎。 GitHub Actions 工作流在标签添加后被触发,从 Issue 内容中解析出表单字段,然后开始执行相应任务。

开发者从代码仓库中获得的一切能力,也同样免费赋予了我的营销工作流:历史记录、可见性、审查机制,以及一个可以记录每项决策的 URL。

有一件事让这一切成为可能,而且它其实与活动本身没有什么关系:我们的活动管理平台提供 API。 我们的 CRM 甚至不需要 API,因为它的官方 CLI 已经覆盖了我们所做的全部操作。我也从来没有配置过 API 密钥,因为这个 CLI 会通过浏览器完成登录,并在此基础上处理身份验证。无论是 API 还是 CLI,要求其实都是一样的:提供一个可以通过脚本进行操作的入口。如果你的重复性工作涉及的工具提供 API 或 CLI——无论是活动平台、CRM、表单构建工具还是分析服务——那么本文介绍的模式同样适用于你。

开发者看到这里可能已经提出了一个显而易见的问题:这不是在重复造轮子吗?市场营销自动化平台已经存在,而且一个好的平台可能原本就能开箱即用地解决其中一些问题。但亚太地区与其说是一个市场,不如说是由许多截然不同的市场组成。即使在我的团队内部,工作流程也会随着不同子区域和不同细分市场而变化。同一场线上研讨会,这个月可能面向东京用户使用日语举办,下个月可能就面向首尔用户使用韩语举办;对应的细分人群不同,CRM 中的字段不同,对“优质潜在客户”的定义也不同。让一个现成工具吸收所有这些差异,意味着定制预算、咨询工时,以及等待其他团队产品路线图的时间。而我们基于现有工具自己构建,则意味着一次工作流变更就是一个 Pull Request:我描述自己想要什么,由审核者检查,然后按照开发者修改软件时使用的同一套流程合并到主分支。

活动策划是一场对话

整个流程其实在 Issue 创建之前就已经开始了。我打开 GitHub Copilot,大致告诉它:“我想在 11 月举办一场关于 AI 辅助开发的线上研讨会。”

接下来发生什么,由仓库根目录下的 AGENTS.md 文件决定。它是我们团队的操作手册,以 Markdown 编写,其中规定了市场活动如何命名、财务季度如何对应日期、每个地区使用哪个时区,以及一封好的邀请邮件应该是什么样子。GitHub Copilot 会读取这些内容,然后找到过去类似的活动,按照我们的命名规则提出一个市场活动名称,起草两版邀请邮件,并根据操作手册中的要求向我提出需要确认的问题。

把对话放在整个流程的最前端,本身就是一个设计决策,同时解决了两个问题。如果把所有事情都自动化,就会失去灵活性;当你希望某一次活动稍微有所不同的时候,一个僵化的流程没有地方容纳这种变化。但如果让人手动填写所有内容,又很容易出错。而对话恰好处于两者之间。GitHub Copilot 会遵循模板,因此最终进入 Issue 的数据是正确的,并且格式也是正确的。同时,因为它是一场对话,我可以针对这一次活动调整具体细节,而不需要破坏后续的自动化流程。

刚开始的时候,这段对话是在终端里的 GitHub Copilot CLI 中完成的。对我来说没什么问题,但“打开终端”对于很多我希望加入这套工作流的人来说,仍然是一道门槛。现在,通过 GitHub Copilot app,同样的对话可以直接在普通的桌面窗口中进行。进入门槛从“熟悉 Shell”降低到了“会打字”。

这里我想明确一下两者之间的分工,因为这恰恰是整个过程的核心:**GitHub Copilot 负责起草;我负责决策。**每一个市场活动名称、每一个邮件主题、每一个日期,都需要经过我的确认之后才能继续推进。对话结束时,GitHub Copilot 会按照正确的方式创建 GitHub Issue,并添加相应的标签。也就是从这一刻开始,机器接管工作。

一个标签,一个活动,全部准备就绪

event-setup 标签被添加到 Issue 后,GitHub Actions 工作流就会接手,在几分钟内完成过去需要我花掉大半天时间才能完成的工作:

  • 在活动平台上复制一个过往活动,创建新的落地页

  • 生成完整的一组带 UTM 参数的 URL:每个渠道一个,每次都保持统一格式

  • 将邀请邮件生成 Word 文档,并提交到代码仓库

  • 向负责邮件发送和区域市场跟踪的团队创建请求 Issue

  • 将活动添加到项目看板,并填写相关字段

  • 在 Issue 中发布摘要评论,让下一个打开它的人可以在一个地方看到所有信息

报名者筛选则通过定时任务运行,而不是依靠标签触发。每天早上,一个由 cron 触发的工作流会获取所有正在进行的活动的最新报名者名单,并分享经过清理的名单。对于定向邀请活动,它还会根据我们的标准筛选候补名单中的报名者。例如,这个人是企业客户中的开发者、学生,还是一个非常希望参加我们高管简报会的竞争对手?在获得批准之前,系统就会完成这些筛选。

我最满意的一项设计,是一个叫作 DRY_RUN 的单一开关。它被存储为一个设置(按照 GitHub 的术语,就是仓库变量),每个工作流运行前都会检查它。打开这个开关后,每个工作流都会完整执行流程,但不会触碰任何外部系统:不会创建落地页,不会在其他仓库中创建 Issue,也不会分享任何名单。当一群市场营销人员开始自动化自己的工作时,需要有一种方式进行演练。DRY_RUN 就是这个演练开关,也是它让我始终不害怕进行实验的原因。

活动结束后,一个斜杠命令就够了

活动结束后的工作曾经是最令人头疼的部分:导出参会者名单、重新整理 CRM 上传所需的列、将公司名称与客户账户记录进行匹配,以及撰写报告。现在只需要两个命令。

/lead-upload 会获取参会者名单,将其整理成营销运营团队上传 CRM 所需的准确格式,创建请求 Issue,并关闭相关的跟踪 Issue。/event-report 会获取参会数据和问卷结果,并将报告作为评论发布到活动对应的 Issue 中。这样,关于这场活动的所有信息依然集中在同一个 URL 下。

这些都是 GitHub Copilot agent skills,而这里是我最希望你了解的一点:一个 skill 本质上就是一个 Markdown 文件。每个 skill 都是一个 SKILL.md 文件:它以自然语言写成一套操作流程,告诉 GitHub Copilot 应该做什么、按照什么顺序做,以及需要注意什么。我的这些文件读起来就像我过去一直记在脑子里的操作手册,因为它们本来就是操作手册。

如果你会写操作手册,你就会写 skill。

Skills 同样让整个系统保持了灵活性。亚太地区的不同市场在活动结束后的跟进方式并不完全相同。受众不同、细分市场不同、本地习惯也不同,而一个硬编码的工作流会迫使所有市场采用同一种方式。用 Markdown 编写的操作流程则更加灵活:每个市场都可以根据自己的实际情况调整操作手册,而无需修改底层的执行机制。这正是为什么活动结束后的步骤被放在 GitHub Copilot skills 中,而不是写进固定的工作流。

在一个方面,我们把 skills 当作代码来管理:新的 skill 通过 Pull Request 提交,并在合并之前经过审核;同时,通过 CODEOWNERS 文件将审核请求分配给维护者。这就是带有审批流程的市场营销自动化。而治理机制同样是平台自带的。

内置的防护机制让我敢于进行实验

我自动化了一套涉及客户数据和 API 凭据的工作流程,而且代码仓库对整个团队可见,而我自己几乎没有编写代码。六个月前,我可能会认为这种组合太过冒险。真正改变我想法的是,我意识到在我开始之前,这套平台本身就已经提供了许多防护机制。

有一些防护措施是我自己构建的:DRY_RUN 开关、每个 Pull Request 都会运行的测试套件,以及每次变更都必须经过代码审查。这些都是开发者的标准实践。事实证明,它们保护营销工作的效果,与保护软件的效果一样好。

但真正重要的那些防护机制,则是平台本身提供的:

  • **密钥扫描与推送保护。**对于我这样的用户来说,最可怕的情况就是不小心把 API Token 提交到代码仓库中。GitHub 的推送保护会在密钥进入仓库之前阻止这次推送。而对于 GitHub 自己的 Token,即使真的有一个漏网之鱼,也会被自动撤销。

  • **GitHub Copilot 的数据策略。**报名者名单属于业务数据,而固定脚本会按照固定方式处理这些数据。但真实工作永远不可能完全固定;有时候,我需要对数据进行一次脚本没有预想到的临时分析。由于 GitHub Copilot 的商业版不会保留提示词,也不会使用这些提示词训练模型,因此我可以直接让它完成这一次性的数据分析,而不是像整个行业中很多人私下会做的那样,把业务数据粘贴到浏览器下一个标签页中打开的某个消费者聊天机器人里。模型也是如此:我能够使用哪些模型由组织策略决定,而不是由我个人自行判断。因此,即使是一次临时实验,也会在公司已经设定好的边界内进行。安全的路径,这一次恰好也是最方便的路径。

Skills 还带来了另一个几乎可以算是附带的好处:因为每个操作流程现在都成为一个有明确名称的固定工作单元,我可以根据具体任务匹配合适的模型,从组织批准的模型中进行选择。快速且成本较低的模型可以处理每天的名单清理工作;更强大的模型则可以负责起草营销文案。

当然,我也有一个真实的失败案例,希望你不要重蹈覆辙:有一次,早上的报名者筛选工作流悄悄失败了整整五天,直到有人发现名单已经过期,才意识到出了问题。没有监控的自动化,本质上只是一个带延迟的定时炸弹。为每个定时工作流提供一种能够大声“报警”的方式,这样你就不会错过问题。

从一项任务开始

如果让我以一个正在逐渐摆脱手工工作的人的身份给另一个人一些建议,我会这样做:

先找出你每周最重复的一项工作。然后看看这项工作涉及的工具是否提供 API 或 CLI。你可能会惊讶于它们的数量。

接着构建一个尽可能小的版本:用一个 Issue 表单收集输入,用一个标签表示“开始执行”,再用一个 Action 完成其中一个步骤。或者,也可以直接把你的操作手册写成 SKILL.md,然后让 GitHub Copilot 执行它。使用 dry-run 开关运行它,直到你真正信任这套流程,然后再逐步扩展。

我没有编写代码。我只是把自己原本就知道的事情——这项工作应该如何完成——写了下来,然后让平台完成剩下的事情。无论你的“每日早晨报名者名单”对应的是什么工作,它很可能只需要再有一份写下来的操作手册,就可以开始自己完成自己。

开始使用:

Logo

微软开发者社区,邀请来自微软以及技术社区专家,带来最前沿的技术干货与实践经验。在这里,您将看到深度教程、最佳实践和创新解决方案。

更多推荐