Andrej Karpathy 力荐的 Vibe Coding 正成为开发者的新宠。这种“只需聊一聊,AI 就能把功能写出来”的体验,极大地提升了简单任务的开发效率。
然而,当我们将目光转向实际的复杂系统,特别是 AI 基础设施(AI Infra)领域时,Vibe Coding 往往会陷入“水土不服”的困境。
总结下来,主要有三方面问题:
- 上下文丢失:对话历史被压缩,关键的设计决策在多轮交互中逐渐被遗忘,导致后续生成的代码与前期讨论脱节。
- 决策偏离:面对复杂系统时,AI 需要做出大量技术决策(如架构选择、接口设计、错误处理策略等),其自主决策容易偏离开发者意图,生成的代码难以符合预期。
- 质量不稳定:即使提供了完整的需求描述,生成代码的质量仍然波动很大,同样的需求在不同时间可能得到截然不同的实现方案。
这些问题背后的根源在于:AI Infra 本质上是复杂系统,动辄数万行代码、成百上千个相互关联的决策点,而当前的对话式编程缺乏持久化、结构化的决策管理机制。换句话说,Vibe 本身是模糊且不稳定的,无法支撑严肃复杂的 Infra 开发。
但 Vibe Coding 的发展趋势不可逆转,其广泛应用的潜力不应就此止步。要让 Vibe Coding 真正适用于 AI Infra 开发,我们实践了文本驱动的 Vibe Coding 方法:通过设计文档将所有关键决策体系化、持久化。
这种方法将复杂系统的关键决策前置到设计阶段,通过结构化文档让开发变得有章可循,大幅降低复杂度门槛。程序员只需专注于高层设计决策,AI 负责代码实现细节,真正实现“几乎不写一行代码,就可以完成复杂功能”。整个过程通过详细的设计规范和代码逻辑来约束 AI 生成,确保实现符合预期,同时提升系统健壮性。
要验证这一新范式的有效性,我们需要一个兼具高复杂度、强工程约束和真实业务价值的典型场景。AI Infra 中的资源调度系统,尤其是面向 Agentic RL(智能体强化学习)的场景,正是这样一个理想试验场。该系统是数万行代码的分布式训练系统,面临 GPU 利用率优化的复杂挑战,涉及核心调度逻辑的改动。
新开发范式如何在这一场景中实操?以下是来自阿里巴巴未来生活实验室与智能引擎团队的实践。
第一部分:Agentic RL 中的 GPU 利用率挑战
在 Agentic RL 的采样过程中,系统需要支持越来越高的交互轮数,让智能体有足够的环境交互来处理复杂任务。然而,这一趋势带来了显著的资源调度挑战。
在实际采样中,智能体执行任务的时间分布呈现典型的长尾特征:绝大多数样本能够在较少轮数内快速完成采样并得出结果,而只有少数复杂样本需要执行到最大轮数限制才能终止。这种极不均匀的执行分布成为 GPU 资源利用的核心瓶颈。
问题的本质在于分布式计算中经典的“落后者效应”(Straggler Effect):无论有多少样本已经完成,系统都必须等待最慢的那个样本执行完毕,才能进入下一阶段。等待过程成为整个训练流程的性能瓶颈,更造成 GPU 资源的严重浪费。
1.2 方案对比与技术优势
业界针对 Agentic RL 训练存在两种主流解决方案,但都存在根本性缺陷:
- 共置方案:采用严格的串行执行策略。所有 GPU 首先统一投入 rollout(采样)阶段,等待全部样本采样完成后再切换至 training(训练)模式。这种方案存在双重效率问题:
- 阶段内资源闲置:在 rollout 阶段,由于落后者效应的存在,大量 GPU 在短样本完成后进入闲置等待状态。
- 阶段间严格串行:rollout 和 training 完全无法并行执行,training 阶段必须等待 rollout 完全结束才能开始,导致整体迭代时间被显著拉长。
- 异步分离方案:通过静态分配专用的 rollout GPU 和 training GPU 实现流水线并行。虽然理论上能够缩短单轮迭代时间,但引入了严重的“双边空泡”问题。在 rollout 侧,短样本快速完成后,rollout GPU 进入闲置状态等待长尾样本执行完毕;在 training 侧,训练任务完成后需要等待新一轮 rollout 数据,training GPU 同样处于闲置状态。这使得理论上的并行优势在实际运行中大打折扣。
我们提出的时分复用方案通过 GPU 池动态分配机制解决上述问题。其核心创新基于一个关键洞察:异步训练过程中,rollout 对 GPU 资源的需求呈现动态波动特征。在 training 触发前,大量样本已进入完成阶段,系统处于样本数目的低谷期,此时对 GPU 资源的需求自然下降。相反,在训练结束后,新一轮大量样本涌入系统,对 GPU 资源的需求急剧激增,形成明显的高峰期。
基于这一波动规律,我们设计了智能资源调度机制,在采样需求低谷期分配部分 GPU 资源用于执行训练任务,从而实现需求波动与资源调度的有效匹配。
系统采用两阶段执行流程来实现这一设计理念:
1. 全力采样阶段:所有 GPU 协同处理大多数样本,快速推进系统至需求低谷状态。
2. 并行执行阶段:当采样完成度达到训练要求时,系统执行缩容操作,释放固定的 rollout GPU 资源转入训练模式。被释放的 GPU 专门执行训练任务(充分利用低谷期的闲置资源),而长尾样本被迁移至剩余 GPU 继续处理。训练任务完成后,系统立即执行扩容操作,回收所有 GPU 资源恢复全力采样状态,为应对下轮需求高峰做好准备。
这种基于工作负载特征的智能时分复用策略,不是简单的资源分割,而是将训练的快速执行特性与 rollout 需求波动在时间维度上巧妙匹配,从而提升了整体的 GPU 资源利用效率。
以 4GPU 系统为例,我们比较各个方案的任务执行时间线。

时分复用方案的核心挑战在于系统复杂度的显著提升。为了追求高性能,需要精细复杂的控制机制,在分布式高并发的系统中实现尤其困难。相比串行执行和静态资源分配,动态调度引入了诸多技术难点:分布式环境下的精确同步控制、扩缩容操作的原子性保证,以及并发场景下样本状态的无缝迁移。

各方案优缺点对比
在一个包含数万行代码的分布式 RL 系统中,手工编码不仅周期长,更易引入隐蔽的状态不一致 bug。传统的开发方式已难以应对这种“高价值、高复杂度”的功能迭代需求。
正是在这一背景下,我们创新性地采用了文档驱动的 Vibe Coding 方法论,通过系统化的设计文档驱动开发流程,显著提升了复杂系统的实现效率和代码质量。
第二部分:文档驱动的 Vibe Coding 方法论
前文提到的 Vibe Coding 三大痛点——上下文丢失、决策偏离、质量不稳定——其根源都指向同一个问题:缺乏持久化、结构化的决策管理机制。
要理解设计文档如何解决这一问题,我们需要先认识到代码实现的本质:它是由成百上千个相互关联的决策点构成的。从顶层的架构选择、接口设计,到底层的变量命名、错误处理,每个决策都影响着最终的代码质量。在理想情况下,如果 AI 已经掌握了完整的代码改动(如代码迁移任务),它可以直接复制执行这些修改。但现实中,我们要解决的往往是全新的问题,比如本文的“训练-推理时分复用优化”功能此前从未实现过。
既然没有现成的代码可以参考,那么退而求其次,如果我们能够系统化地枚举出所有决策点,AI 就可以按照这些明确的决策逐步生成代码。
设计文档正是实现这一目标的关键工具:它通过结构化的方式,将高层的设计思路逐步细化为具体的代码改动,完整记录每一个决策点。
经过程序员审阅的设计文档,意味着人与AI在关键决策上达成一致。这直接解决了氛围编程(Vibe Coding)的三大痛点:持久化文档消除了上下文丢失的风险,明确的决策点避免了AI偏离开发意图,而规范的代码逻辑则确保了最终代码质量的稳定性。
这带来了工作方式的根本转变:程序员从编码、调试、测试等执行性工作中解放出来,转向与AI讨论设计,通过迭代审阅文档来明确并对齐所有决策点。一旦决策完全对齐,AI将负责具体的代码实现。设计文档同时记录实施进度,确保开发过程的可追溯性。更重要的是,设计文档本身由AI辅助管理和维护,大大降低了编写和维护的门槛。

设计文档驱动的氛围编程与传统Vibe Coding工作流对比

三种开发方式的优缺点对比
2.1 核心方法论:设计文档驱动开发
在明确了设计文档的必要性后,需要建立一套系统化的方法论来指导实践。设计文档驱动开发(Design Document Driven Development, D4)不仅关乎文档编写,更是一种全新的开发范式:通过结构化的文档组织决策过程,通过迭代审阅确保决策质量,再通过分步实施来降低实现风险。
该方法论的核心在于将复杂的系统开发问题分解为三个可管理的环节:
1. 内容组织:如何构建层次化的决策体系。
2. 审阅修改:如何通过迭代确保决策质量。
3. 分步实施:如何将决策有序地转化为代码。
每个环节都有明确的操作流程和质量标准,从而确保整个开发过程的可控性与可预测性。
2.1.1 流程概览
设计文档的审阅是一个迭代优化的过程,需要人与AI协作以确保文档质量。我们建立了系统化的审阅流程,通过多轮迭代逐步完善设计,直至达到可实施的标准。
总体审阅流程

2.1.2 如何组织内容:开发者与AI共同完成
代码实现的结果由一系列自顶向下的决策决定,顶层决策关乎新功能如何融入现有架构,底层决策则涉及具体实现细节(如是否需要增加成员变量)。组织设计文档的核心目的,是系统性地跟进这些决策点并逐步完善解决方案。
由于底层决策往往依赖于顶层或上层决策,设计文档需要层次化地拆解决策,形成决策体系。开发者按照章节的先后顺序和目录层次结构,审阅文档中自顶向下的决策过程。当指出顶层设计的错误时,AI会自动修改后续章节的中层和底层决策,以保持内部逻辑的一致性。因此,我们可以按章节层次和顺序,与AI逐个对齐自顶向下的决策。
在开发者和AI共同修正决策的过程中,文档不断演进。文档需要自包含这个迭代过程,记录版本迭代历史。最后,文档也需记录代码实施的进度和衍生的待办事项。
具体而言,我们的设计文档模板包含以下内容:

2.1.3 如何审阅修改:复用 iFlow CLI 的 Prompt 模板
上文描述的逐章节审阅对齐过程在理论上是完备的,但在实践中会遇到一系列挑战。为应对这些挑战,我们建立了多层次的文档质量保证机制。
由于这些场景在文档审阅中反复出现,我们利用 iFlow CLI 的 Sub Command 功能,将不同场景的指令逻辑固化成了自定义的 Prompt 模板。
审阅挑战与解决方案对照表

2.2 设计文档的实施
2.2.1 如何分步计划和实施
当设计文档的“API与实现设计”部分完成后,需要将这些设计转化为可执行代码。这个转化过程分为两个阶段:首先规划实施步骤,然后进入AI辅助的增量开发循环。
1. 规划实施步骤
规划的核心目标是将设计中的方法拆解为依赖关系有序的小步骤。我们首先分析每个方法的依赖关系(deps字段),识别底层辅助方法与高层编排方法之间的依赖,绘制出完整的依赖图。
拆解步骤时遵循“每步越小越好”的原则,通常一个步骤包含3-5个相互关联的方法,避免单个步骤超过10个方法。步骤的排序严格遵循依赖关系:Step 1通常是基础设施(配置、常量、基础类),Step 2到Step N按照从底层到高层的顺序排列,最后一个Step负责集成和端到端测试。每个步骤都定义清晰的验证点和测试用例覆盖,确保可以独立验证并方便回退。
规划完成后,我们得到一个清晰的依赖图,用于指导后续的增量开发:

2. 增量开发循环
实施步骤规划完成后,进入具体的实施阶段。对于每个步骤:
* AI编码:AI首先读取该步骤的目的、依赖关系,以及设计中相关方法的签名与实现描述,然后按照文档字符串(docstring)生成具体代码,同时将验证占位符展开为实际的验证逻辑。编码完成后,AI会自动更新该步骤的状态(如从NOT_STARTED改为DONE)。
* 人工审查:开发者使用IDE的本地历史(Local History)功能查看当前步骤的代码改动,重点检查代码是否符合设计、是否正确实现了验证逻辑、是否存在明显缺陷。若发现问题,进行小范围修正或进入错误处理流程。
* 提交与迭代:审查通过后,创建一个Git提交,提交信息遵循“Step N: [描述]”的格式。然后继续下一个步骤,重复此循环直至所有步骤完成。
2.2.2 防御性编程:让复杂系统更可靠
在分布式AI训练等复杂环境中,微小的错误可能触发级联故障,而异步操作和资源调度的复杂性使得问题追溯本就困难。更棘手的是,AI编程有时会“善意”地主动进行错误处理,这种处理往往掩盖了真实的错误信息,使得问题定位更加复杂。
我们真正需要的是防御性编程,让错误主动暴露而非被掩盖。然而,传统的防御性编程因其开发繁琐性和进度压力常被开发者忽略,导致系统健壮性完全依赖个人自觉。
为此,我们将防御性思维前置到设计阶段:在关键节点预设验证点,构建标准化的错误处理模式库,并利用AI技术自动生成健壮的防御代码。这能在保证开发效率的同时,实现快速问题定位,并显著降低维护成本。
统一的验证模式库
我们维护了一个包含常用验证模式的库,每个模式都有唯一的ID和标准化实现。这些模式遵循“单一定义,多处复用”原则。当需要在代码中增加某个验证逻辑时,只需在注释中引用模式库中的定义ID,AI在实施时会按ID查表并展开为标准代码,确保整个代码库中相同验证逻辑的一致性。

设计阶段的验证标注
在设计文档的实现设计部分,我们不直接编写完整的验证代码,而是使用标准化的注释来标注验证需求。例如,对于 shrink_sampler() 函数:
* 通过 # VAL: VAL_INT_RANGE(min=0, max=7) 标注GPU列表的合法性验证。
* 通过 # AST: AST_POSTCONDITION(len(offload_ranks) > 0) 标注返回结果的有效性检查。
这种标注方式清晰表达了验证意图,同时保持了设计文档的简洁性。
python
def shrink_sampler(self, target_gpus: List[int]):
# VAL: VAL_INT_RANGE(min=0, max=7)
# 将在实施时展开为实际 validation 代码
offload_ranks = self._calculate_offload_ranks(target_gpus)
# AST: AST_POSTCONDITION(len(offload_ranks) > 0)
# 将在实施时展开为 assert 语句
return offload_ranks
AI 自动展开验证逻辑
当 AI 根据设计文档生成代码时,会自动将标注中的模式 ID 展开为具体的验证逻辑。参数范围验证会展开为完整的条件检查语句,后置条件会生成带有详细错误信息的 assert 语句。这种自动展开机制避免了人工编码时的遗漏和不一致。
“`
设计文档中的标注:
AST: AST_POSTCONDITION (len (offload_ranks) > 0)
AI 实施时展开为带详细信息的断言:
assert len (offload_ranks) > 0,
f”Post-condition: offload_ranks not empty, got {offload_ranks}”
“`
复杂验证的独立处理
当验证逻辑超过 10 行时,内联展开会让代码变得臃肿难读。对于这类复杂验证,我们在设计文档中定义专门的验证函数,详细描述验证项和错误处理策略。例如 validate_gpu_allocation() 函数负责验证 GPU 分配逻辑的完整性,包括检查 target_gpus 非空、确保 GPU ID 在有效范围内等。在实施计划中,我们会安排专门的步骤来实现这些复杂验证函数,为后续的核心逻辑步骤提供坚实的基础。
“`python
5.2.8 _validate_gpu_allocation () – Full Specification
def _validate_gpu_allocation (self, target_gpus, current_allocation):
“”” 验证 GPU 分配的复杂逻辑。
检查项:
– target_gpus 非空且元素唯一
– GPU ID 在有效范围内
Raises:
ValueError: 违反任何检查条件
“””
# 10-20 行的详细 validation 逻辑
“`
第三部分:在生产级别的大规模集群上验证
3.1 实验配置
我们在生产级别的大规模集群上验证了时分复用方案的实际效果。实验环境采用 160 卡 GPU 集群,选择了具有代表性的 SWE Agentic 工作负载作为测试场景。模型使用 Qwen3-235B-A22B,这是一个具有 235B 参数规模、22B 激活参数的大规模语言模型,能够充分体现真实生产环境的计算压力。
为了模拟真实的智能体长时交互场景,我们将最大交互轮数设置为 100 轮,最大 token 长度为 64K,batch size 为 512。我们设置异步训练的 async ratio 为 1,这样的配置确保了实验的真实性和挑战性。在对比方案设置上,我们将时分复用方案与传统的异步分离方案进行对比:baseline 采用 128 卡用于 training、32 卡用于 rollout 的静态分配策略,而时分复用方案则采用 128 卡 training、160 卡 rollout 的动态调度策略。
3.2 性能对比分析
实验结果显示时分复用的 rollout 吞吐率提升了 3.5 倍。时分复用方案的 rollout 阶段几乎始终比完全分离的 baseline 要快,甚至在某些情况下训练任务无需等待 rollout 即可开始,性能提升明显。

更值得关注的是任务完成率的提升。在 baseline 的完全分离方案中,由于 rollout 资源受限(仅 32 卡),导致采样速度较慢,大量任务触发了环境默认的超时限制,采样轨迹的 timeout 比例居高不下。而时分复用方案通过动态释放更多 GPU 资源用于 rollout,显著加快了采样速度,完全避免了 timeout,提升了整体训练的稳定性和样本利用效率。

3.3 系统开销分析
在评估时分复用方案时,我们也仔细分析了引入的系统开销。参数同步开销方面,由于时分复用方案需要在更多的 GPU 之间进行参数同步(160 卡 vs 32 卡),相比分离方案会产生额外的通信开销,但这一开销在整体训练整体时间中占比极小。

缩容操作的开销主要来自于 rollout 模型参数的 offload 过程。当系统需要将部分 GPU 从 rollout 模式切换到 training 模式时,需要从显存中将 rollout 参数释放,实测耗时在秒级。尽管这一操作引入了额外的同步点,但由于缩容操作开销极低,因此并未成为性能瓶颈。
综合来看,时分复用方案通过智能的资源调度策略,在引入极小系统开销的前提下,显著提升了 GPU 利用率和训练效率,特别是在降低 timeout 率方面表现突出,充分证明了该方案在大规模 Agentic RL 训练中的实用价值。
关注“鲸栖”小程序,掌握最新AI资讯
本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:http://www.itsolotime.com/archives/17199
