agentscope-extensions-agent-protocol 把 AgentScope 的 Harness Agent 暴露为 Agent Protocol 标准 HTTP 接口,让外部系统(CI、其他 Agent 平台、自动化任务)可以用统一的方式提交”任务”,无需关心你的 Agent 实现细节。
何时使用
- 想让 Agent 像云函数一样被远程调度。
- 已有团队在用 Agent Protocol 客户端,想直接接进去。
- 把 AgentScope Harness Agent 嵌进 Spring Boot 服务,自动暴露
/tasksREST 端点。 - 作为 远程子 agent 的托管端,供另一个 Harness 父代理通过 HTTP 调用。
协议分层
AgentScope 用不同协议覆盖不同信任边界 / 交互面:添加依赖
启用方式
模块以 Spring Boot 自动配置形式提供,所以仅需在 Spring Boot 应用里:- 注入一个
HarnessAgentBean(或自定义AgentFactory)。 - 在
application.yml里启用:
/tasks 系列 REST 接口。
控制面 vs 执行 workspace
AgentProtocolTaskStore 通过独立的 ProtocolTaskRepository 持久化协议任务元数据(submit / resume /
snapshot 用的 TaskRecord)。默认根目录为 agentscope.agent-protocol.task-store-path
(${user.dir}/.agentscope/agent-protocol),落在合成桶
agents/_agentscope_protocol/tasks/ 下。
该路径与每个 HarnessAgent 自己的 WorkspaceManager(MEMORY、sessions、skills)相互独立。
多 agent 的 AgentFactory 可以为每个 agent 配置不同的 .workspace(...);协议侧按 task_id
查找始终走控制面仓库。
也可以自行提供 ProtocolTaskRepository Bean 覆盖默认实现。AgentProtocolTaskStore 只接受
ProtocolTaskRepository,不要传入执行 Agent 的 WorkspaceManager。
并发执行
Agent 在调用之间是无状态的——单例即可服务多个并发任务。每个任务通过RuntimeContext 携带独立的 (userId, sessionId),状态完全隔离:
Agent 选择(AgentFactory)
由哪个 agent 执行任务,交给 AgentFactory bean 决定。不定义时,默认工厂对所有任务返回唯一的 HarnessAgent bean。
自定义 bean 即可按 agent_id、租户或任意自定义提交上下文字段路由:
AgentRequest 字段:
工厂每次运行调用一次——提交时一次,之后每次
/resume 再调用一次,且拿到的仍是最初的提交上下文,因此 HITL 暂停前后的路由结果保持一致。
任务并发执行时请每次返回独立实例(例如 prototype 作用域 bean)。返回 null 会让任务以错误状态结束。
上下文属性(context.attributes)
调用方的自定义数据放在 context.attributes 里,单独嵌一层,不与协议自身的上下文字段混在一起。除了 AgentFactory 能读到之外,这些属性还会随 RuntimeContext 进入实际执行的 agent。
它们整体挂在一个带命名空间的键下——AgentProtocolConstants.RUNTIME_CONTEXT_ATTRIBUTES_KEY(agentprotocol.context.attributes):
agentId 决定异步工具的唤醒路由,outboundAddress 携带网关回推地址。调用方一旦把属性命名成这些词,就会改变 agent 的行为。属性不会写进系统提示词,因此不影响模型看到的内容。
把属性提升为独立键
当某个工具期望直接读ctx.get("tenant"),或需要把属性转成类型化对象时,注册 RuntimeContextCustomizer bean。RuntimeContextCustomizer.flatten 按显式白名单拷贝,并自动跳过框架保留键:
@Order 应用到每次运行,且在命名空间注入之后执行——后者覆盖前者。手写 customizer 属于可信扩展,可以写任意键,包括保留键。
从父 agent 发送属性
父 agent 调用远程子 agent 时有两个来源,二者合并且按调用传入的优先:端点
提交任务
POST /tasks
context 字段:
成功响应:
{ "task_id", "status": "pending" }。
轮询 / 等待 / 取消
远程 agent 等待工具确认时,快照会报告
status: awaiting_confirm,但存储的 TaskStatus 仍为 RUNNING,因此父侧 barrier 会继续等待。
事件流(SSE)
GET /tasks/{taskId}/events
以 Server-Sent Events 推送 agent 进度。需要 agentscope.agent-protocol.streaming-enabled=true(默认开启)。
断线重连 / 续订:
- 查询参数
from_seq—— 从该序号之后开始 - 请求头
Last-Event-ID—— 未传from_seq时使用(含义相同)
id、远程事件类型为 event、JSON 正文为 data。
事件流详细度
提交时的context.detail 决定订阅方能收到多少事件,每一档都是前一档的超集:
只有
verbose 能完整复现 agent 自身的事件流。无法识别的取值按 status 处理。
除各类型专属字段外,每个事件正文还带两个字段:
两者都是增量字段:忽略它们的客户端照旧读扁平字段(
text、toolCallId、status 等),早于 AGENT_EVENT 的客户端则直接跳过这类消息。
HITL 恢复
POST /tasks/{taskId}/resume
tool_call_id 也可作为 toolCallId 的别名。需要 agentscope.agent-protocol.hitl-enabled=true(默认开启)。成功响应:{ "task_id", "status": "running" }。
与调用方父 harness 的 HITL 交互见 远程授权。
配置项
示例:
关闭 enabled 时(默认)即使引入依赖也不会暴露任何 REST 接口,可放心打包。
与 Workspace 配合
每个 task 都会拿到WorkspaceManager 分配的隔离工作目录;任务结束后,工作区里的产物(文件、日志)会通过 Agent Protocol 的标准接口暴露出来,外部客户端可以直接拉取。