zizi d5efe45f71 docs(agentic): 回写 tier2 三份设计档对齐图说(2.0.3真实结构/三层校验/两阶段/二维复用/service化)
把图说确立的本次校正回写进设计档、supersede 旧表述(均经 agentscope 2.0.3 源码实证):
- 四层工程架构: 四层→职责视角(environment=Workspace 双轴注入·Agent 非常驻) / 双层→三层校验 / 复用契约→二维+6项改官方+载体类型 / 补两阶段·service化·goal-task·无 workflow DAG
- 实现详设: 运行时形态(两阶段/service化/session三路径) + 三层校验 + M3 接入(AnthropicChatModel+base_url+thinking) + 建设五步锁2.0.3 + 源项目契约复用 finish schema
- 集成架构: 官方 Agent Service + Agent Team(MsgHub已删) + session三路径 + workflow范式(无DAG+未来需求登记) + trace=Event System+OTel+Studio + 预算软刹官方/硬熔断自建
- 待定: 记忆载体 ReMe(独立框架·要自接) vs mem0(2.0.3官方内置 middleware)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 13:08:15 +00:00

42 KiB
Raw Blame History

tier2 四层工程架构

🚧 评审版 · 已纳入 AGENTS.md §6.8 Codex+Opus 双评审发现并修订;并据《agentic 运行时架构图说》(基于 agentscope 2.0.3 源码实证)做了一次架构校正(2026-06-22),用现行真相 supersede 了若干旧表述,见各节内说明;残留跨档项见 §11。基于《tier2 实现详设》,尚未落代码;过了 0号 spike 才进建设。

这是什么:tier2 自治富游戏轨作为一个独立 AgentScope 模块的内部工程架构 —— 拆成 environment / harness / context / prompt 四层,逐层说清职责、边界、复用 AgentScope 的哪些能力、哪些是硬代码、哪些可配置、是复用/启用/新建。 重要校正(2026-06-22):这四层不是 AgentScope 的真实对象结构,而是一个"职责视角" —— 它叠在 AgentScope 2.0.3 的真实结构(Agent / Workspace / Toolkit / Middleware / AgentState / Agent Service)之上。读本档时请始终带着这层对应关系:environment 这个职责对应的真实载体是 Workspace(它沿两轴注入 Agent,Agent 持有它的引用、并不嵌在它里面);harness 这个职责对应的是 Agent 的 ReAct 循环原语 + Middleware 洋葱 + 自建验收门;context / prompt 则是组装进模型窗口的运行时载荷与离线指令。术语逐项映射见图说 §6。 给谁看:要搭这个独立模块的工程师;拿它去 ce-plan 排执行的人;评审四层切分、硬/软边界、复用契约是否成立的人。 与邻档关系:《自治富游戏引擎》给内核范式(O2 约束自治、Phaser/Pixi 选型、效果验收),《tier2 实现详设》给源项目契约+0号 spike runbook+建设五步+退路树,《agentic 集成架构》给两线共用的控制/管理面,《agentic 运行时架构图说》给整条生命周期的看图入口 + agentscope 2.0.3 源码实证的术语映射。本档只回答:这个独立模块内部怎么按四层职责把地基搭起来 —— 是建设五步第一、二步(底座 + 配置外置)的工程落点,不重排那几份。


1. 三个定调:独立模块 + 复用契约 + 四层职责视角

1.1 独立模块,SAA 可删,独立锁定 AgentScope 2.0.3

tier2 是一个独立的 AgentScope 模块:自己的运行环境、依赖、工具、演进节奏,对现有 SAA 廉价线(game-cloud 里 Java 写的 16 节点 StateGraph)运行期零耦合。这把《自治富游戏引擎》那条最硬边界("tier2 任何改动不许碰、不许回归现有廉价线")推到逻辑终点。

因为是独立 env、独立锁版,tier2 把 AgentScope 版本钉死在 2.0.3,与 SAA 线不强制同版,规避破坏式升级的版本耦合(2.0 是对 1.x 的破坏式重写)。本档后文一切 AgentScope API 都以 2.0.3 源码实证为准(/root/oss/agentscope,逐条核过):没有独立的 ReActAgent——统一是 Agent + ReActConfig(max_iters 默认 20);拦截扩展点是 MiddlewareBase 洋葱(6 个 hook:on_reasoning / on_reply / on_acting / on_model_call / on_compress_context / on_system_prompt),不是 agent hooks;状态载体是 pydantic AgentState(含 cur_iter / context / tasks_context),不是 1.x 的 state_dict / Session;agentscope.init(studio_url=…) 不存在——可观测走纯 OTel(TracingMiddleware)。⚠️ 这几条 supersede 了本档早稿里"2.0.1"、"ReActAgent"、"state_dict checkpoint"、"Studio trace / agentscope.init"的旧假设。

对外暴露方式 = service 化、用官方 Agent Service,不自造 API(2026-06-22 校正):tier2 是一个独立 service,game-cloud 经它调用;但它不自己手搓 REST/会话层,而是直接用 AgentScope 官方的 Agent Service —— create_app 起 FastAPI,自带 REST + SSE(流式 event,断线可 replay)、多租户、durable 会话。会话初始化有三条加载入口:① 续接之前会话(取历史 resume)② 加载已有游戏工程(Workspace.workdir 指向已有目录 → 迭代)③ 新建(阶段 2 模板初始化工具铺模板)。这条与"Agent 非常驻"一致:Service 收到一次 run 请求才现组装 Agent,状态落 AgentState

要钉死一处口径(双评审 M1/M2 指出本档曾与《详设》冲突):tier2 以现有 wg1/gen-worker/worker/agent_loop/studio.py 为种子,一次性拷贝/借鉴其已验证的 AgentScope 用法,然后独立演进、运行期零依赖、不回写。这既吃到"躯干七成已在"的复用红利(《详设》语),又不破"独立模块、SAA 可删"——它是 fork-为-起点,不是 in-place 演进共享的 studio.py。《详设》第一步"演进 studio.py"的措辞需据此对齐(§11 跨档 TODO)。

1.2 复用契约:二维(来源 × 共享)+ 四类获取边界

双评审最重的一组发现(Opus B1/M2/M4、Codex M1/M6)是:本档曾把"上游库有某 API"或"框架理论提供某能力"笼统写成"复用",夸大了地基的现成度。2026-06-22 校正进一步把复用判断收敛成一张二维坐标(supersede 早稿那种把"复用/边界"扁平列举的画法):

  • 维度一·来源:官方现成(AgentScope 2.0.3 自带) vs 自建(tier2 或两线团队自己写)。
  • 维度二·共享:两线公共(SAA 廉价线与 tier2 都用) vs tier2 私有。

由这两维交叉出关键结论:"公共组件 = 自建 ∩ 共享" —— 它们是团队自建的、被两线共用的件(九门 / 三层校验 / CDP / 计费 / 送审 / feed / trace),不是现成的官方能力。别把"框架里有"误当成"公共组件"。完整二维全景见图说图 6,本节只点出对四层地基影响最大的一条校正:

6 项早稿打算自建、现改用 AgentScope 官方现成(这是本次校正对地基现成度的最大上修):

能力 早稿口径 校正后用官方
token 计量 拟自建台账 ChatUsage(model response 自带)
软预算控制 拟自建预算 middleware ReplyBudgetControlMiddleware(官方)
结构化输出 拟自建 schema 校验 generate_structured_output(model 层)
可观测 trace 早稿写 Studio trace TracingMiddleware(纯 OTel)
经验召回 拟自建案例库 ReMe(经验/记忆框架)
多 agent 总线 拟自建协调 Agent Team(TeamCreate/AgentCreate/TeamSay)

⚠️ 一处实证差异、需创始人确认:在 /root/oss/agentscope 2.0.3 源码里,树内捆绑的长期记忆后端是 mem0 middleware;"经验召回 ReMe"是 AgentScope 生态里独立的记忆框架,本档沿用图说(SoT)的 ReMe 口径登记。落地选 ReMe 还是树内 mem0,留 spike 前小验证 + 创始人定。

官方"没有"的(别误指望):无 RAG / 向量检索的现成检索管线(只有 embedding/ 模型封装,不含 retriever);无 evaluate 评测模块;A2A 仅有基座、非成品。 这三项要么自建、要么按需引第三方。

复用的获取方式仍分四类(这是"怎么拿到手"的工程口径,与上面二维"是谁的/给谁用"正交):

flowchart TB
    subgraph A["① 外部包复用(仓内已在跑 · 显式参数)"]
        A1["cost.py 计费 · _client.py new-api 客户端"]
    end
    subgraph B["② 一次性种子拷贝(运行期零依赖)"]
        B1["studio.py 的 AgentScope 用法 → 拷贝起步、独立演进、不回写"]
    end
    subgraph C["③ tier2 自有依赖(独立 env · 锁 2.0.3)"]
        C1["agentscope core 2.0.3(Agent/ReActConfig/AgentState/Middleware/Workspace/skills)"]
        C2["agentscope-runtime 沙箱 = 待验证候选(见 §3 · 当前全仓零引用)"]
    end
    subgraph D["④ 运行期禁止依赖(forbidden-import 守门)"]
        D1["SAA 配置 · 现有 studio.py 运行态 · L2 模型路由/预算表"]
    end
    style C2 stroke-dasharray: 5 5
    style D stroke:#f5b7b1
  • ① 外部包复用:cost.py_client.py 是稳定 IO 边界,真·仓内现成。但复用要纯函数/显式传参 —— endpoint / key / model / pricing / quota / retry / timeout 全显式传入,禁止沿用共享全局状态(否则会暗中继承 SAA/L2 的模型路由与预算表,"SAA 可删"就成空话)。
  • ② 种子拷贝:studio.py 的写法拷来起步,但运行期不 import 现有 worker。
  • ③ tier2 自有依赖:agentscope core 是 tier2 自己 env 里独立安装、锁 2.0.3 的(用户定调"独立周边环境")——所以它不是"与 SAA 共享的复用底座"agentscope-runtime独立 PyPI 包、当前全仓零引用,降级为待验证候选(§3)。
  • ④ 禁止依赖:加一道 forbidden-import 检查(§11 跨档 TODO,CI 侧),从机制上保证运行期不碰 SAA。

这条契约直接消解了 v1 的内部不一致("§1.1 说复用三样、§8 却列四样"):真·外部复用只有 cost.py + _client.py;agentscope 2.0.3 是 tier2 自有依赖;runtime 是候选;studio.py 是种子拷贝;且上表 6 项从"自建"上修为"用官方"。

1.3 四层是"职责视角",叠在 AgentScope 真实对象结构上

诚实说清两层意思,后者是 2026-06-22 的关键校正:

其一,"environment / harness / context / prompt 四层"不是业界主流原话。主流(2025-2026)是三层嵌套:prompt ⊂ context ⊂ harness,environment 通常并进 harness 当"对外数据面"(Deepset:"Prompt engineering is a subset of context engineering";Anthropic context engineering 定义见 §验证状态 来源)。本档把它拆四层,是为了对"单写者 ReAct + 跑确定性门"这种模块讲得更清晰。

其二(校正 · supersede 早稿"把 harness 劈成数据面 + 控制面、两面互相 act/观测"的画法):这四层不是 AgentScope 的真实对象,而是一个职责视角,叠在 2.0.3 的真实结构之上。早稿那张"harness 全域里 harness 控制面 ↔ environment 数据面互相调用"的图,容易让人误以为 environment 是一个被 harness 调用的并列数据面 —— 这与源码不符。真实结构是:

  • environment 这个职责的真实载体 = Workspace(Local/Docker/E2B),它是 Agent 的执行环境,沿两轴注入 Agent:① 把资源(tools / MCP / skills)经 get_toolkit 汇成 Toolkit 交给 Agent;② 它本身作为 offloader(上下文/工具结果卸载)挂在 Agent 上。
  • 所以 Agent 持有 Workspace 的引用,Agent 并不嵌在 Workspace 里、Workspace 也不"调用"Agent。真正"跑在 Workspace 里"的是 MCP 进程 / skills / 文件这些资源。
  • harness 这个职责的真实载体 = Agent 的 ReAct 循环原语(Agent + ReActConfig)+ MiddlewareBase 洋葱 + tier2 自建验收门;context / prompt 则是每步组装进模型窗口的运行时载荷与离线指令(仍是 prompt ⊂ context 的嵌套)。

带这层"职责 → 真实载体"的对应关系读下文,而不是把四层当四个平行筒仓、更不是当互相调用的对等模块:

flowchart TB
    AG["Agent(无状态 ReAct 引擎)<br/>= harness 职责的载体"]
    subgraph WS["Workspace = environment 职责的载体(Agent 的执行环境)"]
        RES["资源:tools / MCP / skills / 文件 / 世界状态 / 观测"]
    end
    CTX["context 运行时载荷<br/>(含 prompt 离线指令 · prompt ⊂ context)"]
    AG -->|"持有引用 · 轴②作 offloader"| WS
    WS -->|"轴① get_toolkit → Toolkit"| AG
    CTX -->|formatter 组装进窗口| AG

一句话:Agent 持有 Workspace 引用、非嵌套;Workspace 经 Toolkit + offloader 两轴接入 Agent;四层只是给这套真实结构分职责看。


2. 一张总图:整条生命周期怎么转起来

先框两个全局结构(2026-06-22 校正补入,它们决定了下面这台机器的形状):

  • 两阶段:tier2 不是上来就一个 agent 闷头写。阶段 1「工作室」用 Agent Team 星形多 agent 做设计(leader 拆解用户意图、AgentCreate 出玩法/关卡/数值/UI/音乐/特效/资产设计 worker 发散,TeamSay 汇 leader 收敛;这阶段只读——设计 worker 用 PermissionMode.EXPLORE 只读已有工程代码 + 工程内设计文档,并与用户跨 session 多轮对话)。阶段 2「单写实现」才把设计落地:模板代码初始化(阶段 2 的工具)→ 把阶段 1 各设计结论写成工程内文档 → 单写 agent 写代码 → 三层校验 → 产出。下面这张"单写者 ReAct 循环"图只刻画阶段 2 的"写代码"那一步;设计发散在阶段 1、用多 agent。
  • Agent 非常驻:Agent 是无状态 ReAct 引擎,Agent Service 每 run 现组装、跑完即弃,状态全在可持久化的 AgentState(落 Redis)。所以"循环"不是一个常驻进程在转,而是一次 run 的生命周期;长程一致性靠 AgentState 持久化 + checkpoint。

阶段 2 的实现内核是一个单写者 ReAct 循环:只有一个 agent 持全局视图、一个人写整个工程(经营游戏多系统共享状态,拆并行几乎必然不一致 —— 曾把 Flappy 拆并行,背景跑成马里奥)。每步从 context 组装载荷(含 prompt)喂模型,模型决定动作,动作经 Toolkit 作用到 Workspace(写多文件 src/ → 构建 → 真跑),Workspace 回吐观测,在三层校验上裁决"过 / 修 / 熔断"。goal/进度的承载:目标 = 输入(brief / play_spec / GDD),进度 = AgentState.tasks_context 把目标拆成 TODO、逐项 TaskCreate/Update 追踪(像 todo 清单),没有 workflow DAG(自治 loop + task + Agent Team 动态调度,详见图说 §5b)。

flowchart TB
    GOAL["目标 = brief / play_spec / GDD<br/>进度 = AgentState.tasks_context(拆 TODO · TaskCreate/Update)"] --> ASM
    subgraph H["阶段2 单写者 ReAct 循环(Agent 非常驻 · 每 run 现组装)"]
        ASM["组装 context"] --> CALL["调模型 M3 · 经 new-api"]
        CALL --> ACT["经 Toolkit 写多文件 src/ → 构建 → 真跑"]
        ACT --> OBS["收观测(Workspace ground truth)"]
        OBS --> GATE{"三层校验"}
        GATE -->|L1 可修| FIX["repair / checkpoint(AgentState→Redis)"] --> ASM
        GATE -->|全绿| EMIT["产出富游戏 src/ 工程"]
    end
    CTX["context:prompt + 源项目视图/GDD + 记忆/错误史/预算"]
    WS["Workspace:Filesystem(src/) · 构建 · 真跑+截图"]
    ASM -.读.- CTX
    ACT -.作用.- WS
    WS -.观测.- OBS
    GATE --> L1["L1 编译/运行错误 · 必须 · 循环"]
    GATE --> L2["L2 设计符合 · 尽量"]
    GATE --> L3["L3 效果 · 只评分(M3)· 绝不阻塞"]
    BREAK["四熔断:步数硬顶 · 预算闸(fail-closed) · 卡死探测 · 双超时"]
    BREAK -. 任一触发即停 .-> H
    style L1 fill:#a9dfbf
    style L2 fill:#d6eaf8
    style L3 fill:#f9e79f
    style BREAK fill:#f5b7b1

一处现状必须诚实(双评审 M1):仓内 studio.py:159ReActConfig(max_iters=1) —— 当前是单轮、靠外层 repair 循环兜,不是多轮自治 ReAct。2.0.3 里 ReActConfig.max_iters 默认 20,所以"门内任意迭代 + 步数硬顶"这层是要放开 max_iters + 新建循环控制的,不是复用现成;复用的只是 Agent + ReActConfig 这个原语。


3. environment 层(载体 = Workspace)—— agent 的工作站(候选底座待验)

校正(2026-06-22):environment 这个职责在 AgentScope 2.0.3 里的真实载体是 Workspace —— 它是 Agent 的执行环境,沿两轴注入 Agent(① 资源经 get_toolkitToolkit;② 本身作 offloader),WorkspaceBase 已有 Local / Docker / E2B 三实现。所以本层不是凭空"自建一个数据面",而是Workspace 这个官方抽象上挂 tier2 要的工具与资源;Agent 持有它的引用、并不嵌在里面。下面讨论的"给 agent 一台游戏工作站"(写多文件源码、构建、真浏览器跑、截图、查资产与文档),落地就是配 / 扩 Workspace 及其 Toolkit。

Workspace 自带的三实现解决"在哪跑、文件/shell 隔离"的问题,但确定性硬门要的"真浏览器低层探针"是否够用,仍是承重前提、需先验(双评审 B1/M7):一个候选是引 agentscope-runtimeSandboxService(CODE/Filesystem/Browser 三沙箱 + sandbox_tool_adapter)补浏览器探针;但 ——agentscope-runtime 当前全仓零引用、是独立 PyPI 包,且 requirements-l2.txt 注释明写"本期只引 base、不引 service/storage"。所以它是新增的待验证候选依赖,不是现成复用底座;"上游有这个 API"(Context7 可查)不等于"装得进 tier2、挂得成 Toolkit、跑得了 esbuild + headless、且撑得住确定性探针"。

确定性硬门要的是低层探针,而 Browser 沙箱给的是高层 API,够不够要先验:

硬门探针 需要的浏览器能力 navigate/screenshot/snapshot 够吗
真跑 + 截图(boot / 视觉软检喂图) navigate / screenshot / snapshot ✔ 够
帧 delta(window.__engine.snapshot().frame 类) page.evaluate / raw CDP ✘ 需 evaluate
canvas 像素回读(亮像素阈值) screenshot + page.evaluate △ 截图有、阈值判定需 evaluate
activity hash 比对 page.evaluate
输入改状态(注入输入再读态) input dispatch / raw CDP ✘ 需低层注入

结论 + 退路:Browser 沙箱够"跑+看",不够"低层确定性探针"。spike 前先跑一个小验证(§10 升格为 spike 前置阻断项):结论为"BrowserSandbox 暴露足够 page.evaluate/CDP"→ 复用它;否则 environment 回落到"自建薄沙箱 + 复用 play.cdp.cjs 的运行/截图/证据骨架(但其探针硬编码 #game-enginewindow.__engine.snapshot().frame,是 LittleJS 专属、非引擎无关 —— selector/frame source 必须为 Phaser 参数化或重写,不是"直接复用")"。这条退路对"薄做地基"的工作量影响要计入排期。

flowchart LR
    AG["单写者 Agent(持 Workspace 引用)"] -->|工具调用| TK["Toolkit(get_toolkit 汇成)"]
    subgraph WS["Workspace(Local/Docker/E2B · environment 载体)"]
        FS["Filesystem:多文件 src/ 读写"]
        CODE["CODE:esbuild 构建 / shell"]
        BR["Browser:真跑 + 截图(低层探针待验)"]
        PACK["引擎能力包工具(见 §6.1 manifest)"]
    end
    TK --- FS & CODE & BR & PACK
    FS & CODE & BR -->|观测 ground truth| AG
    NOTE["浏览器探针底座二选一(spike 前验):<br/>agentscope-runtime 沙箱 ┃ 自建薄沙箱+现有 CDP"] -.- WS
    style BR stroke-dasharray: 5 5
environment 内容
硬代码(机制) 沙箱接线、工具适配器、动作/观测空间的结构(枚举级);权限硬上限(配置只可降不可升)
版本化安全/构建配置(审计 · 不热改) 依赖锁版本、引擎版本、构建 profile、启用哪些沙箱类型 —— 这些是可信边界 + 可复现构建输入,走版本化审计,不像阈值那样热改(双评审 M5)
热配置(改即生效) 资源软配额等可热调项

引擎选型(Phaser/Pixi)两态(双评审 M3):第一版 = Phaser 硬编码进工具(硬代码,换引擎需改适配器、发版);目标态 = 能力包接口抽出后才可配。第一版薄做,等第二个引擎(Pixi)落地有两个实现再抽接口(承《自治富游戏引擎》)。


4. harness 层 —— 控制面与三层校验(本模块重心)

harness 是把模型变成 agent 的循环与脚手架:控制流、工具分发、校验门、熔断、checkpoint、可观测。tier2 的 harness 启用 AgentScope 2.0.3 的循环原语(Agent + ReActConfig),拦截 / 预算 / 可观测尽量挂在官方 MiddlewareBase 洋葱与官方 middleware 上,自己重写的只是验收门

用词分级与 API 校正(双评审 M2 + 2026-06-22):checkpoint、记忆、skills、trace 这些仓内代码一个都没用过,是 agentscope 2.0.3 框架提供、tier2 首次接通、行为待验(2.0 是对 1.x 破坏式重写),本档一律标"启用(待验)",区别于 cost.py/_client.py 的"复用(已在跑)"。同时把早稿的 API 假设按 2.0.3 源码纠正:拦截扩展点是 MiddlewareBase 洋葱(6 hook)、不是 agent hooks;checkpoint 状态是 pydantic AgentState(cur_iter/context/tasks_context)落 StorageBase(Redis)、不是 state_dict;可观测是 TracingMiddleware(纯 OTel)不是 Studio trace / agentscope.init(studio_url)(后者不存在)

4.1 三层校验:L1 硬约束 + L2 设计符合 + L3 效果软检(创始人定义 · M3 绝不阻塞)

校正(2026-06-22):早稿的"双层验收(确定性硬门 + M3 视觉软检)"升级为创始人定义的三层校验 —— 在原"硬门 / 软检"之间补出一层"设计符合":

  • L1 硬约束:编译 / 启动 / 运行错误日志。必须解决 · 循环;工具是确定性的(构建日志 / console / CDP 错误捕获)。现有九门多数落这一层,少数(机制进展类)落 L2。
  • L2 设计符合:玩法 / 关卡实现 vs 设计、UI 缺组件等。尽量解决;靠设计符合度校验。
  • L3 效果:特效 / 美观 / 好不好玩。只评分、不解决;由 M3 多模态软检,绝不阻塞、绝不拒发

现有九门(《详设》更精确叫"九门 + 三联动门 + 经济门 + latch")只判机制、且为 LittleJS 单文件壳而建、不适配 Phaser、还带病灶。tier2 把它抽象重写进 L1/L2(本档新增联动/经济/类校验),三层职责绝不混:

flowchart TB
    PLAY["真跑产物 + 截图(Workspace 观测)"] --> L1
    PLAY --> L2
    PLAY --> L3
    subgraph L1["L1 硬约束 · 必须解决·循环 · 零 LLM 判定 · 定 pass/fail"]
        G1["引擎无关重写(多数九门):能装载 / 不报错 / 帧 delta /<br/>像素回读 / 活动 hash / 引擎调用前缀 / 输入改状态 / 控制跟手"]
        G2["tier2 富游戏专属:跨表联动门(订单引物品可达·合成 DAG 无环)+ 经济门(可盈利可破产)"]
        G3["修旧病灶:latch 分『胜利/弃守』(空壳不再蹭过)"]
    end
    subgraph L2["L2 设计符合 · 尽量解决 · 确定性信号为准"]
        S1["机制进展类九门 + 玩法/关卡实现 vs 设计 + UI 缺组件"]
        G4["品类独立交叉校验:用『题面关键词(确定性)』比对 design 自报品类,<br/>不一致→降权/拒发(拒发权只来自确定性信号);<br/>同其他新增门:默认 observe→enforce,达标后才赋拒发权"]
    end
    subgraph L3["L3 效果 · 只评分不解决 · M3 绝不阻塞/拒发"]
        V1["M3 多模态看截图:好不好看 / 像不像题面 / 明显劣化(空内容·布局崩)"]
        V2["只进:质量趋势 · 告警 · 人工终审升级。绝不参与『算不算完成』、绝不单独拒发(防 Goodhart)"]
    end
    L1 -->|全绿| PASSED["机制地板通过(可发)"]
    L2 -->|确定性信号| GATE2["降权 / 拒发(observe→enforce)"]
    L3 -->|软信号| TREND["趋势 / 告警 / 给人工终审减负"]
    style L1 fill:#a9dfbf
    style L2 fill:#d6eaf8
    style L3 fill:#f9e79f

三条铁律,承创始人定义与《自治富游戏引擎》/生成引擎设计主文档:

  • 确定性的归机器,且绝不让 LLM 给自己打分。 L1/L2 的拒发权全来自确定性信号,是"机制地板",零理由动它的判定权。
  • L3(M3 视觉)严格只评分、绝不阻塞(双评审 B1·Codex + 创始人定义)。 v1 曾写"从 M3 视觉反推品类…不一致即拒发",这等于把 VLM 提成硬门,违反 Goodhart 红线。已改正:M3 只产观测 / 告警 / HITL 升级,绝不单独拒发、绝不阻塞真问题;G4 的品类交叉校验以"题面关键词(确定性)"为拒发依据,M3 至多作软佐证喂趋势。"出题与被考解耦"由这个确定性交叉校验达成,不靠 M3。
  • 迭代原则:初期只识别硬问题(L1),L2/L3 渐进;绝不让效果问题阻塞真问题;用户可经 HITL 要求继续解决任意层。

4.2 循环、熔断、checkpoint、预算闸语义

单写者 agent 在门内迭代,被四道熔断关着、任一先触发即停。其中预算闸要硬、要定义失败语义(双评审 M8):

flowchart LR
    subgraph BRK["四熔断"]
        K1["步数硬顶(每系统构建-修复)"]
        K2["预算闸(见下,fail-closed)"]
        K3["卡死探测(语义层)"]
        K4["双层超时"]
    end
    subgraph BUD["预算闸语义(承 agentic 集成架构 · 现 cost.py 仅 best-effort 取价)"]
        P1["软层:官方 ReplyBudgetControlMiddleware(token 软预算)"]
        P2["硬层:每轮 preflight 预测 + per-call 扣减 + deadline + fail-closed"]
        P3["取价/扣账/quota 写失败 → 默认 fail-closed;纯 token 上限=显式硬兜底状态(进 trace),非二选一"]
    end
    K2 --> BUD

注意分两层:软预算用官方 ReplyBudgetControlMiddleware(token 计量靠 model response 自带的 ChatUsage),挂在 MiddlewareBase 洋葱上即可,这是 2026-06-22 校正"6 项改用官方"之一。但 cost.py 是 best-effort 取价、取不到也不阻断,只是观测台账口径,不等于网关层强制拒绝;tier2 自治多轮 ReAct 的成本风险是真的(一次失控循环能烧数美元),所以强制 fail-closed 预算闸仍要自建,且与《agentic 集成架构》的 D12/tier2 预算治理对齐(§11 跨档 TODO)。长程一致性靠 AgentState checkpoint(pydantic·落 Redis·启用待验) + 半轮副作用幂等。可观测用 TracingMiddleware(纯 OTel)→ Studio 看板(启用待验);统一 trace 契约推迟到 spike 或控制面 phase-1。


5. context 层 —— 运行时载荷

context 是某步推理在窗口里组装的一切经策展的动态信息(prompt 是其子集)。它在 2.0.3 真实结构里就是 AgentState.context(工作记忆)+ 每步经 formatter 逐模型组装进窗口的载荷。tier2 这层启用 AgentScope 的记忆/组装能力(待验):短期工作记忆(AgentState.context)、长期经验召回用官方 ReMe(2026-06-22 校正:经验/debug 案例库从"自建"改用官方记忆框架;⚠️树内捆绑后端实为 mem0,选型见 §1.2 注 + spike 前定)、formatter 逐模型组装;结构化输出走官方 generate_structured_output(model 层),不自建 schema 校验。工程上要设计的是装什么、何时压:

flowchart LR
    subgraph CTX["context · 每步组装的载荷"]
        SYS["system prompt(来自 prompt 层)"]
        TOOLS["工具/skill schema"]
        SRC["源项目视图(当前相关 src/)"]
        GDD["GDD(玩法意图/机制/胜负)"]
        HIST["动作-观测史 / 错误轨迹"]
        BUDGET["预算与成本状态"]
        RAGIN["能力包检索结果注入(见 §6.1)"]
    end
    MEM["长期记忆:debug 案例库(签名→修复)+ template 家族"] -->|按需检索| CTX
    CTX -->|formatter 组装| MODEL["模型窗口"]
    CTX -.超窗.-> COMP["压缩/摘要(保关键状态)"] --> CTX

边界 vs prompt:prompt 是离线写好的静态指令,context 是运行时组装的载荷。这层防的是 context rot 与溢出截断丢关键状态 —— 12+ 文件富游戏尤其靠压缩 + checkpoint 守长程一致性。debug 案例库(签名匹配纯算法、命中即省一次 LLM)挂长期记忆上,是对便宜模型最划算的杠杆。

context 内容
硬代码(机制) 记忆/组装/压缩机制;可入上下文的内容类型(枚举级)
热配置(策略) 上下文预算分配、压缩触发阈值、启用哪些 RAG 源(枚举内取值)、长期记忆模式、检索参数

颗粒度澄清(双评审 M3):新增/删除一类内容 = 改枚举 = 硬代码;在已有类里增减取值(如多挂一个 RAG 源)= 可配置


6. prompt 层 —— 离线编写的指令(⊂ context)

prompt 是塑造模型行为的编写指令文本:静态、离线写、版本化。tier2 这层启用 AgentScope 2.0.3 的 sys_prompt 增广、formatter、以及原生 skills 机制(均待验)。校正(2026-06-22):2.0.3 的 skills 不是 agent 级 register_agent_skill 注册(早稿 API 名有误,源码无此函数),而是挂在 Workspace 上的资源 —— WorkspaceBase.add_skill(skill_path) / list_skills() 加载带 SKILL.md(frontmatter 含 name)的技能目录,再经 get_toolkit 注入 Agent。也就是说 prompt 层的"skill"这一面,落地是配 Workspace 的 skill 目录,与 §3 environment 同源(都在 Workspace 上),正好对应 §6.1 的"一个 manifest、三层各持一面"。

6.1 引擎能力包:一个 manifest,三层各持一面(消除跨层泄漏)

双评审 M3(Codex)指出:同一个"引擎能力包"在 environment(工具/RAG)、context(RAG/记忆)、prompt(skills)三层都出现,没有唯一 owner,会形成三份配置源、引擎切换/回滚/trace 归因无主。改正 —— 立一个轻量能力包 manifest(id + version)作单一 owner,三层各持其一面、共同引用同一 id/version:

flowchart TB
    MANI["引擎能力包 manifest<br/>capability-pack id + version(单一 owner)"]
    MANI --> EF["environment 面:可执行工具(Phaser 写/构建)"]
    MANI --> CF["context 面:检索结果(Phaser API RAG → 注入)"]
    MANI --> PF["prompt 面:文本 skill(SKILL.md:Phaser-API / debug / template)"]
    style MANI fill:#fde68a

v1 范围(防孤儿抽象):第一版 manifest 只做 Phaser facet 归因 + 版本锁定,三面仍按 §3 的 Phaser 硬编码(不由 manifest 驱动接线);"换引擎/回滚 = 换 id/version" 是目标态,待第二引擎(Pixi)抽出接口后才配置化 —— 避免"一上来就建满、接口被唯一实现反向决定"(承《自治富游戏引擎》)。trace 始终按 id/version 归因。

6.2 角色与铁律(分两阶段)

tier2 的"角色"要按 §2 的两阶段分开说(2026-06-22 校正,补出阶段 1 工作室):

  • 阶段 1「工作室设计」用 Agent Team 星形多 agent:leader 拆解用户意图、AgentCreate 出玩法 / 关卡 / 数值 / UI / 音乐 / 特效 / 资产设计 worker 发散,TeamSay 汇 leader 收敛成设计结论。这阶段只读 —— 设计 worker 用 PermissionMode.EXPLORE 只读已有工程代码 + 工程内设计文档(迭代已有游戏时),并与用户跨 session 多轮对话。用多 agent 是为了发散与专业分工。
  • 阶段 2「单写实现」用单写者(双评审 m2):一个写者 agent 持全局、独自写(防并行写冲突);旁边配只读探路 agent + 一道独立评审 + M3 player(L3 效果)单写约束只管"写代码"这一步,不约束阶段 1 的设计发散。模型路由是 per-agent(leader/各设计 worker/写者/探路/评审/player 各自可配),不是把现有 studio.py 的 design/code/fix 三角色照搬进来。
flowchart TB
    subgraph S1["阶段1 工作室(Agent Team 星形 · 只读 EXPLORE · 跨 session 对话)"]
        LEAD["leader:拆解意图 + 收敛"] -->|AgentCreate| W["玩法/关卡/数值/UI/音乐/特效/资产 设计 worker"]
        W -->|TeamSay| LEAD
    end
    subgraph PROMPT["阶段2 prompt 层(几乎全是可配置数据)"]
        ROLE["角色 prompt:单写者 + 只读探路 + 独立评审 + M3 player"]
        LAW["三铁律:数值只进配置 · 只用清单已有行为 · 绝不编造清单外 hook"]
        OUT["输出契约:终态必须是 src/ 多文件工程(非 iife 串)"]
    end
    S1 -->|"设计结论写成工程内文档"| PROMPT
    SKILLS["skills(SKILL.md · 挂 Workspace)= 能力包 prompt 面(§6.1)"] -->|增广进| ROLE
    ROLE --> SYS["sys_prompt → context"]

prompt/skill 走 tier2 自己的版本治理,不并入 SAA 的 prompt-同源工程。三铁律里"绝不编造清单外 hook"能约束便宜模型,前提是有那份 Phaser API 清单当填空靶子。

prompt 内容
硬代码(机制) formatter 机制、skill 加载机制、输出 schema 校验逻辑
热配置(策略) 全部 prompt 文本、per-agent 模型路由、few-shot、agent skills 内容、prompt 版本 —— 这层几乎全是数据

7. 硬代码 vs 可配置:三类门 + 三类配置

这是本模块的组织原则,继承生成引擎设计主文档对旧债的诊断("策略被焊进不该重编译的机制代码")。双评审(Opus M3、Codex M4/M5)指出 v1 这张表有误分类,修正为三类门 + 三类配置:

门分三类(双评审 Codex M4) —— 配置不可绕过机制地板;括号内是它落在 §4.1 三层校验的哪层:

门类 档位
基线确定性硬门(L1) boot / 帧 / 输入改状态 / latch / 控制手感 永远强制,配置不可关
新增确定性门(L1/L2) 跨表联动门 / 经济门 / 品类交叉校验(G4,L2) observe→enforce(默认只观测,达标率稳后才赋强制/拒发权)
M3 视觉软检(L3) 好不好看 / 劣化 永远软观察,绝不放行、绝不拒发

配置分三类(双评审 Codex M5) —— 安全/构建输入不可热改:

flowchart LR
    subgraph HARD["硬代码 · 机制(改它=改代码、重部署)"]
        H1["确定性门断言 · 四熔断机制 · 基线硬门强制"]
        H2["循环/记忆/组装/压缩机制结构 · 权限硬上限"]
        H3["铁律:绝不让 LLM 自评 · M3 绝不拒发"]
    end
    subgraph VER["版本化安全/构建配置(审计·不热改)"]
        V1["依赖锁 · 引擎版本 · 构建 profile · 启用沙箱类型"]
        V2["权限上限:配置只可降不可升"]
    end
    subgraph HOT["热配置 · 策略(改配置不发版)"]
        C1["prompt 文本 · per-agent 模型路由 · few-shot · skills"]
        C2["max_iters · 熔断阈值 · 新增门 observe/enforce 档 · 过门率阈值"]
        C3["上下文预算 · 压缩阈值 · RAG 源(枚举内)· 记忆模式"]
    end
    HARD -. 策略绝不下沉进机制 .- HOT
    VER -. 安全/可复现绝不当热配置 .- HOT

判定经验:"现在要改就得发版"的东西默认挪进热配置;但安全边界(权限上限)、可复现构建输入(依赖锁/引擎版本/构建 profile/沙箱类型)走版本化审计、不热改;唯机制留硬代码 —— 确定性门断言、四熔断、基线硬门强制、绝不让 LLM 自评/M3 拒发。


8. 复用 / fork / 新建 边界(对齐 §1.2 复用契约)

flowchart LR
    subgraph REUSE["复用(已在跑)"]
        R1["cost.py · _client.py(显式传参 · 禁读 SAA 配置)"]
    end
    subgraph OFF["官方现成(2.0.3 自带 · 6 项改用官方)"]
        F1["ChatUsage 计量 · ReplyBudgetControlMiddleware 软预算"]
        F2["generate_structured_output · TracingMiddleware(OTel)"]
        F3["ReMe 经验召回 · Agent Team 多 agent 总线"]
    end
    subgraph OWN["tier2 自有依赖(独立锁 2.0.3)"]
        O1["agentscope core(Agent/ReActConfig/AgentState/Middleware/Workspace · 启用待验)"]
        O2["agentscope-runtime(浏览器探针候选·待验·见 §3)"]
    end
    subgraph SEED["种子拷贝(运行期零依赖)"]
        S1["studio.py 的 AgentScope 用法"]
    end
    subgraph NEW["新建 / 重写(= 自建∩私有或∩公共)"]
        N1["九门→引擎无关重写(L1/L2)+ L3 M3 软检"]
        N2["多轮循环控制(放开 max_iters)+ 四熔断 + 强制 fail-closed 预算闸"]
        N3["引擎能力包 manifest(Phaser)"]
        N4["mini-肥鹅 spike fixtures · tier2 源项目契约"]
    end
    style O2 stroke-dasharray: 5 5

全程运行期零碰 SAA,由 forbidden-import 守门(§11)。注意"官方现成 / 自建"是 §1.2 二维的"来源"轴 —— 上面 NEW 框里的件多数是自建∩共享(公共组件)或自建∩私有,而 OFF 框是官方现成、非 tier2 资产。


9. 衔接《tier2 实现详设》:spike-grade 地基 vs 完整地基

本档是建设五步第一步(AgentScope 底座)+ 第二步(配置外置) 的工程落点。但双评审(Opus M5、Codex M9)指出 v1 的"完成定义"是循环论证、且容易把"完整配置外置/记忆/skill 治理"全压在 spike 前,推迟最该便宜验证的 56% 赌注。改正 —— 区分两档地基,spike 只需 spike-grade:

flowchart LR
    SG["spike-grade 地基(spike 前必须有)"] --> SPIKE{"0号 spike<br/>(便宜模型写 56%?)"}
    SPIKE -->|过 go| FULL["完整地基(配置外置/记忆/skill 治理 全做)"] --> S3["第三步 铺 Phaser 引擎"]
    SPIKE -->|不过| RT["退路树(绝不滑成无限调参)"]
    FULL -.也服务.-> REUSE2["将来 SAA 退场时接棒"]
    style SPIKE fill:#f9e79f
    style RT fill:#f5b7b1

spike-grade 地基 = 逐项映射《详设》第五节六样前置物 + 一项新增(可勾选;硬编码 prompt/config 可接受 —— 《详设》明说"最小 AgentScope + 硬编码配置即可先验"):

《详设》前置物 落在四层哪层
① mini-肥鹅 经营骨架工程 environment(Filesystem src/ 种子)+ prompt(骨架契约)
② 经营 harness driver + 九门对 Phaser 两钩子参数化 harness(确定性门 + 引擎钩子参数化)
③ 三联动门 + 经济门 + latch 的 assertAfterPlay 规格 harness(tier2 专属硬门)
④ studio.py 演进版(放开 max_iters + 写/build/headless/读 verdict/资产注册) harness(循环新建)+ environment(工具)
⑤ 数据表 schema(12 物品/6 链/5 订单)+ 资产池占位图 context(数据)+ environment(资产)
⑥ 成本计量接 new-api quota + 轨迹仓最小版 harness(预算/观测;复用 cost.py)
沙箱底座小验证(§3) environment —— 不在《详设》六样内,需补进《详设》(§11 T3)

spike-grade 预算 = 只需时间盒手动上限(token cap / deadline,承《集成架构》"强制预算建成前只在严格时间盒实验里跑");完整 fail-closed 预算闸强制是 pre-scale(非 pre-spike)项其余后置:完整配置外置、长期记忆治理、skill 家族、管理面 —— 全留 spike 过后。

完成定义的两把尺子(改成可判定):① 凡不在《详设》六样前置物因果链上的,推迟(替代 v1 抽象的"足够");② 用 §7 硬代码侧的机制地板当"该建"代理(机制=该建、策略=可推迟到 spike 后随实测再配),不再诉诸"将来 SAA 能否接棒"这个不可证伪的未来命题冲突时 spike-first 优先,守住《详设》那句"别等平台和引擎都搭漂亮了,才发现便宜模型生成不出富游戏"。


10. 开放项 / 待校准

  • ★ 阈值校准:¥3/款、50%/70% 过门率 —— 需创始人 + 实测定(承《详设》)。
  • 【spike 前置阻断】沙箱底座小验证:跑 §3 那张 probe→API 矩阵,定 agentscope-runtime BrowserSandbox 是否暴露足够 page.evaluate/CDP;不够则回落自建薄沙箱 + 现有 CDP。这是 spike 前必须出结论的阻断项,要补进《详设》前置物清单(当前六样未含)。
  • 引擎能力包接口:第一版薄做(Phaser 硬编码 + manifest),第二个引擎(Pixi)再抽满。
  • trace 契约时机:先用官方 TracingMiddleware(纯 OTel)→ Studio 看板,contracts/trace/ 推迟到 spike 或控制面 phase-1。
  • M3 视觉软检校准:rubric + calibrate vs 创始人 labels —— 这是校准 M3 这把尺子的准度;它有结构性天花板(判不出物理/碰撞/控制手感),不可替代对产物的人工终审(两个独立环节,别混)。

11. 跨档收口 TODO(§6.8 口径:档内已修,跨档列此)

# 事项 落到哪 来源
T1 "演进 studio.py" vs "fork 独立"二选一对齐 —— 统一为"以 studio.py 为种子拷贝、运行期零依赖、独立演进";改一处必改另一处 《tier2 实现详设》§建设五步第一步 Opus M1 / Codex M2
T2 被复用低层库(cost.py/_client.py)在 SAA 退役后的维护归属 + tier2 预算闸与 D12 治理对齐 《agentic 集成架构》 Opus M4 / Codex M8
T3 把"沙箱底座可行性小验证"升格为 spike 前置阻断项写进前置物清单(现六样未含) 《tier2 实现详设》第五节 Opus B1 / Codex M7
T4 tier2 forbidden-import CI 检查(禁运行期 import SAA 配置 / studio.py 运行态) ce-plan 执行(CI/代码侧) Codex M6
T5 确认 tier2 的 latch/解耦重写与生成主文档 §6.3 同名修复独立、不共享实现 与《生成引擎设计主文档》对账 Opus m3
T6 README §6.3(SAA 线 player 软门)仍写"视觉反推品类不一致即降权乃至拒发";tier2 已改 M3 永远软 —— 确认 SAA 线是否同步收紧,还是两线有意不同(不同线、不同决策) 《生成引擎 README》§6.3 / 横切一致性主人 Codex R2

验证状态:评审版,未落代码,已纳入 Codex+Opus §6.8 双评审发现并修订,并据《agentic 运行时架构图说》(基于 agentscope 2.0.3 源码实证,/root/oss/agentscope 逐条核过)做了 2026-06-22 架构校正(B1+5/9 MAJOR + minors 档内已修,跨档见 §11)。本次校正的 API 事实均经源码复核:_version.py = 2.0.3;无 ReActAgent(agent/_agent.py:93 class Agent + agent/_config.py:123 class ReActConfig,max_iters 默认 20);MiddlewareBase 6 hook(middleware/_base.py);AgentState(BaseModel)(state/_state.py:141,含 tasks_context/cur_iter/context);WorkspaceBase(Local/Docker/E2B)+ Offloader + get_toolkit(app/_service/_toolkit.py)证 Workspace 两轴注入、Agent 持引用非嵌套;create_app→FastAPI(app/_app.py:33)= 官方 Agent Service;ReplyBudgetControlMiddleware/TracingMiddleware/generate_structured_output/ChatUsage/Agent Team(_team_create/_agent_create/_team_say)均在树;skills 经 WorkspaceBase.add_skill(无 register_agent_skill);__init__.pyinit(studio_url)一处差异:树内长期记忆后端是 mem0 middleware,图说(SoT)以 ReMe 口径登记经验召回——选型待 spike 前定(§1.2 注)。"主流四层"经 web 研究核(主流实为 prompt⊂context⊂harness 三层嵌套、environment 并入 harness;本档四层据校正重定位为叠在 AgentScope 真实对象结构上的职责视角,来源 Anthropic context-engineering、Deepset、SWE-bench harness 等,完整 dossier 见研究留痕)。仓内实证:studio.py:159 ReActConfig(max_iters=1)requirements-l2.txt 只引 agentscope base、agentscope-runtime 全仓零引用、contracts/trace/ 不存在。硬/软、机制/策略边界承《自治富游戏引擎》与生成引擎设计主文档既有裁定。