本文作者:阿里云无影技术专家 王磊
在 AI Agent 浪潮中,Python 和 TypeScript 凭借其敏捷性,在原型构建和快速迭代上确实走在了前列。然而,在许多企业(包括阿里内部),Java 的稳定性和成熟生态是支撑复杂业务逻辑的基石,许多核心“大脑”(业务系统)是构建在 Java 技术栈之上的。这就带来了一个现实的挑战:当这些 Java“大脑”需要 Agent“手脚”的执行力时,如何安全、高效地将两者连接起来?尤其是今年年初以 Manus 为代表的 Agent 展示了惊人的自主能力(如操作本地文件、执行代码),这在带来兴奋的同时,也让“信任”问题成为了核心焦点。
因此,“沙箱”(Sandbox)——这个用于隔离不可信代码的执行环境——成为了 Agent 领域一个日益重要的安全选项。但现实是,许多“执行层”服务(如云端沙箱)优先拥抱了脚本语言,这使得庞大的 Java 生态在接入时缺少了“开箱即用”的桥梁。基于这个背景, 无影 AgentBay 近期适配了 Java 版SDK。现在,你可以用熟悉的方式,将 Agent 的“手脚”(即安全的代码执行能力)无缝集成到现有的 Java 应用或智能体服务中。
🎉 好消息:AgentBay SDK 已在 GitHub 开源(欢迎 Star✨)!目前已全面支持 Python、TypeScript、Go 和 Java 四大主流语言。
一、 Agent “本地执行”的现实挑战
在 Java 应用中构建 Agent,最直接的方案就是在 Java 服务器本地执行 Agent 任务(比如 ProcessBuilder 调用 Python 脚本)。
在本地调试时这确实很方便,但在生产环境中,这种“方便”可能会带来一系列的现实挑战:
- 安全风险:核心问题是信任。我们真的能信任 LLM 动态生成的代码吗?即使 Prompt 做了严格限制,也难以完全避免潜在的风险,例如“运行时供应链攻击”——Agent 在运行时被诱导执行
pip install a-malicious-package,而这个包从未出现在你的 CI 扫描中。 - 并发与资源瓶颈:这是 Java 后端最关心的问题。企业级应用需要并发处理。如果 100 个用户同时请求 Agent 服务,你的 Java 服务器是否要并行启动 100 个 Python 进程或浏览器实例?这不仅会迅速耗尽宿主机的 CPU 和内存 ,更会与你的核心 Java 业务争抢资源。
- 环境一致性:开发环境能跑,生产环境翻车;“我的机器没问题,同事的机器就是报错” —— Agent 对环境的依赖(如 Python 版本、Chrome 版本、系统库)只会加剧这个经典难题。
二、 云端沙箱:一种“解耦”的思路
如果我们将 Agent 的“执行环境”从 Java 宿主机剥离,转移到云端沙箱 会怎样?
这带来了一种可能:Java 后端(编排层)只负责“思考”和“编排”,而 AgentBay(执行层)负责“执行”和“隔离” 。这有两大好处:
- 首先是安全:所有不可信代码都在云端隔离的沙箱中执行,执行完毕即销毁 。
- 其次是并发:这可能是最大的优势。Java 服务器不再承担执行负载。它只需要通过 SDK 发送任务。AgentBay 作为一个云服务,可以按需、高并发地调度成百上千的 Linux、Windows、Android 和浏览器环境 ,各自独立运行,互不干扰,完全不影响 Java 宿主机的性能和稳定。
AgentBay 提供了专为 Agent 设计的云端运行时 ,包含了四大场景化沙箱:
- 浏览器沙箱:基于 Playwright 的 Web 自动化 。
- 代码空间:Python、JavaScript 等多语言代码执行环境 。
- 云电脑:完整的 Linux/Windows 桌面环境。
- 云手机:Android 设备模拟。
三、无影 AgentBay Java SDK 快速上手
3.1 准备工作
首先,你需要一个 AgentBay API Key:
- 访问 AgentBay 控制台
- 登录你的阿里云账号
- 在服务管理部分创建或选择一个 API KEY
- 在终端中设置环境变量:
export AGENTBAY_API_KEY=your_api_key_here
3.2 Maven 依赖配置 (LangChain4j 示例)
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <langchain4j.version>0.36.2</langchain4j.version> </properties> <dependencies> <dependency> <groupId>com.aliyun</groupId> <artifactId>agentbay-sdk</artifactId> <version>0.14.1</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j</artifactId> <version>${langchain4j.version}</version> </dependency> <dependency> <groupId>dev.langchain4j</groupId> <artifactId>langchain4j-open-ai</artifactId> <version>${langchain4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>2.0.9</version> </dependency> </dependencies>
3.3 第一个 Agent:在云端执行命令
我们从最简单的场景开始 —— 让 Agent 在云端执行一条命令:
import com.aliyun.agentbay.AgentBay; import com.aliyun.agentbay.model.SessionResult; import com.aliyun.agentbay.session.CreateSessionParams; import com.aliyun.agentbay.session.Session; import com.aliyun.agentbay.model.CommandResult; public class HelloAgentBay { public static void main(String args) { String apiKey = System.getenv("AGENTBAY_API_KEY"); AgentBay agentBay = new AgentBay(apiKey); Session session = null; try { // 1. 创建一个云端会话(启动一个隔离沙箱) System.out.println("正在创建云端环境..."); CreateSessionParams params = new CreateSessionParams(); SessionResult result = agentBay.create(params); // session = result.getSession(); System.out.println("✅ 环境就绪! Session ID: " + session.getSessionId()); // 2. 在云端执行命令 CommandResult cmdResult = session.getCommand() .executeCommand("echo 'Hello from Cloud!' && date && uname -a"); System.out.println("命令输出:"); System.out.println(cmdResult.getOutput()); } catch (Exception e) { System.err.println("出错了: " + e.getMessage()); e.printStackTrace(); } finally { // 3. 务必清理环境 if (session!= null) { try { agentBay.delete(session, false); // System.out.println("✅ 环境已清理"); } catch (Exception e) { e.printStackTrace(); } } } } }
四、实战(一):将 AgentBay 接入 Spring AI (FunctionCallback 模式)
在pom.xml中添加Spring AI的相关依赖:
<project> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>${spring.ai.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-openai</artifactId> </dependency> </dependencies> </project>
4.1 步骤一:创建“执行层” —— Function Bean
package com.example.agentdemo.service; import com.aliyun.agentbay.AgentBay; import com.aliyun.agentbay.model.CodeExecutionResult; import com.aliyun.agentbay.model.SessionResult; import com.aliyun.agentbay.session.CreateSessionParams; import com.aliyun.agentbay.session.Session; import com.fasterxml.jackson.annotation.JsonClassDescription; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import org.springframework.stereotype.Service; import java.util.function.Function; @Service("agentBayToolService") // 显式命名 Bean public class AgentBayToolService implements Function<AgentBayToolService.Request, AgentBayToolService.Response> { private final AgentBay agentBay; public AgentBayToolService(AgentBay agentBay) { this.agentBay = agentBay; } @JsonClassDescription("在安全的云端沙箱中执行 Python 3 代码") public record Request( @JsonProperty(required = true, value = "code") @JsonPropertyDescription("要执行的 Python 3 代码字符串") String code ) {} public record Response(String result, boolean success) {} @Override public Response apply(Request request) { String code = request.code(); System.out.println(">>> AgentBay (Function): 收到代码执行任务...\n" + code); Session session = null; try { CreateSessionParams params = new CreateSessionParams(); params.setImageId("code_latest"); SessionResult result = agentBay.create(params); session = result.getSession(); System.out.println(">>> AgentBay: 沙箱环境已创建. Session ID: " + session.getSessionId()); CodeExecutionResult execResult = session.getCode().runCode(code, "python"); if (execResult.isSuccess()) { System.out.println(">>> AgentBay: 执行成功."); return new Response(execResult.getResult(), true); } else { System.err.println(">>> AgentBay: 执行失败: " + execResult.getErrorMessage()); return new Response(execResult.getErrorMessage(), false); } } catch (Exception e) { e.printStackTrace(); return new Response("SDK调用异常: " + e.getMessage(), false); } finally { if (session!= null) { try { agentBay.delete(session, false); System.out.println(">>> AgentBay: 环境已清理."); } catch (Exception e) { e.printStackTrace(); } } } } }
4.2 步骤二:配置“编排层” —— FunctionCallbackWrapper
package com.example.agentdemo.config; import com.aliyun.agentbay.AgentBay; import com.aliyun.agentbay.exception.AgentBayException; import com.example.agentdemo.service.AgentBayToolService; import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.model.function.FunctionCallback; import org.springframework.ai.model.function.FunctionCallbackWrapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AiConfig { @Bean public AgentBay agentBay() { String apiKey = System.getenv("AGENTBAY_API_KEY"); if (apiKey == null || apiKey.isEmpty()) { throw new IllegalStateException("环境变量 AGENTBAY_API_KEY 未设置"); } try { return new AgentBay(apiKey); } catch (AgentBayException e) { throw new IllegalStateException("初始化 AgentBay 失败", e); } } @Bean public FunctionCallback agentBayFunctionCallback(AgentBayToolService agentBayToolService) { // [6, 8] // 使用 FunctionCallbackWrapper 将我们的 Function Bean 包装成一个 LLM 可调用的工具 return FunctionCallbackWrapper.builder(agentBayToolService) .withName("executePythonCode") // LLM 将调用这个名字 .withDescription("在安全的云端沙箱中执行 Python 3 代码") .build(); } @Bean public ChatClient chatClient(ChatModel chatModel, FunctionCallback agentBayFunctionCallback) { return ChatClient.builder(chatModel) // 显式地将函数注册到 ChatClient .defaultFunctions(agentBayFunctionCallback) .build(); } }
4.3 步骤三:调用 Agent
package com.example.agentdemo.service; import org.springframework.ai.chat.client.ChatClient; import org.springframework.stereotype.Service; @Service public class DataAnalysisService { private final ChatClient chatClient; public DataAnalysisService(ChatClient chatClient) { this.chatClient = chatClient; } public String runAnalysis(String prompt) { System.out.println(">>> 用户: " + prompt); // chatClient 会自动处理函数调用的完整流程 String response = chatClient.prompt() .user(prompt) .call() .content(); System.out.println(">>> 助手: " + response); return response; } }
完整项目地址:https://github.com/aliyun/wuying-agentbay-sdk/tree/release/java_sdk/java/demos/spring-ai
五、实战(二):LangChain4j 的实现范式
对于不使用 Spring 的 Java 开发者,LangChain4j 提供了另一套强大的AiService 模式 。这个例子展示了如何向 Agent 提供多个工具(Python, Shell, JavaScript),LangChain4j 会根据用户的提问自动选择最合适的工具。
5.1 步骤一:定义“工具集” —— AgentBayTools.java
package com.example.agent; import com.aliyun.agentbay.AgentBay; import com.aliyun.agentbay.model.CodeExecutionResult; import com.aliyun.agentbay.model.CommandResult; import com.aliyun.agentbay.session.Session; import dev.langchain4j.agent.tool.Tool; public class AgentBayTools { private final AgentBay agentBay; public AgentBayTools(String apiKey) { //... 构造函数... } @Tool("在安全的云端沙箱中执行 Python 3 代码。") public String executePythonCode(String code) { System.out.println(">>> AgentBay (LangChain4j): 收到代码执行任务..."); Session session = null; try { //... (与 Spring 示例中的 apply 方法体相同) //... session create, runCode, delete... return "执行成功,输出:\n..."; } catch (Exception e) { return "SDK调用异常: " + e.getMessage(); } finally { //... (严谨的 session delete) } } @Tool("在云端 Linux 环境中执行 Shell 命令。") public String executeShellCommand(String command) { //... (同上) } @Tool("在云端环境中执行 JavaScript (Node.js) 代码。") public String executeJavaScriptCode(String code) { //... (同上, 但使用 "javascript") } }
5.2 步骤二:定义“编排层” —— DataAnalysisAgent.java
我们使用 AiService 接口来定义 Agent 的角色和能力。
package com.example.agent; import dev.langchain4j.service.SystemMessage; import dev.langchain4j.service.UserMessage; public interface DataAnalysisAgent { @SystemMessage(""" 你是一个专业的数据分析助手。 你可以使用以下工具: - executePythonCode: 执行 Python 代码 - executeShellCommand: 执行 Shell 命令 - executeJavaScriptCode: 执行 JavaScript 代码 请根据用户的需求选择合适的工具来完成任务。 """) String analyze(@UserMessage String query); }
5.3 步骤三:组装并运行 Agent —— AgentBayDemo.java
package com.example.agent; import dev.langchain4j.model.chat.ChatLanguageModel; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.service.AiServices; public class AgentBayDemo { public static void main(String[] args) { String agentbayApiKey = System.getenv("AGENTBAY_API_KEY"); String openaiApiKey = System.getenv("OPENAI_API_KEY"); //... (省略了对 API Key 的空值检查) ChatLanguageModel chatModel = OpenAiChatModel.builder() .apiKey(openaiApiKey).modelName("gpt-4").build(); AgentBayTools tools = new AgentBayTools(agentbayApiKey); DataAnalysisAgent agent = AiServices.builder(DataAnalysisAgent.class) .chatLanguageModel(chatModel) .tools(tools) // 注入工具 .build(); // --- 示例 1: 触发 Python 工具 --- String query1 = "帮我用 Python 计算 1000 以内所有质数的和"; agent.analyze(query1); // --- 示例 2: 触发 Shell 工具 --- String query2 = "在云端环境中,创建一个文本文件 info.txt,写入当前日期"; agent.analyze(query2); } }
完整项目地址:https://github.com/aliyun/wuying-agentbay-sdk/tree/release/java_sdk/java/demos/langchain-4j
说明:如果需要使用ChatModel需要配置Open AI的API Key。
六、超越“执行”:Agent 的“记忆”与“协作”
一个 Agent 的价值不止在于“执行”,还在于“记忆” 。LLM 本身是无状态的,但 AgentBay 的 Context 机制提供了一种“物理记忆”——一个可持久化的云端文件系统 。
场景一: Context 的基本使用
// (伪代码,展示 Context 用法) public void reviewCodeWithPersistence(String workspaceId) throws Exception { // 1. 获取或创建一个持久化的 Context ContextResult contextResult = agentBay.getContext().get(workspaceId, true, "cn-hangzhou"); Context workspaceContext = contextResult.getContext(); // 2. 创建会话时绑定 Context,实现数据持久化 CreateSessionParams params = new CreateSessionParams(); ContextSync sync = ContextSync.create( workspaceContext.getId(), "/workspace", // 云端工作目录 SyncPolicy.defaultPolicy() ); params.setContextSyncs(Arrays.asList(sync)); Session session = agentBay.create(params).getSession(); try { // 3. Agent 在 /workspace 目录下读写文件 boolean hasHistory = session.getFileSystem().exists("/workspace/review_log.txt"); session.getCommand().executeCommand( "echo '...新审查结果...' >> /workspace/review_log.txt" ); } finally { // 4. 删除会话时,syncContext=true 会把 /workspace 的所有变更 // 同步回持久化的 Context 中,下次可继续使用。 agentBay.delete(session, true); // System.out.println("会话已结束,数据已持久化"); } }
场景二:多 Agent 协作 (Multi-Agent Collaboration)
Context 机制也为多 Agent 协作提供了“共享工作区” 。
- Planner Agent 启动,挂载
Context: "project-xyz"。它执行echo 'Task 1:...' > plan.md,同步并终止。 - Coder Agent 启动,挂载同一个
Context: "project-xyz"。它读取plan.md,编写代码app.py,同步并终止。 - Tester Agent 启动,挂载同一个
Context: "project-xyz"。它读取app.py,执行并写入test_results.log。
通过上述实践,我们可以清晰地看到:Java 并非 AI Agent 时代的“旁观者”,而是凭借其深厚的工程底蕴与成熟的生态体系,正稳步转型为智能体架构中值得信赖的“指挥中枢”。无影 AgentBay 的 Java SDK 不仅弥合了 Java 生态在安全执行能力上的缺口,更通过云端沙箱、持久化 Context 以及多语言工具集成,让 Java 应用也能安全、高效地调用 Agent 的“手脚”——以企业级所需的可靠性、可扩展性和高并发能力,无缝融入 AI 原生的新范式。
相关链接
- 无影 AgentBay 官网
- 无影 AgentBay SDK Github- 欢迎 Star 支持!
系列文章
- 打通Agent最后一公里: 用阿里云无影AgentBay+LangChain实现浏览器自动化
- 3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
- 手把手带你使用无影 AgentBay + AgentScope 完成一站式智能体开发部署