Agent Scope Java 2.x 系列【2】 ReActAgent

目录

    • [1. 概述](#1. 概述)
    • [2. 环境准备](#2. 环境准备)
      • [2.1 Maven 依赖](#2.1 Maven 依赖)
      • [2.2 API Key](#2.2 API Key)
    • [3. ReActAgent 架构](#3. ReActAgent 架构)
      • [3.1 三种调用方式](#3.1 三种调用方式)
      • [3.2 Builder 核心参数](#3.2 Builder 核心参数)
    • [4. 第一步:创建模型](#4. 第一步:创建模型)
    • [5. 第二步:定义工具](#5. 第二步:定义工具)
      • [5.1 注解方式](#5.1 注解方式)
      • [5.2 接口方式](#5.2 接口方式)
    • [6. 第三步:注册工具到 Toolkit](#6. 第三步:注册工具到 Toolkit)
    • [7. 第四步:构建 ReActAgent](#7. 第四步:构建 ReActAgent)
    • [8. 第五步:调用 Agent](#8. 第五步:调用 Agent)
      • [8.1 同步调用](#8.1 同步调用)
      • [8.2 流式调用(2.0 新 API)](#8.2 流式调用(2.0 新 API))
      • [8.3 多轮对话(带 RuntimeContext)](#8.3 多轮对话(带 RuntimeContext))
    • [9. 完整 Spring Boot 示例](#9. 完整 Spring Boot 示例)
      • [9.1 配置类](#9.1 配置类)
      • [9.2 控制器](#9.2 控制器)

1. 概述

ReActAgent 是 AgentScope 2.0 的核心推理引擎,实现 ReAct(Reasoning + Acting) 模式------交替进行推理和工具调用,直到得出最终答案。

智能体在每次调用时运行推理-行动循环,下图展示了主要控制流程:
#mermaid-svg-JihK16335oi7sLxw{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-JihK16335oi7sLxw .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-JihK16335oi7sLxw .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-JihK16335oi7sLxw .error-icon{fill:#552222;}#mermaid-svg-JihK16335oi7sLxw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-JihK16335oi7sLxw .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-JihK16335oi7sLxw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-JihK16335oi7sLxw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-JihK16335oi7sLxw .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-JihK16335oi7sLxw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-JihK16335oi7sLxw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-JihK16335oi7sLxw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-JihK16335oi7sLxw .marker.cross{stroke:#333333;}#mermaid-svg-JihK16335oi7sLxw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-JihK16335oi7sLxw p{margin:0;}#mermaid-svg-JihK16335oi7sLxw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-JihK16335oi7sLxw .cluster-label text{fill:#333;}#mermaid-svg-JihK16335oi7sLxw .cluster-label span{color:#333;}#mermaid-svg-JihK16335oi7sLxw .cluster-label span p{background-color:transparent;}#mermaid-svg-JihK16335oi7sLxw .label text,#mermaid-svg-JihK16335oi7sLxw span{fill:#333;color:#333;}#mermaid-svg-JihK16335oi7sLxw .node rect,#mermaid-svg-JihK16335oi7sLxw .node circle,#mermaid-svg-JihK16335oi7sLxw .node ellipse,#mermaid-svg-JihK16335oi7sLxw .node polygon,#mermaid-svg-JihK16335oi7sLxw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-JihK16335oi7sLxw .rough-node .label text,#mermaid-svg-JihK16335oi7sLxw .node .label text,#mermaid-svg-JihK16335oi7sLxw .image-shape .label,#mermaid-svg-JihK16335oi7sLxw .icon-shape .label{text-anchor:middle;}#mermaid-svg-JihK16335oi7sLxw .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-JihK16335oi7sLxw .rough-node .label,#mermaid-svg-JihK16335oi7sLxw .node .label,#mermaid-svg-JihK16335oi7sLxw .image-shape .label,#mermaid-svg-JihK16335oi7sLxw .icon-shape .label{text-align:center;}#mermaid-svg-JihK16335oi7sLxw .node.clickable{cursor:pointer;}#mermaid-svg-JihK16335oi7sLxw .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-JihK16335oi7sLxw .arrowheadPath{fill:#333333;}#mermaid-svg-JihK16335oi7sLxw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-JihK16335oi7sLxw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-JihK16335oi7sLxw .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JihK16335oi7sLxw .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-JihK16335oi7sLxw .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JihK16335oi7sLxw .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-JihK16335oi7sLxw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-JihK16335oi7sLxw .cluster text{fill:#333;}#mermaid-svg-JihK16335oi7sLxw .cluster span{color:#333;}#mermaid-svg-JihK16335oi7sLxw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-JihK16335oi7sLxw .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-JihK16335oi7sLxw rect.text{fill:none;stroke-width:0;}#mermaid-svg-JihK16335oi7sLxw .icon-shape,#mermaid-svg-JihK16335oi7sLxw .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-JihK16335oi7sLxw .icon-shape p,#mermaid-svg-JihK16335oi7sLxw .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-JihK16335oi7sLxw .icon-shape .label rect,#mermaid-svg-JihK16335oi7sLxw .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-JihK16335oi7sLxw .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-JihK16335oi7sLxw .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-JihK16335oi7sLxw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 行动
是
否
退出
推理
无工具调用
允许
询问 / 外部
拒绝
有工具调用
输入: 消息 / 事件
等待

外部事件?
处理事件

更新工具状态
将消息添加到上下文
检查下一步动作
返回: 等待

外部交互
必要时压缩上下文
LLM 调用
返回最终消息
批量工具调用

串行 / 并发
执行工具调用
权限

检查
运行工具 → 结果
暂停并发出

RequireUserConfirmEvent
将错误结果返回 LLM


2. 环境准备

2.1 Maven 依赖

xml 复制代码
<properties>
    <agentscope.version>2.0.1</agentscope.version>
</properties>

<dependencies>
    <!-- AgentScope 2.0 核心(含 ReActAgent + Model + Toolkit) -->
    <dependency>
        <groupId>io.agentscope</groupId>
        <artifactId>agentscope-core</artifactId>
        <version>${agentscope.version}</version>
    </dependency>
</dependencies>

2.2 API Key

bash 复制代码
export DASHSCOPE_API_KEY=sk-your-key-here

3. ReActAgent 架构

#mermaid-svg-rE61p6szBREGM5dY{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rE61p6szBREGM5dY .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rE61p6szBREGM5dY .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rE61p6szBREGM5dY .error-icon{fill:#552222;}#mermaid-svg-rE61p6szBREGM5dY .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rE61p6szBREGM5dY .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rE61p6szBREGM5dY .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rE61p6szBREGM5dY .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rE61p6szBREGM5dY .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rE61p6szBREGM5dY .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rE61p6szBREGM5dY .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rE61p6szBREGM5dY .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rE61p6szBREGM5dY .marker.cross{stroke:#333333;}#mermaid-svg-rE61p6szBREGM5dY svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rE61p6szBREGM5dY p{margin:0;}#mermaid-svg-rE61p6szBREGM5dY .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-rE61p6szBREGM5dY .cluster-label text{fill:#333;}#mermaid-svg-rE61p6szBREGM5dY .cluster-label span{color:#333;}#mermaid-svg-rE61p6szBREGM5dY .cluster-label span p{background-color:transparent;}#mermaid-svg-rE61p6szBREGM5dY .label text,#mermaid-svg-rE61p6szBREGM5dY span{fill:#333;color:#333;}#mermaid-svg-rE61p6szBREGM5dY .node rect,#mermaid-svg-rE61p6szBREGM5dY .node circle,#mermaid-svg-rE61p6szBREGM5dY .node ellipse,#mermaid-svg-rE61p6szBREGM5dY .node polygon,#mermaid-svg-rE61p6szBREGM5dY .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-rE61p6szBREGM5dY .rough-node .label text,#mermaid-svg-rE61p6szBREGM5dY .node .label text,#mermaid-svg-rE61p6szBREGM5dY .image-shape .label,#mermaid-svg-rE61p6szBREGM5dY .icon-shape .label{text-anchor:middle;}#mermaid-svg-rE61p6szBREGM5dY .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-rE61p6szBREGM5dY .rough-node .label,#mermaid-svg-rE61p6szBREGM5dY .node .label,#mermaid-svg-rE61p6szBREGM5dY .image-shape .label,#mermaid-svg-rE61p6szBREGM5dY .icon-shape .label{text-align:center;}#mermaid-svg-rE61p6szBREGM5dY .node.clickable{cursor:pointer;}#mermaid-svg-rE61p6szBREGM5dY .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-rE61p6szBREGM5dY .arrowheadPath{fill:#333333;}#mermaid-svg-rE61p6szBREGM5dY .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-rE61p6szBREGM5dY .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-rE61p6szBREGM5dY .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rE61p6szBREGM5dY .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-rE61p6szBREGM5dY .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rE61p6szBREGM5dY .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-rE61p6szBREGM5dY .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-rE61p6szBREGM5dY .cluster text{fill:#333;}#mermaid-svg-rE61p6szBREGM5dY .cluster span{color:#333;}#mermaid-svg-rE61p6szBREGM5dY div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-rE61p6szBREGM5dY .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-rE61p6szBREGM5dY rect.text{fill:none;stroke-width:0;}#mermaid-svg-rE61p6szBREGM5dY .icon-shape,#mermaid-svg-rE61p6szBREGM5dY .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-rE61p6szBREGM5dY .icon-shape p,#mermaid-svg-rE61p6szBREGM5dY .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-rE61p6szBREGM5dY .icon-shape .label rect,#mermaid-svg-rE61p6szBREGM5dY .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-rE61p6szBREGM5dY .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-rE61p6szBREGM5dY .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-rE61p6szBREGM5dY :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ReActAgent
是
否
ReActAgent
Model

(推理引擎)
Toolkit

(工具注册表)
AgentStateStore

(状态持久化,可选)
call()
stream()
streamEvents()
doCall(msgs)

核心推理循环
while (未完成)

  1. reasoning()

→ Model.stream()
2. acting()

→ Toolkit.callTools()
3. summarizing()

→ 上下文压缩(可选)
返回最终结果

3.1 三种调用方式

方法 返回类型 适用场景
call(List<Msg>) Mono<Msg> 同步等待完整结果
stream(List<Msg>, StreamOptions) Flux<Event> 流式观察(2.0 已废弃)
streamEvents(List<Msg>) Flux<AgentEvent> 2.0 新 API------27 种细粒度事件

3.2 Builder 核心参数

java 复制代码
ReActAgent agent = ReActAgent.builder()
    .name("my-agent")                    // Agent 名称(必填)
    .model(model)                        // 语言模型(必填)
    // 或字符串形式:.model("dashscope://qwen-max")
    .toolkit(toolkit)                    // 工具注册表(可选)
    .sysPrompt("你是一个有用的 AI 助手,用中文回答。")  // 系统提示词
    .maxIters(5)                         // 最大推理迭代次数
    .build();

4. 第一步:创建模型

java 复制代码
Model model = Model.builder()
    .provider("dashscope")
    .model("qwen-max")
    .apiKey(System.getenv("DASHSCOPE_API_KEY"))
    .build();

5. 第二步:定义工具

5.1 注解方式

java 复制代码
public class WeatherTool {
    @Tool(name = "get_weather", description = "查询指定城市的天气")
    public String getWeather(@Param("city") String city) {
        // 调用天气 API 并返回结果
        return "今天 " + city + " 晴,25℃";
    }
}

5.2 接口方式

java 复制代码
public class CalculatorTool implements Tool {
    @Override
    public String getName() { return "calculator"; }

    @Override
    public String getDescription() { return "执行四则运算"; }

    @Override
    public Object call(Map<String, Object> args) {
        double a = (double) args.get("a");
        double b = (double) args.get("b");
        String op = (String) args.get("op");
        switch (op) {
            case "+": return a + b;
            case "-": return a - b;
            case "*": return a * b;
            case "/": return a / b;
            default: throw new IllegalArgumentException("不支持的操作符: " + op);
        }
    }
}

6. 第三步:注册工具到 Toolkit

java 复制代码
Toolkit toolkit = Toolkit.builder()
    .addTool(new WeatherTool())
    .addTool(new CalculatorTool())
    .build();

7. 第四步:构建 ReActAgent

java 复制代码
ReActAgent agent = ReActAgent.builder()
    .name("demo-agent")
    .model(model)
    .toolkit(toolkit)
    .sysPrompt("你是一个有用的 AI 助手,用中文回答。")
    .maxIters(5)
    .build();

8. 第五步:调用 Agent

8.1 同步调用

java 复制代码
Msg msg = Msg.builder()
    .role(MsgRole.USER)
    .content(List.of(TextBlock.builder().text("北京今天天气怎么样?").build()))
    .build();

Msg response = agent.call(List.of(msg)).block();
System.out.println(response.getTextContent());

8.2 流式调用(2.0 新 API)

java 复制代码
agent.streamEvents(List.of(msg))
    .filter(e -> e instanceof TextBlockDeltaEvent)
    .map(e -> ((TextBlockDeltaEvent) e).getDelta())
    .subscribe(System.out::print);

8.3 多轮对话(带 RuntimeContext)

java 复制代码
RuntimeContext context = RuntimeContext.create();
Msg first = Msg.builder().role(MsgRole.USER).content("帮我算 3+5").build();
Msg r1 = agent.call(List.of(first), context).block();

Msg second = Msg.builder().role(MsgRole.USER).content("再乘以 2").build();
Msg r2 = agent.call(List.of(second), context).block();

9. 完整 Spring Boot 示例

9.1 配置类

java 复制代码
@Configuration
public class AgentConfig {

    @Bean
    public Model model() {
        return Model.builder()
            .provider("dashscope")
            .model("qwen-max")
            .apiKey(System.getenv("DASHSCOPE_API_KEY"))
            .build();
    }

    @Bean
    public Toolkit toolkit() {
        return Toolkit.builder()
            .addTool(new WeatherTool())
            .addTool(new CalculatorTool())
            .build();
    }

    @Bean
    public ReActAgent agent(Model model, Toolkit toolkit) {
        return ReActAgent.builder()
            .name("demo-agent")
            .model(model)
            .toolkit(toolkit)
            .sysPrompt("你是一个有用的 AI 助手,用中文回答。")
            .maxIters(5)
            .build();
    }
}

9.2 控制器

java 复制代码
@RestController
public class AgentController {

    private final ReActAgent agent;

    // 同步
    @GetMapping("/call")
    public Mono<Map<String, Object>> call(@RequestParam String query) {
        Msg msg = Msg.builder().role(MsgRole.USER)
            .content(List.of(TextBlock.builder().text(query).build()))
            .build();
        return agent.call(List.of(msg))
            .map(r -> Map.of("query", query, "response", r.getTextContent()));
    }

    // 流式
    @GetMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> stream(@RequestParam String query) {
        Msg msg = Msg.builder().role(MsgRole.USER)
            .content(List.of(TextBlock.builder().text(query).build()))
            .build();
        return agent.streamEvents(List.of(msg))
            .filter(e -> e instanceof TextBlockDeltaEvent)
            .map(e -> "data: " + ((TextBlockDeltaEvent) e).getDelta() + "\n\n");
    }
}
相关推荐
智鸟科技GemeOpen开发者智能设备1 小时前
智能插座二次开发如何接入Home Assistant,从零开始完整工程实现(Python+React)
开发语言·python·物联网·react.js·智能家居
疯狂成瘾者1 小时前
海康 Artemis 接口对接
开发语言·lua
艸肅1 小时前
Ubuntu 安装 JDK (含手动安装)
java·ubuntu·jdk
2601_962218611 小时前
C++中decltype关键字的实现
开发语言·c++
hqyjzsb1 小时前
法律 Prompt 干货:搭建合同审查提示词要包含哪些要素
开发语言·人工智能·python·职场和发展·数据分析·prompt·业界资讯
m0_734172421 小时前
Python字典计数怎样处理首次出现的键
java
孙启超1 小时前
【AI开发之Rust】第 19 课:UniFFI 导出核心能力
开发语言·后端·rust
卓怡学长2 小时前
w204基于springbo旅行社签证代理服务系统
java·spring boot·spring·intellij-idea
泡海椒2 小时前
趋势分析报表:jquick-pdf折线图PDF生成实战
java·大数据·运维·服务器·前端·pdf