Skip to content

发送消息响应结果格式约定

来源: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(状态更新)

json
{
  "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

json
{
  "kind": "text",
  "text": "这是文本回复内容",
  "metadata": {}
}

2. 'tool_call'/'tool_result' - DataPart

通过DataPart传递结构化数据,适用于工具调用和结果: 2

json
{
  "kind": "data",
  "data": {
    "tool_call": {
      "function": "search_web",
      "parameters": {"query": "A2A protocol"}
    }
  },
  "mimeType": "application/json",
  "metadata": {}
}

3. 'artifact' - Artifact对象

直接对应A2A的Artifact对象,用于任务输出: 3

json
{
  "artifactId": "artifact-123",
  "name": "generated_document.txt",
  "parts": [
    {
      "kind": "text",
      "text": "生成的文档内容..."
    }
  ]
}

4. 'error' - JSON-RPC错误响应

通过JSON-RPC错误响应或TaskStatus中的错误状态传递: 4

json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": {
      "details": "具体错误信息"
    }
  }
}

5. 'thinking'/'status' - TaskStatusUpdateEvent

通过TaskStatusUpdateEvent的message字段传递中间状态: 5

json
{
  "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

  1. 状态更新 ('thinking'/'status')
  2. 工件更新 ('artifact')
  3. 最终完成 ('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传递工具调用信息:

json
{
  "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传递:

json
{
  "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. 流式工具调用

如果使用流式推送,工具调用过程可以分步骤推送:

json
{
  "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

json
{
  "skills": [
    {
      "id": "change_background_color",
      "name": "修改背景色",
      "description": "修改聊天页面的背景颜色",
      "tags": ["ui", "frontend", "styling"],
      "inputModes": ["application/json"],
      "outputModes": ["application/json"]
    }
  ]
}

2. 前端工具调用流程

当用户请求修改背景色时,消息流程如下:

用户请求

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "method": "message/send",
  "params": {
    "message": {
      "role": "user",
      "parts": [
        {
          "kind": "text",
          "text": "请把聊天页面背景色改为蓝色"
        }
      ],
      "messageId": "msg-001"
    }
  }
}

后端识别并返回前端工具调用指令

后端识别到这是前端技能,通过DataPart返回前端工具调用指令: 2

json
{
  "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. 前端执行工具并返回结果

前端接收到工具调用指令后,执行相应操作并返回结果:

json
{
  "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

json
{
  "jsonrpc": "2.0",
  "id": "req-001",
  "result": {
    "taskId": "task-123",
    "contextId": "context-456",
    "status": {
      "state": "working",
      "message": "正在修改背景色..."
    },
    "final": false,
    "kind": "status-update"
  }
}

实现要点

  1. 工具识别: 后端需要能够识别哪些是前端工具,哪些是后端工具
  2. 状态同步: 使用input-required状态来暂停任务,等待前端执行
  3. 结果验证: 前端执行完成后,需要将结果返回给后端继续处理
  4. 错误处理: 如果前端工具执行失败,需要通过适当的错误状态反馈

Notes

这种设计充分利用了A2A协议的任务状态管理和DataPart的灵活性,实现了前后端工具的统一调用接口。 前端工具本质上是通过协议层面的协作来实现的,而不是直接的函数调用。

Wiki pages you might want to explore:

User

给我解释下为用户让修改颜色,怎么还是个任务呢?

AI

您问的是为什么用户修改颜色这样简单的操作也要创建一个任务。这是一个很好的问题,让我解释一下A2A协议中任务的设计理念。

A2A协议中的任务概念

在A2A协议中,任务(Task)是所有有状态交互的基本单位1 即使是看似简单的操作,如果涉及到状态管理或需要跟踪执行过程,都会被建模为任务。

为什么修改颜色需要任务?

  1. 状态跟踪需求:修改背景色虽然操作简单,但需要:

    • 记录操作前的状态(原来的颜色)
    • 跟踪执行过程(正在修改、已完成、失败等)
    • 保存执行结果(新颜色值、执行时间等)
  2. 前后端协作:由于这是前端工具,需要:

    • 后端识别并解析用户意图
    • 向前端发送执行指令
    • 前端执行并返回结果
    • 后端确认操作完成
  3. 异步执行模式2 A2A协议设计为支持异步操作,即使是快速的操作也使用统一的任务模式来保持一致性。

任务状态流转

对于修改颜色这个操作,任务状态会经历:

  1. submitted - 任务已创建
  2. input-required - 等待前端执行工具
  3. working - 前端正在执行
  4. 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. 客户端请求

json
{
  "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

json
{
  "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方法中,服务器可以返回两种类型的响应:

  1. Message: 直接响应,无状态
  2. Task: 有状态的任务对象

适用场景 5

直接Message响应适用于:

  • 简单的信息查询
  • 不需要状态跟踪的操作
  • 即时完成的任务
  • 协商阶段的交互

前端工具调用的Message模式实现

对于您提到的前端工具调用,使用Message模式的流程:

  1. 用户请求直接返回工具调用指令
  2. 前端执行发送执行结果
  3. 后端确认返回最终响应

每个步骤都是独立的Message交换,没有持久的任务状态。

Notes

直接Message响应模式提供了更轻量级的交互方式,但失去了状态跟踪、错误恢复和进度监控的能力。 选择使用Message还是Task取决于具体的业务需求和复杂度。

Wiki pages you might want to explore:

Wiki pages you might want to explore:

User

AI

Released under the MIT License.