games-development-ai/docs/architecture/架构/生成引擎/agentic运行时架构图说.md
lili fe6a2b4d98 docs(生成引擎): SoT① Step3 — ②prompt治理改热取 + ③验收门收敛 + ④数据飞轮 canonical
- ② 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>
2026-06-24 22:43:47 -07:00

298 lines
62 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
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 类:固定接口协议
下表是固定协议目录。"形状"列给数据模型与接口签名;"现 / 建"列分清哪条已被代码兑现、哪条还是设计意图;"采标准 / 自研"列接 §二 的对标结论。**A1A7 是生成执行段的接缝**(提交生成 → 跑 ReAct → 过验收门 → 装载进浏览器),**A8A13 是平台面接缝**(送审、资产、模板、试玩、通用检查、配置)。
| 编号 | 协议 | 形状(数据模型 / 接口) | 现 / 建 | 采标准 / 自研 |
|---|---|---|---|---|
| **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 式运行时热取 |
A8A13 这六面的共同状况:廉价线在生产里已把它们大多兑现,但都硬编码在单条 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。