2.0.3 从未发布到 PyPI(最新 2.0.2),requirements.txt 的 ==2.0.3 不可安装。已在 mini-desktop venv 实装 2.0.2 并冒烟:Agent/ReActConfig/Toolkit/FunctionTool/Anthropic*/MCP(Stdio+Http)/create_app(Agent Service)/AgentState/workspace/middleware/event/skill 全在——设计依赖符号对 2.0.2 成立。 活层(docs/tier2/.agents)agentscope 2.0.3→2.0.2:文档+SVG+requirements.txt+knowledge facts(改名 agentscope-2.0.2-facts.md);npm lockfile 第三方 2.0.3 未动。复验 SVG 32 张全过。 注:6c6g 克隆 /root/oss/agentscope 实为 2.0.3-dev(领先 PyPI),与 2.0.2 架构一致(符号已对)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
22 KiB
date, topic, status, 映射源档
| date | topic | status | 映射源档 | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-06-23 | tier2 细节图说 · A 族——运行时形态(Agent Service / 非常驻 + AgentState / Workspace 双轴 / Middleware 洋葱) | 设计中(tier2 待 spike) · 每图映射源档见该图脚注 / frontmatter 记 hash 作防漂移门 |
|
tier2 细节图说 · A 族 —— 运行时形态
本篇是绘境AI 架构图集 生成引擎子树 下的 tier2 细节图说,只覆盖 A 族(运行时形态) 四张图。生成引擎主干、tier2 总览、自治富游戏验收各有自己的图说;这里专门把「tier2 这条富游戏自治线跑起来到底长什么样」这件事画清楚——cloud 怎么接进去、agent 实例怎么活、执行环境怎么挂上来、横切关注点挂在哪。
0 阅读约定与同步纪律
A 族讲的是 tier2 富游戏自治生成线的运行时骨架——从 cloud 怎么经官方 Agent Service 接进来,到 agent 实例非常驻、状态全外置到 AgentState,再到 Workspace 沿两轴注入 agent,最后到成本与观测怎么统一挂在 middleware 洋葱上。这四件事是同一条运行轨的四个切面:图 A1 画接入面(cloud 怎么进、session 三条路怎么汇),图 A2 画 agent 的生命周期与断点续跑(非常驻怎么靠 AgentState + checkpoint 落实),图 A3 纠一个最容易踩的误解(Workspace 不是包着 agent、而是注入 agent),图 A4 画横切关注点的统一挂载点(成本刹车 / 硬熔断 / 观测挂在哪)。
这四张图映射四份属主设计档加 AgentScope 2.0.2 源码。运行时形态的总口径出自《tier2 实现详设》的「运行时形态:两阶段、service 化与 session 三路径」一节,接入面的逐 router 与 MessageBus 细节出自《agentic 集成架构》的「tier2 接入面」与「D12 运行治理门」两节,所有结构性事实——八个 router、AgentState 三字段、WorkspaceBase 三实现、MiddlewareBase 五钩子——都按 AgentScope 2.0.2 源码逐条核过(agentscope/app/、state/_state.py、workspace/、middleware/)。frontmatter 记了这四份的当前 commit hash,作为防漂移门——其中任一份动了运行时口径,本图说与对应 SVG 必须同步改。
整条 tier2 富游戏线现在 整体待建:0号 spike 还没跑,引擎没搭,代码一行没落。所以读 A 族时,「待建」是默认状态,绝不能因为图画得齐整就误以为运行时已经搭起来了。但「待建」不等于「全凭空想」——A 族里有一大块是 AgentScope 2.0.2 已经提供的现成件:官方 Agent Service(create_app 拉起的 FastAPI)、MessageBus(Redis 实现)、AgentState 模型与 StorageBase、WorkspaceBase 三实现、官方两个 middleware(预算软刹与 tracing),这些都现成、不用自造,图里用实线画。tier2 自己要做的是把这些现成件接成一条富游戏自治线:接官方 service、做非常驻装配与每轮 checkpoint、在官方 Workspace 抽象上挂 tier2 要的工具与资源、把硬熔断三件做成 MiddlewareBase 子类——这部分用虚线画。看图时记住这条对照:实线 = 现行已落 / AgentScope 2.0.2 官方现成件,可以直接信;虚线(stroke-dasharray 6 4)= tier2 专属、待 0号 spike 验证后才落代码的接线。 个别图上还有远期紫,标的是「设计已出但排在更长期层级」的元素(如 E2B 远端强隔离),不是 spike 期的投入项。
A 族是《agentic 运行时架构图说》的放大层,不是它的替代。那份总览图说里的图 1(系统全景)、图 2(调用时序)、图 3(运行时内部)、图 5(编排配置)、图 8(关键类图)给的是整体结构,A 族只把「运行时形态」这一面逐字段放大——总览图 3 把 Agent 与 Workspace 的整体结构画在一处,A 族则把非常驻装配、AgentState 三字段、双轴注入的两条轴、middleware 五钩子各自挂什么,一项一项展开。凡总览图已画清的整体结构,A 族不重画,只在脚注里指回去。这是 deepen 而非 duplicate:总览看轮廓,A 族看施工。
1 全图通用图例
A 族四张图共用一套视觉语言,先在这里讲清,后面每张图不再重复。
线型承担状态语义。 实线框 / 实线箭头 = 现行已落或 AgentScope 2.0.2 官方现成件(官方 Agent Service、MessageBus、AgentState、StorageBase、WorkspaceBase 三实现、官方 ReplyBudgetControlMiddleware 与 TracingMiddleware、D12 运行治理门),这些可以直接复用、不用自造。虚线框 / 虚线箭头(stroke-dasharray 6 4)= tier2 专属待建机制(非常驻装配、每轮 checkpoint 落 Redis、session 三路接线、注入工具集、D5 沙箱底座选型、硬熔断三件子类),还要写还要验。远期紫(紫框 / 紫底)= 设计已出但排在更长期层级的元素,典型是 E2B 远端强隔离对齐的多租户 / premium 层,不是 spike 期投入项。
徽章标的是这块内容服务哪个生产维度。 绿色的 可靠(断点续跑不丢、半轮副作用幂等)、成本(压住自治多轮的烧钱)、蓝色的 可观测(每步推理 / 工具调用可对账)、灰色的 数据(状态可持久化落库)、红色的 安全(沙箱隔离 = 写码真跑的信任边界)、紫色的 伸缩(远端沙箱撑多租户)。这些维度落到 A 族的具体接点上:可靠落在 SSE 可恢复与 resume 续跑,成本落在 middleware 洋葱的预算软刹与硬熔断,可观测落在 Workspace 统一面与官方 Event→OTel 管道,数据落在 AgentState→StorageBase 落库,安全落在 Workspace 三实现的隔离强度梯度。
状态码四个,贯穿生成引擎子树。 现 = 现行已建在跑或 AgentScope 2.0.2 官方现成;接 = 设计已出、代码待接线;建 = tier2 立项后要新建、当前待 spike;缓 = 收窄后缓做 / 更长期层级。A 族绝大多数 tier2 自有元素是「建」,官方现成件是「现」,E2B 远端强隔离这类更长期项是「缓」。
2 图集
图 A1 · Agent Service 与 session 三路径
cloud 这边要调 tier2 生成一款富游戏,第一个要回答的问题是「接口在哪、长什么样」。这张图给的答案是:tier2 不自造这层 API,直接用 AgentScope 2.0.2 的官方 Agent Service。它是 create_app 拉起的一个 FastAPI 应用,对外是 REST 加 SSE,天生多租户、天生 durable session,源码在 agentscope/app/ 里逐条核过。图中央那条横向三段链路就是 cloud 接 tier2 的真实姿势——game-cloud 经 REST POST /sessions 建一个会话,再经 SSE 收事件流;tier2 的单写 ReAct agent 跑在这层 service 之上。这么接的理由很直接:一个现成、已经把多租户和可恢复会话都做好的 service 摆在那里,自己重写一遍既慢又容易漏,不如直接用官方的,把力气省下来花在富游戏怎么造上。
图中段那排八个 router 和底下那行 MessageBus,是把「这层现成到什么程度」摆出来给人看清。八个 router——/sessions、/chat、/schedule、/credential、/workspace、/model、/tts_model、外加 agent 管理面——覆盖了一条生成线要用到的会话、对话、定时触发、模型密钥托管、执行环境、模型选择这一整套,全是框架现成件。底座是 MessageBus 的 Redis 实现,它撑起四样分布式协作能力:Redis Stream 做事件 replay 日志(晚到的订阅者能回放、不丢中间过程),pub/sub 做唤醒广播(worker 干完异步通知 leader、不必轮询),分布式锁保证同一会话同一时刻只被一个进程跑,取消信令支持中途叫停。这套底座直接决定了那条绿色的「SSE 可恢复」要点带能成立——cloud 收事件流时掉了线,重连后从 replay 日志续读、不必从头重跑,这正好兜住了「外部服务 / 异步任务要考虑超时、失败、断线」这条可靠性要求。一次富游戏生成可能跑很久,断线重连不丢进度是必须的,而这件事官方已经给了。
图底那三个并排的 session 加载路径,是这张图最该让人看出的设计取舍。tier2 把「游戏 = 长生命周期软件项目」这条基座裁定落到了运行时入口上:一款游戏不是一次性产物,所以进场方式不止「从零新建」一种。路径①是续接之前的会话,从 SessionRecord.state 取回历史工作记忆与轮次,接着往下 reason;路径②是加载一份已有游戏工程,把 Workspace.workdir 指向那个已存在的目录,进迭代模式(改源不改包、重新构建);路径③才是新建,由阶段 2 的模板初始化工具铺一套空骨架,再交单写 agent 写代码。关键在于这三条路最终汇到同一个 Agent 装配点——它们不是三套独立流程,只是初始 state / workdir 不同。把三种入场收敛到同一个装配点,而不是为每种入场各写一条链路,是这张图背后的简化决策。要注意的边界:整条 tier2 轨待 spike,这三条加载路本身都是 tier2 待建(虚线),而它们脚下的官方 Agent Service 与 MessageBus 是现成实线——接线待建,底座现成,这条虚实之分是读这张图时最该先盯住的一层。
图 A2 · Agent 非常驻 + AgentState + checkpoint
这张图回答「tier2 的 agent 实例到底怎么活、断了怎么续」。结论先放在最前面:agent 是一个无状态的 ReAct 引擎,实例非常驻——它不是一个长跑的进程,而是每次 run 现组装、跑完即弃,不留活对象。图左侧那条「现组装 → 跑 ReAct 多轮 → 跑完即弃」的生命周期三态画的就是这件事:构造时持有 model / toolkit / middlewares / state,跑若干轮 ReAct(cur_iter 自增),跑完对象就销毁了。这不是一个随意的实现选择,而是 AgentScope 2.0.2 service 化的天然形态——service 要多租户、要能横向起多个进程处理不同会话,就不能让 agent 在某个进程的内存里长期活着。
图左下角那条「关键推论」是整张图的逻辑枢纽:既然没有常驻进程可以序列化,所有「下一轮还要用」的东西就都得外置到一份可持久化的状态里。这就引出图中段那个实线框的 AgentState——它是 AgentScope 2.0.2 自带的 pydantic 模型(源码 agentscope/state/_state.py),三个核心字段把一次生成的全部活记忆装了进去:context 是工作记忆,即喂进 LLM 的未压缩对话上下文;cur_iter 是当前轮次,记 ReAct 循环走到了第几轮;tasks_context 是任务清单,即拆解后的子任务表。图里那条蓝色说明带点出了 goal 和进度是怎么追踪的——目标来自输入(brief / play_spec / GDD),进度靠 tasks_context 逐项 TaskCreate / TaskUpdate 追踪,像一张会随生成推进不断勾选的 todo list。AgentState 是官方现成的(实线),tier2 直接用它装状态,不自己另造一套状态模型。
图右侧那个虚线框的 checkpoint,是这张图最该破除的一个直觉误解:checkpoint 不是去序列化一个活对象。直觉上「保存进度」像是把正在跑的 agent 冻起来存盘,但 agent 非常驻、根本没有活进程可存——checkpoint 在 tier2 里的真实含义是存 / 取那份 AgentState。它配 AgentScope 2.0.2 现成的 StorageBase 抽象、用 RedisStorage 落 Redis(StorageBase 实线现成,每轮 checkpoint 这件 tier2 接线虚线待建)。两条硬约束写在右下角:一是每轮 checkpoint,cur_iter 每自增一轮就落一次 state,粒度细到能从任意一轮断点续上;二是半轮副作用须幂等无脏,因为续跑可能在一轮的中间断掉重来,如果半轮里那些副作用不幂等,重跑就会脏数据,所以这是一条要在长程一致性里专门采集字段去验的可靠性约束。
图底那条蓝带把「非常驻 + AgentState」这条机理直接接到了实用价值上:它决定了 tier2 怎么做断点续跑。resume 不是什么特殊机制,就是图 A1 里 session 路径①的具体落实——从 StorageBase 读回上次的 AgentState,把它作为初始 state 注入新组装的非常驻引擎,引擎据此重建工作记忆与 cur_iter,然后从那一轮续接 ReAct 循环往下跑,已经完成的 TODO 不重做。一句话:非常驻不是缺陷,而是把「断点续跑」从难题变成了「读回 state 再装配」这件平常事。本图是总览图 3(运行时内部)和图 8(类图)的逐字段放大——总览把 Agent 与 Workspace 的整体结构画在一处,本图只取非常驻、AgentState 三字段、checkpoint 存 state 非存活对象这一面展开,Agent 与 Workspace 的双轴关系见图 A3,本图不重画。
图 A3 · Workspace 双轴注入
这张图存在的唯一目的是纠一个会带歪整个 tier2 设计的误解:很多人第一眼会把 Workspace 理解成「一个 environment,agent 跑在它里面、被它包着」,照这个理解去设计,数据面和注入关系全会接反。实情正相反——Workspace 是执行环境,它沿两条轴注入 agent;agent 持有 Workspace 的引用,不嵌在它里面。图的布局本身就在说这件事:左边是 agent 本体(无状态 ReAct 引擎,官方现成),右边是 Workspace(执行环境的真实载体,官方现成),中间两条箭头都是从 Workspace 指向 agent——注入的方向是 Workspace → Agent,不是 Agent 进 Workspace。
两条轴是这张图的主干。轴①是资源注入:Workspace 经 get_toolkit 把它内建的工具、加上 list_skills() 列出的 skills、加上 list_mcps() 列出的 MCP,汇成一个 Toolkit,注入到 agent 的构造参数里,成为 agent 能调用的工具集(源码 app/_service/_toolkit.py:27)。轴②是 offloader:Workspace 本身被当作 offloader 挂在 agent 上,agent 的上下文与工具结果卸载就挂到这个引用上(源码 agent/_agent.py:104 的 offloader 参数)。看清这两条轴,就能回答「那到底什么东西是『跑在 Workspace 里』的」——是 MCP 进程、是 skills(SKILL.md)、是 workdir 里那套多文件源工程,这些才真正在 Workspace 里运行;agent 本体不在里面,它只持一个引用,每 run 现组装、跑完即弃。这个区分不是咬文嚼字:它决定了 tier2 该把工具和资源挂到哪、该在哪埋观测点、隔离边界画在哪条线上。
图右下那排 WorkspaceBase 三实现,是这套抽象给 tier2 的隔离强度梯度。LocalWorkspace 跑本地进程,隔离最弱、最快;DockerWorkspace 用容器隔离,中等强度;E2BWorkspace 是远端沙箱,隔离最强。三者都是官方现成抽象,tier2 只是在其上挂自己要的工具与资源,不凭空自建一个 environment 数据面。图里把 spike 期的取舍标得很清楚:spike 就近用 Local / Docker 起手(最快、好调试),E2B 那种远端强隔离对齐的是更长期的多租户 / premium 层,用远期紫画、不是 spike 期投入项。
图左下角那个虚线框是这张图里唯一一处真正卡住 spike 的待裁项——D5 沙箱底座选型,标着「spike 前置阻断」。它要先回答一个承重前提:确定性硬门要的「真浏览器低层探针」(page.evaluate、navigate、screenshot、输入注入)在选定的沙箱上够不够用。候选 A 是 agentscope-runtime 的 BrowserSandbox,如果它把这些能力逐项暴露够了,就直接用它跑探针矩阵(当前全仓零引用,要先验);候选 B 是回落到自建薄沙箱加复用现行的 play.cdp.cjs 运行 / 截图 / 证据骨架(但那套探针硬编码了 LittleJS,要为 Phaser 重写)。这道结论必须在 spike 探针矩阵开跑前出来——出不来,矩阵根本跑不起来,所以它是属主标记的前置阻断项。图底那条蓝带把整张图收口成一句话:Workspace 注入 agent,不是 agent 嵌进 Workspace;tier2 不凭空自建 environment 数据面,在官方 Workspace 抽象上挂工具与资源即可,而「在哪跑、隔离多强」由沙箱底座(Local / Docker / E2B 与 D5 选型)解决。本图放大的是总览图 3 的双轴注入和图 8 的 WorkspaceBase 类图,不重画类图本身。
图 A4 · Middleware 洋葱
让 agent 自治生成游戏,光有 agent 和执行环境还不够——还得能在它跑的过程中刹住烧钱、超时硬切、把每一步都记下来,而且这些横切的事不能散落进业务逻辑里各写各的。这张图回答的就是这些横切关注点统一挂在哪。答案是 AgentScope 2.0.2 的 MiddlewareBase 洋葱:它在 agent 执行的若干钩子上层层拦截,每一层用 next_handler() 把下一层包在中间,外层裹内层,所以叫洋葱。tier2 把成本刹车、硬熔断、可观测全挂在这套洋葱上,不另起机制、不散落进业务代码——这是框架给的扩展点,直接用。
图左侧那组同心环画的是四个 onion 钩子,从外到内各裹住 agent 执行的一层。最外环 on_reply 是一整次回复的进出边界;往里 on_reasoning 裹推理 / 模型调用阶段;再往里 on_acting 只裹单次工具执行那层 I/O(toolkit.call_tool);最内环 on_model_call 拦截裸模型 API 调用——这一环是钱算在哪的地方,因为它能读到 ModelCallEndEvent 带的 token 用量(input_tokens / output_tokens),成本台账和 trace 的 token 都从这一环取。洋葱框外下方那个单独的框是第五个钩子 on_system_prompt,它和前四个不同,不是前后包裹,而是顺序变换——多个 middleware 串成一条管线,各拿上一个的输出去改 system prompt 串,所以它是 transformer 而非 onion。四个 onion 加一个 transformer 共五个挂载点,按源码 _base.py 逐条核过,未实现的钩子运行时自动跳过。看懂这五个钩子各裹哪一层,才能回答「某个横切关注点该挂哪个钩子」。
图右侧那三类挂在洋葱上的东西,是这张图最该让人一眼分清的现成与自建之别。第一类是官方 ReplyBudgetControlMiddleware,做预算软刹(实线现成):它挂 on_reply 加 on_reasoning,在 on_reply 里按 ModelCallEndEvent 累计加权 token,越阈值后在 on_reasoning 里注入收尾提示、并强制 tool_choice=none 让它收尾。但要看清它的天花板——它只数 token、不换算金额、更不硬拒,刹不住一个已经在烧钱的失控循环。第二类正是为补这个缺口而设的自建硬熔断(虚线待建):TimeoutMiddleware(超时硬杀本次生成)、StuckDetectMiddleware(卡死 / 无进展硬杀)、预算硬闸(token 乘 new-api 单价换算成 ¥ 累进台账,越硬上限即 fail-closed 抛错终止,不只注入提示)。它们同挂这套洋葱、不另起机制,官方软刹刹不住时由它们硬切;在这套硬熔断建成前,tier2 不规模化跑、只在严格时间盒的实验里跑。第三类是官方 TracingMiddleware,做可观测(实线现成):它把 typed Event 流(ThinkingBlock / ToolCall / ModelCallStart / End 等)转成 OpenTelemetry span 汇进 AgentScope Studio,tier2 写轨迹不必自己埋点,复用这条官方 Event→OTel 管道、再加一层 adapter 映射进统一 trace 契约即可。
图底那条与 D12 运行治理门的分工带,讲清了「洋葱」和「门」各管哪一段,避免把两者混成一回事或重复造。洋葱在 agent 进程内,管 per-run 的成本 / 超时 / 卡死 / 观测;D12 在生成任务入口前,管配额 / 并发 / 背压 / 降级——一个在进程里逐轮拦,一个在入口处先闸,层次不同。两者之间有一个清晰的衔接点:D12 那道「花到上限就拒绝执行」的预算闸,在 agent 内的落点正是同口径自建一个预算 Middleware、挂 on_model_call、订阅 ModelCallEndEvent。这就构成了图底那句三层成本强制——worker 本地预测先闸、D12 网关配额二闸、任务 deadline 三闸。要记一条现行边界:D12 现在只覆盖 SAA,tier2 接入的入口、预算扣减、并发释放、失败补偿还待补,这是 D12 的已知边界。本图放大的是总览图 8 关键类图里 MiddlewareBase 那一支——把 ReplyBudgetControlMiddleware(现成)、TimeoutMiddleware / StuckDetectMiddleware(自建)各自挂哪个钩子、做什么逐项展开,不重画类图。
3 图清单与状态表
| # | 图名 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|
| A1 | Agent Service 与 session 三路径 | SVG · 横向链路 + router 网格 + 三路汇聚 | 现(官方 Agent Service / MessageBus = 现成)/ 建(tier2 接线待 spike) | cloud 经 REST POST /sessions 建会话 + SSE 收流;八个 router;MessageBus 四能力(Redis Stream replay / pub-sub / 分布式锁 / 取消信令);SSE 可恢复;session 三加载路(续接 / 加载已有工程 / 新建)汇到同一 Agent 装配点 |
| A2 | Agent 非常驻 + AgentState + checkpoint | SVG · 三段结构 + resume 链路带 | 现(AgentState / StorageBase = 官方现成)/ 建(tier2 非常驻装配 + 每轮 checkpoint + resume) | agent 非常驻三态生命周期;AgentState 三字段(context / cur_iter / tasks_context)+ goal/进度追踪;checkpoint = 存 state 非存活对象、配 StorageBase 落 Redis;每轮 checkpoint 与半轮幂等两条硬约束;resume = 取回 state 装配续跑(对应 session 路径①) |
| A3 | Workspace 双轴注入 | SVG · 左右双轴 + 三实现 + D5 二分 | 现(Agent / Workspace / Toolkit / 三实现 = 官方现成)/ 建(tier2 注入工具集 + D5 沙箱底座)/ 缓(E2B 远端强隔离 = 更长期层) | 纠误解:Workspace 注入 agent、非嵌套;轴① get_toolkit 汇 Toolkit、轴② Workspace 作 offloader;真跑在 Workspace 里的是 MCP / skills / 文件;WorkspaceBase 三实现隔离强度梯度;D5 沙箱底座 spike 前置阻断(BrowserSandbox vs 回落 CDP) |
| A4 | Middleware 洋葱 | SVG · 同心环 + 右侧三类 + D12 分工 | 建(tier2 洋葱挂载待 spike;软刹 / trace 官方现成,硬熔断自建) | MiddlewareBase 4 onion 钩子(on_reply / on_reasoning / on_acting / on_model_call)+ 1 transformer(on_system_prompt);挂洋葱三类(官方预算软刹 / 自建硬熔断三件 / 官方 TracingMiddleware);三层成本强制;与 D12 运行治理门的进程内 vs 入口前分工 |