Presentation: Move Fast, Don’t Break Trust: Shipping Constantly with Humans and Beyond

TL;DR · AI 摘要
Move Fast, Don’t Break Trust: Shipping Constantly with Humans and Beyond - InfoQ InfoQ Homepage Presentations Move Fast,...
核心要点
- 主题聚焦:Presentation: Move Fast, Don’t Break Trust: Ship
- 来源:InfoQ,建议结合原文判断细节。
- AI 分析暂不可用,本条为保底评分与摘要。
快速前进,不破坏信任:与人类及更远的未来持续交付 - InfoQ
InfoQ 首页 演讲 快速前进,不破坏信任:与人类及更远的未来持续交付
架构与设计
扩展 OpenTelemetry:管理收集器、配置和成本(11月19日网络研讨会)
快速前进,不破坏信任:与人类及更远的未来持续交付
点赞
新下拉阅读列表
- 阅读列表
查看演讲
- 垂直
- 水平
- 全屏
速度:
- 1x
- 1.25x
- 1.5x
- 2x
50:39
概述
Suhail Patel 讨论了 Monzo 如何构建其软件工程组织和技术栈,以实现每天数百次的安全交付。他分享了有关有偏见的微服务抽象、基于租户的预发布环境、静态分析检查、持续性能分析的见解,展示了强大的内部平台如何使工程师和大语言模型(LLMs)在不牺牲可靠性的情况下快速迭代。
个人简介
Suhail Patel 是 Monzo 的高级工程师,专注于构建核心平台。他的工作涉及构建和维护 Monzo 的基础设施,该基础设施包含数千个微服务,并利用 Kubernetes、Cassandra 和 Etcd。他专注于调查异常行为,并确保服务在不断变化的云环境中可靠运行。
关于会议
软件正在改变世界。QCon 伦敦通过促进开发者社区中的知识和创新传播,赋能软件开发。作为以实践为导向的会议,QCon 专为技术团队负责人、架构师、工程总监和项目经理设计,这些人员在团队中影响创新。
INFOQ 活动
- 2026年10月29日,东部时间下午1点 从 Token 到 Feature:为 AI 辅助工程构建成本归属架构 演讲者:Martin Reynolds - Harness 字段首席技术官,Barani Mohandoss - Trimble 云治理、FinOps 与 E-工具总监
- 2026年11月19日,东部时间中午12点 扩展 OpenTelemetry:管理收集器、配置和成本 演讲者:David Iparraguirre - Datadog 高级产品市场经理,Jessica Yang - Datadog 产品经理
演讲稿
Suhail Patel:这将是一场关于我们在 Monzo 如何塑造软件工程组织、如何从技术角度思考、如何构建技术栈以实现与人类及更远的未来(包括自主代理和大语言模型等)持续交付的演讲。我与许多组织交流时发现,他们的开发和部署环境及流程往往如下所示。如果你能够创办自己的组织并完全采用 AI 原生方式,或许可以绕过所有这些步骤。对于我们这些身处受监管行业或存在较长时间的组织的人来说,我在多个小组讨论和演讲中看到其他组织的工程团队已经接受这是他们流程的一部分。在开始任何新项目之前,你必须进行某种形式的评估。然后在任何代码被构思或编写之前,必须完成大量步骤。
在你意识到之前,发布任何东西可能需要几天、几周甚至几个月的时间。其中大部分时间都花在了实现阶段。构建系统确实需要时间。无论你前期做了多少规划,将代码输入编辑器都需要时间。这需要人力,需要测试。现在,这个等式已经完全改变了。如果有人对此持不同看法,我认为他们可能需要看看一些关于如何快速生成代码的演讲。是的,你可能需要花费几美分、几百美元来生成这些代码。代码可以非常快速地生成。许多人忽视了这一关键能力:你可以在并行处理中快速迭代多个变体。过去需要几天、几周甚至几个月才能完成的迭代,通常你只来得及进行一两次。现在你可以对特定实现进行10次、20次迭代,找到最佳方案。这可以在几分钟或几小时内完成。
适应快速变化的节奏
互联网上有很多关于如何衡量开发者生产力并客观评估的内容。有各种各样的开发者体验调查。你可以使用DORA框架。你可以投入大量遥测数据,并以数据驱动的方式确定投资方向。最终,这种证明是投资于后台技术以自动化一些繁琐流程价值的最好例证。当你的工程师使用并依赖这些工具,并能从中获得巨大好处时,这将是组织的最佳证明,因为其他非技术领域的领导者也会注意到这一点。工程师只有在更换组织并失去原有工具生态系统时,才会意识到自己缺失了什么,反之亦然。我们经常有工程师加入时提到,他们在之前的组织有另一套系统,能够显著加快工作进度。
这是一个非常好的学习机会。当开发者体验存在大量摩擦时,这可能是工程师选择离开公司的原因之一。我们不应对此有任何误解。变化的速度也在显著加快。许多公司正在大力投资AI来增强现有工程师的能力。最终,这背后有一个明确的商业目标:我们希望提高每位工程师的生产力。工程师并不廉价。从财务角度来看,有强烈的动机要提高每位工程师的生产力。作为工程师,我们在这个等式中可能显得过于安于现状。我们并没有在日程中腾出更多时间,反而承担了更多工作。因此,必须承受更大的压力去发布这些变更。这种赋能也应扩展到工程领域之外。像Claude和Cursor这样的工具,为设计师和产品经理等与工程相关的领域提供了直接在主代码库中进行原型设计和修改的能力。
我曾回想起第一次下载 Photoshop 时,以为自己可以成为一名设计师。那真是一个天真的幻觉。或者第一次打开 FrontPage 时,以为自己能为网页设计一些东西,看着那些自动生成的代码。如今,如果产品经理或设计师遇到小 bug 或技术实现问题,比如数据相关的问题,例如“我们当前的业务 KPI 是什么?它们的发展趋势如何?”为什么还要花时间创建工单去询问数据人员或工程师来修复或调查这个问题,而不是直接通过 LLM 来解决?
另一方面,即使是一些拥有数万名工程师、设有专门变更管理、软件测试和软件质量团队的大型公司,也无法完全避免变更速度对可靠性和可用性带来的影响。最近《金融时报》有一篇文章,内容在社交媒体和 Hacker News 等平台上广泛传播。文章将亚马逊的一系列可靠性事故归咎于 AI。亚马逊不得不在其博客上发表反驳文章,因为文章声称高级工程师必须对 AI 辅助的变更进行审批。亚马逊澄清这些变更并非 AI 特有的问题。这清楚地表明了行业对 AI 在软件开发中角色的看法。他们不得不解释并公开反驳,说明情况并非如此。无论这些变更是否由人类或 AI 驱动,各方都有一个共同目标:不想破坏系统。
没有人早上醒来会指示自己的代理去写糟糕的代码,就像人类不会突然某天写出糟糕的代码一样。没有人希望因为系统故障而上新闻。另一方面,我发现公司在发生事故或部署出错后,会采取哪些流程来应对,这一点非常有趣。这正是我们行业规则的来源,比如“我们不在周五部署”。一个非常常见的做法是引入变更审批委员会,尤其是在大型金融机构中。通常由一群看起来相当郁闷的人组成(就像照片中那样),他们来自不同领域,如风险与合规、平台、安全等,拥有权力在必要时阻止或延迟发布。结果就是陷入这种非常郁闷且低效的会议,只为推动每一个小的变更。
实际上,这些论坛变得必要,因为这些变更的范围和性质具有巨大的影响范围,或者需要建立大量信心才能进行的变更。你不能只是靠“感觉”来建立信心。你会达到一个临界点,对某些软件失去更改的信心。然后,工程师们即使要更改一个简单的配置值,也会面临巨大的惯性。这种风险在心理上会呈指数级增长。即使从技术角度,这种风险暴露可能实际上相当低。
背景
我的名字是苏海尔。我是伦敦一家名为Monzo的公司的首席工程师之一。我在平台团队工作,负责领导该团队。我们团队为Monzo提供所有底层基础设施、库和工具,让工程师能够专注于构建银行系统,而无需担心基础设施问题。我大部分清醒时间都在思考开发者体验。如果直言不讳地说,开发者可能会犯哪些错误?他们如何将漏洞部署到生产环境?我该如何避免这种情况?我深知碎片化的体验会导致挫败感,进而引发更多漏洞和事故。Monzo是英国一家面向消费者的零售银行,我们在美国也有少量业务。今年我们还计划扩展到欧洲其他地区。我们目前有1400万用户,个人账户和企业银行业务都在快速增长。
我们没有任何实体分行。所有银行业务功能都通过应用程序实现。您无需担心营业时间,可以在任何方便的时间和地点处理所有银行业务。这意味着我们不能出现系统停机。人们期望我们的系统全天候24小时运行。我仍然会收到一些银行的通知,尤其是很多美国银行。如果在场的有美国金融科技从业者,我很想和你们讨论他们如何计划在几小时内停机以处理夏令时调整。如今客户期望无缝的在线体验,尤其是当无法通过实体银行网点服务时。这意味着我们需要提供可靠且易访问的多样化服务。系统停机和漏洞意味着客户无法访问他们的资金。
微服务的结构
这是一张较旧的图片,但它展示了我们支付基础设施和产品功能所依赖的多个微服务之间的连接调用图。每个点代表我们在平台上构建、运营和编写的微服务。连接它们的线条表示这些服务之间的RPC流程。想象一下,每次我们想要进行更改、添加新服务或构建新系统时,都需要添加新点或新边,这时必须经历复杂的变更治理流程。基本上,我们几乎无法推进任何变更。本次演讲将介绍我们在推动持续加速变更方面的一些关键投入。首先,让我们从微服务的结构开始。这是Monzo向工程师提供的开发者体验契约。自我们起步以来,我们始终坚持的一个核心原则是:统一编写服务的方式。
对于绝大多数微服务,我们采用相同的模板构建并遵循相同的底层抽象。平台和安全团队负责基础设施,并将最佳实践封装到这些库的服务层中。在微服务内部,工程师只需填充顶部部分,在那个薄层封装中插入自己的代码,这部分就是添加业务逻辑的地方。工程师无需重写核心抽象,如HTTP处理器、从Kafka队列消费数据、指标收集或数据序列化。他们可以依赖一套定义明确、类型安全、经过充分测试的库和工具。所有这些共享库层默认提供开箱即用的遥测功能。特别是在微服务架构中,一个关键问题是追踪数据流的"谋杀案"。当服务间存在通信流时,如何确定哪里出错以及数据流发生了什么?为此需要非常完善的遥测系统。我们在库层直接嵌入该能力,使所有服务(无论是处理单个请求还是每秒百万个请求)都能统一具备该能力。
我们非常幸运。平台技术栈相对现代。2016年我们早期投入创新资源,押注Go语言、Kubernetes和微服务作为技术基础。此后我们有条不紊地扩展技术栈并引入新技术集成。我们的核心原则是不直接暴露平台组件给工程师。相反,我们在其上构建专为Monzo定制的库抽象层,提供易于使用、经过充分测试和维护的封装,特别是内置了遥测能力。这些基础技术选择带来了巨大回报。我们已构建并扩展到超过3000个生产环境微服务,每天推送数百次变更。我们只有几百名工程师,却能每天推送数百次变更。工程师无需理解Kubernetes或YAML语法或复杂Kafka库逻辑,即可编写服务并完成交付。
他们需要的是可靠且持久的关键原语和抽象。我们维护所有服务的单一代码仓库,其中包含一个引导生成器,为每个服务输出一致的文件夹结构。如前所述,绝大多数微服务使用Go语言编写。这降低了工程师的认知负担。无论你是资深员工还是新加入者,都能掌握导航服务的肌肉记忆。所有服务在整体结构上基本一致,遵循相同的文件夹结构。你期望数据库逻辑位于dao文件夹,队列消费者逻辑位于consumer文件夹,RPC层位于handler文件夹。你知道这些逻辑模块的具体位置。我们整个技术栈在所有服务中保持完全一致。
自早期以来,我们始终将保持快速的迭代周期作为关键目标。当你生成一个微服务时,首先要做的事情是用proto文件填写一个API规范。我们在这些proto文件基础上编写了生成器,将代码编译为后台的RPC实现,这些实现会与我们的服务HTTP库集成,并提供开箱即用的遥测功能。该定义可以包含验证逻辑,这些验证逻辑会自动生成,超越protobuf标准数据类型提供的能力。这会在后台生成大量Golang代码,使工程师无需手动编写HTTP请求,也无需将数据反序列化或转换为Go类型。测试和模拟变得更容易,因为你可以使用静态类型进行工作。我们使用proto文件生成的不只是RPC代码,例如,我们还会生成队列处理逻辑。队列处理遵循相同的基本原理。
你正在通过某种传输总线传递数据,因此可以将这种传输方式定义为一种类型。我们将自动生成所有通信原语。工程师可以指定事件负载定义以及与RPC类似的验证条件。同样,我们有一个proto插件会生成Kafka消费者和生产者逻辑,并调用我们的库。工程师可以使用这些强类型对象和自动生成的函数签名,无需关注底层传输机制。作为基础设施团队和安全团队,我们获得的一个重大优势是:如果你有任何错误修复、新功能或性能改进,这些都可以统一应用到所有服务中。我们只需重新生成你的服务存根,你就能免费获得这些改进。
铺好的道路
你将看到这是一个反复出现的主题。我们投入了大量时间从零开始构建和运营自己的工具,同时也在深度整合的思路下利用开源工具,使其适应我们的生态系统。这些工具中的许多都以模块化设计为核心。我们希望暴露这些工具和包所提供的功能,但要以一种高度一致且开箱即用的方式,而不是简单地将工具抛给用户并观察哪些会粘住。我们的目标是投入时间和精力帮助工程师,让工程师更容易地做正确的事,引导他们走上铺好的道路。通过让这条道路足够有吸引力、默认足够简单快速且安全,使他们选择在铺好的道路上构建软件。然后我们让发布这些软件变得非常容易且充满信心。
我认为这就是打造优秀开发者体验的方式:高度专注于帮助工程师正确地构建产品,然后快速、安全且迭代地将代码交付到生产环境。当工程师加入时,为了获得在我们后端系统上工作的权限并部署代码到生产环境,他们需要完成一个结构化的后端101指南。这个指南会引导他们了解我们所有的工具和所有基础原语。一旦掌握这些内容,这些知识将伴随你整个在Monzo的职业生涯。我们会带你了解所有工具、系统编写方式、我们对Go语言的编写规范、我们的设计逻辑、代码结构、微服务架构等更多内容。其中一大优势是,我们可以将这些文档和我们设想的标准,编码为技能并输入到LLM工具中。
这些大型语言模型工具不会凭空捏造服务包和服务结构。它们能够像工程师一样导航代码。我们之所以可以直接呈现这些文档,是因为我们投入了大量时间和精力对所有工具和流程进行标准化。这些文档原本是为人类编写的,现在我们也可以将其用于增强工程师的工作效率。
回到服务结构本身,像Claude和Cursor这样的自动化工具会像人类一样学习我们的编码流程,并遵循服务结构。另一个显著优势是我们拥有一个包含3000多个示例的单一仓库,你可以随时参考。这些AI工具持续学习我们的统一模式,并能够查看后台已实现的示例。它们不会凭空捏造毫无根据的内容。最终,每个服务都包含几千行实际的业务逻辑。这种规模对工程师团队来说非常易于理解。你可以提交一个PR(Pull Request),这是一件非常容易理解的事情。它在上下文窗口中也极易被引用。当你在我们平台上进行交易时,多个不同的服务会实时参与其中。例如,当你用Monzo卡或任何支付卡刷卡时,许多服务会参与这个流程以做出决策。
我们用于判断是否接受或拒绝某笔特定支付的时间预算非常有限。例如,需要检查账户中是否有足够资金、是否涉及欺诈、确保防范金融犯罪,以及需要对特定支付进行分类的其他诸多领域。我们面临的一个关键挑战是,工程师需要不断对系统进行修改以适应快速变化的环境。工程师希望能够对这些流程进行端到端的测试。我们有强烈的动机鼓励他们这样做。从根本上说,我们是一家银行。银行的一个核心原则是接受和处理支付。这是我们希望持续进行端到端测试的关键环节。我们希望工程师对所推送的更改充满信心。历史上,我们并没有很好的本地开发体验来启动完整的系统。
想象一下,如果要修改这个流程中的某个部分,你必须启动250个微服务,每个微服务都有自己的依赖项和配置,还有其他各种设置。除此之外,你还需要运行作为该流程一部分的机器学习模型。设置机器学习模型后,你还需要配置Python环境,并祈祷Python神灵,希望使用正确的pyenv版本和pip版本,以及顺利安装所有依赖项。这简直是一场噩梦。让大量工程师都经历这样的过程管理起来非常复杂。想象一下,如果我们还想将这种规模扩展到非工程师群体。想象一下让产品经理去安装Python,去祈祷Python神灵并做出牺牲,希望他们能成功运行机器学习模型。他们将面临严重的摩擦,这是我们希望解决的问题。
几年前,Soam 曾在一次非常精彩的演讲中分享过 Stripe 的解决方案。当时他代表 Stripe,介绍了他们如何围绕这个问题构建系统。Stripe 会为每位工程师分配远程实例,工程师可以拥有一个或多个实例。他们开发了自动同步工具,将本地代码同步到开发环境中。本质上,这些实例在云端运行,会检出大量代码,你可以在此机器上启动整个 Stripe 堆栈或其子集。他们显著优化了用户体验,使开发过程感觉就像在本地机器上进行。你感觉像是在本地运行和测试更改。我们希望模仿这种体验。我们希望让工程师能够快速在本地进行开发和迭代,但在远程环境中执行完整的端到端测试时,能够实际运行逻辑。
我们从一个核心前提出发。如果你想在某个服务子集上进行更改,不需要运行整个服务链来测试更改的端到端效果。我提到的许多服务都有自己的数据模型、第三方依赖和其他许多内容。我们不希望给工程师增加这些摩擦。我们有几种选择。从第一性原理来看,一个想法是大力依赖模拟和测试契约,以及记录输出和跨服务边界的模拟。这种模拟只能走这么远。我们发现最安全的方法是直接运行代码本身,而不是尝试模拟或掩盖其副作用。我们有一个功能完善的预发布环境,运行着所有服务的副本,所有集成都为你处理好了。
我们在预发布环境上运行整个平台堆栈。它完全配置且完全运行。我们已将其集成到例如直接与 MasterCard 通信的测试框架和其他多个领域。自然地,我们发现工程师们主要在预发布环境中测试更改,并进行端到端测试。工程师会从分支部署代码,并将其部署到预发布环境。随着工程师数量的增加,我们遇到了许多服务竞争的问题。例如,如果你在账户服务中进行更改,我们只运行一个账户服务实例。工程师们会争相在该账户服务中进行更改。多名工程师希望运行自己的代码。我们需要找到一种方法,让多名工程师可以同时运行相同服务,而无需运行整个平台,也不会干扰整个共享的全局命名空间。
这只是对我们的预发布环境工作原理的快速说明。当请求进入预发布环境时,我们会通过标准 HTTP 将请求路由到运行在相同预发布命名空间内的服务。例如,假设你左侧有粉色服务,它想要与底部的 Aqua 服务通信。在调用路径中,它可能依赖于许多其他服务。它会通过乒乓式请求来回发送数据并返回响应。我们构建了一个分层系统,允许工程师在预发布环境中创建自己的独立命名空间,并仅部署他们修改过的服务。我们将这个系统称为租户(tenancies)。这意味着工程师不需要运行他们正在测试的端到端请求链中的所有服务。他们不需要了解所有 250 个服务并让它们在完全独立的环境中运行。
这意味着他们能够对其修改范围进行端到端测试。例如,如果某个服务作为路径的一部分被依赖,它会调用共享命名空间。我们同时平衡了不为每个工程师单独启动基础设施的需求。工程师可以同时运行一个或多个租户。这些租户在我们的预发布环境中是命名空间,因此创建速度非常快。例如,如果你使用过 Kubernetes,我们有 Kubernetes 命名空间。我们还扩展了其他基础设施抽象。Kubernetes 命名空间非常容易创建和销毁。这些是 Kubernetes、Cassandra 和 Kafka 中的命名空间。我们在库层实现了智能处理。当请求通过租户路由时,我们会智能地将租户中未运行的服务路由回相同的共享预发布命名空间。
这个过程是双向的。如果共享命名空间中的服务需要向外路由,它可以调用租户。实现这个功能的方法并不复杂。我们有效的方式是添加一个 HTTP 头。我们为每个请求添加一个头,类似于你为 OpenTelemetry 添加头的方式,或者任何跨请求边界传递信息的方式。我们添加一个头,表明该请求是租户的一部分,因此你可能需要对请求路由做一些特殊处理。我们在服务网格中注入所有这些请求路由配置,并执行智能路由。
这对无状态请求非常有效。我们还想避免数据交叉污染。例如,假设你在共享命名空间中部署了一个服务,但生成了一些垃圾数据。这些数据可能对接受它的服务看起来是有效的,并通过所有验证检查。但从逻辑上讲,这些数据仍然是垃圾。这不应该永久污染共享服务的队列和数据存储。我们通过在共享库层实现处理来解决这个问题。我们的每个共享组件都支持租户,它们理解如何处理来自租户的请求。例如,在 Cassandra 层,这可能意味着将数据隔离到自己的容器中。在 Kafka 层,这意味着将 Kafka 消息路由到自己的主题和队列,而不是污染主主题。
这意味着你不会遇到在某个租户中生成的队列消息,虽然这些消息可能有效但逻辑上不合理,从而导致队列阻塞,因为处理这些消息的代码并不在全局命名空间中。正如我之前提到的,由于这些租户非常轻量,可以在几分钟内创建,我们可以同时运行数百甚至数千个租户。当某个租户不再需要时,我们也可以同样快速地将其关闭。这种模式在解决工程师资源竞争问题上表现得非常出色,因为我们现在可以为所有工程师创建所有这些租户,工程师可以同时拥有多个租户。我们还基于这种模式扩展了功能,使验收测试也能使用租户。历史上,我们的验收测试是在预发布环境中运行的。这些验收测试需要按顺序调度,如果工程师在测试过程中中途向某个服务部署了变更(可能包含有问题的代码),测试结果就会变得不稳定。我们通过将这些测试的置信度提升到了新的高度,现在可以将这些验收测试作为拉取请求的一部分运行,因为我们能够将这些验收测试逻辑部署到租户中。
代码质量、可维护性和安全性
当你完成所有修改后,可以提交一个拉取请求并寻求相关服务代码所有者的评审。在后台,当你寻求人工评审时,我们已经在运行一系列CI检查并验证你代码的结构和逻辑。在这些检查成为强制要求之前,我们持续添加新的检查项。我们根据学到的经验不断发明新的检查规则。我们确保清理现有代码库,避免工程师因与当前修改无关的代码导致的检查失败而困扰。这意味着这些检查为工程师提供了高质量的信号,工程师不会默认忽略这些检查。我们能够显著增加绕过这些检查的难度。
例如,如果你要绕过这些检查,必须向多个人升级并有效执行"破玻璃"程序,说明绕过这些检查的原因。我们希望将"铺设好的道路"作为正确的行为方式,通过强制所有这些检查并提供高质量的信号,使这条路径成为最简单的选择。我坚信让检查机制稳健、快速且易于理解是最大的技术杠杆点。这不是可以通过购买现成产品来实现的。虽然有些供应商会声称可以让你的CI提升这么多,但从根本上说,你需要将这种能力作为技术学科嵌入到组织中。要让CI检查产生高质量信号需要大量努力,我认为这不是可选的。当发生由代码缺陷导致的事故时,你应该提出一个具体问题:我如何将这个缺陷转化为检查,以防止未来再次发生?
如果你的 CI 检查运行缓慢或容易出错,这正是一个与 LLM 工具协作的理想领域,可以识别瓶颈并提升效率。所有进入生产环境的 PR 都需要人工审核,因此所有服务都有对应的人类代码负责人,且必须作为强制审核者,确保变更内容能清晰传达给服务负责人。我们的服务持续发生变化,工程师们也广泛参与各类服务的开发。这不仅限于工程师仅在所属团队内贡献代码,Monzo 的微服务生态系统中,工程师会参与整个系统的所有服务开发,因为所有代码都存放在统一的单体仓库中,且所有服务结构保持一致,这种熟悉度是关键优势。CI 检查能为你提供信心,确保你正确构建了功能。我们能够验证代码逻辑,确保你完成了所有错误处理等关键环节,这为人工审核团队腾出时间和精力,专注于判断我们是否构建了正确的产品。
这两点是最核心的:你必须确保构建了正确的产品,解决了对应的产品需求;同时也要确保构建过程本身正确无误。要确保所有逻辑保持一致。我们投入大量时间和精力编写确定性测试,以验证构建是否正确,从而让人工审核团队专注于判断产品是否符合预期。
持续开发和高度关注的领域之一,是代码推理与审查能力。这一能力确实能带来帮助,但如果实现方式不当,只会产生大量无关紧要的细节问题,比如拼写错误,而无法发现关键的逻辑缺陷。在我看来,你不需要依赖复杂的 AI 代码审查工具来解决所有问题。相反,投入时间和精力编写高质量的 CI 检查会带来更显著的回报。这些检查具有确定性。使用基于 AI 的审查时,要确保其能有效识别业务逻辑问题,验证产品是否符合需求,而非纠缠于微不足道的语义细节。对我们而言,这些 CI 检查会深入分析代码,标记错误的逻辑行为或需要避免的行为模式。
我们高度依赖 Go 的 AST 解析器和新推出的 analysis 包来构建这些检查。我们拥有一系列小型独立的检查规则,运行速度极快。你可以在本地机器上运行这些检查,测试是否存在需要强烈避免的代码模式。它们也可以作为 Git 推送操作的一部分,通过 pre-push 钩子执行。例如,我们有一个检查规则用于识别是否导入了需要避免的跨服务包。比如,我们希望确保你仅在跨服务边界通信时才导入其他包的代码,而非直接导入其内部实现。我们希望确保服务之间保持解耦,不依赖其他服务的内部实现细节。这一原则同样适用于构建安全服务。对于每个服务,我们都希望确保具备出站和入站防火墙功能。
例如,我们有一个 API 服务。这是一个相对简单的 API 服务,用于打印我们所有的银行分行信息。我认为这可能是英国法规的一部分,要求必须提供一个 API,以编程方式返回所有实体银行分行信息。对我们来说,这个 API 非常稳定,它返回一个空列表。这个服务无需与其他任何服务通信即可返回空列表。它不应该需要与账本或任何第三方服务通信来处理这个特定的 API 请求。
再次回想我们的微服务架构图。我们运行着大量服务,不希望工程师手动管理所有这些连接。这很容易出错并引入漏洞。以这个分行 API 为例,假设在软件栈中引入了一个第三方依赖项,用于与命令与控制中心通信。通过静态分析,我们能够以一种易于工程师理解的方式构建这些防火墙功能,即显式添加与第三方通信的规则,并立即阻止所有其他通信。我们生成一系列规则文件,与代码并存,列举出服务可以执行的所有合法出站通信,并在代码提交和拉取请求中进行检查。
这些规则文件经过同行评审,并与服务代码一同存放。这意味着我们可以在 CI 中添加检查,确保每次更改时这些数据保持一致,从而维持严格的安全态势,使所有人满意。在编写这些检查时,我通常强烈推荐使用像 Semgrep 这样的工具,因为它非常容易编写静态分析检查。Semgrep 还支持多种编程语言。你可以为 SQL 编写检查,也可以为 Python 和其他多种编程语言编写检查。你不需要深入了解所有这些语言的抽象语法树细节。
我最近发现,通过与 Claude 合作,能够更有效地编写原生语法检查工具。这对于复杂逻辑测试来说是一个巨大的变革。例如,假设你想跟踪变量在函数间的生命周期,确保它不会被并发修改。我强烈建议你尝试这种方法。特别是如果你生成了一组测试用例和示例,你可以通过 Claude 自动生成分析器,而无需手动编写大量 AST 解析代码。它能为你提供非常强的灵感。静态分析也是推动代码库走向一致性和统一规范路径的有效方式。引入新的静态分析规则可以阻止进一步添加不良代码,并推动淘汰需要弃用的代码区域。然后你可以跟踪并专注于移除现有的使用案例。
再次强调,这是一项你可以通过LLM工具实现的高杠杆操作。如果它们能够跨整个代码库执行这些检查,就能识别出所有使用场景,并有效完成一些繁琐的工作,比如自动创建PR并修复这些问题,确保问题得到解决,因为你已经投入时间编写了确定性检查。如今,我们不再需要花费大量时间硬编码异常处理,如果你希望确保构建状态为绿色,关键在于花时间评估所有异常并决定是标记为“不修复”还是忽略特定检查。相反,你只需将问题一次性输入LLM并询问:“你能修复这个问题吗?如果不能,请添加忽略标签。”
生产环境的遥测数据
一旦服务上线,你就需要了解其运行表现。特别是在LLM和自主系统大量生成代码的当下,部署存在缺陷或性能不佳的代码变得非常容易。我们大量使用Prometheus、Grafana和OpenTelemetry等开源工具来构建可观测性系统。我们投入大量资源从服务和基础设施中抓取和收集所有遥测数据。这并不便宜,我们为此支付了高额费用。每次发生事故时,只要我们能通过这些遥测数据识别出根本原因,我们都会心怀感激。对于使用我们内置库和工具上线的每个服务,我们都能获取数千甚至数万个数据点,并将这些数据绘制到通用仪表板上。同样,我们也可以让LLM工具访问这些数据,在事故期间帮助调试系统。
这还与告警机制相关。我们为所有服务基于这些通用指标设置了自动化告警,并能追溯到具体部署的变更。告警会自动路由到负责该服务的对应团队。对于大多数后端系统,性能分析通常因各种原因被限制访问。需要特殊权限,比如需要机器的root访问权限等。很少有组织愿意赋予工程师在生产环境中运行分析工具的权限。这种态度必须改变。你需要具备深入检查系统的功能。目前许多语言都提供了开箱即用的高性能分析工具,几乎不会产生任何额外开销。我们让工程师可以非常方便地调用Go分析器进入后端系统,并提供了一个友好的Web界面来请求这些分析。Java通过Flight Recorder提供了非常优秀的工具。如果你使用Python,py-spy也是一个非常出色的工具,开销极低。
我曾讨论过如何让开发者工具运行得更快。最近我在数据工程领域投入了大量工作。这些工具大多用 Python 编写。编写低效的 Python 代码非常容易。比如频繁复制对象、在字典和列表之间进行类型转换。你会产生一种错觉,认为只要调用一个函数,就能以较低的成本完成任务。但当这些操作在 DataFrame 中执行百万次时,这个看似廉价的逻辑反而会变得非常耗时。一个简单的原生实现可以显著减少开销。在性能优化方面存在大量改进空间。为开发者工具节省几秒、几十秒甚至几分钟的执行时间,都能带来显著的提升。目前已有像 Pyroscope 这样的工具,可以实现持续性能分析。软件会持续被分析,从而帮助你发现可能导致性能退化的代码变更。
用商业人士能理解的语言来说,代码运行速度越快,所需的服务器就越少,云计算费用或基础设施成本也就越低。为了激励工程师进行优化,我们有一个名为 "Graph Trending Downwards" 的 Slack 频道。工程师们可以在频道中分享他们的优化成果,向全世界展示自己的贡献。我们的所有工程负责人、CTO 和工程总监都会定期关注这个频道,并为这些优化成果喝彩。这在工程评审季时将成为一个值得炫耀的成就。这对整个工程领域都是净收益,这种优化行为也会在个人评审和反馈中得到认可。再次强调,这是一套非常有效的自主编码激励方式。与其给模型一个大型程序并要求它盲目地找出所有可能的优化点,不如直接提供 CPU 或内存堆的性能分析数据和代码访问权限。
模型可以精准定位代码中的热点区域,进行针对性优化。例如,它可以减少对昂贵函数的调用次数,或直接从源头优化这些昂贵函数。我知道有些团队已经将大语言模型应用于错误跟踪。比如你可能已经在 Sentry 或其他工具中接入了 LLM。例如,你可以设置一个按钮,当发生异常时,通过访问代码来尝试修复问题。同样的方法也可以应用于性能分析,这会让工程师和财务团队都更加满意。
生产环境中的系统调试
最后,让我们谈谈生产环境中的系统调试。工程师能够调试业务逻辑非常重要。你可以调试其他所有内容,为什么不能调试业务逻辑?有时这意味着需要查询服务端点并查看数据状态,即使在生产环境中也是如此。在保证隐私和数据脱敏的前提下,可以实现这一点。在许多组织中,我看到两种极端情况。一种是工程师被迫恳求获得生产数据库的访问权限,或在生产环境中以某种安全假象为由直接调用端点。另一种极端则是他们需要添加大量日志语句,并通过反复的监控和部署来排查问题,比如:"肯定不是这个,肯定是这个,我确定调用了这个函数",以此来调试系统。
我们构建了一个 CLI 工具,使工程师能够直接与生产环境进行交互。该工具通过安全授权连接到我们的平台,允许工程师直接操作后端服务、管理服务配置、安排操作任务,并与基础设施进行交互。我们认为这是以一种更高效的方式暴露功能模块,这些模块可能涉及一系列请求。例如配置管理,所有操作都通过 CLI 工具完成。我们最近在配置管理系统中加入了严格的验证机制,确保工程师不会将不合逻辑的更改提交到配置系统。我们还嵌入了同行评审机制,例如我们构建了自己的多方授权系统,允许通过第二人审核更改内容。又例如,当调用敏感的 RPC 接口时,必须获得代码所属团队的批准,以确保不会在生产环境中做出错误更改。
我看到很多高级用户以自己的命令行历史和可定制的 shell 命令为荣。你可能拥有一个非常复杂的 Postman 脚本或一个出色的 curl 命令。然而,当将这些功能构建为工具时,所有人都可以参与并从中受益。我们看到的一个显著优势是,非工程人员也经常在日常工作中使用 Pound CLI。这些用户可能并不习惯使用大型的 IPython Notebook 或 Postman 脚本。
CLI 正在强势回归
我之前展示的许多工具主要面向后端和前端工程师。但你也可以在机器学习和移动测试等其他领域实现自动化。例如,我们拥有大量工具链,可以生成 ML 服务代码,并在 Vertex AI 上准备训练和测试,然后将模型部署到我们的平台。例如,屏幕上的内容展示了一个 CLI 工具,它与 Android 模拟器交互,帮助自动化 Android 工程师日常执行的任务。特别是如果你是负责发布测试或本周版本 QA 的 Android 工程师,这些工具能极大提升效率,例如自动截图、对比差异、运行自动化测试和启动模拟器等操作。
这些工具已成为工程师日常工具链的重要组成部分。我看到的一个显著趋势是,随着大量 LLM 工具的引入,CLI 正在强势回归。许多团队和公司正在投入大量资源打造优秀的 CLI 界面。拥有优秀的 CLI 界面可以节省大量资源。相比于花费大量时间反复沟通、抓取网页内容或处理非确定性的长指令集,CLI 可以以确定性方式完成相同任务。例如审查 Pull Request:你是要解析 30MB 的 GitHub JavaScript 代码,用无头浏览器渲染 GitHub 界面来查看 Pull Request?还是直接使用 GitHub CLI 拉取差异并以结构化 JSON 格式获取所有元数据?后者显然更高效。
我们已经在整个行业中解决了这个问题,很高兴看到命令行工具(CLI)正在强势回归。希望这能推动更多对CLI的投资。这种类比还延伸到更广泛的人群中,而不仅仅是工程师。我们希望工程师和非工程师都能使用我们铺设的道路。我们的工具需要快速、可靠且易于理解。即使是大语言模型(LLM),调用确定性工具也能带来更可靠的结果。想象一下工程师在进行更改时可能需要执行的所有配置步骤和编译过程。如果工程师需要花费大量精力去解除开发环境的限制,向Python、Ruby或Node的“神”祈祷,安装大量随机包,并等待数分钟甚至数小时来编译软件,人们最终会选择放弃,并试图绕过你铺设的道路。如果通过第三方平台注册并部署到Vercel或其他系统要容易得多,他们就会选择这样做。他们总会找到方法。最终,你实际上是在鼓励越来越多的“氛围编程”(vibe coding)。
综合分析
总结并整理以上内容,我通过示例展示了一些我们构建的工具,这些工具是过去十年中对组织流程进行编码的投资成果。从我们构建的内容中汲取灵感,找到组织流程中存在缺陷的领域,并通过自动化和简化这些流程来创造价值。许多公司正在加大对大语言模型(LLM)更广泛可访问性的投资,实际上,你需要具备相应的基础才能实现这一点。投资这些工具的门槛已大幅降低,并且这一过程正在变得越来越容易。在关键工程能力上的投资,例如确定性代码生成器、标准化包管理、一致的测试工具、可靠的遥测数据、真正可靠的预发布环境和性能分析,在我们推动人类与LLM协作的领域中具有巨大回报,因为代码生成的成本已显著降低。
我们希望促进快速迭代,如果所有其他条件都已满足,LLM可以辅助工程师更快、更安全地验证假设,而不是盲目行动。通过标准化少量技术选择并持续改进这些抽象概念,我们使工程师和LLM能够专注于手头的业务问题,而不是每次使用它们时都重新构建底层基础设施。当然,我们并非从零开始构建一切。我们依赖于围绕我们的整个工程生态系统,包括开源技术。我们依赖大量开源工具和第三方服务,但不会直接将开源技术映射到我们的微服务和系统中。我们有非常明确的立场,始终有意识地进行选择。在为工程师设计体验时要有明确的目标,并确保接口与这种体验相匹配。
参与者1:第一个问题,拥有这样一个观点鲜明的技术栈以及所有构建的库,这不会扼杀开发者的参与度吗?因为开发者只是在解决业务逻辑,而业务逻辑并不总是开发者最感兴趣的方面。与之相关的是,当您需要解决更底层的高性能、高吞吐量问题时,如果他们不理解底层的库,他们如何调试、调查和优化这些问题?
Suhail Patel:让我们谈谈大多数工程师的动机。我认为这是我们行业形成的一种错觉。工程师们希望去解决复杂的工程问题,而他们专注的领域中存在大量复杂的工程问题。例如,如果您在支付或金融犯罪领域,仅在调优机器学习模型、制定越来越复杂的规则,或确保更可靠地处理支付以保持这些工程师的参与度和思维活跃度方面,就有很多有趣的工作。这并不一定需要在基础设施层面。
关于高吞吐量和深入理解的第二个问题。我们在系统中花费大量时间进行文档编写和解释系统内的限制。我们的系统并非完美。例如,我们通过HTTP传输RPC堆栈。当然,HTTP有其局限性。您可能依赖于某个特定的HTTP实现。您可能会问,为什么不使用gRPC,或者在这里插入某种协议?我们依赖的是经过充分测试且观点明确的一套强大框架,这些框架已经被证明能够部署并扩展到大量数据。我们发现工程师需要突破这些吞吐量限制的用例非常少。从根本上说,我们向工程师提出的问题是:您为什么认为需要偏离这条已铺设的道路?因为我们已经在这一规模层面进行了验证,通常远超他们试图实现的规模。这使问题从一个理论假设变成了现实检验,实际上,我们已经拥有在现有约束条件下每秒处理数百万请求的系统。为什么您无法在这样的框架内构建自己的系统?
查看更多带字幕的演讲
录制时间:
2026年10月23日
由
- Suhail Patel
#### 相关赞助商
#### 相关赞助商
2026年12月15-16日。探讨资深从业者如何在生产环境中运行代理、评估、模型服务和AI辅助工程,包括哪些失败了以及发生了什么变化。立即注册。
#### 本内容属于InfoQ主题
##### 相关主题:
- 开发
- 架构与设计
- DevOps
- 持续部署
- 敏捷技术
- 持续交付
- 可观测性
- AI开发
- 代码质量
- 代码生成
- QCon伦敦2026
- 质量
- 自动化部署
- 监控
- 平台工程
- QCon软件开发会议
- 字幕
- 微服务
- 应用性能管理
- 软件工艺
- IT服务管理
- 开发者体验
- 性能
- InfoQ
- 敏捷
- Go语言
- 安全
- 架构
- 云计算
- 相关编辑
- InfoQ热门文章 AWS推出Well-Architected Agent预览版 Reverse Engineer Anything项目将AI代理引入二进制分析 Web应用的未来:AI代理能否实时生成UI? AI构建的Adobe克隆开发者称"距离实用还差很远" Google采用Pyrefly实现更快更精准的Python类型检查 从微服务到代理:分布式系统的下一步进化