Vibe Coding AReaL
那三天,我差点把veRL的代码库扔出窗外
先给你讲个让我血条直接清空的翻车故事。
我花了整整三天,给veRL框架写了三百行配置。调试Agentic RL训练流程,每一步都仔细极了。你猜结果怎么样?
训练曲线出来那一刻——reward全是平的。
平的!跟死了一样,模型根本没有反应。我盯着那个破曲线图,后背的冷汗直接下来了。
我的第一反应是什么?特别本能——把veRL整个代码库扔给Claude,让它帮我查。八万行代码啊,我心想AI这么牛,肯定能给我指条明路。
结果呢?AI在八万行代码里兜圈子,给我提了十几个完全不靠谱的假设。一会儿说“是不是reward函数写错了”,一会儿说“可能FSDP的sharding策略不对”,越扯越远。我整整跟它来回拉扯了两个小时——问题一个没解决,我倒快被搞疯了。
说到这儿,你肯定明白我接下来要讲什么了。
20分钟的醒悟:为什么越大的问题,越要用小的方式解决
后来我换了个思路。
花了20分钟,手写了一个特别简单的PPO训练循环——不用veRL,不用Ray,不用FSDP。就是纯Python采样几轮、算算advantage、更新policy。总共才80行代码的小脚本。
扔给AI一看。
5秒定位问题——我的reward scale设错了整整两个数量级。梯度信号跟救命声淹没在噪音里一样,根本传不到模型那里。
你看,这是不是很反直觉?大家都觉得“大问题该找大工具”。结果恰恰相反——越是复杂系统里的bug,越需要用最小demo去破解。
从那以后,我的习惯彻底变了。遇到分布式训练框架出问题,第一反应不是把整个代码库扔给AI,而是先挤出一个最小复现demo。写这个demo的过程本身就帮我排除了90%的干扰——你不用管Ray的worker分配、不用管SGLang的batch调度、不用管veRL的agent loop层。
说白了,最小demo同时帮了两个人——你和AI。你通过提炼过程理清了问题本质,AI不用在巨量不相关的上下文里猜“哪部分和这个bug有关”。
这个模式我验证了不下十次。花20分钟写demo,成本永远小于在大代码库里让AI瞎猜两小时。
还有个惊喜——很多原本觉得“非搞不可”的bug,在提炼demo的过程中自己就想通了。根本不用问AI。
402次并行:一场32天的“多线程”实验
说到这儿,再给你讲个数字——402。
我在那32天的AReaL开发周期里,记录到了402次多session并行事件。我自己都吓一跳。
刚开始做分布式RL框架的时候,我犯了个典型错误:一个人跟AI对话,等着它写完plan、再等着它写实现、再等着它做review。大部分时间都在等。就跟排大队似的,时间全耗在等待上了。
后来我改了。开三个session同时跑——一个session做plan,一个写代码,一个做审查。三者并行,吞吐量直接翻倍。
但比multitasking更有价值的是什么呢?是pass@k采样。
同一个问题,我给三个session不同的约束。比方要实现一个agent loop的rollout机制:一个session按veRL原版的同步方案做,一个session做fully async的版本,还有一个session尝试用SGLang的batch overlap思路。跑完之后我挑效果最好的那个方案merge。
你可能会问:不怕冲突吗?不怕。git worktree提供了物理隔离,Claude Code编辑文件时会检查write-after-read一致性,有冲突就会报错。这些机制从底层保证了多session不会互相踩踏。
不过!多session并行有个特别致命的盲区。你想想,当所有session都卡在同一个bug上时会发生什么?它们共享同一个错误的前提假设,开再多也白搭。
我在veRL的某个tokenization性能优化上就栽过这个跟头——三个session都在假设“是data loader的问题”,没人去想“可能是token id mapping错了”。浪费了一整天。
这让我深刻意识到:并行不是银弹。什么时候该并行提吞吐,什么时候该停下来先解决阻塞——这才是需要人类介入的元决策。四个session全在错误的方向上狂奔,还不如一session停下来好好想想。
三层验证:防坑的正确姿势
veRL框架的CI我已经跑了快四个月。踩过的坑,能写本小册子。
最后稳定下来的验证体系,其实特别简单。
第一层——pre-commit hook。自动跑格式化、lint、基础类型检查。说实话,这套东西最多拦住25%的问题,基本都是低级错误:少了个import、变量没定义之类的。但它的价值在哪?让AI生成的代码格式统一,后续review不会在缩进这种破事上浪费时间。
第二层——我自己的/pr-review动态审查。用了一个了解veRL全貌的“领域专家agent”对改动做针对性审查。不限于语法,会看接口设计、数据流、潜在的性能瓶颈。这比通用lint深入太多。你想想,AI写的代码语法通常没问题,坑一定是在逻辑层面。
第三层——最痛苦的一层:随着项目变大,不断针对新发现的失败模式补充测试。社区里其他做AI辅助项目的团队也是这么干的——发现“新功能破坏了旧代码”,马上补回归测试,形成滚雪球式的质量积累。
说句实话,第二层和第三层之间的间距很大。很多团队只做了第一层,然后直接跳到“全面测试覆盖”——但这不现实。分布式RL框架的测试太难写了,场景太多。我更推荐优先把review agent调好,它的ROI比写测试高得多。
为什么“写文档”才是最酷的工作?
你知道吗,我之前写过veRL的代码带读,对它熟悉得不能再熟悉了。但真正上手“零手打代码”开发的时候,我还是翻车了。
问题出在哪?
Andrej Karpathy说的vibe coding,本质上是一种“感觉结果对就收工”的开发方式。在写一次性脚本或者demo的时候,这种方式爽得飞起——就像周末做顿火锅,边下料边尝,差不多就行。但在搞分布式训练框架这种复杂系统的时候,vibe就变成了玄学。
我统计过:在没有任何前期设计文档的情况下,直接跟AI对话完成一个agent loop的改动——平均要迭代7轮才能达到可接受的质量。中间每3轮就会有一次“AI开始自由发挥”——它自己决定改某个接口签名、换一种数据传递方式,都是之前对话没商量过的。
后来呢?我换了一个思路——先写设计文档。把关键决策写在md文件里:架构选型、接口签名、错误处理策略、性能目标。然后让AI严格按照文档去生成代码。
效果天差地别。
同样是agent loop改动,文档驱动后平均2轮搞定,而且AI不会擅自改接口了。从7轮到2轮,你想象一下这个效率提升。
我的文档模板很简单:场景描述、架构图(用Mermaid画)、接口定义(protobuf或Python stub)、数据流图、约束条件(“必须兼容verl的FSDP后端”之类的)。写这份文档大概花40分钟,但在整个开发周期里能省下至少两天。
现在veRL框架的新人入职,我都会丢一本设计文档给他们,让他们先读文档再用vibe coding做改动。没有文档打底,很容易在跟AI的多轮对话里迷失方向。
一个让零手打代码真正work的框架
把以上所有经验打包,我理出了一套适合AI Infra开发的vibe coding流程——你拿去直接用:
第一步:设计前置(40分钟)
写设计文档,明确所有关键决策。这是最重要的步骤——不能省,绝对不能省。
第二步:最小demo先跑通(20分钟)
针对最核心的逻辑写一个极简原型,验证可行性。记住,这是帮你和AI同时理清思路的关键。
第三步:多session并行实现(依规模而定)
一个session做实现,一个session做review,一个session做测试。三个session用git worktree隔离。
第四步:评审和测试(持续)
review session审查实现session的输出,测试session写CI脚本。让系统自动运转。
第五步:回退和迭代(当所有session卡住时)
停下来重新审视设计文档,找到共同的前提假设,修正后重新并行。不要硬扛。
这套流程帮我在32天里完成了veRL的分布式训练框架搭建——零手打代码,真的一行都没手写过。
当然,不是所有场景都适合这么搞。如果你的需求很明确、技术上没有太大leverage,或者项目规模小到一个人两周搞定,那直接用对话式vibe coding就够了。这玩意儿的最佳适用范围是:有一定复杂度、但边界清晰的系统。
最后那三件事
你看,现在的vibe coding讨论有两个极端。
一边是“AI啥都能干,代码不用写了”的过度乐观——好像明天程序员就要失业了。一边是“复杂系统还得靠人写代码”的保守主义——仿佛AI只是个高级自动补全。
我的判断更折中:对于AI Infra这种复杂系统,零手打代码是可以做到的。但你必须改变跟AI协作的方式,不能像写简单脚本那样靠感觉莽。
关键就三件事:最小demo前置、多session并行拉吞吐、设计文档保质量。
做完这三件,剩下的就交给AI。说实话,现在让我手写veRL的distributed rollout逻辑,我可能还写不过Claude。但我知道怎么引导它写出符合我预期的代码,怎么在它跑偏的时候拉回来,怎么用最少的工作量验证最终的结果。
这才是我作为人类开发者真正该干的事。
未来我赌一个方向: 随着Claude Code、OpenCode这类工具的成熟,“不再手写代码的infra工程师”会变成常态。但与此同时,能写清晰设计文档、能做系统层面元决策的人,反而会更稀缺。
你想想,当每个人都能用AI写代码的时候——还能写出好代码的人,靠的是什么?
不是手速。不是语法。是知道自己在做什么的能力,是设计系统的眼光,是让上万行代码按照你想要的逻辑运转的那个“元能力”。
说白了,未来的程序员,要么变成“只懂写代码的人”,要么变成“懂得怎么让AI写好代码的人”。
两条路,你自己选。
对了——再跟AI说话之前,先问问自己:我的文档写好了吗?
读者评论 2