From 4f11190a255e4e6baa2415d3d53ceb098c35da99 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 11 Dec 2025 10:14:16 +0800 Subject: [PATCH 1/5] add README-zh.md and CONTRIBUTING.md Change-Id: I90d3723873560a53654aafec410fcdc5521fb0dd --- CONTRIBUTING.md | 103 +++++++++++++++++++++++++++ README-zh.md | 185 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 CONTRIBUTING.md create mode 100644 README-zh.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..6b97ee56 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,103 @@ +# How to Contribute + +Thanks for your interest in the AgentScope Runtime Java project. + +AgentScope Runtime is an open-source project focused on agent deployment and secure tool execution with a friendly community of developers eager to help new contributors. We welcome contributions of all types, from code improvements to documentation. + +## Community + +A good first step to getting involved in the AgentScope Runtime Java project is to participate in our discussions and join us in our different communication channels. Here are several ways to connect with us: + +- **GitHub Discussions**: Ask questions and share experiences (use **English**) +- **Discord**: Join our [Discord channel](https://discord.gg/eYMpfnkG8h) for real-time discussions +- **DingTalk**: Chinese users can join our [DingTalk Group](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) + + +## Reporting Issues + +### Bugs + +If you find a bug in AgentScope Runtime Java, first test against the latest version to ensure your issue hasn't already been fixed. If not, search our issues list on GitHub to see if a similar issue has already been opened. + +If you confirm that the bug hasn't already been reported, file a bug issue before writing any code. When submitting an issue, please include: + +- Clear problem description +- Steps to reproduce +- Code/error messages +- Environment details (OS, Python version) +- Affected components (Engine, Sandbox, or both) + +### Security Issues + +If you discover a security issue in AgentScope Runtime, please report it to us through the [Alibaba Security Response Center (ASRC)](https://security.alibaba.com/). + +## Requesting Features + +If you find yourself wishing for a feature that doesn't exist in AgentScope Runtime, please open a feature request issue on GitHub to describe: + +- The feature and its purpose +- How it should work +- Security considerations (if applicable) + +## Contributing Code + +If you would like to contribute a new feature or a bug fix to AgentScope Runtime Java, please first discuss your idea on a GitHub issue. If there isn't an issue for it, create one. There may be someone already working on it, or it may have particular complexities (especially security considerations for sandbox features) that you should be aware of before starting to code. + +### Fork and Create a Branch + +Fork the main AgentScope Runtime Java code and clone it to your local machine. See the GitHub help page for help. + +```shell +git clone https://github.com/agentscope-ai/agentscope-runtime-java.git +``` + +Create a branch with a descriptive name. + +```bash +git checkout -b feature/your-feature-name +``` + +### Make Your Changes + +- Write clear, well-commented code +- Follow existing code style +- Add tests for new features/fixes +- Update documentation as needed + +### Test Your Changes + +Run the test suite to ensure your changes don't break existing functionality: + +```bash +mvn clean test +``` + +### Submit Your Changes + +0. Format code before submitting: + +```shell +mvn spotless:apply +``` + +1. Commit your changes with a clear message: + +```bash +git commit -m "Add: brief description of your changes" +``` + +2. Push to your fork: + +```bash +git push origin feature/your-feature-name +``` + +3. Create a Pull Request (PR) from your branch to the main repository with a **clear description** + +### Code Review Process + +- All PRs require review from maintainers +- Address any feedback or requested changes +- Once approved, your PR will be merged + +Thank you for contributing to AgentScope Runtime! \ No newline at end of file diff --git a/README-zh.md b/README-zh.md new file mode 100644 index 00000000..11fc9065 --- /dev/null +++ b/README-zh.md @@ -0,0 +1,185 @@ +
+ +# AgentScope Runtime for Java + +[![License](https://img.shields.io/badge/license-Apache%202.0-red.svg?logo=apache&label=License)](LICENSE) +[![GitHub Stars](https://img.shields.io/github/stars/agentscope-ai/agentscope-runtime-java?style=flat&logo=github&color=yellow&label=Stars)](https://github.com/agentscope-ai/agentscope-runtime-java/stargazers) +[![GitHub Forks](https://img.shields.io/github/forks/agentscope-ai/agentscope-runtime-java?style=flat&logo=github&color=purple&label=Forks)](https://github.com/agentscope-ai/agentscope-runtime-java/network) +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime) +[![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) + +[Cookbook](./cookbook/zh) + +**AgentScope Runtime Java** + +这是 [AgentScope Runtime](https://github.com/agentscope-ai/agentscope-runtime/) 的 Java 实现。 + + +
+ +--- + +## ✨ 核心特性 + +- **部署基础设施**:内置会话管理、内存和沙箱环境控制服务 +- **沙箱化工具执行**:隔离的沙箱确保工具执行安全,不会危及系统 +- **开发者友好**:简单部署,强大的自定义选项 +- **框架无关**:不绑定任何特定框架。可与流行的开源 Agent 框架和自定义实现无缝协作 +- 🚧 **可观测性**:全面追踪和可视化 Agent 操作 + +--- + +## 💬 社区 + +加入我们的钉钉社区: + +| DingTalk | +| ------------------------------------------------------------ | +| | + +--- + +## 📋 目录 + +- [快速开始](#-快速开始) +- [Agent 框架集成](#-agent-框架集成) +- [部署](#️-部署) +- [贡献](#-贡献) +- [许可证](#-许可证) + +--- + +## 🚀 快速开始 + +### 前置要求 + +- Java 17 或更高版本 +- Maven 3.6+ + +### 添加依赖 + +在您的 `pom.xml` 中添加以下依赖: + +```xml + + io.agentscope + spring-boot-starter-runtime-a2a + 1.0.0-BETA1 + + + + + io.agentscope + agentscope-runtime-agentscope + 1.0.0-BETA1 + +``` + +### 基础 Agent 使用示例 + +以下示例演示如何使用 AgentScope Runtime 委托一个 AgentScope ReactAgent。完整源代码可在 [examples](./examples) 目录中找到。 + +1. 创建 Agent Handler + +通过扩展 `AgentScopeAgentHandler` 创建自定义 agent handler: + +```java +public class MyAgentScopeAgentHandler extends AgentScopeAgentHandler { + + @Override + public Flux streamQuery(AgentRequest request, Object messages) { + // Create Toolkit and register tools + Toolkit toolkit = new Toolkit(); + if (sandboxService != null) { + Sandbox sandbox = sandboxService.connect( + request.getUserId(), + request.getSessionId(), + BaseSandbox.class + ); + toolkit.registerTool(ToolkitInit.RunPythonCodeTool(sandbox)); + } + + // Create ReActAgent with tools + ReActAgent agent = ReActAgent.builder() + .name("Friday") + .toolkit(toolkit) + .model(DashScopeChatModel.builder() + .apiKey(System.getenv("AI_DASHSCOPE_API_KEY")) + .modelName("qwen-max") + .stream(true) + .formatter(new DashScopeChatFormatter()) + .build()) + .build(); + + // Convert messages and stream agent responses + // See examples/README.md for complete implementation + return agent.stream(queryMessage, streamOptions); + } +} +``` + +2. 初始化服务并部署 + +使用所需服务配置 agent handler,并使用 `AgentApp` 进行部署: + +```java +// Create and configure the agent handler +MyAgentScopeAgentHandler agentHandler = new MyAgentScopeAgentHandler(); +agentHandler.setStateService(new InMemoryStateService()); +agentHandler.setSessionHistoryService(new InMemorySessionHistoryService()); +agentHandler.setMemoryService(new InMemoryMemoryService()); +agentHandler.setSandboxService(new SandboxService( + new SandboxManager(ManagerConfig.builder().build()) +)); + +// Deploy using AgentApp +AgentApp agentApp = new AgentApp(agentHandler); +agentApp.run(8090); // Server will listen on port 8090 +``` + +> [!NOTE] +> 您也可以使用 **Kubernetes** 或阿里云 FC 平台的 **AgentRun** 来执行沙箱工具。更多详情请参考 [examples](./examples) 目录。 +--- + +## 🔌 Agent 框架集成 + +AgentScope Runtime Java 实现可以轻松集成任何用 Java 开发的 Agent 框架。目前支持的框架包括: + +- **AgentScope Java** +- **Spring AI Alibaba, Langchain4j 以及更多即将推出...** + +--- + +## 🤝 贡献 + +我们欢迎社区贡献!以下是如何提供帮助: + +### 🐛 错误报告 + +- 使用 [GitHub Issues](https://github.com/agentscope-ai/agentscope-runtime-java/issues) 报告错误 +- 包含详细的复现步骤 +- 提供系统信息和相关日志 + +### 💡 功能请求 + +- 在 [GitHub Discussions](https://github.com/agentscope-ai/agentscope-runtime-java/discussions) 中讨论新想法 +- 遵循功能请求模板 +- 考虑实现可行性 + +### 🔧 代码贡献 + +1. Fork 仓库 +2. 创建功能分支 (`git checkout -b feature/amazing-feature`) +3. 提交更改 (`git commit -m 'Add amazing feature'`) +4. 推送到分支 (`git push origin feature/amazing-feature`) +5. 打开 Pull Request + +详细的贡献指南,请参阅 [CONTRIBUTING.md](CONTRIBUTING.md)。 + +--- + +## 📄 许可证 + +本项目采用 Apache License 2.0 许可证。详情请参阅 [LICENSE](LICENSE) 文件。 + +--- From f02ac0b112e1d05c5936d959a5f1a302f1f8c374 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 11 Dec 2025 11:59:56 +0800 Subject: [PATCH 2/5] update 1.0 doc Change-Id: I6ae977b37f51b48a7952a749dea505cf715e1cb2 --- cookbook/new-zh/CHANGELOG.md | 0 cookbook/new-zh/concept.md | 156 --- cookbook/new-zh/contribute.md | 92 -- cookbook/new-zh/install.md | 139 --- cookbook/new-zh/intro.md | 65 - cookbook/new-zh/quickstart.md | 414 ------- cookbook/zh/CHANGELOG.md | 315 +++++ cookbook/zh/README.md | 45 - cookbook/zh/concept.md | 222 ++-- cookbook/zh/context_manager.md | 940 -------------- cookbook/zh/contribute.md | 25 +- cookbook/zh/demohouse.md | 208 ---- cookbook/{new-zh => zh}/deployment.md | 0 .../deployment/advanced_deployment.md | 0 .../{new-zh => zh}/deployment/agent_app.md | 0 .../{new-zh => zh}/deployment/react_agent.md | 0 cookbook/zh/environment_manager.md | 311 ----- cookbook/zh/install.md | 208 +--- cookbook/zh/intro.md | 47 +- cookbook/zh/manager.md | 289 ----- cookbook/zh/protocol.md | 1099 ----------------- cookbook/zh/quickstart.md | 678 +++++----- cookbook/zh/react_agent.md | 325 ----- cookbook/zh/sandbox.md | 379 ------ cookbook/{new-zh => zh}/sandbox/advanced.md | 0 cookbook/{new-zh => zh}/sandbox/sandbox.md | 0 .../sandbox/training_sandbox.md | 0 .../{new-zh => zh}/sandbox/troubleshooting.md | 0 cookbook/zh/sandbox_advanced.md | 295 ----- cookbook/zh/sandbox_troubleshooting.md | 59 - cookbook/{new-zh => zh}/service/memory.md | 0 cookbook/{new-zh => zh}/service/sandbox.md | 0 cookbook/{new-zh => zh}/service/service.md | 0 .../{new-zh => zh}/service/session_history.md | 0 cookbook/{new-zh => zh}/service/state.md | 0 cookbook/{new-zh => zh}/tool.md | 0 cookbook/zh/training_sandbox.md | 257 ---- 37 files changed, 854 insertions(+), 5714 deletions(-) delete mode 100644 cookbook/new-zh/CHANGELOG.md delete mode 100644 cookbook/new-zh/concept.md delete mode 100644 cookbook/new-zh/contribute.md delete mode 100644 cookbook/new-zh/install.md delete mode 100644 cookbook/new-zh/intro.md delete mode 100644 cookbook/new-zh/quickstart.md create mode 100644 cookbook/zh/CHANGELOG.md delete mode 100644 cookbook/zh/README.md delete mode 100644 cookbook/zh/context_manager.md delete mode 100644 cookbook/zh/demohouse.md rename cookbook/{new-zh => zh}/deployment.md (100%) rename cookbook/{new-zh => zh}/deployment/advanced_deployment.md (100%) rename cookbook/{new-zh => zh}/deployment/agent_app.md (100%) rename cookbook/{new-zh => zh}/deployment/react_agent.md (100%) delete mode 100644 cookbook/zh/environment_manager.md delete mode 100644 cookbook/zh/manager.md delete mode 100644 cookbook/zh/protocol.md delete mode 100644 cookbook/zh/react_agent.md delete mode 100644 cookbook/zh/sandbox.md rename cookbook/{new-zh => zh}/sandbox/advanced.md (100%) rename cookbook/{new-zh => zh}/sandbox/sandbox.md (100%) rename cookbook/{new-zh => zh}/sandbox/training_sandbox.md (100%) rename cookbook/{new-zh => zh}/sandbox/troubleshooting.md (100%) delete mode 100644 cookbook/zh/sandbox_advanced.md delete mode 100644 cookbook/zh/sandbox_troubleshooting.md rename cookbook/{new-zh => zh}/service/memory.md (100%) rename cookbook/{new-zh => zh}/service/sandbox.md (100%) rename cookbook/{new-zh => zh}/service/service.md (100%) rename cookbook/{new-zh => zh}/service/session_history.md (100%) rename cookbook/{new-zh => zh}/service/state.md (100%) rename cookbook/{new-zh => zh}/tool.md (100%) delete mode 100644 cookbook/zh/training_sandbox.md diff --git a/cookbook/new-zh/CHANGELOG.md b/cookbook/new-zh/CHANGELOG.md deleted file mode 100644 index e69de29b..00000000 diff --git a/cookbook/new-zh/concept.md b/cookbook/new-zh/concept.md deleted file mode 100644 index e20258d6..00000000 --- a/cookbook/new-zh/concept.md +++ /dev/null @@ -1,156 +0,0 @@ -# 概念 - -本章介绍了AgentScope Runtime的核心概念。 - -## 架构 - -AgentScope Runtime使用模块化架构,包含几个关键组件: - -```mermaid -flowchart LR - %% 服务模块 - subgraph Service["💼 服务"] - MS["记忆服务"] - SS["会话服务"] - STS["状态服务"] - SBS["沙箱服务"] - end - - %% 沙箱模块 - subgraph Sandbox["🐳 沙箱"] - BS["浏览器沙箱"] - FS["文件系统沙箱"] - GS["GUI 沙箱"] - CSB["云沙箱"] - MSB["移动端沙箱"] - ETC["更多..."] - end - - %% 适配器模块(大块) - subgraph Adapter["🔌 适配器"] - MAD["记忆适配器"] - SAD["会话适配器"] - STAD["状态适配器"] - SBAD["沙箱工具适配器"] - end - - %% Agent 模块(大块) - subgraph Agent["🤖 智能体"] - AG["AgentScope Java"] - AG_NOTE["(更多...)"] - end - - %% 应用层 - subgraph AgentAPP["📦 智能体应用"] - RA["运行器"] - end - - %% 部署模块 - subgraph Deployer["🚀 部署器"] - CT["容器部署"] - KD["K8s 部署"] - DP["云部署"] - LD["本地部署"] - end - - %% 外部协议 - OAI["OpenAI Responses API SDK"]:::ext - A2A["Google A2A 协议"]:::ext - CUS["自定义端点"]:::ext - - MS --> MAD - SS --> SAD - STS --> STAD - SBS --> SBAD - - BS --> SBS - FS --> SBS - GS --> SBS - CSB --> SBS - MSB --> SBS - ETC --> SBS - - %% 大块到大块的连接 - Adapter --> Agent - - AG --> RA - RA --> CT - RA --> KD - RA --> DP - RA --> LD - - %% 整个部署模块连接到外部协议 - Deployer --> OAI - Deployer --> A2A - Deployer --> CUS - - %% 样式 - classDef small fill:#0066FF,stroke:#004CBE,color:#FFFFFF,font-weight:bold - classDef big fill:#99D6FF,stroke:#004CBE,color:#FFFFFF,font-weight:bold - classDef ext fill:#FFFFFF,stroke:#000000,color:#000000,font-weight:bold - - class Tools,Service,Sandbox,Adapter,Agent,AgentAPP,Deployer big - class RT,ST,PT,MS,SS,STS,SBS,BS,FS,GS,CSB,MSB,ETC,TAD,MAD,SAD,STAD,SBAD,AG,AG_NOTE,RA,CT,KD,DP,LD small - -``` - -- **Agent**:处理请求并生成响应的核心AI组件,在Runtime中,Agent的构建推荐使用AgentScope框架。 -- **AgentApp**: 作为智能体应用入口,负责对外提供 API 接口、路由注册、配置加载,并将请求交由 Runner 调用执行 -- **Runner**:在运行时编排智能体执行并管理部署。它处理智能体生命周期、会话管理、流式响应和服务部署。 -- **Deployer**:将Runner部署为服务,提供健康检查、监控、生命周期管理、使用SSE的实时响应流式传输、错误处理、日志记录和优雅关闭。 -- **Tool**: 提供开箱即用的沙箱工具支持。 -- **Service**:提供智能体所需要的管理服务,比如记忆管理,沙箱管理等。 -- **Adapter**:将Runtime提供的组件/模块适配到Agent框架的适配器 - -### 关键组件 - -#### 1. Agent - -`Agent` 是处理请求并生成响应的核心组件。市面上已有大量的开发框架包含了Agent类,Runtime本身不提供额外的Agent类,开发者可以使用AgentScope开发需要的Agent。 - -#### 2. AgentApp - -`AgentApp` 是 AgentScope Runtime 中的 **应用入口点**,用于将 Agent 部署为可对外提供服务的 API 应用。 - -它的职责是: - -- 初始化并绑定 **Agent** 和 **AgentScopeAgentHandler**,自动构建 **Runner**,将请求委托给运行时处理 -- 提供标准化的 **HTTP API 接口**(含健康检查) -- 支持 **Server-Sent Events (SSE)** 以及标准 JSON 响应 -- 允许注册中间件、任务队列(Celery)以及自定义路由 -- 管理应用生命周期(支持 `before_start` / `after_finish` 钩子) -- 将Agent应用部署为服务 - -#### 3. AgentScopeAgentHandler - -`AgentScopeAgentHandler` 类提供灵活且可扩展的智能体执行逻辑。它管理: - -- 通过 `streamQuery` 支持用户自定义请求执行逻辑 -- 流式响应 - -#### 4. Deployer - -`Deployer`(实现为 `deployer-maven-plugin`插件)提供生产级别的部署功能: - -- maven打包过程中自动**构建 Docker 镜像** -- 可选推送至远程仓库、一键部署到 **K8s 集群**以及部署到 **AgentRun** - -#### 5. Sandbox & Tool - -Runtime提供两种工具接入方式 -- 即用型工具,即由服务提供商提供的开箱即用的服务,比如RAG -- 工具沙箱,即运行在runtime里安全可控的工具,比如浏览器 - - -#### 6. Service - -`Service`包含如下几种: - -- `state_service` 状态服务 -- `memory_service` 智能体记忆服务 -- `sandbox_service` 即沙箱服务 -- `session_history_service` 即会话历史记录保存服务 - -#### 7. Adapter - -`Adapter`按照不同Agent框架分类,包含记忆适配器、会话适配器、消息协议适配器等。 diff --git a/cookbook/new-zh/contribute.md b/cookbook/new-zh/contribute.md deleted file mode 100644 index a2cd02e7..00000000 --- a/cookbook/new-zh/contribute.md +++ /dev/null @@ -1,92 +0,0 @@ -# 如何贡献 - -感谢您对AgentScope Runtime Java 项目的关注。 - -AgentScope Runtime Java 是一个专注于智能体部署和安全工具执行的开源项目,拥有一个乐于帮助新贡献者的友好开发者社区。我们欢迎各种类型的贡献,从代码改进到文档编写。 - -## 社区 - -参与 AgentScope Runtime Java 项目的第一步是加入我们的讨论,通过不同的沟通渠道与我们联系。以下是与我们建立联系的几种方式: - -- **GitHub Discussions**: 提问和分享经验(请使用**英语**) -- **Discord**: 加入我们的 [Discord频道](https://discord.gg/eYMpfnkG8h) 进行实时讨论 -- **DingTalk**: 中文用户可以加入我们的 [钉钉群](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) - -## 报告问题 - -### Bugs - -如果您在 AgentScope Runtime Java 中发现了bug,请首先使用最新版本进行测试,确保您的问题尚未被修复。如果没有,请在 GitHub上搜索我们的问题列表,查看是否已有类似问题被提出。 - -- 如果确认该 bug 尚未被报告,请在编写任何代码之前先提交一个 bug 问题。提交问题时,请包含: -- 清晰的问题描述 -- 重现步骤 -- 代码/错误信息 - - 环境详情(操作系统、JDK 版本) - -- 受影响的组件(例如 Engine 模块、Sandbox 模块等) - -### 安全问题 - -如果您在 AgentScope Runtime Java 中发现安全问题,请通过 [阿里巴巴安全响应中心(ASRC)](https://security.alibaba.com/)向我们报告。 - -## 功能需求 - -如果您希望AgentScope Runtime Java 具有某个不存在的功能,请在 GitHub 上提交功能请求问题,描述 - -- 功能及其目的 -- 应该如何工作 -- 安全考虑(如果适用) - -## 贡献代码 - -如果您想为 AgentScope Runtime Java 贡献新功能或bug 修复,请首先在 GitHub 问题中讨论您的想法。如果没有相关问题,请创建一个。可能已经有人在处理它,或者它可能有特殊的复杂性(特别是 Sandbox 功能的安全考虑),您在开始编码之前应该了解这些。 - -### Fork 和创建分支 - -Fork [AgentScope Runtime Java 主分支代码](https://github.com/agentscope-ai/agentscope-runtime-java) 并将其克隆到本地机器。有关帮助,请参见 GitHub 帮助页面。 - -创建一个具有描述性名称的分支。 - -```bash -git checkout -b feature/your-feature-name -``` - -### 进行更改 - -- 编写清晰、注释良好的代码 -- 遵循现有代码风格 -- 为新功能/修复添加测试 -- 根据需要更新文档 Test Your Changes - -### 测试您的更改 - -运行测试套件以确保您的更改不会破坏现有功能: - -```bash -mvn test -``` - -### 提交您的更改 - -1. 使用清晰的消息提交您的更改: - -```bash -git commit -m "Add: brief description of your changes" -``` - -2. 推送到您的Fork: - -```bash -git push origin feature/your-feature-name -``` - -3. 从您的分支向主仓库创建Pull Request (PR),并提供**清晰的描述** - -### 代码审查流程 - -- 所有 PR 都需要维护者的审查 -- 处理任何反馈或请求的更改 -- 一旦批准,您的 PR 将被合并 - -感谢您为 AgentScope Runtime Java 做出贡献! diff --git a/cookbook/new-zh/install.md b/cookbook/new-zh/install.md deleted file mode 100644 index 80f395d6..00000000 --- a/cookbook/new-zh/install.md +++ /dev/null @@ -1,139 +0,0 @@ -# 安装 - -准备好开始使用 AgentScope Runtime Java 了吗?本指南将帮助您在几分钟内快速搭建和运行**AgentScope Runtime Java**。 - -## 前置要求 - -- **Java 17** 或更高版本 -- **Maven 3.6** 或更高版本 -- **Docker**(可选,用于沙箱工具执行) - -## 安装方式 - -### 通过 Maven Central 安装(推荐) - -AgentScope Runtime Java 已经发布到 Maven Central,您可以直接通过 Maven 依赖使用。 - -> 当前稳定版本:1.0.0 -> -> 您可以在 [Maven Central](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) 上查找和下载所有模块。 - -在您的 `pom.xml` 中添加相应的依赖即可使用: - -#### 核心运行时 (Core) - -在您的 `pom.xml` 中添加核心运行时依赖: - -```xml - - io.agentscope - agentscope-runtime-core - 1.0.0 - -``` - -#### AgentScope Agent 集成 - -如果需要使用 AgentScope Agent: - -```xml - - io.agentscope - agentscope-runtime-agentscope - 1.0.0 - -``` - -#### 一键部署 (Web) - -如果需要使用一键部署功能: - -```xml - - io.agentscope - agentscope-runtime-web - 1.0.0 - -``` - -#### 协议集成 - -如果需要使用 A2A (Agent-to-Agent) 协议: - -```xml - - io.agentscope - spring-boot-starter-runtime-a2a - 1.0.0 - -``` - -#### 自动化部署 - -如果想要自动将 Agent 应用打包为容器,并自动部署到 K8s 或 AgentRun 上,可以使用提供的插件: - -```xml - - io.agentscope - deployer-maven-plugin - 1.0.0 - - deployer.yml - 8080 - - -``` - -### (可选)从源码安装 - -如果您想要使用最新的开发版本或为项目做贡献,可以从源码安装: - -```bash -git clone https://github.com/agentscope-ai/agentscope-runtime-java.git - -cd agentscope-runtime-java - -mvn clean install -Dskiptests -``` - -安装完成后,依赖项将安装在本地 Maven 仓库中,您可以在项目中使用它们。 - -> 从源码安装会使用 SNAPSHOT 版本,适合开发和测试场景。生产环境建议使用 Maven Central 上的稳定版本。 - -### 使用 Maven 检查依赖 - -您也可以使用 Maven 命令检查依赖是否正确解析: - -```bash -mvn dependency:tree | grep agentscope -``` - -这将显示所有与 agentscope 相关的依赖及其版本。 - - -## 安装选项说明 - -这个图展示了安装选项的层次结构,从底层核心运行时(agentscope-runtime-core)开始——其中 **包含 Agent 运行框架 和 Sandbox 依赖**。可选模块(例如 agentscope、web、a2a-starter等)堆叠在核心之上,每个模块都增加了特定的功能(如多Agent框架支持、自动化)。查看所有安装选项的详细信息,请参见项目的 [pom.xml](https://github.com/agentscope-ai/agentscope-runtime-java/blob/main/pom.xml)。 - -| **组件** | **Maven 坐标** | **用途** | -| --------------------- | ----------------------------------------------- | ------------------------------------------------------------ | -| 核心运行时 | `io.agentscope:agentscope-runtime-core` | 最小依赖,提供沙箱管理、记忆管理等基础运行时能力 | -| AgentScope Agent 集成 | `io.agentscope:agentscope-runtime-agentscope` | AgentScope 集成,支持原生 AgentScope Agent 到 Runtime Agent 的转换,并内置 Sandbox Tool 到 AgentScope Tool 的映射逻辑 | -| 一键启动 | `io.agentscope:agentscope-runtime-web` | 通过 LocalDeployer 实现 Agent 应用的一键启动与本地运行 | -| 协议集成 | `io.agentscope:spring-boot-starter-runtime-a2a` | 在用户构建好的 Spring Boot 应用中自动注册 A2A(Agent-to-Agent)通信端点及 Responses API 接口 | -| 自动化部署 | `deployer-maven-plugin` | 将 Agent 应用打包为一个容器,并可选部署到 K8s 或 AgentRun 上 | - -## 版本信息 - -- **当前稳定版本**:`1.0.0` -- **发布位置**:[Maven Central](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) -- **GroupId**:`io.agentscope` - -### 在 Maven Central 上查找 - -您可以在 Maven Central 上搜索和查看所有可用模块: - -- [agentscope-runtime-core](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) -- [agentscope-runtime-agentscope](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-agentscope) -- [agentscope-runtime-web](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-web) -- [spring-boot-starter-runtime-a2a](https://central.sonatype.com/artifact/io.agentscope/spring-boot-starter-runtime-a2a) \ No newline at end of file diff --git a/cookbook/new-zh/intro.md b/cookbook/new-zh/intro.md deleted file mode 100644 index 9b8d640e..00000000 --- a/cookbook/new-zh/intro.md +++ /dev/null @@ -1,65 +0,0 @@ -# 欢迎来到AgentScope Runtime Java Cookbook - -[![License](https://img.shields.io/badge/license-Apache%202.0-red.svg?logo=apache&label=License)](LICENSE) -[![GitHub Stars](https://img.shields.io/github/stars/agentscope-ai/agentscope-runtime-java?style=flat&logo=github&color=yellow&label=Stars)](https://github.com/agentscope-ai/agentscope-runtime-java/stargazers) -[![GitHub Forks](https://img.shields.io/github/forks/agentscope-ai/agentscope-runtime-java?style=flat&logo=github&color=purple&label=Forks)](https://github.com/agentscope-ai/agentscope-runtime-java/network) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime) -[![License](https://img.shields.io/badge/license-Apache%202.0-red.svg?logo=apache&label=License)](https://github.com/agentscope-ai/agentscope-runtime/blob/main/LICENSE) -[![Cookbook](https://img.shields.io/badge/📚_Cookbook-English|中文-teal.svg)](https://runtime.agentscope.io) -[![A2A](https://img.shields.io/badge/A2A-Agent_to_Agent-blue.svg?label=A2A)](https://a2a-protocol.org/) -[![MCP](https://img.shields.io/badge/MCP-Model_Context_Protocol-purple.svg?logo=plug&label=MCP)](https://modelcontextprotocol.io/) -[![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) - -## AgentScope Runtime V1.0 发布 - -AgentScope Runtime Java V1.0 在高效智能体部署与安全沙箱执行的坚实基础上,推出了 **统一的 “Agent 作为 API” 开发体验**,覆盖完整智能体从本地开发到生产部署的生命周期,并扩展了更多沙箱类型、协议兼容性与更丰富的内置工具集。 - -同时,智能体服务的接入方式从过去的 **黑盒化模块替换** 升级为 ***白盒化适配器模式*** —— 开发者可以在保留原有智能体框架接口与行为的前提下,将状态管理、会话记录、工具注册等运行时能力按需嵌入应用生命周期,实现更灵活的定制与跨框架无缝集成。 - -**V1.0 主要改进:** - -- **统一的开发/生产范式** —— 在开发环境与生产环境中 智能体功能性保持一致 -- **原生多智能体支持** —— 完全兼容 AgentScope Java 的多智能体范式 -- **主流 SDK 与协议集成** —— 支持 OpenAI Responses API SDK 与 Google A2A 协议 -- **可视化 Web UI** —— 部署后即可立即体验的开箱即用 Web 聊天界面 -- **扩展沙箱类型** —— GUI、浏览器、文件系统(大部分可通过 VNC 可视化) -- **更丰富的内置工具** —— 面向生产的搜索、RAG、AIGC、支付等模块 -- **灵活的部署模式** —— 本地线程/进程、Docker、Kubernetes、或托管云端 - -更详细的变更说明,以及迁移指南请参考:[CHANGELOG](CHANGELOG.md) - -## 什么是AgentScope Runtime Java? - -**AgentScope Runtime Java** 是一个全面的智能体运行时框架,旨在解决两个关键挑战:**高效的智能体部署**和**沙箱执行**。它内置了基础服务(长短期记忆、智能体状态持久化)和安全沙箱基础设施。无论您需要大规模部署智能体还是确保安全的工具交互,AgentScope Runtime Java 都能提供具有完整可观测性和开发者友好部署的核心基础设施。 - -在 V1.0 中,这些运行时服务通过 **适配器模式** 对外开放,允许开发者在保留原有智能体框架接口与行为的基础上,将 AgentScope Java 的状态管理、会话记录、工具调用等模块按需嵌入到应用生命周期中。从过去的 “黑盒化替换” 变为 “白盒化集成”,开发者可以显式地控制服务初始化、工具注册与状态持久化流程,从而在不同框架间实现无缝整合,同时获得更高的扩展性与灵活性。 - -本指南将指导您使用 **AgentScope Runtime Java** 构建服务级的智能体应用程序。 - -## 核心架构 - -**⚙️ 智能体web应用部署 (Web)** - -提供`AgentApp`作为智能体应用主入口,同时配备部署、管理和监控智能体应用的生产级基础设施,并内置了会话历史、长期记忆以及智能体状态等服务。 - -**🔒 沙箱执行运行时 (Sandbox)** - -安全隔离的环境,让您的智能体能够安全地执行代码、控制浏览器、管理文件并集成MCP 工具——所有这些都不会危及您的系统安全。 - -**🛠️ 生产级工具服务 (Tool)** - -基于可信第三方 API 能力(如搜索、RAG、AIGC、支付等),通过统一的 SDK 封装对外提供标准化调用接口,使智能体能够以一致的方式集成和使用这些服务,而无需关心底层 API 的差异与复杂性。 - -**🔌 适配器模式 (Adapter)** - -将 Runtime 内的各类服务模块(状态管理、会话记录、工具执行等)适配到智能体框架的原生模块接口中,使开发者能够在保留原生行为的同时直接调用这些能力,实现无缝对接与灵活扩展。 - -## 为什么选择 AgentScope Runtime Java? - -- 🤖 **AS原生运行时框架**:由 AgentScope 官方构建和维护,与其多智能体范式、适配器模式及工具使用深度集成,确保最佳兼容性与性能 -- **🏗️ 部署基础设施**:内置长短期记忆、智能体状态和沙箱环境控制服务 -- **🔒 沙箱执行**:隔离的沙箱确保工具安全执行,不会危及系统 -- ⚡ **开发者友好**:简单部署,功能强大的自定义选项 -- **📊 可观测性**:针对运行时操作的全面追踪和监控 - -立即开始使用 AgentScope Runtime Java 部署你的智能体并尝试工具沙箱吧! diff --git a/cookbook/new-zh/quickstart.md b/cookbook/new-zh/quickstart.md deleted file mode 100644 index 24fd76ce..00000000 --- a/cookbook/new-zh/quickstart.md +++ /dev/null @@ -1,414 +0,0 @@ -# 快速开始 - -本教程演示如何在 **AgentScope Runtime Java** 框架中构建一个简单的智能体应用并将其部署为服务。 - -## 前置条件 - -### 🔧 安装要求 - -添加 AgentScope Runtime Java 针对 AgentScope 框架的适配器依赖和应用启动依赖,基础依赖已通过适配器依赖传递依赖完成: - -```xml - - io.agentscope - agentscope-runtime-agentscope - 1.0.0 - - - - io.agentscope - agentscope-runtime-web - 1.0.0 - -``` - -### 🔑 API密钥配置 - -您需要为所选的大语言模型提供商提供API密钥。本示例使用阿里云的Qwen模型,服务提供方是DashScope,所以需要使用其API_KEY,您可以按如下方式将key作为环境变量: - -```bash -export DASHSCOPE_API_KEY="your_api_key_here" -``` - -## 分步实现 - -### 步骤1:构建 Agent 及其执行逻辑 - -#### 1.1 导入依赖 - -首先导入所有必要的依赖: - -```java -import java.util.List; -import java.util.Map; - -import io.agentscope.core.ReActAgent; -import io.agentscope.core.agent.EventType; -import io.agentscope.core.agent.StreamOptions; -import io.agentscope.core.formatter.dashscope.DashScopeChatFormatter; -import io.agentscope.core.memory.LongTermMemoryMode; -import io.agentscope.core.message.Msg; -import io.agentscope.core.model.DashScopeChatModel; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.runtime.adapters.agentscope.AgentScopeAgentHandler; -import io.agentscope.runtime.adapters.agentscope.memory.LongTermMemoryAdapter; -import io.agentscope.runtime.adapters.agentscope.memory.MemoryAdapter; -import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit; -import io.agentscope.runtime.engine.schemas.AgentRequest; -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.box.Sandbox; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import reactor.core.publisher.Flux; -``` - -#### 1.2 构建 AgentScopeAgentHandler 接口的实现 - -下面的四个方法分别定义了整个应用的属性和执行逻辑,`isHealthy`方法用于返回当前应用的健康状况,`getName`方法用于返回当前应用的名称,`getDescription`方法用于返回当前应用的描述,**`streamQuery`**方法则是整个AgentScopeAgentHandler的逻辑执行核心,用于用户设置记忆、构建 Agent 以及自定义 Agent 执行逻辑 - -```java -public class MyAgentScopeAgentHandler extends AgentScopeAgentHandler { - @Override - public boolean isHealthy() { - return false; - } - - @Override - public String getName() { - return ""; - } - - @Override - public String getDescription() { - return ""; - } - - @Override - public Flux streamQuery(AgentRequest request, Object messages) { - return null; - } -} -``` - -#### 1.3 实现核心执行逻辑 streamQuery 方法 - -##### 1.3.1 获取到必要的 id 信息 - -```java -String sessionId = request.getSessionId(); -String userId = request.getUserId(); -``` - -##### 1.3.2 从 StateService 导出历史状态 - -```java -Map state = null; -if (stateService != null) { - try { - state = stateService.exportState(userId, sessionId, null).join(); - } - catch (Exception e) { - logger.warn("Failed to export state: {}", e.getMessage()); - } -} -``` - -- **目的**:恢复该用户在该会话中的**上一轮 Agent 状态**(例如:内部变量、对话阶段、任务进度等)。 -- `roundId = null` 表示取**最新一轮**的状态。 -- 使用 `.join()` 阻塞等待(因为后续构建 Agent 需要同步状态)。 -- 失败时仅警告,不影响主流程(Agent 可从空状态开始)。 - -##### 1.3.3 创建 Toolkit 并注册工具 - -```java -Toolkit toolkit = new Toolkit(); -if (sandboxService != null) { - Sandbox sandbox = sandboxService.connect(userId, sessionId, BaseSandbox.class); - toolkit.registerTool(ToolkitInit.RunPythonCodeTool(sandbox)); -} -``` - -- **Toolkit**:Agent 可调用的工具集合。 -- **Sandbox**:安全沙箱环境,具体包含基础沙箱、文件系统沙箱、浏览器沙箱等,每个 `(userId, sessionId)` 独立实例。 -- 注册沙箱工具。 -- 如果沙箱创建失败,跳过工具注册,Agent 仍可运行,但无法调用此工具。 - -##### 1.3.4 创建短期记忆适配器(MemoryAdapter) - -```java -MemoryAdapter memory = null; -if (sessionHistoryService != null) { - memory = new MemoryAdapter(sessionHistoryService, userId, sessionId); -} -``` - -- **作用**:提供**当前会话的历史消息记录**(如用户和 Agent 的对话历史)。 -- `sessionHistoryService` 是底层存储服务。 -- 适配器将通用服务接口转换为 AgentScope 框架所需的 `Memory` 接口。 - -##### 1.3.5 创建长期记忆适配器(LongTermMemoryAdapter) - -```java -LongTermMemoryAdapter longTermMemory = null; -if (memoryService != null) { - longTermMemory = new LongTermMemoryAdapter(memoryService, userId, sessionId); -} -``` - -- **作用**:访问用户的**跨会话长期记忆**(如个人偏好、知识库摘要等)。 -- 通常基于向量数据库或结构化存储。 -- 后续会配置 Agent 在生成回复时**同时参考短期和长期记忆**。 - -##### 1.3.6 构建 ReActAgent 实例 - -```java -ReActAgent.Builder agentBuilder = ReActAgent.builder() - .name("Friday") - .sysPrompt("You're a helpful assistant named Friday.") - .toolkit(toolkit) - .model( - DashScopeChatModel.builder() - .apiKey(apiKey) - .modelName("qwen-max") - .stream(true) - .formatter(new DashScopeChatFormatter()) - .build()); -``` - -- 使用 **Builder 模式**组装 Agent: - - 名称、系统提示词(system prompt) - - 绑定工具集(`toolkit`) - - 配置大模型(这里用通义千问 `qwen-max`,通过 DashScope API) - - 启用流式输出(`.stream(true)`) -- **注意**:此时 Agent 尚未加载状态或记忆。 - -##### 1.3.7 注入记忆模块 - -```java -if (longTermMemory != null) { - agentBuilder.longTermMemory(longTermMemory) - .longTermMemoryMode(LongTermMemoryMode.BOTH); -} -if (memory != null) { - agentBuilder.memory(memory); -} -``` - -- **`memory`** → 短期记忆(当前会话历史) -- **`longTermMemory`** → 长期记忆(跨会话知识) -- `LongTermMemoryMode.BOTH`:表示在**思考和生成**阶段都使用长期记忆。 - -##### 1.3.8 加载历史状态到 Agent - -```java -if (state != null && !state.isEmpty()) { - agent.loadStateDict(state); -} -``` - -- 将 Step 2 获取的状态字典反序列化到 Agent 内部。 -- 使 Agent 能“接续”上一次的对话状态(如继续未完成的任务)。 - -##### 1.3.9 处理输入消息(messages) - -```java -List agentMessages; -if (messages instanceof List) { - @SuppressWarnings("unchecked") - List msgList = (List) messages; - agentMessages = msgList; -} -else if (messages instanceof Msg) { - agentMessages = List.of((Msg) messages); -} -else { - logger.warn("Unexpected messages type: {}, using empty list", - messages != null ? messages.getClass().getName() : "null"); - agentMessages = List.of(); -} - -Msg queryMessage; -if (agentMessages.size() > 1) { - // 将前 N-1 条消息加入 memory - for (int i = 0; i < agentMessages.size() - 1; i++) { - agent.getMemory().addMessage(agentMessages.get(i)); - } - queryMessage = agentMessages.get(agentMessages.size() - 1); // 最后一条作为当前查询 -} else { - queryMessage = agentMessages.get(0) or empty Msg; -} -``` - -##### 1.3.10 启动流式推理并返回事件流 - -```java -StreamOptions streamOptions = StreamOptions.builder() - .eventTypes(EventType.REASONING, EventType.TOOL_RESULT) - .incremental(true) - .build(); - -Flux agentScopeEvents = agent.stream(queryMessage, streamOptions); -``` - -- **`stream()`**:启动 ReAct 循环(Thought → Action → Observation → ... → Final Answer) -- **`StreamOptions`**: - - `eventTypes`:只返回推理步骤和工具结果(过滤掉内部日志等) - - `incremental = true`:启用增量流式输出(如逐字生成) -- 返回的是 **AgentScope 原生 Event 流**(不是 Runtime Event),由外层 `StreamAdapter` 转换。 - -##### 1.3.11 流完成时保存最终状态 - -```java -return agentScopeEvents - .doOnNext(event -> { - logger.info("Agent event: {}", event); - }) - .doFinally(signalType -> { - if (stateService != null) { - try { - Map finalState = agent.stateDict(); - if (finalState != null && !finalState.isEmpty()) { - stateService.saveState(userId, finalState, sessionId, null) - .exceptionally(e -> { - logger.error("Failed to save state: {}", e.getMessage(), e); - return null; - }); - } - } - catch (Exception e) { - logger.error("Error saving state: {}", e.getMessage(), e); - } - } - }) - .doOnError(error -> { - logger.error("Error in agent stream: {}", error.getMessage(), error); - }); -``` - -- **无论成功/失败/取消**,在流结束时保存 Agent 的**最终状态**。 -- `roundId = null` → 自动分配新轮次 ID(见 `InMemoryStateService` 实现)。 -- 使用 `exceptionally` 处理保存异常,避免影响主流程。 - -> 🔁 实现了“状态持久化闭环”:加载 → 执行 → 保存。 - -### 步骤2:构建 AgentApp - -#### 2.1 导入依赖 - -```java -import io.agentscope.runtime.app.AgentApp; -import io.agentscope.runtime.engine.services.agent_state.InMemoryStateService; -import io.agentscope.runtime.engine.services.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.services.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.services.sandbox.SandboxService; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.client.config.BaseClientConfig; -import io.agentscope.runtime.sandbox.manager.client.config.KubernetesClientConfig; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import org.jetbrains.annotations.NotNull; -``` - -#### 2.2 构建 SandboxService 沙箱管理服务 - -```java -private static SandboxService buidSandboxService() { - BaseClientConfig clientConfig = KubernetesClientConfig.builder().build(); - ManagerConfig managerConfig = ManagerConfig.builder() - .containerDeployment(clientConfig) - .build(); - return new SandboxService( - new SandboxManager(managerConfig) - ); -} -``` - -* 沙箱运行环境支持 **Docker**、**K8s **以及 **AgentRun**,未配置 `clientConfig` 默认使用**本地 Docker **作为运行环境 -* 使用`managerConfig`构建 **SandboxManager**,并由此构建 **SandboxService** - -#### 2.3 构建 AgentApp - -##### 2.3.1 初始化 agentHandler - -```java -MyAgentScopeAgentHandler agentHandler = new MyAgentScopeAgentHandler(); -agentHandler.setStateService(new InMemoryStateService()); -agentHandler.setSessionHistoryService(new InMemorySessionHistoryService()); -agentHandler.setMemoryService(new InMemoryMemoryService()); -agentHandler.setSandboxService(buidSandboxService()); -``` - -实例化刚刚编写的 **AgentScopeAgentHandler** 类,并注册服务 - -##### 2.3.2 构建 AgentApp 并一键启动 - -```java -AgentApp agentApp = new AgentApp(agentHandler); -agentApp.run(10001); -``` - -使用实例化的 **AgentScopeAgentHandler** 类初始化 **AgentApp**,并在10001端口上启动 - -### 步骤3:通过 A2A 协议访问 Agent - -```bash -curl --location --request POST 'http://localhost:10001/a2a/' \ ---header 'Content-Type: application/json' \ ---header 'Accept: */*' \ ---header 'Host: localhost:10001' \ ---header 'Connection: keep-alive' \ ---data-raw '{ - "method": "message/stream", - "id": "2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc", - "jsonrpc": "2.0", - "params": { - "configuration": { - "blocking": false - }, - "message": { - "role": "user", - "kind": "message", - "metadata": { - "userId": "me", - "sessionId": "test1" - }, - "parts": [ - { - "text": "你好,给我用python计算一下第10个斐波那契数", - "kind": "text" - } - ], - "messageId": "c4911b64c8404b7a8bf7200dd225b152" - } - } -}' -``` - -你将会看到以**Server-Sent Events(SSE)**格式流式输出的响应: - -``` -id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc -event:jsonrpc -data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"id":"92ccdc36-006f-4d66-a47c-18d0cb171506","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","status":{"state":"submitted","timestamp":"2025-12-09T10:53:47.612001Z"},"artifacts":[],"history":[{"role":"user","parts":[{"text":"你好,给我用python计算一下第10个斐波那契数","kind":"text"}],"messageId":"c4911b64c8404b7a8bf7200dd225b152","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","metadata":{"userId":"me","sessionId":"test1"},"kind":"message"}],"kind":"task"}} - -id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc -event:jsonrpc -data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","status":{"state":"working","timestamp":"2025-12-09T10:53:47.614736Z"},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","final":false,"kind":"status-update"}} - -...... - -id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc -event:jsonrpc -data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","artifact":{"artifactId":"293bb1b0-1442-4ca2-997f-575b798dfad1","name":"agent-response","parts":[{"text":"是55。","kind":"text"}],"metadata":{"type":"chunk"}},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","append":true,"lastChunk":false,"kind":"artifact-update"}} - -id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc -event:jsonrpc -data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","status":{"state":"completed","message":{"role":"agent","parts":[{"text":"run_ipython_cellrun_ipython_cell第10个斐波那契数是55。","kind":"text"}],"messageId":"7b878071-d63e-4710-81e0-91d50a57c373","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","metadata":{"type":"final_response"},"kind":"message"},"timestamp":"2025-12-09T10:53:51.538933Z"},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","final":true,"kind":"status-update"}} -``` - -## 章节导读 - -后续的章节包括如下几个部分 -- [沙箱与工具](tool.md): 帮助您在Agent中加入工具 -- [部署](deployment.md): 帮助您部署Agent,打包成服务 -- [使用](use.md): 帮助您调用部署后的服务 -- [如何贡献](contribute.md): 贡献代码给本项目的参考文档 \ No newline at end of file diff --git a/cookbook/zh/CHANGELOG.md b/cookbook/zh/CHANGELOG.md new file mode 100644 index 00000000..e804fdf0 --- /dev/null +++ b/cookbook/zh/CHANGELOG.md @@ -0,0 +1,315 @@ +# CHANGELOG + +## v1.0.0 + +AgentScope Runtime Java v1.0 在高效智能体部署与安全沙箱执行的坚实基础上,推出了统一的 “Agent 作为 API” 开发体验,覆盖完整智能体从本地开发到生产部署的生命周期,并扩展了更多沙箱类型、协议兼容性与更丰富的内置工具集。 + +**变更背景与必要性** + +在 v0.x 版本中,AgentScope 的 Agent 模块(如 `AgentScopeAgent`、`SaaAgent` 等)采用黑盒化模块替换方式,通过直接将 Agent 对象传入 `AgentApp` 或 `Runner` 执行。这种封装在单智能体简单场景可以工作,但在复杂应用、尤其是多智能体组合时暴露了以下严重问题: + +1. **自定义 Memory 模块会被黑盒替换** + 用户在开发环境中自定义的 Memory(如 `InMemoryMemory` 或自写类)在生产部署时会被不透明地替换为 `RedisMemory` 等实现,用户无法感知这种变化,也无法控制替换行为,导致线上与本地表现不一致。 +2. **Agent State 未得到保留** + 旧框架缺少智能体状态序列化与恢复机制,多轮交互或任务中断后无法保留 agent 内部状态(如思考链、上下文变量),影响长任务的连续性。 +3. **无法挂载自定义逻辑(Hooks)** + 由于生命周期全被封装在内部,用户无法在 Agent 或执行阶段添加钩子函数(hooks),例如: + - 在推理前后插入自定义数据处理 + - 运行时动态修改工具集或 prompt +4. **多智能体与跨框架组合受限** + 黑盒模式无法在不同 agent 实例之间共享会话记录、长短期记忆服务、工具集,也难以将不同 agent 框架(如 ReActAgent)无缝组合。 + +以上缺陷直接限制了 AgentScope Runtime 在真实生产环境的可扩展性与可维护性,也使得“开发环境与生产环境一致”的目标无法实现。 + +因此,v1.0.0 重构了 Agent 接入模式,引入 **白盒化适配器模式** —— 通过 +* 通过 `AgentHandler` 接口来统一定义智能体逻辑、管理组件声明周期。开发者完全使用原生框架(如 AgentScope)的编码 API 定义自己的智能体。 +* `AgentApp` 作为统一入口,用来加载开发者定义的 `AgentHandler` 智能体、完成与 Runtime 内部组件的绑定、管理组件生命周期等。 + +这使得: + +- 开发者完全使用原生 Agent 框架开发智能体,降低复杂度 +- 记忆、会话、工具注册等运行时能力可按需插入 +- 通过拓展 AgentApp 生命周期可实现更灵活的组件初始化与销毁 + +主要改进: +- **统一的开发/生产范式**:智能体在开发与生产环境中保持一致的功能性。 +- **原生多智能体支持**:完全兼容 AgentScope 的多智能体范式。 +- **主流 SDK 与协议集成**:支持 OpenAI SDK 与 Google A2A 协议。 +- **可视化 Web UI**:部署后开箱即用的 Web 聊天界面。 +- **扩展沙箱类型**:支持 GUI、浏览器、文件系统、移动端、云端(大部分可通过 VNC 可视化)。 +- **丰富的内置工具集**:面向生产的搜索、RAG、AIGC、支付等模块。 +- **灵活的部署模式**:支持本地线程/进程、Docker、Kubernetes、或托管云端部署。 + +### Added +- 原生Short/Long Memory、智能体 State 适配器集成至 AgentScope Framework。 +- 新增多种 Sandbox 类型,如移动端沙箱、AgentBay无影云沙箱等(开发中)。 +- 新增 AgentHandler,用来作为智能体定义入口,开发者需要继承该接口以提供完整的智能体定义和处理逻辑。 +- 新增 AgentApp,用来作为 Runtime 启动入口,实现组件生命周期管理、容器启动等。 + +### Breaking Changes +以下变更会影响现有 v0.x 用户,需要手动适配: +1. **Agent模块接口迁移** + + - `AgentScopeAgent`、`SaaAgent` 等Agent模块已被移除,相关 API 迁移到 `AgentHandler`、`AgentScopeAgentHandler` 基类中。 + - **示例迁移**: + + ```java + # v0.x + public void connect() throws Exception { + buildContextManager(); + // Create SaaAgent + AgentScopeAgent agent = buildAgentScopeAgent(apiKey, toolkit); + // Initialize runner + runner = Runner.builder().agent(agent).contextManager(contextManager).environmentManager(environmentManager).build(); + } + + private void buildContextManager() throws InterruptedException, ExecutionException { + // Initialize session history service + sessionHistoryService = new InMemorySessionHistoryService(); + // Create session + sessionHistoryService.createSession(USER_ID, Optional.of(SESSION_ID)).get(); + // Initialize memory service + memoryService = new InMemoryMemoryService(); + + // Initialize context manager + contextManager = new ContextManager( + ContextComposer.class, + sessionHistoryService, + memoryService + ); + contextManager.start().get(); + } + + private static AgentScopeAgent buildAgentScopeAgent(String apiKey, Toolkit toolkit) { + ReActAgent.Builder agentBuilder = + ReActAgent.builder() + .name("Assistant") + .sysPrompt("You are a helpful AI assistant. Be friendly and concise.") + .model( + io.agentscope.core.model.DashScopeChatModel.builder() + .apiKey(apiKey) + .modelName("qwen-plus") + .stream(true) + .enableThinking(true) + .formatter(new DashScopeChatFormatter()) + .defaultOptions( + GenerateOptions.builder() + .thinkingBudget(1024) + .build()) + .build()) + .memory(new InMemoryMemory()); + + AgentScopeAgent agent = AgentScopeAgent.builder() + .agent(agentBuilder) + .build(); + return agent; + } + + # v1.0 + public class MyAgentScopeAgentHandler extends AgentScopeAgentHandler { + @Override + public Flux streamQuery(AgentRequest request, Object messages) { + String sessionId = request.getSessionId(); + String userId = request.getUserId(); + + try { + // Step 1: Export state from StateService + Map state = null; + if (stateService != null) { + try { + state = stateService.exportState(userId, sessionId, null).join(); + } + catch (Exception e) { + logger.warn("Failed to export state: {}", e.getMessage()); + } + } + + // Step 2: Create Toolkit and register tools + Toolkit toolkit = new Toolkit(); + + // toolkit.registerTool(new ExampleTool()); + + if (sandboxService != null) { + try { + // Create a BaseSandbox instance for this session + Sandbox sandbox = sandboxService.connect(userId, sessionId, BaseSandbox.class); + + // Register Python code execution tool (matching Python: execute_python_code) + toolkit.registerTool(ToolkitInit.RunPythonCodeTool(sandbox)); + logger.debug("Registered execute_python_code tool"); + } + catch (Exception e) { + logger.warn("Failed to create sandbox or register tools: {}", e.getMessage()); + // Continue without tools if sandbox creation fails + } + } + + // Step 3: Create MemoryAdapter + MemoryAdapter memory = null; + if (sessionHistoryService != null) { + memory = new MemoryAdapter( + sessionHistoryService, + userId, + sessionId + ); + } + + // Step 4: Create LongTermMemoryAdapter + LongTermMemoryAdapter longTermMemory = null; + if (memoryService != null) { + longTermMemory = new LongTermMemoryAdapter( + memoryService, + userId, + sessionId + ); + } + + // Step 5: Create ReActAgent + ReActAgent.Builder agentBuilder = ReActAgent.builder() + .name("Friday") + .sysPrompt("You're a helpful assistant named Friday.") + .toolkit(toolkit) + .model( + DashScopeChatModel.builder() + .apiKey(apiKey) + .modelName("qwen-max") + // .enableThinking(true) + .stream(true) + .formatter(new DashScopeChatFormatter()) + .build()); + + // Add long-term memory if available + if (longTermMemory != null) { + agentBuilder.longTermMemory(longTermMemory) + .longTermMemoryMode(LongTermMemoryMode.BOTH); + logger.debug("Long-term memory configured"); + } + + if (memory != null) { + agentBuilder.memory(memory); + logger.debug("Memory adapter configured"); + } + + ReActAgent agent = agentBuilder.build(); + + // Step 6: Load state if available + if (state != null && !state.isEmpty()) { + try { + agent.loadStateDict(state); + logger.debug("Loaded state for session: {}", sessionId); + } + catch (Exception e) { + logger.warn("Failed to load state: {}", e.getMessage()); + } + } + + // Step 7: Convert messages parameter to List + // Python version: msgs parameter is already a list of Msg + List agentMessages; + if (messages instanceof List) { + @SuppressWarnings("unchecked") + List msgList = (List) messages; + agentMessages = msgList; + } + else if (messages instanceof Msg) { + agentMessages = List.of((Msg) messages); + } + else { + logger.warn("Unexpected messages type: {}, using empty list", + messages != null ? messages.getClass().getName() : "null"); + agentMessages = List.of(); + } + + // Step 8: Stream agent responses (matching Python: async for msg, last in stream_printing_messages(...)) + // Configure streaming options - match Python version's streaming behavior + StreamOptions streamOptions = StreamOptions.builder() + .eventTypes(EventType.REASONING, EventType.TOOL_RESULT) + .incremental(true) + .build(); + + // Python version: agent(msgs) - passes the entire list + // In Java, ReActAgent.stream() accepts a single Msg, so we use the first message + // or combine all messages into memory first, then call with the last message + Msg queryMessage; + if (agentMessages.isEmpty()) { + // No messages provided, create a default empty message + queryMessage = Msg.builder() + .role(io.agentscope.core.message.MsgRole.USER) + .build(); + } + else if (agentMessages.size() == 1) { + // Single message - use it directly + queryMessage = agentMessages.get(0); + } + else { + // Multiple messages - add all but the last to memory, then use the last one for query + // This matches Python behavior where all messages are in memory and the last is the query + for (int i = 0; i < agentMessages.size() - 1; i++) { + agent.getMemory().addMessage(agentMessages.get(i)); + } + queryMessage = agentMessages.get(agentMessages.size() - 1); + } + + // Stream agent responses + Flux agentScopeEvents = agent.stream(queryMessage, streamOptions); + + return agentScopeEvents + .doOnNext(event -> { + // Step 9: Handle intermediate events if needed + // (e.g., logging) + logger.info("Agent event: {}", event); + }) + .doFinally(signalType -> { + // Step 10: Save state after completion + if (stateService != null) { + try { + Map finalState = agent.stateDict(); + if (finalState != null && !finalState.isEmpty()) { + stateService.saveState(userId, finalState, sessionId, null) + .exceptionally(e -> { + logger.error("Failed to save state: {}", e.getMessage(), e); + return null; + }); + } + } + catch (Exception e) { + logger.error("Error saving state: {}", e.getMessage(), e); + } + } + }) + .doOnError(error -> { + logger.error("Error in agent stream: {}", error.getMessage(), error); + }); + + } + catch (Exception e) { + logger.error("Error in streamQuery: {}", e.getMessage(), e); + return Flux.error(e); + } + } + } + ``` + +2. **Tool 抽象接口变更** + + - 原 `SandboxTool` 抽象被移除,使用原生Sandbox方法 + + - 示例迁移: + + ```java + # v0.x + Toolkit toolkit = new Toolkit(); + toolkit.registerTool(ToolkitInit.RunPythonCodeTool()); + + # v1.0 + Toolkit toolkit = new Toolkit(); + Sandbox sandbox = sandboxService.connect(userId, sessionId, BaseSandbox.class); + // 需要明确指定 sandbox 实例 + toolkit.registerTool(ToolkitInit.RunPythonCodeTool(sandbox)); + ``` + +### Removed +- `ContextManager`和`EnvironmentManager`已被移除,现在由 Agent 进行上下文管理 +- `AgentScopeAgent`、`SaaAgent` 已被移除,相关逻辑迁移到 `AgentHandler`、`AgentScopeAgentHandler` 中以供用户白盒化开发。 + +------ diff --git a/cookbook/zh/README.md b/cookbook/zh/README.md deleted file mode 100644 index be5818b6..00000000 --- a/cookbook/zh/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# 参与贡献Cookbook - -感谢您对 AgentScope Runtime Java Cookbook 的兴趣! - -AgentScope Runtime Java Cookbook 提供了使用 AgentScope Runtime Java 构建智能体应用程序的实用示例、教程和最佳实践。我们拥有一个友好的开发者、研究人员和从业者社区,他们热衷于帮助新的贡献者。我们欢迎各种类型的贡献,从添加新的教程和示例到改进现有文档和修复问题。 - -## 前提条件 - -在开始之前,请确保您已安装以下软件: - -- **Git** -- **Markdown**的基础知识 - -## 安装 - -克隆仓库并安装必要的开发依赖项: - -```bash -git clone https://github.com/agentscope-ai/agentscope-runtime-java.git -cd agentscope-runtime-java -``` - -## 管理文档 - -- **添加文档**:在适当的目录中创建新的 Markdown (`.md`) 。 -- **删除文档**:删除相关文件。 - -## (可选)手动构建步骤 - -如果您更喜欢手动构建,请按照以下步骤操作: - -1. **安装相关依赖:** - -```bash -npm install -``` - -2. **启动react应用:** - -```bash -npm start -``` - - - diff --git a/cookbook/zh/concept.md b/cookbook/zh/concept.md index 9a26d884..e20258d6 100644 --- a/cookbook/zh/concept.md +++ b/cookbook/zh/concept.md @@ -1,124 +1,156 @@ # 概念 -本章介绍了AgentScope Runtime Java的核心概念,它提供了两种主要的使用模式: +本章介绍了AgentScope Runtime的核心概念。 -- **智能体部署**: 使用引擎模块进行功能完整的智能体部署,包括运行时编排、上下文管理和生产就绪的服务 -- **沙箱工具使用**: 独立使用沙箱模块,在您自己的应用程序中进行安全的工具执行和集成 - -## Engine模块概念 - -### 架构 +## 架构 AgentScope Runtime使用模块化架构,包含几个关键组件: -Installation Options - -- **Agent**:处理请求并生成响应的核心AI组件(支持AgentScope Java、Spring AI Alibaba等 Java Agent框架) -- **AgentApp**: 使用 SpringBoot 作为应用实现,负责对外提供 API 接口、路由注册、配置加载,并将请求交由 Runner 调用执行 -- **Runner**:在运行时编排智能体执行并管理部署 -- **Context**:包含智能体执行所需的所有信息 -- **Context & Env Manager**:提供额外功能服务管理,如会话历史管理、长期记忆管理、沙箱管理 -- **Deployer**:将Runner部署为服务 +```mermaid +flowchart LR + %% 服务模块 + subgraph Service["💼 服务"] + MS["记忆服务"] + SS["会话服务"] + STS["状态服务"] + SBS["沙箱服务"] + end + + %% 沙箱模块 + subgraph Sandbox["🐳 沙箱"] + BS["浏览器沙箱"] + FS["文件系统沙箱"] + GS["GUI 沙箱"] + CSB["云沙箱"] + MSB["移动端沙箱"] + ETC["更多..."] + end + + %% 适配器模块(大块) + subgraph Adapter["🔌 适配器"] + MAD["记忆适配器"] + SAD["会话适配器"] + STAD["状态适配器"] + SBAD["沙箱工具适配器"] + end + + %% Agent 模块(大块) + subgraph Agent["🤖 智能体"] + AG["AgentScope Java"] + AG_NOTE["(更多...)"] + end + + %% 应用层 + subgraph AgentAPP["📦 智能体应用"] + RA["运行器"] + end + + %% 部署模块 + subgraph Deployer["🚀 部署器"] + CT["容器部署"] + KD["K8s 部署"] + DP["云部署"] + LD["本地部署"] + end + + %% 外部协议 + OAI["OpenAI Responses API SDK"]:::ext + A2A["Google A2A 协议"]:::ext + CUS["自定义端点"]:::ext + + MS --> MAD + SS --> SAD + STS --> STAD + SBS --> SBAD + + BS --> SBS + FS --> SBS + GS --> SBS + CSB --> SBS + MSB --> SBS + ETC --> SBS + + %% 大块到大块的连接 + Adapter --> Agent + + AG --> RA + RA --> CT + RA --> KD + RA --> DP + RA --> LD + + %% 整个部署模块连接到外部协议 + Deployer --> OAI + Deployer --> A2A + Deployer --> CUS + + %% 样式 + classDef small fill:#0066FF,stroke:#004CBE,color:#FFFFFF,font-weight:bold + classDef big fill:#99D6FF,stroke:#004CBE,color:#FFFFFF,font-weight:bold + classDef ext fill:#FFFFFF,stroke:#000000,color:#000000,font-weight:bold + + class Tools,Service,Sandbox,Adapter,Agent,AgentAPP,Deployer big + class RT,ST,PT,MS,SS,STS,SBS,BS,FS,GS,CSB,MSB,ETC,TAD,MAD,SAD,STAD,SBAD,AG,AG_NOTE,RA,CT,KD,DP,LD small + +``` + +- **Agent**:处理请求并生成响应的核心AI组件,在Runtime中,Agent的构建推荐使用AgentScope框架。 +- **AgentApp**: 作为智能体应用入口,负责对外提供 API 接口、路由注册、配置加载,并将请求交由 Runner 调用执行 +- **Runner**:在运行时编排智能体执行并管理部署。它处理智能体生命周期、会话管理、流式响应和服务部署。 +- **Deployer**:将Runner部署为服务,提供健康检查、监控、生命周期管理、使用SSE的实时响应流式传输、错误处理、日志记录和优雅关闭。 +- **Tool**: 提供开箱即用的沙箱工具支持。 +- **Service**:提供智能体所需要的管理服务,比如记忆管理,沙箱管理等。 +- **Adapter**:将Runtime提供的组件/模块适配到Agent框架的适配器 ### 关键组件 #### 1. Agent -`Agent` 是处理请求并生成响应的核心组件。它是一个抽象基类,定义了所有智能体类型的接口。我们将使用 `AgentScopeAgent`作为主要示例,但相同的部署步骤适用于所有智能体类型。 - -#### 2. Runner - -`Runner` 类提供灵活且可扩展的运行时来编排智能体执行并提供部署功能。它管理: - -- 智能体生命周期 -- 上下文管理器及沙箱管理器生命周期 -- 智能体响应 - -#### 3. Context - -`Context` 对象包含智能体执行所需的所有信息: - -- 会话信息 -- 用户请求 -- 服务实例 - -#### 4. Context & Env Manager - -包含`ContextManager`和`EnvironmentManager`: - -* `ContextManager`:提供会话历史管理、长期记忆管理 -* `EnvironmentManager`:提供沙箱生命周期的管理 - -#### 5. Deployer - -`Deployer` 系统提供生产级别的部署功能: - -- 将`runner`部署为服务 -- 健康检查、监控和生命周期管理 -- 使用SSE的实时响应流式传输 -- 错误处理、日志记录和优雅关闭 - -## 沙箱模块概念 - -### 架构 - -沙箱模块为各种操作提供了一个**安全**且**隔离**的执行环境,包括MCP工具执行、浏览器自动化和文件系统操作。该架构围绕三个主要组件构建: - -- **Sandbox(沙箱)**: 提供隔离和安全的容器化执行环境 -- **Tools(工具)**:在沙箱内执行的类似函数的接口 - -### 沙箱类型 - -系统支持多种沙箱类型,每种都针对特定用例进行了优化: - -#### 1. BaseSandbox(基础沙箱) +`Agent` 是处理请求并生成响应的核心组件。市面上已有大量的开发框架包含了Agent类,Runtime本身不提供额外的Agent类,开发者可以使用AgentScope开发需要的Agent。 -- **用途**: 基本Python代码执行和shell命令 -- **使用场景**: 基础工具执行和脚本编写的必需品 -- **能力**: IPython环境、shell命令执行 +#### 2. AgentApp -#### 2. GuiSandbox (GUI沙箱) +`AgentApp` 是 AgentScope Runtime 中的 **应用入口点**,用于将 Agent 部署为可对外提供服务的 API 应用。 -- **用途**:具有安全访问控制的图形用户界面(GUI)交互与自动化 -- **使用场景**:用户界面测试、桌面自动化、交互式工作流程 -- **功能**:模拟用户输入(点击、键盘输入)、窗口管理、屏幕捕获等 +它的职责是: -#### 3. FilesystemSandbox(文件系统沙箱) +- 初始化并绑定 **Agent** 和 **AgentScopeAgentHandler**,自动构建 **Runner**,将请求委托给运行时处理 +- 提供标准化的 **HTTP API 接口**(含健康检查) +- 支持 **Server-Sent Events (SSE)** 以及标准 JSON 响应 +- 允许注册中间件、任务队列(Celery)以及自定义路由 +- 管理应用生命周期(支持 `before_start` / `after_finish` 钩子) +- 将Agent应用部署为服务 -- **用途**: 具有安全访问控制的文件系统操作 -- **使用场景**: 文件管理、文本处理和数据操作 -- **能力**: 文件读写、目录操作、文件搜索和元数据等 +#### 3. AgentScopeAgentHandler -#### 4. BrowserSandbox(浏览器沙箱) +`AgentScopeAgentHandler` 类提供灵活且可扩展的智能体执行逻辑。它管理: -- **用途**: Web浏览器自动化和控制 -- **使用场景**: 网页抓取、UI测试和基于浏览器的交互 -- **能力**: 页面导航、元素交互、截图捕获等 +- 通过 `streamQuery` 支持用户自定义请求执行逻辑 +- 流式响应 -#### 5. TrainingSandbox(训练沙箱) +#### 4. Deployer -- **用途**:智能体训练和评估环境 -- **使用场景**: 基准测试和性能评估 -- **能力**: 环境分析、训练数据管理 +`Deployer`(实现为 `deployer-maven-plugin`插件)提供生产级别的部署功能: -### 工具模块 +- maven打包过程中自动**构建 Docker 镜像** +- 可选推送至远程仓库、一键部署到 **K8s 集群**以及部署到 **AgentRun** -#### 类函数接口 +#### 5. Sandbox & Tool -工具设计采用直观的类函数接口,在抽象沙箱复杂性的同时提供最大的灵活性: +Runtime提供两种工具接入方式 +- 即用型工具,即由服务提供商提供的开箱即用的服务,比如RAG +- 工具沙箱,即运行在runtime里安全可控的工具,比如浏览器 -- **直接执行**: 工具可以直接调用,自动创建临时沙箱 -- **沙箱绑定**: 工具可以绑定到特定的沙箱实例以获得持久的执行上下文 -- **模式定义**: 每个工具都有一个定义的模式,指定输入参数和预期行为 -#### 工具执行优先级 +#### 6. Service -工具模块实现了三级沙箱规范优先级: +`Service`包含如下几种: -1. **临时沙箱**(最高优先级): 在函数调用期间指定 -2. **实例绑定沙箱**(第二优先级): 通过绑定方法指定 -3. **演练模式**(最低优先级,未指定沙箱): 当未指定沙箱时自动创建临时沙箱,工具执行后将被释放 +- `state_service` 状态服务 +- `memory_service` 智能体记忆服务 +- `sandbox_service` 即沙箱服务 +- `session_history_service` 即会话历史记录保存服务 -#### 不可变绑定模式 +#### 7. Adapter -当工具绑定到特定沙箱时,会创建一个新的工具实例,而不是修改原始实例。这种不可变绑定模式确保了线程安全,并允许同一工具的多个沙箱绑定版本共存而不会相互干扰。 +`Adapter`按照不同Agent框架分类,包含记忆适配器、会话适配器、消息协议适配器等。 diff --git a/cookbook/zh/context_manager.md b/cookbook/zh/context_manager.md deleted file mode 100644 index 20e380ca..00000000 --- a/cookbook/zh/context_manager.md +++ /dev/null @@ -1,940 +0,0 @@ -# 上下文管理器 (Context Manager) - -## 概述 - -上下文管理器提供了一种方便的方式来管理上下文生命周期。它包含: - -- **一组上下文服务**:会话历史服务(SessionHistoryService)和记忆服务(MemoryService) -- **ContextComposer**:用于编排历史和记忆更新的组合器 - -## 服务架构概览 - -上下文管理器支持两种核心服务类型,每种服务都有多个内置实现: - -### SessionHistoryService(会话历史服务) - -用于以会话级别粒度维护完整的对话历史,不会对记忆进行压缩。 - -**接口方法:** - -- `createSession`:创建新会话 -- `getSession`:获取会话 -- `deleteSession`:删除会话 -- `listSessions`:列出所有会话 -- `appendMessage`:向历史中添加消息 - -**内置实现:** - -| 实现类 | 存储方式 | 适用场景 | 说明 | -|--------|----------|----------|------| -| `InMemorySessionHistoryService` | 内存(Map) | 开发、测试、单机部署 | 数据存储在内存中,服务重启后数据丢失 | -| `RedisSessionHistoryService` | Redis | 生产环境、分布式部署 | 数据持久化到Redis,支持多实例共享 | -| `TableStoreSessionHistoryService` | 阿里云表格存储 | 生产环境、大规模部署 | 使用阿里云TableStore,支持海量数据存储 | - -### MemoryService(记忆服务) - -用于存储和检索长期记忆。在Agent中,记忆存储终端用户之前的对话信息,可以跨会话查询和使用。 - -**接口方法:** -- `addMemory`:向记忆服务添加记忆 -- `searchMemory`:从记忆服务中搜索记忆 -- `deleteMemory`:从记忆服务中删除记忆 -- `listMemory`:列出所有记忆 -- `getAllUsers`:获取所有用户列表 - -**内置实现:** - -| 实现类 | 存储方式 | 适用场景 | 说明 | -|--------|----------|----------|------| -| `InMemoryMemoryService` | 内存(Map) | 开发、测试、单机部署 | 简单关键词搜索,数据存储在内存中 | -| `RedisMemoryService` | Redis | 生产环境、分布式部署 | 数据持久化到Redis,支持多实例共享 | -| `TableStoreMemoryService` | 阿里云表格存储 | 生产环境、大规模部署 | 使用阿里云TableStore KnowledgeStore,支持向量搜索 | -| `Mem0MemoryService` | Mem0 API | 生产环境、需要高级记忆管理 | 使用Mem0云服务,提供高级记忆管理和搜索能力 | - ---- - -## SessionHistoryService(会话历史服务) - -### 接口定义 - -`SessionHistoryService` 是管理会话历史的接口,用于以会话级别粒度维护完整记忆,不会对记忆进行压缩。 - -```java -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; - -public interface SessionHistoryService extends Service { - CompletableFuture createSession(String userId, Optional sessionId); - CompletableFuture> getSession(String userId, String sessionId); - CompletableFuture deleteSession(String userId, String sessionId); - CompletableFuture> listSessions(String userId); - CompletableFuture appendMessage(Session session, List messages); -} -``` - -### 实现1:InMemorySessionHistoryService - -**特点:** -- 数据存储在内存中的 `ConcurrentHashMap` -- 线程安全 -- 服务重启后数据丢失 -- 适用于开发、测试和小规模部署 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; -import io.agentscope.runtime.engine.schemas.context.Session; -import java.util.Optional; - -// 创建服务实例 -SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); - -// 启动服务 -sessionHistoryService.start().get(); - -try { - // 创建会话 - Session session = sessionHistoryService.createSession("userId", Optional.empty()).get(); - - // 获取会话 - Optional retrievedSession = sessionHistoryService.getSession("userId", session.getId()).get(); - - // 使用服务... -} finally { - // 停止服务 - sessionHistoryService.stop().get(); -} -``` - -**实现细节:** -- 数据结构:`Map>` (user_id -> session_id -> Session) -- 如果未提供会话ID,会使用UUID自动生成 -- 空的或仅包含空格的会话ID会被替换为自动生成的ID -- 使用ConcurrentHashMap保证线程安全 - -### 实现2:RedisSessionHistoryService - -**特点:** -- 数据持久化到Redis -- 支持多实例共享数据 -- 适用于生产环境和分布式部署 -- 需要配置Redis连接 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.session.RedisSessionHistoryService; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.StringRedisTemplate; - -// 配置Redis连接 -RedisConnectionFactory connectionFactory = new LettuceConnectionFactory("localhost", 6379); -connectionFactory.afterPropertiesSet(); - -RedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory); -redisTemplate.afterPropertiesSet(); - -// 创建服务实例 -SessionHistoryService sessionHistoryService = new RedisSessionHistoryService(redisTemplate); - -// 启动服务 -sessionHistoryService.start().get(); - -try { - // 使用服务... - Session session = sessionHistoryService.createSession("userId", Optional.empty()).get(); -} finally { - sessionHistoryService.stop().get(); -} -``` - -**实现细节:** -- 使用Redis Hash存储会话数据 -- Key格式:`session:{userId}:{sessionId}` -- 使用Redis Set维护用户会话索引:`session_index:{userId}` -- 支持JSON序列化/反序列化 - -### 实现3:TableStoreSessionHistoryService - -**特点:** -- 使用阿里云表格存储(TableStore) -- 支持海量数据存储 -- 适用于生产环境和大规模部署 -- 需要配置阿里云TableStore客户端 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.session.TableStoreSessionHistoryService; -import com.alicloud.openservices.tablestore.SyncClient; -import com.aliyun.openservices.tablestore.agent.util.Pair; -import com.aliyun.openservices.tablestore.agent.model.MetaType; - -// 配置TableStore客户端 -String endpoint = "https://your-instance.cn-hangzhou.ots.aliyuncs.com"; -String accessKeyId = "your-access-key-id"; -String accessKeySecret = "your-access-key-secret"; -String instanceName = "your-instance-name"; - -SyncClient client = new SyncClient(endpoint, accessKeyId, accessKeySecret, instanceName); - -// 创建服务实例(使用默认表名) -SessionHistoryService sessionHistoryService = new TableStoreSessionHistoryService(client); - -// 或者使用自定义表名和索引 -String sessionTableName = "custom_session_table"; -String messageTableName = "custom_message_table"; -String sessionSecondaryIndexName = "custom_session_index"; -String messageSecondaryIndexName = "custom_message_index"; -List> sessionSecondaryIndexMeta = Collections.emptyList(); - -SessionHistoryService customService = new TableStoreSessionHistoryService( - client, - sessionTableName, - messageTableName, - sessionSecondaryIndexName, - messageSecondaryIndexName, - sessionSecondaryIndexMeta -); - -// 启动服务 -sessionHistoryService.start().get(); - -try { - // 使用服务... - Session session = sessionHistoryService.createSession("userId", Optional.empty()).get(); -} finally { - sessionHistoryService.stop().get(); -} -``` - -**实现细节:** -- 使用TableStore MemoryStore API -- 默认表名:`agentscope_runtime_session` 和 `agentscope_runtime_message` -- 支持二级索引加速查询 -- 自动处理表的创建和初始化 - -### 会话对象结构 - -每个会话由 `Session` 对象表示: - -```java -import io.agentscope.runtime.engine.schemas.context.Session; -import io.agentscope.runtime.engine.schemas.message.MessageType; -import java.util.ArrayList; -import java.util.List; - -// 创建会话对象 -List userContent = new ArrayList<>(); -userContent.add(new MessageContent("text", "Hello")); - -List assistantContent = new ArrayList<>(); -assistantContent.add(new MessageContent("text", "Hi there!")); - -List messages = new ArrayList<>(); -messages.add(new Message(MessageType.USER, userContent)); -messages.add(new Message(MessageType.ASSISTANT, assistantContent)); - -Session session = new Session("session_123", "user_456", messages); - -System.out.println("Session ID: " + session.getId()); -System.out.println("User ID: " + session.getUserId()); -System.out.println("Message count: " + session.getMessages().size()); -``` - -### 核心功能示例 - -#### 创建会话 - -```java -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.schemas.context.Session; -import java.util.Optional; - -InMemorySessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); -sessionHistoryService.start().get(); - -try { - String userId = "test_user"; - - // 创建带自动生成ID的会话 - Session session = sessionHistoryService.createSession(userId, Optional.empty()).get(); - System.out.println("Created session: " + session.getId()); - - // 创建带自定义ID的会话 - Session customSession = sessionHistoryService.createSession( - userId, - Optional.of("my_custom_session_id") - ).get(); - System.out.println("Custom session ID: " + customSession.getId()); -} finally { - sessionHistoryService.stop().get(); -} -``` - -#### 检索会话 - -```java -try { - String userId = "u1"; - String sessionId = "s1"; - - // 检索现有会话 - Optional retrievedSessionOpt = sessionHistoryService.getSession(userId, sessionId).get(); - if (retrievedSessionOpt.isPresent()) { - Session retrievedSession = retrievedSessionOpt.get(); - System.out.println("Session found: " + retrievedSession.getId()); - } else { - System.out.println("Session not found"); - } -} finally { - sessionHistoryService.stop().get(); -} -``` - -#### 列出会话 - -```java -try { - String userId = "u_list"; - - // 创建多个会话 - Session session1 = sessionHistoryService.createSession(userId, Optional.empty()).get(); - Session session2 = sessionHistoryService.createSession(userId, Optional.empty()).get(); - - // 列出所有会话 - List listedSessions = sessionHistoryService.listSessions(userId).get(); - System.out.println("Total sessions: " + listedSessions.size()); - - for (Session s : listedSessions) { - System.out.println("Session ID: " + s.getId()); - } -} finally { - sessionHistoryService.stop().get(); -} -``` - -#### 添加消息 - -```java -import io.agentscope.runtime.engine.schemas.message.MessageType; -import java.util.ArrayList; -import java.util.List; - -try { - String userId = "u_append"; - Session session = sessionHistoryService.createSession(userId, Optional.empty()).get(); - - // 添加单个消息 - List userContent = new ArrayList<>(); - userContent.add(new MessageContent("text", "Hello, world!")); - Message message1 = new Message(MessageType.USER, userContent); - - List messages = new ArrayList<>(); - messages.add(message1); - sessionHistoryService.appendMessage(session, messages).get(); - - // 一次添加多个消息 - List userContent2 = new ArrayList<>(); - userContent2.add(new MessageContent("text", "How are you?")); - Message message2 = new Message(MessageType.USER, userContent2); - - List assistantContent = new ArrayList<>(); - assistantContent.add(new MessageContent("text", "I am fine, thank you.")); - Message message3 = new Message(MessageType.ASSISTANT, assistantContent); - - List moreMessages = new ArrayList<>(); - moreMessages.add(message2); - moreMessages.add(message3); - sessionHistoryService.appendMessage(session, moreMessages).get(); - - // 验证消息已添加 - Optional updatedSession = sessionHistoryService.getSession(userId, session.getId()).get(); - System.out.println("Total messages: " + updatedSession.get().getMessages().size()); -} finally { - sessionHistoryService.stop().get(); -} -``` - -#### 删除会话 - -```java -try { - String userId = "u_delete"; - Session sessionToDelete = sessionHistoryService.createSession(userId, Optional.empty()).get(); - String sessionId = sessionToDelete.getId(); - - // 删除会话 - sessionHistoryService.deleteSession(userId, sessionId).get(); - System.out.println("Session deleted: " + sessionId); -} finally { - sessionHistoryService.stop().get(); -} -``` - ---- - -## MemoryService(记忆服务) - -### 接口定义 - -`MemoryService` 是管理记忆的接口。在Agent中,记忆存储终端用户之前的对话信息,可以跨会话查询和使用。 - -```java -import io.agentscope.runtime.engine.memory.service.MemoryService; - -public interface MemoryService extends Service { - CompletableFuture addMemory(String userId, List messages, Optional sessionId); - CompletableFuture> searchMemory(String userId, List messages, Optional> filters); - CompletableFuture deleteMemory(String userId, Optional sessionId); - CompletableFuture> listMemory(String userId, Optional> filters); - CompletableFuture> getAllUsers(); -} -``` - -### 实现1:InMemoryMemoryService - -**特点:** -- 数据存储在内存中的 `ConcurrentHashMap` -- 简单的关键词搜索(基于文本匹配) -- 线程安全 -- 服务重启后数据丢失 -- 适用于开发、测试和小规模部署 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.schemas.message.MessageType; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -// 创建服务实例 -MemoryService memoryService = new InMemoryMemoryService(); - -// 启动服务 -memoryService.start().get(); - -try { - String userId = "user1"; - - // 添加记忆 - List content = new ArrayList<>(); - content.add(new MessageContent("text", "My name is Alice")); - Message message = new Message(MessageType.USER, content); - - List messages = new ArrayList<>(); - messages.add(message); - memoryService.addMemory(userId, messages, Optional.empty()).get(); - - // 搜索记忆 - List queryContent = new ArrayList<>(); - queryContent.add(new MessageContent("text", "name")); - Message queryMessage = new Message(MessageType.USER, queryContent); - - List searchQuery = new ArrayList<>(); - searchQuery.add(queryMessage); - - Map filters = new HashMap<>(); - filters.put("top_k", 5); - List retrieved = memoryService.searchMemory(userId, searchQuery, Optional.of(filters)).get(); - System.out.println("Retrieved " + retrieved.size() + " messages"); -} finally { - memoryService.stop().get(); -} -``` - -**实现细节:** -- 数据结构:`Map>>` (user_id -> session_id -> messages) -- 未指定会话时使用默认会话ID ("default_session") -- 基于关键词的搜索不区分大小写 -- 消息在每个会话中按时间顺序存储 -- 使用ConcurrentHashMap保证线程安全 - -### 实现2:RedisMemoryService - -**特点:** -- 数据持久化到Redis -- 支持多实例共享数据 -- 简单的关键词搜索 -- 适用于生产环境和分布式部署 -- 需要配置Redis连接 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.RedisMemoryService; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.connection.RedisConnectionFactory; -import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; -import org.springframework.data.redis.core.StringRedisTemplate; - -// 配置Redis连接 -RedisConnectionFactory connectionFactory = new LettuceConnectionFactory("localhost", 6379); -connectionFactory.afterPropertiesSet(); - -RedisTemplate redisTemplate = new StringRedisTemplate(connectionFactory); -redisTemplate.afterPropertiesSet(); - -// 创建服务实例 -MemoryService memoryService = new RedisMemoryService(redisTemplate); - -// 启动服务 -memoryService.start().get(); - -try { - // 使用服务... - String userId = "user1"; - List messages = new ArrayList<>(); - memoryService.addMemory(userId, messages, Optional.empty()).get(); -} finally { - memoryService.stop().get(); -} -``` - -**实现细节:** -- 使用Redis Hash存储记忆数据 -- Key格式:`user_memory:{userId}` -- 使用JSON序列化/反序列化消息 -- 支持健康检查(通过Redis PING命令) - -### 实现3:TableStoreMemoryService - -**特点:** -- 使用阿里云表格存储(TableStore)KnowledgeStore -- 支持向量搜索和语义搜索 -- 支持海量数据存储 -- 适用于生产环境和大规模部署 -- 需要配置阿里云TableStore客户端 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.TableStoreMemoryService; -import com.alicloud.openservices.tablestore.SyncClient; - -// 配置TableStore客户端 -String endpoint = "https://your-instance.cn-hangzhou.ots.aliyuncs.com"; -String accessKeyId = "your-access-key-id"; -String accessKeySecret = "your-access-key-secret"; -String instanceName = "your-instance-name"; - -SyncClient client = new SyncClient(endpoint, accessKeyId, accessKeySecret, instanceName); - -// 创建服务实例(使用默认表名和索引) -MemoryService memoryService = new TableStoreMemoryService(client); - -// 或者使用自定义表名和索引 -String tableName = "custom_memory_table"; -String searchIndexName = "custom_search_index"; -MemoryService customService = new TableStoreMemoryService(client, tableName, searchIndexName); - -// 启动服务 -memoryService.start().get(); - -try { - // 使用服务... - String userId = "user1"; - List messages = new ArrayList<>(); - memoryService.addMemory(userId, messages, Optional.empty()).get(); -} finally { - memoryService.stop().get(); -} -``` - -**实现细节:** -- 使用TableStore KnowledgeStore API -- 默认表名:`agentscope_runtime_memory` -- 默认搜索索引:`agentscope_runtime_knowledge_search_index` -- 支持向量嵌入和语义搜索 -- 自动处理表和索引的创建 - -### 实现4:Mem0MemoryService - -**特点:** -- 使用Mem0云服务API -- 提供高级记忆管理和搜索能力 -- 支持向量搜索和语义理解 -- 适用于生产环境,需要高级记忆功能 -- 需要Mem0 API密钥 - -**使用示例:** - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.Mem0MemoryService; - -// 创建服务实例(需要API密钥) -String apiKey = System.getenv("MEM0_API_KEY"); -MemoryService memoryService = new Mem0MemoryService(apiKey); - -// 或者指定组织ID和项目ID -String orgId = "your-org-id"; -String projectId = "your-project-id"; -MemoryService memoryServiceWithIds = new Mem0MemoryService(apiKey, orgId, projectId); - -// 启动服务 -memoryService.start().get(); - -try { - // 使用服务... - String userId = "user1"; - List messages = new ArrayList<>(); - memoryService.addMemory(userId, messages, Optional.empty()).get(); - - // 搜索记忆 - List searchQuery = new ArrayList<>(); - Map filters = new HashMap<>(); - filters.put("top_k", 5); - List retrieved = memoryService.searchMemory(userId, searchQuery, Optional.of(filters)).get(); -} finally { - memoryService.stop().get(); -} -``` - -**实现细节:** -- 使用Mem0 HTTP API (https://api.mem0.ai) -- 支持Mem0 v1和v2 API -- 自动处理HTTP请求和响应 -- 支持组织级别和项目级别的记忆管理 -- 需要有效的Mem0 API密钥 - -### 核心功能示例 - -#### 添加记忆 - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.model.Message; -import io.agentscope.runtime.engine.memory.model.MessageContent; -import io.agentscope.runtime.engine.schemas.message.MessageType; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -InMemoryMemoryService memoryService = new InMemoryMemoryService(); -memoryService.start().get(); - -try { - String userId = "user1"; - - // 不带会话ID添加记忆 - List content = new ArrayList<>(); - content.add(new MessageContent("text", "My favorite color is blue")); - Message message = new Message(MessageType.USER, content); - - List messages = new ArrayList<>(); - messages.add(message); - memoryService.addMemory(userId, messages, Optional.empty()).get(); - - // 带会话ID添加记忆 - memoryService.addMemory(userId, messages, Optional.of("session1")).get(); -} finally { - memoryService.stop().get(); -} -``` - -#### 搜索记忆 - -```java -try { - String userId = "user1"; - - // 创建搜索查询 - List queryContent = new ArrayList<>(); - queryContent.add(new MessageContent("text", "favorite color")); - Message queryMessage = new Message(MessageType.USER, queryContent); - - List searchQuery = new ArrayList<>(); - searchQuery.add(queryMessage); - - // 搜索记忆(可以传入过滤器,如top_k) - Map filters = new HashMap<>(); - filters.put("top_k", 5); - List retrieved = memoryService.searchMemory(userId, searchQuery, Optional.of(filters)).get(); - - System.out.println("Retrieved " + retrieved.size() + " messages"); - for (Message msg : retrieved) { - System.out.println("Message: " + msg.getContent().get(0).getText()); - } -} finally { - memoryService.stop().get(); -} -``` - -#### 列出记忆 - -```java -try { - String userId = "user1"; - - // 列出记忆(带分页) - Map filters = new HashMap<>(); - filters.put("page_size", 10); - filters.put("page_num", 1); - List memoryList = memoryService.listMemory(userId, Optional.of(filters)).get(); - - System.out.println("Listed " + memoryList.size() + " memory items"); -} finally { - memoryService.stop().get(); -} -``` - -#### 删除记忆 - -```java -try { - String userId = "user1"; - String sessionId = "session1"; - - // 删除特定会话的记忆 - memoryService.deleteMemory(userId, Optional.of(sessionId)).get(); - - // 删除用户的所有记忆 - memoryService.deleteMemory(userId, Optional.empty()).get(); -} finally { - memoryService.stop().get(); -} -``` - -#### 获取所有用户 - -```java -try { - List allUsers = memoryService.getAllUsers().get(); - System.out.println("Total users: " + allUsers.size()); - for (String userId : allUsers) { - System.out.println("User: " + userId); - } -} finally { - memoryService.stop().get(); -} -``` - ---- - -## ContextManager(上下文管理器) - -### 概述 - -`ContextManager` 继承自 `ServiceManager`,用于管理会话历史服务和记忆服务的生命周期,并提供上下文组合功能。 - -### 创建 ContextManager - -可以通过多种方式创建 `ContextManager`: - -```java -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.memory.context.ContextManagerFactory; -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; - -// 方式1:使用默认构造函数(使用内存实现) -ContextManager contextManager1 = new ContextManager(); - -// 方式2:指定服务实现 -SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); -MemoryService memoryService = new InMemoryMemoryService(); -ContextManager contextManager2 = new ContextManager( - ContextComposer.class, - sessionHistoryService, - memoryService -); - -// 方式3:使用 ContextManagerFactory(推荐) -ContextManager defaultManager = ContextManagerFactory.createDefault(); - -// 创建自定义的上下文管理器 -ContextManager customManager = ContextManagerFactory.createCustom( - memoryService, - sessionHistoryService -); -``` - -### 使用 ContextManager - -```java -import io.agentscope.runtime.engine.memory.model.Message; -import io.agentscope.runtime.engine.schemas.context.Session; -import java.util.ArrayList; -import java.util.List; - -// 启动服务 -contextManager.start().get(); - -try { - // 获取服务 - SessionHistoryService sessionService = contextManager.getSessionHistoryService(); - MemoryService memoryService = contextManager.getMemoryService(); - - // 或者通过服务名称获取 - SessionHistoryService session = (SessionHistoryService) contextManager.getService("session"); - MemoryService memory = (MemoryService) contextManager.getService("memory"); - - // 组合会话 - Session session = contextManager.composeSession("userId", "sessionId").get(); - - // 组合上下文 - List requestInput = new ArrayList<>(); - contextManager.composeContext(session, requestInput).get(); - - // 追加消息 - List eventOutput = new ArrayList<>(); - contextManager.append(session, eventOutput).get(); - -} finally { - // 停止服务 - contextManager.stop().get(); -} -``` - -### ContextComposer - -`ContextComposer` 是用于组合上下文的类。它将在上下文管理器创建上下文时被调用。 - -**功能:** -- 按顺序向 `SessionHistoryService` 和 `MemoryService` 更新智能体产生的消息 -- 在向 Agent 输入消息之前进行搜索和拼接,构建输入上下文 -- 从记忆服务中检索相关记忆并添加到会话中 - -**使用方式:** - -```java -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.schemas.context.Session; -import io.agentscope.runtime.engine.memory.model.Message; -import java.util.List; -import java.util.Optional; - -// ContextComposer.compose 方法 -ContextComposer.compose( - requestInput, // 当前输入消息 - session, // 会话对象 - Optional.ofNullable(memoryService), // 记忆服务(可选) - Optional.ofNullable(sessionHistoryService) // 会话历史服务(可选) -).get(); -``` - ---- - -## RAGService - -`RAGService` 是一个接口,用于提供检索增强生成(RAG)功能。当最终用户提出请求时,代理会从知识库中检索相关信息。知识库可以是数据库或文档集合。 - -**接口方法:** -- `retrieve`:从知识库中检索相关信息 - -**注意:** 目前Java版本暂不支持RAGService,相关功能正在开发中。如需使用RAG功能,请参考Python版本的文档。 - ---- - -## 服务生命周期管理 - -所有服务都遵循标准的生命周期模式: - -```java -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import java.util.concurrent.CompletableFuture; - -InMemoryMemoryService memoryService = new InMemoryMemoryService(); - -try { - // 启动服务 - memoryService.start().get(); - - // 检查服务健康状态 - Boolean isHealthy = memoryService.health().get(); - System.out.println("Service health status: " + isHealthy); - - // 使用服务... - -} catch (Exception e) { - e.printStackTrace(); -} finally { - // 停止服务 - memoryService.stop().get(); -} -``` - -### 通过 ContextManager 管理生命周期 - -使用 `ContextManager` 时,服务生命周期会自动管理: - -```java -import io.agentscope.runtime.engine.memory.context.ContextManagerFactory; -import io.agentscope.runtime.engine.memory.context.ContextManager; -import java.util.Map; - -ContextManager contextManager = ContextManagerFactory.createDefault(); - -try { - // 启动服务(会自动启动记忆服务和会话历史服务) - contextManager.start().get(); - - // 检查服务健康状态 - Map healthStatus = contextManager.healthCheck().get(); - System.out.println("Memory service health: " + healthStatus.get("memory")); - System.out.println("Session service health: " + healthStatus.get("session")); - - // 使用服务... - -} catch (Exception e) { - e.printStackTrace(); -} finally { - // 退出时,服务自动停止并清理 - contextManager.stop().get(); -} -``` - ---- - -## 选择指南 - -### 开发/测试环境 -- **SessionHistoryService**: `InMemorySessionHistoryService` -- **MemoryService**: `InMemoryMemoryService` - -### 生产环境(中小规模) -- **SessionHistoryService**: `RedisSessionHistoryService` -- **MemoryService**: `RedisMemoryService` - -### 生产环境(大规模,阿里云) -- **SessionHistoryService**: `TableStoreSessionHistoryService` -- **MemoryService**: `TableStoreMemoryService` - -### 生产环境(需要高级记忆管理) -- **SessionHistoryService**: `RedisSessionHistoryService` 或 `TableStoreSessionHistoryService` -- **MemoryService**: `Mem0MemoryService` - -### 自定义实现 - -如果需要自定义实现,可以实现相应的接口: - -```java -// 实现 SessionHistoryService -public class CustomSessionHistoryService implements SessionHistoryService { - // 实现接口方法... -} - -// 实现 MemoryService -public class CustomMemoryService implements MemoryService { - // 实现接口方法... -} -``` - -然后在使用时传入自定义实现: - -```java -ContextManager contextManager = new ContextManager( - ContextComposer.class, - new CustomSessionHistoryService(), - new CustomMemoryService() -); -``` diff --git a/cookbook/zh/contribute.md b/cookbook/zh/contribute.md index f30424ac..a2cd02e7 100644 --- a/cookbook/zh/contribute.md +++ b/cookbook/zh/contribute.md @@ -6,11 +6,11 @@ AgentScope Runtime Java 是一个专注于智能体部署和安全工具执行 ## 社区 -- 加入我们的钉钉群: +参与 AgentScope Runtime Java 项目的第一步是加入我们的讨论,通过不同的沟通渠道与我们联系。以下是与我们建立联系的几种方式: - | DingTalk | - | ------------------------------------------------------------ | - | | +- **GitHub Discussions**: 提问和分享经验(请使用**英语**) +- **Discord**: 加入我们的 [Discord频道](https://discord.gg/eYMpfnkG8h) 进行实时讨论 +- **DingTalk**: 中文用户可以加入我们的 [钉钉群](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) ## 报告问题 @@ -22,12 +22,13 @@ AgentScope Runtime Java 是一个专注于智能体部署和安全工具执行 - 清晰的问题描述 - 重现步骤 - 代码/错误信息 -- 环境详情(操作系统、Java 依赖详情) -- 受影响的组件(例如Engine模块、Sandbox模块 或两者) + - 环境详情(操作系统、JDK 版本) + +- 受影响的组件(例如 Engine 模块、Sandbox 模块等) ### 安全问题 -如果您在 AgentScope Runtime Java中发现安全问题,请通过 [阿里巴巴安全响应中心(ASRC)](https://security.alibaba.com/)向我们报告。 +如果您在 AgentScope Runtime Java 中发现安全问题,请通过 [阿里巴巴安全响应中心(ASRC)](https://security.alibaba.com/)向我们报告。 ## 功能需求 @@ -37,17 +38,13 @@ AgentScope Runtime Java 是一个专注于智能体部署和安全工具执行 - 应该如何工作 - 安全考虑(如果适用) -## 改进文档 - -请参见 {doc}`README` - ## 贡献代码 -如果您想为 AgentScope Runtime 贡献新功能或bug 修复,请首先在 GitHub 问题中讨论您的想法。如果没有相关问题,请创建一个。可能已经有人在处理它,或者它可能有特殊的复杂性(特别是Sandbox 功能的安全考虑),您在开始编码之前应该了解这些。 +如果您想为 AgentScope Runtime Java 贡献新功能或bug 修复,请首先在 GitHub 问题中讨论您的想法。如果没有相关问题,请创建一个。可能已经有人在处理它,或者它可能有特殊的复杂性(特别是 Sandbox 功能的安全考虑),您在开始编码之前应该了解这些。 ### Fork 和创建分支 -Fork AgentScope Runtime Java 主分支代码并将其克隆到本地机器。有关帮助,请参见 GitHub 帮助页面。 +Fork [AgentScope Runtime Java 主分支代码](https://github.com/agentscope-ai/agentscope-runtime-java) 并将其克隆到本地机器。有关帮助,请参见 GitHub 帮助页面。 创建一个具有描述性名称的分支。 @@ -60,7 +57,7 @@ git checkout -b feature/your-feature-name - 编写清晰、注释良好的代码 - 遵循现有代码风格 - 为新功能/修复添加测试 -- 根据需要更新文档Test Your Changes +- 根据需要更新文档 Test Your Changes ### 测试您的更改 diff --git a/cookbook/zh/demohouse.md b/cookbook/zh/demohouse.md deleted file mode 100644 index 36519c89..00000000 --- a/cookbook/zh/demohouse.md +++ /dev/null @@ -1,208 +0,0 @@ -# Demo 展示厅 - -```{note} -在我们的 展示厅(Demo House) 中,您可以探索各种演示项目,展示如何使用 AgentScope Runtime Java 构建智能体应用。这些演示项目托管在[本仓库](https://github.com/agentscope-ai/agentscope-runtime-java)中 ,访问以查看AgentScope Runtime Java的功能 -``` - - - - - diff --git a/cookbook/new-zh/deployment.md b/cookbook/zh/deployment.md similarity index 100% rename from cookbook/new-zh/deployment.md rename to cookbook/zh/deployment.md diff --git a/cookbook/new-zh/deployment/advanced_deployment.md b/cookbook/zh/deployment/advanced_deployment.md similarity index 100% rename from cookbook/new-zh/deployment/advanced_deployment.md rename to cookbook/zh/deployment/advanced_deployment.md diff --git a/cookbook/new-zh/deployment/agent_app.md b/cookbook/zh/deployment/agent_app.md similarity index 100% rename from cookbook/new-zh/deployment/agent_app.md rename to cookbook/zh/deployment/agent_app.md diff --git a/cookbook/new-zh/deployment/react_agent.md b/cookbook/zh/deployment/react_agent.md similarity index 100% rename from cookbook/new-zh/deployment/react_agent.md rename to cookbook/zh/deployment/react_agent.md diff --git a/cookbook/zh/environment_manager.md b/cookbook/zh/environment_manager.md deleted file mode 100644 index cf2a1097..00000000 --- a/cookbook/zh/environment_manager.md +++ /dev/null @@ -1,311 +0,0 @@ -# 环境管理器(Environment Manager) - -## 概述 - -`EnvironmentManager` 通过 `SandboxManager` 提供沙箱化环境与工具的生命周期与访问能力。 - -默认实现 `DefaultEnvironmentManager` 会注入一个 `SandboxManager` 实例,用于管理环境的创建、连接与释放。 - -## 基础用法 - -```java -// 创建环境管理器(内部会创建 SandboxManager) -EnvironmentManager environmentManager = new DefaultEnvironmentManager(); - -// 获取沙盒管理器 -SandboxManager sandboxManager = environmentManager.getSandboxManager(); - -try { - // 创建沙盒(使用 try-with-resources 自动管理) - try (BaseSandbox sandbox = new BaseSandbox( - sandboxManager, - "u1", // userId - "s1", // sessionId - 300 // timeout in seconds - )) { - // 使用沙盒 - // ... - } // 沙盒自动释放 - -} catch (Exception e) { - e.printStackTrace(); -} finally { - // 清理所有沙盒 - sandboxManager.cleanupAllSandboxes(); -} -``` - -或者,如果您自己管理 `SandboxManager` 的生命周期: - -```java -// 创建并管理 SandboxManager -try (SandboxManager sandboxManager = new SandboxManager()) { - // 创建环境管理器,传入 SandboxManager - EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - - // 使用环境管理器 - try (BaseSandbox sandbox = new BaseSandbox( - sandboxManager, - "u1", - "s1", - 300 - )) { - // 使用沙盒 - // ... - } -} // SandboxManager 自动清理所有资源 -``` - -未来,`EnvironmentManager` 将不仅支持 `SandboxManager`,也会扩展到其它与环境交互的服务。 - -**沙盒管理器**旨在管理和提供对不同用户和会话的沙盒化工具执行(详见{doc}`sandbox`)沙盒的访问。沙盒通过会话ID和用户ID的复合键进行组织,为每个用户会话提供隔离的执行上下文。该服务支持多种沙盒类型,包括 BASE、BROWSER、FILESYSTEM、PYTHON 等。 - -## 沙盒管理器概述 - -沙盒管理器为沙盒管理提供统一接口,支持不同的沙盒类型,如代码执行、文件操作和其他专用沙盒。以下是初始化沙盒管理器的示例: - -```java -// 创建默认沙盒管理器 -SandboxManager sandboxManager = new SandboxManager(); - -// 或者使用自定义配置 -ManagerConfig config = ManagerConfig.builder() - .poolSize(10) - .build(); -SandboxManager sandboxManager = new SandboxManager(config); - -// 或者使用远程沙盒服务 -// ManagerConfig config = ManagerConfig.builder() -// .poolSize(10) -// .baseUrl("remote_url") -// .bearerToken("bearer_token") -// .build(); -// SandboxManager sandboxManager = new SandboxManager(config); -``` - -### 核心功能 - -#### 创建沙盒 - -在 Java 中,沙盒通过 `Sandbox` 类的构造函数创建。沙盒管理器会自动从池中获取或创建容器: - -```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.container.SandboxType; -import io.agentscope.runtime.sandbox.box.BaseSandbox; - -SandboxManager sandboxManager = new SandboxManager(); -String sessionId = "session1"; -String userId = "user1"; - -// 创建基础沙盒 -BaseSandbox baseSandbox = new BaseSandbox( - sandboxManager, - userId, - sessionId, - 300 -) -``` - -#### 使用不同类型的沙盒 - -Java 版本支持多种沙盒类型。每种沙盒类型都有对应的实现类: - -```java -// 创建基础沙盒 -BaseSandbox baseSandbox = new BaseSandbox( - sandboxManager, - userId, - sessionId, - 300 -); - -// 创建浏览器沙盒 -BrowserSandbox browserSandbox = new BrowserSandbox( - sandboxManager, - userId, - sessionId, - 300 -); - -// 创建文件系统沙盒 -FilesystemSandbox filesystemSandbox = new FilesystemSandbox( - sandboxManager, - userId, - sessionId, - 300 -); - -// 创建训练沙盒 -TrainingSandbox trainingSandbox = new TrainingSandbox( - sandboxManager, - userId, - sessionId, - SandboxType.TRAINING, - 300 -); -``` - -#### 沙盒重用 - -沙盒管理器高效地为同一用户会话和沙盒类型重用现有沙盒: - -```java -// 第一次创建 -BaseSandbox sandbox1 = new BaseSandbox( - sandboxManager, - userId, - sessionId, - SandboxType.BASE, - 300 -); - -// 第二次创建相同类型的沙盒会重用现有容器 -BaseSandbox sandbox2 = new BaseSandbox( - sandboxManager, - userId, - sessionId, - SandboxType.BASE, - 300 -); - -// sandbox1 和 sandbox2 使用相同的容器实例 -``` - -#### 使用 try-with-resources 自动释放 - -Java 的 `Sandbox` 类实现了 `AutoCloseable` 接口,可以使用 try-with-resources 自动释放: - -```java -try (BaseSandbox sandbox = new BaseSandbox( - sandboxManager, - userId, - sessionId, - SandboxType.BASE, - 300 -)) { - // 使用沙盒 - // ... -} // 自动释放沙盒 -``` - -#### 手动释放沙盒 - -您也可以手动释放沙盒: - -```java -// 方式1:调用 release() 方法 -sandbox.release(); - -// 方式2:通过 SandboxManager 释放 -sandboxManager.releaseSandbox(SandboxType.BASE, userId, sessionId); - -// 方式3:清理所有沙盒 -sandboxManager.cleanupAllSandboxes(); -``` - -### 服务生命周期 - -`SandboxManager` 实现了 `AutoCloseable` 接口,可以使用 try-with-resources 自动管理资源: - -```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; - -// 使用 try-with-resources 自动管理生命周期 -try (SandboxManager sandboxManager = new SandboxManager()) { - // 沙盒管理器在创建时自动初始化 - - // 使用沙盒管理器 - // ... - -} // 自动清理所有沙盒并关闭资源 -``` - -或者手动管理生命周期: - -```java -SandboxManager sandboxManager = new SandboxManager(); - -try { - // 使用沙盒管理器 - // ... -} catch (Exception e) { - e.printStackTrace(); -} finally { - // 手动清理所有沙盒 - sandboxManager.cleanupAllSandboxes(); - - // 关闭沙盒管理器(会自动清理所有资源) - sandboxManager.close(); -} -``` - -### 环境管理器方法 - -`EnvironmentManager` 接口提供了以下方法: - -```java -EnvironmentManager envManager = new DefaultEnvironmentManager(); - -// 获取沙盒管理器 -SandboxManager sandboxManager = envManager.getSandboxManager(); - -// 获取环境变量 -String value = envManager.getEnvironmentVariable("KEY"); - -// 设置环境变量 -envManager.setEnvironmentVariable("KEY", "VALUE"); - -// 获取所有环境变量 -Map allVars = envManager.getAllEnvironmentVariables(); - -// 检查环境是否可用 -boolean available = envManager.isEnvironmentAvailable(); - -// 初始化环境 -CompletableFuture initFuture = envManager.initializeEnvironment(); -initFuture.get(); // 等待初始化完成 - -// 获取环境信息 -Map envInfo = envManager.getEnvironmentInfo(); - -// 清理环境 -CompletableFuture cleanupFuture = envManager.cleanupEnvironment(); -cleanupFuture.get(); // 等待清理完成 -``` - -### 支持的沙盒类型 - -Java 版本支持以下沙盒类型,每种类型都有对应的实现类: - -| 沙盒类型 | 实现类 | 说明 | -|---------|--------|------| -| `BASE` | `BaseSandbox` | 基础沙盒,提供基本的执行环境 | -| `BROWSER` | `BrowserSandbox` | 浏览器沙盒,支持浏览器自动化 | -| `FILESYSTEM` | `FilesystemSandbox` | 文件系统沙盒,提供文件操作能力 | -| `GUI` | `GuiSandbox` | GUI 沙盒,支持图形界面操作 | -| `TRAINING` | `TrainingSandbox` | 训练沙盒,用于训练场景 | -| `APPWORLD` | `APPWorldSandbox` | 应用世界沙盒,扩展自 TrainingSandbox | -| `BFCL` | `BFCLSandbox` | BFCL 沙盒,扩展自 TrainingSandbox | -| `WEBSHOP` | `WebShopSandbox` | 电商沙盒,扩展自 TrainingSandbox | - -其他沙盒类型(如 `PYTHON`、`NODE`、`JAVA`)可以通过 `BaseSandbox` 使用相应的 `SandboxType` 来创建。 - -### 配置沙盒管理器 - -您可以使用 `ManagerConfig` 来自定义沙盒管理器的行为: - -```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; - -ManagerConfig config = ManagerConfig.builder() - .poolSize(10) // 容器池大小 - .portRange(new int[]{8000, 9000}) // 端口范围 - .redisConfig(redisConfig) // 是否启用redis管理沙箱 - .containerDeployment(clientConfig) // 容器的部署介质(Docker、K8s、Agentrun) - .build(); - -SandboxManager sandboxManager = new SandboxManager(config); -``` diff --git a/cookbook/zh/install.md b/cookbook/zh/install.md index a4ddcd33..80f395d6 100644 --- a/cookbook/zh/install.md +++ b/cookbook/zh/install.md @@ -10,15 +10,13 @@ ## 安装方式 -### 1. 通过 Maven Central 安装(推荐) +### 通过 Maven Central 安装(推荐) AgentScope Runtime Java 已经发布到 Maven Central,您可以直接通过 Maven 依赖使用。 -```{note} -当前稳定版本:0.1.1 - -您可以在 [Maven Central](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) 上查找和下载所有模块。 -``` +> 当前稳定版本:1.0.0 +> +> 您可以在 [Maven Central](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) 上查找和下载所有模块。 在您的 `pom.xml` 中添加相应的依赖即可使用: @@ -30,7 +28,7 @@ AgentScope Runtime Java 已经发布到 Maven Central,您可以直接通过 Ma io.agentscope agentscope-runtime-core - 0.1.1 + 1.0.0 ``` @@ -42,124 +40,65 @@ AgentScope Runtime Java 已经发布到 Maven Central,您可以直接通过 Ma io.agentscope agentscope-runtime-agentscope - 0.1.1 + 1.0.0 ``` -#### Spring-AI-Alibaba Agent 支持 +#### 一键部署 (Web) -如果需要使用 Spring AI Alibaba Agent (SAA): +如果需要使用一键部署功能: ```xml io.agentscope - agentscope-runtime-saa - 0.1.1 + agentscope-runtime-web + 1.0.0 ``` -#### 一键部署 (Web) +#### 协议集成 -如果需要使用一键部署功能: +如果需要使用 A2A (Agent-to-Agent) 协议: ```xml io.agentscope - agentscope-runtime-web - 0.1.1 + spring-boot-starter-runtime-a2a + 1.0.0 ``` -#### A2A 集成 +#### 自动化部署 -如果需要使用 A2A (Agent-to-Agent) 协议: +如果想要自动将 Agent 应用打包为容器,并自动部署到 K8s 或 AgentRun 上,可以使用提供的插件: ```xml - + io.agentscope - spring-boot-starter-runtime-a2a - 0.1.1 - + deployer-maven-plugin + 1.0.0 + + deployer.yml + 8080 + + ``` -### 2. 从源码安装(可选) +### (可选)从源码安装 -如果您想要使用最新的开发版本、测试新功能或为项目做贡献,可以从源码安装: +如果您想要使用最新的开发版本或为项目做贡献,可以从源码安装: ```bash git clone https://github.com/agentscope-ai/agentscope-runtime-java.git cd agentscope-runtime-java -mvn clean install -DskipTests +mvn clean install -Dskiptests ``` 安装完成后,依赖项将安装在本地 Maven 仓库中,您可以在项目中使用它们。 -```{note} -从源码安装会使用 SNAPSHOT 版本,适合开发和测试场景。生产环境建议使用 Maven Central 上的稳定版本。 -``` - -## 检查您的安装 - -要验证安装,您可以检查 Maven 依赖是否成功下载,或者尝试编译一个简单的 Java 类。 - -### 检查核心运行时 - -创建一个简单的 Java 类来测试核心运行时: - -```java -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextManagerFactory; - -public class InstallCheck { - public static void main(String[] args) { - try { - ContextManager manager = ContextManagerFactory.createDefault(); - System.out.println("✅ agentscope-runtime-core - 安装成功"); - } catch (Exception e) { - System.out.println("❌ agentscope-runtime-core - 安装失败: " + e.getMessage()); - System.out.println("💡 请确保已正确添加依赖到 pom.xml"); - } - } -} -``` - -### 检查 AgentScope Agent - -```java -import io.agentscope.runtime.engine.agents.agentscope.AgentScopeAgent; - -public class AgentScopeCheck { - public static void main(String[] args) { - try { - Class agentClass = AgentScopeAgent.class; - System.out.println("✅ AgentScopeAgent - 导入成功: " + agentClass.getName()); - } catch (NoClassDefFoundError e) { - System.out.println("❌ AgentScopeAgent - 导入失败: " + e.getMessage()); - System.out.println("💡 请确保已添加 agentscope-runtime-agentscope 依赖"); - } - } -} -``` - -### 检查 Spring-AI-Alibaba Agent - -```java -import io.agentscope.runtime.engine.agents.saa.SaaAgent; - -public class SaaAgentCheck { - public static void main(String[] args) { - try { - Class agentClass = SaaAgent.class; - System.out.println("✅ SaaAgent - 导入成功: " + agentClass.getName()); - } catch (NoClassDefFoundError e) { - System.out.println("❌ SaaAgent - 导入失败: " + e.getMessage()); - System.out.println("💡 请确保已添加 agentscope-runtime-saa 依赖"); - } - } -} -``` +> 从源码安装会使用 SNAPSHOT 版本,适合开发和测试场景。生产环境建议使用 Maven Central 上的稳定版本。 ### 使用 Maven 检查依赖 @@ -171,92 +110,22 @@ mvn dependency:tree | grep agentscope 这将显示所有与 agentscope 相关的依赖及其版本。 -### 编译和运行检查代码 - -要运行上面的检查代码,您需要: - -1. 创建一个 Maven 项目(如果还没有) -2. 将检查代码保存为 Java 文件 -3. 在项目根目录运行: - -```bash -# 编译项目 -mvn compile - -# 运行检查类(例如 InstallCheck) -mvn exec:java -Dexec.mainClass="InstallCheck" -``` - -或者使用 IDE(如 IntelliJ IDEA 或 Eclipse)直接运行 Java 类。 ## 安装选项说明 -这个图展示了安装选项的层次结构,从底层核心运行时(agentscope-runtime-core)开始——其中 **包含 Agent 运行框架 和 Sandbox 依赖**。可选模块(例如 saa、agentscope、web、a2a-starter等)堆叠在核心之上,每个模块都增加了特定的功能(如多Agent框架支持、自动化),并需要相应的依赖项。查看所有安装选项的详细信息,请参见项目的 [pom.xml](https://github.com/agentscope-ai/agentscope-runtime-java/blob/main/pom.xml)。 - -| **组件** | **Maven 坐标** | **用途** | **依赖项** | -| --------------------------- | ------------------------------------- | ------------------- | --------------------------------------------- | -| 核心运行时 | `io.agentscope:agentscope-runtime-core` | 核心运行环境 | 最小依赖,包括 Agent 运行框架 和 Sandbox 依赖 | -| Spring-AI-Alibaba Agent支持 | `io.agentscope:agentscope-runtime-saa` | SAA Agent 开发支持 | Spring AI Alibaba 框架 | -| AgentScope Agent 集成 | `io.agentscope:agentscope-runtime-agentscope` | AgentScope 开发支持 | AgentScope 框架 | -| 一键部署 | `io.agentscope:agentscope-runtime-web` | 一键对外部署 | SpringBoot 框架 | -| A2A 集成 | `io.agentscope:spring-boot-starter-runtime-a2a` | 引入A2A支持 | A2A SDK | - -### Maven 依赖示例 +这个图展示了安装选项的层次结构,从底层核心运行时(agentscope-runtime-core)开始——其中 **包含 Agent 运行框架 和 Sandbox 依赖**。可选模块(例如 agentscope、web、a2a-starter等)堆叠在核心之上,每个模块都增加了特定的功能(如多Agent框架支持、自动化)。查看所有安装选项的详细信息,请参见项目的 [pom.xml](https://github.com/agentscope-ai/agentscope-runtime-java/blob/main/pom.xml)。 -#### 最小化安装(仅核心运行时) - -```xml - - io.agentscope - agentscope-runtime-core - 0.1.1 - -``` - -#### 完整功能安装(包含所有模块) - -```xml - - - - io.agentscope - agentscope-runtime-core - 0.1.1 - - - - - io.agentscope - agentscope-runtime-agentscope - 0.1.1 - - - - - io.agentscope - agentscope-runtime-saa - 0.1.1 - - - - - io.agentscope - agentscope-runtime-web - 0.1.1 - - - - - io.agentscope - spring-boot-starter-runtime-a2a - 0.1.1 - - -``` +| **组件** | **Maven 坐标** | **用途** | +| --------------------- | ----------------------------------------------- | ------------------------------------------------------------ | +| 核心运行时 | `io.agentscope:agentscope-runtime-core` | 最小依赖,提供沙箱管理、记忆管理等基础运行时能力 | +| AgentScope Agent 集成 | `io.agentscope:agentscope-runtime-agentscope` | AgentScope 集成,支持原生 AgentScope Agent 到 Runtime Agent 的转换,并内置 Sandbox Tool 到 AgentScope Tool 的映射逻辑 | +| 一键启动 | `io.agentscope:agentscope-runtime-web` | 通过 LocalDeployer 实现 Agent 应用的一键启动与本地运行 | +| 协议集成 | `io.agentscope:spring-boot-starter-runtime-a2a` | 在用户构建好的 Spring Boot 应用中自动注册 A2A(Agent-to-Agent)通信端点及 Responses API 接口 | +| 自动化部署 | `deployer-maven-plugin` | 将 Agent 应用打包为一个容器,并可选部署到 K8s 或 AgentRun 上 | ## 版本信息 -- **当前稳定版本**:`0.1.1` +- **当前稳定版本**:`1.0.0` - **发布位置**:[Maven Central](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) - **GroupId**:`io.agentscope` @@ -266,6 +135,5 @@ mvn exec:java -Dexec.mainClass="InstallCheck" - [agentscope-runtime-core](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-core) - [agentscope-runtime-agentscope](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-agentscope) -- [agentscope-runtime-saa](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-saa) - [agentscope-runtime-web](https://central.sonatype.com/artifact/io.agentscope/agentscope-runtime-web) -- [spring-boot-starter-runtime-a2a](https://central.sonatype.com/artifact/io.agentscope/spring-boot-starter-runtime-a2a) +- [spring-boot-starter-runtime-a2a](https://central.sonatype.com/artifact/io.agentscope/spring-boot-starter-runtime-a2a) \ No newline at end of file diff --git a/cookbook/zh/intro.md b/cookbook/zh/intro.md index 0952ff0d..9b8d640e 100644 --- a/cookbook/zh/intro.md +++ b/cookbook/zh/intro.md @@ -10,29 +10,56 @@ [![MCP](https://img.shields.io/badge/MCP-Model_Context_Protocol-purple.svg?logo=plug&label=MCP)](https://modelcontextprotocol.io/) [![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) +## AgentScope Runtime V1.0 发布 + +AgentScope Runtime Java V1.0 在高效智能体部署与安全沙箱执行的坚实基础上,推出了 **统一的 “Agent 作为 API” 开发体验**,覆盖完整智能体从本地开发到生产部署的生命周期,并扩展了更多沙箱类型、协议兼容性与更丰富的内置工具集。 + +同时,智能体服务的接入方式从过去的 **黑盒化模块替换** 升级为 ***白盒化适配器模式*** —— 开发者可以在保留原有智能体框架接口与行为的前提下,将状态管理、会话记录、工具注册等运行时能力按需嵌入应用生命周期,实现更灵活的定制与跨框架无缝集成。 + +**V1.0 主要改进:** + +- **统一的开发/生产范式** —— 在开发环境与生产环境中 智能体功能性保持一致 +- **原生多智能体支持** —— 完全兼容 AgentScope Java 的多智能体范式 +- **主流 SDK 与协议集成** —— 支持 OpenAI Responses API SDK 与 Google A2A 协议 +- **可视化 Web UI** —— 部署后即可立即体验的开箱即用 Web 聊天界面 +- **扩展沙箱类型** —— GUI、浏览器、文件系统(大部分可通过 VNC 可视化) +- **更丰富的内置工具** —— 面向生产的搜索、RAG、AIGC、支付等模块 +- **灵活的部署模式** —— 本地线程/进程、Docker、Kubernetes、或托管云端 + +更详细的变更说明,以及迁移指南请参考:[CHANGELOG](CHANGELOG.md) + ## 什么是AgentScope Runtime Java? -**AgentScope Runtime Java** 是一个全面的智能体运行时框架,旨在解决两个关键挑战:**高效的智能体部署**和**沙箱工具执行**。它内置了上下文管理(长短期记忆、外部知识库)和安全沙箱基础设施,提供了一个框架无关的解决方案,可与流行的开源智能体框架和自定义实现配合使用。无论您需要大规模部署智能体还是确保安全的工具交互,AgentScope Runtime 都能提供具有完整可观测性和开发者友好部署的核心基础设施。 +**AgentScope Runtime Java** 是一个全面的智能体运行时框架,旨在解决两个关键挑战:**高效的智能体部署**和**沙箱执行**。它内置了基础服务(长短期记忆、智能体状态持久化)和安全沙箱基础设施。无论您需要大规模部署智能体还是确保安全的工具交互,AgentScope Runtime Java 都能提供具有完整可观测性和开发者友好部署的核心基础设施。 + +在 V1.0 中,这些运行时服务通过 **适配器模式** 对外开放,允许开发者在保留原有智能体框架接口与行为的基础上,将 AgentScope Java 的状态管理、会话记录、工具调用等模块按需嵌入到应用生命周期中。从过去的 “黑盒化替换” 变为 “白盒化集成”,开发者可以显式地控制服务初始化、工具注册与状态持久化流程,从而在不同框架间实现无缝整合,同时获得更高的扩展性与灵活性。 本指南将指导您使用 **AgentScope Runtime Java** 构建服务级的智能体应用程序。 -## 双核心架构 +## 核心架构 + +**⚙️ 智能体web应用部署 (Web)** + +提供`AgentApp`作为智能体应用主入口,同时配备部署、管理和监控智能体应用的生产级基础设施,并内置了会话历史、长期记忆以及智能体状态等服务。 + +**🔒 沙箱执行运行时 (Sandbox)** + +安全隔离的环境,让您的智能体能够安全地执行代码、控制浏览器、管理文件并集成MCP 工具——所有这些都不会危及您的系统安全。 -**⚙️ 智能体部署运行时 (Engine)** +**🛠️ 生产级工具服务 (Tool)** -用于部署、管理和运行智能体应用程序的基础设施,内置上下文管理(长短期记忆、外部知识库)和环境沙箱控制服务。 +基于可信第三方 API 能力(如搜索、RAG、AIGC、支付等),通过统一的 SDK 封装对外提供标准化调用接口,使智能体能够以一致的方式集成和使用这些服务,而无需关心底层 API 的差异与复杂性。 -**🛠️ 工具执行运行时 (Sandbox)** +**🔌 适配器模式 (Adapter)** -安全隔离的环境,让您的智能体能够安全地执行工具、控制浏览器、管理文件并集成MCP 工具- 所有这些都不会危及您的系统安全。 +将 Runtime 内的各类服务模块(状态管理、会话记录、工具执行等)适配到智能体框架的原生模块接口中,使开发者能够在保留原生行为的同时直接调用这些能力,实现无缝对接与灵活扩展。 ## 为什么选择 AgentScope Runtime Java? -- **🏗️ 部署基础设施**:内置会话管理、内存和沙箱环境控制服务 -- **🔒 沙箱工具执行**:隔离的沙箱确保工具安全执行,不会危及系统 -- **🔧框架无关**:不绑定特定框架,与流行的开源智能体框架和自定义实现无缝配合 +- 🤖 **AS原生运行时框架**:由 AgentScope 官方构建和维护,与其多智能体范式、适配器模式及工具使用深度集成,确保最佳兼容性与性能 +- **🏗️ 部署基础设施**:内置长短期记忆、智能体状态和沙箱环境控制服务 +- **🔒 沙箱执行**:隔离的沙箱确保工具安全执行,不会危及系统 - ⚡ **开发者友好**:简单部署,功能强大的自定义选项 - **📊 可观测性**:针对运行时操作的全面追踪和监控 -- **☕ Java 运行时优势**:依托成熟、高性能、高可靠性的 Java 生态,天然支持跨平台部署、企业级稳定性、丰富的诊断工具(JFR/JMX)以及强大的并发与内存管理能力,特别适合构建长期运行、高可用的智能体服务。 立即开始使用 AgentScope Runtime Java 部署你的智能体并尝试工具沙箱吧! diff --git a/cookbook/zh/manager.md b/cookbook/zh/manager.md deleted file mode 100644 index 9416832e..00000000 --- a/cookbook/zh/manager.md +++ /dev/null @@ -1,289 +0,0 @@ -# 管理器模块(Manager Module) - -该模块提供了一个统一的接口,用于注册、启动和停止多个服务(例如会话历史服务、记忆服务和沙箱服务),并具有自动生命周期管理功能。 - -## 概览 - -- **ServiceManager**:服务管理的抽象基类,提供通用的生命周期和访问API -- **ContextManager**:专注于上下文相关服务(如 `SessionHistoryService` 与 `MemoryService`),继承自 `ServiceManager` -- **EnvironmentManager**:专注于环境/工具相关能力(通过 `SandboxManager`),是一个接口而非继承自 `ServiceManager` - -### 服务接口要求 - -所有服务必须实现 `Service` 接口,该接口定义了三个核心方法: - -```java -import io.agentscope.runtime.engine.shared.Service; -import java.util.concurrent.CompletableFuture; - -public interface Service { - CompletableFuture start(); - CompletableFuture stop(); - CompletableFuture health(); -} -``` - -服务也可以通过继承 `ServiceWithLifecycleManager` 抽象类来实现,该类同时实现了 `Service` 接口和 `AutoCloseable` 接口: - -```java -import io.agentscope.runtime.engine.shared.ServiceWithLifecycleManager; -import java.util.concurrent.CompletableFuture; - -public class MockService extends ServiceWithLifecycleManager { - private String name; - private boolean started = false; - private boolean stopped = false; - - public MockService(String name) { - this.name = name; - } - - @Override - public CompletableFuture start() { - return CompletableFuture.runAsync(() -> { - started = true; - }); - } - - @Override - public CompletableFuture stop() { - return CompletableFuture.runAsync(() -> { - stopped = true; - }); - } - - @Override - public CompletableFuture health() { - return CompletableFuture.completedFuture(started && !stopped); - } -} -``` - -### 服务生命周期管理 - -`ServiceManager` 是一个抽象基类,子类需要实现 `registerDefaultServices()` 方法来注册默认服务: - -```java -import io.agentscope.runtime.engine.shared.ServiceManager; -import io.agentscope.runtime.engine.shared.Service; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -public class MyServiceManager extends ServiceManager { - @Override - protected void registerDefaultServices() { - // 注册默认服务 - } - - public static void main(String[] args) throws Exception { - MyServiceManager manager = new MyServiceManager(); - - // 注册服务类(通过类注册,注意:服务类必须有无参构造函数) - manager.register(MockService.class, "service1"); - manager.register(MockService.class, "service2"); - - // 或者注册服务实例(通过实例注册,推荐方式,可以传入构造参数) - manager.registerService("service3", new MockService("service3")); - - // 启动所有服务 - manager.start().get(); - - try { - // 使用服务 - List serviceNames = manager.listServices(); - Map health = manager.healthCheck().get(); - System.out.println("Services: " + serviceNames); - System.out.println("Health: " + health); - } finally { - // 停止所有服务 - manager.stop().get(); - // 或者使用 try-with-resources(因为实现了 AutoCloseable) - // manager.close(); - } - } -} -``` - -### 服务访问方式 - -`ServiceManager` 提供了以下方法访问服务: - -- 获取服务:`getService(String name)` - 如果服务不存在会抛出异常 -- 获取服务(带默认值):`getService(String name, Service defaultService)` - 如果服务不存在返回默认值 -- 检查服务是否存在:`hasService(String name)` - 返回布尔值 -- 列出所有服务名称:`listServices()` - 返回服务名称列表 -- 获取所有服务:`getAllServices()` - 返回服务名称到服务实例的映射 -- 健康检查:`healthCheck()` - 返回服务名称到健康状态的映射 - -```java -// 获取服务 -Service service1 = manager.getService("service1"); - -// 获取服务(带默认值) -Service service2 = manager.getService("service2", new MockService("default")); - -// 检查服务是否存在 -if (manager.hasService("service1")) { - Service service = manager.getService("service1"); -} - -// 列出所有服务 -List names = manager.listServices(); - -// 获取所有服务 -Map allServices = manager.getAllServices(); - -// 健康检查 -Map health = manager.healthCheck().get(); -``` - -## 上下文管理器(Context Manager) - -`ContextManager` 继承自 `ServiceManager`,默认装配上下文服务(`session`、`memory`),并提供上下文组合方法。 - -### 创建 ContextManager - -可以通过多种方式创建 `ContextManager`: - -```java -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; -import java.util.concurrent.CompletableFuture; - -// 方式1:使用默认构造函数(使用内存实现) -ContextManager contextManager1 = new ContextManager(); - -// 方式2:指定服务实现 -SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); -MemoryService memoryService = new InMemoryMemoryService(); -ContextManager contextManager2 = new ContextManager( - ContextComposer.class, - sessionHistoryService, - memoryService -); - -// 方式3:使用 ContextManagerFactory(推荐) -import io.agentscope.runtime.engine.memory.context.ContextManagerFactory; - -// 创建默认的上下文管理器 -ContextManager defaultManager = ContextManagerFactory.createDefault(); - -// 创建自定义的上下文管理器 -ContextManager customManager = ContextManagerFactory.createCustom( - memoryService, - sessionHistoryService -); -``` - -### 使用 ContextManager - -```java -import io.agentscope.runtime.engine.schemas.message.Message; -import io.agentscope.runtime.engine.schemas.context.Session; -import java.util.ArrayList; -import java.util.List; - -// 启动服务 -contextManager.start().get(); - -try { - // 获取服务 - SessionHistoryService sessionService = contextManager.getSessionHistoryService(); - MemoryService memoryService = contextManager.getMemoryService(); - - // 或者通过服务名称获取 - SessionHistoryService sessionService2 = (SessionHistoryService) contextManager.getService("session"); - MemoryService memoryService2 = (MemoryService) contextManager.getService("memory"); - - // 组合会话 - Session session = contextManager.composeSession("userId", "sessionId").get(); - - // 组合上下文 - List requestInput = new ArrayList<>(); - contextManager.composeContext(session, requestInput).get(); - - // 追加消息 - List eventOutput = new ArrayList<>(); - contextManager.append(session, eventOutput).get(); - -} finally { - // 停止服务 - contextManager.stop().get(); -} -``` - -更多细节见 {doc}`context_manager`。 - -## 环境管理器(Environment Manager) - -`EnvironmentManager` 是一个接口,专注于环境/工具相关能力(通过 `SandboxManager`)。`DefaultEnvironmentManager` 是其默认实现。 - -### 创建 EnvironmentManager - -```java -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -// 方式1:使用默认构造函数(会创建新的 SandboxManager) -EnvironmentManager envManager1 = new DefaultEnvironmentManager(); - -// 方式2:指定 SandboxManager -SandboxManager sandboxManager = new SandboxManager(); -EnvironmentManager envManager2 = new DefaultEnvironmentManager(sandboxManager); -``` - -### 使用 EnvironmentManager - -```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.container.SandboxType; -import io.agentscope.runtime.sandbox.manager.model.container.ContainerModel; - -// 初始化环境 -envManager.initializeEnvironment().get(); - -try { - // 获取 SandboxManager(用于管理沙箱环境) - SandboxManager sandboxManager = envManager.getSandboxManager(); - - // 通过 SandboxManager 创建沙箱 - ContainerModel container = sandboxManager.createFromPool( - SandboxType.BASE, - "userId", - "sessionId" - ); - - // 释放沙箱 - sandboxManager.releaseSandbox(SandboxType.BASE, "userId", "sessionId"); - - // 获取环境变量 - String value = envManager.getEnvironmentVariable("KEY"); - - // 设置环境变量 - envManager.setEnvironmentVariable("KEY", "value"); - - // 获取所有环境变量 - Map allVars = envManager.getAllEnvironmentVariables(); - - // 检查环境是否可用 - boolean available = envManager.isEnvironmentAvailable(); - - // 获取环境信息 - Map info = envManager.getEnvironmentInfo(); - -} finally { - // 清理环境 - envManager.cleanupEnvironment().get(); -} -``` - -更多细节见 {doc}`environment_manager`。 - diff --git a/cookbook/zh/protocol.md b/cookbook/zh/protocol.md deleted file mode 100644 index fc6da42a..00000000 --- a/cookbook/zh/protocol.md +++ /dev/null @@ -1,1099 +0,0 @@ -# Agent API 协议规范 - -## 概述 - -本文档描述了与AI智能体通信的结构化JSON协议。该协议定义了支持以下功能的消息、请求和响应: - -+ 流式内容传输 -+ 工具/函数调用 -+ 多模态内容(文本、图像、数据) -+ 全生命周期的状态跟踪 -+ 错误处理 - -## 协议结构 - -### 1. 核心枚举和常量 - -**角色**: - -在Java实现中,角色使用字符串常量表示,通常为 `"user"`、`"assistant"`、`"system"` 或 `"tool"`。角色值直接存储在 `Message` 类的 `role` 字段中。 - -**消息类型**: - -```java -package io.agentscope.runtime.engine.memory.model; - -public enum MessageType { - CHUNK, - MESSAGE, - SYSTEM, - USER, - ASSISTANT, - FUNCTION_CALL, - FUNCTION_CALL_OUTPUT, - PLUGIN_CALL, - PLUGIN_CALL_OUTPUT, - COMPONENT_CALL, - COMPONENT_CALL_OUTPUT, - MCP_LIST_TOOLS, - MCP_APPROVAL_REQUEST, - MCP_TOOL_CALL, - MCP_APPROVAL_RESPONSE, - HEARTBEAT, - ERROR -} -``` - -**运行状态**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -public class RunStatus { - public static final String CREATED = "created"; - public static final String IN_PROGRESS = "in_progress"; - public static final String COMPLETED = "completed"; - public static final String CANCELED = "canceled"; - public static final String FAILED = "failed"; - public static final String REJECTED = "rejected"; - public static final String UNKNOWN = "unknown"; - - private RunStatus() { - // Utility class, instantiation not allowed - } -} -``` - -### 2. 内容模型 - -**内容类型常量**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -public class ContentType { - public static final String TEXT = "text"; - public static final String DATA = "data"; - public static final String IMAGE = "image"; - public static final String AUDIO = "audio"; - - private ContentType() { - // Utility class, instantiation not allowed - } -} -``` - -**基础内容模型**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -import java.util.Map; - -public abstract class Content extends Event { - private String type; - private String object = "content"; - private Integer index; - private Boolean delta = false; - private String msgId; - - public Content() { - super(); - } - - public Content(String type) { - super(); - this.type = type; - } - - /** - * 内容部分的类型 - */ - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - /** - * 内容部分的标识 - */ - @Override - public String getObject() { - return object; - } - - @Override - public void setObject(String object) { - this.object = object; - } - - /** - * 在消息内容列表中的索引位置 - */ - public Integer getIndex() { - return index; - } - - public void setIndex(Integer index) { - this.index = index; - } - - /** - * 是否为增量内容 - */ - public Boolean getDelta() { - return delta; - } - - public void setDelta(Boolean delta) { - this.delta = delta; - } - - /** - * 消息唯一ID - */ - public String getMsgId() { - return msgId; - } - - public void setMsgId(String msgId) { - this.msgId = msgId; - } -} -``` - -**专用内容类型**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -import java.util.Map; - -public class TextContent extends Content { - private String text; - - public TextContent() { - super(ContentType.TEXT); - } - - public TextContent(String text) { - super(ContentType.TEXT); - this.text = text; - } - - public TextContent(Boolean delta, String text, Integer index) { - super(ContentType.TEXT); - this.setDelta(delta); - this.text = text; - this.setIndex(index); - } - - /** - * 文本内容 - */ - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } -} - -public class ImageContent extends Content { - private String imageUrl; - - public ImageContent() { - super(ContentType.IMAGE); - } - - public ImageContent(String imageUrl) { - super(ContentType.IMAGE); - this.imageUrl = imageUrl; - } - - /** - * 图片URL详情 - */ - public String getImageUrl() { - return imageUrl; - } - - public void setImageUrl(String imageUrl) { - this.imageUrl = imageUrl; - } -} - -public class DataContent extends Content { - private Map data; - - public DataContent() { - super(ContentType.DATA); - } - - public DataContent(Map data) { - super(ContentType.DATA); - this.data = data; - } - - public DataContent(Boolean delta, Map data, Integer index) { - super(ContentType.DATA); - this.setDelta(delta); - this.data = data; - this.setIndex(index); - } - - /** - * 数据内容 - */ - public Map getData() { - return data; - } - - public void setData(Map data) { - this.data = data; - } -} -``` - -**注意**:Java实现中目前支持 `TextContent`、`ImageContent` 和 `DataContent`。`AudioContent`、`FileContent` 和 `RefusalContent` 暂未实现。 - -### 3. 事件模型 - -**基础事件类**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -public class Event { - private Integer sequenceNumber; - protected String object; - protected String status; - private java.lang.Error error; - - public Event() { - this.status = RunStatus.CREATED; - } - - /** - * 序列号 - */ - public Integer getSequenceNumber() { - return sequenceNumber; - } - - public void setSequenceNumber(Integer sequenceNumber) { - this.sequenceNumber = sequenceNumber; - } - - /** - * 对象标识 - */ - public String getObject() { - return object; - } - - public void setObject(String object) { - this.object = object; - } - - /** - * 状态:created, in_progress, completed, canceled, failed, rejected - */ - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - /** - * 错误信息 - */ - public java.lang.Error getError() { - return error; - } - - public void setError(java.lang.Error error) { - this.error = error; - } - - /** - * 设置为创建状态 - */ - public Event created() { - this.status = RunStatus.CREATED; - return this; - } - - /** - * 设置为进行中状态 - */ - public Event inProgress() { - this.status = RunStatus.IN_PROGRESS; - return this; - } - - /** - * 设置为完成状态 - */ - public Event completed() { - this.status = RunStatus.COMPLETED; - return this; - } - - /** - * 设置为拒绝状态 - */ - public Event rejected() { - this.status = RunStatus.REJECTED; - return this; - } - - /** - * 设置为取消状态 - */ - public Event canceled() { - this.status = RunStatus.CANCELED; - return this; - } -} -``` - -### 4. 消息模型 - -```java -package io.agentscope.runtime.engine.schemas.agent; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; -import io.agentscope.runtime.engine.schemas.message.MessageType; - -public class Message extends Event { - private String id; - private String type = MessageType.MESSAGE.name(); - private String role; - private List content; - private String code; - private String message; - private Map usage; - - public Message() { - super(); - this.id = "msg_" + UUID.randomUUID().toString(); - this.object = "message"; - this.status = RunStatus.CREATED; - this.content = new ArrayList<>(); - } - - public Message(String type, String role) { - this(); - this.type = type; - this.role = role; - } - - /** - * 消息唯一ID - */ - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - /** - * 消息类型 - */ - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - /** - * 消息作者角色,应为 "user", "system", "assistant" 或 "tool" - */ - public String getRole() { - return role; - } - - public void setRole(String role) { - this.role = role; - } - - /** - * 消息内容列表 - */ - public List getContent() { - return content; - } - - public void setContent(List content) { - this.content = content != null ? content : new ArrayList<>(); - } - - /** - * 消息错误代码 - */ - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - /** - * 消息错误描述 - */ - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - /** - * 使用情况统计 - */ - public Map getUsage() { - return usage; - } - - public void setUsage(Map usage) { - this.usage = usage; - } -} -``` - -**关键方法**: - -+ `addDeltaContent(Content newContent)`: 向现有消息追加部分内容 -+ `contentCompleted(int contentIndex)`: 标记内容片段为完成状态 -+ `addContent(Content newContent)`: 添加完整的内容片段 -+ `getTextContent()`: 获取消息中的文本内容 -+ `getImageContent()`: 获取消息中的图片URL列表 - -### 5. 请求模型 - -**智能体请求**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -import java.util.List; - -public class AgentRequest { - private List input; - private boolean stream = true; - private String model; - private Double topP; - private Double temperature; - private Double frequencyPenalty; - private Double presencePenalty; - private Integer maxTokens; - private Object stop; // String or List - private Integer n = 1; - private Integer seed; - private List tools; // List or List - private String userId; - private String sessionId; - private String responseId; - - public AgentRequest() {} - - public AgentRequest(List input) { - this.input = input; - } - - /** - * 输入消息列表 - */ - public List getInput() { - return input; - } - - public void setInput(List input) { - this.input = input; - } - - /** - * 是否使用流式响应 - */ - public boolean isStream() { - return stream; - } - - public void setStream(boolean stream) { - this.stream = stream; - } - - /** - * 模型名称 - */ - public String getModel() { - return model; - } - - public void setModel(String model) { - this.model = model; - } - - // 其他getter和setter方法... - public Double getTopP() { return topP; } - public void setTopP(Double topP) { this.topP = topP; } - - public Double getTemperature() { return temperature; } - public void setTemperature(Double temperature) { this.temperature = temperature; } - - public Double getFrequencyPenalty() { return frequencyPenalty; } - public void setFrequencyPenalty(Double frequencyPenalty) { this.frequencyPenalty = frequencyPenalty; } - - public Double getPresencePenalty() { return presencePenalty; } - public void setPresencePenalty(Double presencePenalty) { this.presencePenalty = presencePenalty; } - - public Integer getMaxTokens() { return maxTokens; } - public void setMaxTokens(Integer maxTokens) { this.maxTokens = maxTokens; } - - public Object getStop() { return stop; } - public void setStop(Object stop) { this.stop = stop; } - - public Integer getN() { return n; } - public void setN(Integer n) { this.n = n; } - - public Integer getSeed() { return seed; } - public void setSeed(Integer seed) { this.seed = seed; } - - public List getTools() { return tools; } - public void setTools(List tools) { this.tools = tools; } - - public String getUserId() { return userId; } - public void setUserId(String userId) { this.userId = userId; } - - public String getSessionId() { return sessionId; } - public void setSessionId(String sessionId) { this.sessionId = sessionId; } - - public String getResponseId() { return responseId; } - public void setResponseId(String responseId) { this.responseId = responseId; } -} -``` - -### 6. 响应模型 - -**智能体响应**: - -```java -package io.agentscope.runtime.engine.schemas.agent; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.UUID; - -public class AgentResponse extends Event { - private String id; - private String object = "response"; - private Long createdAt; - private Long completedAt; - private List output; - private Map usage; - private String sessionId; - - public AgentResponse() { - super(); - this.id = "response_" + UUID.randomUUID().toString(); - this.status = RunStatus.CREATED; - this.createdAt = System.currentTimeMillis(); - this.output = new ArrayList<>(); - } - - /** - * 响应唯一ID - */ - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - /** - * 响应对象标识 - */ - @Override - public String getObject() { - return object; - } - - @Override - public void setObject(String object) { - this.object = object; - } - - /** - * 创建时间戳(毫秒) - */ - public Long getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - /** - * 完成时间戳(毫秒) - */ - public Long getCompletedAt() { - return completedAt; - } - - public void setCompletedAt(Long completedAt) { - this.completedAt = completedAt; - } - - /** - * 输出消息列表 - */ - public List getOutput() { - return output; - } - - public void setOutput(List output) { - this.output = output != null ? output : new ArrayList<>(); - } - - /** - * 使用情况统计 - */ - public Map getUsage() { - return usage; - } - - public void setUsage(Map usage) { - this.usage = usage; - } - - /** - * 会话ID - */ - public String getSessionId() { - return sessionId; - } - - public void setSessionId(String sessionId) { - this.sessionId = sessionId; - } - - /** - * 添加新消息 - */ - public void addNewMessage(Message message) { - if (output == null) { - output = new ArrayList<>(); - } - output.add(message); - } -} -``` - -### 7. 错误模型 - -```java -package io.agentscope.runtime.engine.schemas.agent; - -public class Error { - private String code; - private String message; - - public Error() {} - - public Error(String code, String message) { - this.code = code; - this.message = message; - } - - /** - * 错误代码 - */ - public String getCode() { - return code; - } - - public void setCode(String code) { - this.code = code; - } - - /** - * 错误消息 - */ - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} -``` - -## 协议流程 - -### 请求/响应生命周期 - -1. 客户端发送 `AgentRequest`,包含: - - 输入消息 - - 生成参数 - - 工具定义 - - 会话上下文 -2. 服务端响应 `AgentResponse` 对象流,包含: - - 状态更新 (`created` → `in_progress` → `completed`) - - 带内容片段的输出消息 - - 最终使用指标 - -### 内容流式传输 - -当请求中 `stream=True` 时: - -+ 文本内容以 `delta=true` 片段增量发送 -+ 每个片段包含指向目标内容槽的 `index` -+ 最终片段通过 `status=completed` 标记完成 - -**流式传输示例**: - -```bash -{"status":"created","id":"response_...","object":"response"} -{"status":"created","id":"msg_...","object":"message","type":"assistant"} -{"status":"in_progress","type":"text","index":0,"delta":true,"text":"Hello","object":"content"} -{"status":"in_progress","type":"text","index":0,"delta":true,"text":", ","object":"content"} -{"status":"in_progress","type":"text","index":0,"delta":true,"text":"world","object":"content"} -{"status":"completed","type":"text","index":0,"delta":false,"text":"Hello, world!","object":"content"} -{"status":"completed","id":"msg_...","object":"message", ...} -{"status":"completed","id":"response_...","object":"response", ...} -``` - -### 状态转换 - -| 状态 | 描述 | -| ------------- | -------------------------- | -| `created` | 对象创建时的初始状态 | -| `in_progress` | 操作正在处理中 | -| `completed` | 操作成功完成 | -| `failed` | 操作因错误终止 | -| `rejected` | 操作被系统拒绝 | -| `canceled` | 操作被用户取消 | -| `unknown` | 未知状态 | - - -## 最佳实践 - -1. **流处理**: - - 缓冲增量片段直到收到 `status=completed` - - 使用 `msg_id` 关联内容与父消息 - - 尊重多片段消息的 `index` 顺序 -2. **错误处理**: - - 检查响应中的 `error` 字段 - - 监控 `failed` 状态转换 - - 对可恢复错误实施重试逻辑 -3. **状态管理**: - - 使用 `sessionId` 保持会话连续性 - - 跟踪 `createdAt`/`completedAt` 监控延迟(时间戳单位为毫秒) - - 使用 `sequenceNumber` 排序(如已实现) - -## 使用示例 - -**用户查询**: - -```json -{ - "input": [{ - "role": "user", - "content": [{"type": "text", "text": "描述这张图片"}], - "type": "MESSAGE" - }], - "stream": true, - "model": "gpt-4-vision" -} -``` - -**智能体响应流**: - -```bash -{"id":"response_123","object":"response","status":"created"} -{"id":"msg_abc","object":"message","type":"MESSAGE","status":"created","role":"assistant"} -{"status":"in_progress","type":"text","index":0,"delta":true,"text":"这张","object":"content","msgId":"msg_abc"} -{"status":"in_progress","type":"text","index":0,"delta":true,"text":"图片显示...","object":"content","msgId":"msg_abc"} -{"status":"completed","type":"text","index":0,"delta":false,"text":"这张图片显示...","object":"content","msgId":"msg_abc"} -{"id":"msg_abc","status":"completed","object":"message"} -{"id":"response_123","status":"completed","object":"response"} -``` - -**Java代码示例**: - -```java -import io.agentscope.runtime.engine.schemas.agent.*; -import java.util.ArrayList; -import java.util.List; - -// 创建请求 -AgentRequest request = new AgentRequest(); -List input = new ArrayList<>(); - -Message userMessage = new Message(); -userMessage.setRole("user"); -userMessage.setType("MESSAGE"); - -TextContent textContent = new TextContent("描述这张图片"); -List contents = new ArrayList<>(); -contents.add(textContent); -userMessage.setContent(contents); - -input.add(userMessage); -request.setInput(input); -request.setStream(true); -request.setModel("gpt-4-vision"); - -// 处理响应 -AgentResponse response = new AgentResponse(); -response.setSessionId("session_123"); -response.created(); - -Message assistantMessage = new Message("MESSAGE", "assistant"); -assistantMessage.created(); - -TextContent deltaContent = new TextContent(true, "这张", 0); -deltaContent.setMsgId(assistantMessage.getId()); -deltaContent.inProgress(); -assistantMessage.addDeltaContent(deltaContent); - -// ... 继续添加内容 ... -``` - -## Agent API 协议使用方式 - -在Java实现中,可以直接使用类和方法来构建符合协议规范的流式响应数据。 - -### 1. 构建响应对象 - -**创建响应**: - -```java -import io.agentscope.runtime.engine.schemas.agent.*; - -// 创建响应对象 -AgentResponse response = new AgentResponse(); -response.setSessionId("session_123"); -response.created(); // 设置为创建状态 -``` - -**创建消息**: - -```java -// 创建消息对象 -Message message = new Message("MESSAGE", "assistant"); -message.created(); // 设置为创建状态 - -// 添加到响应 -response.addNewMessage(message); -``` - -### 2. 构建内容 - -**文本内容**: - -```java -// 创建文本内容 -TextContent textContent = new TextContent("Hello World"); -textContent.setIndex(0); -textContent.completed(); // 设置为完成状态 - -// 添加到消息 -message.addContent(textContent); -``` - -**增量文本内容(流式)**: - -```java -// 创建增量文本内容 -TextContent deltaContent1 = new TextContent(true, "Hello", 0); -deltaContent1.setMsgId(message.getId()); -deltaContent1.inProgress(); // 设置为进行中状态 -message.addDeltaContent(deltaContent1); - -TextContent deltaContent2 = new TextContent(true, " World", 0); -deltaContent2.setMsgId(message.getId()); -deltaContent2.inProgress(); -message.addDeltaContent(deltaContent2); - -// 完成内容 -message.contentCompleted(0); -``` - -**图片内容**: - -```java -// 创建图片内容 -ImageContent imageContent = new ImageContent("https://example.com/image.jpg"); -imageContent.setIndex(0); -imageContent.completed(); - -// 添加到消息 -message.addContent(imageContent); -``` - -**数据内容**: - -```java -import java.util.HashMap; -import java.util.Map; - -// 创建数据内容 -Map data = new HashMap<>(); -data.put("type", "function_call"); -data.put("name", "get_weather"); -data.put("arguments", "{\"city\": \"Beijing\"}"); - -DataContent dataContent = new DataContent(data); -dataContent.setIndex(0); -dataContent.completed(); - -// 添加到消息 -message.addContent(dataContent); -``` - -### 3. 完整使用示例 - -以下示例展示如何生成完整的流式响应序列: - -```java -import io.agentscope.runtime.engine.schemas.agent.*; -import java.util.ArrayList; -import java.util.List; - -public class StreamingResponseExample { - public static void generateStreamingResponse(String sessionId, - List textTokens, - String role) { - // 创建响应对象 - AgentResponse response = new AgentResponse(); - response.setSessionId(sessionId); - response.created(); - System.out.println(response); // 输出响应创建事件 - - // 创建消息对象 - Message message = new Message("MESSAGE", role); - message.created(); - response.addNewMessage(message); - System.out.println(message); // 输出消息创建事件 - - // 流式输出文本内容 - int index = 0; - for (String token : textTokens) { - TextContent deltaContent = new TextContent(true, token, index); - deltaContent.setMsgId(message.getId()); - deltaContent.inProgress(); - message.addDeltaContent(deltaContent); - System.out.println(deltaContent); // 输出增量内容事件 - } - - // 完成内容 - message.contentCompleted(index); - - // 完成消息 - message.completed(); - System.out.println(message); // 输出消息完成事件 - - // 完成响应 - response.completed(); - response.setCompletedAt(System.currentTimeMillis()); - System.out.println(response); // 输出响应完成事件 - } -} -``` - -### 4. 流式响应序列 - -标准的流式响应序列包括以下步骤: - -1. **响应创建** (`response.created()`) -2. **消息创建** (`message.created()`) -3. **内容流式输出** (`content.inProgress()` with `delta=true`) -4. **内容完成** (`content.completed()`) -5. **消息完成** (`message.completed()`) -6. **响应完成** (`response.completed()`) - -### 5. 支持的内容类型 - -Java实现中目前支持以下内容类型: - -- **TextContent**: 文本内容,支持增量输出 -- **ImageContent**: 图片内容,支持URL格式 -- **DataContent**: 数据内容,支持任意Map数据 - -**注意**:`AudioContent`、`FileContent` 和 `RefusalContent` 暂未在Java实现中提供。 - -### 6. 最佳实践 - -1. **状态管理**: 确保按正确顺序设置状态(created → in_progress → completed) -2. **内容索引**: 为多内容消息正确设置index值 -3. **增量输出**: 使用`addDeltaContent`方法实现流式文本输出 -4. **错误处理**: 在构建过程中适当处理异常情况 -5. **消息ID关联**: 使用`setMsgId`方法将内容与父消息关联 - -### 7. 高级用法 - -#### 多内容消息构建 - -```java -// 创建包含文本和图片的消息 -Message message = new Message("MESSAGE", "assistant"); - -// 添加文本内容 -TextContent textContent = new TextContent("这是一张图片:"); -textContent.setIndex(0); -textContent.completed(); -message.addContent(textContent); - -// 添加图片内容 -ImageContent imageContent = new ImageContent("https://example.com/image.jpg"); -imageContent.setIndex(1); -imageContent.completed(); -message.addContent(imageContent); - -// 完成消息 -message.completed(); -``` - -#### 函数调用数据内容 - -```java -// 创建函数调用 -FunctionCall functionCall = new FunctionCall( - "call_123", - "get_weather", - "{\"city\": \"Beijing\"}" -); - -// 转换为数据内容 -DataContent dataContent = new DataContent(functionCall.toMap()); -dataContent.setIndex(0); -dataContent.completed(); - -// 添加到消息 -Message message = new Message("FUNCTION_CALL", "assistant"); -message.addContent(dataContent); -``` - -通过直接使用Java类和方法,开发者可以构建符合协议规范的复杂流式响应,实现更好的用户体验和更灵活的响应控制。 \ No newline at end of file diff --git a/cookbook/zh/quickstart.md b/cookbook/zh/quickstart.md index 7563a4f9..24fd76ce 100644 --- a/cookbook/zh/quickstart.md +++ b/cookbook/zh/quickstart.md @@ -1,440 +1,414 @@ # 快速开始 -本教程演示如何在 **AgentScope Runtime Java** 框架中构建一个简单的智能体并将其部署为服务。 +本教程演示如何在 **AgentScope Runtime Java** 框架中构建一个简单的智能体应用并将其部署为服务。 ## 前置条件 ### 🔧 安装要求 -- **Java 17** 或更高版本 -- **Maven 3.6+** -- **Docker**(可选,用于沙箱工具执行) - -### 📦 项目依赖 - -在您的 `pom.xml` 文件中添加以下依赖: +添加 AgentScope Runtime Java 针对 AgentScope 框架的适配器依赖和应用启动依赖,基础依赖已通过适配器依赖传递依赖完成: ```xml - - - - io.agentscope - agentscope-runtime-agentscope - 0.1.1 - - - - - io.agentscope - agentscope-runtime-saa - 0.1.1 - - - - - io.agentscope - agentscope-runtime-web - 0.1.1 - - + + io.agentscope + agentscope-runtime-agentscope + 1.0.0 + + + + io.agentscope + agentscope-runtime-web + 1.0.0 + ``` ### 🔑 API密钥配置 -您需要为所选的大语言模型提供商提供API密钥。本示例使用DashScope(Qwen): +您需要为所选的大语言模型提供商提供API密钥。本示例使用阿里云的Qwen模型,服务提供方是DashScope,所以需要使用其API_KEY,您可以按如下方式将key作为环境变量: ```bash -export AI_DASHSCOPE_API_KEY="your_api_key_here" +export DASHSCOPE_API_KEY="your_api_key_here" ``` ## 分步实现 -### 步骤1:初始化上下文管理器 - -上下文管理器用于管理会话历史和记忆服务: - -```java -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; - -private ContextManager initializeContextManager() { - try { - // 创建会话历史服务 - SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); - - // 创建记忆服务 - MemoryService memoryService = new InMemoryMemoryService(); - - // 创建上下文管理器 - ContextManager contextManager = new ContextManager( - ContextComposer.class, - sessionHistoryService, - memoryService - ); - - // 启动服务 - sessionHistoryService.start().get(); - memoryService.start().get(); - contextManager.start().get(); - - System.out.println("✅ ContextManager initialized successfully"); - return contextManager; - } catch (Exception e) { - System.err.println("Failed to initialize ContextManager: " + e.getMessage()); - throw new RuntimeException("ContextManager initialization failed", e); - } -} -``` - -### 步骤2:创建智能体 +### 步骤1:构建 Agent 及其执行逻辑 -您可以选择使用 **AgentScope Agent** 或 **Spring AI Alibaba (SAA) Agent**。 +#### 1.1 导入依赖 -#### 方式1:使用 AgentScope Agent +首先导入所有必要的依赖: ```java +import java.util.List; +import java.util.Map; + import io.agentscope.core.ReActAgent; +import io.agentscope.core.agent.EventType; +import io.agentscope.core.agent.StreamOptions; import io.agentscope.core.formatter.dashscope.DashScopeChatFormatter; -import io.agentscope.core.memory.InMemoryMemory; +import io.agentscope.core.memory.LongTermMemoryMode; +import io.agentscope.core.message.Msg; +import io.agentscope.core.model.DashScopeChatModel; import io.agentscope.core.tool.Toolkit; -import io.agentscope.runtime.engine.agents.agentscope.AgentScopeAgent; +import io.agentscope.runtime.adapters.agentscope.AgentScopeAgentHandler; +import io.agentscope.runtime.adapters.agentscope.memory.LongTermMemoryAdapter; +import io.agentscope.runtime.adapters.agentscope.memory.MemoryAdapter; import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit; -import io.agentscope.core.model.DashScopeChatModel; +import io.agentscope.runtime.engine.schemas.AgentRequest; +import io.agentscope.runtime.sandbox.box.BaseSandbox; +import io.agentscope.runtime.sandbox.box.Sandbox; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import reactor.core.publisher.Flux; +``` -// 创建工具包 -Toolkit toolkit = new Toolkit(); -toolkit.registerTool(ToolkitInit.RunPythonCodeTool()); -toolkit.registerTool(ToolkitInit.RunShellCommandTool()); +#### 1.2 构建 AgentScopeAgentHandler 接口的实现 -// 创建 ReActAgent -ReActAgent.Builder agentBuilder = ReActAgent.builder() - .name("Friday") - .sysPrompt("You're a helpful assistant named Friday.") - .toolkit(toolkit) - .memory(new InMemoryMemory()) - .model(DashScopeChatModel.builder() - .apiKey(System.getenv("AI_DASHSCOPE_API_KEY")) - .modelName("qwen-turbo") - .stream(true) - .enableThinking(true) - .formatter(new DashScopeChatFormatter()) - .build()); - -// 创建 AgentScopeAgent -AgentScopeAgent agentScopeAgent = AgentScopeAgent.builder() - .agent(agentBuilder) - .build(); +下面的四个方法分别定义了整个应用的属性和执行逻辑,`isHealthy`方法用于返回当前应用的健康状况,`getName`方法用于返回当前应用的名称,`getDescription`方法用于返回当前应用的描述,**`streamQuery`**方法则是整个AgentScopeAgentHandler的逻辑执行核心,用于用户设置记忆、构建 Agent 以及自定义 Agent 执行逻辑 + +```java +public class MyAgentScopeAgentHandler extends AgentScopeAgentHandler { + @Override + public boolean isHealthy() { + return false; + } + + @Override + public String getName() { + return ""; + } + + @Override + public String getDescription() { + return ""; + } -System.out.println("✅ AgentScope agent created successfully"); + @Override + public Flux streamQuery(AgentRequest request, Object messages) { + return null; + } +} ``` -#### 方式2:使用 Spring AI Alibaba (SAA) Agent +#### 1.3 实现核心执行逻辑 streamQuery 方法 + +##### 1.3.1 获取到必要的 id 信息 ```java -import com.alibaba.cloud.ai.dashscope.api.DashScopeApi; -import com.alibaba.cloud.ai.dashscope.chat.DashScopeChatModel; -import com.alibaba.cloud.ai.graph.agent.Builder; -import com.alibaba.cloud.ai.graph.agent.ReactAgent; -import io.agentscope.runtime.engine.agents.saa.SaaAgent; -import io.agentscope.runtime.engine.agents.saa.tools.ToolcallsInit; -import java.util.List; +String sessionId = request.getSessionId(); +String userId = request.getUserId(); +``` -// 创建 DashScope API -DashScopeApi dashScopeApi = DashScopeApi.builder() - .apiKey(System.getenv("AI_DASHSCOPE_API_KEY")) - .build(); +##### 1.3.2 从 StateService 导出历史状态 -// 创建 DashScope ChatModel -DashScopeChatModel chatModel = DashScopeChatModel.builder() - .dashScopeApi(dashScopeApi) - .build(); +```java +Map state = null; +if (stateService != null) { + try { + state = stateService.exportState(userId, sessionId, null).join(); + } + catch (Exception e) { + logger.warn("Failed to export state: {}", e.getMessage()); + } +} +``` -// 创建 ReactAgent Builder -Builder agentBuilder = ReactAgent.builder() - .name("Friday") - .model(chatModel) - .tools(List.of( - ToolcallsInit.RunPythonCodeTool(), - ToolcallsInit.RunShellCommandTool() - )); - -// 创建 SaaAgent -SaaAgent saaAgent = SaaAgent.builder() - .agent(agentBuilder) - .build(); +- **目的**:恢复该用户在该会话中的**上一轮 Agent 状态**(例如:内部变量、对话阶段、任务进度等)。 +- `roundId = null` 表示取**最新一轮**的状态。 +- 使用 `.join()` 阻塞等待(因为后续构建 Agent 需要同步状态)。 +- 失败时仅警告,不影响主流程(Agent 可从空状态开始)。 -System.out.println("✅ SAA agent created successfully"); +##### 1.3.3 创建 Toolkit 并注册工具 + +```java +Toolkit toolkit = new Toolkit(); +if (sandboxService != null) { + Sandbox sandbox = sandboxService.connect(userId, sessionId, BaseSandbox.class); + toolkit.registerTool(ToolkitInit.RunPythonCodeTool(sandbox)); +} ``` -### 步骤3:配置沙箱管理器(可选但推荐) +- **Toolkit**:Agent 可调用的工具集合。 +- **Sandbox**:安全沙箱环境,具体包含基础沙箱、文件系统沙箱、浏览器沙箱等,每个 `(userId, sessionId)` 独立实例。 +- 注册沙箱工具。 +- 如果沙箱创建失败,跳过工具注册,Agent 仍可运行,但无法调用此工具。 -如果您需要使用沙箱工具(如Python代码执行、文件操作等),需要配置沙箱管理器: +##### 1.3.4 创建短期记忆适配器(MemoryAdapter) ```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; +MemoryAdapter memory = null; +if (sessionHistoryService != null) { + memory = new MemoryAdapter(sessionHistoryService, userId, sessionId); +} +``` -// 创建沙箱管理器配置(使用默认Docker配置) -ManagerConfig managerConfig = ManagerConfig.builder().build(); +- **作用**:提供**当前会话的历史消息记录**(如用户和 Agent 的对话历史)。 +- `sessionHistoryService` 是底层存储服务。 +- 适配器将通用服务接口转换为 AgentScope 框架所需的 `Memory` 接口。 + +##### 1.3.5 创建长期记忆适配器(LongTermMemoryAdapter) + +```java +LongTermMemoryAdapter longTermMemory = null; +if (memoryService != null) { + longTermMemory = new LongTermMemoryAdapter(memoryService, userId, sessionId); +} +``` -// 创建沙箱管理器 -SandboxManager sandboxManager = new SandboxManager(managerConfig); +- **作用**:访问用户的**跨会话长期记忆**(如个人偏好、知识库摘要等)。 +- 通常基于向量数据库或结构化存储。 +- 后续会配置 Agent 在生成回复时**同时参考短期和长期记忆**。 -// 创建环境管理器 -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); +##### 1.3.6 构建 ReActAgent 实例 -System.out.println("✅ Sandbox manager configured successfully"); +```java +ReActAgent.Builder agentBuilder = ReActAgent.builder() + .name("Friday") + .sysPrompt("You're a helpful assistant named Friday.") + .toolkit(toolkit) + .model( + DashScopeChatModel.builder() + .apiKey(apiKey) + .modelName("qwen-max") + .stream(true) + .formatter(new DashScopeChatFormatter()) + .build()); ``` -### 步骤4:创建 Runner +- 使用 **Builder 模式**组装 Agent: + - 名称、系统提示词(system prompt) + - 绑定工具集(`toolkit`) + - 配置大模型(这里用通义千问 `qwen-max`,通过 DashScope API) + - 启用流式输出(`.stream(true)`) +- **注意**:此时 Agent 尚未加载状态或记忆。 -Runner 将智能体、上下文管理器和环境管理器组合在一起: +##### 1.3.7 注入记忆模块 ```java -import io.agentscope.runtime.engine.Runner; +if (longTermMemory != null) { + agentBuilder.longTermMemory(longTermMemory) + .longTermMemoryMode(LongTermMemoryMode.BOTH); +} +if (memory != null) { + agentBuilder.memory(memory); +} +``` -Runner runner = Runner.builder() - .agent(agentScopeAgent) // 或 saaAgent - .contextManager(contextManager) - .environmentManager(environmentManager) // 如果使用沙箱工具,需要设置 - .build(); +- **`memory`** → 短期记忆(当前会话历史) +- **`longTermMemory`** → 长期记忆(跨会话知识) +- `LongTermMemoryMode.BOTH`:表示在**思考和生成**阶段都使用长期记忆。 + +##### 1.3.8 加载历史状态到 Agent -System.out.println("✅ Runner created successfully"); +```java +if (state != null && !state.isEmpty()) { + agent.loadStateDict(state); +} ``` -### 步骤5:部署智能体 +- 将 Step 2 获取的状态字典反序列化到 Agent 内部。 +- 使 Agent 能“接续”上一次的对话状态(如继续未完成的任务)。 -使用 `LocalDeployManager` 将智能体部署为 A2A 服务: +##### 1.3.9 处理输入消息(messages) ```java -import io.agentscope.runtime.LocalDeployManager; +List agentMessages; +if (messages instanceof List) { + @SuppressWarnings("unchecked") + List msgList = (List) messages; + agentMessages = msgList; +} +else if (messages instanceof Msg) { + agentMessages = List.of((Msg) messages); +} +else { + logger.warn("Unexpected messages type: {}, using empty list", + messages != null ? messages.getClass().getName() : "null"); + agentMessages = List.of(); +} + +Msg queryMessage; +if (agentMessages.size() > 1) { + // 将前 N-1 条消息加入 memory + for (int i = 0; i < agentMessages.size() - 1; i++) { + agent.getMemory().addMessage(agentMessages.get(i)); + } + queryMessage = agentMessages.get(agentMessages.size() - 1); // 最后一条作为当前查询 +} else { + queryMessage = agentMessages.get(0) or empty Msg; +} +``` -// 部署智能体(默认端口 8080) -LocalDeployManager.builder() - .port(8090) - .build() - .deploy(runner); +##### 1.3.10 启动流式推理并返回事件流 -System.out.println("✅ Agent deployed successfully on port 8090"); +```java +StreamOptions streamOptions = StreamOptions.builder() + .eventTypes(EventType.REASONING, EventType.TOOL_RESULT) + .incremental(true) + .build(); + +Flux agentScopeEvents = agent.stream(queryMessage, streamOptions); ``` -### 步骤6:发送请求 +- **`stream()`**:启动 ReAct 循环(Thought → Action → Observation → ... → Final Answer) +- **`StreamOptions`**: + - `eventTypes`:只返回推理步骤和工具结果(过滤掉内部日志等) + - `incremental = true`:启用增量流式输出(如逐字生成) +- 返回的是 **AgentScope 原生 Event 流**(不是 Runtime Event),由外层 `StreamAdapter` 转换。 -您可以使用 `curl` 向 A2A API 发送请求: +##### 1.3.11 流完成时保存最终状态 -```bash -curl --location --request POST 'http://localhost:8090/a2a/' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "method": "message/stream", - "id": "2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc", - "jsonrpc": "2.0", - "params": { - "message": { - "role": "user", - "kind": "message", - "contextId": "okokok", - "metadata": { - "userId": "me", - "sessionId": "test12" - }, - "parts": [ - { - "kind": "text", - "text": "What is the capital of France?" +```java +return agentScopeEvents + .doOnNext(event -> { + logger.info("Agent event: {}", event); + }) + .doFinally(signalType -> { + if (stateService != null) { + try { + Map finalState = agent.stateDict(); + if (finalState != null && !finalState.isEmpty()) { + stateService.saveState(userId, finalState, sessionId, null) + .exceptionally(e -> { + logger.error("Failed to save state: {}", e.getMessage(), e); + return null; + }); + } } - ], - "messageId": "c4911b64c8404b7a8bf7200dd225b152" - } - } - }' + catch (Exception e) { + logger.error("Error saving state: {}", e.getMessage(), e); + } + } + }) + .doOnError(error -> { + logger.error("Error in agent stream: {}", error.getMessage(), error); + }); ``` -您将会看到以 **Server-Sent Events (SSE)** 格式流式输出 **A2A** 协议的响应: +- **无论成功/失败/取消**,在流结束时保存 Agent 的**最终状态**。 +- `roundId = null` → 自动分配新轮次 ID(见 `InMemoryStateService` 实现)。 +- 使用 `exceptionally` 处理保存异常,避免影响主流程。 -```json -event:jsonrpc -data:{"jsonrpc":"2.0","id":"xxx","result":{"taskId":"xxx","status":{"state":"working","message":{"role":"agent","parts":[{"text":"text","kind":"text"}],"messageId":"xxx","contextId":"xxx","taskId":"xxx","metadata":{},"kind":"message"},"timestamp":"xxx"},"contextId":"xxx","final":false,"kind":"status-update"}} -``` +> 🔁 实现了“状态持久化闭环”:加载 → 执行 → 保存。 -### 步骤7:使用沙箱工具(可选) +### 步骤2:构建 AgentApp -如果您想让智能体执行 Python 代码或使用其他沙箱工具,可以在创建智能体时添加相应的工具: +#### 2.1 导入依赖 ```java -// 对于 AgentScope Agent -Toolkit toolkit = new Toolkit(); -toolkit.registerTool(ToolkitInit.RunPythonCodeTool()); -toolkit.registerTool(ToolkitInit.RunShellCommandTool()); -toolkit.registerTool(ToolkitInit.BrowserNavigateTool()); - -// 对于 SAA Agent -Builder agentBuilder = ReactAgent.builder() - .name("Friday") - .model(chatModel) - .tools(List.of( - ToolcallsInit.RunPythonCodeTool(), - ToolcallsInit.RunShellCommandTool(), - ToolcallsInit.BrowserNavigateBackTool() - )); +import io.agentscope.runtime.app.AgentApp; +import io.agentscope.runtime.engine.services.agent_state.InMemoryStateService; +import io.agentscope.runtime.engine.services.memory.persistence.memory.service.InMemoryMemoryService; +import io.agentscope.runtime.engine.services.memory.persistence.session.InMemorySessionHistoryService; +import io.agentscope.runtime.engine.services.sandbox.SandboxService; +import io.agentscope.runtime.sandbox.manager.SandboxManager; +import io.agentscope.runtime.sandbox.manager.client.config.BaseClientConfig; +import io.agentscope.runtime.sandbox.manager.client.config.KubernetesClientConfig; +import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; +import org.jetbrains.annotations.NotNull; ``` -然后可以通过请求让智能体执行代码: +#### 2.2 构建 SandboxService 沙箱管理服务 -```bash -curl --location --request POST 'http://localhost:8090/a2a/' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "method": "message/stream", - "id": "test-id", - "jsonrpc": "2.0", - "params": { - "message": { - "role": "user", - "kind": "message", - "contextId": "id", - "metadata": { - "userId": "me", - "sessionId": "my_session" - }, - "parts": [ - { - "kind": "text", - "text": "Hello, please calculate the 10th Fibonacci number using Python" - } - ], - "messageId": "test-message-id" - } - } - }' +```java +private static SandboxService buidSandboxService() { + BaseClientConfig clientConfig = KubernetesClientConfig.builder().build(); + ManagerConfig managerConfig = ManagerConfig.builder() + .containerDeployment(clientConfig) + .build(); + return new SandboxService( + new SandboxManager(managerConfig) + ); +} ``` -## 完整示例 +* 沙箱运行环境支持 **Docker**、**K8s **以及 **AgentRun**,未配置 `clientConfig` 默认使用**本地 Docker **作为运行环境 +* 使用`managerConfig`构建 **SandboxManager**,并由此构建 **SandboxService** + +#### 2.3 构建 AgentApp -以下是一个完整的可运行示例: +##### 2.3.1 初始化 agentHandler ```java -import io.agentscope.core.ReActAgent; -import io.agentscope.core.formatter.dashscope.DashScopeChatFormatter; -import io.agentscope.core.memory.InMemoryMemory; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.runtime.LocalDeployManager; -import io.agentscope.runtime.engine.Runner; -import io.agentscope.runtime.engine.agents.agentscope.AgentScopeAgent; -import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit; -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.core.model.DashScopeChatModel; +MyAgentScopeAgentHandler agentHandler = new MyAgentScopeAgentHandler(); +agentHandler.setStateService(new InMemoryStateService()); +agentHandler.setSessionHistoryService(new InMemorySessionHistoryService()); +agentHandler.setMemoryService(new InMemoryMemoryService()); +agentHandler.setSandboxService(buidSandboxService()); +``` -public class QuickStartExample { - - public static void main(String[] args) { - // 检查 API 密钥 - if (System.getenv("AI_DASHSCOPE_API_KEY") == null) { - System.err.println("Please set the AI_DASHSCOPE_API_KEY environment variable"); - System.exit(1); - } - - try { - // 步骤1:初始化上下文管理器 - ContextManager contextManager = initializeContextManager(); - - // 步骤2:创建智能体 - AgentScopeAgent agent = createAgent(); - - // 步骤3:配置沙箱管理器 - EnvironmentManager environmentManager = createEnvironmentManager(); - - // 步骤4:创建 Runner - Runner runner = Runner.builder() - .agent(agent) - .contextManager(contextManager) - .environmentManager(environmentManager) - .build(); - - // 步骤5:部署智能体 - LocalDeployManager.builder() - .port(8090) - .build() - .deploy(runner); - - System.out.println("✅ Agent deployed successfully on http://localhost:8090"); - - } catch (Exception e) { - System.err.println("Failed to deploy agent: " + e.getMessage()); - e.printStackTrace(); +实例化刚刚编写的 **AgentScopeAgentHandler** 类,并注册服务 + +##### 2.3.2 构建 AgentApp 并一键启动 + +```java +AgentApp agentApp = new AgentApp(agentHandler); +agentApp.run(10001); +``` + +使用实例化的 **AgentScopeAgentHandler** 类初始化 **AgentApp**,并在10001端口上启动 + +### 步骤3:通过 A2A 协议访问 Agent + +```bash +curl --location --request POST 'http://localhost:10001/a2a/' \ +--header 'Content-Type: application/json' \ +--header 'Accept: */*' \ +--header 'Host: localhost:10001' \ +--header 'Connection: keep-alive' \ +--data-raw '{ + "method": "message/stream", + "id": "2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc", + "jsonrpc": "2.0", + "params": { + "configuration": { + "blocking": false + }, + "message": { + "role": "user", + "kind": "message", + "metadata": { + "userId": "me", + "sessionId": "test1" + }, + "parts": [ + { + "text": "你好,给我用python计算一下第10个斐波那契数", + "kind": "text" } + ], + "messageId": "c4911b64c8404b7a8bf7200dd225b152" } - - private static ContextManager initializeContextManager() throws Exception { - SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); - MemoryService memoryService = new InMemoryMemoryService(); - - ContextManager contextManager = new ContextManager( - ContextComposer.class, - sessionHistoryService, - memoryService - ); - - sessionHistoryService.start().get(); - memoryService.start().get(); - contextManager.start().get(); - - return contextManager; - } - - private static AgentScopeAgent createAgent() { - Toolkit toolkit = new Toolkit(); - toolkit.registerTool(ToolkitInit.RunPythonCodeTool()); - - ReActAgent.Builder agentBuilder = ReActAgent.builder() - .name("Friday") - .sysPrompt("You're a helpful assistant named Friday.") - .toolkit(toolkit) - .memory(new InMemoryMemory()) - .model(DashScopeChatModel.builder() - .apiKey(System.getenv("AI_DASHSCOPE_API_KEY")) - .modelName("qwen-turbo") - .stream(true) - .formatter(new DashScopeChatFormatter()) - .build()); - - return AgentScopeAgent.builder() - .agent(agentBuilder) - .build(); - } - - private static EnvironmentManager createEnvironmentManager() { - ManagerConfig managerConfig = ManagerConfig.builder().build(); - SandboxManager sandboxManager = new SandboxManager(managerConfig); - return new DefaultEnvironmentManager(sandboxManager); - } -} + } +}' ``` -## 下一步 +你将会看到以**Server-Sent Events(SSE)**格式流式输出的响应: + +``` +id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc +event:jsonrpc +data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"id":"92ccdc36-006f-4d66-a47c-18d0cb171506","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","status":{"state":"submitted","timestamp":"2025-12-09T10:53:47.612001Z"},"artifacts":[],"history":[{"role":"user","parts":[{"text":"你好,给我用python计算一下第10个斐波那契数","kind":"text"}],"messageId":"c4911b64c8404b7a8bf7200dd225b152","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","metadata":{"userId":"me","sessionId":"test1"},"kind":"message"}],"kind":"task"}} + +id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc +event:jsonrpc +data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","status":{"state":"working","timestamp":"2025-12-09T10:53:47.614736Z"},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","final":false,"kind":"status-update"}} + +...... + +id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc +event:jsonrpc +data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","artifact":{"artifactId":"293bb1b0-1442-4ca2-997f-575b798dfad1","name":"agent-response","parts":[{"text":"是55。","kind":"text"}],"metadata":{"type":"chunk"}},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","append":true,"lastChunk":false,"kind":"artifact-update"}} + +id:2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc +event:jsonrpc +data:{"jsonrpc":"2.0","id":"2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc","result":{"taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","status":{"state":"completed","message":{"role":"agent","parts":[{"text":"run_ipython_cellrun_ipython_cell第10个斐波那契数是55。","kind":"text"}],"messageId":"7b878071-d63e-4710-81e0-91d50a57c373","contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","taskId":"92ccdc36-006f-4d66-a47c-18d0cb171506","metadata":{"type":"final_response"},"kind":"message"},"timestamp":"2025-12-09T10:53:51.538933Z"},"contextId":"fd5bccd1-770f-4872-8c9a-f086c094f90a","final":true,"kind":"status-update"}} +``` -- 浏览 **完整实现示例** 在 `examples/simple_agent_use_examples` 目录中 -- 查看 **协议文档** 了解 A2A 协议和其他通信方式 -- 了解 **上下文管理器** 和 **记忆服务** 的详细用法 -- 探索 **沙箱工具** 和 **环境管理器** 的配置选项 +## 章节导读 -更多详细信息,请参考: -- {doc}`manager` - 管理器模块文档 -- {doc}`context_manager` - 上下文管理器文档 -- {doc}`protocol` - 协议文档 -- {doc}`environment_manager` - 环境管理器文档 +后续的章节包括如下几个部分 +- [沙箱与工具](tool.md): 帮助您在Agent中加入工具 +- [部署](deployment.md): 帮助您部署Agent,打包成服务 +- [使用](use.md): 帮助您调用部署后的服务 +- [如何贡献](contribute.md): 贡献代码给本项目的参考文档 \ No newline at end of file diff --git a/cookbook/zh/react_agent.md b/cookbook/zh/react_agent.md deleted file mode 100644 index fedc0013..00000000 --- a/cookbook/zh/react_agent.md +++ /dev/null @@ -1,325 +0,0 @@ -# 部署配备工具沙箱的ReAct智能体 - -本教程演示了如何使用AgentScope Runtime Java与[**AgentScope Java框架**](https://github.com/agentscope-ai/agentscope-java)创建和部署 *"推理与行动"(ReAct)* 智能体。 - -```{note} -ReAct(推理与行动)范式使智能体能够将推理轨迹与特定任务的行动交织在一起,使其在工具交互任务中特别有效。通过将AgentScope的`ReActAgent`与AgentScope Runtime的基础设施相结合,您可以同时获得智能决策和安全的工具执行。 -``` - -## 前置要求 - -### 🔧 安装要求 - -- **Java 17** 或更高版本 -- **Maven 3.6+** -- **Docker**(用于沙箱工具执行) - -### 📦 项目依赖 - -在您的 `pom.xml` 文件中添加以下依赖: - -```xml - - - - io.agentscope - agentscope-runtime-core - 0.1.1 - - - - - io.agentscope - agentscope-runtime-agentscope - 0.1.1 - - - - - io.agentscope - agentscope-runtime-web - 0.1.1 - - -``` - -### 🐳 沙箱设置 - -```{note} -确保您的浏览器沙箱环境已准备好使用,详细信息请参见{doc}`sandbox`。 -``` - -确保浏览器沙箱镜像可用: - -```bash -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest agentscope/runtime-sandbox-browser:latest -``` - -### 🔑 API密钥配置 - -您需要为您选择的LLM提供商准备API密钥。此示例使用DashScope(Qwen),但您可以将其适配到其他提供商: - -```bash -export AI_DASHSCOPE_API_KEY="your_api_key_here" -``` - -## 分步实现 - -### 步骤1:导入依赖项 - -首先导入所有必要的模块: - -```java -import io.agentscope.core.ReActAgent; -import io.agentscope.core.formatter.dashscope.DashScopeChatFormatter; -import io.agentscope.core.memory.InMemoryMemory; -import io.agentscope.core.tool.Toolkit; -import io.agentscope.runtime.LocalDeployManager; -import io.agentscope.runtime.engine.Runner; -import io.agentscope.runtime.engine.agents.agentscope.AgentScopeAgent; -import io.agentscope.runtime.engine.agents.agentscope.tools.ToolkitInit; -import io.agentscope.runtime.engine.memory.context.ContextManager; -import io.agentscope.runtime.engine.memory.context.ContextComposer; -import io.agentscope.runtime.engine.memory.persistence.memory.service.InMemoryMemoryService; -import io.agentscope.runtime.engine.memory.persistence.session.InMemorySessionHistoryService; -import io.agentscope.runtime.engine.memory.service.MemoryService; -import io.agentscope.runtime.engine.memory.service.SessionHistoryService; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -``` - -### 步骤2:配置浏览器工具 - -定义您的智能体可访问的浏览器工具(如果您想为智能体配置其他工具,请参考{doc}`sandbox`中的工具用法): - -```java -// 创建工具包 -Toolkit toolkit = new Toolkit(); - -// 注册浏览器工具 -toolkit.registerTool(ToolkitInit.BrowserNavigateTool()); -toolkit.registerTool(ToolkitInit.BrowserTakeScreenshotTool()); -toolkit.registerTool(ToolkitInit.BrowserSnapshotTool()); -toolkit.registerTool(ToolkitInit.BrowserClickTool()); -toolkit.registerTool(ToolkitInit.BrowserTypeTool()); - -System.out.println("✅ 已配置浏览器工具"); -``` - -**可用的浏览器工具包括:** -- `BrowserNavigateTool()` - 导航到指定URL -- `BrowserClickTool()` - 点击页面元素 -- `BrowserTypeTool()` - 在页面中输入文本 -- `BrowserTakeScreenshotTool()` - 截取页面截图 -- `BrowserSnapshotTool()` - 获取页面快照 -- `BrowserTabNewTool()` - 创建新标签页 -- `BrowserTabSelectTool()` - 选择标签页 -- `BrowserTabCloseTool()` - 关闭标签页 -- `BrowserWaitForTool()` - 等待页面元素 -- `BrowserResizeTool()` - 调整浏览器窗口大小 -- `BrowserCloseTool()` - 关闭浏览器 -- `BrowserConsoleMessagesTool()` - 获取控制台消息 -- `BrowserHandleDialogTool()` - 处理对话框 -- `BrowserFileUploadTool()` - 上传文件 -- `BrowserPressKeyTool()` - 按键操作 -- `BrowserNavigateBackTool()` - 后退 -- `BrowserNavigateForwardTool()` - 前进 -- `BrowserNetworkRequestsTool()` - 获取网络请求 -- `BrowserPdfSaveTool()` - 保存PDF -- `BrowserDragTool()` - 拖拽操作 -- `BrowserHoverTool()` - 悬停操作 -- `BrowserSelectOptionTool()` - 选择选项 -- `BrowserTabListTool()` - 列出标签页 - -### 步骤3:定义系统提示词 - -创建一个系统提示词,为您的智能体建立角色、目标和网页浏览任务的操作指南: - -```java -String SYSTEM_PROMPT = """You are a Web-Using AI assistant. - -# Objective -Your goal is to complete given tasks by controlling a browser to navigate web pages. - -## Web Browsing Guidelines -- Use the `browser_navigate` command to jump to specific webpages when needed. -- Use `generate_response` to answer the user once you have all the required information. -- Always answer in English. - -### Observing Guidelines -- Always take action based on the elements on the webpage. Never create URLs or generate new pages. -- If the webpage is blank or an error, such as 404, is found, try refreshing it or go back to the previous page and find another webpage. -"""; - -System.out.println("✅ 系统提示词已配置"); -``` - -### 步骤4:初始化上下文管理器 - -初始化上下文管理器以管理会话历史和记忆: - -```java -private ContextManager initializeContextManager() throws Exception { - // 创建会话历史服务 - SessionHistoryService sessionHistoryService = new InMemorySessionHistoryService(); - - // 创建记忆服务 - MemoryService memoryService = new InMemoryMemoryService(); - - // 创建上下文管理器 - ContextManager contextManager = new ContextManager( - ContextComposer.class, - sessionHistoryService, - memoryService - ); - - // 启动服务 - sessionHistoryService.start().get(); - memoryService.start().get(); - contextManager.start().get(); - - System.out.println("✅ ContextManager initialized successfully"); - return contextManager; -} -``` - -### 步骤5:初始化智能体和模型 - -使用AgentScope框架中您选择的大模型设置ReAct智能体: - -```java -// 创建工具包 -Toolkit toolkit = new Toolkit(); -toolkit.registerTool(ToolkitInit.BrowserNavigateTool()); -toolkit.registerTool(ToolkitInit.BrowserClickTool()); -toolkit.registerTool(ToolkitInit.BrowserTypeTool()); -toolkit.registerTool(ToolkitInit.BrowserTakeScreenshotTool()); -toolkit.registerTool(ToolkitInit.BrowserSnapshotTool()); - -// 创建 ReActAgent -ReActAgent.Builder agentBuilder = ReActAgent.builder() - .name("Friday") - .sysPrompt(SYSTEM_PROMPT) - .toolkit(toolkit) - .memory(new InMemoryMemory()) - .model(io.agentscope.core.model.DashScopeChatModel.builder() - .apiKey(System.getenv("AI_DASHSCOPE_API_KEY")) - .modelName("qwen-max") - .stream(true) - .enableThinking(true) - .formatter(new DashScopeChatFormatter()) - .build()); - -// 创建 AgentScopeAgent -AgentScopeAgent agentScopeAgent = AgentScopeAgent.builder() - .agent(agentBuilder) - .build(); - -System.out.println("✅ 智能体初始化成功"); -``` - -### 步骤6:配置沙箱管理器 - -配置沙箱管理器以支持浏览器工具执行: - -```java -// 创建沙箱管理器配置(使用默认Docker配置) -ManagerConfig managerConfig = ManagerConfig.builder().build(); - -// 创建沙箱管理器 -SandboxManager sandboxManager = new SandboxManager(managerConfig); - -// 创建环境管理器 -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -System.out.println("✅ 沙箱管理器配置成功"); -``` - -### 步骤7:创建 Runner - -Runner 将智能体、上下文管理器和环境管理器组合在一起: - -```java -Runner runner = Runner.builder() - .agent(agentScopeAgent) - .contextManager(contextManager) - .environmentManager(environmentManager) - .build(); - -System.out.println("✅ Runner created successfully"); -``` - -### 步骤8:部署智能体 - -使用 `LocalDeployManager` 将智能体部署为 A2A 服务: - -```java -LocalDeployManager.builder() - .port(8090) - .build() - .deploy(runner); - -System.out.println("✅ Agent deployed successfully on port 8090"); -``` - -运行后,服务器会启动并监听:`http://localhost:8090/a2a/` - -### 步骤9:发送请求 - -您可以使用 `curl` 向 A2A API 发送请求: - -```bash -curl --location --request POST 'http://localhost:8090/a2a/' \ - --header 'Content-Type: application/json' \ - --data-raw '{ - "method": "message/stream", - "id": "2d2b4dc8-8ea2-437b-888d-3aaf3a8239dc", - "jsonrpc": "2.0", - "params": { - "message": { - "role": "user", - "kind": "message", - "contextId": "id", - "metadata": { - "userId": "me", - "sessionId": "my_session" - }, - "parts": [ - { - "kind": "text", - "text": "Navigate to https://example.com and tell me what is on the page" - } - ], - "messageId": "c4911b64c8404b7a8bf7200dd225b152" - } - } - }' -``` - -您将会看到以 **Server-Sent Events (SSE)** 格式流式输出 **A2A** 协议的响应: - -```json -event:jsonrpc -data:{"jsonrpc":"2.0","id":"xxx","result":{"taskId":"xxx","status":{"state":"working","message":{"role":"agent","parts":[{"text":"text","kind":"text"}],"messageId":"xxx","contextId":"xxx","taskId":"xxx","metadata":{},"kind":"message"},"timestamp":"xxx"},"contextId":"xxx","final":false,"kind":"status-update"}} -``` - -## 总结 - -通过遵循这些步骤,您已经成功设置、交互并部署了使用AgentScope框架和AgentScope Runtime的ReAct智能体。此配置允许智能体在沙箱环境中安全地使用浏览器工具,确保安全有效的网页交互。根据需要调整系统提示词、工具或模型,以自定义智能体的行为来适应特定任务或应用程序。 - -除了基本的 HTTP API 访问外,您还可以使用不同的协议与智能体进行交互,例如:Response API、Agent API等。详情请参考 {doc}`protocol`。 - -## 下一步 - -- 浏览 **完整实现示例** 在 `examples/browser_use_fullstack_runtime` 目录中 -- 查看 **协议文档** 了解 A2A 协议和其他通信方式 -- 了解 **沙箱工具** 和 **环境管理器** 的配置选项 -- 探索更多浏览器工具的功能和使用方法 - -更多详细信息,请参考: -- {doc}`quickstart` - 快速开始指南 -- {doc}`manager` - 管理器模块文档 -- {doc}`protocol` - 协议文档 -- {doc}`sandbox` - 沙箱文档 diff --git a/cookbook/zh/sandbox.md b/cookbook/zh/sandbox.md deleted file mode 100644 index 5f33c727..00000000 --- a/cookbook/zh/sandbox.md +++ /dev/null @@ -1,379 +0,0 @@ -# 工具沙箱 - -AgentScope Runtime Java 的 Sandbox 提供了一个**安全**且**隔离**的环境,用于工具执行、浏览器自动化、文件系统操作、训练评测等功能。在本教程中,您将学习如何设置工具沙箱依赖项并在沙箱环境中运行工具。 - -## 前提条件 - -```{note} -当前的沙箱环境默认使用 Docker 进行隔离。此外,我们还支持 Kubernetes (K8s) 和 阿里云函数计算Agentrun 作为远程服务后端。未来,我们计划在即将发布的版本中加入更多第三方托管解决方案。 -``` - -````{warning} -对于使用**苹果芯片**(如M1/M2)的设备,我们建议以下选项来运行**x86** Docker环境以获得最大兼容性: -* Docker Desktop:请参阅[Docker Desktop安装指南](https://docs.docker.com/desktop/setup/install/mac-install/)以启用Rosetta2,确保与x86_64镜像的兼容性。 -* Colima:确保启用Rosetta 2支持。您可以使用以下命令启动[Colima](https://github.com/abiosoft/colima)以实现兼容性:`colima start --vm-type=vz --vz-rosetta --memory 8 --cpu 1` -```` - -- Docker -- (可选,仅支持远程模式)Kubernetes -- (可选)阿里云函数计算 Agentrun -- Java 8 或更高版本 -- Maven 或 Gradle - -## 安装 - -### 安装依赖项 - -首先,在您的 Maven 项目中添加 AgentScope Runtime 依赖: - -```xml - - io.agentscope - agentscope-runtime-core - 0.1.1 - -``` - -### 准备Docker镜像 - -沙箱为不同功能使用不同的Docker镜像。您可以只拉取需要的镜像,或者拉取所有镜像以获得完整功能: - -#### 选项1:拉取所有镜像(推荐) - -为了确保完整的沙箱体验并启用所有功能,请按照以下步骤从我们的仓库拉取并标记必要的Docker镜像: - -```{note} -**镜像来源:阿里云容器镜像服务** - -所有Docker镜像都托管在阿里云容器镜像服务(ACR)上,以在全球范围内实现可获取和可靠性。镜像从ACR拉取后使用标准名称重命名,以与AgentScope Runtime无缝集成。 -``` - -```bash -# 基础镜像 -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-base:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-base:latest agentscope/runtime-sandbox-base:latest - -# GUI镜像 -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-gui:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-gui:latest agentscope/runtime-sandbox-gui:latest - -# 文件系统镜像 -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-filesystem:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-filesystem:latest agentscope/runtime-sandbox-filesystem:latest - -# 浏览器镜像 -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-browser:latest agentscope/runtime-sandbox-browser:latest -``` - -#### 选项2:拉取特定镜像 - -根据您的具体需求选择镜像: - -| Image | Purpose | When to Use | -| -------------------- | ------------------------- | ------------------------------------------------------------ | -| **Base Image** | Python代码执行,shell命令 | 基本工具执行必需 | -| **GUI Image** | 计算机操作 | 当你需要图形操作页面时 | -| **Filesystem Image** | 文件系统操作 | 当您需要文件读取/写入/管理时 | -| **Browser Image** | Web浏览器自动化 | 当您需要网络爬取或浏览器控制时 | -| **Training Image** | 训练和评估智能体 | 当你需要在某些基准数据集上训练和评估智能体时 (详情请参考 {doc}`training_sandbox` ) | - -### 验证安装 - -您可以通过创建并运行一个基础沙箱来验证一切设置是否正确: - -```java -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -public class SandboxVerification { - public static void main(String[] args) { - // 创建 SandboxManager - ManagerConfig managerConfig = ManagerConfig.builder().build(); - SandboxManager sandboxManager = new SandboxManager(managerConfig); - EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - - // 创建基础沙箱并执行测试代码 - try (BaseSandbox sandbox = new BaseSandbox(sandboxManager, "test_user", "test_session")) { - String result = sandbox.runIpythonCell("print('Setup successful!')"); - System.out.println(result); - } - } -} -``` - -### (可选)从头构建Docker镜像 - -如果您更倾向于在本地自己通过`Dockerfile`构建镜像或需要自定义修改,可以从头构建它们。请参阅{doc}`sandbox_advanced`了解详细说明。 - -## 沙箱使用 - -### 创建沙箱 - -在 Java 版本中,所有沙箱操作都需要先创建 `SandboxManager` 和 `EnvironmentManager`。然后通过沙箱类创建不同类型的沙箱实例。 - -**基础沙箱(Base Sandbox)**:用于在隔离环境中运行 **Python 代码** 或 **Shell 命令**。 - -```java -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -try (BaseSandbox sandbox = new BaseSandbox(sandboxManager, "user_1", "session_1")) { - // 列出所有可用工具 - System.out.println(sandbox.listTools("all")); - - // 执行 Python 代码 - System.out.println(sandbox.runIpythonCell("print('hi')")); - - // 执行 Shell 命令 - System.out.println(sandbox.runShellCommand("echo hello")); -} -``` - -**GUI 沙箱 (GUI Sandbox)**: 提供**可视化桌面环境**,可执行鼠标、键盘以及屏幕相关操作。 - -GUI Sandbox - -```java -import io.agentscope.runtime.sandbox.box.GuiSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import java.util.ArrayList; -import java.util.List; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -try (GuiSandbox sandbox = new GuiSandbox(sandboxManager, "user_1", "session_1")) { - // 列出所有可用工具 - System.out.println(sandbox.listTools("all")); - - // 获取桌面访问链接 - System.out.println("Desktop URL: " + sandbox.getDesktopUrl()); - - // 获取鼠标位置 - System.out.println(sandbox.computerUse("get_cursor_position")); - - // 获取屏幕截图 - System.out.println(sandbox.computerUse("get_screenshot")); -} -``` - -**文件系统沙箱 (Filesystem Sandbox)**:基于 GUI 的隔离沙箱,可进行文件系统操作,如创建、读取和删除文件。 - -GUI Sandbox - -```java -import io.agentscope.runtime.sandbox.box.FilesystemSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -try (FilesystemSandbox sandbox = new FilesystemSandbox(sandboxManager, "user_1", "session_1")) { - // 列出所有可用工具 - System.out.println(sandbox.listTools("all")); - - // 获取桌面访问链接 - System.out.println("Desktop URL: " + sandbox.getDesktopUrl()); - - // 创建目录 - System.out.println(sandbox.createDirectory("test")); -} -``` - -**浏览器沙箱(Browser Sandbox)**: 基于 GUI 的沙箱,可进行浏览器操作。 - -GUI Sandbox - -```java -import io.agentscope.runtime.sandbox.box.BrowserSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -try (BrowserSandbox sandbox = new BrowserSandbox(sandboxManager, "user_1", "session_1")) { - // 列出所有可用工具 - System.out.println(sandbox.listTools("all")); - - // 获取浏览器桌面访问链接 - System.out.println("Desktop URL: " + sandbox.getDesktopUrl()); - - // 打开网页 - System.out.println(sandbox.navigate("https://www.google.com/")); -} -``` - -**TrainingSandbox**:训练评估沙箱,详情请参考:{doc}`training_sandbox`。 - -```java -import io.agentscope.runtime.sandbox.box.TrainingSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.sandbox.manager.model.container.SandboxType; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -// 创建训练评估用沙箱 -try (TrainingSandbox sandbox = new TrainingSandbox( - sandboxManager, - "user_1", - "session_1", - SandboxType.BASE)) { - String profileList = sandbox.getEnvProfile("appworld", "train", null); - System.out.println(profileList); -} -``` - -```{note} -我们很快会扩展更多类型的沙箱——敬请期待! -``` - -### 向沙箱添加MCP服务器 - -MCP(模型上下文协议)是一个标准化协议,使AI应用程序能够安全地连接到外部数据源和工具。通过将MCP服务器集成到您的沙箱中,您可以在不影响安全性的情况下使用专门的工具和服务扩展沙箱的功能。 - -沙箱支持通过`addMcpServers`方法集成MCP服务器。添加后,您可以使用`listTools`发现可用工具并使用`callTool`执行它们。以下是添加提供时区感知的MCP的示例: - -```java -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import java.util.HashMap; -import java.util.Map; - -ManagerConfig managerConfig = ManagerConfig.builder().build(); -SandboxManager sandboxManager = new SandboxManager(managerConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - -try (BaseSandbox sandbox = new BaseSandbox(sandboxManager, "user_1", "session_1")) { - Map mcpServerConfigs = new HashMap<>(); - Map timeServer = new HashMap<>(); - timeServer.put("command", "uvx"); - timeServer.put("args", new String[]{ - "mcp-server-time", - "--local-timezone=America/New_York" - }); - - Map mcpServers = new HashMap<>(); - mcpServers.put("time", timeServer); - mcpServerConfigs.put("mcpServers", mcpServers); - - // 将MCP服务器添加到沙箱 - sandbox.addMcpServers(mcpServerConfigs, false); - - // 列出所有可用工具(现在包括MCP工具) - System.out.println(sandbox.listTools("all")); - - // 使用MCP服务器提供的时间工具 - Map arguments = new HashMap<>(); - arguments.put("timezone", "America/New_York"); - System.out.println(sandbox.callTool("get_current_time", arguments)); -} -``` - -### 连接到远程沙箱 - -```{note} -沙箱远程部署特别适用于: -* 将计算密集型任务分离到专用服务器 -* 多个客户端共享同一沙箱环境 -* 在资源受限的本地机器上开发,同时在高性能服务器上执行 -* K8S集群部署沙盒服务 - -有关sandbox-server的更高级用法,请参阅{doc}`sandbox_advanced`了解详细说明。 -``` - -要连接到远程沙箱服务,需要在 `ManagerConfig` 中配置 `baseUrl`: - -```java -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; - -// 配置远程沙箱服务器地址 -ManagerConfig remoteConfig = ManagerConfig.builder() - .baseUrl("http://your_IP_address:10001") - .bearerToken("optional-token") // 可选:如果需要认证 - .build(); - -SandboxManager remoteManager = new SandboxManager(remoteConfig); -EnvironmentManager environmentManager = new DefaultEnvironmentManager(remoteManager); - -try (BaseSandbox sandbox = new BaseSandbox(remoteManager, "user_1", "session_1")) { - System.out.println(sandbox.runIpythonCell("print('hi')")); -} -``` - -## 工具列表 - -* 基础工具(在所有沙箱类型中可用) -* 计算机操作工具(在`GuiSandbox`中可用) -* 文件系统工具(在`FilesystemSandbox`中可用) -* 浏览器工具(在`BrowserSandbox`中可用) - -| 分类 | 工具名称 | 描述 | -| ------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -| **基础工具** | `runIpythonCell(code: String)` | 在IPython环境中执行Python代码 | -| | `runShellCommand(command: String)` | 在沙箱中执行shell命令 | -| **文件系统工具** | `readFile(path: String)` | 读取文件的完整内容 | -| | `readMultipleFiles(paths: List)` | 同时读取多个文件 | -| | `writeFile(path: String, content: String)` | 创建或覆盖文件内容 | -| | `editFile(path: String, edits: Object[], dryRun: boolean)` | 对文本文件进行基于行的编辑 | -| | `createDirectory(path: String)` | 创建新目录 | -| | `listDirectory(path: String)` | 列出路径中的所有文件和目录 | -| | `directoryTree(path: String)` | 获取目录结构的递归树视图 | -| | `moveFile(source: String, destination: String)` | 移动或重命名文件和目录 | -| | `searchFiles(path: String, pattern: String, excludePatterns: String[])` | 搜索匹配模式的文件 | -| | `getFileInfo(path: String)` | 获取文件或目录的详细元数据 | -| | `listAllowedDirectories()` | 列出服务器可以访问的目录 | -| **浏览器工具** | `navigate(url: String)` | 导航到特定URL | -| | `navigateBack()` | 返回到上一页 | -| | `navigateForward()` | 前进到下一页 | -| | `closeBrowser()` | 关闭当前浏览器页面 | -| | `resize(width: Double, height: Double)` | 调整浏览器窗口大小 | -| | `click(element: String, ref: String)` | 点击Web元素 | -| | `type(element: String, ref: String, text: String)` | 在输入框中输入文本 | -| | `hover(element: String, ref: String)` | 悬停在Web元素上 | -| | `drag(startElement: String, startRef: String, endElement: String, endRef: String)` | 在元素之间拖拽 | -| | `selectOption(element: String, ref: String, values: String[])` | 在下拉菜单中选择选项 | -| | `pressKey(key: String)` | 按键盘按键 | -| | `fileUpload(paths: String[])` | 上传文件到页面 | -| | `snapshot()` | 捕获当前页面的可访问性快照 | -| | `takeScreenshot(raw: Boolean, filename: String, element: String, ref: String)` | 截取页面或元素的屏幕快照 | -| | `pdfSave(filename: String)` | 将当前页面保存为PDF | -| | `tabList()` | 列出所有打开的浏览器标签页 | -| | `tabNew(url: String)` | 打开新标签页 | -| | `tabSelect(index: Integer)` | 切换到特定标签页 | -| | `tabClose(index: Integer)` | 关闭标签页(如果未指定索引则关闭当前标签页) | -| | `waitFor(time: Double, text: String, textGone: String)` | 等待条件或时间流逝 | -| | `consoleMessages()` | 获取页面的所有控制台消息 | -| | `networkRequests()` | 获取页面加载以来的所有网络请求 | -| | `handleDialog(accept: Boolean, promptText: String)` | 处理浏览器对话框(警告、确认、提示) | -| **计算机操作工具** | `computerUse(action: String, coordinate: List, text: String)` | 使用鼠标和键盘与桌面 GUI 互动,支持以下操作:移动光标、点击、输入文字以及截图 | diff --git a/cookbook/new-zh/sandbox/advanced.md b/cookbook/zh/sandbox/advanced.md similarity index 100% rename from cookbook/new-zh/sandbox/advanced.md rename to cookbook/zh/sandbox/advanced.md diff --git a/cookbook/new-zh/sandbox/sandbox.md b/cookbook/zh/sandbox/sandbox.md similarity index 100% rename from cookbook/new-zh/sandbox/sandbox.md rename to cookbook/zh/sandbox/sandbox.md diff --git a/cookbook/new-zh/sandbox/training_sandbox.md b/cookbook/zh/sandbox/training_sandbox.md similarity index 100% rename from cookbook/new-zh/sandbox/training_sandbox.md rename to cookbook/zh/sandbox/training_sandbox.md diff --git a/cookbook/new-zh/sandbox/troubleshooting.md b/cookbook/zh/sandbox/troubleshooting.md similarity index 100% rename from cookbook/new-zh/sandbox/troubleshooting.md rename to cookbook/zh/sandbox/troubleshooting.md diff --git a/cookbook/zh/sandbox_advanced.md b/cookbook/zh/sandbox_advanced.md deleted file mode 100644 index 5ff00d8f..00000000 --- a/cookbook/zh/sandbox_advanced.md +++ /dev/null @@ -1,295 +0,0 @@ -# 工具沙箱高级用法 - -```{note} -本节介绍 Java 版本的沙箱高级用法。我们强烈建议在继续之前先完成上一节的基础教程({doc}`sandbox`)。 -``` - -## 远程沙箱服务概览 - -AgentScope Runtime Java 通过 `SandboxManagerController` 暴露与 Python 版本等价的远程管理接口。只要为 `Runner` 启动一个 `LocalDeployManager`,所有带有 `@RemoteWrapper` 注解的方法都会自动映射为 REST API,客户端只需在 `ManagerConfig` 中配置 `baseUrl` 即可透明地调用远程沙箱。 - -### 使用 LocalDeployManager 启动沙箱控制器 - -下面的示例演示如何在本机 `0.0.0.0:10001` 上启动远程沙箱控制器。示例中的 `NoopAgent` 仅用于满足 `Runner` 的依赖;在实际业务中可以替换为任意 Agent 实现。 - -```java -import io.agentscope.runtime.LocalDeployManager; -import io.agentscope.runtime.engine.Runner; -import io.agentscope.runtime.engine.agents.Agent; -import io.agentscope.runtime.engine.agents.AgentConfig; -import io.agentscope.runtime.engine.agents.BaseAgent; -import io.agentscope.runtime.engine.schemas.message.Event; -import io.agentscope.runtime.engine.schemas.context.Context; -import io.agentscope.runtime.engine.service.EnvironmentManager; -import io.agentscope.runtime.engine.service.impl.DefaultEnvironmentManager; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import reactor.core.publisher.Flux; - -public final class SandboxServerExample { - - private static final class NoopAgent extends BaseAgent { - NoopAgent() { - super(new AgentConfig()); - } - - @Override - protected Flux execute(Context context, boolean stream) { - AgentResponse response = new AgentResponse(); - response.created(); - response.completed(); - return Flux.just(response); - } - - @Override - public Agent copy() { - return new NoopAgent(); - } - } - - public static void main(String[] args) { - ManagerConfig managerConfig = ManagerConfig.builder() - .poolSize(2) - .build(); - - SandboxManager sandboxManager = new SandboxManager(managerConfig); - EnvironmentManager environmentManager = new DefaultEnvironmentManager(sandboxManager); - - Runner runner = Runner.builder() - .agent(new NoopAgent()) - .environmentManager(environmentManager) - .build(); - - LocalDeployManager deployManager = LocalDeployManager.builder() - .endpointName("sandbox-manager") - .host("0.0.0.0") - .port(10001) - .build(); - - deployManager.deploy(runner); - Runtime.getRuntime().addShutdownHook(new Thread(deployManager::shutdown)); - } -} -``` - -> **提示**:示例依赖 `reactor-core`,请确认已经引入 `spring-boot-starter-web` 或显式添加 `reactor-core` 依赖。 - -### HTTP 接口概览 - -部署后,`SandboxManagerController` 默认以 `/` 为前缀暴露接口。所有响应均为 JSON,并在 `data` 字段返回有效载荷。常用端点如下表所示: - -| Path | 方法 | 作用 | 关键请求字段 | -| --- | --- | --- | --- | -| `/createFromPool` | POST | 为指定用户/会话分配或复用容器 | `sandboxType`, `userID`, `sessionID` | -| `/createContainer` | POST | 创建指定类型的沙箱容器 | `sandboxType`, `mountDir`, `storagePath`, `environment` | -| `/startSandbox` / `/stopSandbox` | POST | 启动或暂停现有沙箱 | `sandboxType`, `userID`, `sessionID` | -| `/getSandboxStatus` | POST | 查询沙箱运行状态 | `sandboxType`, `userID`, `sessionID` | -| `/getInfo` | POST | 根据名称/ID/会话ID 返回容器详情 | `identity` | -| `/release` | POST | 销毁并释放容器资源 | `identity` | -| `/listTools` | POST | 列出沙箱内可用工具 | `sandboxId`, `userId`, `sessionId`, `toolType` | -| `/callTool` | POST | 执行指定工具 | `sandboxId`, `toolName`, `arguments` | -| `/addMcpServers` | POST | 向沙箱注册 MCP 服务 | `sandboxId`, `serverConfigs`, `overwrite` | -| `/cleanupAllSandboxes` | POST | 停止并移除所有托管容器 | 无 | - -> **说明**:如果需要为接口增加 Token 校验,可在 Spring 容器中添加自定义过滤器;客户端可通过 `ManagerConfig.builder().bearerToken("token")` 自动携带 `Authorization: Bearer ...` 头部。 - -### 将客户端切换到远程模式 - -当 `ManagerConfig` 设置了 `baseUrl` 时,`SandboxManager` 会切换到远程模式,所有调用都会通过 `RemoteHttpClient` 转发到前文启动的服务: - -```java -import io.agentscope.runtime.sandbox.box.BaseSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; - -ManagerConfig remoteConfig = ManagerConfig.builder() - .baseUrl("http://127.0.0.1:10001") - .bearerToken("optional-token") - .build(); - -SandboxManager remoteManager = new SandboxManager(remoteConfig); - -try (BaseSandbox sandbox = new BaseSandbox(remoteManager, "user_1", "session_1")) { - String result = sandbox.runIpythonCell("print(\"Hello Sandbox\")"); - System.out.println(result); -} -``` - -如果未提供 `bearerToken`,客户端仍会尝试调用远程接口。需要鉴权时,请确保服务端已实现认证逻辑。 - -## ManagerConfig 进阶配置 - -`ManagerConfig` 控制了沙箱的容器后端、文件系统、端口策略、Redis 缓存等高级行为。下表列出了常用选项: - -| 配置项 | 说明 | 默认值 / 示例 | -| --- | --- | --- | -| `containerPrefixKey` | 新建容器名称前缀 | `runtime_sandbox_container_` | -| `poolSize` | 预热容器池容量(0 表示禁用) | `0` | -| `portRange(start, end)` | 动态端口分配范围 | `49152` - `59152` | -| `fileSystemConfig.mountDir` | 宿主机挂载目录 | `sessions_mount_dir` | -| `fileSystemConfig.storageFolderPath` | 持久化同步目录(上传/下载) | `""` | -| `fileSystemConfig.readonlyMounts` | 只读挂载映射 | `null` | -| `redisConfig` | 启用 Redis 用于多进程共享容器信息 | `null` | -| `containerDeployment` | 容器后端(Docker/K8s/AgentRun) | Docker | -| `baseUrl` | 远程模式地址 | `null`(本地模式) | -| `bearerToken` | 远程模式下附加的认证 Token | `null` | - -### 配置示例:本地 Docker + 只读挂载 - -```java -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.sandbox.manager.model.fs.LocalFileSystemConfig; - -LocalFileSystemConfig fileSystemConfig = LocalFileSystemConfig.builder() - .mountDir("/var/agentscope/mounts") - .storageFolderPath("/var/agentscope/storage") - .addReadonlyMount("/etc/ssl/certs", "/etc/ssl/certs") - .build(); - -ManagerConfig managerConfig = ManagerConfig.builder() - .containerPrefixKey("sandbox_") - .poolSize(3) - .portRange(41000, 42000) - .fileSystemConfig(fileSystemConfig) - .build(); -``` - -> **提示**:挂载目录需提前创建并赋予 Docker 访问权限;`storageFolderPath` 会在释放容器时同步文件内容。 - -### 配置示例:Kubernetes 集群 - -```java -import io.agentscope.runtime.sandbox.manager.client.config.KubernetesClientConfig; - -ManagerConfig managerConfig = ManagerConfig.builder() - .containerDeployment( - KubernetesClientConfig.builder() - .kubeConfigPath(System.getenv("KUBECONFIG")) - .namespace("agentscope") - .build() - ) - .build(); -``` - -Kubernetes 模式会将沙箱以 Pod 的形式创建到指定命名空间,请确保镜像仓库凭证在集群中可用。 - -### 配置示例:启用 Redis 共享池 - -```java -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; -import io.agentscope.runtime.sandbox.manager.model.container.RedisManagerConfig; - -RedisManagerConfig redisConfig = RedisManagerConfig.builder() - .redisServer("redis.internal") - .redisPort(6380) - .redisPassword("s3cret") - .redisPortKey("_runtime_ports") - .redisContainerPoolKey("_runtime_pool") - .build(); - -ManagerConfig managerConfig = ManagerConfig.builder() - .redisConfig(redisConfig) - .poolSize(10) - .build(); -``` - -启用 Redis 后,多个进程可以共享容器映射与端口占用信息,适用于多副本或水平扩展场景。 - -### 配置示例:部署到 AgentRun - -```java -import io.agentscope.runtime.sandbox.manager.client.config.AgentRunClientConfig; - -AgentRunClientConfig agentRunConfig = AgentRunClientConfig.builder() - .agentRunAccessKeyId(System.getenv("AGENTRUN_AK")) - .agentRunAccessKeySecret(System.getenv("AGENTRUN_SK")) - .agentRunAccountId(System.getenv("AGENTRUN_ACCOUNT")) - .agentRunRegionId("cn-hangzhou") - .agentRunCpu(4.0f) - .agentRunMemory(4096) - .build(); - -ManagerConfig managerConfig = ManagerConfig.builder() - .containerDeployment(agentRunConfig) - .build(); -``` - -当 `containerDeployment` 设置为 AgentRun 时,会调用阿里云 Serverless AgentRun 平台执行沙箱实例,请提前配置网络、VPC 及镜像权限。 - -## 注册自定义沙箱 - -通过 `@RegisterSandbox` 注解可以为自定义镜像注册新的沙箱类型(或为现有类型替换镜像)。环境变量支持 `${VAR}` 与 `${VAR:default}` 占位符,在运行时会读取宿主机环境变量。 - -```java -import io.agentscope.runtime.sandbox.box.Sandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.container.SandboxType; -import io.agentscope.runtime.sandbox.manager.registry.RegisterSandbox; - -@RegisterSandbox( - imageName = "registry.example.com/runtime-sandbox-analytics:latest", - sandboxType = SandboxType.BASE, - timeout = 120, - securityLevel = "medium", - description = "Sandbox with analytics dependencies", - environment = { - "HF_TOKEN=${HF_TOKEN}", - "JAVA_TOOL_OPTIONS=-Xmx2g" - }, - resourceLimits = { - "memory=3g", - "cpu=3.0" - } -) -public class AnalyticsSandbox extends Sandbox { - public AnalyticsSandbox( - SandboxManager managerApi, - String userId, - String sessionId) { - super(managerApi, userId, sessionId, SandboxType.BASE, 120); - } -} -``` - -注册流程: - -```java -import io.agentscope.runtime.sandbox.manager.registry.SandboxAnnotationProcessor; -import io.agentscope.runtime.sandbox.manager.registry.SandboxRegistryInitializer; - -SandboxRegistryInitializer.initialize(); -SandboxAnnotationProcessor.processClass(AnalyticsSandbox.class); -``` - -如果设置了 `customType`,可以使用字符串类型构造沙箱。 - -## 构建自定义沙箱镜像 - -Java 版本不再提供 `runtime-sandbox-builder` 命令,请使用原生 Docker 工具链: - -```bash -docker build -t registry.example.com/runtime-sandbox-analytics:latest -f docker/analytics/Dockerfile . -docker push registry.example.com/runtime-sandbox-analytics:latest -``` - -一个精简的 Dockerfile 示例: - -```dockerfile -FROM agentscope/runtime-sandbox-base:latest - -RUN apt-get update && apt-get install -y --no-install-recommends graphviz \ - && rm -rf /var/lib/apt/lists/* - -COPY requirements.txt /tmp/requirements.txt -RUN pip install --no-cache-dir -r /tmp/requirements.txt -``` - -构建完成后,将镜像地址写入 `@RegisterSandbox.imageName` 即可。 - -## 资源清理与运维建议 - -- `SandboxCleanupListener` 会在 Spring 上下文关闭时调用 `cleanupAllSandboxes`,确保容器被安全回收。 -- 远程模式下可以显式调用 `/cleanupAllSandboxes` 接口执行清理任务。 -- 建议在服务关闭前调用 `LocalDeployManager.shutdown()` 并等待任务完成。 -- 对于长时间占用的沙箱,可使用 `SandboxManager.releaseSandbox(...)` 主动释放资源。 -- 合理配置 `poolSize` 与 `portRange`,并结合日志监控(例如容器数量、端口占用、Redis 队列长度)提前发现资源泄漏。 diff --git a/cookbook/zh/sandbox_troubleshooting.md b/cookbook/zh/sandbox_troubleshooting.md deleted file mode 100644 index 835159fd..00000000 --- a/cookbook/zh/sandbox_troubleshooting.md +++ /dev/null @@ -1,59 +0,0 @@ -# 沙盒故障排除 -如果您在使用浏览器模块时遇到任何问题,以下是一些故障排查步骤: - -## Docker连接错误 - -如果您遇到以下错误: - -```bash -Failed to connect to Docker using configured host (localhost:2375): com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.HttpHostConnectException: Connect to http://localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused -``` - -此错误通常表示 Docker Java SDK 无法连接到Docker服务。目前 AgentScope Runtime Java 对于Docker设置了回退策略,当客户端无法连接到用户指定的 port 及 host 的 Docker 服务时,会自动回退到默认本地连接方式,如果均失败会报错。 - -遇到这种情况,请检查 Docker 服务是否正常启动,如果在 Mac 上使用的 colima 虚拟机,请启动后重试,如果使用的 Docker desktop,请运行 Docker Desktop 后重试。 - -## 沙盒启动超时 - -如果您遇到超时错误,说明沙盒健康检查失败,你可能需要登录到容器中查看日志,以便进行进一步的故障排查。 - -1. **列出正在运行的容器** - - ```bash - docker ps - ``` - - 找到与你的沙盒相关的容器,记下它的 **CONTAINER ID** 或 **NAMES**。 - -2. **进入容器** - - ```bash - docker exec -it /bin/bash - ``` - -3. **进入日志目录** - - ```bash - cd /var/log && ls -l - ``` - -4. **识别并查看日志文件** - - - `agentscope_runtime.err.log` — `agentscope_runtime` 服务的错误输出 - - `agentscope_runtime.out.log` — `agentscope_runtime` 服务的标准输出 - - `supervisord.log` — Supervisor 进程管理日志 - - `nginx.err.log` — Nginx 错误日志 - - `nginx.out.log` — Nginx 访问/标准输出日志 - - 查看日志的示例命令: - - ```bash - cat agentscope_runtime.err.log - ``` - -5. **常见的日志提示** - - - 如果看到缺少环境变量的错误,请确保运行沙盒管理器的环境中已设置所需的 API 密钥。 - - 如果看到网络错误,请检查防火墙、代理或云端 Shell 网络设置。 - -> 在容器内部查看日志通常是最快定位沙盒健康检查失败原因的方法。 diff --git a/cookbook/new-zh/service/memory.md b/cookbook/zh/service/memory.md similarity index 100% rename from cookbook/new-zh/service/memory.md rename to cookbook/zh/service/memory.md diff --git a/cookbook/new-zh/service/sandbox.md b/cookbook/zh/service/sandbox.md similarity index 100% rename from cookbook/new-zh/service/sandbox.md rename to cookbook/zh/service/sandbox.md diff --git a/cookbook/new-zh/service/service.md b/cookbook/zh/service/service.md similarity index 100% rename from cookbook/new-zh/service/service.md rename to cookbook/zh/service/service.md diff --git a/cookbook/new-zh/service/session_history.md b/cookbook/zh/service/session_history.md similarity index 100% rename from cookbook/new-zh/service/session_history.md rename to cookbook/zh/service/session_history.md diff --git a/cookbook/new-zh/service/state.md b/cookbook/zh/service/state.md similarity index 100% rename from cookbook/new-zh/service/state.md rename to cookbook/zh/service/state.md diff --git a/cookbook/new-zh/tool.md b/cookbook/zh/tool.md similarity index 100% rename from cookbook/new-zh/tool.md rename to cookbook/zh/tool.md diff --git a/cookbook/zh/training_sandbox.md b/cookbook/zh/training_sandbox.md deleted file mode 100644 index 23ddf765..00000000 --- a/cookbook/zh/training_sandbox.md +++ /dev/null @@ -1,257 +0,0 @@ -# 训练用沙箱 - -```{note} -在阅读本节之前,建议先完成基础沙箱章节 {doc}`sandbox` 中关于 Docker 与 SandboxManager 的准备工作。 -``` - -## 背景介绍 - -AgentScope Runtime Java 提供了针对多种公开评测数据集的训练型沙箱(Training Sandbox)。目前内置的训练沙箱包括: - -- `APPWorldSandbox`(`SandboxType.APPWORLD`):用于 APPWorld 多步骤任务评测。 -- `BFCLSandbox`(`SandboxType.BFCL`):用于 BFCL 函数调用与工具使用评测。 -- `WebShopSandbox`(`SandboxType.WEBSHOP`):用于 WebShop 购物对话任务评测。 - -每个沙箱都会在容器中启动对应的数据与工具服务,并暴露统一的实例管理 API:获取数据集切分、创建训练样本、执行一步(step)、评测(evaluate)以及释放实例。 - -## 准备工作 - -### 环境要求 - -- Java 17 或更高版本 -- Maven 3.6+ -- 本地 Docker 守护进程已启动,并允许当前用户访问 -- (可选)Kubernetes 或 Alibaba AgentRun,用于托管训练沙箱(如果不使用 Docker) -- 根据数据集不同,需要的额外环境变量: - - BFCL:`OPENAI_API_KEY`(必需),`DATASET_SUB_TYPE`(默认 `multi_turn`) - -### 拉取训练沙箱镜像 - -训练沙箱镜像托管在阿里云容器镜像服务(ACR)。请根据本机架构拉取并重命名镜像,以便 SandboxManager 直接使用。 - -```bash -# APPWorld(x86_64) -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest \ - && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest \ - agentscope/runtime-sandbox-appworld:latest - -# APPWorld(ARM64,可选) -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest-arm64 \ - && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-appworld:latest-arm64 \ - agentscope/runtime-sandbox-appworld:latest-arm64 - -# BFCL(x86_64) -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest \ - && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest \ - agentscope/runtime-sandbox-bfcl:latest - -# BFCL(ARM64,可选) -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest-arm64 \ - && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-bfcl:latest-arm64 \ - agentscope/runtime-sandbox-bfcl:latest-arm64 - -# WebShop(x86_64) -docker pull agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-webshop:latest \ - && docker tag agentscope-registry.ap-southeast-1.cr.aliyuncs.com/agentscope/runtime-sandbox-webshop:latest \ - agentscope/runtime-sandbox-webshop:latest -``` - -### (可选)从源码构建镜像 - -需要自定义镜像时,可使用仓库中的 Dockerfile 手动构建: - -```bash -# 以 APPWorld 为例(在仓库根目录执行) -docker build \ - -f core/src/main/resources/training_box/environments/appworld/Dockerfile \ - -t agentscope/runtime-sandbox-appworld:latest . - -# BFCL 的 Dockerfile 位于 -# core/src/main/resources/training_box/environments/bfcl/Dockerfile -``` - -## Java API 概览 - -训练沙箱相关的核心类位于 `io.agentscope.runtime.sandbox.box` 包中: - -| 类名 | 对应沙箱类型 | 说明 | -| --- | --- | --- | -| `APPWorldSandbox` | `SandboxType.APPWORLD` | APPWorld 训练环境 | -| `BFCLSandbox` | `SandboxType.BFCL` | BFCL 函数调用评测环境 | -| `WebShopSandbox` | `SandboxType.WEBSHOP` | WebShop 购物对话环境 | - -所有训练沙箱都继承自 `TrainingSandbox`,并实现以下方法: - -- `getEnvProfile(envType, split, params)`:获取数据集切分信息,默认 `split="train"`。 -- `getTaskIds(envType, split, params)`:获取任务 ID 列表。 -- `createInstance(envType, taskId, instanceId, params)`:创建训练实例,返回 JSON 字符串,包含 `info`(实例信息)与 `state`(输入消息)。 -- `step(instanceId, action, params)`:执行一步,`action` 推荐遵循对话消息格式。 -- `evaluate(instanceId, messages, params)`:评估当前实例,返回评测结果。 -- `releaseInstance(instanceId)`:释放实例资源。 - -所有方法返回的都是 JSON 字符串,可使用 Jackson 的 `ObjectMapper` 解析。 - -## 初始化 SandboxManager - -```java -import io.agentscope.runtime.sandbox.manager.SandboxManager; -import io.agentscope.runtime.sandbox.manager.model.ManagerConfig; - -SandboxManager sandboxManager = new SandboxManager(); -// 或自定义配置 -// ManagerConfig config = ManagerConfig.builder() -// .poolSize(0) -// .build(); -// SandboxManager sandboxManager = new SandboxManager(config); -``` - -SandboxManager 默认使用本地 Docker。如果需要 Kubernetes 或 AgentRun,请通过 `ManagerConfig` 传入对应的 `containerDeployment` 配置。 - -在应用退出时,请调用 `sandboxManager.cleanupAllSandboxes()` 以确保容器被释放。 - -## APPWorld 示例 - -```java -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.agentscope.runtime.sandbox.box.APPWorldSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; - -public class AppWorldExample { - private static final ObjectMapper MAPPER = new ObjectMapper(); - - public static void main(String[] args) throws Exception { - SandboxManager sandboxManager = new SandboxManager(); - try (APPWorldSandbox sandbox = new APPWorldSandbox(sandboxManager, "user1", "session1")) { - // 1. 查看数据集概要 - String profileJson = sandbox.getEnvProfile("appworld", "train", null); - JsonNode profiles = MAPPER.readTree(profileJson); - System.out.println("Profile sample: " + profiles.get(0)); - - // 2. 创建训练实例 - String initJson = sandbox.createInstance("appworld", "82e2fac_1", null, null); - JsonNode initNode = MAPPER.readTree(initJson); - String instanceId = initNode.path("info").path("instance_id").asText(); - JsonNode queryState = initNode.path("state"); - System.out.println("Instance " + instanceId + " state: " + queryState); - - // 3. 执行动作 - Map action = Map.of( - "role", "assistant", - "content", "```python\nprint('hello appworld!!')\n```" - ); - String stepJson = sandbox.step(instanceId, action, null); - System.out.println("Step result: " + stepJson); - - // 4. 评测 - String evalJson = sandbox.evaluate(instanceId, Map.of(), Map.of("sparse", true)); - System.out.println("Evaluate result: " + evalJson); - - // 5. 释放实例 - String release = sandbox.releaseInstance(instanceId); - System.out.println("Release status: " + release); - } finally { - sandboxManager.cleanupAllSandboxes(); - } - } -} -``` - -## BFCL 示例 - -在使用 BFCL 之前,请设置必要的环境变量: - -```bash -export OPENAI_API_KEY="your_openai_api_key" -export DATASET_SUB_TYPE="multi_turn" # 可选: all、single_turn、python 等 -``` - -```java -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.agentscope.runtime.sandbox.box.BFCLSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; - -public class BfclExample { - private static final ObjectMapper MAPPER = new ObjectMapper(); - - public static void main(String[] args) throws Exception { - SandboxManager sandboxManager = new SandboxManager(); - try (BFCLSandbox sandbox = new BFCLSandbox(sandboxManager, "bfcl-user", "bfcl-session")) { - String profileJson = sandbox.getEnvProfile("bfcl", "train", null); - JsonNode profiles = MAPPER.readTree(profileJson); - String taskId = profiles.get(0).asText(); - - String initJson = sandbox.createInstance("bfcl", taskId, null, null); - JsonNode initNode = MAPPER.readTree(initJson); - String instanceId = initNode.path("info").path("instance_id").asText(); - - // 构建对话步骤 - Map action = Map.of( - "role", "assistant", - "content", "...工具调用示例..." - ); - String stepJson = sandbox.step(instanceId, action, null); - System.out.println("Step result: " + stepJson); - - String evalJson = sandbox.evaluate(instanceId, Map.of(), Map.of("sparse", true)); - System.out.println("Evaluate result: " + evalJson); - - sandbox.releaseInstance(instanceId); - } finally { - sandboxManager.cleanupAllSandboxes(); - } - } -} -``` - -## WebShop 示例 - -WebShop 沙箱提供了电商对话场景的数据集。下面展示如何读取任务、创建实例并执行一次 step: - -```java -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import io.agentscope.runtime.sandbox.box.WebShopSandbox; -import io.agentscope.runtime.sandbox.manager.SandboxManager; - -public class WebShopExample { - private static final ObjectMapper MAPPER = new ObjectMapper(); - - public static void main(String[] args) throws Exception { - SandboxManager sandboxManager = new SandboxManager(); - try (WebShopSandbox sandbox = new WebShopSandbox(sandboxManager, "web-user", "web-session")) { - String tasksJson = sandbox.getTaskIds("webshop", "train", null); - JsonNode tasks = MAPPER.readTree(tasksJson); - String taskId = tasks.get(0).asText(); - - String initJson = sandbox.createInstance("webshop", taskId, null, null); - JsonNode initNode = MAPPER.readTree(initJson); - String instanceId = initNode.path("info").path("instance_id").asText(); - - Map action = Map.of( - "role", "assistant", - "content", "请列出商品详情。" - ); - String stepJson = sandbox.step(instanceId, action, null); - System.out.println("Step result: " + stepJson); - - sandbox.releaseInstance(instanceId); - } finally { - sandboxManager.cleanupAllSandboxes(); - } - } -} -``` - -## 清理资源 - -- 沙箱实例实现了 `AutoCloseable`,推荐使用 try-with-resources 自动释放。 -- 在所有沙箱操作完成后,调用 `sandboxManager.cleanupAllSandboxes()`,确保容器停止并回收。 - -## 下一步 - -- {doc}`sandbox`:了解通用沙箱与工具调用。 -- {doc}`manager`:掌握 `ServiceManager` 与 `EnvironmentManager` 的整体架构。 -- {doc}`context_manager`:在训练样本对话完成后,将数据写入上下文。 -- {doc}`quickstart`:快速构建并部署一个完整的 Java 智能体。 From 6b18a794f9fc2a005b1a581dd93e6d4a7ee26ebc Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 11 Dec 2025 12:31:31 +0800 Subject: [PATCH 3/5] update README.md Change-Id: I23d217bab32ace688ba302ff54977d8e645730c7 --- README-zh.md | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-zh.md b/README-zh.md index 11fc9065..8774a842 100644 --- a/README-zh.md +++ b/README-zh.md @@ -8,7 +8,9 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime) [![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) -[Cookbook](./cookbook/zh) +[[Cookbook]](./cookbook/zh) +[[English README]](README_zh.md) +[[Examples]](./examples) **AgentScope Runtime Java** @@ -42,8 +44,6 @@ ## 📋 目录 - [快速开始](#-快速开始) -- [Agent 框架集成](#-agent-框架集成) -- [部署](#️-部署) - [贡献](#-贡献) - [许可证](#-许可证) diff --git a/README.md b/README.md index 0bf24a42..9184d3cb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,9 @@ [![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.agentscope/agentscope-runtime) [![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) -[Cookbook](./cookbook/zh) +[[Cookbook]](./cookbook/zh) +[[中文README]](README_zh.md) +[[Examples]](./examples) **AgentScope Runtime Java** @@ -42,8 +44,6 @@ Join our community on DingTalk: ## 📋 Table of Contents - [Quick Start](#-quick-start) -- [Agent Framework Integration](#-agent-framework-integration) -- [Deployment](#️-deployment) - [Contributing](#-contributing) - [License](#-license) From 5ae293d41dbe15365db9625817636033179a5ac4 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Thu, 11 Dec 2025 23:03:11 +0800 Subject: [PATCH 4/5] update README.md Change-Id: I8fb14f9c2fe6b1e982988ea4002d48ff51a61d95 --- README.md | 2 +- README-zh.md => README_zh.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename README-zh.md => README_zh.md (99%) diff --git a/README.md b/README.md index 9184d3cb..e884b0cb 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ [![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) [[Cookbook]](./cookbook/zh) -[[中文README]](README_zh.md) +[[中文README]](./README_zh.md) [[Examples]](./examples) **AgentScope Runtime Java** diff --git a/README-zh.md b/README_zh.md similarity index 99% rename from README-zh.md rename to README_zh.md index 8774a842..753371bb 100644 --- a/README-zh.md +++ b/README_zh.md @@ -9,7 +9,7 @@ [![DingTalk](https://img.shields.io/badge/DingTalk-Join_Us-orange.svg)](https://qr.dingtalk.com/action/joingroup?code=v1,k1,OmDlBXpjW+I2vWjKDsjvI9dhcXjGZi3bQiojOq3dlDw=&_dt_no_comment=1&origin=11) [[Cookbook]](./cookbook/zh) -[[English README]](README_zh.md) +[[English README]](./README.md) [[Examples]](./examples) **AgentScope Runtime Java** From 204371c27349e7e780ae23ce985148b0058b9222 Mon Sep 17 00:00:00 2001 From: chickenlj Date: Fri, 12 Dec 2025 10:00:41 +0800 Subject: [PATCH 5/5] update README.md Change-Id: I7a10b6913bb2aac29124e6370ffa41e0fd2b50eb --- README.md | 2 +- README_zh.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e884b0cb..4886a0fe 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This is the Java implementation of [AgentScope Runtime](https://github.com/agent - **Sandboxed Tool Execution**: Isolated sandboxes ensure safe tool execution without system compromise - **Developer Friendly**: Simple deployment with powerful customization options - **Framework Agnostic**: Not tied to any specific framework. Works seamlessly with popular open-source agent frameworks and custom implementations -- 🚧 **Observability**: Trace and visualize agent operations comprehensively +- 🚧 **Observability**: Trace and visualize agent operations comprehensively (under development) --- diff --git a/README_zh.md b/README_zh.md index 753371bb..e2262c58 100644 --- a/README_zh.md +++ b/README_zh.md @@ -27,7 +27,7 @@ - **沙箱化工具执行**:隔离的沙箱确保工具执行安全,不会危及系统 - **开发者友好**:简单部署,强大的自定义选项 - **框架无关**:不绑定任何特定框架。可与流行的开源 Agent 框架和自定义实现无缝协作 -- 🚧 **可观测性**:全面追踪和可视化 Agent 操作 +- 🚧 **可观测性**:全面追踪和可视化 Agent 操作(开发中) ---