阿里开源AgentScope-Java多智能体框架快速入门指南

2026-06-01阅读 0热度 0
智能体

总述

AgentScope-Java 是一款面向生产环境的 AI 智能体编程框架,专为 Java 生态打造,用于构建由大模型驱动的智能应用。该框架不仅实现了 Agent、模型与工具三大核心环节的串联,更关键的是,它将运行时控制、内置工具、协议集成与可观测性这类企业级应用的刚性需求,作为一等公民融入体系设计。

阿里开源AgentScope多智能体框架解析系列(一)第1章:AgentScope-Ja va 概述与快速入门

接下来,我们围绕 **What(定义)、Why(选型理由)、How(落地实践)** 三条主线,拆解 AgentScope-Java,并结合真实的业务场景,看它如何解决那些棘手的工程难题。

主架构设计图

graph TB
    User[用户/应用] --> Agent[Agent接口层]
    Agent --> ReActAgent[ReActAgent
推理-行动循环] Agent --> UserAgent[UserAgent
用户交互] Agent --> OtherAgents[其他Agent实现] ReActAgent --> Model[Model层
LLM调用] ReActAgent --> Memory[Memory层
记忆管理] ReActAgent --> Toolkit[Toolkit层
工具管理] ReActAgent --> Hook[Hook系统
事件拦截] Model --> DashScope[DashScope] Model --> OpenAI[OpenAI] Model --> Anthropic[Anthropic] Model --> Gemini[Gemini] Model --> Formatter[Formatter
消息格式化] Memory --> InMemory[InMemoryMemory] Memory --> LongTerm[LongTermMemory] Memory --> Session[Session持久化] Toolkit --> ToolRegistry[ToolRegistry
工具注册表] Toolkit --> ToolExecutor[ToolExecutor
工具执行器] Toolkit --> MCP[MCP集成] Hook --> RAGHook[RAG Hook] Hook --> PlanHook[Plan Hook] Hook --> MemoryHook[Memory Hook] Hook --> CustomHook[自定义Hook] ReActAgent --> Pipeline[Pipeline
多智能体协作] ReActAgent --> Interruption[Interruption Tracing[Tracing
可观测性] style Agent fill:#e1f5ff style ReActAgent fill:#fff4e1 style Model fill:#e8f5e9 style Memory fill:#f3e5f5 style Toolkit fill:#fff9c4 style Hook fill:#ffe0b2

这张图清晰勾勒出核心组件间的依赖关系:Agent 接口层位于最上层,其下是 ReActAgent 这一核心实现,串联起模型、记忆、工具与 Hook 四大模块。工具与 Hook 尤为关键,因为它们直接决定了框架能否真正落地到生产环境。

1. ReActAgent 执行流程

sequenceDiagram
    participant User as 用户
    participant Agent as ReActAgent
    participant Hook as Hook系统
    participant Model as LLM模型
    participant Toolkit as 工具箱
    participant Memory as 记忆系统

    User->>Agent: call(msg)
    Agent->>Memory: 添加用户消息

    loop 推理-行动循环
        Agent->>Hook: PreReasoningEvent
        Hook-->>Agent: 处理钩子

        Agent->>Memory: 获取历史消息
        Memory-->>Agent: 返回消息列表
        Agent->>Model: 请求推理
        Model-->>Agent: 返回思考+工具调用

        Agent->>Hook: PostReasoningEvent
        Hook-->>Agent: 处理钩子

        alt 需要调用工具
            Agent->>Hook: PreActingEvent
            Hook-->>Agent: 处理钩子
            Agent->>Toolkit: 执行工具
            Toolkit-->>Agent: 工具结果
            Agent->>Hook: PostActingEvent
            Hook-->>Agent: 处理钩子
            Agent->>Memory: 保存工具结果
        else 无需工具调用
            Agent->>Memory: 保存最终回答
            Agent-->>User: 返回结果
        end
    end

这个时序图完整呈现了 Agent 内部的推理-行动循环。关键设计在于,每次推理与行动的前后都预留了 Hook 插入点。这意味着你可以在 Agent 完全不知情的情况下,向其思考过程注入外部知识、控制逻辑,甚至直接中断执行。

2. 工具调用流程

sequenceDiagram
    participant Agent as ReActAgent
    participant Toolkit as Toolkit
    participant Registry as ToolRegistry
    participant Executor as ToolExecutor
    participant Tool as 实际工具方法
    participant Context as ExecutionContext

    Agent->>Toolkit: 调用工具
    Toolkit->>Registry: 查找工具定义
    Registry-->>Toolkit: 返回工具元数据
    Toolkit->>Executor: 准备执行
    Executor->>Context: 设置执行上下文
    Executor->>Tool: 反射调用方法
    Tool-->>Executor: 返回结果
    Executor->>Context: 清理上下文
    Executor-->>Toolkit: 返回执行结果
    Toolkit-->>Agent: 返回格式化结果

工具调用的核心逻辑并不复杂。Agent 通过 Toolkit 查找到已注册的工具,ToolExecutor 利用反射调用对应方法。设计上的亮点在于 ExecutionContext,它确保工具执行过程与外部环境隔离,有效避免状态污染。

3. Hook 系统执行流程

sequenceDiagram
    participant Agent as ReActAgent
    participant HookChain as Hook链
    participant RAGHook as RAG Hook
    participant MemoryHook as Memory Hook
    participant PlanHook as Plan Hook
    participant Model as LLM模型

    Agent->>HookChain: 触发PreReasoningEvent
    HookChain->>RAGHook: handle(event)
    RAGHook->>RAGHook: 检索相关知识
    RAGHook->>HookChain: 添加知识到提示词
    HookChain->>MemoryHook: handle(event)
    MemoryHook->>MemoryHook: 检索长期记忆
    MemoryHook->>HookChain: 添加记忆到提示词
    HookChain->>PlanHook: handle(event)
    PlanHook->>PlanHook: 获取当前计划
    PlanHook->>HookChain: 添加计划提示
    HookChain-->>Agent: 返回增强后的消息
    Agent->>Model: 发送请求

Hook 系统采用责任链模式,你可以将各种自定义逻辑像插件一样插入 Agent 的推理流程。例如,在此处集成 RAG 检索、查询长期记忆,或根据当前计划动态调整提示词。好处很明显:核心 Agent 代码无需修改,所有扩展能力均通过 Hook 机制注入。

4. 流式响应处理流程

sequenceDiagram
    participant User as 用户
    participant Agent as ReActAgent
    participant Model as LLM模型
    participant Accumulator as ContentAccumulator
    participant Stream as 事件流

    User->>Agent: stream(msg, options)
    Agent->>Model: 请求流式响应

    loop 流式接收
        Model-->>Agent: ChatResponse chunk
        Agent->>Accumulator: 累积内容

        alt 推理阶段
            Accumulator->>Stream: ReasoningChunkEvent
            Stream-->>User: 实时推理内容
        else 行动阶段
            Accumulator->>Stream: ActingChunkEvent
            Stream-->>User: 实时执行内容
        end
    end

    Model-->>Agent: 最终响应
    Agent->>Stream: 完整事件(isLast=true)
    Stream-->>User: 最终结果

流式响应是众多业务场景的刚性需求。AgentScope 的流式处理将推理过程与行动过程拆解为独立的事件流,用户能够在 Agent 思考的同时,实时看到它正在推理什么,或正在执行哪项工具调用。这种透明性对调试和用户体验的价值不言而喻。

5. 中断与恢复流程

sequenceDiagram
    participant User as 用户
    participant Agent as ReActAgent
    participant Context as InterruptContext
    participant Tool as 工具执行
    participant Memory as 记忆系统

    User->>Agent: call(msg)
    Agent->>Tool: 执行长时工具

    User->>Agent: interrupt()
    Agent->>Context: 设置中断标志
    Tool->>Context: 检查中断状态
    Context-->>Tool: 已中断
    Tool-->>Agent: 取消执行
    Agent->>Memory: 保存中断状态
    Agent-->>User: 返回中断信息

    User->>Agent: call() 继续执行
    Agent->>Memory: 恢复上下文
    Agent->>Tool: 重新执行或跳过
    Tool-->>Agent: 完成
    Agent-->>User: 返回结果

中断与恢复机制相当关键。设想一下,当 Agent 正在执行一个耗时工具调用,而你发现它行动路线完全偏离预期,此时可以直接打断它,保存当前上下文,随后恢复执行。这种控制能力在必须保证人机协同的场景中,不可或缺。

1.1 项目背景与设计理念

1.1.1 为什么需要AgentScope-Ja va?

用大模型构建智能应用,开发者在实践中会遇到几个绕不开的坑。

问题1:LLM的自主性与可控性矛盾

假设你给电商平台做了一个自主 AI 助手,它能够自主查询商品、推荐产品、处理订单。但某天,它出现了幻觉,给客户承诺了一个根本不存在的优惠,或者尝试完成一项它没有权限的操作。此时你该怎么办?

AgentScope 的解决方案很明确:

  • 安全中断:你可以在任意时刻暂停 Agent,完整的上下文和工具状态都会被保留,后续还能无损恢复。
  • 优雅取消:可以终止长时间运行的工具调用,同时保证 Agent 内部状态不崩溃。
  • 人机协同:通过 Hook 系统,你可以在任何一个推理步骤注入修正、额外上下文,或直接给出指导。
graph LR
    A["自主决策循环"] -->|发现问题| B["暂停"]
    B -->|人工审核| C["修正/取消"]
    C -->|恢复上下文| D["继续执行"]

问题2:多步骤复杂任务的结构化管理

当用户提出一个需要 10 个步骤才能完成的请求时,比如“先分析数据,再生成报告,最后发邮件”,如果中间某一步挂了,你很难搞清楚当前进度,更别提修改计划或者恢复执行了。

AgentScope 引入了一个叫PlanNotebook的组件,专门做结构化任务管理。它可以自动跟踪多步骤工作流,支持动态修改、暂停、恢复,甚至并发执行多个计划。更有意思的是,它可以和 Agent 的推理过程集成,让 Agent 自发创建和修改自己的计划。

graph TB
    Plan["计划(Plan)"]
    Plan --> SubTask1["子任务1:准备数据"]
    Plan --> SubTask2["子任务2:生成图表"]
    Plan --> SubTask3["子任务3:撰写总结"]
    SubTask1 --> Status1["状态:待执行/进行中/完成/放弃"]
    SubTask2 --> Status2["状态:待执行/进行中/完成/放弃"]
    SubTask3 --> Status3["状态:待执行/进行中/完成/放弃"]

问题3:LLM输出的不可靠性

你让 Agent 调用一个 API,返回 JSON 格式的数据。但大模型可能会返回格式错误的 JSON,缺少必要字段,甚至塞进一些完全不正确的值。常规做法是写一堆验证和重试逻辑。

AgentScope 的处理方式更聪明:它提供了结构化输出功能。如果 LLM 返回的内容不符合预期格式,系统会自动重试,并在重试时告知 LLM“你上次的格式有问题,请按正确格式生成”。整个过程对开发者透明,而且可以直接映射到 Java POJO,实现类型安全。

问题4:知识库与LLM的集成

企业场景下,AI 助手通常需要基于内部知识库(如 FAQ、操作文档、培训资料)来回答问题。但简单地把所有文档塞进 Prompt,不仅会造成 Token 溢出,回答精度也会大幅下降。

AgentScope 的 RAG(检索增强生成)模块解决了这个问题。它支持多知识库集成,包括自建知识库、阿里云百炼、Dify 等第三方服务。这些能力可以通过 Hook 或 Tool 的形式透明地增强 Agent 的回答能力,核心代码无需改动。

问题5:工具生态碎片化

现代智能应用需要集成的外部服务太多了:OpenAI 的 API、企业内部的微服务、MCP 生态里的各种工具。每次对接一个新服务,往往都要重写集成代码。

AgentScope 把工具生态做了统一抽象:

  • MCP协议集成:可以直接连接到 MCP 生态里的任何工具和服务。
  • A2A协议:支持分布式多 Agent 协作,通过服务注册中心自动发现和调用。
  • 统一工具系统:不管是本地用@Tool注解定义的工具,还是 MCP 工具,都通过统一的接口调用。

1.1.2 核心设计理念

理念1:响应式非阻塞架构

AgentScope-Java 基于 Project Reactor 构建,所有操作都是非阻塞的。这意味着什么?

业务意义:
├─ 高吞吐量:一个线程可以处理数千个并发Agent
├─ 低延迟:充分利用CPU,避免线程阻塞浪费
├─ 良好扩展性:支持Serverless、容器编排等云原生部署
└─ 可观测性更好:异步操作更容易追踪和监控

代码上的体现也很直观:

// 所有操作返回 Mono 或 Flux
Mono response = agent.call(userMessage);
response.subscribe(msg -> System.out.println(msg.getTextContent()));

// 支持链式异步操作
agent.call(msg1).flatMap(response -> agent.call(response)).subscribe();

理念2:消息驱动通信

Agent 之间通过不可变的 Message 对象(Msg)通信,而不是直接调用对方的方法。这么做的好处很直接:

优势:
├─ 解耦:Agent不需要知道其他Agent的内部实现
├─ 可追踪:所有通信都记录为消息,便于调试和审计
├─ 支持存储:消息可以被持久化、重放、分析
└─ 支持扩展:消息可以包含多种内容类型(文本、图片、音频、工具调用等)

理念3:可组合与可扩展

  • Agent可组合:可以在 Pipeline 中组织多个 Agent,实现复杂的协作模式。
  • 工具可扩展:通过@Tool注解轻松添加新工具,或者集成 MCP/A2A 工具。
  • Hook可插拔:在 Agent 执行的任何阶段插入自定义逻辑,不需要修改核心代码。

1.2 核心特性介绍

1.2.1 ReAct 推理-行动循环

ReAct(Reasoning + Acting)是这个框架的灵魂,它让 Agent 具备自主规划和执行任务的能力。

什么是ReAct?

第1轮:
用户: "帮我分析过去12个月的销售数据"
↓
[推理阶段] Agent思考: "我需要查询销售数据库,然后分析数据,最后生成报告"
↓
[行动阶段] Agent执行: 调用 query_sales_data 工具,获得数据
↓
[结果] 获得JSON格式的销售数据

第2轮:
[推理阶段] Agent思考: "现在我有数据了,我需要计算增长率、趋势等"
↓
[行动阶段] Agent执行: 调用 analyze_data 工具
↓
[结果] 获得分析结果

第3轮:
[推理阶段] Agent思考: "分析完成了,现在生成报告"
↓
[行动阶段] Agent执行: 调用 generate_report 工具
↓
[结果] 最终报告生成完成

为什么ReAct比Prompt Chaining更优?

方面Prompt ChainingReAct
灵活性固定的步骤动态决定下一步
适应性无法处理出错情况可以重试或改变策略
工具利用预定义的工具序列动态选择最合适的工具
可控性很难干预支持在任意步骤暂停和修正

生产场景示例:客服工单处理

用户问题: "我的订单 #12345 已经5天还没收到,我需要退款"

↓
Agent推理:"我需要:1. 查询订单状态(调用order_status工具)2. 根据状态决定是否需要查询物流信息或直接处理退款3. 生成解决方案"
↓
[工具调用] 查询订单 #12345
结果:订单状态为"已发货,预计3-5天送达",今天是第5天,已超期
↓
Agent推理:"订单已超期,我需要:1. 查询物流信息,确认是否丢失2. 根据结果决定是补邮还是退款"
↓
[工具调用] 查询物流信息
结果:物流显示包裹在运输中,但延迟了
↓
Agent推理:"物流延迟,我应该为客户自动赔偿100积分,并承诺加急配送。如果客户坚持退款,触发人工审批"
↓
[工具调用] 给客户加100积分 + 加急配送处理
↓
返回给用户:自动方案 + 人工审批链接

1.2.2 工具调用系统

工具是 Agent 与现实世界交互的桥梁。AgentScope 提供了一个简洁但功能强大的工具系统。

快速定义工具

// 第1步:创建一个类,添加@Tool注解的方法
public class WeatherTools {

    @Tool(name = "get_weather", description = "Get current weather for a city")
    public String getWeather(
            @ToolParam(name = "city", description = "City name") String city,
            @ToolParam(name = "unit", description = "Temperature unit, celsius or fahrenheit") String unit) {
        // 实际的获取天气的逻辑
        return String.format("Weather in %s: 25°%s, Sunny", city, unit);
    }

    @Tool(name = "get_forecast", description = "Get 7-day forecast for a city")
    public String getForecast(
            @ToolParam(name = "city", description = "City name") String city) {
        return String.format("7-day forecast for %s: ...", city);
    }
}

// 第2步:注册到工具箱
Toolkit toolkit = new Toolkit();
toolkit.registerObject(new WeatherTools());

// 第3步:传给Agent,就可以自动使用
ReActAgent agent = ReActAgent.builder()
        .toolkit(toolkit)
        .build();

工具系统如何工作?

graph TB
    A["Agent"]
    B["推理:我需要查询天气"]
    C["Model返回:调用 get_weather 工具,参数:city=beijing, unit=celsius"]
    D["工具系统"]
    E["ToolRegistry:查找 get_weather 的定义"]
    F["ToolExecutor:反射调用 WeatherTools.getWeather方法"]
    G["WeatherTools.getWeather 执行"]
    H["返回结果给Agent"]

    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    G --> H

生产场景:销售订单系统

public class OrderTools {

    @Tool(name = "create_order", description = "Create a new sales order")
    public String createOrder(
            @ToolParam(name = "customer_id") String customerId,
            @ToolParam(name = "items") String itemsJson, // JSON格式: [{sku, qty, price}]
            @ToolParam(name = "discount_percent", description = "Discount 0-100") int discount) {

        // 生产环节:
        // 1. 验证输入
        if (discount < 0 || discount > 100) {
            throw new IllegalArgumentException("Discount must be 0-100");
        }

        // 2. 调用订单系统API
        OrderRequest req = new OrderRequest(customerId, itemsJson, discount);
        OrderResponse resp = orderService.createOrder(req);

        // 3. 返回结构化结果(方便Agent理解)
        return String.format("Order created: ID=%s, Total=%.2f, Status=%s",
                resp.getOrderId(), resp.getTotalPrice(), resp.getStatus());
    }

    @Tool(name = "query_order", description = "Query order status and details")
    public String queryOrder(
            @ToolParam(name = "order_id") String orderId) {
        OrderDetails details = orderService.getOrder(orderId);
        return ObjectMappers.toJson(details);
    }

    @Tool(name = "apply_promotion", description = "Apply a promotion code to an order")
    public String applyPromotion(
            @ToolParam(name = "order_id") String orderId,
            @ToolParam(name = "promo_code") String promoCode) {

        // 验证promo_code的有效性
        Promotion promo = promotionService.validatePromo(promoCode);
        if (promo == null) {
            return "Promotion code invalid or expired";
        }

        // 应用折扣
        ApplyResult result = orderService.applyPromotion(orderId, promo);
        return String.format("Promotion applied: new_total=%.2f, discount=%.2f",
                result.getNewTotal(), result.getDiscount());
    }
}

// 使用示例:
Toolkit toolkit = new Toolkit();
toolkit.registerObject(new OrderTools());

ReActAgent agent = ReActAgent.builder()
        .name("Sales Assistant")
        .sysPrompt("You are a helpful sales assistant. Help customers create orders and apply promotions. " +
                "Never apply discount > 20% unless customer has valid promotion code.")
        .model(model)
        .toolkit(toolkit)
        .build();

// Agent会自动调用这些工具
Msg response = agent.call(Msg.builder()
        .textContent("Customer: Zhang Wei wants to buy 2 units of SKU-001 at ¥100 each. " +
                     "Create an order and apply promo code WELCOME10")
        .build()).block();

1.2.3 记忆系统

Agent 需要记住对话历史和关键信息,才能在多轮交互中保持上下文。AgentScope 的記憶系统分了三层:

三层记忆架构

┌─────────────────────────────────────────┐
│        短期记忆 (Short-term Memory)       │
│  - 当前会话的所有消息                     │
│  - 最近N轮对话                         │
│  - 用途:即时上下文                    │
└─────────────────────────────────────────┘
                      ↓ 当消息堆积时自动压缩
┌─────────────────────────────────────────┐
│       中期记忆 (Medium-term Memory)      │
│  - 重要对话的摘要                       │
│  - 关键决策和结果                       │
│  - 用途:跨越较长时间保留重要信息         │
└─────────────────────────────────────────┘
                      ↓
┌─────────────────────────────────────────┐
│       长期记忆 (Long-term Memory)        │
│  - 跨会话的持久化存储                    │
│  - 支持语义搜索(向量化)               │
│  - 用途:学习过去的经验,做出更好的决策    │
└─────────────────────────────────────────┘

生产场景:客户关系管理

// 场景:一个AI客服需要记住常见客户信息
ReActAgent agent = ReActAgent.builder()
        .name("Customer Service Agent")
        .model(model)
        .toolkit(toolkit)
        // 配置长期记忆:客户会自动记住重要信息
        .withLongTermMemory(longTermMemory,
                LongTermMemoryMode.HYBRID // 自动+主动记录混合模式)
        .build();

// 第1次对话(User: Alice)
agent.call(Msg.builder()
        .textContent("Hello! I'm Alice from TechCorp. I've been a customer for 3 years. " +
                     "We usually buy 100 units of Product X every month. " +
                     "This month we need to increase to 200 units.")
        .build()).block();
// Agent自动记住:Alice / TechCorp / 3年老客户 / 正常订购量100 / 本月200

// 一周后,Alice再次联系
agent.call(Msg.builder()
        .textContent("Hi! It's Alice again. Can you remind me what we discussed last week?")
        .build()).block();
// Agent的长期记忆让它能够:
// ✓ 立即认出Alice是老客户
// ✓ 回忆上周的增量订单需求
// ✓ 做出个性化的服务建议(如:由于你增量订购,这个月可以享受额外2%折扣)

1.2.4 多智能体协作

单个 Agent 的能力是有限的。AgentScope 支持多个 Agent 在 Pipeline 中协作,形成复杂的处理流程。

Pipeline模式

场景:内容创作工作流

用户输入: "写一篇关于AI技术趋势的文章"

    
┌─────────────────────────────────┐
  Agent 1: 研究员 Agent         
  职责:搜索和整理相关资料       
└──────────────┬──────────────────┘
               
┌─────────────────────────────────┐
  Agent 2: 写作 Agent             
  职责:基于研究员的资料进行创作 
└──────────────┬──────────────────┘
               
┌─────────────────────────────────┐
  Agent 3: 审核 Agent             
  职责:检查文章的正确性和风格   
└──────────────┬──────────────────┘
               
           最终文章输出

并行工作流

用户输入: "为我生成一份综合性的年度报告"

    

    ├─→  Agent A: 财务分析          ─┐
                                  
    ├─→  Agent B: 市场分析          ─┤─→ 汇总 Agent → 最终报告
                                  
    └─→  Agent C: 竞争对手分析      ─┘

生产代码示例

// 定义三个专业的Agent
ReActAgent researchAgent = ReActAgent.builder()
        .name("Research")
        .sysPrompt("You are a research expert. Search and gather relevant information.")
        .model(model)
        .toolkit(researchToolkit)
        .build();

ReActAgent writerAgent = ReActAgent.builder()
        .name("Writer")
        .sysPrompt("You are a professional writer. Write high-quality content.")
        .model(model)
        .toolkit(writerToolkit)
        .build();

ReActAgent reviewerAgent = ReActAgent.builder()
        .name("Reviewer")
        .sysPrompt("You are an editor. Review and improve content for clarity and style.")
        .model(model)
        .toolkit(reviewerToolkit)
        .build();

// 创建顺序Pipeline:研究 → 写作 → 审核
SequentialPipeline pipeline = new SequentialPipeline<>(
        List.of(researchAgent, writerAgent, reviewerAgent),
        (response, nextAgent) -> {
            // 将前一个Agent的输出转为下一个Agent的输入
            return Msg.builder()
                    .role(MsgRole.ASSISTANT)
                    .content(TextBlock.builder()
                            .text("Based on the previous work:\n" + response.getTextContent())
                            .build())
                    .build();
        });

// 执行
Msg result = pipeline.execute(Msg.builder()
        .textContent("Write an article about AI trends")
        .build()).block();

1.3 快速开始示例解析

1.3.1 最小化可工作示例

先看一个最简单的例子,感受一下AgentScope的工作流程:

package com.example;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.model.DashScopeChatModel;

public class HelloAgentExample {
    public static void main(String[] args) {
        // 第1步:创建模型(连接到LLM)
        DashScopeChatModel model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))  // 从环境变量读取API Key
                .modelName("qwen-plus")                        // 使用通义千问Plus模型
                .build();

        // 第2步:创建Agent
        ReActAgent agent = ReActAgent.builder()
                .name("Assistant")
                .sysPrompt("You are a helpful AI assistant.")  // 系统提示词
                .model(model)
                .build();

        // 第3步:调用Agent
        Msg userMessage = Msg.builder()
                .textContent("你好!请告诉我2024年有哪些重要的科技事件")
                .build();
        Msg response = agent.call(userMessage).block();  // .block() 等待响应

        // 第4步:获取结果
        System.out.println("Agent: " + response.getTextContent());
    }
}

执行流程详解

1步:创建模型(DashScopeChatModel)
├─ 初始化HTTP客户端
├─ 配置API Key和模型名称
└─ 准备与DashScope API通信

第2步:创建Agent(ReActAgent)
├─ 初始化系统提示词
├─ 设置内存为默认的InMemoryMemory
├─ 注册模型和默认工具箱
└─ 准备好处理用户输入

第3步:创建用户消息(Msg)
├─ 设置消息内容为纯文本
├─ 默认角色为USER
└─ 自动生成唯一ID和时间戳

第4步:调用Agent
agent.call(userMessage) 返回 Mono
.block() 阻塞等待响应(生产环境应使用异步处理)
└─ 返回Agent的完整响应

第5步:提取并显示结果
response.getTextContent() 获取文本内容
└─ 输出:Agent生成的回答

1.3.2 使用工具的示例

上一个示例中,Agent只能通过对话回答。现在给它加上工具能力:

package com.example;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.message.Msg;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;
import io.agentscope.core.tool.Toolkit;

public class AgentWithToolsExample {

    // 第1步:定义工具类
    public static class CalculatorTools {
        @Tool(name = "add", description = "Add two numbers")
        public String add(
                @ToolParam(name = "a", description = "First number") double a,
                @ToolParam(name = "b", description = "Second number") double b) {
            return String.valueOf(a + b);
        }

        @Tool(name = "multiply", description = "Multiply two numbers")
        public String multiply(
                @ToolParam(name = "a", description = "First number") double a,
                @ToolParam(name = "b", description = "Second number") double b) {
            return String.valueOf(a * b);
        }
    }

    public static void main(String[] args) {
        // 第2步:创建模型
        DashScopeChatModel model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .build();

        // 第3步:创建工具箱并注册工具
        Toolkit toolkit = new Toolkit();
        toolkit.registerObject(new CalculatorTools());

        // 第4步:创建Agent并配置工具箱
        ReActAgent agent = ReActAgent.builder()
                .name("MathAssistant")
                .sysPrompt("You are a helpful math assistant. " +
                        "Use the calculator tools to solve math problems.")
                .model(model)
                .toolkit(toolkit)  // 传入工具箱
                .build();

        // 第5步:调用Agent
        Msg response = agent.call(Msg.builder()
                .textContent("25乘以48等于多少?")
                .build()).block();
        System.out.println("Result: " + response.getTextContent());
    }
}

带工具调用的执行流程

用户: "25乘以48等于多少?"

↓
[推理阶段]
Agent收到问题,思考:需要调用 multiply(25, 48)
Model返回:{"tool_call": "multiply", "args": {"a": 25, "b": 48}}

↓
[行动阶段]
ToolExecutor找到 CalculatorTools.multiply 方法
反射调用:multiply(25.0, 48.0)
得到结果:1200.0

↓
[反馈到内存]
Agent记住:multiply(25, 48) = 1200

↓
[推理阶段]
Agent继续思考:我已经得到结果了,可以回答用户
Model返回:最终答案的文本

↓
[完成]
返回给用户:25乘以48等于1200

1.3.3 包含记忆的对话示例

再来一个能记住对话历史的Agent:

package com.example;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.message.Msg;
import io.agentscope.core.model.DashScopeChatModel;

public class ConversationWithMemoryExample {
    public static void main(String[] args) throws InterruptedException {
        DashScopeChatModel model = DashScopeChatModel.builder()
                .apiKey(System.getenv("DASHSCOPE_API_KEY"))
                .modelName("qwen-plus")
                .build();

        // 创建Agent并配置记忆
        ReActAgent agent = ReActAgent.builder()
                .name("Conversational AI")
                .sysPrompt("You are a friendly assistant. Remember the context of conversations.")
                .model(model)
                .memory(new InMemoryMemory())  // 明确创建记忆对象
                .build();

        // 第1轮对话
        System.out.println("=== 第1轮对话 ===");
        Msg msg1 = agent.call(Msg.builder()
                .textContent("我叫张三,我是一个工程师")
                .build()).block();
        System.out.println("User: 我叫张三,我是一个工程师");
        System.out.println("Agent: " + msg1.getTextContent());
        Thread.sleep(1000);  // 等待1秒

        // 第2轮对话:Agent应该记得张三的身份
        System.out.println("\n=== 第2轮对话 ===");
        Msg msg2 = agent.call(Msg.builder()
                .textContent("我的工作是什么?")
                .build()).block();
        System.out.println("User: 我的工作是什么?");
        System.out.println("Agent: " + msg2.getTextContent());
        // Agent会回答:你是一个工程师,之前告诉我的

        // 第3轮对话
        System.out.println("\n=== 第3轮对话 ===");
        Msg msg3 = agent.call(Msg.builder()
                .textContent("我最擅长的编程语言是Ja va。这个信息对我的工作有什么影响?")
                .build()).block();
        System.out.println("User: 我最擅长的编程语言是Ja va。这个信息对我的工作有什么影响?");
        System.out.println("Agent: " + msg3.getTextContent());
        // Agent能综合前面的信息做出回答
    }
}

记忆如何工作?

第1轮对话:
Agent.call(msg) → memory.addMessage(userMsg) + memory.addMessage(agentResponse)
记忆状态:[UserMessage: "我叫张三,我是一个工程师"]
         [AssistantMessage: "Nice to meet you, 张三! 很高兴认识你..."]

第2轮对话:
Agent.call(msg) → 
  1. memory.addMessage(userMsg)
  2. memory.getMessages() 返回所有历史消息(包括第1轮)
  3. 将完整的历史消息发送给Model
  4. Model生成响应,记住了张三的身份
  5. memory.addMessage(agentResponse)
记忆状态:[UserMessage: "我叫张三,我是一个工程师"]
         [AssistantMessage: "..."]
         [UserMessage: "我的工作是什么?"]
         [AssistantMessage: "根据你之前告诉我..."]

1.4 项目结构与模块划分

1.4.1 整体模块组织

agentscope-ja va/
├── agentscope-core/                     # 核心模块(必需)
│   ├── src/main/ja va/io/agentscope/core/
│   │   ├── agent/                      # Agent接口和实现
│   │   ├── message/                    # 消息系统(Msg、ContentBlock等)
│   │   ├── model/                     # 模型接口和实现
│   │   ├── tool/                       # 工具系统(@Tool、Toolkit)
│   │   ├── memory/                    # 记忆系统
│   │   ├── hook/                      # Hook系统(事件拦截)
│   │   ├── plan/                      # PlanNotebook任务管理
│   │   ├── rag/                       # RAG检索增强生成
│   │   ├── pipeline/                  # 多Agent协作管道
│   │   ├── session/                   # 会话管理(持久化)
│   │   ├── skill/                     # 技能系统
│   │   ├── interruption/              # 中断和取消机制
│   │   ├── tracing/                   # 可观测性追踪
│   │   └── ReActAgent.ja va            # 核心实现
│   └── pom.xml
│
├── agentscope-extensions/               # 扩展模块(可选)
│   ├── agentscope-extensions-scheduler/ # 定时调度
│   ├── agentscope-extensions-rag-*/     # 各种RAG集成
│   ├── agentscope-extensions-a2a/       # A2A多Agent协议
│   ├── agentscope-extensions-studio/    # Studio集成
│   ├── agentscope-spring-boot-starters/ # Spring Boot集成
│   └── ...
│
├── agentscope-examples/                 # 示例代码
│   ├── quickstart/                     # 快速开始
│   ├── boba-tea-shop/                 # 完整应用示例
│   ├── werewolf/                      # 游戏示例
│   └── ...
│
└── docs/                               # 文档
    ├── zh/                             # 中文文档
    ├── en/                             # 英文文档
    └── llm/                            # LLM相关文档

1.4.2 核心模块详解

1. Agent接口层(agent/

核心类:
├── Agent              # 所有Agent的接口
├── AgentBase          # Agent的基础实现
├── ReActAgent         # ReAct推理-行动循环实现
├── UserAgent          # 用户交互Agent
└── StructuredOutputHandler  # 结构化输出处理

职责:定义Agent的行为和生命周期。关键方法:call()observe()interrupt()stream()

2. 消息系统(message/

核心类:
├── Msg                # 消息对象(不可变)
├── MsgRole            # 消息角色枚举
│   ├── USER           # 用户消息
│   ├── ASSISTANT      # Agent回复
│   ├── SYSTEM         # 系统消息
│   └── TOOL           # 工具执行结果
└── ContentBlock及其实现
    ├── TextBlock      # 文本内容
    ├── ImageBlock     # 图像内容
    ├── AudioBlock     # 音频内容
    ├── VideoBlock     # 视频内容
    ├── ToolUseBlock   # 工具调用
    └── ToolResultBlock # 工具结果

设计特点:

  • 不可变设计(Immutable),线程安全。
  • 支持多种内容类型,天然支持多模态。
  • 元数据支持,便于携带结构化数据。

3. 模型层(model/

核心接口/类:
├── Model                     # 模型接口
│   └── stream()              # 流式调用LLM
├── Model实现
│   ├── DashScopeChatModel    # 阿里云通义千问
│   ├── OpenAiChatModel       # OpenAI GPT
│   ├── GeminiChatModel       # Google Gemini
│   └── AnthropicChatModel    # Anthropic Claude
├── GenerateOptions           # 生成参数(temperature、max_tokens等)
├── ChatResponse              # 模型响应
└── Formatter                 # 消息格式化器

职责:屏蔽不同LLM的差异,提供统一接口。

4. 工具系统(tool/

核心类:
├── @Tool                 # 工具注解
├── @ToolParam            # 工具参数注解
├── Toolkit               # 工具箱(管理多个工具)
├── AgentTool             # 工具接口
├── ToolSchema            # 工具定义(发送给LLM的描述)
├── ToolExecutor          # 工具执行器
├── ToolRegistry          # 工具注册表
└── mcp/
    └── McpTool           # MCP协议工具适配

工作流:

@Tool注解 → ToolRegistry(发现) → ToolSchema(生成定义) → Model(选择工具)
    → ToolExecutor(执行) → 结果返回

5. 记忆系统(memory/

核心类:
├── Memory                     # 记忆接口
├── InMemoryMemory             # 内存实现
├── LongTermMemory             # 长期记忆(跨会话)
├── LongTermMemoryTools        # LTM相关工具
├── LongTermMemoryMode         # LTM工作模式
└── StaticLongTermMemoryHook   # LTM Hook集成

特点:

  • 短期记忆:当前对话历史。
  • 长期记忆:跨会话持久化存储,支持语义搜索。

6. Hook系统(hook/

核心类:
├── Hook                       # Hook接口
├── HookEvent                  # Hook事件基类
│   ├── PreReasoningEvent      # 推理前
│   ├── ReasoningChunkEvent    # 推理流式
│   ├── PostReasoningEvent     # 推理后
│   ├── PreActingEvent         # 行动前
│   ├── ActingChunkEvent       # 行动流式
│   └── PostActingEvent        # 行动后
└── HookChain                  # Hook链(责任链模式)

用途:在Agent执行的各个阶段插入自定义逻辑。

7. 任务管理(plan/

核心类:
├── PlanNotebook               # 计划管理工具
├── Plan                       # 计划模型
├── SubTask                    # 子任务模型
├── PlanState                  # 计划状态
└── PlanStorage                # 计划存储抽象
    ├── InMemoryPlanStorage    # 内存存储
    └── JsonPlanStorage        # JSON文件存储

8. RAG系统(rag/

核心类:
├── Knowledge                  # 知识库接口
├── Document                   # 文档模型
├── RetrieveConfig             # 检索配置
├── KnowledgeRetrievalTools    # RAG工具
└── GenericRAGHook             # RAG Hook集成

9. Pipeline(pipeline/

核心类:
├── Pipeline                # Pipeline接口
├── SequentialPipeline         # 顺序执行
├── FanoutPipeline             # 并行执行
└── MsgHub                     # 消息中心(多Agent通信)

10. Session(session/

核心类:
├── Session                    # Session接口
├── InMemorySession            # 内存Session
├── JsonSession                # JSON文件Session
├── MysqlSession               # MySQL Session
└── RedisSession               # Redis Session

1.5 生产场景详解

1.5.1 场景:智能客服系统

需求

需求:为电商平台构建一个智能客服系统
├─ 功能1:自动回答常见问题(FAQ)
├─ 功能2:处理订单相关查询
├─ 功能3:处理投诉和退货
├─ 功能4:支持知识库检索(RAG)
├─ 功能5:关键问题升级到人工
└─ 约束:每小时处理 1000+ 消息,99.9%可用性

架构设计

graph TB
    User["用户消息"]
    User --> Agent["智能客服 Agent"]

    Agent --> Tools["工具箱"]
    Tools --> FAQ["FAQ工具"]
    Tools --> Order["订单查询工具"]
    Tools --> Return["退货处理工具"]
    Tools --> Escalate["人工升级工具"]

    Agent --> Memory["记忆系统"]
    Memory --> ShortMem["短期:当前对话"]
    Memory --> LongMem["长期:客户历史"]

    Agent --> RAG["RAG系统"]
    RAG --> KB["知识库检索"]

    Agent --> Monitor["监控和指标"]

    Output["最终回复"]
    Agent --> Output

完整代码实现

package com.example.ecommerce;

import io.agentscope.core.ReActAgent;
import io.agentscope.core.memory.InMemoryMemory;
import io.agentscope.core.memory.LongTermMemory;
import io.agentscope.core.memory.LongTermMemoryMode;
import io.agentscope.core.message.Msg;
import io.agentscope.core.model.DashScopeChatModel;
import io.agentscope.core.rag.Knowledge;
import io.agentscope.core.rag.RAGMode;
import io.agentscope.core.tool.Tool;
import io.agentscope.core.tool.ToolParam;
import io.agentscope.core.tool.Toolkit;

import ja va.util.Map;
import ja va.util.concurrent.ConcurrentHashMap;

public class SmartCustomerServiceExample {

    // 第1步:定义工具类
    public static class CustomerServiceTools {
        private Map faqDatabase = new ConcurrentHashMap<>();
        private Map orderDatabase = new ConcurrentHashMap<>();

        public CustomerServiceTools() {
            // 初始化FAQ数据库
            faqDatabase.put("shipping", "标准快递3-5天送达,加急1-2天。支持到付和预付。");
            faqDatabase.put("return", "收货后30天内无损产品可无条件退货。已使用产品需扣除使用费。");
            faqDatabase.put("warranty", "所有产品享受1年保修,覆盖生产缺陷但不包括人为损坏。");
        }

        @Tool(name = "search_faq", description = "Search FAQ database for common questions")
        public String searchFAQ(
                @ToolParam(name = "question", description = "Customer question or keyword") String question) {
            // 简单的关键词匹配(生产环境应使用向量搜索)
            for (Map.Entry entry : faqDatabase.entrySet()) {
                if (question.toLowerCase().contains(entry.getKey())) {
                    return String.format("FAQ: %s → %s", entry.getKey(), entry.getValue());
                }
            }
            return "No matching FAQ found for: " + question;
        }

        @Tool(name = "query_order", description = "Query order status and details")
        public String queryOrder(
                @ToolParam(name = "order_id", description = "Order ID to query") String orderId) {
            Order order = orderDatabase.get(orderId);
            if (order == null) {
                return String.format("Order not found: %s", orderId);
            }
            return String.format("Order %s: Status=%s, Total=¥%.2f, Items=%d, " +
                            "Created=%s, EstimatedDelivery=%s",
                    orderId, order.status, order.total, order.itemCount,
                    order.createdTime, order.estimatedDelivery);
        }

        @Tool(name = "process_return_request", description = "Initiate a return or refund process")
        public String processReturnRequest(
                @ToolParam(name = "order_id", description = "Order to return") String orderId,
                @ToolParam(name = "reason", description = "Reason for return") String reason,
                @ToolParam(name = "damage_percent", description = "Damage percentage 0-100, 0=unused, 100=unusable") int damagePercent) {

            if (damagePercent < 0 || damagePercent > 100) {
                return "Invalid damage_percent. Must be 0-100.";
            }

            Order order = orderDatabase.get(orderId);
            if (order == null) {
                return String.format("Order not found: %s", orderId);
            }

            // 计算退款金额
            double refundRate = 1.0 - (damagePercent / 100.0);
            double refundAmount = order.total * refundRate;

            // 更新订单状态
            order.status = "RETURN_PROCESSING";

            return String.format("Return request created: Order=%s, Reason=%s, " +
                            "RefundAmount=¥%.2f, RefundRate=%.0f%%, " +
                            "Status=RETURN_PROCESSING. Refund will be processed within 3-5 days.",
                    orderId, reason, refundAmount, refundRate * 100);
        }

        @Tool(name = "escalate_to_human", description = "Escalate issue to human agent")
        public String escalateToHuman(
                @Tool    
免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策