news 2026/8/13 11:37:38

AgentScope 2.0:4. Message Event —— 消息模型与事件流深度解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AgentScope 2.0:4. Message Event —— 消息模型与事件流深度解析

目录:
1. 面向生产环境的智能体工程平台
2. 快速上手 从零构建生产级智能体
3. Agent —— 智能体的核心抽象与工程化实践
4. Message & Event —— 消息模型与事件流深度解
5. Middleware —— 无侵入式智能体扩展机制深度解析
6. Model —— 统一模型接入层与容错机制深度解析
7. Permission System —— 权限控制系统深度解析
8. Tool —— 工具系统架构与生产级实践深度解析
9. Context —— 运行时上下文与状态管理深度解析

一、引言:为什么消息与事件是智能体框架的"神经系统"

在 AgentScope Java 2.0 的构建块体系中,Message(消息)Event(事件)共同构成了智能体的"神经系统":

  • Message是智能体之间、智能体与模型之间传递信息的静态载体——它定义了"说什么"
  • Event是推理-行动循环中每一步的动态信号——它定义了"正在发生什么"

消息与事件模块,打造可观测、可交互的执行流。

本文深入解析这两大核心抽象的设计哲学、类型体系与工程实践。

二、消息模型(Message):统一 ContentBlock 架构

2.1 设计哲学

AgentScope 2.0 对消息层进行了彻底重构,核心设计原则:

原则说明
统一抽象文本、图片、音频、视频、工具调用、工具结果统一收敛到 ContentBlock
强类型校验使用 Java 17 sealed class + record,构造期按 role 校验,非法组合直接报错
可持久化Msg 是可序列化的最小对话单元,直接写入 AgentState
多模态原生不是"附加"多模态,而是从类型系统层面原生支持

2.2 Msg 消息结构

Msg ├── role: MsgRole (USER / ASSISTANT / SYSTEM / TOOL) ├── content: List<ContentBlock> ├── generateReason: GenerateReason (可选) └── name: String (可选,用于多 Agent 场景标识)

核心定义:
Msg 是消息主体,由 role + List 组成,是可持久化的最小对话单元。

// 源码位置: io.agentscope.core.message.MsgpublicfinalclassMsg{privatefinalMsgRolerole;privatefinalList<ContentBlock>content;privatefinalGenerateReasongenerateReason;privatefinalStringname;// ...}

2.3 MsgRole —— 消息角色

角色说明允许的 ContentBlock
USER用户输入TextBlock, ImageBlock, DataBlock
ASSISTANT模型输出TextBlock, ThinkingBlock, ToolUseBlock
SYSTEM系统指令TextBlock
TOOL工具返回ToolResultBlock

强校验机制:构造期按 role 校验 ContentBlock 类型,非法组合在构造时即抛出异常,而非运行时才暴露。这是 2.0 相比 1.x 的重大改进——将错误前移到编译/构造阶段。

2.4 ContentBlock 类型体系

ContentBlock 是消息内容的原子片段,采用 sealed class 设计,确保类型安全与穷举性:

publicsealedinterfaceContentBlockpermitsTextBlock,ImageBlock,DataBlock,ThinkingBlock,ToolUseBlock,ToolResultBlock{}
2.4.1 TextBlock —— 纯文本
recordTextBlock(Stringtext)implementsContentBlock{}

最基础的内容类型,承载对话文本。

2.4.2 ImageBlock —— 图片
recordImageBlock(Sourcesource,StringmediaType)implementsContentBlock{}

支持多模态图片输入,Source 定义数据来源(Base64 / URL / 文件路径)。

2.4.3 DataBlock —— 文件/数据
recordDataBlock(Sourcesource,StringfileName,StringmediaType)implementsContentBlock{}

承载文件、音频、视频等二进制数据。

2.4.4 Source —— 数据源抽象

ImageBlock 和 DataBlock 共享 Source 抽象:

Source 类型说明
Base64Source内联 Base64 编码
URLSource远程 URL 引用
FileSource本地文件路径
2.4.5 ThinkingBlock —— 模型思考
recordThinkingBlock(Stringthinking)implementsContentBlock{}

承载模型的推理过程(Chain-of-Thought),仅在 ASSISTANT 角色消息中出现。这一设计使得"思考过程"成为一等公民,可被中间件拦截、记录或展示。

2.4.6 ToolUseBlock —— 工具调用请求
recordToolUseBlock(Stringid,// 调用唯一标识Stringname,// 工具名称Map<String,Object>input// 调用参数)implementsContentBlock{}

出现在 ASSISTANT 角色消息中,表示模型决定调用某个工具。

2.4.7 ToolResultBlock —— 工具调用结果
recordToolResultBlock(StringtoolUseId,// 对应的 ToolUseBlock idStringcontent,// 执行结果booleanisError// 是否执行出错)implementsContentBlock{}

出现在 TOOL 角色消息中,表示工具执行完毕后的返回。

2.5 ContentBlock 类型全景图

ContentBlock (sealed interface) ├── TextBlock ← 纯文本(USER/ASSISTANT/SYSTEM) ├── ImageBlock ← 图片(USER) ├── DataBlock ← 文件/音频/视频(USER) ├── ThinkingBlock ← 模型思考过程(ASSISTANT) ├── ToolUseBlock ← 工具调用请求(ASSISTANT) └── ToolResultBlock ← 工具执行结果(TOOL)

2.6 GenerateReason —— 生成原因

标识本轮 Assistant 消息的终止原因:

枚举值说明
END_TURN模型自然结束回复
TOOL_USE模型请求调用工具(循环继续)
MAX_ITERATIONS达到最大迭代次数,强制终止

这一设计让上层逻辑可以精确判断"为什么停止了",而非猜测。

2.7 快捷消息工厂

框架提供静态工厂方法简化消息创建:

// 用户消息MsguserMsg=newUserMessage("帮我查一下北京天气");// 系统消息MsgsysMsg=newSystemMessage("你是一个天气助手");// 带图片的多模态消息MsgmultiModal=Msg.builder().role(MsgRole.USER).content(TextBlock.of("这张图里有什么?")).content(ImageBlock.of(Source.base64(imageBytes),"image/png")).build();

2.8 常用模式

模式一:提取纯文本
Stringtext=msg.getTextContent();// 拼接所有 TextBlock
模式二:读取结构化输出
WeatherResultresult=msg.getStructuredData(WeatherResult.class);
模式三:消息在 ReAct 循环中的传递
UserMessage → [推理] → AssistantMessage(ToolUseBlock) → [工具执行] → ToolMessage(ToolResultBlock) → [推理] → AssistantMessage(TextBlock, GenerateReason.END_TURN)

三、事件系统(Event):可观测的执行流

3.1 设计理念

每一步——模型调用、文本增量、工具执行、工具结果——都以类型化事件流出。订阅一次,前端 UI 实时跟上。

AgentScope 2.0 的事件系统提供约 35 个事件类,覆盖智能体执行的完整生命周期。事件通过 streamEvents() 以 Flux 形式流出,天然适配响应式编程与 SSE(Server-Sent Events)。

3.2 AgentEvent 基类

每个事件都继承自 AgentEvent,提供统一的元数据:

publicabstractclassAgentEvent{publicStringgetId();// 唯一事件标识符publicStringgetCreatedAt();// ISO 8601 时间戳publicAgentEventTypegetType();// 事件类型枚举publicStringgetSource();// 来源路径}

source 字段的精妙设计:

  • 顶层 Agent:source = null
  • 子 Agent:source = “main/sub-agent-1”(斜杠分隔路径)

这使得在多层嵌套的子 Agent 架构中,每个事件都能精确追溯到产生它的 Agent 层级。

3.3 事件生命周期:标准三段式模式

AgentScope 2.0 的事件遵循标准三段式(Start → Delta → End):

┌─────────────────────────────────────────────────────┐ │ XxxStartEvent → 标记某个阶段开始 │ │ XxxDeltaEvent → 流式增量数据(可多次触发) │ │ XxxEndEvent → 标记某个阶段结束 │ └─────────────────────────────────────────────────────┘

这种设计使得:

  • 前端渲染可以精确知道何时开始显示、何时追加内容、何时关闭
  • 性能监控可以精确计算每个阶段的耗时
  • 异常处理可以精确定位中断点

3.4 事件分类详解

3.4.1 智能体调用事件
事件说明
AgentStartEventAgent 开始处理请求
AgentEndEventAgent 完成本轮回复
3.4.2 模型调用事件
事件说明
ModelCallStartEvent开始调用 LLM
ModelCallEndEventLLM 返回完成
3.4.3 文本块事件
事件说明
TextBlockStartEvent文本生成开始
TextBlockDeltaEvent文本增量(流式输出核心)
TextBlockEndEvent文本生成结束
3.4.4 思考块事件
事件说明
ThinkingBlockStartEvent模型开始思考
ThinkingBlockDeltaEvent思考内容增量
ThinkingBlockEndEvent思考结束
3.4.5 数据块事件
事件说明
DataBlockStartEvent数据块开始
DataBlockDeltaEvent数据增量
DataBlockEndEvent数据块结束
3.4.6 工具调用事件
事件说明
ToolCallStartEvent工具调用开始(含工具名、参数)
ToolCallEndEvent工具调用完成
3.4.7 工具结果事件
事件说明
ToolResultEvent工具执行结果返回
3.4.8 异常与中断事件
事件说明
ErrorEvent执行异常
InterruptEvent执行被中断
3.4.9 HITL(Human-in-the-Loop)事件
事件说明
PermissionRequestEvent请求人工审批
PermissionResponseEvent人工审批结果
3.4.10 子 Agent 事件
事件说明
SubAgentStartEvent子 Agent 启动
SubAgentEndEvent子 Agent 完成

3.5 事件类型枚举(AgentEventType)

所有事件类型通过 AgentEventType 枚举统一管理,便于 switch 分发:

publicenumAgentEventType{AGENT_START,AGENT_END,MODEL_CALL_START,MODEL_CALL_END,TEXT_BLOCK_START,TEXT_BLOCK_DELTA,TEXT_BLOCK_END,THINKING_BLOCK_START,THINKING_BLOCK_DELTA,THINKING_BLOCK_END,DATA_BLOCK_START,DATA_BLOCK_DELTA,DATA_BLOCK_END,TOOL_CALL_START,TOOL_CALL_END,TOOL_RESULT,ERROR,INTERRUPT,PERMISSION_REQUEST,PERMISSION_RESPONSE,SUB_AGENT_START,SUB_AGENT_END,// ... 更多类型}

3.6 执行流程中的事件序列

一次典型的 ReAct 循环产生的事件序列:

AgentStartEvent ├── ModelCallStartEvent │ ├── ThinkingBlockStartEvent │ ├── ThinkingBlockDeltaEvent × N │ ├── ThinkingBlockEndEvent │ ├── TextBlockStartEvent │ ├── TextBlockDeltaEvent × N │ ├── TextBlockEndEvent │ └── ToolCallStartEvent (模型决定调用工具) ├── ModelCallEndEvent ├── ToolCallStartEvent (工具实际执行) ├── ToolResultEvent ├── ModelCallStartEvent (第二轮推理) │ ├── TextBlockStartEvent │ ├── TextBlockDeltaEvent × N │ └── TextBlockEndEvent ├── ModelCallEndEvent └── AgentEndEvent

3.7 从事件流重建消息

事件流不仅是"观察窗口",还可以反向重建完整的 Msg:

TextBlockDelta × N → 拼接 → TextBlock ToolCallStart + ToolResult → ToolUseBlock + ToolResultBlock 这使得即使只订阅了事件流,也能完整还原对话历史。 ## 四、事件订阅与流式输出实战 ### 4.1 基础订阅 ```java agent.streamEvents(new UserMessage("介绍 AgentScope 2.0")) .doOnNext(event -> { switch (event.getType()) { case TEXT_BLOCK_DELTA -> System.out.print(((TextBlockDeltaEvent) event).getDelta()); case TOOL_CALL_START -> System.out.println("\n🔧 调用工具: " + ((ToolCallStartEvent) event).getToolCallName()); case THINKING_BLOCK_DELTA -> System.out.print("💭 " + ((ThinkingBlockDeltaEvent) event).getDelta()); case AGENT_END -> System.out.println("\n✅ 回复完成"); } }) .blockLast();

4.2 Spring WebFlux SSE 端点

@GetMapping(value="/chat/stream",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<ServerSentEvent<String>>streamChat(@RequestParamStringmessage,@RequestParamStringsessionId,@RequestParamStringuserId){RuntimeContextctx=RuntimeContext.builder().sessionId(sessionId).userId(userId).build();returnagent.streamEvents(newUserMessage(message),ctx).filter(e->e.getType()==AgentEventType.TEXT_BLOCK_DELTA).map(e->ServerSentEvent.<String>builder().data(((TextBlockDeltaEvent)e).getDelta()).build());}

4.3 多 Agent 事件追踪

agent.streamEvents(newUserMessage("帮我完成数据分析")).doOnNext(event->{Stringsource=event.getSource();if(source!=null){// 来自子 Agent 的事件System.out.println("["+source+"] "+event.getType());}else{// 来自主 Agent 的事件System.out.println("[main] "+event.getType());}}).blockLast();

五、消息与事件的协作关系

5.1 静态 vs 动态

维度Message (Msg)Event (AgentEvent)
本质静态数据载体动态执行信号
生命周期持久化存储瞬时流过
用途上下文传递、状态恢复实时渲染、监控、干预
粒度完整消息增量片段
产生时机推理完成后推理过程中

5.2 转换关系

事件流(实时) 消息(持久化) ───────────── ───────────── TextBlockDelta × N ──聚合──→ Msg(ASSISTANT, [TextBlock]) ToolCallStart ──记录──→ Msg(ASSISTANT, [ToolUseBlock]) ToolResult ──记录──→ Msg(TOOL, [ToolResultBlock])

5.3 事件驱动的消息更新

在 2.0 架构中,消息的构建是事件驱动的:

// 内部实现逻辑(简化)MsgBuilderbuilder=Msg.builder().role(MsgRole.ASSISTANT);eventStream.subscribe(event->{if(eventinstanceofTextBlockEndEvente){builder.content(newTextBlock(e.getFullText()));}if(eventinstanceofToolCallStartEvente){builder.content(newToolUseBlock(e.getId(),e.getName(),e.getInput()));}});// 流结束后 → 完整 Msg 写入 AgentState

六、与 1.x 的对比:消息模型演进

维度1.x2.0
消息类型多种 Msg 子类(TextMsg, ImageMsg…)统一 Msg + ContentBlock
类型安全运行时检查 构造期sealed class 强校验
多模态附加支持原生一等公民
工具调用特殊字段ToolUseBlock / ToolResultBlock
思考过程无独立表示ThinkingBlock 独立承载
事件系统Hook 回调(扁平)35+ 类型化事件(结构化)
流式输出有限支持完整三段式事件流
子 Agent 追踪source 路径精确标识

七、工程化最佳实践

7.1 事件日志与审计

agent.streamEvents(userMsg,ctx).doOnNext(event->{auditLog.record(AuditEntry.builder().eventId(event.getId()).timestamp(event.getCreatedAt()).type(event.getType()).source(event.getSource()).userId(ctx.getUserId()).sessionId(ctx.getSessionId()).build());}).subscribe();

7.2 Token 消耗监控

.doOnNext(event->{if(eventinstanceofModelCallEndEvente){metrics.recordTokenUsage(e.getModelName(),e.getPromptTokens(),e.getCompletionTokens());}})

7.3 异常告警

.doOnNext(event->{if(eventinstanceofErrorEvente){alertService.fire(Alert.builder().level(AlertLevel.CRITICAL).message("Agent 执行异常: "+e.getErrorMessage()).source(event.getSource()).build());}})

7.4 HITL 审批流集成

.doOnNext(event->{if(eventinstanceofPermissionRequestEvente){// 推送到审批系统approvalService.submit(ApprovalRequest.builder().toolName(e.getToolName()).parameters(e.getParameters()).agentSource(event.getSource()).build());}})

八、设计哲学总结

AgentScope Java 2.0 的消息与事件系统体现了三个核心设计原则:

8.1 类型即文档

使用 sealed class + record,让编译器成为第一道防线。开发者无需查阅文档即可通过 IDE 自动补全了解所有可能的 ContentBlock 和 Event 类型。

8.2 事件即接口

事件流是框架与外部世界的唯一实时接口。无论是 Web 前端、TUI 终端、监控系统还是审批流程,都通过同一套事件流接入。

8.3 消息即状态

Msg 不只是"传话",它是 AgentState 的持久化单元。会话恢复、上下文压缩、记忆提炼,全部基于 Msg 进行操作。

九、结语

AgentScope Java 2.0 的消息与事件系统,用类型安全解决了"消息混乱"问题,用结构化事件解决了"执行黑箱"问题,用三段式模式解决了"流式渲染"问题。
对于 Java 开发者而言,这套设计完美契合了 JVM 生态的强类型传统:

  • sealed class 保证穷举性
  • record 保证不可变性
  • Flux 保证响应式
  • 构造期校验保证 fail-fast

消息定义了智能体"说什么",事件定义了智能体"怎么做"。两者合一,构成了一个可观测、可干预、可信赖的智能体执行流。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/13 11:35:58

深度解析:建设银行网站是什么以及它如何重塑现代金融服务体验

在这个数字化浪潮席卷全球、智能手机几乎成为人体“外置器官”的时代,我们对待银行业务的态度也发生了翻天覆地的变化。如果你问我,在2024年的今天,去银行网点排队办理业务是不是傻?我会笑着回答,这得看你办理的是什么业务。如果是存取一两百块钱零钱,那确实,为了这几十…

作者头像 李华
网站建设 2026/8/13 11:35:15

用Python代码打造父亲节专属礼物:从动态爱心到交互游戏的创意实现

1. 当代码成为情感的表达媒介父亲节快到了&#xff0c;朋友圈里又开始刷屏各种祝福和礼物。作为一个程序员&#xff0c;我总觉得那些千篇一律的贺卡和“爸爸辛苦了”的文案&#xff0c;有点不够味儿。我们这行&#xff0c;最擅长的不就是用逻辑和符号构建世界吗&#xff1f;那为…

作者头像 李华
网站建设 2026/8/13 11:33:37

实测Ollama本地部署LLM:从环境配置到客户端接入完整指南

在实际项目中&#xff0c;将大型语言模型&#xff08;LLM&#xff09;集成到本地开发环境或企业内部工具链中&#xff0c;正成为一个高频需求。无论是为了数据安全、降低API调用成本&#xff0c;还是为了获得更快的响应速度和定制化能力&#xff0c;本地部署模型都提供了核心解…

作者头像 李华
网站建设 2026/8/13 11:31:24

快慢指针算法:高效检测回文链表的原理与实践

1. 回文链表检测与快慢指针原理剖析链表结构在算法面试中出现的频率堪比数组&#xff0c;而回文链表检测更是高频中的高频。不同于数组可以通过下标随机访问&#xff0c;链表只能顺序遍历的特性让这个问题变得有趣起来。我曾在某大厂终面时被要求在白板上15分钟内完成这个问题的…

作者头像 李华