# 发送消息并启动任务

向已经发布的智能体发送一条文本消息。成功响应可能包含已经完成的结果，也可能只创建一个仍在运行的任务；无论哪种情况，都应先保存返回的任务 ID。

## 前提条件

- 已按[获取智能体调用信息](get-agent-card.md)确认目标智能体及其输入类型。
- 已设置 `PRODUCT_API_BASE_URL`、`PRODUCT_API_KEY`、`WORKSPACE_ID` 和 `AGENT_ID`。
- 为本次请求和消息分别生成唯一的请求 ID 与消息 ID。

```bash
export REQUEST_ID='<unique-request-id>'
export MESSAGE_ID='<unique-message-id>'
```

## 发送文本消息

```bash
curl -X POST "$PRODUCT_API_BASE_URL/agents/a2a" \
  -H "X-API-Key: $PRODUCT_API_KEY" \
  -H "X-Workspace-ID: $WORKSPACE_ID" \
  -H "Content-Type: application/json" \
  -d "{
    \"agent_id\": \"$AGENT_ID\",
    \"jsonrpc\": \"2.0\",
    \"id\": \"$REQUEST_ID\",
    \"method\": \"message/send\",
    \"params\": {
      \"message\": {
        \"kind\": \"message\",
        \"role\": \"user\",
        \"messageId\": \"$MESSAGE_ID\",
        \"parts\": [
          {
            \"kind\": \"text\",
            \"text\": \"汇总本季度各区域销售额\"
          }
        ]
      }
    }
  }"
```

| 字段 | 类型 | 必需 | 说明 |
| --- | --- | --- | --- |
| `agent_id` | string | 与 `agent_code` 二选一 | 目标智能体 ID。后续查询同一任务时继续使用相同选择器。 |
| `jsonrpc` | string | 是 | 固定为 `2.0`。 |
| `id` | string 或 number | 建议 | 调用方生成的请求 ID。响应会回传该值；它不是任务 ID。 |
| `method` | string | 是 | 非流式文本调用使用 `message/send`。 |
| `params.message.kind` | string | 是 | 消息对象使用 `message`。 |
| `params.message.role` | string | 是 | 用户消息使用 `user`。 |
| `params.message.messageId` | string | 是 | 调用方生成的消息 ID。重试同一逻辑消息时保持稳定。 |
| `params.message.parts` | array | 是 | 消息内容列表。文本 Part 使用 `kind: text` 和 `text`。 |
| `params.idempotencyKey` | string | 否 | 调用方的幂等键。只有应用已经建立稳定重试策略时使用。 |

## 检查响应

A2A 成功响应使用 JSON-RPC 结构，不使用 Product API 的 `code/msg/data` 包络。任务型响应示例如下：

```json
{
  "jsonrpc": "2.0",
  "id": "<REQUEST_ID>",
  "result": {
    "kind": "task",
    "id": "<TASK_ID>",
    "contextId": "<CONTEXT_ID>",
    "turnId": "<TURN_ID>",
    "status": {
      "state": "working"
    },
    "artifacts": []
  }
}
```

首先检查响应是否包含 `error`。成功时再读取 `result.kind`；当结果为 Task 时，至少保存以下字段：

| 字段 | 用途 |
| --- | --- |
| `result.id` | Task ID。查询状态、取消任务和提交补充输入时使用。 |
| `result.contextId` | 后续普通消息继续同一会话时使用。 |
| `result.turnId` | 智能体要求结构化补充输入时使用。 |
| `result.status.state` | 当前状态。`working` 不表示任务已经完成。 |

网络超时不能证明任务没有创建。不要立刻换一个消息 ID 重发相同内容；如果已经取得任务 ID，先查询任务。如果没有取得任务 ID，使用应用保存的请求 ID、消息 ID 和调用记录排查，再决定是否重试。

## 继续已有上下文

要发送普通的后续消息，在下一条消息中加入服务端返回的 `contextId`。如果智能体明确进入 `input-required`，则按[提交后续输入](submit-follow-up-input.md)处理，不要把结构化回答拼成另一条无关联的新消息。

## 下一步

- [查询任务状态与结果](query-task-status-results.md)
- [提交后续输入](submit-follow-up-input.md)
