编者按:技术债务经常被讨论,但几乎从未被量化。Michael Sun 认为,将其视为一个模糊的比喻是它从未得到优先处理的原因——并提供了具体的框架来量化它,就像量化金融债务一样。
这个比喻正在阻碍你
Ward Cunningham 在 1992 年创造了”技术债务”一词,向业务利益相关者解释为什么快速交付会产生未来的成本。这是一个有用的沟通工具。但在过去的三十年中的某个时候,这个比喻变成了拐杖。开发者挥挥手,说”技术债务”,然后期望房间里的人能理解紧迫性。但房间里的人不明白,因为这个比喻缺乏精确性。
当 CFO 说”我们有债务”时,他们可以告诉你本金、利率、还款计划以及违约的后果。当技术负责人说”我们有技术债务”时,他们通常无法告诉你任何等量的衡量标准。他们可以指出感觉糟糕的代码、看似脆弱的系统以及缓慢的流程——但他们无法对影响或修复成本给出具体数字。
这就是为什么技术债务很少得到优先处理。不是业务利益相关者不关心,而是”我们有很多技术债务”不是可操作的信息。”这个债务每周花费我们 15 个工程小时,修复需要 3 周的专注工作”才是可操作的。区别在于衡量。
技术债务实际是什么(以及不是什么)
在衡量技术债务之前,你需要一个清晰的定义。不是让开发者感到沮丧的一切都是技术债务。一个有用的框架区分了三类:
故意债务:有意识地通过推迟质量来更快地交付。”我们知道这个缓存层应该使用 Redis,但我们使用内存缓存来满足发布日期。我们将在发布后迁移。”这是 Cunningham 比喻的原始含义——一个有计划偿还的已知捷径。
意外债务:在当时合理但随着需求演变而成为问题的设计决策。当你有 3 个端点时,你的单体架构是正确的架构。现在你有 200 个端点,单一的部署管道需要 45 分钟。没有人做出糟糕的决定——情况变了。
代码腐化:因忽视而导致的退化。两年没有更新的依赖项。被临时禁用且从未重新启用的测试。描述一个不再存在的系统的文档。这是无人追踪的债务所产生的利息。
什么不是技术债务:你不喜欢的代码、你不会选择的模式、不是你偏好的技术。”我们应该用 Rust 重写这个”不是债务声明——而是一种偏好。技术债务有可衡量的成本,而审美上的分歧则没有。
衡量本金:你所欠的
技术债务的本金是将系统带到理想状态所需的预估工作量。衡量它需要将债务分解为具体、可估算的项目。
债务登记册
创建一个活文档——电子表格、Notion 数据库、专门的 Jira 看板——来记录每一项已知的技术债务。每个条目应包括:
- 描述:债务的具体内容。不是”认证模块中的混乱代码”,而是”认证服务没有会话管理和用户验证的分离,导致所有测试都需要完整的数据库设置。”
- 位置:哪些文件、服务或系统受到影响。
- 预估修复工作量:修复所需的人日数。这不需要精确——T恤尺码(S/M/L/XL)比没有估计要好。
- 类别:故意、意外或腐化。
- 识别日期:何时首次认识到这项债务。
- 负责人:谁负责跟踪并最终解决此项问题。
记录债务的行为本身就有价值。维护债务登记册的团队能做出更好的优先级决策,因为他们能看到全局,而不是仅仅响应本周感觉最痛苦的问题。
量化工作量
对于估算,我建议基于团队容量采用一个简单的三点量表:
- 小:1-3人日。可以在单个冲刺中与功能开发一起修复。
- 中:1-2人周。需要专门分配,但不是一个完整的项目。
- 大:1+人月。需要项目级别的规划,可能需要一个专门的团队或冲刺。
将你的债务登记册中的这些估计值相加,你就得到了以工程时间表示的粗略本金金额。拥有40人周累积债务的团队与拥有4人周债务的团队有着截然不同的战略图景。
衡量利息:它给你的成本
技术债务的利息是不修复它的持续成本。这是大多数团队在衡量方面失败的地方——他们跟踪债务但不跟踪其持有成本。利息以几种可衡量的方式体现:
速度税
你的团队因现有技术债务而行动速度慢了多少?测量这一点的最实际方法是跟踪每个冲刺或周期中,有多少时间花在了可直接归因于技术债务的工作上:临时解决方案、调试脆弱系统、复杂性导致的新成员入职摩擦、基础设施差导致的部署延迟。
如果你的团队在每个冲刺中 consistently 花费 20% 的时间来处理已知债务引起的问题,那就是你的利率。一个 5 人团队损失 20% 的能力,就相当于永久性地失去了一名完整工程师的产出——直到债务得到解决。
事件关联分析
跟踪哪些生产事件是由已知技术债务引起或加剧的。如果你的值班轮换每月产生 10 个事件,其中 4 个可追溯到已记录的债务项,你就有了衡量债务运营影响的具体指标。将事件数量乘以平均解决时间,你就得到了每月损失的小时数。
交付时间影响
衡量交付一个典型功能需要多长时间,以及其中有多少时间花在了绕过债务上。如果因为部署管道脆弱且测试套件不可靠,部署一个简单的 API 端点需要 3 天而不是半天,这个差异就是你基础设施债务的利息支出。
债务比率:一个重要的指标
将本金和利息合并成一个领导层可以理解的债务比率:
技术债务比率 = 每周利息成本 / 团队总能力
如果你的团队每周有 200 人时的能力,并花费 30 人时处理债务相关工作,你的债务比率就是 15%。这个单一数字比任何定性描述更能传达紧迫性。
根据我的经验,债务比率低于 10% 的团队可以机会性地管理债务——在遇到问题时修复项目。比率在 10-25% 之间的团队需要刻意分配——在每个冲刺中留出一部分时间用于减少债务。比率高于 25% 的团队处于危机状态——债务增长速度快于他们解决的速度,除非他们将减少债务作为主要关注点,否则功能交付速度将继续下降。
优先偿还
并非所有债务都值得修复。就像金融债务可以战略性地有用一样,技术债务有时也值得承担。问题不在于”我们应该修复这个”,而在于”修复这个与构建新东西相比,回报是什么?”
利息与本金框架
对于每个债务项,计算每周利息成本与修复工作的比率:
优先级评分 = 每周利息小时数 / 修复人天数
一个每周花费5小时、需要3人天修复的技术债务项,其优先级评分为1.67。另一个每周花费2小时但需要20人天修复的项,评分为0.1。第一个项目在不到一周的时间内就能收回投资。第二个则需要数月时间。相应地进行优先级排序。
这个框架还能识别出不应修复的技术债务。如果一个混乱的模块每周给团队带来15分钟的工作量,而重写它需要2周,那么回收期将超过2年。除非你有其他修复它的理由——安全需求、扩展需求——否则保留这笔债务是理性的。
分配模型
一旦你对技术债务进行了优先级排序,就需要一个可持续的分配模型。我所见过的最有效的方法是固定比例分配:
- 健康的团队(债务比率低于10%):分配10%的冲刺容量用于债务减少。在相关领域工作时,可以顺便修复这些项目。
- 紧张的团队(债务比率10-25%):分配20%的冲刺容量。每个冲刺应有一名工程师专门从事债务工作。
- 危急的团队(债务比率高于25%):分配30-50%的容量,直到比率降至20%以下。这需要高管的支持,这就是为什么数据很重要。
向利益相关者推销
这种财务框架之所以有效,是因为业务利益相关者已经理解债务的概念。当你说”我们的技术债务比率是22%,这意味着我们每周都在为一个完整工程师的工作量支付利息,而三个最高优先级的项目可以在8人天内修复,每周能回收12小时”时,你使用的是高管们能理解的语言。
与此相比”我们有很多技术债务,需要时间来修复”。前者能获得预算批准,后者只会得到礼貌的点头,没有实际行动。
关键要点
- 维护债务登记册,记录每项已知技术债务的具体描述、位置、工作量估算和负责人。模糊的意识不是管理。
- 衡量你的利率——即每周因现有债务导致的工程时间损失,包括因变通方案、事件和减速所损失的时间。
- 计算你的债务比率(每周利息/总容量),并据此确定适当的分配策略:健康团队10%,紧张团队20%,危急团队30-50%。
- 按投资回报率优先偿还,而不是按严重程度或烦人程度。首先修复每周利息成本与修复工作量比率最高的项目。
- 以财务术语向利益相关者呈现债务。数字能获得预算,比喻只能获得同情的点头。
