通过agentscope在EKS部署远程沙盒和代理应用

news/2026/1/21 0:24:06/文章来源:https://www.cnblogs.com/peacemaple/p/19509149

参考资料

  • https://runtime.agentscope.io/zh/tool.html

AgentScope Runtime是一个面向 AI Agent 的全栈运行时,解决高效部署与服务化以及安全的沙箱化执行。

测试环境为python3.13,安装agentscope-runtime

uv add "agentscope-runtime[ext]"

Spring AI Alibaba 和 AgentScope-Java 的比较?

  • Spring AI Alibaba:追求稳定可控、业务嵌入,覆盖 90% 企业级应用场景
  • AgentScope-Java:若追求目标驱动、自主决策、多智能体协作,构建复杂智能体应用

sandbox沙盒工具和服务

Sandbox提供了一个安全且隔离的环境,用于工具执行、浏览器自动化、文件系统操作、训练评测等功能。Runtime支持即用和沙盒工具两种,本文只涉及到沙盒工具。

可以通过 Sandbox SDK 创建、连接、释放沙箱,默认使用docker运行sandbox,例如:

Base Image的示例如下

image-20260120224340787

Filesystem Image的示例类似,但是额外可以通过Web桌面访问地址访问文件系统,这里的url很有趣,是一个vnc的link,即

  • 通过websocket协议来连接浏览器的novnc客户端与容器中的vnc服务端,实现图形界面传输
  • 而对于浏览器的操作,则使用了Chrome DevTools Protocol (CDP) 协议

image-20260120224444105

sandbox sdk除了会启动对应的docker容器外,还会自动挂载本地目录到容器的/workspace下

"Binds": ["/home/xxx/sessions_mount_dir/c48d9ix2r7zl2zy766xwh0dq5:/workspace:rw"
]

runtime-sandbox-server

runtime-sandbox-server 是 Runtime Manager Service(运行时管理服务),用于集中管理和协调多个沙箱容器,如下日志的记录表明调用过程如下

  • 为客户端动态创建沙箱容器,从沙箱池中分配可用实例
  • 按照请求内容调用工具
  • 使用完毕后释放和清理容器

image-20260120222243246

runtime-sandbox-server 可以通过配置文件扩展功能,配置参考

export RUNTIME_SANDBOX_REGISTRY="agentscope-registry.ap-southeast-1.cr.aliyuncs.com"
runtime-sandbox-server --config k8s.env

通过额外的配置可以实现以下

  • 身份令牌验证
  • 预热容器池,当用户请求新沙箱时,系统将首先尝试从这个预热池中分配,相比从零开始创建容器显著减少启动时间。
  • 指定容器运行时,支持dockerk8sagentrun, fcgvisor,关于不同后端的比较也进行了详细罗列
  • 指定持久存储目录/workspace,默认为sessions_mount_dir
  • 启用redis为沙箱状态和状态管理提供缓存,优势是简单且延迟更低

我们尝试在k8s上启动sandbox,配置如下

POOL_SIZE=1
DEFAULT_SANDBOX_TYPE=base,browser
CONTAINER_DEPLOYMENT=k8s
K8S_NAMESPACE=default
KUBECONFIG_PATH=/home/ec2-user/.kube/config
CONTAINER_PREFIX_KEY=runtime-sandbox-container-

启动结果如下

image-20260120231826431

使用sandbox sdk连接远程执行,server报错如下,但是pod正常启动了

ERROR:agentscope_runtime.sandbox.manager.server.app:Error in call_tool: Runtime service did not start within the specified timeout.

检查发现server创建 Pod 时会自动创建一个 NodePort 类型的 名为runtime-sandbox-container-0ban2c523t0md7sx14w2c5g6v-service的svc,server会通过远程集群返回 Node 的 ExternalIP 或 InternalIP访问,优先使用ExternalIP 。在eks中配置的node的external ip地址为公网ip地址,由于没有放行规则导致无法连接。

暂时修改源码让InternalIP优先返回,始终返回internal ip,之后访问成功

image-20260120235056670

runtime-sandbox-mcp

runtime-sandbox-mcp 具体在做什么?允许通过 MCP 协议远程访问沙箱功能,实际上通过mcp.run() 运行服务器,默认 transport 是 'stdio',将sandbox-server暴露为mcp服务,例如如下的配置示例,通过远程的 sandbox 服务器 http://127.0.0.1:8000 来安全地执行沙箱中的命令

{"mcpServers": {"sandbox": {"command": "uvx","args": ["--from","agentscope-runtime","runtime-sandbox-mcp","--type=base","--base_url=http://127.0.0.1:8000"]}}
}

可见将两者搭配,可以通过runtime-sandbox-server在远程机器启动sandbox服务,然后通过runtime-sandbox-mcp将sandbox封装为mcp服务供agent使用

from agentscope_runtime.sandbox import BaseSandboxwith BaseSandbox(base_url="http://127.0.0.1:8000") as box:print(box.run_ipython_cell(code="print('hi')"))

还可以通过添加mcp的方式扩展sandbox tools

with BaseSandbox() as sandbox:mcp_server_configs = {...} # mcp配置服务提供get_current_time工具sandbox.add_mcp_servers(server_configs=mcp_server_configs) # # 将MCP服务器添加到沙箱print(sandbox.list_tools()) # 列出所有可用工具(现在包括MCP工具)sandbox.call_tool("get_current_time",arguments={"timezone": "America/New_York"})

sandbox service

  • https://runtime.agentscope.io/v1.0.5/zh/service/sandbox.html

除了基本的运行方式,还可以通过 sandbox service 沙箱服务实现多会话场景下复用与隔离资源,具体是通过 session_iduser_id 来管理不同用户会话的沙箱环境

async def main():# sandbox_service = SandboxService() # 启动本地服务器# 指定远程服务器地址sandbox_service = SandboxService(base_url="http://your_IP_address:8000",  # 替换为实际的服务器IPbearer_token="your_token"  # 可选:如果需要身份验证)await sandbox_service.start()...sandboxes = sandbox_service.connect(session_id=session_id,user_id=user_id,sandbox_types=["base"],)base_sandbox = sandboxes[0]result = base_sandbox.run_ipython_cell("print('Hello, World!')")base_sandbox.run_ipython_cell("a=1")# 可以使用相同的 session_id 和 user_id 会复用同一个沙箱实例new_sandboxes = sandbox_service.connect(session_id=session_id,user_id=user_id,sandbox_types=["base"],)...

在EKS上部署agent应用

  • https://runtime.agentscope.io/v1.0.5/zh/agent_app.html

LocalDeployManager部署

AgentScope Runtime提供多种不同的部署方式,LocalDeployManager部署模式示例如下,适合开发、测试和需要手动控制的持久服务的单用户场景。

import osfrom agentscope.agent import ReActAgent
from agentscope.model import OpenAIChatModel
from agentscope.formatter import OpenAIChatFormatter
from agentscope.tool import Toolkit, execute_python_code
from agentscope.pipeline import stream_printing_messages
from agentscope.memory import InMemoryMemoryfrom agentscope_runtime.engine import AgentApp
from agentscope_runtime.engine.schemas.agent_schemas import AgentRequest
from agentscope_runtime.engine.services.agent_state import (InMemoryStateService,
)
from agentscope_runtime.engine.deployers.local_deployer import LocalDeployManageragent_app = AgentApp(app_name="Friday",app_description="A helpful assistant",
)@agent_app.init
async def init_func(self):self.state_service = InMemoryStateService()  # 创建内存状态服务实例await self.state_service.start()  # 启动状态服务@agent_app.shutdown
async def shutdown_func(self):await self.state_service.stop()  # 停止并清理状态服务@agent_app.query(framework="agentscope")
async def query_func(self,msgs,request: AgentRequest = None,**kwargs,
):session_id = request.session_id  # 获取会话IDuser_id = request.user_id  # 获取用户ID# 尝试从状态服务加载之前的状态state = await self.state_service.export_state(session_id=session_id,user_id=user_id,)# 创建工具包并注册Python代码执行功能toolkit = Toolkit()toolkit.register_tool_function(execute_python_code)# 创建ReAct智能体实例agent = ReActAgent(name="Friday",model=OpenAIChatModel(model_name="qwen3-vl",api_key="sk-uzpq0u0n5FN14HorW45hUw",client_kwargs={"base_url": "http://localhost:4000"},stream=True,  # 启用流式响应),sys_prompt="You're a helpful assistant named Friday.",  # 系统提示词toolkit=toolkit,  # 绑定工具包memory=InMemoryMemory(),  # 使用内存存储记忆formatter=OpenAIChatFormatter(),  # 设置消息格式化器)agent.set_console_output_enabled(enabled=False)  # 禁用控制台输出# 如果存在之前的状态,则恢复智能体状态if state:agent.load_state_dict(state)# 执行智能体并流式返回消息async for msg, last in stream_printing_messages(agents=[agent],  # 指定要使用的智能体coroutine_task=agent(msgs),  # 执行智能体任务):yield msg, last  # 逐个返回消息# 获取智能体当前状态以供后续使用state = agent.state_dict()# 保存会话状态到状态服务await self.state_service.save_state(user_id=user_id,session_id=session_id,state=state,)async def main():# 部署agent_app到本地服务器,监听所有IP地址的8091端口deploy_manager = LocalDeployManager(host="0.0.0.0", port=8091)# 使用 standalone 模式,阻塞运行直到手动停止# 1. daemon_thread - 守护线程模式(默认)# 2. detached_process - 独立进程模式# 3. standalone - 独立模式await agent_app.deploy(deploy_manager, mode='standalone')if __name__ == "__main__":import asyncioasyncio.run(main())

之后使用openai客户端测试访问

from openai import OpenAI
client = OpenAI(base_url="http://127.0.0.1:8654/compatible-mode/v1",api_key="sk-placeholder"
)
response = client.responses.create(model="any_name",input="杭州天气如何?"
)
print(response)

KubernetesDeployManager部署

将local中的部署代码替换即可,agent app不变,示例如下

import asyncio
import os
from agentscope_runtime.engine.deployers.kubernetes_deployer import (KubernetesDeployManager,RegistryConfig,K8sConfig,
)# 使用agent_app
...async def deploy_to_k8s():# 配置镜像仓库和 K8s 连接deployer = KubernetesDeployManager(kube_config=K8sConfig(k8s_namespace="agentscope-runtime",kubeconfig_path=None,),registry_config=RegistryConfig(registry_url="000000000.dkr.ecr.cn-north-1.amazonaws.com.cn",namespace="agentscope-runtime",),use_deployment=True,)# 执行部署result = await agent_app.deploy(deployer,port="8080",replicas=1,image_name="agent_app",image_tag="v1.0",requirements=["agentscope", "fastapi", "uvicorn"],base_image="python:3.10-slim-bookworm",environment={"PYTHONPATH": "/app",},runtime_config={"resources": {"requests": {"cpu": "200m", "memory": "512Mi"},"limits": {"cpu": "1000m", "memory": "2Gi"},},},platform="linux/amd64",push_to_registry=True,)print(f"✅ 部署成功:{result['url']}")return result, deployerif __name__ == "__main__":asyncio.run(deploy_to_k8s())

实际上会使用本地docker打包镜像,并推送到指定的镜像仓库中(000000000000.dkr.ecr.cn-north-1.amazonaws.com.cn/agentscope-runtime/agent_app:v1.0),然后在eks中创建pod

image-20260121000728215

结果如下,调用正常

image-20260121001459096

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1191321.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何测试AI生成的邮件是否符合商务礼仪:软件测试从业者指南

AI邮件测试的必要性与挑战在AI工具(如豆包AI、文心一言)广泛应用于商务邮件生成的背景下,测试从业者面临新挑战:确保AI输出邮件符合专业礼仪,避免因文化误解、语气不当或格式错误导致沟通失误。 据统计,近4…

IDEA_pom.xml_spring-boot-maven-plugin爆红问题解决

文章目录IDEA中spring-boot-maven-plugin报红问题及解决方案项目场景问题描述原因分析解决方案1. 添加版本号2. 刷新 Maven 项目3. IDEA 重启(必要时)经验总结总结IDEA中spring-boot-maven-plugin报红问题及解决方案 在使用 IntelliJ IDEA 进行 Spring …

跨境电商防关联:从“单点隔离”到“系统化风控”一套打穿

很多卖家做防关联只停留在“换IP换浏览器”,结果仍然二审频繁、限流或资金风控。原因是平台判定关联不是只看某一个点,而是把设备指纹、网络链路、业务资料、资金履约、内容与行为拼成整体画像。要想稳定跑矩阵,必须把防关联做成“系统工程”…

全国现代物业管理人才培养赋能新质生产力发展研讨会 (MPMTT 2026)

全国现代物业管理人才培养赋能新质生产力发展研讨会(MPMTT 2025)将于2026年3月13日-15日在中国昆明隆重举行。MPMTT 2025 由昆明理工大学津桥学院主办,将针对物业管理的相关研究领域展开探讨,旨在为相关领域的专家学者&#xff0c…

玩转Synbo|为什么说质押是进入Club的关键动作

各位社区成员大家好,在进入Synbo体系过程中,质押是获取Club门票与绑定身份的关键动作。当你的质押数量达到某个Club设置的阈值,你就会获得这个Club的成员身份,并解锁:融资可见性、参与权限、激励分配关系,本…

Galaxy比数平台功能介绍及实现原理|得物技术

一、背景 得物经过10年发展,计算任务已超10万,数据已经超200PB,为了降低成本,计算引擎和存储资源需要从云平台迁移到得物自建平台,计算引擎从云平台Spark迁移到自建Apache Spark集群、存储从ODPS迁移到OSS。 在迁移时…

上位机软件开发中串口超时机制的设计实践

串口通信“卡死”怎么办?上位机超时机制的实战设计之道你有没有遇到过这样的场景:上位机软件点击“读取参数”,界面瞬间“假死”,鼠标动不了,任务管理器都救不回来?等了整整30秒,才弹出一个“设…

Eclipse 打开报 `An error has occurred. See the log null` 错误及解决方法

Eclipse 打开报 An error has occurred. See the log null 错误及解决方法 项目场景: 在日常 Java 开发中,Eclipse 是最常用的开发工具之一。我们在 Windows 系统中使用 Eclipse 时,有时会遇到突然无法打开 Eclipse 的情况,报错信…

第七篇:告别手动拼 URL!我们封装自己的“地图超市”

View Post第七篇:告别手动拼 URL!我们封装自己的“地图超市”本专栏旨在手把手带你从零开始,基于开源三维地球引擎 **Cesium** 封装一套功能完善、可复用的 **WebGIS 增强型 SDK**。内容涵盖核心封装思路、关键代码…

基于微信小程序的小区租车拼车系统【源码+文档+调试】

🔥🔥作者: 米罗老师 🔥🔥个人简介:混迹java圈十余年,精通Java、小程序、数据库等。 🔥🔥各类成品Java毕设 。javaweb,ssm,springboot等项目&#…

数字频率计设计超详细版:基本结构与工作流程讲解

以下是对您提供的博文《数字频率计设计超详细版:基本结构与工作流程讲解》的深度润色与专业重构版本。本次优化严格遵循您的全部要求:✅ 彻底去除AI痕迹,语言自然、有“人味”,像一位资深嵌入式工程师在技术博客中娓娓道来&#x…

35岁转行学了网络安全,能谋生吗?

35岁转行学了网络安全,能谋生吗? 35岁转型搞安全是否还有戏? 放眼现在安全圈 00后的黑客CEO已经出场了 18岁的少年也开始穿梭于微软、谷歌、苹果各大国际公司的安全致谢榜 年轻的黑客们早已登上国际舞台,开始在世界顶级黑客大…

VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查

VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查VitePress 进阶指南:自动化侧边栏配置与 TOC 渲染深度排查 在使用 VitePress 搭建文档系统时,随着文件数量的增加,手动维护 .vitepress/config.ts 中的 si…

ERROR. pos 145, line 2, column 21, token COMMA 报错已解决

ERROR. pos 145, line 2, column 21, token COMMA 报错已解决 在软件开发过程中,尤其是 Java、C 以及基于模板的配置文件中,偶尔会遇到编译器或 IDE 报出的类似如下错误: ERROR. pos 145, line 2, column 21, token COMMA虽然错误提示看起来枯…

前端指纹技术是如何实现的?(Canvas、Audio、硬件API 核心原理解密)

什么是设备指纹?在讲实现之前,先纠正一个误区:设备指纹(Device Fingerprint)不是为了知道你是张三,而是为了知道 这台设备是编号 9527。它的核心逻辑只有一条:利用浏览器暴露的硬件底层差异&…

vivado安装资源推荐:新手自学的最佳路径

Vivado 安装指南:从零开始搭建 FPGA 开发环境 你是不是也曾在搜索“vivado安装”时,被一堆杂乱的教程、失效的链接和复杂的系统要求搞得头大? 明明只是想学点 FPGA 基础逻辑设计,结果第一步—— 装软件 ,就卡了三天…

LLM动态调参医疗设备故障预警提前30%

📝 博客主页:Jax的CSDN主页 LLM动态调参:医疗设备故障预警提前30%的范式突破 目录 LLM动态调参:医疗设备故障预警提前30%的范式突破 1. 引言:医疗设备故障的隐性危机 2. 现有预警系统的瓶颈与LLM的破局点 3. LLM动态调…

uni-app使用北斗卫星实现离线定位

权限配置仍然采用 HTML5 的定位方法,首先需要打开定位权限:// manifest.json/* 模块配置 */ "modules" : {"Geolocation" : {}, // 启用定位模块}, /* 应用发布信息 */ "distribute" : {/* android打包配置 */"andr…

React 官方纪录片观后:核心原理解析与来龙去脉

你真的理解 React 的运作方式吗?这段时间在回顾自己过去几年的 React 项目时,我发现一个有点尴尬但很真实的情况: 我能熟练写Hooks、拆组件、做性能优化,但如果有人让我用几分钟解释清楚——React 内部到底是怎么运作的&#xff0…

Java中构建前端可视化维度指标列表:从代码实现到最佳实践

在后端对接前端可视化需求(比如雷达图、多维度评分展示)时,经常需要把数据库中分散的字段,转换成前端友好的结构化数据格式。今天记录一段典型的“维度指标列表构建代码”,从实现逻辑到优化思路一次性讲透。 一、需求背…