AgentScope Service 技术解读:控制面、数据面与可恢复的 Agent 运行时¶
如果把发布通告看作「AgentScope Service 能做什么」,这篇更关注「它是怎么做成的」。我们将沿着产品资源模型、平面边界、Turn 生命周期、Brain / Hands 拆分、Session 事件契约,以及多框架接入路径,把平台背后的系统设计讲清楚。
产品概述与能力说明见姊妹篇:AgentScope Service 正式发布。本文默认读者已了解 AgentScope 2.0 / Harness 的基本概念,并关心如何把单个可运行 Agent 扩展成可运营平台。
什么是 AgentScope Service(实现视角)¶
从实现上看,AgentScope Service 不是单一进程,而是一组边界清晰的组件:
组件 |
角色 |
|---|---|
|
对外入口:认证、路由、公共 API |
|
Go 控制面:产品资源、舰队注册、Session / Team 运行时状态、控制台后端 |
|
Java 数据面:Managed Session Brain,基于 AgentScope Harness 执行 Turn |
|
Channel、Cron、出站任务、Self-hosted Hands Worker |
PostgreSQL |
按 schema 分割的权威状态: |
Web Console |
Dashboard · Managed Agents · Agent Teams |
它同时服务两类 workload:
Managed Agents:控制面持有版本化 Snapshot,数据面按 Snapshot 构建
HarnessAgent并跑事件化 Turn;BYO Agents:已有 AgentScope / LangChain / Claude 等运行时通过扩展、
instrument()或 Sidecar 接入,进入同一舰队与 Session 观测模型。
控制面管理期望状态与运行状态,但不执行模型 Turn;推理循环留在数据面或接入方自己的 Runtime。这个边界贯穿整套架构:一旦控制面开始「顺便跑模型」,平面职责、扩缩容和故障域都会纠缠在一起。
对部署形态而言,本地开发可关闭 Kubernetes Reconciler,走 Hosted Product 路径;生产也可启用 Aistio 的 CRD / Workload 能力,把声明式 Agent 与舰队治理接到集群。产品品牌仍是 Agent Service,底层控制组件是 aistiod。
为什么需要这样一套平台¶
单看 agent loop,现在的框架已经足够写 Demo。难的是把「能跑」变成「能运维」:
本机脚本 / CLI:状态在本地目录,适合个人,不适合多副本与审计。
业务服务内嵌 SDK:每个应用各自实现 SessionStore、HITL、租约、事件回放与权限,成本重复且标准不一。
低代码编排:把 Harness 工程细节外泄给业务配置者,平台难统一升级。
单一托管运行时:效果好,但跨框架舰队、客户 VPC Hands、以及团队协作状态往往另起炉灶。
另一类隐藏成本是「状态归属不清」。很多人把 Java/Python 进程里的 agent 对象、前端 SSE 流、数据库里的聊天记录混为一谈。对象可丢、流可断,只有带序号的持久化事件与可恢复状态存储,才能支撑多副本、故障切换和审计回放。AgentScope Service 把这件事做成默认契约,而不是留给每个业务自选。
因此平台的解法可以概括为三句:
治理问题收敛到控制面与数据面契约;
推理内核收敛到 AgentScope Harness;
工具执行边界收敛到 Environment(Hands)。
业务侧尽量只定义 Agent 差异(prompt、工具、Skills、权限策略);压缩、恢复、事件、租约、审批则作为平台能力持续演进。平台升级 Harness 后,Managed Agent 应能共同受益,而不必逐个改流程图。
整体架构¶
┌────────────────────────────────────────────────────────────────────────────┐
│ Agent Service │
│ │
│ Web Console ──► Gateway :8080 ──┬──► aistiod :8081 (CP / RT) │
│ └──► dataplane :8082 (DP Brain) │
│ │ │
│ ▼ │
│ PostgreSQL │
│ cp · rt · dp schemas │
│ ▲ │
│ │ │
│ scheduler :8083 │
│ Channel / Cron / Hands Worker │
└────────────────────────────────────────────────────────────────────────────┘
平面职责¶
平面 |
负责 |
明确不负责 |
|---|---|---|
Gateway |
JWT / 公共路由 |
业务状态、模型调用 |
Control( |
用户、Agent 版本、Environment、Session 绑定、Team、舰队实例、运行时命令 |
模型 Turn |
Dataplane |
Turn Lease、事件落库、SSE、HITL、按 Snapshot 构建 Harness、Work Queue |
直读 |
Scheduler |
Channel、Cron、出站 Hands Worker |
推理循环 |
数据归属¶
各平面可共用同一个 PostgreSQL Server,但不共享表:
Schema |
Owner |
数据 |
|---|---|---|
|
|
用户、Agent、版本、Environment、Session、Vault、Memory、Deployment |
|
Aistio Runtime Store |
舰队实例、运行时 Session、Context、Team、Task、Message |
|
Java Dataplane |
Session Event、协调状态、HITL、Work Item、数据面投影 |
Dataplane 通过控制面内部 API 解析 Managed Session,并只使用返回的 Agent Snapshot 构建运行时。数据面副本可以水平扩展,但产品 Catalog 仍以控制面为准,避免双写和缓存漂移。本地 Catalog 回退看起来省事,长期往往制造「实例 A 已更新、实例 B 还在跑旧定义」的幽灵 bug。
一次 Turn 的完整路径¶
客户端向已有 Session 追加
user.message。Dataplane 获取 Turn Lease,并把 Session 标记为
running。控制面解析已固定版本的 Agent Snapshot、Environment、Workspace、Memory 与 Vault。
SessionTurnRunner执行HarnessAgent.streamEvents。agent.message、agent.tool_use、span.model_request_*等权威事件写入 PostgreSQL;可选 Preview Delta 仅用于打字机效果,不落库。Session 回到
idle、因 HITL / Tool Result 暂停,或以类型化错误终止。
客户端以持久化事件序列恢复,并通过:
GET /api/sessions/{id}/events/stream?after={seq}
做增量续传。进程内 Agent 对象和 Preview Stream 都不是权威数据源——这是可恢复 Session 的前提。
Turn Lease 的意义在于并发控制:同一时刻应只有一个执行者推进该 Session 的 Turn,避免双写事件序号、重复扣费调用模型,或在 HITL 等待期间被另一副本误续跑。Lease 丢失/过期后的接管策略,是数据面多副本可用性的关键细节。
Brain 与 Hands¶
Environment |
执行方式 |
|---|---|
|
在 Dataplane 宿主机跑文件系统与 Shell,仅建议开发 |
|
托管 E2B 等云沙箱 |
|
远程 / 分布式文件系统,不提供本地 Shell |
|
Brain 只暴露 Tool Schema;客户侧出站 Worker poll / ack / heartbeat / 回传结果 |
self_hosted 适合私有网络:无需给 Brain 开入站到客户内网,由 Worker 主动出站拉取工具调用。协议语义是稳定的 tool_use / tool_result 事件闭环——Hands 换地方,Brain 的推理循环不必重写。
安全与合规团队因此可以分开审批三个问题:模型上下文可见范围、工具可达网络与文件系统、结果回传 Brain 的数据最小化策略。这比把「整个 Agent 容器」当成一个黑盒权限对象更容易落地。
核心能力(实现层)¶
UI 截图请见产品版文章;此处聚焦机制。
Dashboard:舰队与运行时观测¶
Dashboard 的数据主要来自控制面 Runtime Store 与数据面事件投影,而不是前端临时聚合:
Agent / Instance 健康与在线清单
Session phase(如
active/idle/compressing/archived/terminated)与 Turn 时长Context pressure、Token delta、错误计数
Team 成员状态、任务进度、生命周期事件
这里有两个容易混淆的概念需要分开:
Session:可恢复的对话线程;
phase描述线程运营态。Turn:一次用户请求到回复的执行单元;时长统计应落在 Turn,而不是把 Session 存活墙钟时间误当成「活跃耗时」。
对 BYO Agent,Level-1 Session Snapshot 由适配器周期上报;控制面据此做舰队统计与运营操作(压缩、终止等)。字段语义必须跨框架一致,否则 Dashboard 会退化成各适配器各自为政的「指标墙」。Token 类指标也应优先使用 delta 聚合,而不是简单累加绝对值快照。
Managed Agents:版本化定义 + 事件化 Session¶
产品资源模型大致如下:
资源 |
作用 |
|---|---|
Agent |
版本化 System Prompt、模型、工具、MCP、Skill、协作配置 |
Environment |
工具执行边界与 Sandbox / Worker 配置 |
Session |
Agent 版本、Environment、Memory、Vault 与事件流的有状态绑定 |
Memory / Vault |
跨 Session 文档与加密凭据 |
Deployment / Channel |
Cron、Webhook、手动触发与消息通道 |
Team |
Lead / Member、Message、Task、Plan、生命周期 |
几个关键设计选择:
Session 创建是静态绑定
创建时只记录资源关系,不跑 Agent;第一条user.message才启动 Turn。Event-native
入站事件驱动工作,出站事件描述进度与结果。每个持久化事件有 Session 内单调递增序号,客户端可断点续传。HITL 作为一等公民
Ask Policy 工具会暂停 Turn,发出确认请求;user.tool_confirmation继续或拒绝,同时保留完整历史。权威事件 vs Preview
SSE 可推送event_start/event_delta获得即时体验,但最终以落库事件为准。UI 刷新、多端恢复、审计回放都依赖同一真相源。版本 pin
Session 绑定 Agent 的具体版本 Snapshot,避免运行中途定义被热更新导致不可复现轨迹。需要升级时,显式创建新 Session 或走产品定义的升级路径。
Managed Agent 在 Java Dataplane 中根据控制面 Snapshot 构建。底层直接复用 AgentScope 2.0 HarnessAgent:上下文压缩、工具结果淘汰、状态恢复、Skills / 子任务等工程默认项,不必在产品层再造一套 agent loop。产品层补的是租户资源、ACL、事件契约、Turn Lease、HITL ticket、Environment 与 Worker 队列——这些才是「框架」上升为「平台」的成本所在。
Agent Teams:跨 Session 的协作状态机¶
Agent Teams 把多 Agent 协作做成控制面资源,而不是某个进程内存里的临时聊天:
Lead / Member 拓扑与动态成员(数量 / 白名单约束)
单播与广播消息
共享任务、Claim / Assign、Plan Approval
成员 Wakeup、优雅关闭、生命周期时限、故障恢复
消息与任务跨进程、跨 Session 保留
对于 Managed 成员,Wakeup 可以进一步落到数据面 Session / Turn;对于 BYO 成员,则通过控制面命令与适配器能力协同。团队状态主要落在 rt schema,避免与单 Session 的 dp 事件日志混淆——Session 负责一次对话轨迹,Team 负责跨成员协作的持久单元。
一个务实约束是:Teams 不假设所有成员同源。Lead 可以是 Managed Harness Agent,Member 可以是接入的 Coding Agent 或 LangChain 服务。控制面负责拓扑、任务与生命周期,成员侧只需满足协作与观测契约。异构组队比「先统一框架再谈协作」更贴近企业现状。
如何接入¶
AgentScope(原生)¶
Java 侧通过 agentscope-extensions-aistio 接入。扩展负责把 Runtime 注册到控制面,上报 Session / Context / 健康信息,并承接运营命令。对已有 AgentScope 应用,这是侵入性最低、契约最完整的路径:与 Managed Agent 共用 Dashboard 与 Session 观测模型。
因为双方共享同一套 AgentScope 事件与状态语义,Level-1 / Context / 压缩等能力通常最先对齐。若你已经在用 HarnessAgent,接入的边际成本主要是依赖、注册配置与运行时标识,而不是重写业务 Prompt。
LangChain¶
Python SDK 提供 aistio.instrument()。对 LangChain / LangGraph,适配器挂在 Callback / Checkpointer 等拦截点:
import aistio
aistio.instrument(
app_or_client,
control_plane="aistiod.aistio-system:9090",
agent_name="my-langchain-agent",
namespace="default",
enable_events=False, # Level 2 事件默认关,可按需打开
)
设计原则是旁路上报:主路径成功优先,上报失败静默降级,避免控制面抖动拖垮业务推理。Level-1 默认打开以支撑舰队视图;更细粒度事件(Level-2)可按成本与合规要求打开。Context 上报采用 hash 变更防抖,减少无效全量推送。
Claude SDK 与 Sidecar¶
Claude Agent SDK 同样走 instrument(),通过装饰 SessionStore 等路径获得 Level-1 快照与压缩 / 终止能力。
对于 Claude Code、Qoder 等不便嵌入 SDK 的 Coding Agent,采用 Sidecar:
主容器继续跑原有 CLI / Agent;
Sidecar 观察本地 Session 目录(如
~/.claude/)与运行状态;向控制面上报舰队与 Session 信息,并转发可支持的运营命令;
必要时把 Session 文件态同步到外部存储,以支持跨节点恢复。
Sidecar 不是「再实现一个 agent loop」,而是在无法改二进制时,补齐控制面所需的最小可观测与可运营面。它也提醒我们:很多 Coding Agent 的真相在文件系统,而不在数据库——控制面必须能理解这种状态形态,而不是强迫所有 Runtime 先改存 PostgreSQL。
本地启动与验收¶
export DASHSCOPE_API_KEY=sk-xxx
cd agentscope-service
BUILDER_REBUILD=1 scripts/dev-up.sh
# Console: http://localhost:8080
scripts/smoke.sh
建议至少验收三类路径:
Managed Session:投递
user.message,从事件流恢复,刷新页面后序号续传正确;HITL:触发 Ask Policy,确认后续跑,历史完整;
self_hosted:Worker poll / ack / heartbeat / 回传tool_result,Turn 正确恢复。
详见 docs/guide/14-validation.md 与架构说明 docs/guide/02-architecture.md。
几个值得提前避开的实现误区¶
把 Preview SSE 当权威日志
打字机效果可以丢、可以重连重建;审计、复盘、计费应对齐落库事件序号。让数据面本地缓存产品 Catalog 并在控制面不可达时静默回退
短期看起来高可用,长期会出现「跑了未知版本」的最坏故障。宁可失败可感知,也不要静默用旧定义。把 Session phase 与 Turn 时长混用
active/idle描述线程态;耗时应落到 Turn。否则 Dashboard「谁最忙」会被长挂起会话误导。在 BYO 适配器里发明平行指标
舰队 KPI 必须共用语义。新框架适配优先对齐契约,再谈特化字段。把 Team 消息塞进某个成员的 Session 事件流冒充协作状态
Session 轨迹与 Team 状态机生命周期不同;混存会导致恢复、清理和权限边界全部出错。
这些点在单体 demo 里不明显,一旦多副本、多框架、多团队同时出现,就会变成线上事故的温床。
Roadmap(工程视角)¶
适配器覆盖面
深化 LangChain、ADK、Claude、Qoder、OpenAI Agents 等 Level-1 / Level-2 / Context 能力对齐,减少框架特化字段,保证 Dashboard KPI 同义。生产级多租户与治理
ACL、配额、审计、灰度发布、密钥轮换与更严格的 Environment 隔离策略;Vault / Memory 的生命周期与访问边界也会继续打磨。Automation
Deployment / Cron / Webhook / Channel 从「能触发」演进到「可编排、可回放、可补偿」。自动 Turn 一旦失败,要有类型化错误、重试策略与人工接管入口。事件驱动入口
GitHub / GitLab、钉钉、企微等:把外部事件稳定映射为 Session Turn 或 Team Task,并保留幂等与鉴权边界。外部系统重试是常态,平台侧必须防重复开工。Teams 与恢复
动态成员、计划审批、成员失联恢复、跨 Session Restart,以及 Managed / BYO 混合组队的一致性。协作状态机比单 Session 更难,因为失败域跨多个 Runtime。
和「只嵌入 Harness」差在哪里¶
如果业务服务里直接嵌入 HarnessAgent,你已经拥有不错的长任务与压缩能力。但一旦面对多租户、多副本、多团队,你还要补齐:
版本化 Agent 定义与 Session pin;
append-only 事件与游标续传;
Turn Lease 与 HITL ticket;
Environment 切换与 Self-hosted Work Queue;
舰队注册、上下文压力、压缩 / 终止命令;
Team 任务板与跨 Session 协作状态。
AgentScope Service 并不是「在 Harness 外面加一层 UI」,而是把上述分布式职责做成稳定产品资源与内部契约。Harness 让平台不必重写 agent loop;平台层仍要对状态归属、故障域和治理边界负责。
结语¶
AgentScope Service 的技术内核可以概括成三句话:
控制面管期望与运行状态,数据面跑 Turn,Hands 决定工具落点;
持久化事件序列才是 Session 真相,进程内对象只是可丢弃的缓存;
Managed 与 BYO 共用舰队契约,框架差异收敛在适配器,而不是散落在 Console。
如果你正在从「单个 Harness Agent」走向「可运营的 Agent 舰队」,这套分层会减少大量重复基础设施。欢迎直接阅读 agentscope-service/README_zh.md;产品能力与接入故事则可回到发布版文章。