不是所有优化都该马上做:finish gate 如何防止无限打磨
问题:一个永远收不了尾的计划
我最近在搭一套计划执行系统——简单说,就是把项目拆成任务队列,按优先级逐步推进。听起来很常规,但跑起来之后我发现了一个系统性的问题:队列里有任务执行了三轮还在"优化中",整个计划始终无法收尾。
这不是某个人的拖延,而是一个结构性陷阱。当你完成一个任务时,总有一些"可以更好"的方向冒出来——性能可以再提 20%、代码可以再精简几十行、测试可以再补几个边界 case。每一个建议单独看都合理,但它们合在一起的效果是:任务永远无法被标记为"完成"。
更危险的是,这种无限打磨会阻塞后续任务。计划队列是串行的,前面的任务不关,后面的排不上队。一个本该两小时搞定的模块,因为反复优化拖了三天,后面五个任务全在等着。
根因:缺少"完成"的定义
我复盘了那些卡住的任务,发现一个共性:它们都没有明确的完成标准。
任务描述往往是这样的:
- "优化数据处理模块"
- "完善错误处理"
- "提升接口响应速度"
这些描述只说了方向,没说做到什么程度算完。执行者(不管是人还是 AI)在面对一个模糊目标时,自然倾向于"做到更好"——因为"更好"没有上限,所以优化没有终点。
这不是执行力的问题,是定义的问题。你没有在计划阶段回答"什么是完成",执行阶段就只能凭感觉判断。而凭感觉的结果,几乎一定是"还能再改改"。
设计:finish gate——强制定义完成条件
我给这个系统加了一层机制,叫 finish gate。
核心思路很简单:每个任务在进入执行队列之前,必须定义一组可量化的完成条件。 当任务满足这些条件时,系统判定它已完成,不再接受新的优化请求。
举个例子,一个任务"优化数据处理模块",加上 finish gate 之后变成:
任务:优化数据处理模块
finish gate:
- P99 延迟 < 200ms
- 测试覆盖率 > 80%
- 错误处理覆盖所有已知异常类型
- 代码审查通过
现在"完成"有了客观标准。P99 延迟到了 180ms?达标了,关掉。测试覆盖率 82%?达标了,不再加 case。你当然可以继续优化,但那些优化不属于当前任务——它们应该进入下一个迭代周期。
失败案例:过早关闭的代价
finish gate 刚上线时,我踩了一个坑。
有个任务是"编写用户认证模块的文档"。我定义的 finish gate 是:
finish gate:
- 覆盖所有公开接口
- 包含至少 2 个使用示例
任务执行后很快达标,系统自动关闭了它。但两天后,有个新同事跑来说文档里缺少错误码对照表,他调 API 时完全不知道返回码是什么意思。
问题出在哪?finish gate 定义得太窄了。 "覆盖所有公开接口"只保证了接口文档的存在,没保证文档的实用程度。我把"必须完成"的条件(错误码表)漏掉了,却把"可以延后"的条件(更多示例)当作了门槛。
这让我意识到一个关键区分:finish gate 里的条件,必须是"不做就不算完成"的硬性要求,而不是"做了更好"的优化建议。 混淆两者,要么导致过早关闭(漏掉必要条件),要么导致无限打磨(把优化建议也塞进 gate)。
迭代:finish gate + deferred list
吸取教训后,我引入了组合方案:finish gate + deferred list。
每个任务现在有两个部分:
- finish gate:硬性完成条件,必须全部满足才能关闭任务
- deferred list:优化建议,记录但不阻塞,留给下一个迭代周期
还是用户认证文档的例子:
任务:编写用户认证模块文档
finish gate:
- 覆盖所有公开接口
- 包含错误码对照表
- 包含至少 2 个使用示例
deferred list:
- 补充 OAuth 流程的详细步骤
- 添加多语言示例
- 制作 API 调用速查卡片
deferred list 里的内容不是"不做",而是"现在不做"。它们会被自动收集起来,作为下一个迭代周期的输入。这样既保证了当前任务的及时收尾,又不丢失任何优化想法。
这个组合方案还带来了一个意外的收益:它让计划的节奏感变好了。 以前是"一个任务磨到完美再进下一个",现在是"每个任务做到够用就推进,定期回头批量优化"。后者显然更健康——你先跑通一轮,再根据实际反馈决定优化方向,而不是在真空里打磨。
在计划脚本中落地
我把这个机制写进了计划脚本的规则里。每个任务模板现在必须包含 finish_gate 字段,否则计划校验不通过。常见的 gate 规则包括:
- 测试覆盖率阈值:比如
coverage > 80%,用 CI 数据自动判定 - 文档完整度:比如
所有公开函数有 docstring,可以脚本扫描 - 代码审查通过:比如
至少 1 人 approve,接入 review 系统 - 性能基准:比如
P99 < target,跑 benchmark 自动校验
关键原则:gate 条件必须可机器判定或可人工快速确认。 如果一个条件需要"讨论"才能判断是否满足,那它大概率是一个模糊目标,需要拆成更具体的可量化指标。
下次我会怎么做
回头看这段经历,如果我从头开始设计这个系统,我会这么做:
- 第一天就要求每个任务带 finish gate,而不是等问题暴露了再补。缺 gate 的任务不进队列,这应该是零容忍的规则。
- gate 条件在计划评审时就确认,而不是执行时临时想。计划评审的核心问题就是"你怎么知道它做完了"——答不上来,说明任务定义不够清晰。
- deferred list 从一开始就设。不要幻想一轮迭代能把所有事做到完美,承认"够用就行"比假装"这次一定做全"更务实。
- 定期回顾 deferred list,而不是让它变成永远不看的垃圾箱。我的做法是每个迭代周期开始时,先扫一遍 deferred list,挑出 ROI 最高的条目升级为新任务的 gate 条件。
- 对"优化型"任务特别警惕。如果一个任务的关键动词是"优化""完善""提升",几乎一定需要 finish gate,否则它就是无限打磨的温床。
不是所有优化都该马上做。把"什么算完成"提前定义清楚,把"可以更好但不必现在"的东西放进 deferred list——你的计划才能跑起来,而不是原地打转。