A2A 有三个核心数据结构——Message(消息)、Part(内容块)、Task(任务)
Task(任务:有状态、有生命周期)
├── status: 当前状态(submitted/working/completed/...)
├── history: Message 列表(对话历史)
│ └── Message(一轮发言)
│ ├── role: ROLE_USER(客户端)或 ROLE_AGENT(服务端)
│ ├── messageId / taskId / contextId
│ └── parts: Part 列表(具体内容)
│ └── Part(最小内容单元)
│ ├── text —— 纯文本 (TextPart)
│ ├── raw / url + mediaType (FilePart:
│ │ 文件字节或文件链接)
│ └── data —— 结构化 JSON (DataPart)
└── artifacts: 任务产物(见 05 篇)
{"text": "帮我查天气"} —— 最常用;raw,base64)或文件链接(url),
配 mediaType(如 image/png)和 filename;{"data": {...}} —— 结构化 JSON,适合表单、参数、机器可读结果。id;
Client 之后可凭 id 查询、取消、追加消息。Client 向 Server 发送第一条消息,Server 二选一地回应:
示例 JSON-RPC 请求/响应:
// POST / (HTTP 头需带 A2A-Version: 1.0)
{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"messageId": "msg-001",
"role": "ROLE_USER",
"parts": [{ "text": "roll 2d6" }]
}
}
}
// 响应:Server 创建并完成了任务
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"task": {
"id": "4b22460b-8ea6-4989-adf4-0383f48a6faf",
"contextId": "496b80c4-d8ae-4364-adfb-858f19211370",
"status": { "state": "TASK_STATE_COMPLETED",
"timestamp": "2026-11-12T10:49:58.838213Z" },
"artifacts": [{
"artifactId": "2f3a398c-...",
"name": "dice-result",
"parts": [{ "text": "掷 2 个 6 面骰子: [4, 4],总和 = 8" }]
}],
"history": [{ "messageId": "msg-001", "role": "ROLE_USER",
"parts": [{ "text": "roll 2d6" }] }]
}
}
}
Task 的 status.state 按以下状态机流转(v1.0 共 8 个有效状态):
┌─────────────┐
Client 发消息 │ submitted │ 已受理,排队中
──────────> └──────┬──────┘
▼
┌─────────────┐
┌──────►│ working │ Agent 处理中
│ └──┬───┬───┬──┘
Client 补 │ │ │ │
充了输入 │ │ │ └───────────────┐
│ │ │ │
┌──────┴───────┐ │ │ ┌──────▼──────┐
│input-required│◄─┘ │ │auth-required│ 需要额外认证
│ 等用户补充 │ │ └─────────────┘
└──────────────┘ │
▼
┌───────────┬──────────────┬───────────┬──────────┐
▼ ▼ ▼ ▼ ▼
┌─────────┐ ┌────────┐ ┌─────────┐ ┌────────┐ ┌────────┐
│completed│ │ failed │ │canceled │ │rejected│ │(error) │
└─────────┘ └────────┘ └─────────┘ └────────┘ └────────┘
└──────────────── 终态(不再接受新消息)────────────┘
| 状态 | 含义 | 终态? |
|---|---|---|
submitted |
已受理,尚未开始 | 否 |
working |
正在处理 | 否 |
input-required |
暂停,等 Client 补充信息(见 06 篇) | 否(可恢复) |
auth-required |
暂停,需要额外的认证/授权 | 否(可恢复) |
completed |
成功完成,产物在 artifacts |
✅ |
failed |
处理出错 | ✅ |
canceled |
被 Client 主动取消(CancelTask) | ✅ |
rejected |
Server 拒绝接单 | ✅ |
两条重要规则:
contextId 开新任务。import uuid
from a2a.types import Message, Part, Role, SendMessageRequest
request = SendMessageRequest(
message=Message(
message_id=str(uuid.uuid4()),
role=Role.ROLE_USER,
parts=[
Part(text="帮我分析这份数据"), # TextPart
Part(data={"quarter": "Q3", "metric": "营收"}), # DataPart
],
)
)