--- name: agentscope-2.0-facts description: AgentScope 2.0 架构事实速查(源码实证 v2.0.2 + 官方文档)——编排/沙箱/服务化部署,给 tier2 富游戏线设计用 node_type: knowledge --- # AgentScope 2.0 架构事实(源码实证 + 官方文档) 本文记录 AgentScope 2.0 的真实形态。来源是直接读 `/root/oss/agentscope`(checkout 在正式版 **v2.0.2**,即 PyPI 当前最新稳定版)的源码,并与官方文档 `docs.agentscope.io/v2` 交叉验证,每条关键结论都给了源码出处。 **版本号澄清**:PyPI 上没有 2.0.3 这个版本,早先文档里的「AgentScope 2.0.3」是笔误,正确是 2.0.2。AgentScope 的 1.0.x 到 2.0.x 是同一条线的连续大版本升级,不是两条并行的线;引用时以 `/root/oss/agentscope` 当前 checkout 的 tag 为准。 ## 核心范式 2.0 是一次架构大重写。1.x 的静态编排原语(`pipeline` / `MsgHub` / `sequential_pipeline`)已经全部删除——在 `src/` 下搜这些类名零命中。取而代之的是「单个自带 ReAct 循环的 `Agent` 类 + 一个 FastAPI 服务层(`agentscope.app`)」。多 agent 协作、对外发布、沙箱执行这些能力,都上移到了服务层,而不再是库里的拼接式管道。 ## 编排:单 Agent 自治 + 服务层 Team 工具 `agentscope.agent` 模块只导出一个统一的 `Agent` 类,它自带 reasoning→acting 的 ReAct 循环(`agent/_agent.py:594` 的迭代主体,`max_iters` 兜底退出)。1.x 那种声明式的 agent 子类(ReActAgent / DialogAgent)和消息管道都不存在了。 需要多个 agent 协作时,走的不是静态拓扑图,而是**把「建队、派 worker、对话」做成工具交给 leader agent 自己调用**:`AgentCreate` / `TeamCreate` / `TeamSay` / `TeamDelete` 四个工具配 `SubAgentTemplate`(worker 蓝图)。leader 调 `AgentCreate` 就 spawn 一个 worker agent + session,worker 的 `source="team"`、只拿得到 `TeamSay`(向 leader 汇报),leader 拿全套工具(`app/_service/_toolkit.py` 按 `source` 选工具可见性)。这是 agent-as-tool 的动态组队,对应官方哲学——靠模型自身的推理和工具调用,而不用刚性 prompt 和带倾向的编排去约束它。 **一个硬约束**:这套多 agent 能力**只在 app 服务层可用**,纯库里 import 一个 `Agent` 跑脚本是没有的。 ## 沙箱:编排后工具调用直接落沙箱执行 Workspace 提供三种执行后端(`workspace/__init__.py`):`LocalWorkspace`(host 进程内,零隔离,开发用)、`DockerWorkspace`(容器)、`E2BWorkspace`(E2B 云沙箱)。agent 的工具来自 workspace(`get_toolkit(workspace=...)` 时 `tools = await workspace.list_tools()`),所以「换一个 workspace」就把执行环境从本地搬到了容器或云沙箱。 执行如何落进沙箱:Local 后端的 Bash/Read/Write 是 host 进程内的 Python 工具;Docker/E2B 后端的 `list_tools()` 返回空,工具改由容器内的 FastAPI MCP gateway 提供——agent 调工具时,host 侧 `GatewayClient` 发 `HTTP POST {gateway}/mcps/{mcp}/tools/{tool}`(`_gateway_client.py:136`)到容器内 gateway 真正执行。这就是「编排好之后工具调用直接在沙箱里跑」的机制。 **一个坑**:Docker/E2B 沙箱镜像默认不注册任何 filesystem/bash MCP,要在沙箱里有 Bash/Read/Write,得自带 MCP server 注册为 `default_mcps`;只有 Local 后端内置这些工具。 ## 安装与部署:pip 装包即可,官方只主推一条生产路径 跑 AgentScope **不需要 clone 仓库**——`pip install agentscope[full]` 装包即可,`app` / `workspace` / `tool` 全在 wheel 内。框架**没有 CLI**(pyproject 无 `[project.scripts]`,不存在 `as serve` 之类命令),启动靠在 `main.py` 里自己调 uvicorn。两个例外要记:Docker 沙箱在 2.0.2 这个「尚未发布到 PyPI 的过渡期」目前需要本地有 agentscope 源码(构建镜像时 COPY 进去);E2B 沙箱需要 E2B 账号和 API key。`/root/oss/agentscope` 这份 clone 的主要价值是读源码核对,而非生产运行的必需品。 生产部署,官方主推且唯一给出端到端示例的形态是 **Agent Service**:用 `create_app(storage, message_bus, workspace_manager)` 造一个 FastAPI/ASGI app(`app/_app.py:33`),再用 uvicorn 起进程(`examples/agent_service/`)。它提供多租户、多会话、REST 触发 + SSE 事件流、HITL 审批、定时任务、凭据托管。两个要点决定了接入方式:一是 **chat 端点是 fire-and-forget**,`POST /chat` 立即返回 `started`,事件要另外从 `GET /sessions/{id}/stream` 的 SSE 流里收;二是**强依赖 Redis**——storage 和 message_bus 都只有 Redis 实现,没有 in-memory/SQLite 版本,生产必须配 Redis。要弹性扩展,就把这个 ASGI app 自己容器化后上 K8s 或 serverless,框架不提供 app 级的 Dockerfile/compose。 ## 生态定位与一个架构信号 独立的 `agentscope-runtime` 项目**已归档**:官方声明其全部能力(工具沙箱、Agent-as-a-Service、可观测)已原生并入 AgentScope 2.0。所以 2.x 做沙箱和部署不要再装那个独立仓,`agentscope[full]` 一个包就齐。AgentScope Studio 是开发期的可视化追踪/调试台,不是生产承载层。 一个值得记的信号:官方称 **Spring AI Alibaba 底层将采用 agentscope-java 作为引擎**。这意味着项目里「SAA 廉价线」和「AgentScope 富游戏线」在引擎血统上正趋同。这条长期架构判断**已裁定(2026-06-25 reframe):框架收敛 AgentScope、SAA 降最低优先级(留作远期适配验证可插拔的目标)**——三档生成不再按引擎或产线分,而按 AI 参与深度切;详见运行时 SoT [`生成引擎/agentic运行时架构图说`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md) §一 / §四。相关决策见 [[saa-agentic-infra-decision]]。 ## 关键纠偏对照 | 凭名臆想 | 源码实证(v2.0.2) | |---|---| | 2.x = pipeline / MsgHub | 已删,改单 Agent ReAct + 服务层 Team 工具 | | 多 agent 是静态编排图 | agent-as-tool 动态组队,且只在 app 服务层 | | 用框架要 clone 源码 | `pip install agentscope[full]` 即可(Docker 沙箱过渡期暂需源码) | | 有 CLI / `serve` 命令 | 无,生产 = `create_app()` FastAPI + uvicorn + Redis | | 沙箱要装独立 agentscope-runtime | 已归档,能力并入 2.0 主框架 | ## 便宜档 cheap-worker 实现 API 速查(2.0.2 源码实证 + WU-A spike 落地) 上文偏架构(编排/沙箱/服务化)。本节是「怎么用库写一个跑通的 agent」的实现层速查——WU-A spike 把便宜档生成核心重写进 AgentScope(`cheap-worker/`,import 复用 tier2 框架层)时落地并核验,下一个 WU-A 全量重写 / n=5 直接照用,不必重新挖。 **import 路径(全部源码核验存在)**:`from agentscope.agent import Agent, ReActConfig, ContextConfig` · `from agentscope.tool import Toolkit, FunctionTool` · `from agentscope.middleware import MiddlewareBase` · `from agentscope.model import OpenAIChatModel, AnthropicChatModel` · `from agentscope.message import UserMsg, TextBlock` · `from agentscope.state import AgentState` · `from agentscope.permission import PermissionContext, PermissionMode`。 **三个「凭名臆想会用错」的不存在 API(源码全树零命中,别用)**: - `register_tool_function` **不存在** → 注册靠构造器 `Toolkit(tools=[FunctionTool(fn), ...])`。 - `ReplyBudgetControlMiddleware` **不存在** → 预算/软刹得自挂 `MiddlewareBase` 的 `on_system_prompt`/`on_model_call` 钩子(tier2 的 `CircuitBreakerMiddleware` 即如此自实现)。 - 内置 ReAct **不会「跑满 max_iters 才停」** → 在「模型产出无 tool_call 的纯文本回合」即退出(`agent/_agent.py`)。要多轮自修必须在 Agent 外**自建有界 resume 循环**:`for attempt in range(max_resumes): await agent.reply(...); 判收敛/门绿;否则带失败反馈再 reply`。这一圈正对应 Node 生成 harness 的 while 主循环。 **工具写法(schema 自动抽)**:每个工具是 `async def` + 参数类型注解 + Google docstring(`Args:`),`FunctionTool(fn)` 据此抽 schema;闭包捕获一个可变 session 对象做跨工具状态;返回 str(纯文本或 `json.dumps`)。 **Agent 构造(无人值守跑脚本)**:`Agent(name, system_prompt, model, toolkit, middlewares=[trace, breaker], state=AgentState(permission_context=PermissionContext(mode=PermissionMode.BYPASS)), react_config=ReActConfig(max_iters=...), context_config=ContextConfig(...))`。**BYPASS 必给**——否则 FunctionTool 默认 check_permissions 返回 ASK,无人值守跑会卡死。`reply` 是 async:`await agent.reply(UserMsg(name="user", content=text))`(UserMsg 必带 name)。**model 直调(验连通用)**:`await model([UserMsg(...)]) → ChatResponse(content=[TextBlock(text=...)], ...)`。 **便宜档复用 tier2 框架层(import 不重写、零改 tier2)**:`config.build_model_openai("MiniMax-M3", max_tokens=16000, record=True)`(OpenAI 协议、自动补 /v1、自动装代理旁路 + 取 key)· `config.build_context_config()`(历史压缩)· `CircuitBreakerMiddleware` + `Tier2TraceMiddleware`(四道熔断 + trace,与模型档无关,`enable_rmb_gate=False` 可关 ¥ 闸)· `client.install_proxy_bypass`(**必须在 import openai 之前**,否则本机 clash 把发往内网网关的请求转走得 502)· `client.get_api_key()`(**只读 env `NEWAPI_KEY`**;内网阶段 key 在 `docs/内网凭据与端点.md`,调用方先解析注入 env)。 **跨包 import 含连字符目录**:`gen-worker` 不能 `import`;把 `tier2/gen-worker/` 加进 `sys.path` 再 `from worker import ...`(`from observability import ...` 同理)。 落地实证 = 便宜档 Python 线 `cheap-worker/`(WU-A spike,端到端九门对照 Node 9/9 持平、过门率 1.0=1.0、对 tier2 零改动)。便宜档生成线现状见 [`cheap-model-game-generation`](../skills/cheap-model-game-generation.md)(注意其旧 W-G1 路已被 cheap-worker 取代)。