一个项目管理软件的诞生(七):状态机与流程编排,复杂协作如何建模
同一需求详情页上三套进度并存,谁都没错却说不清进展。本文从数据层判断状态机与流程编排的分界,剖析三种履约模型,并给出选型与运行治理的落地建议,助产品经理理清复杂流程的本质。

打开一条需求,同一张详情页上三套进度:对象状态写着“开发中”,流程图显示“联合验收”,任务清单里还有两项没完成。同一个需求,三个说法。谁都没错,但谁也说不清它到底走到哪了。
做内部项目管理平台这几年,我越来越警惕一个听起来很明确的词:流程。产品说一条需求要“走完需求流程”;研发理解的是状态从待开发变成开发中、再变成待测试;测试画出来的是客户端、服务端、测试准备同时开跑的协作图;管理者还指望流程里能挂审批、通知、超时催办和上线确认。每个人说的都是流程,讨论的却不是同一种产品模型。
第六篇讲过,状态机管的是一个业务决定如何合法发生,回答工作项现在处于什么状态、还能执行哪些迁移。可客户端、服务端、美术、测试要同时推进时,一个当前状态装不下全部进展。这里摆着三种选择:继续用总体状态管需求、拆出子工作项、在需求内部跑一组活动节点。三种选择都能画流程图,保存的却是完全不同的业务事实。
真正危险的从来不是选错组件,而是没意识到自己已经换了模型。继续加状态,会把多个活动压成一个越来越难解释的枚举值;把活动都拆成任务,又造出一批只在本次协作里才有意义的工作项;引入流程编排,平台就要开始管理节点实例、分支汇聚、异常恢复和版本迁移。
这篇文章想回答一件事:判断要用状态机还是流程编排,到底看什么。下面先给判断依据,再沿着它推出三种模型,最后落到选型和运行治理。
01 分界不是串并行,是要同时保存几个履约事实
后台有没有流程设计器,图上有没有方框和箭头,都说明不了什么。要看一条实例跑起来以后,系统到底保存什么。
状态机的运行态是一个“当前位置”。需求当前在“待评审”,系统就从待评审出发找合法迁移;执行“评审通过”后,位置挪到“待开发”。同一套生命周期里,一条工作项通常只有一个当前状态。
流程编排保存的不是一个位置,而是一组活动的运行情况。需求分析完成后,客户端设计、服务端设计、测试方案可以同时被激活:客户端正在进行,服务端已经完成,测试准备还在等接口文档。系统要分别记录每个节点的负责人、开始时间、截止时间、输入、结果,以及它为什么被激活、被跳过或退回。

借用流程引擎的说法,状态机像一枚标记在状态之间移动,流程编排允许执行路径在分支处展开、在汇聚处按规则合并。不必记“令牌”这个术语,但要理解背后的数据差异:一个当前状态值,装不下多条活动路径的运行事实。
这里有个容易误判的地方:串行不等于状态机,并行不等于编排。产品、研发、测试依次交接,虽然跨角色,只保存一个当前阶段,状态机照样能用;同一个测试团队要同时执行安全、兼容、性能三组验证,未必跨角色,却可能需要三个独立活动实例。反过来,一条完全串行、但每个环节都有独立负责人、表单、结论、催办和退回记录的评审流,跑的也是编排,它保存的不是一个位置,而是一串各自有结果的环节。
所以分界只有一条:系统是否需要同时保存多个可以被分别操作、查询、等待和恢复的履约事实。 需要,就得到一组节点实例;不需要,一个状态字段就够了。这不是个人对概念的偏好,而是数据层面的判断:同一时刻要并存几件能独立操作的事,就决定了模型的档位。
形式化状态图确实可以有层级状态、并行区域,理论上一张图也能存多条路径。但 Jira、ONES 这类研发管理平台暴露给产品经理的典型工作项模型,就是一个当前业务状态。真要去实现并行状态区,同样要处理多条路径、汇聚、异常和历史,它面对的问题已经接近流程编排。所以这条边界与其当成免责声明,不如当成判断的起点。
02 状态、节点、工作项,是三个粒度不同的履约模型
复杂流程一上来就画图,通常会把状态、节点、任务混在一起。更稳的做法,是先问每个概念到底承担什么责任。
状态是业务对象能稳定停留的阶段,互斥、可查询,会改变下一步允许做的业务动作,比如”开发中””待验收”。节点是一次需要执行的协作活动,要回答谁负责、什么时候完成、提交什么、满足什么条件才能结束,比如”客户端实现””安全评审”。工作项是值得独立管理和追责的工作对象,有自己的负责人、状态机、排期、估算和关系,比如一条客户端研发任务。
同一句“客户端开发”,放三层里含义完全不同:
- 作为状态,它表示需求当前处于客户端开发的阶段;
- 作为节点,它表示本次流程正在执行客户端开发这项活动;
- 作为工作项,它表示一条能进迭代、独立估算、单独追责的研发事项。
三层的区别,说到底就是上一节那条判据的三档:一个稳定阶段、一组本次协作的履约活动、一批能离开当前流程继续独立排期追责的交付。
判断一个东西该做成节点还是独立工作项,我习惯先问自己五个问题:
- 离开当前流程以后,它还是一项有意义的工作吗?
- 需要独立排期、估算或进入迭代吗?
- 有能单独验收的交付物吗?
- 需要单独查询、关联、统计或跨流程复用吗?
- 有自己完整的生命周期,还是只有等待、进行、完成?
大多数成立,它就是独立工作项;只属于这一次协作、但要负责人和结论的,适合做节点;只是对象当前停的阶段,留在状态里。
03 产品入口可以统一,事实层不能合成一张表
到这里会冒出一个很合理的反对意见:用户都说“流程”,为什么非要两套 Workflow?一套设计器、一套权限、一套运行引擎,不是更简单吗?
这个反对意见成立。分别提供状态设计器、节点设计器、两套规则、两套版本、两套监控,管理员会被迫先理解产品架构,才能配置自己的业务。状态和节点之间还要额外同步,两边都允许修改,同一个对象就会出现两套互相打架的进度。
所以产品界面完全可以只开一个“流程管理”入口。简单模式只暴露状态和迁移;用户要为活动配负责人、期限、交付物,或需要并行和汇聚时,再进高级模式。权限、条件表达式、版本发布、运行历史和异常监控,复用同一套平台能力。
但统一入口不等于统一事实。系统只存一个 status_id,就回答不了“客户端已完成、服务端仍在进行、测试为什么还没启动”;反过来只有节点实例、把业务状态全藏进流程图,列表、看板、跨空间检索和管理汇总全都做不顺。我把这件事拆成两层看:

上层可以共享设计器、权限和规则;进入运行态以后,三类事实只能通过明确事件和单向规则连接,不能彼此自由覆盖。要分开的是事实语义,不一定是配置入口、产品界面或者底层执行引擎。这才是产品经理真正要做的决定,比“做一套还是两套工作流”更接近事情的形状。
04 流程编排不是画更多节点,它是一套独立的运行模型
真要让流程编排跑起来,第一件事是把流程定义和流程实例分开。
流程定义是一张可复用模板:有哪些节点、怎么连接、什么条件决定分支、负责人怎么算、完成时提交什么。流程实例是这张模板在某个业务对象上的一次真实运行:实际走了哪条路径、每个节点的执行人、开始和完成时间、提交结果、当前停在哪。只保存流程图、不保存实例,得到的是说明书,不是流程系统。
从产品模型看,至少需要六类对象:

节点实例不是一个“已完成”复选框。它至少要经历等待、已激活、进行中、已完成、已跳过、已取消或异常这些状态。等待表示前置条件没满足;已激活表示它成了某个角色的待办;已完成表示活动真实执行并提交了结果;已跳过表示按条件本次不要求执行。跳过和完成必须分开,否则流程审计会把“没做”解释成“做完”。
拿一条游戏版本需求举例。方案确认后,可以同时激活“客户端实现”“服务端实现”“美术资源制作”“测试方案准备”四个节点,各有负责人、排期和交付物;必要分支全部结束后进入联合验收;需求涉及支付链路,再额外激活安全评审。
这图里的”研发中”仍可以是需求对象的当前状态,但它替代不了四个节点各自的运行数据。反过来,四个节点完成了三个,也不能推成需求完成了 75%,剩下那个可能正是阻断上线的安全评审,四个节点的工作量也不相等。流程编排生产的是活动事实,不是另一个状态字段,也不是一个看起来精确的完成百分比。
05 难的不是画分支,是把”等谁”写成可解释的规则
设计器里画个菱形、拉几条线,谁都会。把它变成确定、可解释的运行规则,才见功夫。
最常见的分支汇聚有三种。并行分支(AND) 同时激活所有后继节点,汇聚时等所有被激活的分支完成,比如客户端、服务端、测试准备全结束才进联合验收。排他分支(XOR) 只选一条满足条件的路径,高风险需求进安全评审、普通需求直接验收,后面的排他汇聚不用同步等待,哪条路径到达就沿哪条走。包容分支(OR) 按条件激活一条或多条路径,汇聚时必须知道这次到底激活了哪些分支,再等它们结束。
Camunda 对三种网关的界定很直白:并行取所有路径、汇聚等所有进入路径;排他只取一条、汇聚不负责同步;包容选所有条件成立的路径、汇聚等本次实际可能到达的路径。产品不一定要用 BPMN 的全部符号,但必须给出同样确定的执行语义。
如果方案只写“支持并行、条件分支”,设计其实还没完成。至少要能回答:
- 分支条件在流程启动时算,还是节点到达时算?
- 条件依赖的字段后来又变了,已经激活的路径要重新算吗?
- 节点被跳过、取消或异常终止,汇聚算它完成还是失败?
- 某个节点被退回,同批次已经完成的平行节点还保留结果吗?
- 汇聚后已经触发通知或外部动作,再退回时怎么补偿?
“退回上一节点”尤其容易被低估。在线性流程里,它只是把指针往回挪;在并行流程里,系统根本没有唯一的“上一节点”。一次退回可能只要重开客户端分支,也可能要撤销整个研发批次、同时保留服务端已交付的结果。所以编排模型里的退回不该是随便拖一条反向连线,要定义退回指定节点、重开本分支、撤销当前批次、终止流程、发起补偿,每个动作都有明确的作用范围和历史。这也是状态机和编排差得最明显的地方:状态迁移只关心对象从哪一阶段进到哪一阶段,节点操作还要处理同一批次其他活动是否继续有效。
06 “一个工作项支持多个流程”,是三件完全不同的事
前几篇反复说“一个工作项类型可以配多套流程”“一个对象可以挂多个流程”。进入设计以后,这两句话必须拆开,否则配置模型和运行模型会混成一团。
第一种发生在实例创建前,是模板选择问题。系统预置多套流程定义,创建实例时按条件选一套。支付业务线用带安全评审的流程,内容业务线用带版权检查的流程,同一类“需求”在不同业务线走不同的模板。Jira、ONES 在不同空间和项目、不同工作项类型上应用不同工作流,解决的是配置复用与差异化;飞书项目按业务线指定流程模板和默认参与角色,也是这一类。这类模型要回答:选择条件什么时候算?实例创建后业务线变了,允许重新选吗?新旧流程的状态和节点怎么映射?如果平台只在页面初始化时临时判断,却不把选中的流程定义和版本固化到实例上,以后说不清它为什么走了这条路径。
第二种发生在运行时,是对象与流程实例的关联问题。一条需求除了主研发流程,还可能分别发起安全评审、设计评审、发布审批。每个流程有独立的负责人、版本、运行状态和结论,主需求只是挂上它们,通过明确门禁消费结果,比如安全评审不过就不能进待发布。这才是真正的一对多:对象主键、流程实例主键、节点实例主键完全分开,一个对象可以拥有多次历史主流程,某一时刻通常至多一个有效主流程实例。平台还要定义流程用途、哪个是主流程、独立流程能不能重复发起、取消需求时关联流程怎么处理。
第三种发生在流程内部,是嵌套问题。节点跑一半再启动子流程,或创建子工作项。飞书项目的节点子流程形成独立实例、与父流程同步角色和状态;TAPD 并行工作流也能在节点下关联子需求,靠子需求自己的工作流形成嵌套。需要独立排期、估算、进团队看板的工作,创建子工作项更合适;只是可复用的标准过程,启动子流程更自然。
业务对象一对多关联流程实例,流程实例一对多包含节点实例,某个节点实例还可以启动子流程或创建子工作项;主流程、专项流程和历史流程靠“流程用途”和运行状态区分,而不是把对象和主流程写成永久一对一。
一句话:多套流程可选是配置问题,一个对象挂多个流程是实例关系问题,节点启动子流程是嵌套问题。它们要不同的数据结构、权限和变更策略,不能都塞进一个“支持多工作流”的开关。
07 三套进度并存没错,错的是没定义谁说了算
回到开头的那个详情页。三套进度并存本身不一定错,错误的是没定义每层保存什么、又谁有权改。

状态定义没有负责人,不等于业务进到这个阶段就没人负责。平台可以把“当前责任人”做成对象字段,也可以根据状态、角色或活动节点算出来。但别因为某个产品展示了“状态负责人”,就把状态当成一项能完成的活。
状态和节点的连接,有三种可成立的方案。第一种独立状态模型,状态机保存对象主事实,节点完成后只能请求一次合法迁移:联合验收节点通过后请求“验收通过”,状态机检查权限、必填信息和前置条件,再把需求从待验收迁到待发布,Jira、ONES 更接近这条线。第二种派生状态模型,节点运行态保存主事实,对象状态只是列表、看板和统计用的投影:TAPD 并行工作流按进行中最右节点所属状态算出当前状态,飞书节点流也允许配置状态计算规则。这时候不能再把状态当成可随意修改的入口,否则手改一次状态,就绕开了一组还没完成的活动。第三种混合模型,需求总生命周期由状态机管,某些阶段内部再跑活动节点:需求进“研发中”后同时启动客户端、服务端、测试准备,必要节点完成后流程提交“进入验收”的迁移请求。混合模型不错误,但每个映射都要指定唯一事实来源和触发方向。
不管选哪种,有四条规则要守住:一个业务事实只有一个权威来源,不让状态和节点循环触发;派生状态只能由明确规则算,不能一边自动计算、一边允许任意手工覆盖;任务型工作项的结果只是节点完成条件之一,不自动等于节点结论;取消、退回、重开和重复事件,必须定义对另外两层的影响范围和幂等处理。
界面同样要分层。对象状态适合做列表和详情页摘要,活动节点适合展示当前责任、并行关系和等待原因,任务型工作项进个人待办、迭代和团队看板。把三层都做成顶部“进度条”,用户只会看到三个互相打架的百分比。度量也不该混:对象从创建到完成的时间是交付周期,节点从激活到完成可以拆成等待时间和处理时间,任务完成量反映执行负荷。拿已完成任务数除以任务总数去推需求完成百分比,既忽略任务规模,也忽略关键路径,只会制造精确的错觉。
08 选哪条路,是把复杂度寄存在哪个模型里
状态机、子工作项网络、流程编排不是初级到高级的三级能力,是在为不同复杂度付费。
Jira 的官方工作流用 Status 和 Transition 管理单个工作项生命周期,ONES 围绕工作项类型配状态、步骤、验证和后置动作,这两家面对并行研发更自然的建模,是拆子工作项和关联工作项,再靠关系和自动化汇总。TAPD 允许需求类别绑串行或并行模式工作流,并行模式下状态做阶段泳道、节点表达要执行的活动,当前状态按进行中最右节点算,把对象状态和节点运行态放进同一套工作流语境。飞书项目把状态流和节点流分成两类能力,状态流服务缺陷、任务这类对象生命周期,节点流承载负责人、排期、交付物、并行节点、状态计算、子工作项和节点子流程,更接近跨角色过程的编排。
比产品不必比谁的流程图漂亮,要比复杂度由什么承载:运行时只有一个当前状态,还是能同时存在多个活动节点?并行活动是独立工作项,还是流程实例内部的节点?节点有没有负责人、输入、结果、期限和独立历史?分支、汇聚、跳过、退回有没有确定的执行语义?对象状态、节点进度、子工作项结果由谁保持一致?
回到具体方案,通常有三条可落地路线。单工作项加状态机,适合责任基本串行、当前阶段最重要、分支少的过程,比如普通缺陷处理,理解成本低、查询配置简单,但多个活动要同时追时,状态会开始硬扛它装不下的信息。主工作项加子工作项网络,适合并行活动要独立估算、排期、进迭代、追责的研发场景,复用统一的工作项、权限、看板和报表,代价是对象数量上涨,父子汇总、依赖、退回和跨对象自动化都要额外治理。业务对象加流程编排,适合稳定、跨角色、有条件分支、会签、交付物审查和强审计的过程,协作全景直观、能准确记录等待和汇聚,代价是设计器、运行引擎、实例监控、异常处理和版本治理整体变复杂。
选的时候别先问”要不要做流程编排”,要看业务是不是长期出现这些信号:同一对象上会同时存在多个要履约的活动;不同条件会激活不同路径;必须等指定分支汇聚;活动要独立保存负责人、期限、交付物和审计;管理者要能说清卡在哪个等待节点。只偶尔出现,状态机加子工作项往往够用。流程编排不是免费的灵活性,每多一种网关、退回方式和实例迁移能力,管理员就多一套必须理解的运行规则。
09 上线以后,真正要管的是运行治理
流程在白板上跑通,只完成了一半。企业级平台还得处理发布前验证、版本、权限、异常和可观测性。这些不该是散落在后台的六个功能,而是一整条治理链路:流程定义从草稿进入发布版本,实例绑定版本开始运行;监控发现的等待、异常和重开问题,再回到下一版草稿。任何修改绕开这条链路直接覆盖运行实例,历史就失去解释能力。
上线前先自检能不能跑。看有没有够不到的节点,排他分支在所有条件都不成立时有没有默认路径,并行或包容汇聚会不会永久等待,节点负责人能不能解析,必填表单对执行人可不可见,循环路径有没有明确退出条件。这些检查不能保证业务一定对,但能挡住一批确定会造成卡死、越权或无人处理的配置。更进一步,允许管理员用测试数据模拟路径,看哪些节点被激活、哪些角色被算出来、最终状态怎么生成,再决定是否发布。
版本上管住“保存配置”不等于直接覆盖。新增一条并行分支、删一个汇聚节点、改条件计算时机,都可能让运行中的实例失去可达路径。稳妥的做法是让流程定义拥有草稿、已发布、已停用三种状态,实例启动时固化所用版本,新版本默认只影响新实例;展示名和帮助文案算非运行语义,节点、连线、条件和汇聚的改动必须发新版本。确实要升级旧实例时,先给影响清单:多少实例仍在跑、各停在哪、旧节点怎么映射到新版本、已完成的结果保不保留、哪些实例迁不动。确认后逐个迁移,记录前后版本、映射规则、执行人和失败结果。
权限上,节点权限决定谁能执行完成、退回或跳过,工作项权限决定谁能查看对象、编辑字段。两者冲突时,节点权限不该自动获得整个工作项的编辑权;迁移表单只开放本次活动要填的字段,敏感信息仍按对象和字段权限保护。
异常要成为一等运行状态。节点负责人离职、条件计算失败、外部系统超时、子工作项被删除,都可能让流程卡住。管理端要能解释卡点原因,允许有权限的人重试、转交、跳过、终止或做补偿,每一次管理动作都写进历史。只处理得了成功路径的流程引擎,最后一定会依赖人工改数据。
可观测性最直接:管理者既要看到“需求整体在研发中”,也要能说清“服务端已完成、客户端逾期、测试准备还在等接口文档”。平台要分别记录对象周期、节点等待时间、节点处理时间、分支重开次数和异常终止原因,再把它们呈现出来,而不是把全部过程压成一个完成百分比。这几件事,决定了流程编排是一项可运营的企业能力,还是一张漂亮但脆弱的流程图。
10 一句话收束
把第六篇和第七篇放在一起看,记住三层事实就够了:工作项状态保存业务对象当前在哪个稳定阶段,流程节点保存当前有哪些协作活动在跑,子工作项保存哪些工作已经变成独立责任对象。
落到界面,可以做成一个统一详情页:状态摘要读状态机,流程面板读活动实例,子工作项区域读独立工作项,三者只通过有方向、有条件、可重试的规则相连。每一条同步都要指定触发方向、执行条件、幂等规则和失败处理。所谓幂等,讲直白点,就是同一个事件重复到达也只能生效一次。不能既让节点激活自动改状态、又让状态变化反过头再激活同一节点,也不能因为管理员手动改了个字段,就让流程实例悄悄跳过一段历史。
产品经理真正要设计的不是“状态和节点怎么同步”,而是每个业务事实由谁负责。对象完不完成由状态机管,流程只能请求合法迁移;对象状态由节点派生,状态只能消费计算结果,不能成为第二个修改入口;多条关联流程都能影响对象,要明确是全部通过、任一通过,还是只有主流程说了算。
状态机和流程编排不是初级和高级的关系,也不是二选一。前者让业务对象的阶段保持清楚,后者让一组协作活动能被执行和观察。成熟平台的套路不新鲜:体验上尽量统一,数据上把对象状态、协作活动和独立工作分开,再用少量、明确、单向的规则把它们连起来。
下一篇,继续沿着交付链路往后走:迭代、版本和发布为什么不是三个叫法不同的容器,它们又如何把工作项真正连到研发交付。
作者:AI产品零度,公众号:AI产品零度
本文由 @AI产品零度 原创发布于人人都是产品经理。未经作者许可,禁止转载
题图来自作者提供
- 目前还没评论,等你发挥!

起点课堂会员权益




