diff --git a/docs/architecture/架构/生成引擎/agentic运行时架构图说.md b/docs/architecture/架构/生成引擎/agentic运行时架构图说.md index a50fe417..7d7d3140 100644 --- a/docs/architecture/架构/生成引擎/agentic运行时架构图说.md +++ b/docs/architecture/架构/生成引擎/agentic运行时架构图说.md @@ -1,8 +1,8 @@ --- title: agentic 生成运行时架构 — 可插拔 agent 平台 -status: 架构演进中 · tier2 核心已落 + 0 号 spike feie-005 accept(首跑;下一步收敛环 n=5、有错再追加 5)· §4.2/§5.x 已按 2026-06-24 HANDOFF doc-sync(2026-06-25)· "采标准"方向 §6.8 双评审已过(采纳但修),已收口定稿:成熟度五列(§二补二)+ 6 条 build-vs-buy ADR(§二补三)已补、§三 定级已冻 +status: 架构演进中 · tier2 核心已落 + 0 号 spike feie-005 accept(首跑;下一步收敛环 n=5、有错再追加 5)· §4.2/§5.x 已按 2026-06-24 HANDOFF doc-sync(2026-06-25)· "采标准"方向 §6.8 双评审已过(采纳但修),已收口定稿:成熟度五列(§二补二)+ 6 条 build-vs-buy ADR(§二补三)已补、§三 定级已冻 · **2026-06-25 核心 reframe(创始人)**:框架收敛 AgentScope(SAA/dify 降最低优先级、留作远期适配验证可插拔)+ 三档按 AI 参与深度(去超休闲、全模板化非从零)+ per-gen 预算闸 <¥10/<¥50(图音另算) canonical: true # 生成运行时架构唯一 SoT,收敛原 16 份图说/详设/接口协议草案 -topic: 生成运行时架构(adapter + 可插拔 agent 框架 + 两生成实例) +topic: 生成运行时架构(adapter + 可插拔 agent 框架 + 三档生成实例) date: 2026-06-24 --- @@ -18,11 +18,13 @@ date: 2026-06-24 ## 一、命题与定位:可插拔的 agent 平台 -绘境AI 的游戏生成正在从一条线长成两条。一条是已经在生产里跑的**廉价线**:便宜模型经 new-api 网关、由 SAA(Spring AI Alibaba)裸图编排,产物落在 LittleJS 增强发行版上,过九门兜底,目标是低成本批量产出不同质化的高质轻游戏喂进大众 feed。另一条是 **tier2 富游戏线**:一个自治的 ReAct agent(AgentScope 框架)去造廉价线做不出的多系统富游戏,产物是真 Phaser 源工程。两条线还会继续分叉——引擎可能从 LittleJS 换到 Phaser、Pixi,编排框架可能从 SAA 换到 AgentScope,乃至将来接 dify、coze 或自训框架。 +绘境AI 的游戏生成统一由 **AgentScope 一套自治 agent 框架**编排,按 **AI 参与深度**分三档(Tier0/1/2):级别越高,AI 写进游戏的内容与代码越多。三档都不从零写——平台预建工程脚手架、备好玩法模板,AI 在**玩法模板加工程模板**上按档位深浅填数值、写逻辑、写表现层;最低档也是能上线、能挂广告或内购的真游戏,无法形成商业闭环的超休闲玩具不做。引擎按表现复杂度选(轻量档 LittleJS 增强发行版、最富档 Phaser),但引擎只是实现、不是分档的轴——分档的轴只有 AI 参与深度这一条。无论哪档,产物都过九门兜底真玩判定。 + +生产编排现阶段只押 AgentScope 一套;SAA(Spring AI Alibaba)、dify、coze 等别的框架降到最低优先级,留作后期"验证框架可插拔"的适配目标——等 AgentScope 这条做扎实,再把它们一一适配进来,用这件事证明下面这条可插拔原则不是空话,而不是现在并行养两套编排。 如果每换一次引擎或框架,就要改一遍业务侧调用、改一遍验收门、改一遍落库,这套东西就废了。所以平台的第一原则是划一条线:哪些是**系统内固定的接口协议**,任何人换引擎换框架都不许动;哪些是**可插拔的实现模块**,换引擎换框架就是换它们。换框架等于接一个新 adapter,而不是动契约。这就是"可插拔 agent 平台"的全部含义——平台拥有协议,框架只租用、不拥有。一旦某个框架的私有结构悄悄渗进固定协议(轨迹格式被某框架的 span 绑死、任务协议泄漏框架内部状态),那就是锁死的开始,要立刻在协议层把它隔离回去。 -这条原则不是空谈"将来好换",它有具体落点:它正是将来要不要把某条轨从 SAA 切到别的框架时的判据。只要固定协议稳稳钉在那里,切换就只是换一个被治理的执行后端,而不是推倒重来。 +这条原则不是空谈"将来好换",它有具体落点:后期把 SAA、dify 适配进来时,固定协议钉在那里,适配就只是给它们各接一个被治理的 adapter、各包一个执行后端,而不是推倒重来——把它们适配进来这件事本身,就是对这条可插拔原则的验证。 **两块不外包的自研——这是护城河。** 采标准能解决绝大多数适配问题(见 §二),但有两件事没有主流对等物,必须自建:一是**确定性验收门**——在没有人、也没有看图模型的情况下,用纯代码机器判定一局游戏"真的可玩",判定权与"出题的和被考的绝不能是同一只模型"这条纪律不让步;二是**生成专属的断点续跑语义**——一次自治生成跑到哪、能否按平台口径续上,各框架自造、互不通用。这两块是平台真正的工程纵深,别人短期补不上。 @@ -61,7 +63,7 @@ date: 2026-06-24 │ · 〔自研·护城河〕确定性验收门(judge 禁自评 + per-tier verdict) │ └────────────────────────────────────────────────────────────┘ ↕ 标准端点(框架只要会说 A2A+MCP+OTel 即插入) - 可插拔 agent 框架:SAA(廉价线) / AgentScope(富游戏线) / 未来 dify·coze + agent 框架:AgentScope(主框架,三档统一编排) / SAA·dify·coze(最低优先级,远期适配验证可插拔) 沙箱 = microVM 沙箱抽象(每 run 独立 microVM、暴露 CDP);扩容 = 无状态 worker + 队列 + 共享 checkpoint ``` @@ -75,7 +77,7 @@ date: 2026-06-24 **① 成熟度分层(不是"全部已收敛")**:可即采的成熟子集 = **MCP Tools**、**A2A 任务壳**(状态/流式/发现)、**OTel GenAI span 映射**、**SKILL.md**;须隔离 / 标 maturity gate 的实验子集 = **MCP Tasks**(2025-11 引入、官方 experimental)、**durable-execution**(范式非标准)、**microVM 沙箱**(能力/成本待验)、**Langfuse 热取**(须调和 GitOps)。每条标准落定前补「权威来源 / 版本 / 成熟度 / 本项目采用位置 / 待验证项」五列。 -**② 可移植性是分层的,不是"白得"**:**协议边界可迁移**(A2A/MCP/OTel 接缝)是真;**业务语义层 net-new**——换引擎/框架时这些都要重写:prompt 语义与 few-shot、工具副作用、Workspace 文件系统、checkpoint schema、verdict schema、CDP/沙箱能力、cost/trace adapter。采标准把"换框架"从"推倒重来"降到"重写 B 类实现、A 类协议不动",**不降到零**。"框架可整体替换"在 MVP(两线分立、SAA 锁裸图、tier2 锁 AgentScope)实际收益≈零,降为远期可选、不作主论据。 +**② 可移植性是分层的,不是"白得"**:**协议边界可迁移**(A2A/MCP/OTel 接缝)是真;**业务语义层 net-new**——换引擎/框架时这些都要重写:prompt 语义与 few-shot、工具副作用、Workspace 文件系统、checkpoint schema、verdict schema、CDP/沙箱能力、cost/trace adapter。采标准把"换框架"从"推倒重来"降到"重写 B 类实现、A 类协议不动",**不降到零**。现阶段生产编排已收敛到 AgentScope 一套,SAA/dify 降为最低优先级;"框架可整体替换"的收益不在 MVP 当下省力,而在后期把 SAA、dify 适配进来这件事本身——它是对可插拔原则的验证,作此用、不作主论据。 **③ 扩容与沙箱降为 future-state + 独立选型**:K-槽**已参数化非反模式**(线程池+Semaphore(K)+K 错开端口槽+单测守);durable-execution 第 2 步独立选型(Temporal / DB queue+Redis lock / AgentScope MessageBus 等 **≥3 具名候选 + 排除理由**,按 [`.agents/rules/build-vs-buy.md`](../../../../.agents/rules/build-vs-buy.md) 硬门),先旁路 tier2、不动在产 SAA。沙箱抽象改名 **SandboxDriver**,先做能力矩阵(CDP/Chrome、文件 I/O、网络封锁、冷启动、并发、成本、数据主权),近期只承诺 Local/Docker/薄沙箱;microVM(E2B/AgentRun)云端多租户才需、AgentRun 厂商锁死。 @@ -221,7 +223,7 @@ agentscope 2.0.2 内置 Workspace 三后端(源码实证 `LocalWorkspace` / `Doc | **A12** | 通用检查门协议 | 提交侧(prompt 内容安全,fail-closed)+ 产物侧(体积门 / 逻辑扫描 / CSP),两时相、共用一道引擎无关门外壳 | 现·散三处 + 建(收成一门) | 自研 | | **A13** | 配置注册表协议 | model / prompt / skill / mcp 四类统一注册;分流判据 = 影响生成质量/安全(prompt、生成门阈值)走 GitOps 四闸不可热改,运营降级开关/阈值走 DB 热改 | 建(代码侧零落地) | 采 Langfuse 式运行时热取 | -A8–A13 这六面的共同状况:廉价线在生产里已把它们大多兑现,但都硬编码在单条 publish 链路上,从没抽成"两条生成线 + 各发行渠道共用"的固定接缝。这一轮不是从零造协议,而是把已长出来、却埋在单线实现里的接缝形状抬出来固定,并诚实标出哪几段已兑现、哪几段还空白。 +A8–A13 这六面的共同状况:低档在生产里已把它们大多兑现,但都硬编码在单条 publish 链路上,从没抽成"各档生成 + 各发行渠道共用"的固定接缝。这一轮不是从零造协议,而是把已长出来、却埋在单线实现里的接缝形状抬出来固定,并诚实标出哪几段已兑现、哪几段还空白。 ### 3.3 B 类:可插拔实现模块 @@ -229,13 +231,13 @@ B 类对接上面某几条 A 协议,换引擎 / 换框架 / 换渠道时被换 **换引擎轴——引擎能力包 + 探针实现。** 引擎能力包给 agent 提供在某引擎上写游戏的全套能力:写法 playbook(skill)+ 引擎文档范例(RAG 语料)+ 脚手架工程骨架 + 验收门探针的该引擎钩子实现。探针实现只兑现 A6(读帧 / canvas / state / 注入输入),绝不碰 A5 判定。 -- `B-ENG-LittleJS`(现,廉价线在跑)/ `B-PROBE-LittleJS`(现,九门 harness 生产已跑、判过大量游戏) +- `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-FRAMEWORK-AgentScope`(**主框架**,锁 2.0.2,三档生成统一经它编排,经 Agent Service 接 A1)、`B-FRAMEWORK-SAA`(**最低优先级**,留作后期"验证框架可插拔"的适配目标、非生产编排)、`B-FRAMEWORK-dify·coze`(同 SAA,远期适配验证) **换渠道 / 资产 / 品类 / 合规轴——平台面可插拔件。** @@ -248,27 +250,27 @@ B 类对接上面某几条 A 协议,换引擎 / 换框架 / 换渠道时被换 --- -## 四、两实例 +## 四、生成实例(三档 · 两引擎) -两条生成线是同一套 adapter 协议的两个实例,运行期零耦合,只在公共组件(计费 / 送审 / feed / 验收基线)交汇。 +三档生成都跑在 **AgentScope 一套框架**上,是同一套 adapter 协议在不同 **AI 参与深度**上的实例,运行期零耦合,只在公共组件(计费 / 送审 / feed / 验收基线)交汇。分档的轴只有一条——AI 写进游戏的内容与代码的深浅,**级别越高 AI 写得越多**;引擎只是实现、不是轴,按表现复杂度选:轻-中深度档用 LittleJS 增强发行版(§4.1)、最高深度档用 Phaser 多文件工程(§4.2)。三档都在玩法模板加工程脚手架上生成、没有一档从零写,最低档也得能商业闭环(无法闭环的超休闲不做)。SAA、dify 等别的编排框架降为最低优先级,留作后期适配验证可插拔、不进现阶段生产线。 -![图 · 全局两线与 tier 体系总览](assets/07-全局两线与tier体系.svg) +![图 · 全局档位与 tier 体系总览](assets/07-全局两线与tier体系.svg) -### 4.1 实例一:SAA · LittleJS 廉价线(Tier0/1) +### 4.1 轻-中 AI 深度档:LittleJS 引擎 · A-model 写真 src/ **范式(现行 = A-model)**:便宜模型在 LittleJS 增强发行版上**直接写真 `src/` 多文件游戏代码**、调 L2 插件库给手感卖相,再用九门把"是不是真能玩"判定下来。这是 2026-06-21 起的现行范式;它**取代了已废的 gameDefinition 路**(便宜模型吐声明式 JSON、运行时 `new Function` 解释——那条已判为错误路线,见下"废弃路线")。 -**创作入口已开闸为一句话直接驱动**:创作页不再强制先选模板,生成请求的 templateId 可选、缺省走 generic 通用路,玩法模板退化为可选的品类引导框架(经营 / 剧情 / 解谜 / TRPG / 非遗五品类,影响 prompt 与脚手架、不是可执行的游戏壳,旧"填参整局代码"产线已废,见 §三 A10)。这条主链贯通后,廉价线的端到端闭环是:创作页一句话 → 经 D12 配额与提交侧合规先行两道入口门(见 §5.2、§5.4)→ generic 的 SAA 生成路 → 轮询进度 → 过发布门入游戏 feed → 种子用户真人试玩。发布门走管理员审核台还是创作者自助直发是产品待裁项,种子期建议管理员把关。 +**创作入口已开闸为一句话直接驱动**:创作页不再强制先选模板,生成请求的 templateId 可选、缺省走 generic 通用路,玩法模板退化为可选的品类引导框架(经营 / 剧情 / 解谜 / TRPG / 非遗五品类,影响 prompt 与脚手架、不是可执行的游戏壳,旧"填参整局代码"产线已废,见 §三 A10)。这条主链贯通后,这一档的端到端闭环是:创作页一句话 → 经 D12 配额与提交侧合规先行两道入口门(见 §5.2、§5.4)→ generic 的 AgentScope 生成路 → 轮询进度 → 过发布门入游戏 feed → 种子用户真人试玩。发布门走管理员审核台还是创作者自助直发是产品待裁项,种子期建议管理员把关。 -**护城河 = 九门 harness(确定性自动验收)**:把随机、时间、输入全部收进受控种子;把胜负置成不可逆 latch 终态;把游戏世界投影成测试侧可按命名路径读取的取证形状。这三件合起来,九门 harness 才能用确定性对照"真玩一局并判定"。这是别人短期补不上的——竞品大多能让模型吐出能跑的代码,却无法机器化地证明它可玩。这套验证地板**引擎无关、判"能不能玩"不判"怎么写的"**,所以对 A-model 写的真 `src/` 工程同样适用(它正是廉价线从 gamedef 切到 A-model 时一行没动的资产)。 +**护城河 = 九门 harness(确定性自动验收)**:把随机、时间、输入全部收进受控种子;把胜负置成不可逆 latch 终态;把游戏世界投影成测试侧可按命名路径读取的取证形状。这三件合起来,九门 harness 才能用确定性对照"真玩一局并判定"。这是别人短期补不上的——竞品大多能让模型吐出能跑的代码,却无法机器化地证明它可玩。这套验证地板**引擎无关、判"能不能玩"不判"怎么写的"**,所以对 A-model 写的真 `src/` 工程同样适用(它正是低档从 gamedef 切到 A-model 时一行没动的资产)。 -**废弃路线 = gameDefinition(错误路线,已删)**:廉价线最初走的是 gameDefinition——便宜模型吐一份声明式结构化 JSON、运行时用 `new Function` 解释执行。2026-06-20 对抗式裁决揭穿了它名实不符:顶着"声明式结构化源"的名号,内核却是"声明式数据壳 + 一坨未受契约约束的自由 JS"(承载全部玩法逻辑的 `behavior.code` 根本没进契约),表达力被运行时焊死在四类几何色块玩具上、好玩好看无下限托底。**这条路已于 2026-06-21 判为错误路线、删除废弃**——不是"坚持做 Tier0",而是整条路被 A-model(写真 `src/`)取代。它的天花板正是 A-model 转向的由来。 +**废弃路线 = gameDefinition(错误路线,已删)**:低档最初走的是 gameDefinition——便宜模型吐一份声明式结构化 JSON、运行时用 `new Function` 解释执行。2026-06-20 对抗式裁决揭穿了它名实不符:顶着"声明式结构化源"的名号,内核却是"声明式数据壳 + 一坨未受契约约束的自由 JS"(承载全部玩法逻辑的 `behavior.code` 根本没进契约),表达力被运行时焊死在四类几何色块玩具上、好玩好看无下限托底。**这条路已于 2026-06-21 判为错误路线、删除废弃**——不是"坚持做 Tier0",而是整条路被 A-model(写真 `src/`)取代。它的天花板正是 A-model 转向的由来。 **A-model 怎么补上天花板**:A-model 让 LLM 直接写真 `src/` 多文件、调 L2 十一插件(juice / gamefeel / palettePost 给手感卖相),逻辑与表现都不再被声明式数据壳焊死。所以 tier1 高质轻游戏的载体是 **L2 能力库 + L3 自由写**,产物就是真 `src/` 工程——与 tier2 同范式(LLM 写真 src/),只是引擎(LittleJS vs Phaser)与表现层复杂度档不同。这条把"轻量≠简单"落到工程上:轻量是用公共素材、玩法模板、工程模板低成本生成相对不复杂、又不易同质化的高质小游戏,不是产没人会玩的简单玩具。 ![图 · 廉价线端到端闭环](assets/09-廉价线端到端.svg) -### 4.2 实例二:AgentScope · Phaser 富游戏线(tier2) +### 4.2 最高 AI 深度档:Phaser 引擎 · 富游戏 **范式**:一个自治的单写 ReAct agent 去造多系统耦合、稠密 UI、大内容量的富游戏,产物是真 Phaser 多文件源工程。骨架 = 自治 loop(怎么走)+ task/goal 清单(走向哪、走到哪)+ Agent Team 动态调度(谁来走),**没有预先画死的 workflow DAG**。 @@ -298,11 +300,11 @@ tier2 这条线另有一套总览图,与 §5 各 facet 的细化图互补: ## 五、运行时八面(facet) -> 八个 facet 是 §四 两实例的逐面放大,把两条线在每一面的设计讲到可照着实现的颗粒度。tier2 富游戏线的内容偏多——**它的核心已落、0 号 spike 已 accept**(各面"现/建"按 2026-06-24 `tier2/HANDOFF.md` 真相标注:多数已落,留后的是更多款的收敛环验证(n=5、有错追加 5)、阶段 1 Agent Team、控制面/管理面);廉价线在每一面以现行已落的对照锚出现。各面引用的 svg 大图在 `assets/`——**这些图是 0 号 spike 前视角(虚线、以及图内"整图状态 = 建·待 spike"小标都是当时的待建标记),现状真相以各面散文的"现/建"为准,不以图的虚线为准**(svg 重绘待 mini-desktop 出图管线)。 +> 八个 facet 是 §四 生成实例的逐面放大,把各档在每一面的设计讲到可照着实现的颗粒度。最高深度档(tier2 富游戏)的内容偏多——**它的核心已落、0 号 spike 已 accept**(各面"现/建"按 2026-06-24 `tier2/HANDOFF.md` 真相标注:多数已落,留后的是更多款的收敛环验证(n=5、有错追加 5)、阶段 1 Agent Team、控制面/管理面);低档在每一面以现行已落的对照锚出现。各面引用的 svg 大图在 `assets/`——**这些图是 0 号 spike 前视角(虚线、以及图内"整图状态 = 建·待 spike"小标都是当时的待建标记),现状真相以各面散文的"现/建"为准,不以图的虚线为准**(svg 重绘待 mini-desktop 出图管线)。 ### 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 补发。 +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 装配点,不为每种入场各写一条链路。 @@ -325,15 +327,15 @@ tier2 富游戏线的运行时按 AgentScope 2.0.2 的真实对象结构落地, ### 5.2 控制面与配置热取 -两条生成线共用一层治理面——让 agent 自治生成游戏还不够,平台还得能配置它(改 prompt、换模型、调 skill 不发版)、看见它(每次生成到底发生了什么)、审计它(谁改了哪条配置)、在入口拦住它(配额、并发、降级)。这就是创始人最早提的"像 Dify 一样可视化、可追踪、可审计地管 agent 平台"。控制面四个组件对两条线暴露同一套契约(读配置、写轨迹、过门),生成线只照契约办事、不感知管理面长什么样。 +各档生成共用一层治理面——让 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 只在严格时间盒的实验里跑、绝不规模化。 +**D12 运行治理门**把配额、并发、背压、降级、记账骨架焊在生成任务入口前,是已存在的件,本设计只复用、默认关闭、零行为变更进主干。它现在只覆盖廉价线,tier2 接进来的入口、预算扣减、并发释放、失败补偿还要补。它接上的是引擎那道"花到上限就拒绝执行"的预算闸,而成本强制是三层纵向叠、任一道先到上限即拦:worker 本地预测闸(动手前先估这一步要花多少,越本局预算就不发起调用,最便宜、调模型之前就拦)、网关配额闸(就是 D12)、任务 deadline 闸(超墙钟时间盒即停,兜住 token 没烧穿但卡在长循环的纯耗时失控)。**预算闸的硬上限按 AI 参与深度分档钉死**:低深度档一次生成 < ¥10、最高深度档 < ¥50,图像与音乐生成各走独立预算线、不计入这两个上限(初期"拉高、给足探索空间"的口径——对比 tier2 富游戏 spike 实测仅 ¥1.29;数字红线来源=创始人 2026-06-25,失效=单位经济或模型单价大变即复审)。取价通路不可达时要显式定一条策略——直接失败、宁停不超支,或降级到纯 token 上限兜底,不留模糊。这套三层强制落地之前,tier2 只在严格时间盒的实验里跑、绝不规模化。 -**管理面 UI** 是注册表与观测仓的视图与编辑器,不是真相本身——配置才是真相。它不从零造一个 Dify 式可视化建图器,因为裸图的节点是 Java 代码、ReAct 的工具也是代码,真相在代码与配置里,靠 UI 拖拽生成代码是另一套不可靠的范式。但"配置是真相、UI 是视图"不等于第一期什么都不做,管理面按三档诚实命名地落:phase-1 是配置管理加运行可观测(含一个纯只读、不依赖任何前置、立刻能给创始人看见的最小切片——看各角色当前用什么模型、回放任意一次生成的全轨迹、按 new-api 口径对账成本;其上再加配置编辑,改完落 Git 加审计、不直接热生效),phase-2 是限定范围的图编辑(节点启停、参数、版本 diff、轨迹回放,但渲染的拓扑来自运行时自报、不让用户拖拽改结构),phase-3 是完整可视化建图(拖拽改拓扑,远期不投)。一条贯穿约束:管理面对拓扑只渲染框架运行时自报的结构,绝不在管理面这侧另持一份拓扑模型——廉价线是静态图、tier2 的 ReAct 没有静态图,两套异构范式用同一个管理面,只能靠"渲染运行时自报"这个共同口径,而硬编码的拓扑模型在换框架时反而成为阻力。这也是反锁死(§一)在管理面的落点。 +**管理面 UI** 是注册表与观测仓的视图与编辑器,不是真相本身——配置才是真相。它不从零造一个 Dify 式可视化建图器,因为裸图的节点是 Java 代码、ReAct 的工具也是代码,真相在代码与配置里,靠 UI 拖拽生成代码是另一套不可靠的范式。但"配置驱动地建并部署一个 agent"这件事 **AgentScope Service 原生就给**:`/agent` 全 CRUD + `GET /agent/schema`(返回 agent 配置表单的 JSON Schema、专给配置 UI 用)——填表单(身份 / 模型 / 上下文 / 选哪些已注册的 skill·tool)→ `POST /agent` → Service 注册上线该 agent。管理面 phase-1 的配置管理直接建在它上、不用自造,这是统一到 AgentScope 的一个红利(SAA 裸图无此能力、只能配置值热取);但能配的永远是"选已注册的能力",新工具 / 新拓扑两边都得写代码、不拖拽生成。但"配置是真相、UI 是视图"不等于第一期什么都不做,管理面按三档诚实命名地落:phase-1 是配置管理加运行可观测(含一个纯只读、不依赖任何前置、立刻能给创始人看见的最小切片——看各角色当前用什么模型、回放任意一次生成的全轨迹、按 new-api 口径对账成本;其上再加配置编辑,改完落 Git 加审计、不直接热生效),phase-2 是限定范围的图编辑(节点启停、参数、版本 diff、轨迹回放,但渲染的拓扑来自运行时自报、不让用户拖拽改结构),phase-3 是完整可视化建图(拖拽改拓扑,远期不投)。一条贯穿约束:管理面对拓扑只渲染框架运行时自报的结构,绝不在管理面这侧另持一份拓扑模型——廉价线是静态图、tier2 的 ReAct 没有静态图,两套异构范式用同一个管理面,只能靠"渲染运行时自报"这个共同口径,而硬编码的拓扑模型在换框架时反而成为阻力。这也是反锁死(§一)在管理面的落点。 > **现 / 建(2026-06-24)**:D12 现行已落(默认关闭,在 SAA Java 后端);配置注册表是"现·部分"(prompt 构建期快照),热取、推广到 skill/tool/mcp、配置审计日志、管理面三 phase 待建。tier2 侧 `genconfig` 热配已落(雏形);控制面/管理面对 tier2 的接入(D12 入口、管理面 UI)按 plan 决策⑤ 留 Phase B。 ![图 B1 · 控制面四组件](assets/t2-B-01-控制面四组件.svg) @@ -350,7 +352,7 @@ tier2 富游戏线的运行时按 AgentScope 2.0.2 的真实对象结构落地, **为什么单写、不并行写**:经营游戏的多个系统共享同一套状态与约定,拆给并行 agent 几乎必然不一致。一手教训是曾把"造 Flappy Bird"拆给并行子 agent,背景跑成了马里奥。单写意味着只有一个 agent 持整个工程的全局视图。要分清边界:单写只管阶段 2 写代码这一环,阶段 1 的工作室设计仍用 Agent Team 星形多 agent 发散——设计要发散与专业分工,实现要防写冲突而收敛到单写。 -**为什么把多轮放进 Agent 内、而不是外层**:tier2 与廉价线 WG1 的真正差别不在 prompt、不在生成域,而在"多轮自治放在哪一层"。WG1 是 `ReActConfig(max_iters=1)` 单轮加外层 repair 重试——单写、单轮、靠外层喂错重跑;它故意单轮,是为压便宜档的单价(廉价线生产主线明确不引 AgentScope,框架的 token 膨胀会吃掉便宜档的利润)。tier2 原打算把多轮搬进 Agent 内部 ReAct(放开 max_iters),但 **0 号 spike 实测推翻了"纯内部多轮"**:AgentScope 2.0.2 原生 ReAct 一旦模型产出"无 tool_call 的纯文本回合"就退出,M3 调一次 run_gates 看到 fix 就收尾、根本没续修——纯自治 ReAct 会过早放弃。**修法是回归 wg1 的"有界外层 resume"范式**:编排层(`studio.py`)在 agent 停下后,若没真 finish、门没绿、还有预算,就带 verdict 失败反馈再 reply(跨 reply 保留 memory = 原地续修),上限 6 次,外加 finish 门(门没绿不许 finish)。所以"多轮放哪一层"的最终答案不是"搬进 Agent 内部",而是"内部 ReAct 单轮 reason→act + 有界外层 resume 续修",即 wg1 外层 repair 范式从单轮放到多轮。参照系是 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。 +**为什么把多轮放进 Agent 内、而不是外层**:tier2 与低档 WG1 的真正差别不在 prompt、不在生成域,而在"多轮自治放在哪一层"。WG1 是 `ReActConfig(max_iters=1)` 单轮加外层 repair 重试——单写、单轮、靠外层喂错重跑;它故意单轮,是早期为压便宜档单价的做法——当时怕 AgentScope 框架的 token 膨胀吃掉便宜档薄利润。但单次预算抬到低深度档 < ¥10 后这条约束放松了,三档已统一改用 AgentScope 编排;WG1 单轮省 token 的优势退为 SAA 远期适配时的备选,不再是"不引 AgentScope"的理由(见 §一、§5.2 预算闸)。tier2 原打算把多轮搬进 Agent 内部 ReAct(放开 max_iters),但 **0 号 spike 实测推翻了"纯内部多轮"**:AgentScope 2.0.2 原生 ReAct 一旦模型产出"无 tool_call 的纯文本回合"就退出,M3 调一次 run_gates 看到 fix 就收尾、根本没续修——纯自治 ReAct 会过早放弃。**修法是回归 wg1 的"有界外层 resume"范式**:编排层(`studio.py`)在 agent 停下后,若没真 finish、门没绿、还有预算,就带 verdict 失败反馈再 reply(跨 reply 保留 memory = 原地续修),上限 6 次,外加 finish 门(门没绿不许 finish)。所以"多轮放哪一层"的最终答案不是"搬进 Agent 内部",而是"内部 ReAct 单轮 reason→act + 有界外层 resume 续修",即 wg1 外层 repair 范式从单轮放到多轮。参照系是 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 来绕过它)、双层超时(单步钉死一次工具调用、整局钉死本局总时长)。这套熔断 tier2 是**自建的、且实际比"软刹"强**——要纠一处早稿错:早稿把"官方 `ReplyBudgetControlMiddleware` 软刹"当现成件,但 2.0.2 源码核验**该类根本不存在**;tier2 用自建的 `on_system_prompt` 变换钩子 + 中间件洋葱上订阅模型调用结束事件的硬熔断替代,把 token 按 new-api 计费口径折成 ¥ 累进、越过硬上限就 fail-closed 直接终止本次生成(spike 实测 60/80 轮硬熔断兜底已落,比"软刹优雅收尾"强)。这道硬闸的三层强制架构见 §5.2。 @@ -371,7 +373,7 @@ tier2 富游戏线的运行时按 AgentScope 2.0.2 的真实对象结构落地, 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 独立仓已归档、能力并入 2.0.2,所以先小验 agentscope 2.0.2 内置 Workspace 的 Docker 后端能否托管这套 CDP 探针(它是 MCP-gateway 工具沙箱、不直接暴露 CDP),够就用、不够回落自建 Docker 薄沙箱复用现有 harness——这个结论必须在生成迭代开跑前出来,出不来整个 spike 跑不起来。 +现有九门是为低档的 LittleJS 建的,探针钩子硬编码了 LittleJS 专属取法。tier2 复用的是"真玩判定加零自评"这套哲学、**不是**这套代码,探针要为 Phaser 整套重写——canvas 选择器、帧源、boot 信号、输入注入与 state 读取四条钩子各自重写,不是参数化一键切。沙箱底座是 spike 的前置阻断项:agentscope-runtime 独立仓已归档、能力并入 2.0.2,所以先小验 agentscope 2.0.2 内置 Workspace 的 Docker 后端能否托管这套 CDP 探针(它是 MCP-gateway 工具沙箱、不直接暴露 CDP),够就用、不够回落自建 Docker 薄沙箱复用现有 harness——这个结论必须在生成迭代开跑前出来,出不来整个 spike 跑不起来。 九门是超休闲单局的机制地板,不查跨系统接线;富游戏的难点恰在跨系统,所以在九门之上补三道 tier2 专属的确定性门。**三联动门**证三个系统真耦合而非孤岛:订单要的物品必须能被合成系统产出(从合成链静态推到订单的跨表可达性检查)、合成链必须是有向无环图(拓扑检查不许成环)、完成订单时必须真调资源系统加金币、合成消耗时必须真调扣食材。**经济门**用真输入把两条路驱动到终态:可盈利路径(金币从开局攒到目标判赢)、可破产路径(连续若干订单流失判输),关键约束是两条路都得被 harness 的真输入序列驱动跑到终态——能在数据表里算出来和能被真玩到是两回事。**latch 门**管终态落定不回弹、宿主能读到终局,承接的是"游戏无 emit 通道、终态焊成可轮询 latch、宿主轮询读"这条现行装载约束。九门加这三门合起来全绿,才算 tier2 的富游戏机制地板通过。 @@ -380,7 +382,7 @@ L1 的主体是九门,每门在真浏览器里真玩一局取确定性证据:A_b 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)。 -> **现 / 建(2026-06-24 spike 后)**:廉价线九门现行已落。tier2 侧——三层校验框架、Phaser 探针(九门 + 富游戏三门:三联动/经济/latch)、L3 视觉软检 observe-only 接线**已落并在 feie-005 全过**;spike 收敛补的四道契约机器门(`validate_datatable` 数据表 schema+DAG+可达性、`LOCKED_PLATFORM_FILES` 锁平台文件、`validate_play_scene` 表现层契约、finish 门)也已落。待:自产 driver 三层隔离(spike 第二段)、偏脆的文本契约门做成结构化校验。 +> **现 / 建(2026-06-24 spike 后)**:低档九门现行已落。tier2 侧——三层校验框架、Phaser 探针(九门 + 富游戏三门:三联动/经济/latch)、L3 视觉软检 observe-only 接线**已落并在 feie-005 全过**;spike 收敛补的四道契约机器门(`validate_datatable` 数据表 schema+DAG+可达性、`LOCKED_PLATFORM_FILES` 锁平台文件、`validate_play_scene` 表现层契约、finish 门)也已落。待:自产 driver 三层隔离(spike 第二段)、偏脆的文本契约门做成结构化校验。 ![图 D1 · 三层校验全景](assets/t2-D-01-三层校验全景.svg) ![图 D2 · 九门逐门](assets/t2-D-02-九门逐门.svg) @@ -399,9 +401,9 @@ spike 第二段放开让 agent 自产或扩展 driver 时,会撞上一个 Goodha 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)。 +tier2 与 A-model(低档那条 LittleJS 轻量经营档)**两档分立、运行期零依赖**(引擎不同,但同走 AgentScope 编排),但 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 与代码里、不进本文。 +SAA 那一侧的能力面是另一套形态,但它现已降为最低优先级、留作后期"验证框架可插拔"的适配目标,不再是活的生产能力面:SAA 用裸 `StateGraph` 加自定义 `NodeAction` 手写确定性编排,模型层直接复用上游 spring-ai 的 `OpenAiChatModel`(baseUrl 指 new-api、多个 bean 仅 model 名不同),checkpoint 用 `MysqlSaver` 单权威。它和 tier2 的能力面同源于"框架可换、契约不变"的原则;两者的差别是它把编排做成裸图确定性多步、tier2 是给 LLM 一堆工具自决,这正是后期把 SAA 适配进来时要验证的"异构框架共用同一套固定协议"。具体的图原语 API、repair 回边、子进程调用与依赖冲突避让属实现细节,落在配套 playbook 与代码里、不进本文。 > **现 / 建(2026-06-24 spike 后)**:九门 harness 钩子、A-model 四插件契约、SAA 能力现行已落(SAA 一侧基于 v1.1.2.2 真实源码四路取证)。tier2 侧——九工具的 Phaser 实现(含 `write_source` 的 `LOCKED_PLATFORM_FILES` 锁:拒改 main.js/game-core/systems/layout/tables/play-runtime)、mmx 资产工具、阶段 2 单写 ReAct **已落并经 feie-005 accept**。待:阶段 1 工作室 Agent Team(留 Phase B,spike 只跑阶段 2 单写)、五件套通用接口(克制:只有 Phaser 一个真实现时不抽,等第二引擎落地有两实现再抽)。 ![图 E1 · skills 清单](assets/t2-E-01-skills清单.svg) @@ -414,11 +416,11 @@ tier2 与 A-model(廉价线那条 LittleJS 轻量经营档)**两线分立、运 ### 5.6 源项目契约与装载 -两条线的装载分流在这里劈开。**廉价线左支**是 LittleJS engineBundle 装载(A-model 写的真 `src/` 构建成 engineBundle;原 gamedef 数据壳已废,但装载机制不变):一款游戏就是库里一条 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,能力经受控接口注入。 +两引擎的装载分流在这里劈开。**LittleJS 左支**是 engineBundle 装载(A-model 写的真 `src/` 构建成 engineBundle;原 gamedef 数据壳已废,但装载机制不变):一款游戏就是库里一条 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 的契约。 +这套契约必须另立独立 schema、编为契约组的新一类,绝不复用低档那份同名的 ECS-lite 数据壳契约——撞名但语义完全不同,共用一份会把本该解耦的两档焊在一起、改 tier2 时污染在产线上跑的低档。同样地,A-model 把它的源项目 schema 升成了绑定 LittleJS 装载路的变体,tier2 的 Phaser 工件走另一条装载序列,另立独立 schema、不并进同一个 keystone,避免把 Phaser 的差异焊进 LittleJS 的契约。 右支的装载比左支多出一段:入库的是一个真 Phaser 工程(多源文件加构建脚本加依赖锁),取回之后要先按构建 profile 用 esbuild 打包出可玩 bundle,再在沙箱里跑——这一段构建是左支即取即跑所没有的。`finish` 工具交付的形状与落库取回认的形状**共用同一份 schema**:agent 自治跑完经 finish 吐出的那个工程,和落库取回认的那个工程本是两处定义,共用一份则"契约即工具签名,改一处即两处一起改",从源头消除交付与落库漂移这个失败面。装载终态仍服从 latch 轮询:游戏跑到结束态时不主动发事件,而是把状态焊成可轮询的终态、宿主每帧轮询读。整条线的产物是可维护的源工程而非死 bundle,改源、重新构建、按内容哈希长期取回重建——这正是"改源不改包、游戏即长生命周期项目"在装载面的兑现。 @@ -433,13 +435,13 @@ tier2 与 A-model(廉价线那条 LittleJS 轻量经营档)**两线分立、运 ### 5.7 观测与成本(OTel) -一份 trace 契约要管两条异构的线,办法是**接口层对称、内容层不对称**:一个对称的公共核心子集加各轨一个不对称的 JSON 扩展段。消灭轨迹分散(split-brain)的真口径是"每条派发路诚实镜像它真有的字段、没有的绝不编造",而不是强求两条线字段对齐——tier2 是 ReAct 的"想一步、做一动作、看一结果",廉价线是十六节点的阶段裁决,本就不同构,强求对齐等于逼一条线编造它根本没有的字段。公共核心子集是五个字段(`traceId`、`step`、`cost`、`verdict`、`timestamp`),两条线必填、同名同义;扩展段各写各的——廉价线塞阶段、修复轮次、门裁,tier2 塞推理、动作、观察。这份契约约束的是数据口径、不是采集机制:采集各按各的框架来,数据口径不随框架漂移。它该落成 `contracts/trace/` 下契约组的新一类,含字段定义、schema 版本、脱敏规则、两条线 adapter 怎么映射,以及一条策略——轨迹写不进去时默认 best-effort 不阻塞主生成流程、但落一条告警(不能让一次落库抖动废掉整局已跑出的生成,也不能让它无声丢失)。这一位当前还没建,随 spike 或控制面 phase-1 落地再新立,别当现成件引用。 +一份 trace 契约要管多个异构框架的 adapter——AgentScope(ReAct)为主,SAA(十六节点裁决)是远期适配进来时的另一个 adapter——办法是**接口层对称、内容层不对称**:一个对称的公共核心子集加各轨一个不对称的 JSON 扩展段。消灭轨迹分散(split-brain)的真口径是"每个 adapter 诚实镜像它真有的字段、没有的绝不编造",而不是强求各 adapter 字段对齐——ReAct 是"想一步、做一动作、看一结果",SAA 是十六节点的阶段裁决,本就不同构,强求对齐等于逼一个 adapter 编造它根本没有的字段。公共核心子集是五个字段(`traceId`、`step`、`cost`、`verdict`、`timestamp`),各 adapter 必填、同名同义;扩展段各写各的——SAA 那条塞阶段、修复轮次、门裁,ReAct 塞推理、动作、观察。这份契约约束的是数据口径、不是采集机制:采集各按各的框架来,数据口径不随框架漂移。它该落成 `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 调试和对账当下就用得上,不等于现在就铺独立基建。 +采集机制采 **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 按核心子集加扩展段映射进统一表。SAA 那条 Java 线远期适配进来时,则按自己的节点裁决埋点、走同一份契约的另一个 adapter。各 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 就是真实的倍率成本,比按公开单价估更准。OTel 的语义约定里没有成本属性,所以"成本钉 new-api 计费行"这条自研口径要保留,经 traceId 关联进 trace。这里有一个红线缺口:M3 那一档走 Anthropic 原生端点,而现有成本记录只覆盖 OpenAI 路,抓不到它,于是 M3 这档的 token 用量采不到、单款成本对它直接缺、全矩阵成本没法对比。接点是补一个包住 Anthropic 模型调用的录制变体,抓每次按模型分列的 token 用量,把 Anthropic 路补齐。计费平面的纪律是"协议自由、计费收口"——M3 走 Anthropic 端点、便宜档走各自端点,协议与 SDK 不锁死、每档走各自最优端点,但所有路最终都收口到 new-api 的 quota 按模型折 ¥ 这一个计费平面。成本台账按 AI 深度档对账硬上限:低深度档一次生成 < ¥10、最高深度档 < ¥50,图像与音乐生成各走独立预算线、不计入这两个上限(数字红线来源=创始人 2026-06-25,失效条件=单位经济或模型单价大变即复审)。 -> **现 / 建(2026-06-24 spike 后)**:tier2 侧全部已落并真跑验证——`Tier2TraceMiddleware` 挂 writer agent 最外层洋葱、ReAct 全事件旁路 ingest 进 TraceAdapter(真跑 647 事件 dropped=0);`RecordingChatModel.records` 经 `newapi_pricing.py`(活读 new-api /api/pricing 倍率,取不到回落显式参数并告警、不中断主链)折 ¥(真跑 cost_rmb=1.29);`contracts/trace/` 已立 additive 事件契约位(忠实 trace.py 真实 sink 形状)。待:统一 trace 契约的 SAA 侧 adapter 映射(两条线对齐)。NEWAPI_KEY、端点、机器见 `docs/内网凭据与端点.md`。 +> **现 / 建(2026-06-24 spike 后)**:tier2 侧全部已落并真跑验证——`Tier2TraceMiddleware` 挂 writer agent 最外层洋葱、ReAct 全事件旁路 ingest 进 TraceAdapter(真跑 647 事件 dropped=0);`RecordingChatModel.records` 经 `newapi_pricing.py`(活读 new-api /api/pricing 倍率,取不到回落显式参数并告警、不中断主链)折 ¥(真跑 cost_rmb=1.29);`contracts/trace/` 已立 additive 事件契约位(忠实 trace.py 真实 sink 形状)。待(远期):SAA 适配进来时补它那侧的 adapter 映射,与 ReAct 共用同一份 trace 契约。NEWAPI_KEY、端点、机器见 `docs/内网凭据与端点.md`。 ![图 H1 · trace 统一契约](assets/t2-H-01-trace统一契约.svg) ![图 H2 · 观测管道](assets/t2-H-02-观测管道.svg) @@ -450,7 +452,7 @@ tier2 与 A-model(廉价线那条 LittleJS 轻量经营档)**两线分立、运 把 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 归因"这条目标态有落点,也防止把本该热配的东西硬编码进机制。 +复用边界看两个维度:来源(官方现成,即 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。**这里要纠一处早稿错**:早稿还列了"软预算控制用官方 `ReplyBudgetControlMiddleware`",但 0 号 spike 期 2.0.2 源码核验**该类不存在**——这一项不属"改用官方",反而归下面"必须自建"(tier2 已用自建 `on_system_prompt` + 订阅模型调用结束事件的硬熔断实现)。官方确实没有、必须自建或引第三方的是:RAG 检索管线、评测模块、成品级的框架互通、以及两块护城河——确定性验收门(框架不提供)和强制 fail-closed 的预算硬闸。