作者将规格决策、图像生成、代码修改、浏览器测试和部署拆给六个智能体,并在关键节点保留人工审批。相比单一智能体,该流水线更容易定位故障并控制各阶段风险。
这是「游戏工厂」系列 8 篇文章中的第 2 篇。
游戏工厂是一条由多个 Agent 组成的流水线,可以把一句话描述的主题,变成一个已经部署、可以直接玩的老虎机游戏。我输入「古埃及宝藏老虎机」,在过程中批准几个决策,几分钟后,一个主题游戏就出现在某个 URL 上:转轴上是金色圣甲虫,背景是莎草纸,中奖提示与法老有关,还有一个正常工作的排行榜。我不需要绘制任何图标,不需要写一行 React,也不需要打开控制台。
第 1 篇讲的是我为了学习 iGaming 领域,亲手构建的那一台老虎机。这篇文章讲的是,那一个游戏如何演变成一条能按需生产不同变体的流水线——六个 Agent 分别是什么,它们如何交接,以及人类仍然站在流水线的哪些位置。
最显而易见的方案,是使用一个足够聪明的 Agent:「这是主题,这是代码库,帮我做一个游戏。」但我没有这么做,而背后的原因很重要。
制作一个老虎机变体并不是一项任务。首先要确定规格,然后生成图片、修改代码、进行浏览器测试,最后部署——每一步需要的工具不同,失败模式不同,而且在继续之前,人类想要检查的位置也不同。让单个 Agent 完成所有事情,意味着它必须在上下文中同时掌握太多信息;它的失败很难定位;而且在各个步骤之间,你也没有任何可供检查的中间产物。因此,我把整个过程拆成了一条流水线:每个阶段都是一个小型 Agent,只负责一项工作,并输出一个结构清晰、可供下一阶段使用的结果。
这里的 Agent 并不是什么复杂的东西:它只是一个运行在循环中的模型,配有一组工具,以及一个结束循环的条件。调用模型,让它调用工具,把工具结果反馈给它,如此重复,直到它发出完成信号。我刻意没有使用任何框架,只用了 Bedrock API 和 Python,这样我就能理解其中的每一个部分。真正有意思的工程问题不在循环本身,而在于如何限定每个 Agent 的职责范围,让这个循环能够顺利终止。
这条流水线按顺序运行。每个阶段读取之前生成的内容,并写出下一阶段需要的东西。
one sentence in
│
▼
┌────────────────┐
│ Designer │ ──▶ the spec (a JSON contract)
└────────────────┘
│
▼
┌────────────────┐
│ Image-Gen │ ──▶ symbol icons
└────────────────┘
│
▼
┌────────────────┐
│ Background-Gen │ ──▶ the page background
└────────────────┘
│
▼
┌────────────────┐
│ Builder │ ──▶ the themed React code
└────────────────┘
│
▼
┌────────────────┐
│ Tester │ ──▶ a pass / fail QA report
└────────────────┘
│
▼
┌────────────────┐
│ Deployer │ ──▶ a live URL
└────────────────┘
│
▼
a deployed, playable game
{
"theme_id": "ancient-egypt-slots",
"symbols": [{ "name": "Scarab", "value": "scarab", "weight": 3 }],
"color_palette": { "primary": "#C8A24B", "background": "#1A0F0A" },
"win_names": { "three_of_a_kind": "PHARAOH'S FORTUNE" }
}
Image-Gen。它会根据 prompt,为规格中的每一个符号生成图标,然后把图标缩放到转轴所需的尺寸。于是,转轴上的图案不再是云服务 Logo,而变成了圣甲虫和安卡十字。
Background-Gen。思路相同,只不过它只生成一次,用作页面背景。
Builder。这个 Agent 会把赌场的 React 代码转换成当前主题对应的代码。它是负责修改代码的 Agent,也是最让我头疼的一个——以至于它值得单独写一篇文章,讲述它如何经历了一次重新设计。
Tester。它使用 Playwright,在真实浏览器中运行构建完成的游戏,并在每一步截取屏幕截图。随后由视觉模型判断游戏是否真的可以正常游玩——转轴会不会旋转、中奖结果能否正确显示、UI 看起来是否正常。这是一种依靠「看」来作出判断的自动化 QA,而不是对 DOM 编写断言。
Deployer。它负责构建应用并将其部署到 AWS——前端部署到 CloudFront,并连接到 serverless 后端。如果 Tester 的报告没有表明游戏已经通过测试,它就会拒绝运行。
这条流水线并不是完全自主运行的,这是刻意设计的结果。各个阶段之间设有审批关卡:Designer 提出规格方案并等待确认;Builder 在修改代码之前先提交计划;Deployer 在正式发布之前再次确认。它遵循的模式是:Agent 提议,人类批准。这样,人类只需要在错误决策会带来高昂撤销成本的关键节点参与其中,而不必亲自完成具体工作。
各阶段之间的交接被刻意设计得十分朴素。规格说明是磁盘上的一个文件;图标和背景是磁盘上的文件;测试结果也是磁盘上的文件。每个 Agent 都会读取前序 Agent 生成的产物。朴素的交接方式意味着交接过程可以被检查——当构建结果看起来不对时,我可以打开规格文件和图片,准确查看下一阶段收到的内容。
如果你正在构建一个能把 prompt 转换成真实产物的系统,真正值得借鉴的形态并不是「一个包办所有工作的 Agent」,而是一条由多个职责明确的 Agent 组成的流水线:每个 Agent 只负责一项工作,输出一个供下一阶段读取的普通文件,并在错误代价高昂的位置设置人工审批关卡。
这种设计能够把故障限制在局部——当生成的游戏有问题时,我知道应该追究哪个阶段,因为我能看到它具体生成了什么。它也允许你单独替换或强化某个阶段,而不必改动其他阶段。正因如此,后来我才能拆掉并重建 Builder,同时不影响环绕在它前后的另外五个 Agent。
接下来,每个阶段都会按照顺序拥有一篇单独的文章,而且每篇都会回答同样三个问题:它是什么、它做了什么,以及哪里出了问题。
上一篇:那个后来变成工厂的老虎机。下一篇:Designer Agent。
如需采取进一步行动,你可以考虑屏蔽此人和/或举报其滥用行为。