文章目录
- [1. 概述](#1. 概述)
- [2. Msg ------ 消息主体](#2. Msg —— 消息主体)
- [3. MsgRole ------ 消息角色](#3. MsgRole —— 消息角色)
- [4. ContentBlock](#4. ContentBlock)
-
- [4.1 TextBlock ------ 纯文本](#4.1 TextBlock —— 纯文本)
- [4.2 ImageBlock ------ 图片](#4.2 ImageBlock —— 图片)
- [4.3 DataBlock ------ 文件/数据](#4.3 DataBlock —— 文件/数据)
- [4.4 ImageBlock / DataBlock 的 Source](#4.4 ImageBlock / DataBlock 的 Source)
- [4.5 ThinkingBlock ------ 模型思考](#4.5 ThinkingBlock —— 模型思考)
- [4.6 ToolUseBlock ------ 工具调用请求](#4.6 ToolUseBlock —— 工具调用请求)
- [4.7 ToolResultBlock ------ 工具调用结果](#4.7 ToolResultBlock —— 工具调用结果)
- [5. GenerateReason ------ 生成原因](#5. GenerateReason —— 生成原因)
- [6. 快捷消息工厂](#6. 快捷消息工厂)
- [7. 常用模式](#7. 常用模式)
-
- [7.1 纯文本对话](#7.1 纯文本对话)
- [7.2 多模态消息](#7.2 多模态消息)
- [7.3 带文件的请求](#7.3 带文件的请求)
- [7.4 解析工具调用](#7.4 解析工具调用)
- [7.5 构造工具结果](#7.5 构造工具结果)
1. 概述
io.agentscope.core.message 是 AgentScope 的消息系统 ,定义了 Agent 通信的全部数据结构。
核心设计:
Msg:消息主体,由role+List<ContentBlock>组成,是可持久化的最小对话单元ContentBlock:消息内容的原子片段------文本、图片、文件、音频、视频、工具调用、工具结果等,统一继承自ContentBlock- 强校验 :构造期按
role校验ContentBlock类型,非法组合直接报错
消息结构:
Msg
│
├── role: MsgRole (USER / ASSISTANT / SYSTEM / TOOL)
├── content: List<ContentBlock>
│ ├── TextBlock ← 纯文本
│ ├── ImageBlock ← 图片(base64 / URL)
│ ├── DataBlock ← 文件/数据(base64 / URL)
│ ├── AudioBlock ← 音频
│ ├── VideoBlock ← 视频
│ ├── ThinkingBlock ← 模型思考过程
│ ├── HintBlock ← 给用户的提示
│ ├── ToolUseBlock ← 工具调用请求
│ └── ToolResultBlock ← 工具调用结果
├── metadata: Map<String, Object>
├── usage: ChatUsage ← Token 用量
└── timestamp: String
2. Msg ------ 消息主体
java
Msg msg = Msg.builder()
.role(MsgRole.USER)
.content(List.of(
TextBlock.builder().text("你好").build(),
ImageBlock.builder()
.source(URLSource.of("https://example.com/photo.jpg"))
.build()
))
.metadata(Map.of("request_id", "req-001"))
.build();
// 便捷工厂
Msg userMsg = Msg.builder()
.content(TextBlock.builder().text("hello").build())
.build(); // role 默认 USER
| 方法 | 说明 |
|---|---|
builder() |
默认 role=USER |
builderForRole(MsgRole) |
指定 role |
getId() |
自动生成的唯一 ID |
getRole() |
USER / ASSISTANT / SYSTEM / TOOL |
getContent() |
List<ContentBlock> |
getTextContent() |
提取纯文本(拼接所有 TextBlock) |
getContentBlocks(Class<T>) |
按类型过滤 content |
hasContentBlocks(Class<T>) |
检查是否有某类型 block |
getUsage() |
ChatUsage(input/output tokens) |
getGenerateReason() |
为何生成此消息(MODEL_STOP / TOOL_CALLS / ...) |
getMetadata() |
元数据 map |
withContent(List) |
返回新 Msg,替换 content |
3. MsgRole ------ 消息角色
java
public enum MsgRole {
USER, // 用户消息
ASSISTANT, // 模型回复
SYSTEM, // 系统提示
TOOL // 工具结果
}
校验规则(构造期强制执行):
| Role | 允许的 ContentBlock |
|---|---|
USER |
TextBlock, ImageBlock, DataBlock, AudioBlock, VideoBlock |
ASSISTANT |
TextBlock, ThinkingBlock, ToolUseBlock |
SYSTEM |
TextBlock |
TOOL |
ToolResultBlock, TextBlock, DataBlock |
4. ContentBlock
块类型完整对照表:
| 块名称 | 功能说明 | 允许归属消息角色 |
|---|---|---|
| TextBlock | 承载纯文本字符串内容,通用文字载体 | USER、ASSISTANT、SYSTEM |
| DataBlock | 统一二进制多媒体数据块,支持base64编码字符串/远程URL两种资源格式;完全替代旧版ImageBlock、AudioBlock、VideoBlock | USER、ASSISTANT |
| ImageBlock(旧兼容) | 仅图片资源,历史兼容保留,新业务禁止新增使用 | USER |
| AudioBlock(旧兼容) | 仅音频资源,历史兼容保留,新业务禁止新增使用 | USER |
| VideoBlock(旧兼容) | 仅视频资源,历史兼容保留,新业务禁止新增使用 | USER |
| ThinkingBlock | 大模型内部推理、思维链、中间思考过程文本,仅助手侧输出 | ASSISTANT |
| ToolUseBlock | 工具调用指令块,内置字段:调用id、工具名称、入参、调用状态枚举ToolCallState |
ASSISTANT |
| ToolResultBlock | 工具执行返回结果块,内置执行状态枚举ToolResultState |
ASSISTANT |
| HintBlock | 循环会话中注入的上下文约束指令,依附助手消息透传上下文规则 | ASSISTANT |
4.1 TextBlock ------ 纯文本
java
TextBlock block = TextBlock.builder()
.text("你好,世界!")
.build();
block.getText(); // "你好,世界!"
最常用的 block,所有 role 都支持。
4.2 ImageBlock ------ 图片
java
// URL 图片
ImageBlock img1 = ImageBlock.builder()
.source(URLSource.of("https://example.com/photo.jpg"))
.minPixels(256).maxPixels(4096)
.build();
// Base64 图片
ImageBlock img2 = ImageBlock.builder()
.source(Base64Source.of("iVBORw0KGgo...", "image/png"))
.build();
4.3 DataBlock ------ 文件/数据
java
// URL 文件
DataBlock file1 = DataBlock.builder()
.source(URLSource.of("https://example.com/doc.pdf"))
.name("doc.pdf")
.build();
// Base64 文件
DataBlock file2 = DataBlock.builder()
.source(Base64Source.of("UEsDBBQAAAAI...", "application/pdf"))
.name("report.pdf")
.build();
4.4 ImageBlock / DataBlock 的 Source
java
// 两种数据源
public class Source { }
// URL 方式:引用外部资源
URLSource url = URLSource.of("https://example.com/file.pdf");
// Base64 方式:内嵌数据(mediaType 如 "image/png", "application/pdf")
Base64Source b64 = Base64Source.of("base64-string", "image/png");
4.5 ThinkingBlock ------ 模型思考
java
// 读取模型的思考过程(仅 ASSISTANT role)
msg.getContentBlocks(ThinkingBlock.class)
.forEach(think -> System.out.println(think.getText()));
4.6 ToolUseBlock ------ 工具调用请求
java
ToolUseBlock toolCall = ToolUseBlock.builder()
.id("call_001")
.name("get_weather")
.input(Map.of("city", "Beijing"))
.build();
toolCall.getId(); // "call_001"
toolCall.getName(); // "get_weather"
toolCall.getInput(); // {city: "Beijing"}
toolCall.getState(); // PENDING / IN_PROGRESS / COMPLETED / ERROR / SUSPENDED
ToolCallState 枚举:
| 状态 | 说明 |
|---|---|
PENDING |
等待执行 |
IN_PROGRESS |
执行中 |
COMPLETED |
已完成 |
ERROR |
执行出错 |
SUSPENDED |
被挂起(等待外部执行) |
4.7 ToolResultBlock ------ 工具调用结果
java
// 文本结果
ToolResultBlock result = ToolResultBlock.text("城市: Beijing, 温度: 22°C");
// 错误结果
ToolResultBlock error = ToolResultBlock.error("API 超时");
// 挂起结果
ToolResultBlock suspended = ToolResultBlock.suspended(toolUseBlock);
// 结构化结果
ToolResultBlock structured = ToolResultBlock.of(
List.of(TextBlock.builder().text("结果1").build(),
DataBlock.builder().source(URLSource.of("...")).build()));
// Builder
ToolResultBlock result = ToolResultBlock.builder()
.id("call_001").name("get_weather")
.output(List.of(TextBlock.builder().text("22°C, 晴").build()))
.metadata(Map.of("latency_ms", 350))
.build();
ToolResultState :PENDING / IN_PROGRESS / COMPLETED / ERROR / SUSPENDED
5. GenerateReason ------ 生成原因
标记 Msg 是在什么情况下产生的:
| 枚举值 | 说明 |
|---|---|
MODEL_STOP |
模型自然结束 |
TOOL_CALLS |
模型发出了工具调用 |
STRUCTURED_OUTPUT |
结构化输出工具 |
TOOL_SUSPENDED |
工具被挂起 |
REASONING_STOP_REQUESTED |
推理阶段收到停止请求 |
ACTING_STOP_REQUESTED |
工具调用阶段收到停止请求 |
PERMISSION_ASKING |
权限询问 |
MIDDLEWARE_STOP_REQUESTED |
Middleware 请求停止 |
INTERRUPTED |
用户中断 |
MAX_ITERATIONS |
达到最大迭代数 |
java
// 检查 Agent 为何结束
GenerateReason reason = msg.getGenerateReason();
if (reason == GenerateReason.MAX_ITERATIONS) {
System.out.println("Agent 达到最大推理轮次");
}
6. 快捷消息工厂
AgentScope 提供了 4 种快捷工厂方法:
java
// 用户消息
Msg userMsg = UserMessage.builder()
.content(TextBlock.builder().text("你好").build())
.build();
// 等价于 Msg.builder().role(USER).content(...).build()
// 系统消息
Msg sysMsg = SystemMessage.builder()
.content(TextBlock.builder().text("你是助手").build())
.build();
// 助手消息
Msg asstMsg = AssistantMessage.builder()
.content(TextBlock.builder().text("你好!").build())
.build();
// 工具结果消息
Msg toolMsg = ToolResultMessage.builder()
.content(ToolResultBlock.text("22°C"))
.build();
7. 常用模式
7.1 纯文本对话
java
Msg msg = Msg.builder()
.content(List.of(TextBlock.builder().text("今天天气如何?").build()))
.build();
7.2 多模态消息
java
Msg msg = Msg.builder()
.content(List.of(
TextBlock.builder().text("分析这张图片").build(),
ImageBlock.builder()
.source(URLSource.of("https://example.com/chart.png"))
.build()
))
.build();
7.3 带文件的请求
java
Msg msg = Msg.builder()
.content(List.of(
TextBlock.builder().text("总结这个 PDF 的内容").build(),
DataBlock.builder()
.source(Base64Source.of(base64Pdf, "application/pdf"))
.name("report.pdf")
.build()
))
.build();
7.4 解析工具调用
java
Msg reply = agent.call(List.of(userMsg)).block();
// 检查是否有工具调用
if (reply.hasContentBlocks(ToolUseBlock.class)) {
for (ToolUseBlock tool : reply.getContentBlocks(ToolUseBlock.class)) {
System.out.printf("工具: %s, 参数: %s%n", tool.getName(), tool.getInput());
}
}
7.5 构造工具结果
java
// 从 Assistant 消息中提取工具调用,构建 ToolResultBlock
ToolUseBlock toolCall = reply.getFirstContentBlock(ToolUseBlock.class);
ToolResultBlock result = ToolResultBlock.builder()
.id(toolCall.getId())
.name(toolCall.getName())
.output(List.of(TextBlock.builder().text("执行结果...").build()))
.build();
Msg toolMsg = Msg.builder()
.role(MsgRole.TOOL)
.content(List.of(result))
.build();