思维 · 心智模型 · 工程原则
YAGNI
You Aren't Gonna Need It——「你不会需要它」。一句工程里最省钱的纪律:功能等到真正需要时再加,别为「以后可能用到」提前写。它听起来像偷懒,其实是在拒绝一笔几乎注定亏本的投资。
篇幅 5 节 · 约 7 分钟
受众 全员 · 不写代码也能看懂
主线 团队工程纪律 + 脱敏实例
做产品时最诱人的念头是:「这个地方我先做灵活一点,以后要扩展就方便了。」于是多写了一个配置项、多抽了一层框架、多留了三个「万一要用」的接口。半年后回头看,那些为未来准备的东西——大部分从没被用到,剩下小部分等真要用时,需求早已长成了另一副样子。
一句话记住 · YAGNI 不是「不做设计」,也不是「能跑就行」。它只反对一件事:为想象中的、还没发生的需求,提前付出真金白银的代码。下面讲清楚它的成本逻辑、怎么判断该不该做、以及它不适用的边界。
YAGNI 出自极限编程(XP),Kent Beck、Ron Jeffries 这批人在 90 年代末总结出来的一条纪律。原话很直白:
YAGNI · 原则
永远在你真正需要一个功能的时候才去实现它,
而不是在你预见到你将会需要它的时候。
Always implement things when you actually need them,
never when you just foresee that you need them.
关键词是「真正需要」对上「预见到会需要」。前者是现在手上就有的、确定的用例;后者是脑子里对未来的猜测。YAGNI 的主张是:只为前者写代码,把后者留到它真的变成前者的那一天。
它和另外两条老原则是一伙的——KISS(保持简单)、「先让它能跑,再让它对,最后才谈快」。三条都指向同一个方向:抵抗「顺手多做一点」的冲动。
「多做一点又没坏处」——错。为想象中的未来写的每一行代码,都在同时付三笔账:
- 猜错的概率很高。未来的需求大概率不来,就算来,长得也和你当初想的不一样。你是在为一个还没被验证的假设下注。
- 现在就先亏了时间。那份「灵活性」占用的是此刻本该用来打磨真实需求的精力,机会成本立即发生,收益却遥遥无期。
- 它会一直收租。多出来的代码不是写完就完事——它要被读、被测、被维护,还会挡住以后的重构:每次别人改到附近,都得先绕开你这段「以后可能有用」的东西。
脱敏实例 · 不提前套框架 · 给 AI 编排选型时,最省事的念头是先套一个大框架(比如 LangChain / LangGraph)「以后好扩展」。团队评估后没有这么做——编排逻辑用普通代码自己写,只在确实需要「看清 AI 在做什么」时引入 Langfuse。理由正是 YAGNI:框架承诺的「未来灵活性」是想象的,眼下的用例普通代码就够,框架反而白白增加一层依赖和认知负担。对照站内《LangChain · LangGraph · Langfuse》一篇。
这就是 YAGNI 的算术:省下的想象中的收益 < 立即付出的成本 + 长期的维护租金。绝大多数「顺手做的灵活性」,一算账都是亏的。
要不要现在就做,问自己一句话就够了:「此刻有没有一个真实、具体、正在痛的用例,非它不可?」有——做。没有,只是「想象中会有人要」——先别做。
现在就做
已经有真实用户/真实数据在等;不做就有具体的东西跑不起来;痛点当下可见、可描述。
vs
先别做
「以后可能」「万一哪天」「先留个口子」;说不出具体是谁、在什么场景下要用;为一个假设的规模提前搭重基建。
几个一听就该踩刹车的信号词:
- 「以后可能会要……」——以后再说,以后真要了它一分钟也跑不掉。
- 「先做通用一点,省得将来改。」——将来的「改」往往比你现在的「通用」更便宜,因为那时你才真正知道要什么。
- 「顺手把这几个 case 也覆盖了。」——只覆盖眼前真实发生的 case,没发生的不是需求,是猜想。
反过来用最好用 · YAGNI 天然是删减器。做方案时先按最小可用去想,再逐条问「这一块,现在有真实用例吗?」没有的一律砍掉——这也是团队做需求对齐时的默认动作:先把不需要的删掉,剩下的才值得认真做。
YAGNI 最容易被念歪成「别想那么多,能跑就行」。这是危险的误读。它砍的是应对想象中未来的投机,绝不砍应对已知复杂度的必要投入。两者的区别是这篇最该记住的一句:
YAGNI 砍掉
投机未知:为「说不定会来」的需求提前写的功能、通用层、配置口子。
≠
YAGNI 不碰
应对已知:现在就确定会发生、且事后补代价极高的东西。
下面这些属于「已知复杂度」,不在 YAGNI 的射程内,该现在做对就现在做对:
| 不适用区 | 为什么不能等「以后需要」 |
| 安全 · 正确性 | 鉴权、金额服务端校验、失败即拒(fail-closed)——这些当下就必须对,不是「功能」,是底线。等出事再补就是事故。 |
| 数据 schema | 有历史数据包袱,改一次要迁移、要兜底,代价远高于写代码。值得提前想清楚。 |
| 对外契约 | 公开 API、给别人依赖的接口边界——一旦有人用上就很难改,边界要先设计。 |
| 可回滚 · 可监控 | 「为出错做准备」不是投机,是已知一定会出错。上线就要能回滚、能观测。 |
一句话分辨 · 问自己:这是在应对一个已经确定的复杂(安全、贵的迁移、对外承诺),还是在投机一个还没发生的未来?前者该做,YAGNI 不拦;后者就是 YAGNI 要你现在放下的。
YAGNI 不是一条要额外记的新规矩——团队 CLAUDE.md 里好几条纪律,本质都是它换了个说法:
- 「有现成体系不要写 ad-hoc。」搜索、分析、跨项目能力,先找有没有现成的 Skill / 命令 / agent,有就用,禁止重写逻辑。自己造一个「更贴合」的轮子,往往是在解决一个还不存在的问题。
- 「先问这个判断有没有确定性答案。」能用几行代码判定的事,就别塞给大模型去「灵活处理」——那层灵活性多半用不上,还更贵、更不可控。
- 不为想象中的规模提前搬家。有人问「上 AWS 是不是更专业」,团队跑了完整评估,结论是对现有规模每一项都更差——现在的组合够用,为假想的「规模化」提前搬到重基建,就是典型的 YAGNI 违背。
- 新旗舰不投机切换。新模型一发布就想换?团队的做法是先摆到生产在用的模型旁边算账,没有真实收益就不换。「可能更好」不是换的理由。
怎么用起来 · 下次你写下或听到「先做灵活一点 / 以后可能会要 / 顺手也覆盖了」时,停一秒问那句判断线:现在有没有真实、正在痛的用例?没有,就把它记进 backlog,然后删掉——等它真的变成需求,再花那一分钟也不迟。
「以后可能用得上」是工程里最贵的一句话。
为想象中的未来写的代码,几乎都是白写——需要时再建,永远来得及。