编码代理加速了代码生成,但企业分布式系统中的验证瓶颈日益严重。传统CI滞后,需将验证左移。Signadot提出Kubernetes沙盒和Skills框架,让代理在开发阶段自主安全验证,实现高效开发。
译自:Enterprise dev teams are about to hit a wall. And CI pipelines can't save them.
作者:Anirudh Ramanathan
在过去两年中,软件开发的经济模式已经颠覆。生成代码变得很快,但验证它仍然异常困难。
对于构建独立应用程序的开发人员来说,编码代理可以立即带来变革。反馈循环是本地且紧密的:编写、运行、观察、调整。
但在企业环境中,应用程序由跨多个团队的数十个微服务组成,生成和验证之间的差距正在扩大为一场危机。代理可以在几秒钟内重构一个服务,但证明更改实际有效仍然依赖于从未为此速度设计的基础设施和流程。
“生成代码变得很快,但验证它仍然异常困难。”
业界多年来一直在谈论“左移”。编码代理即将推动这一问题的解决。
具有前瞻性的平台团队正在认识到需要提供基础设施,以便开发人员和代理都能获得环境访问权限和工具,从而根据依赖图的实际情况安全地验证其代码。

CI反馈循环为时已晚
在大多数企业组织中,“安全”意味着只有在拉取请求(pull request)打开后才触发的持续集成(CI)管道。当开发人员每周只生成少量拉取请求(PR)时,这种模式是有效的。但当代理帮助他们每小时生成少量PR时,它就不再奏效了。
计算很简单。如果每次更改都需要在共享staging环境中进行30分钟的验证,并且由代理辅助的开发人员每天生成5或6个PR,那么开发人员将大部分时间花在管理部署队列上,而不是构建软件。代理加速了代码输出速度,但如果周围的系统仍然缓慢,那么这种速度就会遇到瓶颈。
真正的瓶颈不再是编写代码的速度。而是验证代码的速度。当代码到达CI管道时,已经太晚了。验证需要发生在开发循环内部,而不是之后。
代理的复杂性上限
随着系统复杂性的增长,这个问题会变得更加复杂。对于单体应用程序或简单的API,代理可以在本地运行测试并获得合理的信号。但对于具有十几个相互依赖服务的云原生分布式系统,这种方法就会失效。
当一个服务的更改通过多个下游依赖项传播时,一个没有基础设施访问权限的代理实际上是盲目的。它生成的代码在隔离状态下看起来是正确的,但在部署时会失败,因为它缺乏对整个系统运行时行为的可见性。
代理无法看到请求如何流动,无法观察schema更改如何影响下游消费者,也无法验证当实际依赖它的服务调用时,新端点是否正常运行。
这迫使开发人员陷入一个令人沮丧的循环:代理生成一个PR,开发人员手动审查它,部署到共享环境,等待,发现只有在真实基础设施条件下才会出现的副作用,然后重新开始。代理完成了它的工作。它周围的系统未能提供代理做好这项工作所需的上下文。
基础:Kubernetes沙盒
解决这个难题的第一步是让代理访问真实的基础设施,而无需复制整个集群的开销。
为了解决这个问题,我们利用一种方法,使用Istio或Linkerd等服务网格来创建沙盒,这些轻量级、短暂的环境利用请求路由来提供真实的运行时,而不是完全的环境复制。
沙盒不是为每次更改都启动一个完整的staging集群副本,而是只部署修改后的服务,并通过它路由特定请求,而其余流量则流经共享的staging基础设施。每个环境的成本降至传统方法的一小部分,沙盒可以在几秒钟而不是几分钟内启动。
这种架构改变了计算方式。当环境廉价、快速且可废弃时,它们不再是开发人员和代理争夺的稀缺资源。它们成为代理可以在其正常工作流程中以编程方式使用的工具,针对整个系统的实时版本测试更改,而不会阻塞任何人。

但仅仅访问基础设施是不够的。代理还需要结构化、可靠的方式来与该基础设施交互。企业团队需要确信代理能够跨组织一致且安全地验证代码。
这是平台工程的下一个挑战。正如今天的平台团队提供CI管道、部署工具和可观测性作为共享服务一样,他们将需要提供开发人员和代理在开发阶段本身就可以使用的验证能力。
“关键的见解是,分布式系统中的验证不是单一的检查。它是由一系列步骤组成的。”
这些能力需要是确定性的,以便结果可复现且值得信赖。它们需要受到治理,以便平台团队能够控制代理在实时环境中可以做什么。它们还需要是可组合的,以便开发人员能够将它们组装成符合其服务特定验证需求的工作流,而不是依赖于单一的、庞大的测试套件。
关键的见解是,分布式系统中的验证不是单一的检查。它是一系列由基础设施供应、服务交互和结果验证组成的步骤。
闭环
这里的愿景很直接。当编码代理生成一个更改时,它应该能够在将其呈现给开发人员之前,根据真实的基础设施验证该更改。开发人员不应该只收到一个PR,而应该收到一个正确性证明:一份记录,显示代理已针对实时服务测试了其工作,集成点按预期运行,并且没有引入任何回归。
这使得传统的CI反馈循环融入到开发阶段本身。循环不再是编写、提交、打开PR、等待CI、发现故障和修复,而是变为编写、验证、呈现已验证结果。
Signadot如何处理这个问题
在Signadot,我们正在通过我们称之为Skills框架的方法来实现这一愿景。Skills建立在我们短暂的沙盒基础设施之上,并带有一个我们称之为Actions的平台治理原语库,例如向沙盒中的服务发送HTTP请求、捕获日志或断言响应与预期schema匹配。
每个Action都由平台团队单独治理,这意味着安全和合规性要求在原语层面强制执行,而不是事后附加。
由于Actions是确定性的,平台团队可以赋予开发人员和代理灵活性,让他们组合自己的验证工作流,而不会牺牲代码在整个组织中验证方式的一致性。
开发人员或代理编写一个计划,这是一个验证特定行为的Actions序列。该计划被标记、版本化并作为开发人员编码代理的本机技能导出。当代理进行更改时,它会自动在实时沙盒中运行该技能并报告结果。
目标是赋予代理自主验证其工作的能力,同时让平台团队控制边界。我们认为这种自主性与治理之间的平衡对于企业大规模实现代理开发的好处至关重要。
欢迎在我们的架构博客中阅读更多关于我们正在用Skills构建的内容。我们欢迎反馈!