那次要做的事情,表面上很简单:把一段文案送进一套视频流程,先形成普通稿,再接到文字成片,最后导出一个可以验收的文件。真正开始拆任务以后,我发现最需要处理的不是“能不能一键完成”,而是每一步到底由谁负责、在哪一步需要人工决定、出了问题能不能从中间继续。
这个区别很重要。因为流程里有一段会产生实际用量和成本的生成动作,不能由后台线程或子线程替用户触发。与此同时,普通稿转换和导出又是已经存在、可以复用的收尾能力。它们如果被一股脑塞进一个不可暂停的大脚本,看起来更自动,实际上会把付费决策、文件生成和结果验收搅在一起。
先把“一键完成”拆开
我一开始也会本能地把需求理解成一条直线:输入文案,调用几个步骤,等成片出来。可一条直线并不等于一个好流程。输入文案、生成视频、转换普通稿、导出文件,这4件事的风险并不相同,不能因为它们在页面上连续出现,就假设它们应该由同一个入口无条件执行。
这次的明确要求是把文案、AI文字成片、普通稿转换和导出串成标准入口,但同时不能让后台线程代为触发有成本的AI成片。于是我先把流程分成两段:前段负责准备和人工触发,后段负责生成之后的整理、转换与导出。前段的边界是“准备好,可以开始”;后段的边界是“已有结果,可以继续验收”。
一个标准入口不应该替用户做出用户必须承担后果的决定。
如果不处理这个边界,最直接的后果是后台任务可能在用户没有看到状态、没有确认内容、甚至没有准备好用量的情况下触发生成。即使最后得到一个视频,也不能说流程是可靠的,因为这个结果建立在未经授权的动作上。更糟的是,一旦生成失败,责任会变得模糊:是文案没准备好,还是自动化越过了不该越过的门?
复用能力,不重新发明流程
拆开之后,第二个问题是怎样把各段接起来。需求里已经有建稿、转换和导出能力,最容易犯的错误却是为了做一个“完整入口”,再写一套新的建稿机制和一套新的导出机制。这样做会让代码看起来更集中,但也会让同一个动作出现两种行为。
我选择薄编排,是因为现有能力已经分别解决了各自的问题。新的入口只需要负责传递输入、标记阶段、保存输出位置和决定下一步是否可以继续。它不需要重新解释普通稿怎么生成,也不需要重新发明导出格式。把已有动作串起来,能够继承原来的校验和错误处理,减少一条新路径带来的差异。
这里的“薄”不是少做验证,而是少做重复工作。编排层可以检查上一阶段有没有产物、当前状态是否允许进入下一阶段、输出是否可读;但它不应该复制每个子能力内部已经做过的业务判断。这样发生问题时,我能更快定位:是入口没有正确传参,还是被调用的能力本身没有通过验收。
复用既有能力的价值,不只是省代码,更是让同一个动作继续拥有同一套行为和边界。
如果不这样处理,后续每次修复都可能出现分叉。原来的普通稿转换修了一个问题,新入口却没有同步;原来的导出支持断点,新入口却把文件重新覆盖。表面上是“多了一条方便入口”,实际上是多了一条需要长期维护的规则。
付费动作必须停在门外
整个流程中最需要单独标记的,是AI文字成片。它不是普通的格式转换,也不是把一个已有文件换个名字。它会产生实际成本,因此不能把它和无成本的前后整理混成一个无人看管的后台任务。
我的判断是,自动化可以把准备工作做到人工触发点之前,也可以在生成已经发生之后继续做可恢复的收尾,但不能替用户跨过那个触发点。原因并不复杂:是否生成,不只是技术上的下一步,也是用户对内容、时机和用量的决定。程序能知道“现在有一段文案”,却不能替用户判断“现在应该花这次成本”。
这也是一种责任边界:系统负责把按钮前的条件准备清楚,把按钮后的结果接住;人负责确认是否按下那个会产生后果的按钮。边界写清以后,后台线程可以做检查、保存状态和等待,而不是偷偷替用户执行付费操作。
错误捷径是把所有阶段包成一个“从文案到成片”的长脚本,认为只要默认不报错,就等于体验更好。这个捷径的问题在于,它把“能自动做”误当成“应该自动做”。一旦用户想修改文案、暂缓生成或更换输入,整条流程就只能从头重跑,已经完成的准备工作也难以复用。
每一段都要留下回滚点
可恢复不是一句口号,而是每个阶段都能说清输入、输出和停止位置。准备阶段的输入是文案,输出是结构清楚的普通稿或待生成内容;人工触发阶段的输入是已经确认的稿件,输出是用户明确启动后的生成任务;收尾阶段的输入是已有成片或中间结果,输出是转换后的普通稿、导出文件和可读的状态。
这样安排以后,任何一步失败,都不会自动推断前面的东西全部失效。普通稿转换失败,可以保留原始文案,修正后重新转换;导出失败,可以重新处理已有结果,不需要再次触发生成;用户暂时不做付费生成,也可以把准备好的内容留在门前,下一次从人工触发点继续。
一个流程成熟的标志,不是它能顺利跑通一次,而是中途停下以后还能知道从哪里继续。
这里最容易忽略的是状态。只保存“完成”或“失败”两个词不够,因为它们无法说明完成的是什么。更可靠的记录应该能回答:当前稿件是哪一版,哪个阶段已经通过,哪个阶段尚未开始,输出文件是否存在并且可以读取。状态越接近真实动作,恢复时越少依赖人的记忆。
如果不保留这些信息,导出失败后就可能出现两种坏结果:要么为了保险重新触发一次有成本的生成,要么凭感觉拿一个不确定的文件继续交付。前者增加不必要的用量,后者把未验收的结果当成完成。可恢复设计的意义,正是把这两种风险分开挡住。
验收要分别看结构和文件
生成之后的普通稿转换和零前台导出,属于可以复用的收尾阶段,但“调用成功”不等于“结果可交付”。我会把验收分成两层:先看普通稿的结构,再看导出文件本身。前者确认内容有没有按预期转换,段落、顺序和基本信息是否还在;后者确认文件是否真的生成、位置是否正确、能不能被打开或继续使用。
这两层不能互相替代。普通稿结构正确,不能证明导出文件完整;文件存在,也不能证明里面装的是当前这版稿件。尤其在流程允许暂停和重试时,旧文件残留会制造一种很像成功的假象。文件名或时间并不能独立证明它来自这次操作,仍需要结合当前阶段的状态核对。
我选择分层验收,是因为每一层失败后的处理方式不同。结构不对,应该回到转换阶段检查输入;文件打不开,应该回到导出阶段检查产物;如果状态与文件互相矛盾,就先暂停交付,而不是继续往下推。这样做可能比“一次检查全部通过”慢一点,却能把问题定位在更小的范围内。
表面上我是在验收一个视频文件,其实我是在确认一条责任链没有断:谁提供了输入,哪一步产生了结果,谁确认了付费动作,最后交付的文件又是否对应那次结果。只有这条链能被复述,后续的人才不需要重新猜测。
把方法变成一条可复用规则
这次形成的方法,可以概括为4个动作。先划分成本边界,明确哪些动作可以后台自动做,哪些动作必须停下来等人工决定。再复用已有正门,把新的入口做成传递状态的薄编排,不复制建稿、转换和导出的内部逻辑。然后为每段保留输入、输出和停止位置,让任何阶段都能单独重试。最后做分层验收,把内容结构、文件产物和前台状态分别确认。
这4个动作可以迁移到很多自动化流程里。凡是涉及购买、发送、发布、删除或消耗额度的步骤,都不应该因为前后有自动化能力,就被默认为后台可以代办。凡是已经有稳定能力的步骤,也不应该为了追求一个看起来完整的入口而重新实现。凡是可能失败或等待的步骤,都应该留下足够的信息,让下一次能从最近的安全位置继续。
这件事让我重新意识到,真正难的不是把动作串起来,而是知道哪一个动作不能被“顺手”串过去。自动化的边界如果只靠口头提醒,下一次就可能被更短的脚本覆盖;如果边界写进状态和阶段,系统才会在结构上提醒执行者停在哪里。
好的自动化不是替人消灭所有停顿,而是把必须由人决定的停顿保留下来,把其余工作做成可验证、可恢复的连续流程。
下次我会怎么做
下次再设计类似入口,我会先画出阶段,而不是先写“一键完成”。我会把每个阶段的输入、输出、成本和负责人写在一起,先找出必须人工确认的门,再决定哪些动作可以放到门前或门后。只要某一步会产生实际用量或不可逆后果,就默认它需要人工触发,直到有明确授权和验收依据。
接着我会优先寻找已有能力,确认它们分别怎样接收输入、怎样报告状态、怎样处理失败。新的编排只负责连接,不替已有能力改规则。对于每个输出,我会留下可以独立检查的标志:稿件能不能读,结构是否完整,文件是否存在并可打开,当前状态是否与文件一致。
最后,我会做一次故障演练:在生成前暂停一次,在生成后转换失败一次,在导出后重新打开一次。只要其中任何一步需要凭记忆猜测下一步,就说明责任边界还没有写清。我想交付的不是一条看起来全自动的长链,而是一条知道何时停、停下后还能继续的工作路径。