@katelyn_lesse: https://x.com/katelyn_lesse/status/2073902681668931927
摘要
Katelyn Lesse 的一条 Twitter 主题讨论,认为团队应该直面项目中最困难的部分,而不是逐步回避,并以 Stripe v2 账户的故事为例说明。
查看缓存全文
缓存时间: 2026/07/06 14:13
你无法绕开困难的部分
想想你的团队曾做过的最难的项目,或者你认为不可能所以一直回避的那个项目。
有时你还不知道什么会是困难的部分。如果你在构建一个全新的产品或功能,你大概无法预测限制因素会是什么,这没关系——你只需先做出点东西,然后从那里出发。但有时明显存在一个困难的部分。也许之前有人尝试过,已经暴露了困难之处。或者你的第一个版本上线后,一旦有了真实使用量,问题就浮现了。
假设你知道困难的部分,并且你没有直接放弃整件事(不幸的是很多团队会这样做)。面对这个特别困难的部分,你会采取什么方法?从宏观层面看,你有几种选择。其中一种是做安全、渐进式的增量方法。你在努力最小化风险,很多团队选择这条路。但可能有一些潜藏的原因,导致这条路实际上行不通。实际上,你真正在做的是回避那个特别困难的部分。所以你必须问:我们能避开困难的部分还能成功吗?如果答案是肯定的,那当然要避开。但如果答案是否定的,那么增量路径实际上并不安全。你只是在延迟不可避免的失败。
还有另一种选择:正面猛攻那个特别困难的部分,很可能需要你冒一次大而冒险的风险。我最喜欢的解决问题的方法之一是:固定一个变量,评估其余部分。在这种情况下——假设你采取了那个大而冒险的举措,并且它确实奏效了。其余的计划是否足够坚实,使得整个项目很可能成功?如果答案是肯定的,并且你真的想完成这个项目并成功,你就应该冒这个大险。
这听起来非常简单,但要让团队能做到,需要具备一些重要条件。我会深入探讨这些条件,但首先,分享两个我看到这种情况真实上演的故事。
一个故事:Stripe v2 Accounts
在 Stripe 工作时,我参与了 Connect 项目,它让平台能够嵌入支付和金融服务。我们相信,如果一个平台及其底层用户能够解锁 Stripe 产品套件中的网络效应,那将极其强大。想象一下,你有一个用户,你需要向他收取订阅费(他是客户),同时他也想接受付款(他是商家),并且想收款(他是收款人)。我们可以假设这个用户在 Stripe 上有一个余额,因为他接受了一笔他所售商品的卡支付,并且收到了另一 Stripe 商家的转账。他想用那笔余额支付你的订阅费。我们知道这个用户在这些不同的上下文中是同一个人,但我们的抽象层不允许对该用户进行统一表示。我们有 v1/accounts、v1/customers 等,因此如果没有一个重大的新抽象,我们无法真正解锁这一能力。这就是 v2 accounts 背后的动机——一个能够处理多种配置的单一抽象。
在我加入 Stripe 之前,很多个人和团队就已经设想过这一点,并尝试解决它。这是一个雄心勃勃的目标。如果你问“什么让它具有挑战性“,简单的答案是:Stripe 的整个抽象层和业务逻辑都需要学会如何与 v2 account 协作。即使你先咬下一块,比如用 v2 accounts 替换 merchants 或用 v2 accounts 替换 customers,每个方面的表面区域都极其庞大,因为 Stripe 代码库中每一个涉及支付或计费的 API 和业务逻辑都需要修改。而且,只有当你至少替换两个时,你才能获得我们追求的好处。
当我开始与团队合作时,已有的计划是建立新的抽象和数据模型,并与旧的并存,同时进行双向同步。这样,Stripe 的大部分业务逻辑就不需要理解新的抽象,可以继续使用旧的。这可以看作是安全、渐进式的路径,基本规避了解决困难的部分。这条路径潜藏的问题是:同步会很脆弱,而且我们很快就会遇到规模问题。如果有人创建了一个同时配置为商家和客户的 v2 account,我们就需要保持三个底层模型同步,每个模型都包含相同数据的副本(比如姓名和电子邮件)。
团队尝试了很多条路来让这个方案可行,但现实是,所有这些方案都在规避那个潜藏的问题,而这个问题很可能会成为障碍。我们组织了一个小规模的工程师团队进行异地会议,讨论如何处理。我们发现自己不断绕回另一条路:正面攻克这个挑战。我们可以构建一个接口,替换每一个读和写的调用点,最终直接写入我们新的数据模型。我们称之为“封装“。以前有人提出过这个想法,但大家都忽略它作为一个真正的解决方案,因为它估算的工程月数高得离谱(实际上是工程年数)。这一次,我们稍微推演了一下:如果我们假设能够完成封装——整个项目能否成功?答案是肯定的。但这太疯狂了。
很多人会不惜一切代价回避这样的问题,但也有其他人会被最困难的事情吸引。事实证明,我们团队里有几位工程师对这个绝对疯狂挑战感到非常兴奋,我们赋予了他们解决它的权力。我们考虑了几种运行迁移的方式,比如把工作分发给每个拥有调用点的团队,但我们最终决定保持集中化并采用 codemod,因为要协调那么多各有优先级的团队显然是一座难以翻越的大山。在整个过程中,我与团队合作推动前进,尽管封装可能变得过长而导致项目延期,但我们真的相信这是唯一可行的路径。
那是 2020 年初,还没有编码智能体,所以估算确实是多个工程年。尽管经历了一波三折的挑战,团队还是完成了。我相信如果没有封装,v2 accounts 不可能发布。
另一个故事:Claude Managed Agents
在 Anthropic,我的团队最近发布了 Claude Managed Agents(测试版),这是一个用于运行 Agent 的 API 套件。当我们构建第一个版本时,我们并不清楚困难的部分是什么,所以做了在面对全新产品时应该做的事:构建最简单的可行方案。API 启动一个沙盒并在其中加载 Claude Code,Agent 会话的一切都运行在那个容器里。我们在内部使用它,给一小部分客户早期访问权限,并开始收集反馈。
问题很快就出现了。延迟不佳,因为 Claude 甚至开始思考之前,容器必须启动。如果容器挂了,整个会话也随之消亡,这让可靠性变得很差。而且我们也不喜欢 Claude 编写的代码就在 MCP 凭证旁边运行。
有一段时间我们把这些问题当作独立的问题,试图逐一修补。团队在让故障容器恢复健康方面做得更好,并花了大量时间调试卡住的会话——你无法判断是 harness、事件流还是容器失败了。最终我们向自己承认,每一个问题都追溯到同一个选择:所有东西都在一个容器里运行。这就是我们潜藏的问题。修复它意味着将大脑(harness 循环)与手(代码执行的地方)分开,而这需要构建一个真正的分布式系统,这是原始设计刻意避免的显著复杂性。
此时我们已经接近公开测试版,延迟发布以重构架构是一个痛苦的决定。但我们问了自己同样的问题:能否在单一容器架构下进入测试版并仍然成功?我们知道不能。所以我们推迟了发布,进行了全面的重构。当我们重新让早期访问客户使用时,凭证和可靠性问题消失了,首次 token 生成时间也大幅下降。我们将这个系统带到了测试版。
也许我们可以预测到,在规模下的可靠性会成为我们必须解决的困难部分,才能成功。但对于一个全新的产品,通过迭代找到答案,比从一开始就让完美成为好的敌人要好。真正的错误是,在我们发现问题后仍然按原计划进入测试版。
赋能团队去冒大风险
团队回避艰难路径的原因相当理性。艰难路径伴随着巨大且低置信度的估算,团队需要承担巨大的责任和风险才能走下去。而回避困难的路径则有潜藏的问题,这些会在以后显现,并最终可能导致整个项目失败。但那条路径听起来安全,因此非常有诱惑力。所以你选择了安全路径,有时甚至持续数年,即使有一堆人认为它会失败,但仍继续推进。
如果你希望成为一个敢于冒大风险的团队,需要满足两个条件。
首先,你需要有对挑战感到非常兴奋的人。你不需要共识,也绝对不需要每个人都相信它会成功。大多数人会看着困难的部分并认为它不可能,这没关系。你需要那些看到可能是有史以来最有趣挑战的人。把问题交给他们,让他们在如何解决问题上拥有很大的自主权。
其次,作为领导者,你需要愿意承担责任,并保护团队去追求这个目标。如果行不通,那就是你的责任,并且可能带来一系列后果。承担这种风险需要你个人感受到两件事:第一,你真的非常希望这个项目成功;第二,你真的相信这个大冒险是必要的。
界限正在移动——一些困难的事情变得比以前更容易了。如果我在 Stripe 的团队是用 Claude Fable 写代码的,我们可能就不会觉得封装那么令人生畏了。实际上正在发生的是,AI 正在把真正困难的部分留给我们。所以,真正关键的问题并没有改变:你能避开困难的部分还能成功吗?如果答案是否定的,安全路径只是把失败推迟了。如果你真的想成功,就必须冒大风险。
相似文章
@alvinsng: https://x.com/alvinsng/status/2077114275412512868
Alvin Sng 解释了他们的团队为何放弃使用 Stripe、WorkOS 和 Slack 的客户端 SDK,转而通过集中式包装器直接调用其 REST API。他们认为,SDK 会隐藏关键的调试细节,在生产环境中不稳定,并且容易引发反模式,而借助 AI 辅助编码,这些反模式如今可以更轻松地避免。
@nicholaschen__: https://x.com/nicholaschen__/status/2070979090094633439
一个Twitter帖子系列分享了在初创公司工作学到的10条经验教训,强调了深思熟虑的优先级安排、数据驱动的决策和以客户为中心。
@StartupArchive_:Stripe CEO Patrick Collison 分享他寻找产品市场契合度的策略 “我们非常努力地去理解……”
Patrick Collison 分享了 Stripe 实现产品市场契合度的具体策略,包括监控早期用户行为、向创始人发送错误提醒,以及通过嵌入的文本输入框收集未经筛选的反馈。
@rohanpaul_ai:Stripe 正面临一种杰文斯悖论:工程师能在更短时间内开发出更多软件,但待完成的软件项目积压量却似乎在增加…
Stripe 正经历一种杰文斯悖论:AI 让工程师能更快构建软件,但有价值的软件积压工作却持续增长。Will Gaybrick 讨论了 AI 如何改变 Stripe 的产品开发流程。
@FilipPanoski: SaaS 最难的部分:意识到没人想要你构建的东西。然后做出决定:→ 转型 → 坚持 → 放弃
Filip Panoski 分享了他七年构建失败的 SaaS 副项目的历程,强调了决定转型、坚持或放弃项目以最终找到成功的重要性。