spike 验证通过:M3 经 new-api(openai+tools)agentic 自闭环产出可玩 A-model 游戏。 - harness game-runtime/tools/amodel-gen/(tools/play/m3/prompt/gen.mjs,零三方依赖): scaffold(clone _template)→ ReAct(read/write/list/check/build/done;done 门=check+build 绿; compaction + loop-detection)→ 循环外 play(headless Chrome boot+截图+交互 = 能跑能玩)。 - 3/3 玩法干净自闭环实证:打地鼠 / 陨石躲避 / 反应点击(13-22 步,175-378K token,play PASS)。 - skill .agents/skills/agentic-amodel-generation.md(链路/配方/8 坑/M3 实证/主流定性)+ README/AGENTS 索引同步。 - 设计 docs/agent-specs/2026-06-21-agentic-amodel-generation-design.md(§0 整链路 current→new + 四层 + §0.8 主流对照;draft 待 §6.8 双评审)。 取代旧 gamedef/factory 单次产线(A-model 生产形态);production 删 gamedef 待双评审(D1=A 无退路)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
21 KiB
topic, type, status, date, owner, origin
| topic | type | status | date | owner | origin | ||
|---|---|---|---|---|---|---|---|
| Agentic A-model 游戏生成 · 四层设计(自上而下) | design | draft(执行前过 §6.8 双评审) | 2026-06-21 | Mac 开发执行线 |
|
Agentic A-model 游戏生成 · 四层设计(自上而下)
为什么自上而下、prompt 最后:每层是下一层的地基——env(在哪跑/怎么隔离)→ harness(agent 有什么工具/怎么循环)→ context 拼装(agent 能读到/读什么)→ prompt(只是指挥 agent 用好上面三层的薄指令)。上一轮失败正是跳过前三层、直接手写 6.6KB prompt 硬塞(skill 全文 + api.d.ts + 范例 0 进 prompt + harness path bug)= 地基没打就盖楼。
方案 = B(agentic):给模型 read/write-file 工具,让它自己读 skill→读 api.d.ts→读范例→写多文件(catch-fruit 已证有能力 agent 行)。不用 A(单次塞满 prompt)。
§0 · 整条链路架构(current → new · 删 gamedef 留概念) — 2026-06-21 founder 定调
founder 三条定调(2026-06-21):① 可删旧 gamedef 生成代码;② 保留整体设计概念、重写整条链路;③ 模型只用 M3。 已验证前提(本日实测):M3 经 new-api(openai 协议)发 tool_calls 干净且快(1.8s,reasoning=0,并行 2 调用,参数正确)→ 方案 B agentic 成立。M3-only 使旧的「模型档阶梯(stage1/stage2/fallback)」塌缩为单档。
§0.1 现状 → 新架构 · 节点级映射(16 节点拓扑保留,generate 换芯)
| 节点 | 现状 | 新(D1=A 单一 A-model + M3 + agentic) | 动作 |
|---|---|---|---|
| render | init role/tier/counters | 同;tier 简化(仅 M3) | 改·简化 |
| classify | 品类→archetype+三维profile | 同,M3 | 留 |
| design | 单次 M3→设计稿+自产 gatespec | M3(可 agentic 读 design-skill) | 留·可增强 |
| generate | 单次 completion → iife OR gamedef JSON | agentic ReAct:M3 + read/write/list → 多文件 src/ |
重写·核心 |
| validate | iife 静态契约 OR gamedef build-from-source.mjs | A-model 静态:node --check × src/*.js + 五法契约 + host-config 导出 + 插件键一致 |
重写 |
| scaffold | 落 generated-factory.js + 模板 | 装配固定 plumbing(entry-bundle/index/assets-stub)环绕 agent 的 src/ |
改 |
| asset | 六类资产规格 | 同(spike 可 stub→标题底纹兜底) | 留 |
| build | esbuild build.mjs → bundle.iife.js | 同(--global-name=__GameBundle) |
留 |
| play | 九门 serve-and-play(A–E 客观门) | boot+截图+点击 = 能跑能玩(spike 暂丢九门) | 改·简化 |
| player | VLM 视觉+文本顾问 | M3 文本顾问(视觉待 M3 能力确认) | 留·spike 暂缓 |
| nreview | 叙事质量门 | 同 | 留·spike 暂缓 |
| modify | 改源路 | 同(spike 只走 create) | 留·spike 外 |
| repair | count++,feedback→generate | 同 | 留 |
| escalate | 升档 stage2 强档模型 | M3-only 模型档塌缩 → 重定义为 M3+thinking预算/温度升档,或并入 repair | 改·塌缩 |
| emit | 读 bundle→engineBundle,成功 | 同(→ GamePackage 契约,对下游不变的边界) | 留 |
| giveup | 终态失败完整 dump | 同 | 留 |
§0.2 新链路 · 系统架构(分层 ASCII)
┌─ 后端 game-cloud · SAA StateGraph(进程内 dispatcher=saa,Java)──────────────────┐
│ │
│ START→render→classify→design→[generate]→validate→scaffold→asset→build→play │
│ ▲ │ │ │
│ repair 回环 ◄─────────┴── validate/build/play fail ──┘ │
│ │ play pass │
│ giveup(终态失败) {player | nreview} │
│ │ ok │
│ emit(终态成功) │
│ │ generate:HTTP+工具循环 │ validate/build/play:ProcessBuilder│ emit │
└─────────┼───────────────────────────┼───────────────────────────────────┼────────┘
▼ (M3 ReAct) ▼ → node 脚本 ▼ GamePackage
┌──────────────┐ ┌─────────────────────────────────────────┐ ┌──────────┐
│ new-api 网关 │ │ 运行时 game-runtime(node · mini-desktop)│ │ 契约边界 │
│ 100.64.0.8 │ │ ┌───────────────────────────────────┐ │ │ game- │
│ **M3 only** │◄────►│ │ games/<id>/ ← 本次产物 │ │ │ package │
│ tool-calls ✓ │ 工具 │ │ src/{core,render,balance,game, │ │ │ .schema │
└──────────────┘ 读写 │ │ host-config}.js ← M3 写 │ │ │ →落库→ │
│ │ entry-bundle.js(__GameBundle) │ │ │ studio/ │
│ │ + index.html + assets stub │ │ │ feed │
│ ├───────────────────────────────────┤ │ └──────────┘
│ │ src/plugins/*(12) · core/*.d.ts │ │
│ │ build.mjs(esbuild)· serve+play │ │
│ └───────────────────────────────────┘ │
└──────────────────────────────────────────┘
§0.3 generate 节点 · agentic 内循环(四层 + 循环内 check/build 自检 / 循环外 play 权威门 —— 详见 §0.8)
下图 read/write/list 之外,工具集已加 check/build(循环内快反馈);done 门 = check+build 必须已绿;
play是 done 之后的循环外权威门(慢)。
╔═ L1 ENV · games/<id>/(scoped 写)· repo 只读 · M3@new-api · 无 shell ════════════╗
║ ║
║ ╔═ L2 HARNESS · ReAct 控制器(node,确定性)═══════════════════════════════════╗ ║
║ ║ ┌ L4 PROMPT(薄):角色+步骤+红线+完成判据;指 agent 读真 skill,不手抄 ┐ ║ ║
║ ║ │ system+brief ─► M3 ─► tool_calls? ─yes─► harness 执行 │ ║ ║
║ ║ │ ▲ │ read/write/list │ ║ ║
║ ║ │ │ 回喂结果/纠错 no(done) └ L3 CONTEXT:按需读 ┐│ ║ ║
║ ║ │ └───────────────────┼──── code-skill→api.d.ts→catch-fruit ──┘│ ║ ║
║ ║ └────────────────────────── ▼ done/max-steps ───────────────────────┘ ║ ║
║ ║ build.mjs ─► serve ─► play(boot+截图+点击)─► verdict(能跑能玩?) ║ ║
║ ╚═══════════════════════════════════════════════════════════════════════════╝ ║
╚═════════════════════════════════════════════════════════════════════════════════╝
§0.4 单次生成作业 · 流程图(repair/giveup 分支)
brief
└► render ─create─► classify(品类→archetype) ─► design(M3 读 design-skill → 玩法设计 + gatespec)
│
┌──────────────────────────────────────▼─────────────────────────────────┐
│ generate(agentic M3):读 code-skill + 用到插件 api.d.ts + catch-fruit 范例 │
│ → 多轮工具写 src/{core,render,balance,game,host-config}.js │
└──────────────────────────────────────┬─────────────────────────────────┘
▼
validate(A-model 静态:node --check + 五法契约 + host-config + 插件键)
│ ok │ fail
▼ ▼
scaffold(固定 plumbing) ──► asset ──► build repair(count++,feedback→generate)
│ ok │ fail ▲ repairCount<max? ─是
▼ └────────┴── 否 ─► giveup(终态失败 dump)
play(boot+截图+点击 = 能跑能玩)
│ pass │ fail ─► repair
▼
[player / nreview 质量门 · 生产保留 / spike 暂缓]
▼
emit(读 bundle → engineBundle → GamePackage,成功)
§0.5 删除候选清单(D1=A · 执行时须过 §6.8 双评审 + grep 复核,本设计不删)
- gamedef 表示层(核心删除):
game-runtime/src/host/gd-runtime.js(声明式 runtime +new Functionbehavior)、build-from-source.mjs(JSON→factory 装配器)、二者*.test.mjs—— A-model 无 gameDefinition、无new Function,这一层整体退役。 - factory(iife)路分支:
SaaPrompts的SYSTEM(iife 形状)与GAMEDEF_SYSTEM二选一 → 收敛为单一 A-model system;buildGameDefMessages/ factorybuildRegenerateMessages按需清。 - Python worker 全套(D6=A,SAA 进程内已接替):
wg1/gen-worker/worker/{service,run,validate,prompt}.py、agent_loop/{studio,roles}.py、gamedef_quickcheck.py。 - 死契约:
contracts/prompts/(SaaPrompts 已为 SSOT)、contracts/agent-loop/(Dify workflow,SAA 图接替)。 - 配置开关:
AigcExecutorProperties.saaSourceMode(factory|gamedef 二选一)→ 删,单一 A-model 路;saaModelProtocol视 M3 走 openai+tools 可简化(thinking 节点如需另议)。
§0.6 保留概念清单(重写但不丢的设计骨架)
16 节点图拓扑(generate 换芯)· repair 回环 · checkpoint 续跑(MysqlSaver)· observation 可观测 · feedback 回喂闭环(validate/build/play 失败皆回喂)· token 拆账(总量+per-model+per-attempt)· play 客观门(九门概念,spike 暂以"能跑能玩"代替)· 五法工厂契约(game-host.d.ts:init/update/render/destroy/_forensicsView)· 受控面铁律(time/random/引擎/输入皆经 ctx)· emit→GamePackage 作为对下游(studio/feed)不变的契约边界。
§0.7 建设次序(spike 先证,production 后删 —— D1=A 无退路铁律)
- spike(独立 node harness · mini-desktop):按 L1→L2→L3→L4 建 agentic generate + validate + build + play(能跑能玩),用 M3 端到端跑通 catch-fruit 级别游戏。不碰 SAA Java、不删 任何 gamedef 代码。
- production rewrite:spike 过 → 把 agentic generate 节点端口进
SaaStudioGraph,按 §0.5 删 gamedef/factory,validate/play 换 A-model 版。此步过 §6.8 Codex+Opus 双评审后才执行删除。 - 不过则:补 skill/工具/context,绝不先删退路。
§0.8 主流 agentic 对照 + 本设计定性(2026-06-21 评审确认)
基准:Anthropic《Building Effective Agents》《Effective context engineering for AI agents》《Writing effective tools for agents》、SWE-agent 的 ACI(Agent-Computer Interface)、ReAct。
- 四支柱对照:主流 = 环境/工具(ACI)· agent 循环(ReAct)· context 工程 · 记忆。本设计:L1 + L2 工具 = 环境/ACI(✅ 最小工具集、沙箱最小权限);L2 = ReAct 循环(✅,M3 已实测发 tool_calls);L3 + L4 = context 工程(⚠️ 主流把 prompt 视为 context 子项;本设计尚缺"长循环压缩");记忆 = ❌ 暂无(单局生成可弱化)。
- 定性(Anthropic taxonomy):整张 SAA 图 = orchestrator workflow;generate 节点 = 内嵌 agentic(ReAct);repair 回环 = evaluator-optimizer。这是 Anthropic 明确推荐用于可预测生产管线的组合("要可预测用 workflow,全自治留给真需要灵活性处")。本设计属受约束 agentic 流派——主流且被推荐,非缺陷。
- 已采纳的关键修正:把验证从"循环外"补一半进"循环内"——给 agent
check/build工具 + done 前自检门(§0.3)。理由:便宜模型最常死在它看不见的语法/API 错;in-loop 编译反馈是主流让弱模型成功的头号技巧,直接服务 spike 目标;慢的真玩仍留循环外作权威门。 - 按需补的 3 缺口(非 spike 阻塞):① agent scratchpad/todo(外化计划,弱模型受益);② 长循环 context 压缩(文件累积撑爆时:压缩/子代理/清旧 tool 结果;M3 上下文大可暂缓但要有上限保护);③ 停机:
max-steps已有,补 loop-detection + token/预算上限。
L1 · Environment(环境 / 沙箱)—— 最先建
目标:干净、可复现、隔离的运行沙箱;生成 + build + play 都在里面,跑崩不污染 repo/live。
| 关键决策 | 方案 |
|---|---|
| 在哪跑 | mini-desktop(100.64.0.7):node22 + Chrome146 + java17 + new-api 内网可达(已验);ssh 直连 ssh -o ProxyCommand=none root@100.64.0.7 + Bash dangerouslyDisableSandbox(别名→死代理 198.18.0.7) |
| 隔离单元 | 每 run 一个 git worktree 或 Docker 容器(repo 副本 + 锁分支 feat/mac-amodel-foundation);轻量起步可先「scoped 目录 + 端口隔离」 |
| 文件边界 | agent 的 write 工具只许写本 run 的 game 目录(games/_spike-<id>/);read = repo 只读;不给 agent 任意 shell |
| 命令边界 | build(esbuild)/ play(Chrome 九门/或 boot+截图)由 harness 跑,非 agent;端口错开 live :48080(4320/9222) |
| 凭据 | new-api key + base 经 env 注入(docs/内网凭据与端点.md) |
| 可观测 | 全程一个 run 日志(agent 每步工具调用 + build + play),founder 可 tail;SAA app 日志 = /root/game-staging/app.log |
依赖:无(最底层)。先建好它,后面才有地方跑。
✅ L1 实测结论(2026-06-21,mini-desktop):用已知可玩的 catch-fruit 当控制——build(esbuild,220KB,引擎 inline)+ boot + play(真引擎、水果下落、HUD 活、截图确认)全通 → build/play 基础设施对 A-model 游戏成立。recipe 已得。
🔑 harness 形态决策(L1→L2 关键,基于 recipe):
- 目录:run 落
games/amgen-<id>/(直接在games/下,与 catch-fruit 同深度 → 插件 import 用../../../src/,与 catch-fruit 范例逐字一致,根除路径深度坑);gitignore。 - 形态 = catch-fruit shape(多文件
src/),不用_wg1-gen旧的单文件generated-factory.js(那是 factory 单文件路,与 A-model 多文件矛盾;且嵌进_wg1-gen/<id>/src会变 4-up 触发深度坑)。 - 固定 plumbing(harness 写,不让 agent 碰):
index.html+entry.js+src/main.js,固定全局名__AModelGame+ 固定 boot 标记(__gameBooted/__gameHost/__gameForensics);agent 只产src/{host-config,game,core,render,balance,assets}.js,约定host-config.js导出固定名buildHostConfig、game.js默认导出工厂、update(dt)内调opts.runtime.bundle.tick(dt)。 - play = 轻量 CDP(serve + headless Chrome boot + 截图 + 一次 tap + 读
__gameForensics状态 = 能跑能玩),不复用serve-and-play.sh九门(founder 已弃九门;且它硬编码_wg1-gen布局)。 - build(locked esbuild,不改):
node scripts/build.mjs games/amgen-<id>/entry.js games/amgen-<id>/dist/bundle.js --global-name=__AModelGame(cwd=game-runtime)。
L2 · Harness(编排循环 + 工具框架)
目标:确定性控制器,驱动「agentic 生成 → 装配 → build → play → verdict」,并定义 agent 的工具。这就是项目延期的 ReAct 生成节点的 spike 版;验通后端口进 SAA generate 节点。
| 关键决策 | 方案 |
|---|---|
| 工具集(给 agent) | read_file(repo 只读)、write_file(scoped run 目录)、list_dir、check(node --check × src/*.js + 五法/host-config/插件键静态 lint)、build(esbuild,秒级);无任意 shell。经 new-api function-calling 暴露(M3 已实测支持) |
| ✅ 可行性(已验证) | M3 经 new-api(openai 协议)发 tool_calls 干净且快(1.8s,reasoning=0,并行 2 调用,参数正确)——agentic ReAct 成立,无需回退伪 agentic |
| agent 循环 | system+brief → M3 发 tool_calls → harness 执行(读/写/check/build)→ 回结果 → 循环至 agent done 或 max-steps;done 门:check + build 必须已绿;越界/读不到/check 失败 → 回喂纠错 + loop-detection 防卡死 |
| 装配(固定 plumbing) | run 目录预置:entry-bundle.js(暴露 __GameBundle.bootGameHost,用 per-game host-config 而非 generic 壳)+ index.html(play 模板)+ src/assets.js stub;深度 = games/<id>/(治路径 bug:import 插件用 ../../../src/plugins);agent 只产 src/{core,render,balance,game,host-config}.js |
| 收口(循环外权威门) | agent done(已自 build 绿)→ play:serve + 无头 Chrome boot+截图+点击(bar=能跑能玩,暂丢九门)→ 存 verdict/截图/日志;fail → repair 回 generate |
| 多 run | 循环 briefs(模型固定 M3)→ 汇总过率/失败模式 |
依赖:L1(先有沙箱才能定工具边界)。
L3 · Context 拼装(agent 读什么 / 怎么读)
目标:让 agent 拿到充足但不过量的 context(治上一轮"skill 没加载")。agentic 让 skill 的指针生效(agent 按需读文件)。
| 关键决策 | 方案 |
|---|---|
| 两阶段 | design 阶段(读 sim-business-game-design.md → brief 变具体玩法设计:核心循环/机制/解锁/数值/插件清单/反无趣自检)→ code 阶段(读 littlejs-game-dev.md + 选用插件 api.d.ts + catch-fruit 范例 → 写多文件实现该设计) |
| 按需读、别全读 | skill 指引"用 X 插件就读 src/plugins/X/api.d.ts";一份完整范例(catch-fruit)即可,不读全 12;控 token |
| 必读锚点(prompt 点名) | ① 两份 skill ② game-host.d.ts(工厂五法契约)③ games/catch-fruit/(唯一完整范例)④ 用到插件的 api.d.ts |
| skill 生成可用度 | 已是指针式,agentic 下够用(agent 能读到指向的文件);若 agent 反复踩同一坑(如某 API),再把那条 inline 进 skill |
依赖:L2(先有 read_file,agent 才能读)。
L4 · Prompt(薄指令层)—— 最后写
目标:最薄的指令,指挥 agent 用好 L1-L3。绝不手抄 skill(上一轮的错)——指 agent 去读真 skill。
system prompt 骨架:
- 角色:你是 A-model 游戏生成 agent;产物 = 本 run 目录
src/下多文件 LittleJS 游戏。 - 步骤:读 skill(你的 manual)→ design(读 design skill)→ 读用到插件 api.d.ts + catch-fruit 范例 → 写
src/→ 自检。 - 工具:read_file / write_file(scoped)/ list_dir。
- 红线(精炼):工厂默认导出 + 零引擎 import;零裸
Date/Math/setTimeout;render 画在 g;timer 经 timer-scheduler + update 内runtime.bundle.tick(dt);host-config 导出buildHostConfig返{factory,plugins,registerOrder,viewport,buildFactoryOpts};插件键名与 game.js 解构一致。 - 完成判据:harness build 过 + 能 boot + 能玩。
依赖:L1+L2+L3 全定好。
建设顺序(= 创始人定)
L1 环境 → L2 harness → L3 context 拼装 → L4 prompt,每层验通再下一层。验证策略:先用能力够的模型把 agentic 端到端跑通(确认 harness/工具/context 对)→ 再逐级换便宜模型测经济性(bar=能跑能玩)。过 = 才动 SAA 删 factory/gamedef(D1=A 无退路);不过 = 补 skill/工具,绝不先删退路。