发送消息响应结果格式约定
来源:https://deepwiki.com/search/text-toolcall-toolresult-artif_0ba9c335-895e-43a2-85bc-01e4c699c43d
User: 假如我使用规范搭建了聊天接口,'text' | 'tool_call' | 'tool_result' | 'artifact' | 'error' | 'thinking' | 'status'这几种回复,请给我详细的推送消息内容,
AI:
根据您的问题,您想了解在使用A2A协议搭建聊天接口时,针对'text' | 'tool_call' | 'tool_result' | 'artifact' | 'error' | 'thinking' | 'status'这几种回复类型的详细推送消息内容。
A2A协议中的消息推送机制
A2A协议支持两种主要的推送机制:流式推送(Server-Sent Events)和推送通知(Push Notifications)。 1
流式推送消息结构
当使用message/stream方法时,服务器会通过SSE推送以下类型的事件: 2
1. TaskStatusUpdateEvent(状态更新)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "task-id-123",
"contextId": "context-id-456",
"status": {
"state": "working",
"message": "正在处理您的请求...",
"timestamp": "2025-04-02T16:59:25.331844"
},
"final": false,
"kind": "status-update"
}
}
``` [3](#0-2)
#### 2. TaskArtifactUpdateEvent(工件更新)
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "task-id-123",
"contextId": "context-id-456",
"artifact": {
"artifactId": "artifact-123",
"name": "response.txt",
"parts": [
{
"kind": "text",
"text": "这是生成的文本内容..."
}
]
},
"append": true,
"lastChunk": false,
"kind": "artifact-update"
}
}
``` [4](#0-3)
#### 3. Task对象(任务完成)
```json
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "task-id-123",
"contextId": "context-id-456",
"status": {
"state": "completed",
"timestamp": "2025-04-02T16:59:35.331844"
},
"artifacts": [...],
"kind": "task"
}
}
``` [5](#0-4)
### 针对您提到的回复类型的映射
基于A2A协议的结构,您提到的回复类型可以这样映射:
- **'text'**: 使用`TextPart`在Message或Artifact中传递 [6](#0-5)
- **'tool_call'/'tool_result'**: 可以通过`DataPart`传递结构化数据 [7](#0-6)
- **'artifact'**: 直接对应A2A的`Artifact`对象 [8](#0-7)
- **'error'**: 通过JSON-RPC错误响应或TaskStatus中的错误状态传递 [9](#0-8)
- **'thinking'/'status'**: 通过TaskStatusUpdateEvent的message字段传递中间状态 [3](#0-2)
### 推送通知配置
对于长时间运行的任务,您还可以配置推送通知: [10](#0-9)
```json
{
"pushNotificationConfig": {
"url": "https://your-webhook.com/notifications",
"token": "your-auth-token",
"authentication": {
"schemes": ["Bearer"]
}
}
}Notes
A2A协议提供了灵活的消息传递机制,通过Part联合类型(TextPart、FilePart、DataPart)可以支持多种内容格式。 11 您可以根据具体的聊天场景选择合适的推送方式和消息结构。
Wiki pages you might want to explore:
User
我希望你参考标准可以给我列出来 针对您提到的回复类型的映射 基于A2A协议的结构,您提到的回复类型可以这样映射: 'text': 使用TextPart在Message或Artifact中传递 specification.md:334-340 'tool_call'/'tool_result': 可以通过DataPart传递结构化数据 specification.md:350-356 'artifact': 直接对应A2A的Artifact对象 specification.md:382-388 'error': 通过JSON-RPC错误响应或TaskStatus中的错误状态传递 specification.md:437-443 'thinking'/'status': 通过TaskStatusUpdateEvent的message字段传递中间状态 specification.md:582-588
AI
根据A2A协议规范,我来为您详细列出每种回复类型的标准映射和具体消息结构:
基于A2A协议的回复类型映射
1. 'text' - TextPart
使用TextPart在Message或Artifact中传递文本内容: 1
{
"kind": "text",
"text": "这是文本回复内容",
"metadata": {}
}2. 'tool_call'/'tool_result' - DataPart
通过DataPart传递结构化数据,适用于工具调用和结果: 2
{
"kind": "data",
"data": {
"tool_call": {
"function": "search_web",
"parameters": {"query": "A2A protocol"}
}
},
"mimeType": "application/json",
"metadata": {}
}3. 'artifact' - Artifact对象
直接对应A2A的Artifact对象,用于任务输出: 3
{
"artifactId": "artifact-123",
"name": "generated_document.txt",
"parts": [
{
"kind": "text",
"text": "生成的文档内容..."
}
]
}4. 'error' - JSON-RPC错误响应
通过JSON-RPC错误响应或TaskStatus中的错误状态传递: 4
{
"jsonrpc": "2.0",
"id": 1,
"error": {
"code": -32603,
"message": "Internal error",
"data": {
"details": "具体错误信息"
}
}
}5. 'thinking'/'status' - TaskStatusUpdateEvent
通过TaskStatusUpdateEvent的message字段传递中间状态: 5
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "task-123",
"contextId": "context-456",
"status": {
"state": "working",
"message": "正在思考中...",
"timestamp": "2025-04-02T16:59:25.331844"
},
"final": false,
"kind": "status-update"
}
}完整的流式推送示例
在实际的聊天接口中,这些类型可以组合使用。例如,一个完整的对话流程可能包含: 6
- 状态更新 ('thinking'/'status')
- 工件更新 ('artifact')
- 最终完成 ('text')
Notes
A2A协议通过Part联合类型(TextPart、FilePart、DataPart)提供了灵活的内容传递机制,可以很好地映射到常见的聊天回复类型。 每种类型都有明确的结构定义,确保了跨系统的互操作性。
Wiki pages you might want to explore:
User
前端注册的工具被用户提问映射使用时,消息是什么样子的?
AI
根据您的问题,您想了解在A2A协议中,当前端注册的工具被用户提问映射使用时,消息的结构是什么样子的。
工具调用在A2A协议中的消息结构
在A2A协议中,工具调用主要通过DataPart来传递结构化数据。 1 当前端注册的工具被映射使用时,消息结构如下:
1. 工具调用请求 (tool_call)
用户发起工具调用时,使用DataPart传递工具调用信息:
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "data",
"data": {
"tool_call": {
"id": "call_123",
"function": "search_web",
"parameters": {
"query": "A2A protocol documentation",
"max_results": 5
}
}
},
"mimeType": "application/json",
"metadata": {
"tool_type": "web_search"
}
}
],
"messageId": "msg-456"
}
}
}2. 工具执行结果 (tool_result)
代理执行工具后,返回结果也通过DataPart传递:
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"id": "task-789",
"contextId": "context-abc",
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"kind": "data",
"data": {
"tool_result": {
"call_id": "call_123",
"function": "search_web",
"result": {
"results": [
{
"title": "A2A Protocol Specification",
"url": "https://example.com/a2a-spec",
"snippet": "The Agent2Agent Protocol..."
}
],
"total_results": 1
}
}
},
"mimeType": "application/json"
}
],
"messageId": "msg-789",
"taskId": "task-789"
},
"timestamp": "2025-04-02T16:59:25.331844"
},
"kind": "task"
}
}3. 流式工具调用
如果使用流式推送,工具调用过程可以分步骤推送:
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"taskId": "task-789",
"contextId": "context-abc",
"status": {
"state": "working",
"message": {
"role": "agent",
"parts": [
{
"kind": "text",
"text": "正在调用搜索工具..."
}
]
},
"timestamp": "2025-04-02T16:59:20.331844"
},
"final": false,
"kind": "status-update"
}
}与MCP协议的关系
值得注意的是,A2A协议主要用于代理间通信,而工具调用更适合使用MCP(Model Context Protocol)。 2 在实际应用中:
- MCP: 用于代理与工具的直接交互
- A2A: 用于代理间的协作,可能包含工具调用结果的传递
Notes
A2A协议通过DataPart的灵活结构支持工具调用信息的传递,但主要设计目标是代理间协作而非工具集成。 3 对于前端工具注册和调用,建议结合使用MCP协议来处理工具层面的交互,然后通过A2A传递结果。
Wiki pages you might want to explore:
User
我说的工具是创建会话时,我把前端的工具注册到后端了,所以聊天时就可以使用工具了,只是工具分前端工具、后端工具,后端工具执行在后端,给到前端的tool_result,但是前端技能执行在前端,举例:用户通过聊天修改聊天页面背景色,我就可以封装成一个前端技能,具体如何实现
AI
根据您的描述,您想了解如何在A2A协议中实现前端工具(前端技能)的调用,特别是像"修改聊天页面背景色"这样的前端操作。
前端工具在A2A协议中的实现方案
基于A2A协议的设计,您可以通过以下方式实现前端工具的调用:
1. 工具注册阶段
在创建会话时,前端工具需要在AgentCard中注册为技能: 1
{
"skills": [
{
"id": "change_background_color",
"name": "修改背景色",
"description": "修改聊天页面的背景颜色",
"tags": ["ui", "frontend", "styling"],
"inputModes": ["application/json"],
"outputModes": ["application/json"]
}
]
}2. 前端工具调用流程
当用户请求修改背景色时,消息流程如下:
用户请求
{
"jsonrpc": "2.0",
"id": "req-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "请把聊天页面背景色改为蓝色"
}
],
"messageId": "msg-001"
}
}
}后端识别并返回前端工具调用指令
后端识别到这是前端技能,通过DataPart返回前端工具调用指令: 2
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"id": "task-123",
"contextId": "context-456",
"status": {
"state": "input-required",
"message": {
"role": "agent",
"parts": [
{
"kind": "data",
"data": {
"frontend_tool_call": {
"tool_id": "change_background_color",
"function": "changeBackgroundColor",
"parameters": {
"color": "blue",
"target": "chat-container"
}
}
},
"mimeType": "application/json",
"metadata": {
"execution_context": "frontend"
}
}
]
},
"timestamp": "2025-04-02T16:59:25.331844"
},
"kind": "task"
}
}3. 前端执行工具并返回结果
前端接收到工具调用指令后,执行相应操作并返回结果:
{
"jsonrpc": "2.0",
"id": "req-002",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "data",
"data": {
"frontend_tool_result": {
"tool_id": "change_background_color",
"success": true,
"result": {
"previous_color": "#ffffff",
"new_color": "#0066cc",
"applied_at": "2025-04-02T16:59:30.000Z"
}
}
},
"mimeType": "application/json"
}
],
"messageId": "msg-002",
"taskId": "task-123"
}
}
}4. 任务状态管理
使用A2A的任务状态机制来管理前端工具的执行: 3
input-required: 等待前端执行工具working: 前端正在执行工具completed: 工具执行完成
5. 流式更新支持
如果需要实时反馈,可以使用流式推送: 4
{
"jsonrpc": "2.0",
"id": "req-001",
"result": {
"taskId": "task-123",
"contextId": "context-456",
"status": {
"state": "working",
"message": "正在修改背景色..."
},
"final": false,
"kind": "status-update"
}
}实现要点
- 工具识别: 后端需要能够识别哪些是前端工具,哪些是后端工具
- 状态同步: 使用
input-required状态来暂停任务,等待前端执行 - 结果验证: 前端执行完成后,需要将结果返回给后端继续处理
- 错误处理: 如果前端工具执行失败,需要通过适当的错误状态反馈
Notes
这种设计充分利用了A2A协议的任务状态管理和DataPart的灵活性,实现了前后端工具的统一调用接口。 前端工具本质上是通过协议层面的协作来实现的,而不是直接的函数调用。
Wiki pages you might want to explore:
User
给我解释下为用户让修改颜色,怎么还是个任务呢?
AI
您问的是为什么用户修改颜色这样简单的操作也要创建一个任务。这是一个很好的问题,让我解释一下A2A协议中任务的设计理念。
A2A协议中的任务概念
在A2A协议中,任务(Task)是所有有状态交互的基本单位。 1 即使是看似简单的操作,如果涉及到状态管理或需要跟踪执行过程,都会被建模为任务。
为什么修改颜色需要任务?
状态跟踪需求:修改背景色虽然操作简单,但需要:
- 记录操作前的状态(原来的颜色)
- 跟踪执行过程(正在修改、已完成、失败等)
- 保存执行结果(新颜色值、执行时间等)
前后端协作:由于这是前端工具,需要:
- 后端识别并解析用户意图
- 向前端发送执行指令
- 前端执行并返回结果
- 后端确认操作完成
异步执行模式: 2 A2A协议设计为支持异步操作,即使是快速的操作也使用统一的任务模式来保持一致性。
任务状态流转
对于修改颜色这个操作,任务状态会经历:
submitted- 任务已创建input-required- 等待前端执行工具working- 前端正在执行completed- 操作完成 3
简化的替代方案
A2A协议也支持无状态的Message响应。 4 对于非常简单的操作,代理可以选择直接返回Message而不是Task,但这样就失去了状态跟踪和错误恢复的能力。
Notes
任务模式虽然看起来为简单操作增加了复杂性,但它提供了统一的状态管理、错误处理和可追溯性,这对于企业级应用和复杂的多代理协作场景是必要的。 如果您的场景确实不需要状态跟踪,可以考虑使用直接的Message响应模式。
Wiki pages you might want to explore:
User
直接的Message响应模式具体交互数据是什么样子的?详细讲解下
AI
根据您的问题,您想了解A2A协议中直接的Message响应模式的具体交互数据结构。
直接Message响应模式
在A2A协议中,代理可以选择直接返回Message对象而不是创建Task,这适用于简单、无状态的交互。 1
基本交互结构
1. 客户端请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "请把聊天页面背景色改为蓝色"
}
],
"messageId": "9229e770-767c-417b-a0b0-f0741243c589"
},
"metadata": {}
}
}2. 服务器直接Message响应 2
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"messageId": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"role": "agent",
"parts": [
{
"kind": "data",
"data": {
"frontend_tool_call": {
"tool_id": "change_background_color",
"function": "changeBackgroundColor",
"parameters": {
"color": "blue",
"target": "chat-container"
}
}
},
"mimeType": "application/json"
}
],
"kind": "message",
"metadata": {}
}
}Message对象结构详解 3
Message对象包含以下关键字段:
role: 标识发送者("user" 或 "agent")parts: 内容部分数组,支持多种类型messageId: 消息唯一标识符contextId: 上下文标识符,用于关联相关交互kind: 类型判别器,值为"message"
与Task响应的区别 4
在message/send方法中,服务器可以返回两种类型的响应:
- Message: 直接响应,无状态
- Task: 有状态的任务对象
适用场景 5
直接Message响应适用于:
- 简单的信息查询
- 不需要状态跟踪的操作
- 即时完成的任务
- 协商阶段的交互
前端工具调用的Message模式实现
对于您提到的前端工具调用,使用Message模式的流程:
- 用户请求 → 直接返回工具调用指令
- 前端执行 → 发送执行结果
- 后端确认 → 返回最终响应
每个步骤都是独立的Message交换,没有持久的任务状态。
Notes
直接Message响应模式提供了更轻量级的交互方式,但失去了状态跟踪、错误恢复和进度监控的能力。 选择使用Message还是Task取决于具体的业务需求和复杂度。
Wiki pages you might want to explore:
Wiki pages you might want to explore:
User
AI
