AgentScope-Tool参数传递所有方式
·
🔄 AgentScope 参数传递的所有方式
详细列举父 Agent 向子 Agent 传递参数的所有可用方式
📋 参数传递方式完整列表
方式 1:textContent(消息正文)✅
用途:传递对话内容,AI 会读取和处理
示例:
Msg msg = Msg.builder()
.textContent("用户想查询订单ORDER-001的状态") // ← 方式1:文本内容
.build();
特点:
- ✅ AI 会读取这个内容
- ✅ 用于传递对话上下文
- ⚠️ 不适合传递结构化参数
方式 2:metadata(元数据)✅ 推荐
用途:传递结构化业务参数,AI 不读取,程序提取
示例:
Msg msg = Msg.builder()
.textContent("用户想查询订单")
.metadata(Map.of( // ← 方式2:元数据
"userId", 12345L,
"orderId", "ORDER-001",
"priority", "HIGH"
))
.build();
特点:
- ✅ 结构化数据,易于提取
- ✅ AI 不会读取,不干扰对话
- ✅ 支持任意键值对
- ✅ 最常用、最推荐的方式
子 Agent 提取:
String userId = msg.getMetadata().get("userId").toString();
String orderId = msg.getMetadata().get("orderId").toString();
方式 3:role(角色)⚠️
用途:指定消息角色,影响 AI 的理解
示例:
Msg msg = Msg.builder()
.textContent("用户想查询订单")
.role("user") // ← 方式3:角色
.build();
可选值:
"user"- 用户消息"assistant"- AI 助手消息"system"- 系统消息
特点:
- ⚠️ 主要用于控制对话上下文
- ⚠️ 不用于传递业务参数
- ⚠️ 通常由框架自动设置
方式 4:name(消息名称)⚠️
用途:标识消息来源或发送者
示例:
Msg msg = Msg.builder()
.textContent("用户想查询订单")
.name("supervisor_agent") // ← 方式4:名称
.build();
特点:
- ⚠️ 用于标识消息来源
- ⚠️ 不常用于参数传递
- ⚠️ 主要用于多 Agent 场景的追踪
方式 5:通过 AgentRequestOptions ✅
用途:传递请求级别的控制参数
示例:
// 父 Agent 工具类
AgentRequestOptions options = AgentRequestOptions.builder()
.taskId("task-123") // ← 方式5:通过 options
.userId("user-456")
.timeout(Duration.ofSeconds(30))
.build();
businessAgent.call(msg, options).block();
子 Agent 接收:
@Override
public Flux<Event> stream(List<Msg> requestMessages, AgentRequestOptions options) {
String taskId = options.getTaskId(); // ← 从 options 提取
String userId = options.getUserId();
Duration timeout = options.getTimeout();
// ...
}
特点:
- ✅ 用于传递请求级别的参数
- ✅ 不会混入对话内容
- ⚠️ 可用参数由
AgentRequestOptions定义,不如 metadata 灵活
方式 6:通过 ContentBlock(复杂内容)⚠️
用途:传递多种类型的内容(文本、图片、工具调用结果等)
示例:
Msg msg = Msg.builder()
.content(List.of(
TextBlock.of("用户想查询订单"), // ← 文本内容
ImageBlock.of("image_url"), // ← 图片
ToolResultBlock.of("tool_result") // ← 工具结果
))
.build();
特点:
- ⚠️ 用于多模态内容(文本+图片+工具结果)
- ⚠️ 不常用于简单参数传递
- ⚠️ 比较复杂,适合高级场景
方式 7:直接在 textContent 中嵌入参数 ❌ 不推荐
用途:把参数混在文本里
示例:
Msg msg = Msg.builder()
.textContent("用户ID:12345,订单号:ORDER-001,用户想查询订单状态") // ← 方式7:混在文本里
.build();
子 Agent 提取:
// 需要解析文本
String text = msg.getTextContent();
String userId = extractUserId(text); // 自己写解析逻辑
String orderId = extractOrderId(text);
特点:
- ❌ 难以解析,容易出错
- ❌ AI 会读取参数,可能干扰对话
- ❌ 不推荐使用
方式 8:通过全局 Session/Context ⚠️
用途:在 Agent 构建时传递参数
示例:
// 父 Agent 工具类
public ToolResultBlock callBusinessAgent(
@ToolParam String context,
@ToolParam Long userId) {
// 方式8:通过 Session 传递全局参数
Session session = sessionManager.getSession(userId);
session.setAttribute("userId", userId);
session.setAttribute("currentOrder", "ORDER-001");
// 子 Agent 可以从 Session 读取
Msg msg = Msg.builder()
.textContent(context)
.build();
return businessAgent.call(msg).block();
}
特点:
- ⚠️ 用于跨多次对话的全局状态
- ⚠️ 不适合单次请求的参数传递
- ⚠️ 需要额外的 Session 管理
📊 方式对比表
| 方式 | 用途 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| textContent | 对话内容 | AI 能理解 | 混淆参数和对话 | ⭐⭐⭐ |
| metadata | 业务参数 | 结构化、易提取 | 需要手动放入/提取 | ⭐⭐⭐⭐⭐ |
| role | 消息角色 | 控制对话流程 | 不适合传参数 | ⭐ |
| name | 消息来源 | 标识发送者 | 不适合传参数 | ⭐ |
| AgentRequestOptions | 请求参数 | 不混入消息 | 参数有限 | ⭐⭐⭐⭐ |
| ContentBlock | 多模态内容 | 支持多种类型 | 复杂 | ⭐⭐ |
| 嵌入 textContent | - | - | 难解析、易出错 | ❌ |
| Session/Context | 全局状态 | 跨对话共享 | 管理复杂 | ⭐⭐ |
🎯 推荐的最佳实践
标准组合:textContent + metadata ✅
@Tool(description = "处理订单")
public ToolResultBlock callBusinessAgent(
@ToolParam(name = "context") String context,
@ToolParam(name = "userId") Long userId,
@ToolParam(name = "orderId") String orderId,
@ToolParam(name = "priority") String priority) {
// 标准组合
Msg msg = Msg.builder()
.textContent(context) // ← 对话内容放这里(AI 读)
.metadata(Map.of( // ← 业务参数放这里(程序用)
"userId", userId,
"orderId", orderId,
"priority", priority
))
.build();
return businessAgent.call(msg).block();
}
子 Agent 提取:
@Override
public Flux<Event> stream(List<Msg> requestMessages, AgentRequestOptions options) {
// 提取对话内容
String textContent = requestMessages.get(0).getTextContent();
// 提取业务参数
String userId = extractMetadata(requestMessages, "userId");
String orderId = extractMetadata(requestMessages, "orderId");
String priority = extractMetadata(requestMessages, "priority");
// 使用参数
ReActAgent agent = buildReActAgent(userId, orderId, priority);
return agent.stream(requestMessages);
}
🌰 完整示例:使用多种方式
场景:复杂的订单处理
@Tool(description = "处理订单")
public ToolResultBlock handleComplexOrder(
@ToolParam(name = "context") String context,
@ToolParam(name = "userId") Long userId,
@ToolParam(name = "orderId") String orderId,
@ToolParam(name = "priority") String priority,
@ToolParam(name = "timeout") Integer timeoutSeconds) {
// ========== 方式1:textContent(对话内容)==========
String textContent = context;
// ========== 方式2:metadata(业务参数)==========
Map<String, Object> metadata = new HashMap<>();
metadata.put("userId", userId);
metadata.put("orderId", orderId);
metadata.put("priority", priority);
metadata.put("timestamp", System.currentTimeMillis());
metadata.put("source", "supervisor-agent");
// ========== 方式3:role(消息角色)==========
String role = "user"; // 标识这是用户消息
// ========== 方式4:name(消息来源)==========
String name = "supervisor-agent";
// ========== 方式5:AgentRequestOptions(请求参数)==========
AgentRequestOptions options = AgentRequestOptions.builder()
.taskId("task-" + System.currentTimeMillis())
.userId(userId.toString())
.timeout(Duration.ofSeconds(timeoutSeconds))
.build();
// 构造消息
Msg msg = Msg.builder()
.textContent(textContent) // 方式1
.metadata(metadata) // 方式2
.role(role) // 方式3
.name(name) // 方式4
.build();
// 调用子 Agent(带 options)
Msg result = businessAgent.call(msg, options).block(); // 方式5
return ToolResultBlock.of(result.getContent());
}
子 Agent 接收:
@Override
public Flux<Event> stream(List<Msg> requestMessages, AgentRequestOptions options) {
Msg firstMsg = requestMessages.get(0);
// ========== 从不同方式提取参数 ==========
// 方式1:textContent
String textContent = firstMsg.getTextContent();
// 方式2:metadata
Map<String, Object> metadata = firstMsg.getMetadata();
String userId = metadata.get("userId").toString();
String orderId = metadata.get("orderId").toString();
String priority = metadata.get("priority").toString();
Long timestamp = (Long) metadata.get("timestamp");
String source = metadata.get("source").toString();
// 方式3:role
String role = firstMsg.getRole();
// 方式4:name
String name = firstMsg.getName();
// 方式5:AgentRequestOptions
String taskId = options.getTaskId();
String optionsUserId = options.getUserId();
Duration timeout = options.getTimeout();
// 使用所有参数
log.info("Received request - textContent: {}, userId: {}, orderId: {}, priority: {}, " +
"timestamp: {}, source: {}, role: {}, name: {}, taskId: {}, timeout: {}",
textContent, userId, orderId, priority, timestamp, source, role, name, taskId, timeout);
ReActAgent agent = buildReActAgent(userId, orderId, priority);
return agent.stream(requestMessages);
}
🔥 实战建议
建议 1:日常开发只用两种方式
// 90% 的场景只需要这两种
Msg msg = Msg.builder()
.textContent(context) // 方式1:对话内容
.metadata(Map.of( // 方式2:业务参数
"userId", userId,
"orderId", orderId
))
.build();
建议 2:参数分类
// 对话内容 → textContent
// 业务参数 → metadata
// 控制参数 → AgentRequestOptions
Msg msg = Msg.builder()
.textContent("用户想查询订单") // 对话
.metadata(Map.of("userId", 123, "orderId", "001")) // 业务
.build();
AgentRequestOptions options = AgentRequestOptions.builder()
.timeout(Duration.ofSeconds(30)) // 控制
.build();
建议 3:避免混用
// ❌ 不要这样:参数既在 textContent 又在 metadata
.textContent("用户12345想查询订单ORDER-001") // ❌ 参数混在文本里
.metadata(Map.of("userId", 12345, "orderId", "ORDER-001")) // ❌ 又在 metadata
// ✅ 应该这样:清晰分离
.textContent("用户想查询订单") // ✅ 纯粹的对话内容
.metadata(Map.of("userId", 12345, "orderId", "ORDER-001")) // ✅ 参数在 metadata
📝 总结答案
你的问题:除了 context 和 metadata,还有哪些方式可以传递参数?
答案:共有 8 种方式,但实际常用的只有 2-3 种:
| 方式 | 使用频率 | 说明 |
|---|---|---|
| textContent | ⭐⭐⭐⭐⭐ | 传对话内容,最常用 |
| metadata | ⭐⭐⭐⭐⭐ | 传业务参数,最推荐 |
| AgentRequestOptions | ⭐⭐⭐ | 传控制参数,偶尔用 |
| role | ⭐⭐ | 控制对话角色,少用 |
| name | ⭐⭐ | 标识消息来源,少用 |
| ContentBlock | ⭐ | 多模态内容,高级场景 |
| 嵌入 textContent | ❌ | 不推荐 |
| Session/Context | ⭐ | 全局状态,特殊场景 |
最佳实践:
// 90% 的场景只需要这个组合
Msg msg = Msg.builder()
.textContent(context) // 对话内容
.metadata(metadata) // 业务参数
.build();
明白了吗?🎉
更多推荐


所有评论(0)