- ② prompt治理:加 canonical frontmatter;§5 新增"目标态:采 Langfuse 式运行时热取" (按 id@label 运行时拉取+缓存TTL+后台刷新+回落,替构建期 maven 快照反模式; 四道闸治理纪律不变;对齐 SoT① A13) - ③ 验收门:验收门-W-G1.md → 验收门.md(git mv);加 canonical frontmatter (topic=对外开闸放行);修 3 处改名断链(生成引擎图说/OpenGame对照/WG1基准) - ④ 数据飞轮:加 canonical frontmatter(保留) - SoT① §5.4 指针校准:验收门=开闸放行6门(坐九门之上),九门护城河命题即在 §5.4+A5 - canonical 唯一性:4 topic 各一份,预检通过 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
298 lines
62 KiB
Markdown
298 lines
62 KiB
Markdown
---
|
||
title: agentic 生成运行时架构 — 可插拔 agent 平台
|
||
status: 架构演进中 · 现状已 grounded;"采标准"方向为提案(待 §6.8 双评审最终拍板)
|
||
canonical: true # 生成运行时架构唯一 SoT,收敛原 16 份图说/详设/接口协议草案
|
||
topic: 生成运行时架构(adapter + 可插拔 agent 框架 + 两生成实例)
|
||
date: 2026-06-24
|
||
---
|
||
|
||
# agentic 生成运行时架构
|
||
|
||
> **定位**:绘境AI 游戏生成的统一运行时架构,单一事实源。把"谁来生成"(agent 框架)和"生成什么、怎么验收、怎么落库"(平台契约)彻底分开:平台只认一层 adapter,框架在 adapter 背后可换、可并存、可水平扩容。本文收敛原先散在十余份图说与详设里的设计,采用 2025 年已收敛的业界标准作 adapter 底座,自研只保留两块主流空白——生成专属的断点续跑、确定性验收门。
|
||
>
|
||
> **给谁看**:判断"整个生成架构是不是想要的那个"的创始人;照此实现的工程师。
|
||
>
|
||
> **本文不含什么**:实现代码、文件行号、提交哈希。那些只在代码文件里,配完整中文注释与日志。本文只到数据模型、接口协议、类名这一层。
|
||
|
||
---
|
||
|
||
## 一、命题与定位:可插拔的 agent 平台
|
||
|
||
绘境AI 的游戏生成正在从一条线长成两条。一条是已经在生产里跑的**廉价线**:便宜模型经 new-api 网关、由 SAA(Spring AI Alibaba)裸图编排,产物落在 LittleJS 增强发行版上,过九门兜底,目标是低成本批量产出不同质化的高质轻游戏喂进大众 feed。另一条是 **tier2 富游戏线**:一个自治的 ReAct agent(AgentScope 框架)去造廉价线做不出的多系统富游戏,产物是真 Phaser 源工程。两条线还会继续分叉——引擎可能从 LittleJS 换到 Phaser、Pixi,编排框架可能从 SAA 换到 AgentScope,乃至将来接 dify、coze 或自训框架。
|
||
|
||
如果每换一次引擎或框架,就要改一遍业务侧调用、改一遍验收门、改一遍落库,这套东西就废了。所以平台的第一原则是划一条线:哪些是**系统内固定的接口协议**,任何人换引擎换框架都不许动;哪些是**可插拔的实现模块**,换引擎换框架就是换它们。换框架等于接一个新 adapter,而不是动契约。这就是"可插拔 agent 平台"的全部含义——平台拥有协议,框架只租用、不拥有。一旦某个框架的私有结构悄悄渗进固定协议(轨迹格式被某框架的 span 绑死、任务协议泄漏框架内部状态),那就是锁死的开始,要立刻在协议层把它隔离回去。
|
||
|
||
这条原则不是空谈"将来好换",它有具体落点:它正是将来要不要把某条轨从 SAA 切到别的框架时的判据。只要固定协议稳稳钉在那里,切换就只是换一个被治理的执行后端,而不是推倒重来。
|
||
|
||
**两块不外包的自研——这是护城河。** 采标准能解决绝大多数适配问题(见 §二),但有两件事没有主流对等物,必须自建:一是**确定性验收门**——在没有人、也没有看图模型的情况下,用纯代码机器判定一局游戏"真的可玩",判定权与"出题的和被考的绝不能是同一只模型"这条纪律不让步;二是**生成专属的断点续跑语义**——一次自治生成跑到哪、能否按平台口径续上,各框架自造、互不通用。这两块是平台真正的工程纵深,别人短期补不上。
|
||
|
||
---
|
||
|
||
## 二、采标准:仓内自研 vs 2025 收敛标准
|
||
|
||
要的"可插拔 agent 平台 / adapter",在 2025 年已经被业界标准化了:任务与状态有 **A2A**,工具与 skill 有 **MCP / SKILL.md**,trace 有 **OpenTelemetry GenAI**,三者全部收敛进 Linux Foundation 的 Agentic AI Foundation;沙箱有 **microVM 沙箱**(E2B、阿里云 AgentRun),长跑扩容有 **durable-execution**,prompt 热管理有 **Langfuse 式运行时热取**。
|
||
|
||
一个最重大的对标发现:**没有任何主流平台真支持"换底层 agent 框架"**——Dify、Coze、LangGraph、AutoGen、ADK、OpenAI SDK 全是"我即终点框架,只让 model 和 tool 可换"。但"框架可移植"的主流正解,恰恰就是采用上面这些标准:微软 Agent Framework 1.0(2026-04 GA)就是靠 MCP + A2A + OTel 实现跨运行时可移植。所以"框架可替换"这个目标对,但方法应当是"采标准",而不是"自研一套 adapter"。下表把仓内自研逐项对到它真正对应的标准(均经源码级验真):
|
||
|
||
| 仓内自研 | 它其实是 | 2025 收敛标准 | 判定 |
|
||
|---|---|---|---|
|
||
| 任务协议(dispatch / cancel / progress / callback) | 任务提交、取消、查进度 | **A2A**(Task 生命周期 + send/get/cancel/list/subscribe) | **采 A2A** —— 白得 cancel、状态机、流式、发现 |
|
||
| 状态机(submitted / working / … / failed) | 任务状态枚举 | **A2A TaskState** | 采 A2A 状态语义 |
|
||
| trace(推理 / 动作 / 观察三段) | ReAct 三段轨迹 | **OTel GenAI semconv**(invoke_agent / chat / execute_tool + ReasoningPart + usage.*) | **采 OTel**(钉版本 + adapter 隔离);成本钉 new-api 计费行(OTel 无成本属性) |
|
||
| 工具签名(write / build / run_gates / finish) | agent 工具接口 | **MCP**(Tool inputSchema / outputSchema + structuredContent + Task 原语) | **MCP-native** —— run_gates 输出即 verdict outputSchema,慢门用 Task 原语 |
|
||
| skill(自定义 / 框架私有) | agent 专长包 | **SKILL.md**(agentskills.io 开放标准) | 采开放标准 frontmatter |
|
||
| 沙箱(固定端口 CDP) | 隔离的 build + run 环境 | **microVM 沙箱**(E2B Firecracker / 阿里云 AgentRun·AIO Sandbox 神龙+RunD MicroVM) | **采 microVM 沙箱抽象** —— 每 run 独立 microVM 消解端口撞车,实现可切 AgentScope-local / E2B / 阿里云 AgentRun |
|
||
| 水平扩容(K-槽 Semaphore + 进程内端口槽) | 长跑 agent 并发 | **durable-execution**(无状态 worker + 共享 checkpoint + 队列 + cancel 通道) | K-槽是单 JVM 反模式;搬成无状态 worker + 共享 saver |
|
||
| prompt / model 配置 | 配置注册 + 热改 | **Langfuse 式**(registry + 运行时热取 + 缓存 TTL + config-as-data) | 采;后端构建期快照是反模式,tier2 热配是雏形→推广主线 |
|
||
| 验收门(judge 纯代码、禁 LLM 自评、出题≠被考) | 确定性验收 | **无主流对等** | **自研 —— 护城河,必须自建** |
|
||
| checkpoint / 续跑 | 生成专属续跑 | **无跨框架标准** | **自研合理** |
|
||
|
||
收敛后的架构是"采标准 + 瘦身自研":adapter 退化成三个标准端点加两块自研。
|
||
|
||
```
|
||
周边服务(13 后端模块 / runtime / feed / pay / 素材 / 审核 …)
|
||
↕
|
||
┌────────────────────────────────────────────────────────────┐
|
||
│ adapter = 三标准端点 + 两块自研 │
|
||
│ · A2A server ← 任务提交 / cancel / 状态 / 流式 / 发现 │
|
||
│ · MCP server ← 工具(write / build / run_gates / finish)+ 资产/模板 │
|
||
│ · OTel GenAI ← trace(invoke_agent / chat / execute_tool) │
|
||
│ · 〔自研〕生成 checkpoint / 续跑语义 │
|
||
│ · 〔自研·护城河〕确定性验收门(judge 禁自评 + per-tier verdict) │
|
||
└────────────────────────────────────────────────────────────┘
|
||
↕ 标准端点(框架只要会说 A2A+MCP+OTel 即插入)
|
||
可插拔 agent 框架:SAA(廉价线) / AgentScope(富游戏线) / 未来 dify·coze
|
||
沙箱 = microVM 沙箱抽象(每 run 独立 microVM、暴露 CDP);扩容 = 无状态 worker + 队列 + 共享 checkpoint
|
||
```
|
||
|
||
"框架适配器"于是瘦身成一件事:**把 SAA、AgentScope 各包成一个 A2A + MCP + OTel 端点**。换框架、加引擎、接第三方 agent,等于让它会说这三个标准,周边零改。
|
||
|
||
> **状态与评级**:本节"采标准"方向触及生成平台基石(build-vs-buy 翻转),属高风险,作为提案待 §6.8 双评审(Codex + Opus)最终拍板后,据以收口下面 §三 的协议定级。所有"采标准"建议均带源码级对标证据。沙箱选型来源(2026-06-24 验证):[阿里云 AgentRun](https://help.aliyun.com/zh/functioncompute/fc/what-is-agentrun) · [AIO Sandbox](https://help.aliyun.com/zh/functioncompute/fc/aio-sandbox) · [AgentScope Runtime Sandbox](https://runtime.agentscope.io/en/sandbox/sandbox.html)。下面 §三 把每条 A 协议对到它采的标准,并如实标"现 / 建 / 待定"。
|
||
|
||
---
|
||
|
||
## 三、adapter 协议层
|
||
|
||
协议分两类。**A 类是固定接口协议**——换框架、换引擎都不许动,是业务侧与生成执行后端之间认的那个接口签名、那份状态 schema、那份 verdict schema。**B 类是可插拔实现模块**——换引擎换框架就是换它们。判断一样东西归哪类,问一句:换框架 / 换引擎时它变不变?不变(业务侧调用、状态口径、判定纪律)进 A 类;变(某引擎怎么读帧、某框架怎么存状态)进 B 类。
|
||
|
||
### 3.1 划线五原则
|
||
|
||
1. **契约固定、实现可插拔。** 固定的是"形状"——接口签名、状态 schema、verdict schema;可插拔的是"形状背后由谁去满足它"。SAA 实现一遍任务协议,AgentScope 再实现一遍;LittleJS 实现一套探针,Phaser 再实现一套。
|
||
2. **契约不做成 skill。** skill 本质是"喂给 agent 的指令 + 资源包",自身不执行代码,agent 可读可不读。把硬约束写成 skill,等于降格成提示。固定协议必须落在机器可校验的载体上:JSON Schema、`.d.ts` 接口、Java interface、纯代码的 judge 判定。skill 只承载"怎么用某个引擎写游戏"这类 playbook,不承载"完成与否谁说了算"这类纪律。
|
||
3. **门探针劈两半。** "门要从引擎读哪几样"(canvas 选择器、帧计数源、boot 就绪信号、输入注入、可观测 state)是引擎无关的抽象,该固定;"怎么从某个具体引擎把这几样读出来"是 per-engine 的实现,该可插拔。判 pass / fail 的逻辑永远待在固定层、由纯代码产出,探针只负责"读"和"驱动",绝不负责"判"。
|
||
4. **多语言走 MCP / shell-out。** 单写 agent 跑在 Python,但探针是 node/CDP、构建是 esbuild、某些能力包可能是别的语言。跨语言不靠在 Python 里硬塞,走两条标准通道:MCP 协议天生跨进程跨语言;或 skill 目录放任意语言脚本、SKILL.md 指示 agent 用内置 Bash shell-out 去跑。
|
||
5. **单一实现时不冻接口(rule-of-three)。** 一个接口只有一套真实现时把形状钉死,必被那唯一一套实现反向决定,等第二套落地才发现抽错。所以第一套实现先定 v1 directional(方向性草案 + 留演进位),真正冻结推迟到第二套实现落地。这条直接影响 A6 / A7 的定级——它们现在只有 LittleJS 一套真实现,不该被当成已冻结的协议。
|
||
|
||
### 3.2 A 类:固定接口协议
|
||
|
||
下表是固定协议目录。"形状"列给数据模型与接口签名;"现 / 建"列分清哪条已被代码兑现、哪条还是设计意图;"采标准 / 自研"列接 §二 的对标结论。**A1–A7 是生成执行段的接缝**(提交生成 → 跑 ReAct → 过验收门 → 装载进浏览器),**A8–A13 是平台面接缝**(送审、资产、模板、试玩、通用检查、配置)。
|
||
|
||
| 编号 | 协议 | 形状(数据模型 / 接口) | 现 / 建 | 采标准 / 自研 |
|
||
|---|---|---|---|---|
|
||
| **A1** | 生成任务协议 | `GenerationDispatcher.dispatch(job)->bool` 投递握手 + 回调边;`GenerationRequest{ brief, confirmedGoal, assetContext, tier(0/1/2), idempotencyKey }`;待建 `cancel(taskId)` / `progress(taskId)->status` | 现(dispatch 单方法 + 回调)+ 建(cancel / progress) | 采 A2A |
|
||
| **A2** | 生成状态 + checkpoint | `GenerationState{ traceId, phase/step, cur_iter, tasks_context, cost, checkpointId }`;续跑按 traceId 取 checkpoint,须显式传 checkpointId(saved_at 无 tiebreaker) | 现(SAA 侧)+ 建(显式 GenerationState v1) | 状态枚举采 A2A TaskState;**checkpoint / 续跑自研** |
|
||
| **A2.5** | 统一 trace 契约 | 平台 trace 信封`{ traceId, step, cost, verdict, ts + 扩展段:推理/动作/观察 }`;成本权威钉 new-api 计费行,trace 只携关联键、不让 agent 自报金额成账 | 建(不存在,反锁死链上最该先立) | 采 OTel GenAI semconv |
|
||
| **A3** | 源项目契约(tier2) | `tier2-source-project.schema{ projectType:'tier2-engine', fileTree, entry, buildProfile, depLock, contentHash(sha256), addressing }`;最小 keystone = projectType + contentHash + fetchById | 建(新立 schema,keystone 先行) | 自研(沿用 sha256 落库范式) |
|
||
| **A3.5** | 源项目版本寻址 | sourceHash 寻址 + versionId 版本化;改源重建产新版本、旧版本仍可取回 | 建(不存在) | 自研 |
|
||
| **A4** | 装载协议 | `game-host.d.ts`:`GameHostBootContext{ ctx, mainContext, canvas, seed, assets? }`、`GameInstance{ init, update(dt), render(g), onInput?, destroy }`、`GameHostFactory`;终态焊成可轮询 latch、宿主每帧轮询读 | 现(ECS-lite 左支)+ 建(tier2 右支) | 自研 |
|
||
| **A4.5** | 构建产物 + feed→play 入口 | 构建缓存键`buildInputHash = sha256(sourceHash + buildProfile)`;`engineBundle` 可执行 iife;feed 卡片按 engineBundle 存在性 / tier2 projectType 分流装载 | 现(部分载体)+ 建(tier2 分支) | 自研 |
|
||
| **A5** | 验收门协议 | verdict 元协议`{ decision:accept/fix/kill, severity, 机器判 + 禁自评 }` + per-tier schema(Tier0/1 现行 / tier2 fork);三层校验 L1 硬约束必解 / L2 设计符合尽量 / L3 效果只评分不阻塞 | 现(元协议 + 左支 schema)+ 建(tier2 fork schema) | **自研 —— 护城河** |
|
||
| **A6** | 探针钩子抽象接口 | `EngineProbeHooks{ canvasSelector, frameSource()->number, bootReadySignal()->bool, injectInput(tap/key/drag), readState()->GameState }`;引擎级量 per-engine,富游戏语义 state per-品类 | 现(LittleJS)+ 建(Phaser) | v1 directional(第二实现后冻) |
|
||
| **A7** | agent 工具签名 | `write_source(files[])`、`build(profile)->bundle`、`headless_check()->quickVerdict`、`run_gates(spec)->Verdict`、`read_verdict()->Verdict`、`screenshot()`(只取证)、`query_assets(spec)->assetRefs`、`scaffold_init(template)`、`finish(sourceProject)`;finish 形状 = A3 | 建(v1 directional) | 采 MCP(第二实现后固化) |
|
||
| **A8** | 送审 / 审核协议 | `evaluate(ComplianceGateReqDTO{ gameId, versionId, title, summary, ageRating, promptHash })->GateVerdict{ verdict:pass/review/block, rating, detail[] }`;合规门 verdict ≠ 人工审核 `decision(1通过/2拒绝/3下架)`,两段串联 | 现·部分(Tier0/1 单线硬编码)+ 建 | 自研(同进程接缝) |
|
||
| **A9** | 资产协议 | `assetSpec{ id, category(sprite/character/effect/scene/ui/music), ref, url, provider }`;须补`{ license, ownership, identity }` + 资产血缘;provider = 可插拔接缝 | 现·骨架 + 建(护城河字段缺失) | 自研 |
|
||
| **A10** | 玩法模板协议 | templateId 白名单(generic / business-sim / narrative / puzzle / trpg / heritage)+ prompt md + bundle 校验 schema;`getTemplateList()->TemplateRespVO`;模板 schema 与 A5 的 structureOk 耦合 | 现·部分(编译期常量)+ 建(结构 schema) | skill 采 SKILL.md;注册迁 A13 |
|
||
| **A11** | 试玩 / HITL 迭代 | 装载复用 A4;`StudioModify{ baseVersionId, mode:deterministic/regenerate-module, target, payload }`;三档反馈回路(确定性覆写 / 模块重生成 / 整体重设计) | 现·部分(装载复用 A4)+ 建(反馈回路) | 自研 |
|
||
| **A12** | 通用检查门协议 | 提交侧(prompt 内容安全,fail-closed)+ 产物侧(体积门 / 逻辑扫描 / CSP),两时相、共用一道引擎无关门外壳 | 现·散三处 + 建(收成一门) | 自研 |
|
||
| **A13** | 配置注册表协议 | model / prompt / skill / mcp 四类统一注册;分流判据 = 影响生成质量/安全(prompt、生成门阈值)走 GitOps 四闸不可热改,运营降级开关/阈值走 DB 热改 | 建(代码侧零落地) | 采 Langfuse 式运行时热取 |
|
||
|
||
A8–A13 这六面的共同状况:廉价线在生产里已把它们大多兑现,但都硬编码在单条 publish 链路上,从没抽成"两条生成线 + 各发行渠道共用"的固定接缝。这一轮不是从零造协议,而是把已长出来、却埋在单线实现里的接缝形状抬出来固定,并诚实标出哪几段已兑现、哪几段还空白。
|
||
|
||
### 3.3 B 类:可插拔实现模块
|
||
|
||
B 类对接上面某几条 A 协议,换引擎 / 换框架 / 换渠道时被换掉。按四条轴组织。
|
||
|
||
**换引擎轴——引擎能力包 + 探针实现。** 引擎能力包给 agent 提供在某引擎上写游戏的全套能力:写法 playbook(skill)+ 引擎文档范例(RAG 语料)+ 脚手架工程骨架 + 验收门探针的该引擎钩子实现。探针实现只兑现 A6(读帧 / canvas / state / 注入输入),绝不碰 A5 判定。
|
||
|
||
- `B-ENG-LittleJS`(现,廉价线在跑)/ `B-PROBE-LittleJS`(现,九门 harness 生产已跑、判过大量游戏)
|
||
- `B-ENG-Phaser`(建,tier2 富游戏首批真实现)/ `B-PROBE-Phaser`(建,Phaser 四钩子重写,是 A6/A7 的第二套实现——它落地才把抽象接口从 v1 固化)
|
||
- `B-ENG-Pixi`(桩,第二引擎,逼出通用接口)、`B-ENG-Cocos`(future,退回 3D / 渠道导出 / 人在环轴,不在自治循环)
|
||
|
||
**换框架轴——框架适配器。** 把一套自治框架接到平台五条固定协议上:实现任务协议、状态模型、工具接口、服从验收门、映射遥测。它吃平台的固定协议,用框架机制去满足。换框架 = 重写这一个适配器,A 协议不动。
|
||
|
||
- `B-FRAMEWORK-SAA`(现,廉价线裸图编排)、`B-FRAMEWORK-AgentScope`(建,锁 2.0.2,经 Agent Service 接 A1)
|
||
|
||
**换渠道 / 资产 / 品类 / 合规轴——平台面可插拔件。**
|
||
|
||
- `B-CHANNEL-wechat / douyin / kuaishou / taptap`(建,发行侧渠道 adapter,接 A8 下游;不在生成循环内)
|
||
- `B-ASSET-mmx`(现,默认 provider)/ `B-ASSET-MARKET`(建,可交易素材市场)/ `B-ASSET-3RD`(建,第三方源);经 provider 字段路由,消费侧 query_assets 不变
|
||
- `B-TPL-<品类>`(现:5 品类 prompt-md 形态 / 建:RAG 语料、模板 DB 表;模板是品类框架引导生成,不是 pre-built 整局代码)
|
||
- `B-COMPLIANCE-ATOM-style / ip`(桩,compliance 模块内同进程可替换 Java 实现,聚合取 max;不宜改成异步 MCP——会破坏 evaluate 同步语义)
|
||
|
||
> **机制依据**(AgentScope 2.0.2 源码实证):skill = 含 SKILL.md 的目录,frontmatter 携 name + description,经内置 SkillViewer 回灌正文给 agent,自身不执行代码——这是"契约不做成 skill"的硬依据。tool = agent 能直接 call 的最细执行单元(进程内 Python 经 `FunctionTool` 薄壳 / 跨进程经 `MCPTool` / 内置 Bash·Read·Write)。MCP 完全语言无关(Stdio 子进程或 HTTP),`command` 可以是任何语言的 server。探针(node/CDP)从 Python agent 跑起来靠 skill + Bash shell-out 或 MCP。
|
||
|
||
---
|
||
|
||
## 四、两实例
|
||
|
||
两条生成线是同一套 adapter 协议的两个实例,运行期零耦合,只在公共组件(计费 / 送审 / feed / 验收基线)交汇。
|
||
|
||
> 全局两线与 tier 体系总览:`assets/07-全局两线与tier体系.svg`。
|
||
|
||
### 4.1 实例一:SAA · LittleJS 廉价线(Tier0/1)
|
||
|
||
**范式**:便宜模型先吐一份结构化游戏定义,平台用确定性运行时去解释它,再用九门把"是不是真能玩"判定下来。产物落 LittleJS 增强发行版。
|
||
|
||
**创作入口已开闸为一句话直接驱动**:创作页不再强制先选模板,生成请求的 templateId 可选、缺省走 generic 通用路,玩法模板退化为可选的品类引导框架(经营 / 剧情 / 解谜 / TRPG / 非遗五品类,影响 prompt 与脚手架、不是可执行的游戏壳,旧"填参整局代码"产线已废,见 §三 A10)。这条主链贯通后,廉价线的端到端闭环是:创作页一句话 → 经 D12 配额与提交侧合规先行两道入口门(见 §5.2、§5.4)→ generic 的 SAA 生成路 → 轮询进度 → 过发布门入游戏 feed → 种子用户真人试玩。发布门走管理员审核台还是创作者自助直发是产品待裁项,种子期建议管理员把关。
|
||
|
||
**它聪明在哪,该坚持**:把随机、时间、输入全部收进受控种子;把胜负置成不可逆 latch 终态;把游戏世界投影成测试侧可按命名路径读取的取证形状。这三件合起来,九门 harness 才能用确定性对照"真玩一局并判定"。这是别人短期补不上的——竞品大多能让模型吐出能跑的代码,却无法机器化地证明它可玩。把"出图"整个从模型手里拿走(渲染器按 render 组件自动画、behavior 只写逻辑碰不到画面)也消掉了便宜模型最高频的三个 bug 源。
|
||
|
||
**它的天花板,要诚实**:对抗式裁决判定这套范式"部分合理"——它是为"便宜模型 + 自动验收"量身打造的聪明 Tier0 超休闲范式,但顶着"声明式结构化源"的名号,内核却是"声明式数据壳 + 一坨未受契约约束的自由 JS"(承载全部玩法逻辑的 `behavior.code` 没进契约),表达力被运行时焊死在四类几何色块玩具上,九门只判机制地板、"好玩好看"无下限托底。结论很清楚:**坚持它做 Tier0 是对的;拿它去够 Marvel / KOF 那一档富交互愿景,是范式选错。**
|
||
|
||
**怎么补**:不是推倒,是"对齐名实、显式分层、把逻辑往结构化拽回"。真正补差距的工程载体是 2026-06-21 的 **A-model 转向**——LLM 写真 `src/` 多文件、调 L2 十一插件(juice / gamefeel / palettePost 给手感卖相),而不是 gamedef 色块。所以 tier1 高质轻游戏的载体是 **L2 能力库 + L3 自由写**。这条把"轻量≠简单"落到工程上:轻量是用公共素材、玩法模板、工程模板低成本生成相对不复杂、又不易同质化的高质小游戏,不是产没人会玩的简单玩具。
|
||
|
||
> 廉价线端到端闭环图:`assets/09-廉价线端到端.svg`。
|
||
|
||
### 4.2 实例二:AgentScope · Phaser 富游戏线(tier2)
|
||
|
||
**范式**:一个自治的单写 ReAct agent 去造多系统耦合、稠密 UI、大内容量的富游戏,产物是真 Phaser 多文件源工程。骨架 = 自治 loop(怎么走)+ task/goal 清单(走向哪、走到哪)+ Agent Team 动态调度(谁来走),**没有预先画死的 workflow DAG**。
|
||
|
||
**两阶段**:阶段 1 工作室用 Agent Team 星形——leader 拆解用户意图,`AgentCreate` 出玩法/关卡/数值/UI/音乐/特效/资产设计 worker 发散,`TeamSay` 汇 leader 收敛成设计结论;这阶段只读 + 对话(设计 worker 只读已有工程代码与工程内设计文档,并与用户跨 session 多轮对话)。阶段 2 单写实现——模板初始化工具铺工程骨架、把阶段 1 每个设计结论写成工程内文档、单写 agent 写代码、三层校验、产出。**闭环**:阶段 2 写进 repo 的文档/代码,下次迭代阶段 1 只读它再设计——这正是"游戏 = 长生命周期项目、改源不改包"。设计用多 agent(发散、专业),实现用单写(防并行写冲突)。
|
||
|
||
**接入面不自造**:直接用 AgentScope 2.0.2 的官方 Agent Service(`create_app` 拉起 FastAPI、对外 REST + SSE、天生多租户、durable session)。`POST /sessions` 建会话,三条加载路径对应"游戏=长生命周期项目"的三种入场:续接之前会话 / 加载已有工程迭代 / 新建铺模板。SSE 流断线可经 MessageBus replay 补发。
|
||
|
||
**运行时真实结构**:核心是 **Agent——无状态 ReAct 引擎**,构造参数持有 model(M3)/ toolkit / middlewares / state。**Workspace 是执行环境,沿两轴注入 Agent**:工具 / MCP / skills 经 Toolkit 注入,本身作 offloader。所以 Agent 持有 Workspace 引用、不嵌在里面;真正"跑在 Workspace 里"的是 MCP 进程、skills、文件。**Agent 实例非常驻**——每 run 现组装、跑完即弃,状态全在可持久化 `AgentState{ context, cur_iter, tasks_context }`。
|
||
|
||
**这条线尚未落代码**:整轨待 0 号 spike 验证,Phaser 一行未落,锁 AgentScope 2.0.2。验证方式不是 n≥30 统计批跑,而是收敛环:并发跑 5 个,错 > 1 个就读日志、分析、修复、并发重跑 5 个。
|
||
|
||
> tier2 这条线另有一套总览图,与 §5 各 facet 的细化图互补:生成两阶段 `assets/00-生成两阶段.svg`、系统全景 `assets/01-系统全景.svg`、调用时序 `assets/02-调用时序.svg`、运行时内部结构 `assets/03-运行时内部架构.svg`、ReAct 循环 `assets/04-ReAct循环流程.svg`、复用边界 `assets/06-reuse边界全景.svg`。
|
||
|
||
---
|
||
|
||
## 五、运行时八面(facet)
|
||
|
||
> 八个 facet 是 §四 两实例的逐面放大,把两条线在每一面的设计讲到可照着实现的颗粒度。tier2 富游戏线的内容偏多——它整轨待 spike、设计密度最高;廉价线在每一面以现行已落的对照锚出现。各面引用的 svg 大图在 `assets/`。
|
||
|
||
### 5.1 运行时形态
|
||
|
||
tier2 富游戏线的运行时按 AgentScope 2.0.2 的真实对象结构落地,不自造接入层。对外的接入面是官方 **Agent Service**——`create_app` 拉起一个 FastAPI 应用,天生多租户、对外 REST + SSE,会话状态可持久化、可恢复。八个官方 router(`/sessions`、`/chat`、`/schedule`、`/credential`、`/workspace`、`/model`、`/tts_model`,外加 agent 管理面)覆盖了会话、对话、定时、密钥托管、执行环境这些底座能力。底下一套 **MessageBus**(Redis 实现)撑起分布式协作:Redis Stream 做事件 replay 日志(断线晚到的订阅者能回放、不丢中间过程)、pub/sub 做唤醒广播、分布式锁保证同一会话同时只有一个进程在跑、还有取消信令。所以业务侧接 tier2 的真实姿势是:经 REST `POST /sessions` 建一个 durable 会话,再经 SSE 收事件流,断线靠 MessageBus 补发。
|
||
|
||
会话初始化有三条加载路径,对应"游戏 = 长生命周期项目"的三种入场:续接之前的会话(从 `SessionRecord.state` 取回历史工作记忆与轮次,resume)、加载一个已有工程(`Workspace.workdir` 指向已存在的游戏目录,进迭代模式、改源不改包重新构建)、新建(阶段 2 的模板初始化工具铺出空骨架)。三条路只是初始 state 与 workdir 不同,汇到同一个 Agent 装配点,不为每种入场各写一条链路。
|
||
|
||
运行时的核心是 **Agent——一个无状态的 ReAct 引擎**(`Agent` + `ReActConfig`,没有独立的 ReActAgent 类),构造时持有 model、toolkit、middlewares、state 四样。它**非常驻**:每次 run 现组装、跑完即弃。这是 Service 要多租户、要横向起多进程处理不同会话逼出来的——不能让 Agent 在某个进程的内存里长期活着,于是一切"下一轮还要用"的东西都必须外置到可持久化的 **`AgentState`**。AgentState 是一个 pydantic 模型,三个字段:`context`(工作记忆,即喂给模型的未压缩对话上下文)、`cur_iter`(当前 ReAct 轮次)、`tasks_context`(拆解后的子任务表)。它落在 StorageBase(Redis 实现)上。由此 **checkpoint 就是存取这份 AgentState,而不是序列化一个活对象**——Agent 非常驻,没有活进程可冻。两条硬约束随之而来:每一轮都 checkpoint(`cur_iter` 每自增一轮落一次,可在任意轮断点续上),且半轮的副作用必须幂等无脏(续跑可能从半轮中断处重来)。断点续跑于是从一道难题降成"读回 state 再装配续跑",已完成的子任务不重做。
|
||
|
||
**Workspace 是执行环境,沿两轴注入 Agent,而不是 Agent 嵌在 Workspace 里**——这是最容易反向理解的一处。一轴是资源注入:Workspace 的 `get_toolkit` 把内建工具、`list_skills()`、`list_mcps()` 汇成一个 **Toolkit**,灌进 Agent 的构造参数;另一轴是 Workspace 本身作 offloader 挂在 Agent 上,卸载上下文与工具结果。所以 Agent 只持有 Workspace 的引用,真正"跑在 Workspace 里"的是 MCP 进程、skills、以及 workdir 下的多文件源工程。这个朝向决定了工具资源挂在哪、观测点埋在哪、隔离边界画在哪。Workspace 有三套实现(Local / Docker / E2B),隔离强度递增——这正是 §二"采 microVM 沙箱抽象"的落点:沙箱底座可在 AgentScope-local、E2B、阿里云 AgentRun 之间切,每个 run 独立。
|
||
|
||
横切关注点统一挂在 **Middleware 洋葱**上,不散进业务逻辑。四道洋葱钩子(`on_reply` 管整次回复进出、`on_reasoning` 管推理加模型调用、`on_acting` 管单次工具调用的 I/O、`on_model_call` 管裸模型 API)加一道顺序变换钩子(`on_system_prompt`),逐层内外相套,未实现的钩子运行时自动跳过。成本刹车、超时硬切、卡死探测、可观测都是这套扩展点上的实现(详见 §5.3 熔断、§5.7 观测)。
|
||
|
||
多 agent 协作走部署态的 **Agent Team** 星形(leader 用 `TeamCreate` / `AgentCreate` / `TeamSay` 调度 worker),不是进程内 pipeline——2.0.2 已删掉进程内的 MsgHub / pipeline 那套同步编排原语。任务目标与进度的承载也对齐这套结构:目标 = 输入(brief / play_spec / GDD),进度 = `AgentState.tasks_context` 逐项用 `TaskCreate` / `TaskUpdate` 追踪,像一份 todo 清单,没有预先画死的 workflow DAG。
|
||
|
||
> **现 / 建**:Agent Service、MessageBus、AgentState + StorageBase、Workspace 三实现、官方预算软刹与 trace 中间件都是 2.0.2 现成件(已逐条核源码)。tier2 专属待建的是非常驻装配加每轮 checkpoint 落 Redis、session 三路接线、注入工具集、三道自建硬熔断、沙箱底座选型;整条轨待 0 号 spike,代码一行未落。一处现状要诚实:仓内现有形态是 `ReActConfig(max_iters=1)` 单轮加外层 repair,**不是**多轮自治 ReAct;放开 max_iters、把多轮搬进 Agent 内部是待建(见 §5.3)。
|
||
> 图:`assets/t2-A-01-AgentService与session三路.svg`、`assets/t2-A-02-Agent非常驻与AgentState.svg`、`assets/t2-A-03-Workspace双轴注入.svg`、`assets/t2-A-04-Middleware洋葱.svg`。
|
||
|
||
### 5.2 控制面与配置热取
|
||
|
||
两条生成线共用一层治理面——让 agent 自治生成游戏还不够,平台还得能配置它(改 prompt、换模型、调 skill 不发版)、看见它(每次生成到底发生了什么)、审计它(谁改了哪条配置)、在入口拦住它(配额、并发、降级)。这就是创始人最早提的"像 Dify 一样可视化、可追踪、可审计地管 agent 平台"。控制面四个组件对两条线暴露同一套契约(读配置、写轨迹、过门),生成线只照契约办事、不感知管理面长什么样。
|
||
|
||
**配置注册表**是配置的唯一事实源,回应"改 prompt、模型、skill、mcp 还要重新部署"那句话:凡是现在"要改就得发版"的东西,都搬进一个版本化、可回滚的注册表,节点是 prompt、model、skill、tool、mcp 五类。这里有一处必须诚实的现状——今天的 prompt 注册表**不是热加载地基**,而是构建期被 maven 插件复制进 classpath 的快照,改一条 prompt 等于改原文件、升版本号、过四道闸,下次构建部署才带新版。这正是 §二对标判定的反模式。**目标态是采 Langfuse 式的运行时热取**:注册表按 `id@label` 在运行时取、带缓存 TTL 与后台刷新、取不到回落内置默认,配置当数据热改、不重新构建部署。tier2 那条 Python 线的 genconfig 已经是这个思路的雏形,要把它推广到后端主线。但推广前有一条硬纪律:别在裂的地基上盖更大的注册表——先补一道一致性 CI(注册表里每条配置都有对应文件、每个硬编码加载的 id 都登记、占位条目要么补正要么标为不可上线),地基自洽了推广才有意义。prompt 这一类的完整治理(第 8 契约、四道闸、HITL、热取加载)是独立 SoT,见 [`prompt治理.md`](prompt治理.md)。
|
||
|
||
**观测 / 审计仓**回答两个独立问题:运行轨迹(每步推理、每次工具调用、每道门裁决、每次成本,落统一 trace 契约,详见 §5.7)和配置审计日志(谁、何时、改了哪条配置、前后 diff——这条线现在完全没有、是全新建的)。配置改动按性质分流:prompt、models 这类版本化资产走 GitOps(改配置就是建 PR,审计天然、可回滚),运营开关类(降级、配额数值)走 DB 直写、即时生效、复用现成通路。这条分流判据正是 A13 配置注册表最该先定的核心——影响生成质量与安全的配置走 GitOps 四闸不可热改,运营降级开关与阈值走 DB 热改。
|
||
|
||
**D12 运行治理门**把配额、并发、背压、降级、记账骨架焊在生成任务入口前,是已存在的件,本设计只复用、默认关闭、零行为变更进主干。它现在只覆盖廉价线,tier2 接进来的入口、预算扣减、并发释放、失败补偿还要补。它接上的是引擎那道"花到上限就拒绝执行"的预算闸,而成本强制是三层纵向叠、任一道先到上限即拦:worker 本地预测闸(动手前先估这一步要花多少,越本局预算就不发起调用,最便宜、调模型之前就拦)、网关配额闸(就是 D12)、任务 deadline 闸(超墙钟时间盒即停,兜住 token 没烧穿但卡在长循环的纯耗时失控)。取价通路不可达时要显式定一条策略——直接失败、宁停不超支,或降级到纯 token 上限兜底,不留模糊。这套三层强制落地之前,tier2 只在严格时间盒的实验里跑、绝不规模化。
|
||
|
||
**管理面 UI** 是注册表与观测仓的视图与编辑器,不是真相本身——配置才是真相。它不从零造一个 Dify 式可视化建图器,因为裸图的节点是 Java 代码、ReAct 的工具也是代码,真相在代码与配置里,靠 UI 拖拽生成代码是另一套不可靠的范式。但"配置是真相、UI 是视图"不等于第一期什么都不做,管理面按三档诚实命名地落:phase-1 是配置管理加运行可观测(含一个纯只读、不依赖任何前置、立刻能给创始人看见的最小切片——看各角色当前用什么模型、回放任意一次生成的全轨迹、按 new-api 口径对账成本;其上再加配置编辑,改完落 Git 加审计、不直接热生效),phase-2 是限定范围的图编辑(节点启停、参数、版本 diff、轨迹回放,但渲染的拓扑来自运行时自报、不让用户拖拽改结构),phase-3 是完整可视化建图(拖拽改拓扑,远期不投)。一条贯穿约束:管理面对拓扑只渲染框架运行时自报的结构,绝不在管理面这侧另持一份拓扑模型——廉价线是静态图、tier2 的 ReAct 没有静态图,两套异构范式用同一个管理面,只能靠"渲染运行时自报"这个共同口径,而硬编码的拓扑模型在换框架时反而成为阻力。这也是反锁死(§一)在管理面的落点。
|
||
|
||
> **现 / 建**:D12 现行已落(默认关闭);配置注册表是"现·部分"(prompt 构建期快照),热取、推广到 skill/tool/mcp、配置审计日志、管理面三 phase 全部待建。
|
||
> 图:`assets/t2-B-01-控制面四组件.svg`、`assets/t2-B-02-反锁死五协议.svg`、`assets/t2-B-03-预算三层强制.svg`、`assets/t2-B-04-管理面三phase.svg`。
|
||
|
||
### 5.3 单写 ReAct 循环
|
||
|
||
阶段 2 的实现交给一个**单写者 ReAct agent**——想一步、调一个工具、看结果、再想下一步,而不是一次把整个游戏写完。富游戏跨十几个源文件、多个系统互相接线,一次写完几乎不可能对,必须每观测一次就回头重想。一轮闭环是:读引擎文档与资产 → 写源文件 → esbuild 构建 → 无头快检 → 九门在真浏览器里真玩 → 读 verdict → 没过就改 → 回到写源,每轮 checkpoint。agent 不按固定顺序走完九个工具,每一轮自己决定下一个调谁——九工具是 ReAct 循环的工具面(见 §5.5),不是一张阶段图。
|
||
|
||
**为什么单写、不并行写**:经营游戏的多个系统共享同一套状态与约定,拆给并行 agent 几乎必然不一致。一手教训是曾把"造 Flappy Bird"拆给并行子 agent,背景跑成了马里奥。单写意味着只有一个 agent 持整个工程的全局视图。要分清边界:单写只管阶段 2 写代码这一环,阶段 1 的工作室设计仍用 Agent Team 星形多 agent 发散——设计要发散与专业分工,实现要防写冲突而收敛到单写。
|
||
|
||
**为什么把多轮放进 Agent 内、而不是外层**:tier2 与廉价线 WG1 的真正差别不在 prompt、不在生成域,而在"多轮自治放在哪一层"。WG1 是 `ReActConfig(max_iters=1)` 单轮加外层 repair 重试——单写、单轮、靠外层喂错重跑;它故意单轮,是为压便宜档的单价(廉价线生产主线明确不引 AgentScope,框架的 token 膨胀会吃掉便宜档的利润)。tier2 把 max_iters 放开,把多轮从外层 repair 搬进 Agent 内部的 ReAct。这套多轮不是凭空发明,从两条已跑通的参照系演进而来:WG1 的单轮加外层 repair(现行已落)、以及 A-model 那条已经在 M3 上跑通的多轮 ReAct。从 A-model 复用三件成熟范式——agent 自己 reason 判"够了"才终止的 done 门(不靠外层固定轮数,finish 工具收尾吐出 `src/` 源工程)、每轮先跑便宜检查再决定下一步的快反馈、以及把历史压缩了喂下一轮的长程一致性(多文件富游戏轮数多、上下文长,压缩才不撑爆窗口)。fork 起步、独立演进:它复用的框架接缝在 2.0.2 全兼容、零签名改,但拖的 validate / run / prompt / roles 是 LittleJS 专属,按 Phaser 重写近乎全新写——真功夫在重写面加 net-new 的多轮循环、Workspace、Service。
|
||
|
||
**四道熔断加预算闸**叠在中间件洋葱上,任一先触发即停本局:步数硬顶(给每系统的构建-修复定上限、给整局定 max_iters,防模型靠多轮反复试错把门擦边混过去)、预算闸、卡死探测(语义层判 agent 是否原地打转、空转换汤不换药,而非单纯计步;还要防 agent 改 driver 来绕过它)、双层超时(单步钉死一次工具调用、整局钉死本局总时长)。四道里只有预算闸现在画实线——用官方 `ReplyBudgetControlMiddleware` 软刹,在推理与回复钩子上按预算优雅收尾。但它只是软刹、不强杀:自治多轮一旦不强制截断,会在那 56% 表现层上烧钱发散(一次失控循环能烧掉数美元)。所以**硬熔断(fail-closed)与 ¥ 金额台账必须自建**,做成中间件洋葱上订阅模型调用结束事件的 Middleware,把 token 按 new-api 计费口径折成 ¥ 累进、越过硬上限就直接终止本次生成;这道硬闸的三层强制架构见 §5.2。规模化之前它必须落地,spike 阶段可容忍只挂软刹先跑通。
|
||
|
||
**M3 的接法**是这条线能不能成的根因之一。tier2 agent 经官方 `AnthropicChatModel` 走 `AnthropicCredential.base_url`(指向 new-api 的 Anthropic 端点),到 MiniMax-M3,计费统一从 new-api 一个平面走。"用对 M3"是三件事:走 Anthropic 原生协议加 agentic 工具循环(循环调工具写源 / build / 跑门 / 读 verdict / 改,而不是 OpenAI 式单次 JSON 填空);thinking 分离(开 thinking,且 max_tokens 须严格大于 thinking_budget);完整 response 与历史保留(每轮的 thinking / text / tool_use 块原样回传入历史,否则 M3 的交错思维失效)。旧用法 60% 失败的最深根因正是反着来——关 thinking、单次 JSON 填空、失败从头重生成,是用法错、不是模型天花板。
|
||
|
||
> **现 / 建**:九门 harness、new-api 计费平面、WG1 单轮形态、A-model 多轮范式、官方预算软刹、AnthropicChatModel 接法都是现成可信。Agent 内多轮 ReAct、M3 原生接法链路、thinking 分离、三道自建硬熔断、强制硬闸、写源/改/快检的内循环,都是 tier2 待建。
|
||
> 图:`assets/t2-C-01-单写ReAct循环.svg`、`assets/t2-C-02-M3原生接法.svg`、`assets/t2-C-03-四道熔断.svg`、`assets/t2-C-04-多轮范式承amodel.svg`。
|
||
|
||
### 5.4 三层校验与九门
|
||
|
||
验收分三层,处置力度递减。**L1 硬约束**管编译、启动、运行错误——boot 不起、跑着抛异常、画面死;判据全是确定性信号(构建日志、浏览器 console、CDP 错误捕获、九门探针),零 LLM 参与,必须循环逼到解决为止。**L2 设计符合**管玩法与关卡实现对不对、UI 缺组件、品类约定有没有违反;靠确定性的设计符合度信号,尽量解决而非死循环;它的拒发权不是天生的,走 observe→enforce——先只观测积累信号,在真实数据上证明判得准,才赋予拒发权。**L3 效果**管特效、美观、好不好玩;只用 M3 多模态视觉软检打分,绝不解决、绝不阻塞拒发,产出只进质量趋势、告警、给人工终审减负。L3 死活不当门有两条硬理由:扩确定性门去自动判"好不好玩"只会得到能被刷的代理指标(精心做的打砖块和"摆三块砖点一下就赢"的退化品会一起全绿,门即废);让纯 LLM 当玩家裁判则踩 Goodhart——模型进了验收当裁判,会学会优化成"让裁判说好"而非真好。所以"好不好玩"最终归人工终审。迭代上初期只焊死 L1,L2 / L3 渐进,绝不让效果问题阻塞真问题。
|
||
|
||
L1 的主体是九门,每门在真浏览器里真玩一局取确定性证据:A_boot(能否 boot,轮询 boot 信号)、B_uncaught(有无未捕获异常,监听 console 与 CDP 错误)、C_frame(帧在不在推进,前后取帧号差大于零)、D_render(画面有无真实内容,截图回读亮像素阈值)、E_live(画面在不在变,对多帧取哈希去重)、F_wiring(逻辑真调引擎还是空桩,查引擎 API 调用有没有出现)、G_input(注入输入后状态有无变化)、H_progress(核心机制有无真进展,driver 驱动加玩后断言、含 latch 终态)、I_control(控制响应跟不跟手,输入到反应的时序在阈值内)。九门里只有 H_progress 落 L2,其余落 L1;E_live 与 H_progress 是条件门(没有 driver 时降为 advisory),其余是硬门。九门全绿等于机制地板通过、可发——把"做完了"钉在客观证据上,绝不让模型自评。
|
||
|
||
现有九门是为廉价线的 LittleJS 建的,探针钩子硬编码了 LittleJS 专属取法。tier2 复用的是"真玩判定加零自评"这套哲学、**不是**这套代码,探针要为 Phaser 整套重写——canvas 选择器、帧源、boot 信号、输入注入与 state 读取四条钩子各自重写,不是参数化一键切。沙箱底座是 spike 的前置阻断项:先小验 agentscope-runtime 的 BrowserSandbox 暴露的能力够不够跑探针,够就用、不够回落自建薄沙箱复用现有 harness——这个结论必须在生成迭代开跑前出来,出不来整个 spike 跑不起来。
|
||
|
||
九门是超休闲单局的机制地板,不查跨系统接线;富游戏的难点恰在跨系统,所以在九门之上补三道 tier2 专属的确定性门。**三联动门**证三个系统真耦合而非孤岛:订单要的物品必须能被合成系统产出(从合成链静态推到订单的跨表可达性检查)、合成链必须是有向无环图(拓扑检查不许成环)、完成订单时必须真调资源系统加金币、合成消耗时必须真调扣食材。**经济门**用真输入把两条路驱动到终态:可盈利路径(金币从开局攒到目标判赢)、可破产路径(连续若干订单流失判输),关键约束是两条路都得被 harness 的真输入序列驱动跑到终态——能在数据表里算出来和能被真玩到是两回事。**latch 门**管终态落定不回弹、宿主能读到终局,承接的是"游戏无 emit 通道、终态焊成可轮询 latch、宿主轮询读"这条现行装载约束。九门加这三门合起来全绿,才算 tier2 的富游戏机制地板通过。
|
||
|
||
两道条件门靠 **driven 感知的 advisory 分级**自动切换:一个 play-spec 既没有 driver 也没有非空输入序列时,判定 driven=false,E_live 与 H_progress 降为 advisory(仍跑仍报告,但不计入 pass),硬门只剩七道;一旦给了 driver 或输入序列,driven=true,两门自动恢复致命、九门全计入——不改一行代码。理由很朴素:没人给输入时画面本就静、机制本就没进展,硬判这两门是冤枉它。这正是 observe→enforce 范式的源头,tier2 修 latch 门与经营门复用它。这套分级已在 A-model 分支实现、创始人 2026-06-22 裁定,但尚未合并进主干,tier2 以合并后版本为准对账。
|
||
|
||
spike 第二段放开让 agent 自产或扩展 driver 时,会撞上一个 Goodhart 雷:**写者不能写判自己游戏的那张卷子**——agent 既造游戏又造判它的 driver,会把 driver 写成只走它走过的路、只读不暴露真实力的字段,然后全绿假绿。隔离办法是拆开写卷人与判卷人,走三层:平台先按 schema 加白名单编译(非白名单或越界字段直接拒)、再交一个不向着被评对象、专找漏洞的独立 adversarial 评审(查它是否覆盖真实玩家路径、是否读了作弊字段)、三层全过才入验收。配套采两个指标:自产 driver 被独立评审打回的比例、driver 被修改的次数(防靠反复改 driver 逃避卡死探测)。
|
||
|
||
> **本节是运行时视角的九门与三层校验,确定性验收的护城河命题(机器判、禁自评、出题≠被考、per-tier verdict 元协议)即落在此节与 §三 A5**;另有一层"对外开闸放行"的 6 道门(D12 控制平面、GP9 合规先行、落库观测三门、首局体验门、G0/G1 前置)坐在九门机制地板之上,是独立 SoT,见 [`验收门.md`](验收门.md),其基准靶集见 [`WG1基准.md`](WG1基准.md)。
|
||
> **现 / 建**:廉价线九门现行已落、判过大量游戏;三层校验框架、tier2 三道专属门、Phaser 探针重写、自产 driver 三层隔离全部待建。
|
||
> 图:`assets/t2-D-01-三层校验全景.svg`、`assets/t2-D-02-九门逐门.svg`、`assets/t2-D-03-富游戏专属门.svg`、`assets/t2-D-04-advisory分级与Goodhart隔离.svg`、`assets/t2-D-05-CDP探针Phaser重写.svg`。
|
||
|
||
### 5.5 能力面:skills 与 MCP 工具
|
||
|
||
单写 agent 的工具面是九个工具,按角色分三类,围成一圈自治内循环而非流水线。**核心环六个**:`write_source`(写那 56% 表现层——逐像素手画的场景与 UI、点击命中、本游戏独有规则,压不成数据表或骨架、只能现写,也最易崩,是整轨最深的赌注)、`build`(esbuild 打成可玩 bundle)、`headless_check`(跑全套真玩门前先做一道便宜快筛,能早断就不浪费一整轮)、`run_gates`(上确定性的九门加富游戏专属门,判定见 §5.4)、`read_verdict`(把裁决喂回循环、让 agent 知道改哪)、`finish`(收尾吐出结构化的 `src/` 源工程)。**取证两个**:`screenshot`(只喂软检与人审,故意不进硬门判定——让模型看截图给自己打分会优化成"截图里好看"而非"真能玩")、`query_assets`(查资产)。**起手收尾两个**:`scaffold_init`(session 开头铺平台预建的工程骨架,给单写 agent 一个先天能过 boot 的起手点)、`finish`。三条工具铁律:单写独占(整工程只一个 agent 写)、finish 与源项目契约共用同一份 schema(见 §5.6)、验收零自评。
|
||
|
||
引擎不是"一次选定、所有游戏长在上面的固定底座",而是一个**动态加载的能力包**;换引擎等于换"我手里有哪些工具能调"那一组,不是架构重写。能力包五件套各管一面:**skill** 是这一引擎下"如何做某一类事"的固化 playbook(沉淀对的写法、少让模型现场摸索)、**tool** 是上面九个工具的该引擎实现(经 FunctionTool 薄壳接进 Toolkit)、**mcp** 把引擎侧能力标准化暴露成可调接口、**rag** 是引擎文档与范例的检索增强(补模型训练数据里这个引擎的密度,见得越多自治循环越少编不存在的 API)、**scaffold** 是模板初始化铺的工程骨架(平台预建的那 25%)。换引擎就是换这一套加载的工具集,不动两阶段角色、不动三层校验主干。这一面正是 §二"工具采 MCP-native、playbook 采 SKILL.md 开放标准"的落点。
|
||
|
||
prompt 分**两阶段角色**。阶段 1 工作室设计师跑在 Agent Team 星形上:leader 拆解用户意图,经 `AgentCreate` 拉起玩法、关卡、数值、UI、音乐、特效、资产等设计 worker 发散,经 `TeamSay` 把各路结论汇回 leader 收敛;这阶段只读加对话——设计 worker 用 `PermissionMode.EXPLORE` 只读已有工程代码与工程内设计文档,与用户跨 session 多轮对话、不写代码。阶段 2 单写 coder:模板初始化铺骨架、把每个设计结论写成工程内文档、单写 agent 跑 ReAct 多轮写代码、过三层校验、产出真 Phaser 源工程。星形有一条铁律:worker 只能经 TeamSay 把结果报回 leader,禁止 worker 互评互相喊话,所有协调过 leader 这个唯一中心(2.0.2 已删进程内的 MsgHub / pipeline,工作室必须建在部署态 Agent Team 上)。
|
||
|
||
tier2 与 A-model(廉价线那条 LittleJS 轻量经营档)**两线分立、运行期零依赖**,但 A-model 的引擎无关契约可以复用、渲染按 Phaser 重做。复用的是四个插件的契约与命名(`scene-fsm` 场景状态机、`hud-ui` 界面、`session-score` 局内计分、`timer-scheduler` 定时调度)、`sim-business` 经营配方(数值与系统结构、非渲染件)、以及九门基线那套 driver 感知 advisory 分级范式;但探针要为 Phaser 整套重写。源项目契约维持独立 schema、不并进 A-model 的 LittleJS keystone(见 §5.6)。
|
||
|
||
廉价线那一侧的能力面是另一套:SAA 用裸 `StateGraph` 加自定义 `NodeAction` 手写确定性编排,模型层直接复用上游 spring-ai 的 `OpenAiChatModel`(baseUrl 指 new-api、多个 bean 仅 model 名不同),checkpoint 用 `MysqlSaver` 单权威。它和 tier2 的能力面同源于"框架可换、契约不变"的原则,但因为生成主线本质是确定性多步编排、不是给 LLM 一堆工具自决,所以用裸图原语、不套自治 agent 框架。具体的图原语 API、repair 回边、子进程调用与依赖冲突避让属实现细节,落在配套 playbook 与代码里、不进本文。
|
||
|
||
> **现 / 建**:九门 harness 钩子、A-model 四插件契约与 driver 分级、SAA 能力都是现行已落(SAA 一侧基于 v1.1.2.2 真实源码四路取证)。九工具的 Phaser 实现、五件套通用接口、Agent Team 星形、阶段 2 单写 ReAct 待 spike 后落码。一条克制纪律:第一版不把五件套建满——只有 Phaser 一个真实现(Pixi 留桩)时把接口钉死,会被唯一实现反向决定,真正的通用接口等第二引擎落地、有两实现做依据再抽。
|
||
> 图:`assets/t2-E-01-skills清单.svg`、`assets/t2-E-02-引擎能力包manifest.svg`、`assets/t2-E-03-prompt两阶段角色.svg`、`assets/t2-E-04-Amodel插件复用.svg`。
|
||
|
||
### 5.6 源项目契约与装载
|
||
|
||
两条线的装载分流在这里劈开。**廉价线左支**是声明式结构化源的固定架构:一款游戏就是库里一条 GamePackage,代码打成 engineBundle 内嵌在 manifest JSON 里(整包带 sha256,出于 CSP 不放外域)。它的特征是不构建、即取即跑——bundle 本身就是产物,固定运行时一套、所有数据壳共用。装载五步已被 Runner v2 实证:存库时 engineBundle 内嵌进 DB-manifest、feed 点开后下发 manifest、iframe 内联脚本取出挂上 `window.__GameBundle`、`bootGameHost` 在沙箱 canvas 启动、之后每帧回调 update / render。装载契约的接口形状(`GameHostBootContext`、`GameInstance`、`GameHostFactory`,见 §三 A4)按 engineBundle 是否存在分流。受控运行时面的纪律是:引擎是唯一掌帧源、绘制面唯一是引擎的 mainContext、游戏不自起 requestAnimationFrame,能力经受控接口注入。
|
||
|
||
**tier2 右支**是真 Phaser 工程,要为它新写一套独立的源项目契约,钉死一个真工程"是什么、怎么构建、怎么存回"的七要素四组:身份(源项目类型标记,装载侧据它分流到正确的装载分支,是整条分流的第一道闸);工程骨架(文件树 manifest 记有哪些文件各自什么角色、入口文件标出 build 从哪起手);构建可复现(构建 profile 把命令与打包配置随款冻结、依赖锁钉死引擎与插件版本——直接服务"两年前的游戏今天仍要原样构得出");落库取回(内容哈希既做缓存命中又做完整性校验、落库与寻址 API 定义怎么存进 MySQL 加对象存储、怎么按 id 取回重建,沿用 GamePackage 那套 sha256 数据范式)。
|
||
|
||
这套契约必须另立独立 schema、编为契约组的新一类,绝不复用廉价线那份同名的 ECS-lite 数据壳契约——撞名但语义完全不同,共用一份会把本该解耦的两条线焊在一起、改 tier2 时污染在产线上跑的廉价线。同样地,A-model 把它的源项目 schema 升成了绑定 LittleJS 装载路的变体,tier2 的 Phaser 工件走另一条装载序列,另立独立 schema、不并进同一个 keystone,避免把 Phaser 的差异焊进 LittleJS 的契约。
|
||
|
||
右支的装载比左支多出一段:入库的是一个真 Phaser 工程(多源文件加构建脚本加依赖锁),取回之后要先按构建 profile 用 esbuild 打包出可玩 bundle,再在沙箱里跑——这一段构建是左支即取即跑所没有的。`finish` 工具交付的形状与落库取回认的形状**共用同一份 schema**:agent 自治跑完经 finish 吐出的那个工程,和落库取回认的那个工程本是两处定义,共用一份则"契约即工具签名,改一处即两处一起改",从源头消除交付与落库漂移这个失败面。装载终态仍服从 latch 轮询:游戏跑到结束态时不主动发事件,而是把状态焊成可轮询的终态、宿主每帧轮询读。整条线的产物是可维护的源工程而非死 bundle,改源、重新构建、按内容哈希长期取回重建——这正是"改源不改包、游戏即长生命周期项目"在装载面的兑现。
|
||
|
||
> **现 / 建**:左支 ECS-lite 装载契约现行已落、是唯一的对照锚;右支七要素契约、第二装载分支、finish 共用 schema 全部待建(tier2 整轨待 spike)。
|
||
> 图:长生命周期源项目 `assets/08-长生命周期源项目.svg`;`assets/t2-F-01-源项目契约七要素.svg`、`assets/t2-F-02-第二装载分支.svg`、`assets/t2-F-03-finish共用schema.svg`。
|
||
|
||
### 5.7 观测与成本(OTel)
|
||
|
||
一份 trace 契约要管两条异构的线,办法是**接口层对称、内容层不对称**:一个对称的公共核心子集加各轨一个不对称的 JSON 扩展段。消灭轨迹分散(split-brain)的真口径是"每条派发路诚实镜像它真有的字段、没有的绝不编造",而不是强求两条线字段对齐——tier2 是 ReAct 的"想一步、做一动作、看一结果",廉价线是十六节点的阶段裁决,本就不同构,强求对齐等于逼一条线编造它根本没有的字段。公共核心子集是五个字段(`traceId`、`step`、`cost`、`verdict`、`timestamp`),两条线必填、同名同义;扩展段各写各的——廉价线塞阶段、修复轮次、门裁,tier2 塞推理、动作、观察。这份契约约束的是数据口径、不是采集机制:采集各按各的框架来,数据口径不随框架漂移。它该落成 `contracts/trace/` 下契约组的新一类,含字段定义、schema 版本、脱敏规则、两条线 adapter 怎么映射,以及一条策略——轨迹写不进去时默认 best-effort 不阻塞主生成流程、但落一条告警(不能让一次落库抖动废掉整局已跑出的生成,也不能让它无声丢失)。这一位当前还没建,随 spike 或控制面 phase-1 落地再新立,别当现成件引用。
|
||
|
||
采集机制采 **OpenTelemetry GenAI 这套标准**,而且 tier2 这条线几乎不必自己埋点——AgentScope 2.0.2 自带一套完整的强类型 Event System,agent 每跑一步就吐出强类型事件流,经官方 TracingMiddleware 直接调真 OTel SDK 转成 span、汇进 AgentScope Studio 可视化。七类事件里,文本、思考、工具调用各带起始/增量/结束三相,工具结果一类,模型调用用一对起止事件圈住——**结束那一下带这次调用的 token 用量**,成本台账的 token 正是从这里抓;回复事件圈住一轮完整的 reason→act→observe。所以 tier2 写轨迹的活只是"订阅加映射",不是"埋点加采集":订阅 Event System、走官方 TracingMiddleware→OTel 管道,再加一层 adapter 按核心子集加扩展段映射进统一表。廉价线那条 Java 线则按自己的节点裁决埋点、走同一份契约的另一个 adapter。两条线机制各异、契约一致,正是"接口对称、内容不对称"在可观测面的落点。存储复用已部署的 MySQL 加对象存储,不上重型可观测中间件——观测早建是为 spike 调试和对账当下就用得上,不等于现在就铺独立基建。
|
||
|
||
成本不是估的,从 new-api 的 quota 权威口径折出每款多少人民币——每次调用的 quota 就是真实的倍率成本,比按公开单价估更准。OTel 的语义约定里没有成本属性,所以"成本钉 new-api 计费行"这条自研口径要保留,经 traceId 关联进 trace。这里有一个红线缺口:M3 那一档走 Anthropic 原生端点,而现有成本记录只覆盖 OpenAI 路,抓不到它,于是 M3 这档的 token 用量采不到、单款成本对它直接缺、全矩阵成本没法对比。接点是补一个包住 Anthropic 模型调用的录制变体,抓每次按模型分列的 token 用量,把 Anthropic 路补齐。计费平面的纪律是"协议自由、计费收口"——M3 走 Anthropic 端点、便宜档走各自端点,协议与 SDK 不锁死、每档走各自最优端点,但所有路最终都收口到 new-api 的 quota 按模型折 ¥ 这一个计费平面。
|
||
|
||
> **现 / 建**:new-api quota 计费平面与读 quota 折 ¥ 现行已落;统一 trace 契约、tier2 的 Event→OTel adapter、包住 Anthropic 路的录制变体都待建。NEWAPI_KEY、端点、机器见 `docs/内网凭据与端点.md`。
|
||
> 图:`assets/t2-H-01-trace统一契约.svg`、`assets/t2-H-02-观测管道.svg`、`assets/t2-H-03-成本台账.svg`。
|
||
|
||
### 5.8 四层职责
|
||
|
||
把 tier2 的运行时拆成 environment、harness、context、prompt 四层,是一个**职责视角**,叠在 AgentScope 2.0.2 的真实对象结构(Agent / Workspace / Toolkit / Middleware / AgentState / Agent Service)之上,不是四个平行筒仓、更不是互相调用的对等模块。读的时候带着"职责→真实载体"的对应:environment 的真实载体是 Workspace(沿两轴注入 Agent,见 §5.1);harness 是 Agent 的 ReAct 循环原语加 Middleware 洋葱加 tier2 自建的验收门;context 与 prompt 是每一步组装进模型窗口的运行时载荷加离线指令,两者是 prompt ⊂ context 的嵌套关系。业界主流的口径是 prompt ⊂ context ⊂ harness 三层嵌套、environment 并进 harness 当对外数据面;本文拆成四层是为了讲清"单写者 ReAct 加跑确定性门"这种结构。
|
||
|
||
复用边界看两个维度:来源(官方现成,即 AgentScope 2.0.2 自带,还是自建)乘以共享(两条生成线公共,还是 tier2 私有)。一个关键的交叉结论是——**公共组件等于自建与共享的交集**(九门、三层校验、CDP、计费、送审、feed、trace),它们是团队自建、被两条线共用的,**不是官方现成能力**;"框架里有"不等于"公共组件"。每个自建项还标出它用哪种 AgentScope 扩展点落地:验收门是框架外的确定性断言、硬熔断三件是挂在洋葱上的 Middleware、角色 prompt 与模型路由是纯数据的 Prompt 热配置、skill 目录经 Workspace 的 add_skill 注入、工作记忆与经验召回是 AgentState 的 context 加经验库。把载体类型标清楚,是为了让"换引擎等于换 id 和 version、trace 始终按 id/version 归因"这条目标态有落点,也防止把本该热配的东西硬编码进机制。
|
||
|
||
一次诚实的对地基现成度的上修:有六样早稿打算自建的能力,其实官方已有现成件,该删掉自建、改用官方——token 计量用模型响应自带的用量、软预算控制用官方的预算中间件、结构化输出用模型层能力、可观测 trace 用官方 TracingMiddleware(纯 OTel)、经验召回用现成的记忆框架、多 agent 总线用 Agent Team。反过来,官方确实没有、必须自建或引第三方的是:RAG 检索管线、评测模块、成品级的框架互通、以及两块护城河——确定性验收门(框架不提供)和强制 fail-closed 的预算硬闸(官方软刹刹不住已在烧钱的失控循环)。
|
||
|
||
配置分三类,决定一样东西改了要不要发版。硬代码机制类(确定性门断言、四道熔断、基线硬门强制、循环与记忆的组装压缩机制、权限硬上限、那几条铁律)随代码走、不外置。版本化安全与构建配置类(依赖锁、引擎版本、构建 profile、启用的沙箱类型、权限上限只可降不可升)审计留痕、不热改。热配置策略类(prompt 文本、各 agent 的模型路由、few-shot、skills、max_iters、熔断阈值、新增门的 observe/enforce 档、上下文预算、压缩阈值、枚举内的 RAG 源、记忆模式)改配置不发版。一条颗粒度澄清:新增或删除一类内容等于改枚举、是硬代码;已有类里增减取值(比如多挂一个 RAG 源)是可配置。三类门也同此分:基线确定性硬门永远强制、不可关,新增确定性门走 observe→enforce(默认只观测,达标率稳了才赋拒发权),M3 视觉软检永远只观察、绝不放行也绝不拒发。
|
||
|
||
> **现 / 建**:四层视角与复用边界是设计框架;tier2 私有自建项(多轮循环控制、硬熔断、Phaser 能力包、验收门重写)全部待 spike 后落码。一处实证差异留待 spike 前小验:经验召回用树内捆绑的记忆 middleware 还是生态里独立的记忆框架。spike 阶段只需 spike-grade 地基(硬编码 prompt/config 可接受),完整的配置外置、长期记忆治理、skill 家族、管理面都留 spike 过后。
|
||
> 图:本面以档内 mermaid 呈现(四层职责对应、复用边界二维、三类门加三类配置),无独立 svg。
|
||
|
||
---
|
||
|
||
> **同步纪律**:本文是生成运行时架构唯一 SoT。设计一变动,本文与对应 svg 必须同步更新(并入 wave 收口清单)。被本文收敛、已退役的原文档在各自 tombstone 指针处指回本文。
|
||
>
|
||
> **相邻 SoT**:prompt / 配置治理 → [`prompt治理.md`](prompt治理.md);对外开闸放行 6 门 → [`验收门.md`](验收门.md)(基准靶集 [`WG1基准.md`](WG1基准.md));数据护城河 → [`数据飞轮.md`](数据飞轮.md);能力框架调研对照 → [`OpenGame对照.md`](OpenGame对照.md);执行序列 → `docs/plans/` 下生成线执行 plan。
|