ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AgentScope 学习系列 - 02:ReActAgent 配置、消息与事件

AgentScope 学习系列 - 02:ReActAgent 配置、消息与事件 1. 写在前面为了后续的学习我们先来看两个概念ReActAgent和HarnessAgent。Agent接口位于io.agentscope.core.agent.Agent默认实现是ReActAgent是 AgentScope 的核心抽象——一个推理-行动循环引擎将模型、工具、权限系统、人机交互、上下文管理、中间件、状态管理和事件系统整合到一个统一接口中。HarnessAgent是ReActAgent的一层薄包装把长期运行 agent 必备的工程能力打包进单一 builder工作区驱动的人格、长期记忆、子 agent 编排、沙箱隔离、技能装配、计划模式、Channel 路由。裸的ReActAgent只解决”一次请求 → 推理 → 工具 → 回复”。Harness 要回答的是另一组问题下一轮怎么接着上一轮、上下文如何保持有界、多用户如何隔离、危险操作如何先 review 再执行、可复用能力如何沉淀。有点类似于Deep Agents和LangChain的关系HarnessAgent是针对ReActAgent的进一步包装。整体的学习路线我们将快速的过一遍ReActAgent的知识点然后核心放到HarnessAgent。2. ReActAgent配置介绍上一篇搭建了一个简单的demo。那么这一篇我们一起看看ReActAgent具体有哪些参数和配置。参数说明参数类型默认值描述nameString必填智能体标识符用于消息和日志sysPromptString必填智能体的基础系统提示词modelModel必填用于推理的大语言模型继承自ChatModelBasetoolkitToolkitnew Toolkit()管理工具、MCP 客户端、技能和工具组middlewaresList? extends MiddlewareBaseList.of()应用于 agent / reasoning / acting / model call / system prompt 钩子stateStoreAgentStateStorenull不持久化配置后 agent 在每次call后自动加载/保存AgentState按该次调用RuntimeContext的(userId, sessionId)寻址defaultSessionIdStringagentname当某次调用的RuntimeContext没带sessionId时的兜底值permissionContextPermissionContextState默认DEFAULT模式工具执行的细粒度规则modelConfigModelConfig默认值模型重试次数和备用模型reactConfigReactConfig默认值最大迭代次数和拒绝处理方式maxItersint10ReAct 主循环最大迭代次数也可放在reactConfig中有一些基础的参数我们就不展开赘述了。这里先大体一览后面我们会逐渐介绍。本篇所有的代码下面会用到不再一一贴了packagecom.maple.agent.demo;importcom.maple.agent.MapleAgentApplication;importcom.maple.agent.config.OpenAiModelConfig;importio.agentscope.core.ReActAgent;importio.agentscope.core.event.*;importio.agentscope.core.message.*;importio.agentscope.extensions.model.openai.OpenAIChatModel;importorg.springframework.boot.SpringApplication;importorg.springframework.context.ConfigurableApplicationContext;publicclassReActAgent_02{publicstaticvoidmain(String[]args){// 为了方便提及代码不暴露隐私信息密钥放到application-pro.yml中ConfigurableApplicationContextctxSpringApplication.run(MapleAgentApplication.class,args);OpenAiModelConfigpropsctx.getBean(OpenAiModelConfig.class);OpenAIChatModelmodelOpenAIChatModel.builder().baseUrl(props.getBaseUrl()).apiKey(props.getApiKey()).modelName(props.getModelName()).stream(true).build();ReActAgentagentReActAgent.builder().name(笑小枫的学习助手).model(model).sysPrompt(你是笑小枫的学习助手可以帮助用户快速学习使用AgentScope开发智能体。).build();// call(agent);streamEvents(agent);}// 多模态消息直接返回结果privatestaticvoidcall(ReActAgentagent){UserMessageuserMessagenewUserMessage(user,TextBlock.builder().text(这张图片是什么).build(),DataBlock.builder().source(URLSource.builder().url(https://image.xiaoxiaofeng.site/blog/image/image-20260719154443011.png?xiaoxiaofeng).build()).build());Msgreplyagent.call(userMessage).block();System.out.println(reply.getTextContent());}// 流式返回结果privatestaticvoidstreamEvents(ReActAgentagent){agent.streamEvents(newUserMessage(user,帮我制定学习计划)).doOnNext(event-{if(eventinstanceofAgentStartEventstart){System.out.println([start replyIdstart.getReplyId()]);}elseif(eventinstanceofTextBlockDeltaEventdelta){System.out.print(delta.getDelta());}elseif(eventinstanceofAgentEndEventend){System.out.println(\n[完成]);}}).blockLast();}// 演示执行事件流式返回结果privatestaticvoidstreamEvents2(ReActAgentagent){StringBuilderaccumulatednewStringBuilder();agent.streamEvents(newUserMessage(user,你是谁)).doOnNext(event-{if(eventinstanceofAgentStartEventstart){System.out.println([start replyIdstart.getReplyId()]);}elseif(eventinstanceofThinkingBlockStartEventthinkingBlockStartEvent){System.out.println([思考开始 replyIdthinkingBlockStartEvent.getReplyId()]);}elseif(eventinstanceofThinkingBlockDeltaEventthinkingBlockDeltaEvent){System.out.println([思考内容 thinkingBlockDeltaEvent.getDelta()]);}elseif(eventinstanceofThinkingBlockEndEventthinkingBlockEndEvent){System.out.println([思考完成 replyIdthinkingBlockEndEvent.getReplyId()]);}elseif(eventinstanceofTextBlockDeltaEventdelta){accumulated.append(delta.getDelta());}elseif(eventinstanceofToolCallStartEventtc){System.out.println([tool] tc.getToolCallName());}elseif(eventinstanceofToolResultEndEventend){System.out.println([tool result stateend.getState()]);}elseif(eventinstanceofAgentEndEventend){System.out.println(\n[end] full text:\naccumulated);}}).blockLast();}}3. 消息类型Msg位于io.agentscope.core.message代表对话中的一个轮次——用户输入、智能体回复或系统指令内容以有序的类型化块ContentBlock列表表示。Msg类的核心字段getter如下方法类型说明getId()String唯一消息标识符getName()String发送方名称可空getRole()MsgRoleUSER/ASSISTANT/SYSTEM/TOOLgetContent()ListContentBlock有序内容块列表不可变getMetadata()MapString, Object任意键值元数据getTimestamp()String创建时间yyyy-MM-dd HH:mm:ss.SSSgetUsage()ChatUsageToken 用量仅 assistant 消息getGenerateReason()GenerateReason退出原因MODEL_STOP/TOOL_SUSPENDED/REASONING_STOP_REQUESTED/ACTING_STOP_REQUESTED/ALL_TOOLS_DENIED/INTERRUPTED/MAX_ITERATIONS通过断点图可以比较直观的看到上面的内容。内容块消息内容由类型化的块组成每种块代表一类独立信息。块类位于io.agentscope.core.message块类型说明允许出现在TextBlock纯文本内容USER、ASSISTANT、SYSTEMDataBlock二进制数据图片、音频、视频通过 base64 或 URL统一替代旧的 ImageBlock/AudioBlock/VideoBlockUSER、ASSISTANTThinkingBlock模型推理过程思维链ASSISTANTToolUseBlock工具调用包含id/name/input/stateToolCallStateASSISTANTToolResultBlock工具执行结果包含stateToolResultStateASSISTANTHintBlock以用户上下文形式注入循环的指令ASSISTANT我们用到的比较多的也就是前面两个看一下怎么使用privatestaticvoidcall(ReActAgentagent){UserMessageuserMessagenewUserMessage(user,TextBlock.builder().text(这张图片是什么).build(),DataBlock.builder().source(URLSource.builder().url(https://image.xiaoxiaofeng.site/blog/image/image-20260719154443011.png?xiaoxiaofeng).build()).build());Msgreplyagent.call(userMessage).block();System.out.println(reply.getTextContent());}返回的结果如下关于ThinkingBlock和Tool相关(后面讲到工具再说)的消息只有在streamEvents方式中能更好的体现。4. 输出方式我们上一篇演示的demo直接返回了结果如果我们想要打字机的那种展示怎么做呢这里我们详细的讲一讲callcall在内部消费所有事件当智能体完成或因外部交互暂停时返回最终Msg。streamEvents构建流式输出。streamEvents逐一产出AgentEvent对象让你实时将文本输出、工具调用进度和生命周期事件流式传输给用户。5. 执行事件在上面我们看到了各种执行过程中的事件事件是消息的流式对应物。每种类型的事件都遵循start → delta → end模式。其中delta可能产生多次属于增量内容片段。关于事件的执行顺序和生命周期这里就不展开了可以前往AgentScope官网查看。https://java.agentscope.io/v2/zh/docs/building-blocks/message-and-event6. 本章小结本篇围绕ReActAgent展开主要讲了三件事1. 概念区分ReActAgent是 AgentScope 的核心抽象负责“一次请求 → 推理 → 工具 → 回复”的循环HarnessAgent是它的薄包装额外打包了工作区、长期记忆、子 agent、沙箱等工程能力。2. 消息体系Msg代表对话中的一个轮次由有序的ContentBlock组成。常用的有TextBlock文本和DataBlock图片/音频/视频等多模态数据此外还有ThinkingBlock思维链、ToolUseBlock/ToolResultBlock工具调用与结果、HintBlock注入指令。3. 输出方式和执行事件call会内部消费所有事件等智能体完成或暂停后返回最终Msg适合一次性拿结果streamEvents则逐一产出AgentEvent遵循start → delta → end模式适合打字机式的实时展示。本篇就到这里了下一篇会深入介绍下ReActAgent的Middleware的扩展能力。本系列源码https://gitee.com/hack-feng/maple-agent-demo
返回列表