From 27584a1fdbb89bd0e45d18d7acdcca89851d86bc Mon Sep 17 00:00:00 2001 From: lili Date: Wed, 24 Jun 2026 22:27:39 -0700 Subject: [PATCH] =?UTF-8?q?docs(=E7=94=9F=E6=88=90=E5=BC=95=E6=93=8E):=20S?= =?UTF-8?q?oT=E2=91=A0=20Step2=20=E2=80=94=208=20facet=20=E5=B9=B6?= =?UTF-8?q?=E5=85=A5(=E8=BF=90=E8=A1=8C=E6=97=B6=E5=BD=A2=E6=80=81/?= =?UTF-8?q?=E6=8E=A7=E5=88=B6=E9=9D=A2/ReAct/=E6=A0=A1=E9=AA=8C=E4=B9=9D?= =?UTF-8?q?=E9=97=A8/=E8=83=BD=E5=8A=9B=E9=9D=A2/=E6=BA=90=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE/=E8=A7=82=E6=B5=8B/=E5=9B=9B=E5=B1=82)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 经 4 个非重叠抽取代理浓缩 ~2600 行源文档,亲笔写成散文并入: - 5.1 运行时形态:Agent Service/session三路/Agent非常驻+AgentState/Workspace双轴/Middleware洋葱 - 5.2 控制面与配置热取:四组件/采Langfuse热取替构建期快照/热改vs GitOps/三层预算强制/管理面三phase - 5.3 单写ReAct循环:一轮闭环/多轮进Agent内/四熔断+硬闸自建/M3原生接法/承A-model - 5.4 三层校验与九门:L1/L2/L3+九门逐门+富游戏三门(联动/经济/latch)+advisory分级+自产driver三层隔离 - 5.5 能力面:九工具三类/引擎能力包五件套/prompt两阶段/A-model四插件复用/SAA能力 - 5.6 源项目契约与装载:七要素四组/独立schema不复用/第二装载分支/finish共用schema - 5.7 观测与成本:统一trace契约(对称核心+扩展段)/采OTel GenAI/成本钉new-api quota - 5.8 四层职责:职责视角叠真实结构/复用边界二维/六项该删改官方/三类配置 治理:零 file:line/hash/实现代码;九门逐门归本文运行时视角,验收门完整命题指向 ③。 Co-Authored-By: Claude Opus 4.8 (1M context) --- .../架构/生成引擎/agentic运行时架构图说.md | 111 +++++++++++++++--- 1 file changed, 94 insertions(+), 17 deletions(-) diff --git a/docs/architecture/架构/生成引擎/agentic运行时架构图说.md b/docs/architecture/架构/生成引擎/agentic运行时架构图说.md index eaeb409e..8ef33a7e 100644 --- a/docs/architecture/架构/生成引擎/agentic运行时架构图说.md +++ b/docs/architecture/架构/生成引擎/agentic运行时架构图说.md @@ -165,47 +165,124 @@ B 类对接上面某几条 A 协议,换引擎 / 换框架 / 换渠道时被换 ## 五、运行时八面(facet) -> **本章为 Step 2 待并入区**。下面八个 facet 是 §四 两实例的逐面放大,内容从原细节图说与详设并入(去重、剥实现/定位细节后)。每节先给一句话 scope + 待并入来源,Step 2 替换为并入后的散文与图。 +> 八个 facet 是 §四 两实例的逐面放大,把两条线在每一面的设计讲到可照着实现的颗粒度。tier2 富游戏线的内容偏多——它整轨待 spike、设计密度最高;廉价线在每一面以现行已落的对照锚出现。各面引用的 svg 大图在 `assets/`。 ### 5.1 运行时形态 -Agent Service 与 session 三路径、Agent 非常驻 + AgentState、Workspace 双轴注入、Middleware 洋葱。 -*待并入:`tier2细节图说-A-运行时形态.md`、`agentic运行时架构图说`(原图 1/2/3)、`tier2四层工程架构.md`(environment 层)。* +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 控制面与配置热取 -两条生成线共用的治理层:配置注册表(配置即数据、改配置不发版)、观测/审计仓、D12 运行治理门、管理面 UI 三档;配置 model/prompt/skill/mcp 四类的热改 vs GitOps 分流判据;采 Langfuse 式运行时热取替后端构建期快照。 -*待并入:`agentic集成架构.md`、`tier2细节图说-B-控制面与管理面.md`、`prompt治理.md`(指针,详设在 ② SoT)。* +两条生成线共用一层治理面——让 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 循环 -ReAct 一轮(组装 context → reason 调 M3 → 判断调工具或收尾 → act 去 Workspace 写码/构建/真跑 → CDP 取证 → 三层校验 → 没过 repair → checkpoint)、多轮自治、四道熔断 + 预算闸(软刹官方 / 硬熔断与 ¥ 台账自建)、承 A-model 单写范式。 -*待并入:`tier2细节图说-C-单写ReAct循环.md`、`agentic运行时架构图说`(原图 4)、`tier2实现详设.md`(循环段)。* +阶段 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 必解 / L2 尽量 / L3 只评分)、九门逐门(A 装载 / C 掌帧 / D 真渲 / E 活性 / F 接线 / G 输入 / H 进展 / I 控制)、富游戏专属门(三系统联动 / 经济 / latch)、advisory 分级 + Goodhart 隔离、CDP 探针 Phaser 重写;验收门 = 自研护城河,机器判 + 禁自评。 -*待并入:`tier2细节图说-D-三层校验与九门.md`、`引擎与运行时.md`(九门段)、`agentic运行时架构图说`(三层校验表)。验收门完整命题详设在 ③ `验收门.md` SoT,本节只给运行时视角。* +验收分三层,处置力度递减。**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 逃避卡死探测)。 + +> **本节是运行时视角的门与判定**;确定性验收门作为护城河的完整命题(机器判、禁自评、出题≠被考、W-G1 批跑、per-tier verdict 元协议)是独立 SoT,见 [`验收门.md`](验收门.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 工具 -toolkit 九工具签名、引擎能力包五件套(写法 skill / RAG 语料 / 脚手架 / 探针钩子 / 工具薄壳)、prompt 两阶段角色、A-model 插件复用;采 MCP-native 暴露工具、采 SKILL.md 承载 playbook。 -*待并入:`tier2细节图说-E-能力面skills与prompt.md`、`SAA能力API-dossier.md`、`tier2四层工程架构.md`(能力库层)。* +单写 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 源项目契约与装载 -源项目契约七要素四组(身份 / 工程骨架 / 构建可复现 / 落库取回)、第二装载分支(取产物 → boot → 每帧 update/render → latch 终态轮询)、finish 工具共用 A3 schema、改源不改包的长生命周期寻址。 -*待并入:`tier2细节图说-F-源项目契约与装载.md`、`固定游戏架构.md`(装载契约段)、`agentic运行时架构图说`(原图 7)。* +两条线的装载分流在这里劈开。**廉价线左支**是声明式结构化源的固定架构:一款游戏就是库里一条 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/t2-F-01-源项目契约七要素.svg`、`assets/t2-F-02-第二装载分支.svg`、`assets/t2-F-03-finish共用schema.svg`。 ### 5.7 观测与成本(OTel) -统一 trace 契约(公共核心子集对称 + 扩展段各写各的)、观测管道(Event System → TracingMiddleware → OTel → Studio)、成本台账(钉 new-api 计费行、token×单价折 ¥);采 OTel GenAI semconv。 -*待并入:`tier2细节图说-H-观测与成本.md`、`agentic集成架构.md`(观测/审计仓段)。* +一份 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 四层职责 -四层职责视角(environment / harness / context / prompt)叠在 AgentScope 真实结构上;复用边界二维(来源:官方现成 vs 自建 × 共享:两线公共 vs tier2 私有);每个自建项标载体类型(Tool / Middleware / Skill / Prompt / Memory / Schema)。 -*待并入:`tier2四层工程架构.md`、`tier2实现详设.md`、`agentic运行时架构图说`(原图 6 复用边界)。* +把 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。 ---