技术选型的后悔与庆幸——做对了什么做错了什么
> 回首过去六年的技术决策之路,有庆幸到后背发凉的选择——如果当时选了另一个技术栈,今天可能已经挂了。也有后悔到拍大腿的选择——浪费了大量的时间和精力。把这些记录下来,给正在做技术选型的你一个参考。
选对了的——让我们庆幸至今的决策
庆幸一:选择了TypeScript而非JavaScript
2025年公司刚成立时,用纯JavaScript还是TypeScript是一个争议很大的技术决策。反对TypeScript的理由是:"学习成本高、写起来麻烦、影响开发速度"。但我们选择了TypeScript,而且从一开始就强制strict模式。
六年后的今天回顾,这是我们在技术层面做出的最正确的决策。原因有三:第一,TypeScript的类型系统在项目超过五万行代码后变得至关重要——它避免了大量由于"不确定参数类型"导致的运行时Bug。第二,类型即文档——新人看一个TypeScript函数的类型签名就能理解它的输入输出,而不需要追查调用链。第三,重构时的安全感——在有完善类型覆盖的项目中重构核心模块,编译器会告诉你所有受影响的地方,而不是发布后等着客户报告Bug。
庆幸二:选择了PostgreSQL而非MySQL
这个选择在当时也曾有过争议。MySQL在国内的企业软件生态中更主流,运维人员更熟悉。但PostgreSQL在几个关键能力上让我们受益巨大:JSONB让我们可以灵活存储半结构化数据而不失查询能力;全文搜索让我们不需要引入独立的搜索引擎;而最关键是事务和并发控制——在AI Agent并发执行多个工具调用时,PostgreSQL的事务隔离级别保证了数据一致性。
庆幸三:早期就引入了向量数据库
2025年我们决定引入pgvector做向量存储时,很多同行问"你们一个小B2B软件公司搞什么向量数据库?"当时的主要驱动力是:我们发现客户经常用自然语言问问题,传统的关键词搜索无法匹配"帮我看看最近利润下降的原因"这种语义查询。向量数据库让AI能理解客户的语言意图,而不只是匹配关键词。今天回头来看,这个决策让我们在AI能力上领先了竞品至少一年。
庆幸四:坚持模块化架构,拒绝单体应用
团队小的时候,单体应用的诱惑非常大——开发快、部署简单、一个仓库搞定一切。但我们从一开始就采用了"模块化单体"的方式——所有代码在一个仓库里,但模块之间的依赖关系和职责边界非常清晰。当项目增长到三十多个Agent、二十多个服务时,模块化的架构让我们可以独立开发、独立测试每个模块——而不会陷入"动一个地方全崩"的泥潭。
选错了的——让我们付出代价的决策
后悔一:过早引入了微服务
2025年我们听了太多"微服务是未来"的布道,在没有足够多的服务和团队规模的情况下,把系统拆成了十几个微服务。结果是灾难性的——服务间的网络延迟和故障排查复杂度大幅增加,一个人需要同时维护多个服务的代码和部署。半年后我们不得不做了"逆微服务"的合并——把大部分服务重新合并回一个"模块化单体",只留下两三个独立性强、访问量大的服务。
教训:微服务解决的是"组织规模化"的问题(团队大了怎么分工),不是"技术先进性"的问题。团队不到二十人时,微服务带来的收益远小于它带来的复杂度。
后悔二:追了太多的"新框架"
2022到2025年间,我们经历过几次"框架迁徙"——从一个前端框架换到另一个,从一个状态管理库换到另一个,从一个ORM换到另一个。每一次迁徙都"理由充分"——新框架性能更好、社区更活跃、写法更优雅。但每一次迁徙都耗费了数周甚至数月的时间——这些时间本可以用来做产品迭代、修复Bug、服务客户。
教训:选择一个"足够好"的技术栈然后深耕,远比不断追逐"最好"的技术栈重要。技术的边际改进带来的收益,远小于产品功能改进和客户体验优化带来的收益。创业公司的技术选择应该遵循"Boring Technology"原则——选择那些经过验证的、稳定的、有大量社区支持的技术,而非最新的、最酷的、但未经大规模验证的技术。
后悔三:自研了不该自研的组件
2021到2025年间,由于"程序员的自尊心",我们花大量时间自研了一些基础设施组件——比如自定义的权限管理系统、自研的任务队列、自研的日志收集系统。但每一个自研的系统,在后来的维护中都变成了沉重的负担——Bug要自己修、性能要自己优化、文档要自己写、新人要自己培训。
教训:除非你的核心竞争力和差异化就建立在这个组件的独特能力上,否则——使用成熟的第三方解决方案或开源项目。把宝贵的工程资源投入在你的产品核心功能上。
技术选型的核心原则——我们后来总结的
基于上述后悔和庆幸,我们后来总结了技术选型的六个核心原则:
原则一:"无聊的技术"优于"性感的技术"。选择那些已经被大量项目验证过的、社区成熟度高的技术,而非新出的、宣称"革命性"的技术。稳定性、文档质量、社区支持和人才可获得性——这些才是技术选型的核心考量因素。
原则二:当前需求优于未来需求。不要为了"三年后可能会需要"而引入复杂的技术架构。解决今天的需求,用最简的架构。当未来需求真的到来时,再扩展架构——到时候你对需求的了解远比今天清晰。提前为不确定的未来做过度设计,是资源的最大浪费。
原则三:团队能力匹配优于技术指标领先。最好的技术栈不是性能最强的那一个,而是你的团队最熟悉、最高效的那一个。一个用顺手的"普通技术"产出的结果,远高于一个用不熟的"顶尖技术"。
原则四:标准化优于定制化。如果一个功能可以用标准化的方式实现(标准库、标准协议、标准接口),就不要写自定义实现。标准化意味着:别人能看懂、新团队成员能快速上手、出了问题有社区支持、未来迁移有路径。
原则五:可替换性优于完美契合。选择技术组件时,要考虑"未来如果要替换这个组件,难度有多大?"好的技术选型是每个组件都有明确的接口边界、替换时不牵一发而动全身。
原则六:延迟决策。当一个技术决策可以推迟而不影响当前开发进度时——推迟它。因为时间会带来更多信息——两周后你可能对需求有更深的理解,市场的技术趋势可能更清晰,团队对候选方案的实际体验也更充分。
AI相关技术选型的特殊考量
作为一家AI Native的公司,我们在AI相关技术选型上还有一些额外的经验:
一、大模型选型要"多模型策略",不要"ALL IN一个"。不同的任务适合不同的模型。复杂的推理任务用GPT-4级别的模型,简单的文本生成用轻量级模型。把"模型选择"作为一个可以动态切换的配置项,而非硬编码在系统中。这样当某个模型的API涨价、降质或被禁时,你可以快速切换。
二、提示词工程和管理需要专门的工具和方法。不要把提示词以字符串的形式散落在代码各处。集中管理、版本控制、支持A/B测试、能追踪提示词变更对效果的影响——这些基础设施在AI产品规模化后变得至关重要。
三、关注"模型不可知"的架构设计。不要让你的核心业务逻辑过度绑定在某个特定模型的特性上。模型市场变化极快——今天领先的模型可能半年后被超越。设计一个"模型适配层"来隔离模型差异,保持核心业务逻辑的稳定。
四、重视本地数据处理能力。B2B客户对数据私密性有极高的要求。在技术架构上要支持"客户数据不出境、不上公有云"的处理方案。混合架构——敏感数据的向量化和本地查询 + 非敏感任务的云端模型调用——是B2B AI产品的常见选择。
"少即是多"——创业公司的技术极简主义
回头看这些年的教训,最大的感悟是:创业公司最稀缺的资源不是资金、不是人才——是"注意力和时间"。每一次你决定"尝试一个新框架",就意味着你的团队注意力从"客户需求和产品质量"上被分散了一部分。每多一个技术组件,就多一个潜在的故障点、多一份维护负担、多一项新人培训成本。
"完美的技术栈"是创业公司最大的陷阱之一。它让技术出身的创业者沉迷于"搭建完美的技术地基"——而忽视了"这个房子到底有没有人想住"。
我们的经验是:用最少的、最成熟的组件,构建恰好能满足当前需求和适度未来扩展的产品。当产品验证了PMF(产品市场契合)、用户基础增长、团队规模扩大后——再逐步引入更复杂的技术架构来匹配增长的需求。
技术选型不是"做一次就一劳永逸"的事。它是一个持续的、需要随着产品阶段、团队规模和市场需求不断演化调整的过程。最关键的不是做了"最正确的选择"——而是建立了一个"可以修正错误选择"的架构体系。
技术债务管理——欠下的债迟早要还
如果说技术选型是"选择往哪个方向走",技术债务就是"你在这条路上欠下的债"。在创业公司,"技术债务"常常被包装成"快速迭代的代价"——为了快速上线,跳过了单元测试、跳过了代码审查、快速修补而非系统修复。这个逻辑在短期内成立——但只在一定限度内。
技术债务和金融债务有一个关键的相似之处:利息会累积。你今天为"快速上线"而跳过的每一次代码重构和测试覆盖,都会在未来的每一次功能迭代中向你索要"利息"——修改一个地方影响了五个地方、加一个新功能需要先理解"这段临时代码是怎么工作的"、新人上手时间从一周变成了一个月。
我们管理技术债务的方法:
一、区分"策略性技术债务"和"惰性技术债务"。前者是你有意识做出的权衡——"这个模块的功能需要两周做完美,但客户说等不了,我们先用五天做一个八十分的方案,然后在下个迭代中补到九十五分"。后者是因为"懒得写测试"、"没时间做代码审查"、"以后再重构"而积累的。前者可以接受但要记录和追踪;后者必须零容忍。
二、每一个迭代中固定留出百分之二十的产能用于"还债"。不要让技术债务越积越多。无论多忙,每个迭代中留出五分之一的时间用于偿还之前留下的债务——补测试、做重构、优化性能。这不是"和业务抢资源"——这是在降低未来的业务开发成本。
三、建立"技术债务可视化管理"。技术债务和Bug一样——如果不可见,就会被无限期忽略。在我们的代码仓库中,每一个已知的技术债务都以"技术债务标签"的Issue形式记录,包含它的位置、影响范围和预计修复成本。在每次迭代计划会议中,我们评审这些技术债务Issue——决定哪些立即修复、哪些可以继续推迟、哪些因为业务逻辑变化已经不再需要修复了。
四、当技术债务开始显著影响开发效率时——停下来,先还债。如果团队的开发速度从每周交付五个功能下降到了每周只能交付两个功能——不是因为需求变复杂了,而是因为代码库的混乱程度使得每一次修改都如履薄冰——这就是"技术债务高到必须集中治理"的信号。
技术选型做的再好,也抵不过技术债务的长期侵蚀。代码是人写的——而人写的代码,如果不持续维护就会腐化。接受这个事实,并建立一个系统来应对它——这是技术领导者最重要的职责之一。
*EIOS — 企业AI操作系统。今日之工,明日之基。*
*系列:创业思维,共15篇。第12篇。*