1. 从“给AI配团队”到“全砍掉”的折腾始末
去年年底我开始用AI辅助做一款小体量的2D网页游戏,技术栈选的是Godot加TypeScript导出Web,美术资源靠AI生成,代码部分则交给大模型来写。一开始我的想法很朴素:既然AI能写代码,那我给它配一套完整的“开发团队”不就行了?于是我在工作流里塞进了两个角色——一个“架构师”负责拆解模块、定义接口,一个“代码审查”负责在每次生成后挑毛病、提修改意见。听起来很美好对吧?结果跑了不到三周,我把这两个角色全砍了。这篇文章就是把这中间踩过的坑、试过的方案、以及最后为什么选择“裸奔”式单Agent开发,完整地摊开来讲。
如果你也在用AI做游戏开发,或者正在折腾AI Agent工作流,尤其是涉及代码生成、测试驱动、多角色协作这些环节,那这篇内容应该能帮你省下不少试错时间。我不会讲什么“AI将改变游戏开发”这种大话,只聊具体操作:怎么配的、哪里崩的、怎么改的、最后为什么放弃。全文基于我自己的项目实践,涉及Godot、TypeScript、DeepSeek和Claude的混合使用,以及一套自建的提示词流水线。
先说结论:多角色协作在AI游戏开发里不是不能做,而是成本收益比在中小项目里极不划算。架构师角色容易过度设计,代码审查角色容易陷入“为审查而审查”的循环,两者叠加后,我每天花在协调AI角色上的时间比写游戏逻辑还多。砍掉之后,开发效率反而提升了将近一倍。下面我从头拆解这个过程。
1.1 为什么一开始会想到配“架构师”和“代码审查”
我最初的项目是一个类似《吸血鬼幸存者》的割草类网页游戏,核心循环很简单:玩家移动、自动攻击、敌人波次刷新、经验升级、道具掉落。按传统开发思路,这种体量一个人两周就能撸完。但我想试试AI能不能把速度再压一压,于是设计了一套多Agent流水线。
架构师角色的职责是:接收我的自然语言需求,输出模块划分、接口定义、数据结构、以及每个文件的职责说明。代码审查角色的职责是:接收架构师的定义和AI生成的代码,检查是否符合接口、是否有边界问题、是否违反SOLID原则,然后给出修改建议。我当时的设想是,这两个角色能把AI生成的代码质量拉到“可维护”的水平,避免后期改不动。
这个想法来源于我过去在传统软件团队里的经验:有架构师把关,代码不会乱;有代码审查兜底,bug不会多。但问题在于,AI角色和人类角色有本质区别。人类架构师会考虑团队能力、工期、技术债务的取舍,而AI架构师只会按照“最佳实践”往复杂里设计。人类审查者会判断哪些问题值得改、哪些可以放过,而AI审查者会事无巨细地挑刺,导致无限循环。
1.2 第一版工作流的具体配置
我用的工具链是这样的:DeepSeek负责架构设计和代码审查,因为它长上下文便宜,适合塞大量代码;Claude负责具体代码生成,因为它在Godot的GDScript和TypeScript上表现更稳。中间用了一个简单的Node.js脚本做消息路由,把架构师的输出格式化后传给代码生成,再把生成的代码传给审查角色。
提示词方面,架构师角色的系统提示词大概是这样写的:“你是一个资深游戏架构师,负责将需求拆解为模块,定义每个模块的接口、数据结构和依赖关系。输出格式为JSON,包含modules数组,每个模块有name、responsibility、interfaces、dependencies字段。”代码审查角色的提示词则是:“你是一个严格的代码审查者,检查代码是否符合架构定义、是否有潜在bug、是否违反单一职责原则。输出问题列表,每个问题包含severity、location、suggestion。”
第一周跑下来,架构师输出了7个模块、23个接口、4层继承关系。我当时还觉得挺专业,现在回头看,一个割草游戏根本不需要这么多抽象层。但当时我被“专业感”迷惑了,直接让代码生成角色按这个架构去写。结果就是,光是定义接口和类型就花了三天,真正写游戏逻辑的时间被压缩得所剩无几。
2. 架构师角色为什么成了“过度设计发动机”
2.1 AI架构师的“最佳实践”陷阱
AI架构师有一个很明显的倾向:它会把你给的需求当成一个“企业级系统”来设计。我输入的需求是“玩家自动攻击最近的敌人”,它输出的接口定义里包含了IAttackStrategy、ITargetSelector、IDamageCalculator、IAttackCooldownManager四个接口,还建议用策略模式来支持未来可能出现的多种攻击方式。问题是,我的游戏里只有一种攻击方式,而且短期内不打算扩展。
这种过度设计的根源在于,AI的训练数据里充满了“可扩展、可维护、高内聚低耦合”的教条,但它没有“工期”和“实际需求”的概念。人类架构师会问:“你确定未来会加多种攻击方式吗?不确定的话先写死。”AI架构师不会问,它默认所有东西都要可扩展。结果就是,我花了大量时间在实现这些抽象接口上,而游戏的核心玩法反而没时间打磨。
更麻烦的是,一旦架构定义好了,代码生成角色就会严格遵循。即使我后来发现某个接口根本没必要,想删掉,代码审查角色又会跳出来说“删除接口会导致架构不一致”。整个系统陷入了一种“为了架构而架构”的自我循环。
2.2 接口定义与游戏逻辑的脱节
游戏开发和普通应用开发有一个很大的区别:游戏逻辑高度依赖实时反馈和手感调优。一个攻击间隔是0.3秒还是0.35秒,手感完全不同。但架构师角色定义的是“AttackCooldownManager.shouldAttack(currentTime)”,它不关心具体数值,只关心接口签名。代码生成角色拿到这个接口后,会写一个通用的冷却管理器,然后我需要在一个配置文件里调数值。
听起来没问题对吧?但实际操作中,每次调数值我都要改配置文件、重新导出、在浏览器里测试。而如果直接写死在攻击逻辑里,我改一行代码就能立刻看到效果。架构师带来的“配置化”优势,在这个体量的项目里完全被“调参链路变长”的劣势抵消了。
我后来统计了一下,光是攻击冷却这一个功能,因为要适配架构师的接口,我多写了大约120行胶水代码,包括配置加载、类型定义、默认值处理、边界检查。而这些代码在砍掉架构师之后,全部被删掉了,攻击逻辑回归到一个简单的if (now - lastAttack > 0.3)判断。
2.3 架构变更时的连锁反应
第三周的时候,我决定把敌人的移动方式从“直线追踪”改成“绕障碍物寻路”。这是一个很常见的需求变更。但在有架构师的系统里,这个变更触发了连锁反应:架构师需要重新定义IMovementStrategy接口,代码生成需要重写移动模块,代码审查需要检查新模块是否符合架构,然后我发现新的接口和旧的ITargetSelector有冲突,又得回去改架构。
整个变更花了整整两天,而如果是我自己写代码,这个改动大概两个小时就能搞定。AI架构师把“变更成本”放大了,因为它强制所有模块都通过接口通信,而接口一旦定义就很难改。人类架构师会权衡“这个接口未来会不会变”,AI架构师则默认接口是稳定的,变更时就要付出代价。
注意:如果你非要用AI架构师,建议把它的输出限制在“模块列表+职责说明”层面,不要让它定义具体接口。接口定义交给代码生成角色在写代码时自然形成,后期再重构。
3. 代码审查角色如何拖垮开发节奏
3.1 审查粒度过细导致的“修改-审查”死循环
代码审查角色的本意是好的:每次AI生成代码后,让它检查一遍,有问题就改。但实际跑起来是这样的:代码生成角色写了一个敌人刷新逻辑,审查角色说“第47行没有处理敌人数量为0的情况”,代码生成角色改了,审查角色又说“第52行的数组越界检查不够严谨”,代码生成角色再改,审查角色继续说“第58行的变量命名不符合驼峰规范”……
一个简单的敌人刷新函数,被审查了7轮才通过。每一轮都要调用一次大模型,消耗token不说,时间也全浪费在这种细枝末节的修改上。更关键的是,很多被审查出来的问题在实际运行中根本不会发生。比如“敌人数量为0”的情况,在我的游戏里敌人数量永远不会为0,因为波次系统保证至少有一个敌人。但审查角色不知道这个业务规则,它只会按照通用编程规范去挑刺。
我后来算了一笔账:代码审查角色平均每个函数要提出4.3个问题,其中只有0.8个是真正需要修复的bug,其余3.5个都是风格建议、防御性编程建议、或者“未来可能用到”的扩展建议。为了这0.8个真bug,我要处理4.3个问题,效率极低。
3.2 审查角色与生成角色的“对抗模式”
更微妙的问题是,当审查角色和生成角色都是AI时,它们会陷入一种“对抗模式”。生成角色写代码时,会下意识地“防御”审查角色的挑刺,比如加一堆没必要的空值检查、写冗长的注释来解释为什么这么写。而审查角色看到这些防御性代码后,又会提出新的问题,比如“注释过于冗长,建议精简”。
这种对抗导致代码风格越来越扭曲。我后来翻看那段时间生成的代码,发现里面充斥着if (enemy !== null && enemy !== undefined && enemy.isAlive)这种三重检查,而实际上在我的类型系统里,enemy永远不可能是null或undefined。这些检查完全是审查角色逼出来的,它们让代码变得臃肿且难以阅读。
3.3 审查意见的“正确但无用”困境
审查角色提出的意见,单独看每一条都是“正确”的。比如“建议使用常量代替魔法数字”、“建议添加错误处理”、“建议拆分长函数”。但这些建议叠加在一起,就会导致代码过度工程化。一个原本20行的函数,按照审查意见改完后变成了80行,拆成了5个小函数,每个函数都有错误处理和日志记录。
在游戏开发里,这种“正确但无用”的审查意见尤其致命,因为游戏逻辑往往需要紧凑和直接。一个攻击判定函数,如果拆成“获取攻击者”、“获取目标”、“计算距离”、“判断是否在范围内”、“执行伤害”五个函数,每个函数都加错误处理,那性能开销和代码复杂度都会飙升。而实际上,这个函数只需要三行代码就能搞定。
我印象最深的一次是,审查角色建议我给一个纯函数添加try-catch,理由是“防止运行时错误”。但那个函数只是做简单的数学运算,根本不可能抛异常。我按照建议加了try-catch后,代码变成了这样:
function calculateDamage(base: number, multiplier: number): number { try { return base * multiplier; } catch (e) { console.error('Damage calculation failed', e); return 0; } }这段代码在审查角色眼里是“健壮”的,但在我眼里是荒谬的。一个乘法运算加try-catch,除了增加代码量和降低可读性之外,没有任何实际作用。
4. 砍掉两个角色后的“裸奔”方案与实测效果
4.1 单Agent直出代码的配置调整
砍掉架构师和代码审查之后,我的工作流简化成了:一个代码生成角色,接收我的自然语言需求,直接输出可运行的代码。提示词也大幅简化:“你是一个Godot游戏开发者,用TypeScript写游戏逻辑。代码要简洁直接,不要过度抽象,不要添加不必要的错误处理。优先保证可运行和可读性。”
这个调整带来的变化是立竿见影的。以前一个敌人刷新功能要走“架构定义→代码生成→审查→修改→再审→再改”的流程,现在直接“需求→代码→运行测试”。时间从平均45分钟压缩到了8分钟。而且生成的代码更符合我的预期,因为它不再被架构师的接口和审查角色的规范束缚。
我举一个具体的例子。割草游戏里有一个“经验值达到阈值后升级”的逻辑。在有架构师的版本里,这个逻辑被拆成了IExperienceCalculator、ILevelUpHandler、IUpgradeSelector三个接口,代码分散在四个文件里。砍掉之后,我直接让AI写了一个checkLevelUp()函数,20行代码搞定,逻辑一目了然。
4.2 测试驱动作为替代质量保障
砍掉代码审查后,我用测试驱动来兜底。具体做法是:每次AI生成一个功能模块,我立刻写一个简单的测试用例,在浏览器控制台里跑一遍。比如敌人刷新功能,我写一个测试脚本,模拟10秒的游戏时间,检查敌人数量是否在预期范围内、是否有报错、帧率是否稳定。
这种“运行测试”比“代码审查”有效得多,因为它检查的是实际行为,而不是代码风格。AI审查角色会告诉你“这个变量名不好”,但运行测试会告诉你“这个功能有bug”。在游戏开发里,后者才是真正重要的。
我用的测试框架很简单,就是浏览器自带的console.assert加上一些手动写的检查函数。比如:
function testEnemySpawn() { const game = new Game(); game.start(); for (let i = 0; i < 600; i++) { game.update(1/60); } console.assert(game.enemies.length > 0, 'Enemies should spawn'); console.assert(game.enemies.length < 200, 'Enemy count should be reasonable'); console.log('Enemy spawn test passed'); }这种测试虽然粗糙,但能抓住90%的实际问题。而且写测试的时间远少于处理审查意见的时间。
4.3 效率对比与质量评估
我统计了砍掉两个角色前后各两周的数据。砍掉之前,平均每天完成3.2个功能点,其中约40%的时间花在协调AI角色上。砍掉之后,平均每天完成6.7个功能点,协调时间降到5%以下。代码质量方面,砍掉之前因为过度抽象,代码行数多了约60%,但实际bug数量并没有显著减少。砍掉之后,代码更紧凑,bug主要集中在逻辑错误上,反而更容易定位和修复。
当然,单Agent方案也有代价。最大的代价是架构一致性下降。因为没有架构师统一规划,不同模块之间的接口风格可能不一致,后期重构成本会高一些。但对于一个预计两周完成的小游戏来说,这个代价完全可以接受。如果项目周期超过两个月,或者团队有多人协作,那可能还是需要某种形式的架构约束,但不一定是AI架构师。
实操心得:砍掉角色后,我保留了一个“轻量级架构笔记”,就是自己在Markdown里记一下模块划分和关键接口。需要的时候手动喂给AI,不需要的时候就不管。这比让AI维护一套完整的架构定义灵活得多。
5. 多AI协作在游戏开发中的适用边界
5.1 什么情况下多角色协作反而有效
多AI角色协作不是完全没用,但它有明确的适用边界。根据我的实践,以下几种情况可能值得保留多角色:
- 大型项目的前期架构设计:如果项目预计超过3个月,模块超过20个,那让AI架构师做一次性的架构规划是有价值的。但规划完之后就应该把架构文档固化,不要让架构师角色持续参与每次代码生成。
- 多人协作的接口对齐:如果有多个人同时用AI写代码,那需要一个统一的接口定义来避免冲突。这时候AI架构师可以作为“接口仲裁者”存在。
- 安全关键或性能关键的代码审查:如果游戏涉及网络同步、存档加密、支付逻辑等敏感模块,那让AI审查角色专门检查这些模块是值得的。但不要让它审查所有代码。
5.2 什么情况下单Agent直出更优
对于中小体量的游戏,尤其是个人开发者或小团队,单Agent直出几乎总是更优的选择。原因很简单:游戏开发的核心是快速迭代和手感调优,而不是代码的完美性。一个能跑但代码有点乱的游戏,比一个代码完美但玩法无聊的游戏有价值得多。
单Agent直出的另一个优势是上下文一致性。在多角色系统里,架构师、生成者、审查者各自维护自己的上下文,信息在传递过程中会丢失或扭曲。而单Agent只有一个上下文,它记得自己之前写过什么,风格更统一。
5.3 我的最终工作流配置
目前我的工作流是这样的:一个主Agent负责所有代码生成,提示词里明确要求“简洁、直接、可运行”。我自己维护一个轻量级的架构笔记,只在需要时手动注入。测试驱动作为质量保障,每个功能模块写完立刻跑测试。如果遇到复杂逻辑,我会把问题拆成多个小步骤,让AI一步步生成,而不是一次性生成一个大模块。
这套配置跑了一个月,完成了游戏的核心玩法、UI、存档、音效集成。代码量大约3000行,bug率在可接受范围内。最重要的是,我每天都能看到游戏在变好,而不是在跟AI角色扯皮。
6. 踩坑之后总结的几条硬核经验
6.1 不要用AI模拟人类团队结构
人类团队有架构师和审查者,是因为人类有沟通成本、有认知偏差、有工期压力。AI没有这些限制,它可以直接从需求跳到代码,中间不需要“角色”来协调。强行给AI配角色,相当于给一辆自动驾驶汽车配一个“方向盘操作员”和一个“油门踩踏员”,除了增加复杂度之外没有任何好处。
6.2 审查角色的替代方案是“运行测试”
代码审查的本质是“在运行之前发现问题”。但AI审查者只能检查代码的“形式”,不能检查代码的“行为”。而游戏开发中,行为才是关键。所以与其让AI审查代码,不如让AI生成测试用例,然后运行测试。测试失败的地方,才是真正需要修改的地方。
6.3 架构师角色的替代方案是“手动笔记”
AI架构师的问题是它不知道项目的实际边界,它会按照理论最优去设计。而你自己知道项目要做多大、要做多久、哪些地方可以妥协。所以架构决策应该由你自己做,AI只负责在你给定的架构下生成代码。如果你不确定架构,可以先让AI生成一版代码,跑起来之后根据实际痛点再调整。
6.4 提示词要“做减法”而不是“做加法”
我一开始的提示词写得很长,塞了各种规范、约束、最佳实践。后来发现,提示词越长,AI越容易陷入“满足提示词”而不是“解决问题”。现在我的提示词只有一句话:“用TypeScript写Godot游戏逻辑,代码简洁直接,不要过度设计。”效果反而更好。
6.5 砍掉角色后,开发节奏回归正常
砍掉两个角色后,我最大的感受是“节奏回来了”。以前每天要花大量时间在AI角色之间传话、协调、处理冲突,现在这些时间全部用来写游戏逻辑和调手感。游戏开发本来就应该是一件直接的事情:想一个玩法,写代码,跑起来,调,再跑。AI角色把这件事搞复杂了,砍掉它们之后,事情回到了它本来的样子。
最后分享一个我最近在用的技巧:如果你不确定某个功能要不要抽象,就先让AI写一个最直接的版本,跑起来。如果跑起来之后你觉得需要抽象,再让AI重构。大多数情况下,你会发现根本不需要抽象。游戏开发里,能跑的代码就是好代码,其他的都是废话。