Dev

精简技术栈:为什么我们宁选”无趣”的专用工具,也不用庞大的框架

几乎每个项目启动会上,都会有那么一刻,有人提议用"那个大框架"——有自己的技术大会、有认证课程、有"企业版"套餐,还有一页声称无所不能的幻灯片。而几乎每一次,选了它,就是这个项目第一个悄无声息的错误。

交付了十多年的企业级软件之后,我们 Simplico 形成了一个鲜明的倾向:我们会挑那个能解决眼前问题的、最小、最无趣、最专用的工具。不是最强大的,也不是最流行的,而是两年后我们要去维护的"面积"最小的那个。

这不是为了极简而极简。这是我们在另一条路上真正走过之后,得出的立场。

"无趣"到底是什么意思

我们说无趣,不是指老旧或过时,而是指可预测。无趣的工具大体就做它名字所说的事,以你能想明白的方式出错,不会在凌晨两点给你惊喜。PostgreSQL 很无趣。一张纸就能讲清楚的消息队列很无趣。一个只做一件事、300 行的 FastAPI 服务也很无趣。

无趣的工具有几个共同点。其一,它的故障模式有完备的文档,因为在你之前,已经有成千上万个团队撞过同样的墙。其二,它的抽象足够浅,必要时你能直接读源码看懂。最关键的是,你在运维它的过程中积累的知识可以迁移——Postgres 的索引,无论是支撑 ERP 还是支撑向量检索,行为都一样。

而"令人兴奋"的工具,这三点全都反过来。它的故障模式很新鲜(恭喜,你是第一个提交这个问题的人);它的抽象很深,调试就成了一层层剥开你自己没写过的代码;而你学到的本领无法迁移——你不再用这个工具的那天,它就蒸发了。

框架解决的是"平均"问题,而你的问题并不平均

一个大框架,本质上是在赌:你的问题,长得和它作者设想的问题一样。当真的一样时,框架就像魔法——只需一个配置文件,你就拿到了认证、后台管理、ORM、数据库迁移,以及其他几十样东西。

问题在于,客户的真实业务几乎从不落在这个赌注的正中央,而往往落在边缘。而正是在这些边缘地带,框架当初给你的每一份便利,都会变成你如今不得不对抗的约束。那些应急的"逃生口"很难用,它认定的"正确做法"不再对得上你的做法。于是你把宝贵的创新预算,花在了如何说服框架"允许"你去做客户花钱请你做的那件事上。

我们见过不少团队,与框架在后台任务上的"成见"较劲、与它对请求生命周期的假设搏斗,耗掉的时间比自己把那个无趣的东西写出来还多。框架没有替你省下工作,它只是把工作推迟了,再加上利息向你收回来。

这正是我们这一立场的核心。专用工具对你的问题所做的假设更少,于是这些假设出错的可能也就更小。

我们究竟在哪里划线

这套理念诚实的一面,是承认大工具有时确实更胜一筹——因为有些场合它就是更好。下面是我们实际的判断方式。

多数时候用 FastAPI 而非 Django,但并非总是如此。 我们的工作大多是精简的小服务:AI 中间件、集成层、内部 API。对这些来说,FastAPI 小巧的表面积恰到好处。我们的 soc-integrator 中间件——把 Wazuh 接到 DFIR-IRIS、再到 SOAR 平台、再到告警通知的那个枢纽部件——之所以是一个职责明确的 FastAPI 服务,正是因为它只干一件事,并且必须在事件应急的压力下依然容易理解。但当一个项目真正需要 Django 擅长的东西时,我们也乐意拿起它:开箱即用的后台、成熟的 ORM 迁移、有真实用户和会话、以内容为主的应用。错误不在于使用 Django,而在于条件反射地用了它,然后一半的功能都没碰过。

中小型工厂,用 ERPNext 而非 SAP。 当制造业客户需要 ERP 时,会议室里的本能反应往往是报出最大那家厂商的名字。但对中小型工厂而言,重量级的企业套件,多半只是为他们永远用不上的能力,堆出一笔许可费和对顾问的依赖。一套他们能自行托管、自行定制、真正拥有的开源 ERP,通常每一泰铢换来的可用软件都更多。从总拥有成本来看——实施、托管、培训、第二年的维护——在这个规模上,几乎总是更轻的那个选项占优。

用 pgvector 而非专用向量数据库。 RAG(检索增强生成)系统有个时髦的答案:搭一个专门的向量库。但对我们构建的大多数系统来说,那意味着又多一套要运维、要做安全、要备份、要保持同步的基础设施——而这个问题,我们本来就在跑的那个数据库就能处理。把向量嵌入和其他数据一起存进 Postgres,再在同一个引擎里把语义检索和字面检索结合起来,需要你去理解的系统就从两个变成了一个。只有当规模真正提出要求时,我们才会动用专用向量库——而这远比那些鼓吹所暗示的要少得多。

用开源安全工具而非商业 SIEM。 在 Wazuh 和 OpenSearch 之上搭建 SOC 技术栈,而不用动辄六位数(美元)的商业 SIEM,这不是预算上的妥协,而是同一条原则:工具要能让我们审查、能做版本管理、能按客户真实的检测需求去塑造,并且不让一个按 GB 计费的许可表,替我们做出架构上的决定。

请留意这里的规律。问题从来不是"哪个工具最强",而是"哪个是能力与这个问题相称、并且我们能完全拥有的、最小的工具"。

表面积带来的复利式代价

你引入的每一个工具,都是一笔要背负到系统寿命终结的负债。它需要打补丁,它会有 CVE(漏洞),它对下一位工程师有学习曲线,它有一条迟早会崩的升级路径,它还有一套迟早会跟需求撞车的"成见"。

精简的技术栈不只是更好搭,更是养活它的成本要低得多。到了第三年,由四个被充分理解的组件构成的项目依然康健,而背着十四个组件的项目,则沦为一笔没人愿意接手的维护重税。我们为那个第三年而设计,因为对我们的客户而言,第三年正是软件要么证明自己物有所值、要么悄悄变成人人都怕去碰的那个东西的分水岭。

这里头还有用人的一面。一套由广为人知的工具组成的精简技术栈,意味着下一位工程师——无论是我们的还是客户的——几天就能上手,而不是几个月。晦涩的框架制造出对少数懂它的特定人员的晦涩依赖。无趣的工具,则让团队的"巴士因子"保持健康。

我们什么时候不这么做

这套理念也有它的失败模式,如果我们假装它不存在,那就是在向你兜售东西了。

走过了头,"精简"就成了重复造轮子。如果我们每一次都自己写认证、自己写 ORM、自己写迁移系统、自己写后台,那我们不过是在一行一行地造一个更差劲的框架,并且照样付出了我们声称要避开的那笔表面积代价,只是悄悄一个人付罢了。框架存在的全部意义恰恰在于:有些问题确实是"平均"问题,对它们而言,那个被共享、经过实战检验的方案,才是精简的选择。

所以规则不是"永远用小工具",而是"让工具匹配问题,并对哪些问题真正属于标准问题保持诚实"。登录系统是标准问题,那就用经过验证的现成方案。而客户那台老旧机器控制器与现代 ERP 之间的定制集成,则不是标准问题——没有哪个框架会把这个答案递到你手上,假装有,只会在你和工作之间又加上一层。

真正的功夫,在于分清这两者;也在于一旦那个曾让某个工具显得合理的前提不再成立,就有把它删掉的果断。

结语

无趣的专用工具,不是我们勉强容忍的约束,而是我们刻意选择的竞争优势。它们造出的系统,我们想得明白、交付得更快、移交得更干净,并且能以低成本养活很多年。

下次启动会上有人提议用那个大框架时,该问的不是"它能做这个吗"——几乎什么都能做几乎任何事。该问的是"为了跟它共处未来三年,我们要付出什么代价"。而答案比你以为的更常是:比那个无趣的工具所要的,还要多。

这就是我们一再下的赌注。而到目前为止,第三年一直在证明我们押对了。