第一章 AgentScope Java 2.0 入门:从源码编译到第一个能对话的 Agent
"本章把 2.0.0-RC2 框架从 GitHub 拉下来编译安装、用纯 Java 启动工程、接入 DeepSeek 模型并跑通对话——完成你 AgentScope Java 学习之旅的'第 0 步'。"
1.1 AgentScope Java 是什么
AgentScope Java 是阿里巴巴开源的 Agent 编程框架,用于构建基于大语言模型(LLM)的智能体应用。2.0 是一次较大规模的重构:在 1.x 的 ReAct 循环基础上,抽出独立的 HarnessAgent 层,把工作区、人格、长期记忆、子 agent 编排、沙箱隔离、技能装配、计划模式打包成一个"工程就绪"的入口;同时把 1.x 的"模块大杂烩"拆成清晰的核心 + 扩展。
项目地址:https://github.com/agentscope-ai/agentscope-java
2.0 的核心能力
ReActAgent:核心推理循环(思考 → 调用工具 → 观察结果 → 继续思考),1.x 的核心类完全保留。HarnessAgent(推荐入口):在ReActAgent之上的一层薄包装,把长期运行 agent 必备的工程能力(工作区、Session、记忆、压缩、子 agent、沙箱、技能、Plan Mode)用一个 Builder 串起来。- 工具系统:通过
@Tool注解将任意 Java 方法注册为 Agent 可调用的工具;工具元数据生成 JSON Schema 由 LLM 自动调用。 - 多模型支持:内置 OpenAI 协议(DeepSeek、GLM、Ollama 等所有 OpenAI 兼容服务)、DashScope(通义千问)、Anthropic Claude、Google Gemini。
- 会话与状态:
AgentState+AgentStateStore取代了 1.x 的Memory体系,跨进程、跨机器、跨副本的状态恢复统一由AgentStateStore后端承担(InMemoryAgentStateStore/JsonFileAgentStateStore/RedisAgentStateStore/MysqlAgentStateStore)。 - 子 Agent 编排(2.0 取代 Pipeline/MsgHub):
SubagentDeclaration声明一个子 agent,主 agent 通过agent_spawn工具委派;支持同步(timeout_seconds > 0)和后台(timeout_seconds = 0),后台任务完成时自动反向通知。 - Middleware 体系(2.0 取代 Hook):
MiddlewareBase暴露 5 个钩子位置(onAgent/onReasoning/onActing/onModelCall/onSystemPrompt),可在 ReAct 循环关键时机插入逻辑。 - 工作区驱动的人格:在
workspace/AGENTS.md写人格、workspace/MEMORY.md沉淀长期事实,workspace/subagents/<id>.md声明子 agent,文件即配置。 - 结构化输出:让 Agent 返回指定 Java 类型的数据。
- MCP 集成:声明式 MCP server + 工具粒度允许/拒绝。
1.x → 2.0 重大变更:
io.agentscope.core.pipeline.*(Pipeline、SequentialPipeline、FanoutPipeline、MsgHub、Pipelines)已移除,改用子 agent 系统。io.agentscope.core.memory.*(InMemoryMemory、LongTermMemory)@Deprecated(forRemoval = true),保留为兼容层,新代码请用AgentState.getContext()+AgentStateStore。io.agentscope.core.model.tts.*已移除,TTS 不在 core 中提供。Hook接口@Deprecated(forRemoval = true),新代码请用Middleware/MiddlewareBase。agent.stream()(返回Flux<Event>)@Deprecated(forRemoval = true),新代码请用agent.streamEvents()(返回Flux<AgentEvent>)。
技术栈
| 技术 | 版本 |
|---|---|
| Java | 17+(推荐 21) |
| Maven | 3.8+ |
| Project Reactor | 2025.0.2 BOM |
| Jackson | 2.21.1 |
| OkHttp | 5.3.2 |
| DashScope SDK | 2.22.9 |
| OpenAI Java SDK | 4.28.0 |
| Anthropic Java SDK | 2.14.0 |
| Google GenAI SDK | 1.45.0 |
| MCP SDK | 0.17.0 |
模块结构
agentscope-java/
agentscope-core/ -- 核心框架(ReActAgent、Model、Tool、Middleware、AgentState、AgentStateStore)
agentscope-harness/ -- HarnessAgent、工作区、沙箱、压缩、子 agent、技能、Plan Mode
agentscope-extensions/ -- 扩展模块(状态后端、RAG、Channel、Skill、Sandbox 等)
agentscope-examples/ -- 示例代码
agentscope-dependencies-bom/ -- 依赖版本管理
agentscope-distribution/ -- 分发打包(agentscope-bom)
2.0 之后,生产应用请使用 agentscope-harness;学习 ReAct 循环的细节可以单独依赖 agentscope-core;状态持久化、多副本恢复等后端能力来自 agentscope-extensions(如 agentscope-extensions-redis)。
1.2 环境准备
前置条件
- JDK 17+:推荐使用 JDK 21
- Maven 3.8+:用于构建和依赖管理
- IDE:IntelliJ IDEA 推荐
- API Key:至少需要一个 LLM 服务的 API Key
本教程使用 DeepSeek
本教程统一使用 DeepSeek 作为示例模型(OpenAI 兼容协议,国内访问稳定、价格便宜)。如果你用其他服务,配置方法相同,只是 api-key / model-name / base-url 不同。
获取 DeepSeek API Key:https://platform.deepseek.com/api_keys
框架内置支持的 LLM 服务(任选其一即可):
| 服务商 | 获取地址 | 是否 OpenAI 兼容 | 配置类 |
|---|---|---|---|
| DeepSeek(本教程示例) | https://platform.deepseek.com/api_keys | ✅ | OpenAIChatModel + baseUrl |
| OpenAI | https://platform.openai.com/api-keys | ✅ | OpenAIChatModel |
| DashScope(通义千问) | https://dashscope.console.aliyun.com/apiKey | ❌ 专用协议 | DashScopeChatModel |
| Anthropic | https://console.anthropic.com/ | ❌ 专用协议 | AnthropicChatModel |
| Google Gemini | https://aistudio.google.com/apikey | ❌ 专用协议 | GeminiChatModel |
| Ollama(本地) | https://ollama.com/ | ✅ | OpenAIChatModel + baseUrl |
1.3 安装框架到本地 Maven 仓库
教程使用的版本是 2.0.0-RC2(仓库根 pom.xml 的 <revision>)。RC2 已发布到 Maven Central,你可以在 pom.xml 中直接引入依赖,无需本地编译:
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-harness</artifactId>
<version>2.0.0-RC2</version>
</dependency>
如果你需要查看源码或自行修改编译,也可以从 GitHub 拉源码,在本地执行 mvn install -DskipTests 安装。
1.3.1 克隆源码
git clone https://github.com/agentscope-ai/agentscope-java.git
cd agentscope-java
git checkout v2.0.0-RC2 # 切到目标 tag,没有 tag 就用 main 分支
源码里有这些关键目录:
agentscope-core/— 核心框架(ReActAgent、Middleware、AgentState、AgentStateStore)agentscope-harness/—HarnessAgent、工作区、压缩、子 agent、沙箱、技能、Plan Modeagentscope-extensions/— 扩展模块(agentscope-extensions-redis等)agentscope-distribution/— 生成agentscope-bom的地方agentscope-dependencies-bom/— 第三方依赖版本管理agentscope-examples/— 官方示例(多 Agent 模式、生产部署等)
1.3.2 编译并安装
在仓库根目录执行:
mvn install -DskipTests
-DskipTests 跳过所有模块的单元测试。首次安装会跑十几分钟(要拉一堆三方依赖),完成后所有 io.agentscope:* 工件都装进 ~/.m2/repository 了。
注意:框架用
<revision>2.0.0-RC2</revision>这种"动态版本号"机制(revision占位符),所以要装根 POM 才能让 BOM 解析正常。如果只装agentscope-core不装根 POM,会出现"找不到 BOM"的错。mvn install在根目录跑会按模块依赖顺序自动处理这个。
1.3.3 验证安装是否成功
ls ~/.m2/repository/io/agentscope/agentscope-harness/2.0.0-RC2/
应该看到 agentscope-harness-2.0.0-RC2.jar 和 .pom。再检查 BOM:
ls ~/.m2/repository/io/agentscope/agentscope-bom/2.0.0-RC2/
如果两个都在,后面创建的应用项目才能正确解析依赖。
1.3.4 常见问题
Q: 报 "Non-resolvable import POM"
A: 没装根 POM。在 agentscope-java/ 根目录执行 mvn install -DskipTests,不要进子模块单独装。
Q: 报 "Could not find artifact io.agentscope:..." 但 jar 文件明明在本地
A: 缓存问题。执行 mvn -U clean 或在 IDE 里 Reload All Maven Projects。
Q: 后续 git pull 后代码更新了,本地应用报找不到类
A: 重新跑 mvn install -DskipTests,新版本的工件才能覆盖到本地。
Q: 报 Failed to execute goal com.diffplug.spotless:spotless-maven-plugin:...:check,说几百个文件格式违规
A: 这是 Spotless 格式化检查失败,不是代码错误。Windows 上最常见的原因是 CRLF 换行符问题——git 检出时把 Unix 换行符(LF)自动转成了 Windows 换行符(CRLF),Spotless 期望 LF 所以报错。
修复方法:
# 第一步:让 Spotless 自动修复所有违规文件
mvn spotless:apply
# 第二步:重新编译
mvn install -DskipTests
mvn spotless:apply 会扫描整个项目,把所有文件的缩进、换行、import 顺序等按项目规范就地修复。
如果用了 Windows git 且担心以后再犯,可以关掉 git 的自动换行转换:
git config --global core.autocrlf false
或者在项目根目录的 .gitattributes 文件里加一行 * text=auto eol=lf 强制统一为 LF。
1.4 创建项目
使用 Maven 创建
创建一个标准的 Maven 项目:
mkdir my-agent-app
cd my-agent-app
pom.xml
2.0 推荐直接依赖 agentscope-harness——它会传递引入 agentscope-core 和 Harness 自身的所有能力:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-agent-app</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<java.version>17</java.version>
<agentscope.version>2.0.0-RC2</agentscope.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-bom</artifactId>
<version>${agentscope.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 2.0 推荐:HarnessAgent 一站式入口 -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-harness</artifactId>
</dependency>
<!-- 分布式状态后端(生产用,单机可省) -->
<dependency>
<groupId>io.agentscope</groupId>
<artifactId>agentscope-extensions-redis</artifactId>
</dependency>
</dependencies>
</project>
2.0 没有官方
agentscope-spring-boot-starter1.x 那种开箱即用的 starter。Spring Boot 集成由你自由组合——HarnessAgent本身是个普通 Java 对象,你可以用WebMvc包成 REST 接口、用CommandLineRunner启动时构建并注册到 IoC 容器,或者用 Spring AI 的ChatClient风格自己写一层薄包装。详细见 第九章 Spring Boot 集成。
项目结构
my-agent-app/
src/
main/
java/
com/example/
Application.java ← 启动入口,构造 HarnessAgent
controller/
ChatController.java ← 把 HarnessAgent 暴露为 HTTP 接口
resources/
application.yml ← 模型配置 + 工作区路径
workspace/ ← HarnessAgent 的人格、记忆、技能文件(运行时生成)
AGENTS.md
MEMORY.md
pom.xml
1.5 配置 LLM 模型
HarnessAgent 的 LLM 通过 Builder 模式配置,核心就三件事:
| 字段 | 含义 | DeepSeek 示例 |
|---|---|---|
apiKey |
服务的 API 密钥 | ${DEEPSEEK_API_KEY} |
modelName |
模型标识 | deepseek-chat |
baseUrl |
API 服务地址 | https://api.deepseek.com |
1.5.1 配置 application.yml
application.yml 写在 src/main/resources/ 下:
agentscope:
deepseek:
api-key: ${
DEEPSEEK_API_KEY:}
model-name: deepseek-chat
base-url: https://api.deepseek.com
workspace:
path: ./workspace
2.0 没有了 1.x 的
agentscope.spring.boot自动装配类。application.yml的字段由你自己解析——可以用 Spring 的@ConfigurationProperties,也可以在Application.java里直接new Yaml().loadAs(...)。
设置环境变量:
# Windows PowerShell
$env:DEEPSEEK_API_KEY="sk-xxxxxxxx"
# Linux/macOS
export DEEPSEEK_API_KEY="sk-xxxxxxxx"
Java 代码里完全不用关心 api-key——构造 Model 时从环境变量/YAML 读:
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey(System.getenv("DEEPSEEK_API_KEY"))
.modelName("deepseek-chat")
.baseUrl("https://api.deepseek.com")
.stream(true)
.build();
1.6 验证环境
完整示例:基于 HarnessAgent
src/main/java/com/example/Application.java:
package com.example;
import io.agentscope.core.formatter.openai.OpenAIChatFormatter;
import io.agentscope.core.model.OpenAIChatModel;
import io.agentscope.harness.HarnessAgent;
import io.agentscope.harness.HarnessConfig;
public class Application {
public static void main(String[] args) {
String apiKey = System.getenv("DEEPSEEK_API_KEY");
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey(apiKey)
.modelName("deepseek-chat")
.baseUrl("https://api.deepseek.com")
.stream(true)
.formatter(new OpenAIChatFormatter())
.build();
HarnessAgent agent = HarnessAgent.builder()
.name("Assistant")
.sysPrompt("You are a helpful AI assistant. Be friendly and concise.")
.model(model)
.workspace(java.nio.file.Path.of("./workspace"))
.build();
// 这里直接同步调用一次(生产请用 Spring Controller 包成 HTTP 接口)
String reply = agent.call("你好,请介绍一下自己")
.block()
.getTextContent();
System.out.println("Agent> " + reply);
}
}
启动:
# Windows PowerShell
$env:DEEPSEEK_API_KEY="sk-xxxxxxxx"
mvn exec:java -Dexec.mainClass="com.example.Application"
# Linux/macOS
export DEEPSEEK_API_KEY="sk-xxxxxxxx"
mvn exec:java -Dexec.mainClass="com.example.Application"
如果能看到 Agent 的回复,说明环境搭建成功。
2.0 起步的最小选择:
- 只学 ReAct 循环 → 依赖
agentscope-core,直接用ReActAgent.builder().build()。- 做生产/长期运行的应用 → 依赖
agentscope-harness,用HarnessAgent.builder().workspace(...).build(),拿到工作区、Session、记忆、压缩、子 agent 等能力。后面的章节会逐步展开
HarnessAgent的各项能力;本章只验证它能跑起来。
用其他模型?改 YAML + 改环境变量
OpenAIChatModel 支持所有 OpenAI 兼容服务。DeepSeek 也是改 YAML 配置出来的——api-key 字段里的 ${DEEPSEEK_API_KEY:} 是 Spring 的占位符,启动时从环境变量读。换模型要做两件事:
- 改
application.yml(或Model的 Builder 参数)里的api-key占位符 /model-name/base-url - 改环境变量名(不同的服务商用不同的 key)
用官方 OpenAI:
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey(System.getenv("OPENAI_API_KEY"))
.modelName("gpt-4o-mini")
.baseUrl("https://api.openai.com")
.stream(true)
.build();
export OPENAI_API_KEY="sk-xxxxxxxx"
用本地 Ollama:
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey("ollama") // Ollama 不校验 key
.modelName("llama3")
.baseUrl("http://localhost:11434")
.build();
Ollama 不用设环境变量。
用 GLM(智谱):
OpenAIChatModel model = OpenAIChatModel.builder()
.apiKey(System.getenv("GLM_API_KEY"))
.modelName("glm-4-plus")
.baseUrl("https://open.bigmodel.cn/api/paas/v4")
.build();
export GLM_API_KEY="xxxxxxxxxxxxxxxx"
简单记:Model Builder 管"用哪家、哪个模型、什么地址",环境变量管"密钥"。改模型 = 改 Builder + 改环境变量名,Java 代码其它部分完全不动。
1.7 框架核心概念速览
在开始写代码之前,先理解几个核心概念:
ReActAgent(推理循环)
ReActAgent 是 1.x 起就存在的核心类。agent.call(messages) 跑一次"思考 → 调用工具 → 观察结果 → 继续思考"循环,返回最终回复。所有"Agent"都基于 ReActAgent——HarnessAgent 也是 ReActAgent 的子类。
HarnessAgent(工程包装)
HarnessAgent = ReActAgent + 一组叠加在循环关键时机上的 middleware(工作区注入、压缩、记忆、子 agent、沙箱、Plan Mode)。Builder 上每开一个能力,就挂一个 middleware;不写则默认行为。
安装、依赖、跑通第一个
HarnessAgent的端到端示例见 快速开始。
Msg(消息)
Msg 是 Agent 之间通信的基本单位。每条消息包含:
- role:角色(USER、ASSISTANT、SYSTEM、TOOL)
- content:内容块列表(文本、图像、工具调用等)
- name:发送者名称
2.0 仍然保留 Msg 作为底层传输对象,但业务代码里更推荐用具体子类型 UserMessage / AssistantMessage / SystemMessage / ToolResultMessage,类型更明确。
Model(模型)
Model 接口封装了与 LLM 的交互。框架内置的支持:
OpenAIChatModel(OpenAI 以及 DeepSeek、GLM、Ollama 等所有 OpenAI 兼容服务)DashScopeChatModel(通义千问)AnthropicChatModel(Claude)GeminiChatModel(Google Gemini)
1.x 的
OllamaChatModel(专用协议)在 2.0 不再单独提供——直接用OpenAIChatModel+baseUrl=http://localhost:11434即可。
Toolkit(工具集)
Toolkit 管理 Agent 可以调用的工具。通过 @Tool 注解把 Java 方法注册为工具;2.0 继续完整支持 1.x 的 @Tool / @ToolParam 语法。
AgentState + AgentStateStore(替代 1.x 的 Memory)
AgentState 是 agent 当前"瞬时"运行状态的完整快照——对话历史、权限规则、Plan Mode 状态、todo 列表等。AgentStateStore 把 AgentState 持久化到外部存储(文件、Redis、MySQL……),实现"同 sessionId 跨进程、跨机器、跨副本"地恢复会话。这是 2.0 取代 1.x Memory 接口的统一抽象。
SubagentDeclaration(子 agent,2.0 取代 Pipeline/MsgHub)
把子 agent 的 spec 写到 workspace/subagents/<id>.md,主 agent 就能在推理时通过 agent_spawn 委派。同步(timeout_seconds > 0,默认 30 秒)和后台(timeout_seconds = 0,立即返回 task_id)两种模式;后台任务完成时框架自动把结果作为系统提醒注入下一轮。
Middleware(2.0 取代 Hook)
Middleware / MiddlewareBase 暴露 5 个钩子位置(onAgent / onReasoning / onActing / onModelCall / onSystemPrompt),在 ReAct 循环的关键时机插入逻辑。Hook 接口在 2.0 仍可用(@Deprecated(forRemoval = true)),新代码请用 Middleware。