Task 与返回结构
每次 message/send 都会产生一个 Task。草料的三个 skill 都是同步查询,请求返回时 Task 已经跑完,结果就在同一个响应里。
生命周期
submitted → working → (artifact-update) → completed
└→ failed因为服务不支持流式,你看不到中间状态,拿到的响应里 status.state 已经是 completed 或 failed。
成功的返回
json
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"kind": "task",
"id": "9332c282-1fa7-4c42-96ac-58e4e2f88f4c",
"contextId": "e9c10667-e79b-4c99-b05f-0cb237067127",
"status": {
"state": "completed",
"timestamp": "2026-08-12T17:14:13.272Z"
},
"history": [
{
"kind": "message",
"role": "user",
"messageId": "m1",
"parts": [{ "kind": "text", "text": "这个二维码是什么?https://qr71.cn/okDISU/qssTnoy" }]
}
],
"artifacts": [
{
"artifactId": "6915a6bd-d63c-42e6-b629-8aed3bb06236",
"name": "entity",
"parts": [
{ "kind": "data", "data": { "...": "ObjectCard v2" } },
{ "kind": "text", "text": "数控车床-A08-03-06;建档组织:草料二维码;状态:设备运行状态=正常;账本 1 条;属性 7 项;可执行操作 2 个" }
]
}
]
}
}| 字段 | 说明 |
|---|---|
id | Task id,用于 tasks/get 回查 |
contextId | 会话上下文 id,同一轮对话中的多个 Task 共享 |
status.state | completed 或 failed |
history | 本次交互的消息记录 |
artifacts | 结果。草料每次只产出一个 |
artifact 的两个部分
每个 artifact 固定包含两个 part:
- DataPart(
kind: "data"):结构化数据,给程序消费。结构由 skill 决定,见 Skill 列表 - TextPart(
kind: "text"):一句话摘要,可以直接进对话,不需要你再做一次总结
artifact 的 name 表明这次返回的是什么:entity、records 或 actions。
回查已完成的 Task
bash
curl -X POST https://a2a.objqr.com/a2a/jsonrpc \
-H 'content-type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": "2",
"method": "tasks/get",
"params": { "id": "9332c282-1fa7-4c42-96ac-58e4e2f88f4c" }
}'返回同样的 Task 结构。
注意:Task 记录保存在服务进程的内存里,服务重启后查不到历史 Task。请不要把
tasks/get当成持久化查询接口用——需要留存的结果,请在拿到响应时自己存下来。
失败的返回
失败不是 JSON-RPC 层的错误,仍然返回 result,只是 status.state 为 failed,原因写在 status.message 里:
json
{
"jsonrpc": "2.0",
"id": "9",
"result": {
"kind": "task",
"id": "d091e105-9767-472a-b7e7-5951541cab15",
"status": {
"state": "failed",
"timestamp": "2026-08-12T17:23:56.789Z",
"message": {
"kind": "message",
"role": "agent",
"parts": [{ "kind": "text", "text": "查询失败:码不存在或无法解析" }]
}
}
}
}所以判断成败要看 result.status.state,不能只看 HTTP 状态码或有没有 error 字段。
「码不存在」与「码存在但不可公开」返回的是同一个结果。 这是刻意设计——如果两者可区分,就能被用来枚举探测哪些码存在。对调用方而言,两种情况都等价于「没有可读的公开实体」。
取消
协议支持 tasks/cancel,但草料的三个 skill 都是同步查询,返回时已经结束,实际上没有可取消的窗口。
已知限制
| 限制 | 说明 |
|---|---|
| 不支持流式 | capabilities.streaming 为 false,一问一答 |
| 不支持推送通知 | capabilities.pushNotifications 为 false |
| 不保留状态变更历史 | capabilities.stateTransitionHistory 为 false |
| Task 不持久化 | 服务重启后 tasks/get 查不到 |
| 只读 | 不执行任何写入,操作交由人在 humanUrl 上完成 |
| 不跨组织 | 一次调用只看一个组织范围内的数据 |