- 消息 — 智能体间通信与持久化的基本单元。每个
Msg代表一个完整的对话轮次,存储在上下文中并在智能体之间传递。 - 事件 — 前端交互与流式传输的基本单元。事件携带增量进度更新(文本 token、工具调用片段、权限请求等),驱动实时界面和人工介入工作流。
call 调用产生的事件序列最终汇聚成恰好一条 assistant Msg,这保证了完整的消息状态始终可以从事件流中还原。
消息
Msg(位于 io.agentscope.core.message)代表对话中的一个轮次——用户输入、智能体回复或系统指令,内容以有序的类型化块(ContentBlock)列表表示。
结构
Msg 类的核心字段(getter)如下:
内容块
消息内容由类型化的块组成,每种块代表一类独立信息。块类位于io.agentscope.core.message:
角色约束在构造时强制执行:
USER 消息只能包含 text/data/image/audio/video 块;SYSTEM 消息只能包含 TextBlock;ASSISTANT 消息可包含所有块类型。创建消息
按 role 固定的子类提供便捷构造(io.agentscope.core.message.UserMessage / AssistantMessage / SystemMessage / ToolResultMessage)。当 content 是普通字符串时,会自动包装为 TextBlock。
metadata、timestamp、usage、generateReason)时使用各子类的 builder():
访问内容
Msg 提供了一组辅助方法用于提取特定块类型:
事件
事件是消息的流式对应物。智能体执行过程中会持续产出一系列AgentEvent 对象(位于 io.agentscope.core.event),表示增量进度——文本 token 到达、工具调用逐步构建、结果流式返回。每个事件都是轻量且自包含的。
事件生命周期
每个事件都携带getReplyId(),将其关联到正在构建的消息。在一次回复中,getBlockId() 或 getToolCallId() 用作事件关联键,表示事件属于同一个内容块生命周期。事件遵循 start → delta → end 模式:
同一次回复中的所有事件共享相同的 replyId。在回复内部,用 blockId 关联文本/思考/数据块事件,用 toolCallId 关联工具调用和工具结果事件。blockId 是 replyId 作用域内的关联键,不要求是全局唯一的随机 ID;当某类内容块在一次回复中最多出现一个生命周期时,实现可以使用稳定的类型标识(如文本块的固定标识)作为 blockId。
事件类型
所有事件继承自AgentEvent(位于 io.agentscope.core.event),提供以下公共方法:
事件按类别分组如下。除特别说明外,每个事件还携带
getReplyId(),关联到正在构建的消息。
生命周期事件
生命周期事件
AgentStartEvent — 智能体开始新的回复。
AgentEndEvent — 智能体完成回复。
ExceedMaxItersEvent — 智能体达到最大推理-执行迭代次数。
RequestStopEvent — 中间件或工具发起的提前停止请求。
文本流式事件
文本流式事件
TextBlockStartEvent — 新的文本块开始。
TextBlockDeltaEvent — 增量文本内容到达。
TextBlockEndEvent — 文本块完成。
思考流式事件
思考流式事件
ThinkingBlockStartEvent / ThinkingBlockDeltaEvent / ThinkingBlockEndEvent —— 与文本流式事件结构对应,仅用于模型的思维链内容;
blockId 同样表示当前回复中的关联键。数据流式事件
数据流式事件
DataBlockStartEvent / DataBlockDeltaEvent / DataBlockEndEvent —— 与文本流式事件结构对应,承载图片 / 音频 / 视频等二进制数据:
DataBlockStartEvent:getMediaType()返回 MIME 类型(如"image/png")。DataBlockDeltaEvent:getData()返回增量 base64 编码数据。
工具调用流式事件
工具调用流式事件
ToolCallStartEvent — 智能体开始一次工具调用。
ToolCallDeltaEvent — 增量工具调用参数到达;
getDelta() 返回 JSON 参数片段。ToolCallEndEvent — 工具调用参数完成。工具结果流式事件
工具结果流式事件
ToolResultStartEvent — 工具开始执行(带
toolCallId、toolCallName)。ToolResultTextDeltaEvent — 工具的增量文本输出;getDelta() 返回文本片段。ToolResultDataDeltaEvent — 工具的二进制数据输出;与 DataBlockDeltaEvent 类似,包含 mediaType / data / url 字段。ToolResultEndEvent — 工具执行完成。模型调用事件
模型调用事件
ModelCallStartEvent — 模型 API 调用开始(带
modelName)。ModelCallEndEvent — 模型 API 调用完成(带 inputTokens / outputTokens)。人工介入事件
人工介入事件
RequireUserConfirmEvent — 智能体暂停等待用户确认。
RequireExternalExecutionEvent — 智能体暂停等待外部执行。
UserConfirmResultEvent — 用户提供确认结果。携带
List<ConfirmResult>。
replyId 与最初暂停智能体的 RequireUserConfirmEvent 相同。ExternalExecutionResultEvent — 后续
call() 恢复外部执行暂停时发出。
携带一个或多个 ToolResultBlock,且 replyId 与之前的 RequireExternalExecutionEvent 相同。AllToolsDeniedEvent — 用户通过 HITL 确认拒绝了最近一轮推理产出的全部工具调用。该事件通过
onActing middleware 链发出,middleware 可据此发出 RequestStopEvent 停止 agent。若无 middleware 处理,agent 默认继续下一轮推理(向后兼容)。子 Agent 事件
子 Agent 事件
SubagentExposedEvent — 通过
agent_spawn(expose_to_user=true) 生成的子 Agent 被暴露为用户可寻址的入口点。SSE / 流式消费端可据此在 UI 上渲染新的会话入口。从事件流重建消息
事件与消息并非相互独立,而是同一数据的两种视图。streamEvents 产出的事件流可以按 replyId / blockId / toolCallId 聚合还原成完整的 AssistantMessage。这保证了最终消息状态可以仅凭事件流完整还原。
可以参考 agentscope-core 中的 agent/StreamingHook.java 与 agentscope-examples/documentation/.../streaming/AgentEventStreamExample.java,它们演示了用 Reactor 算子按 block 分组并累积内容的标准做法。
示例:流式界面
构建流式界面的典型模式(Spring WebFlux SSE 形态可参考streaming/StreamingWebExample.java):
延伸阅读
智能体
智能体如何在 ReAct 循环中产出事件和消息
上下文
消息如何存储与持久化