Agent 任务¶
任务表示一次可持续运行、可观察的 Agent 执行。发送消息后,调用方应保存 Task id 和 contextId,并根据 status.state 驱动界面与后续操作,而不是把 HTTP 请求结束视为任务结束。
Task 结构¶
Task 的字段会随 Agent 和 A2A 协议版本扩展。客户端通常需要关注:
{
"kind": "task",
"id": "task_123",
"contextId": "ctx_123",
"status": {
"state": "working"
},
"artifacts": []
}
字段 |
客户端用途 |
|---|---|
|
查询、取消和重新订阅时使用的稳定 Task 标识 |
|
后续用户消息继续同一上下文时使用 |
|
当前生命周期状态 |
|
与本次状态相关的可选消息;按 Part 解析 |
|
Agent 已产生的文本或结构化产物 |
|
Agent 提供时的消息或状态历史 |
常见状态包括 working、input-required、completed、failed 和 canceled。客户端必须容忍未知状态,不能把未识别的值当作成功。completed、failed 和 canceled 可作为终态;input-required 表示当前执行暂停等待用户,而不是失败。
查询 Task¶
使用 tasks/get 读取最新状态。params.id 是 Task ID,不是 JSON-RPC 请求 ID:
{
"agent_code": "explore",
"jsonrpc": "2.0",
"id": "req_task_get_01",
"method": "tasks/get",
"params": {
"id": "task_123"
}
}
查询时必须使用创建该 Task 时相同的 Agent 选择器。Task ID 本身不负责把请求路由到正确的 Agent。
如果应用没有使用流式调用,可以在 Task 仍为非终态时轮询:
import time
while True:
task = call_a2a("tasks/get", {"id": task_id})["result"]
state = task["status"]["state"]
if state in {"completed", "failed", "canceled"}:
break
if state == "input-required":
show_requested_input(task)
break
time.sleep(2)
call_a2a 在此表示应用对 POST /newmoi/agents/a2a 的封装,并非当前官方 Python SDK 的方法。生产环境应增加整体截止时间、指数退避和随机抖动,避免大量 Task 以固定频率同时轮询。
取消 Task¶
tasks/cancel 请求服务端停止 Task:
{
"agent_code": "explore",
"jsonrpc": "2.0",
"id": "req_task_cancel_01",
"method": "tasks/cancel",
"params": {
"id": "task_123"
}
}
取消是一次状态转换请求,不保证能撤销已经完成的外部副作用。收到取消响应后,应读取返回的 Task 状态;如果调用结果不明确,再用 tasks/get 核实。不要因为本地用户关闭页面就假定服务端 Task 已取消。
重新订阅事件¶
流式连接在 Task 到达终态前中断时,使用 tasks/resubscribe 恢复事件。它与查询、取消的参数名不同:
{
"agent_code": "explore",
"jsonrpc": "2.0",
"id": "req_task_resubscribe_01",
"method": "tasks/resubscribe",
"params": {
"taskId": "task_123",
"afterSeq": 12
}
}
taskId指定要恢复的 Task。afterSeq是客户端已完整处理并持久化的最后一个 SSEid。响应仍是
text/event-stream,解析方式与message/stream相同。
只有在事件对应的本地状态已经持久化后,才能推进保存的序号。这样进程若在写入中途崩溃,可以安全地从较早序号重放。消费者还应按事件序号或业务事件标识去重,因为网络恢复可能带来重复投递。
如果从未收到有效事件,可以省略 afterSeq;具体保留时长由服务端配置决定,客户端不能假定 Task 事件会永久保留。重新订阅失败后,先用 tasks/get 确认最新 Task 状态,再决定提示用户、重新执行或人工排查。
处理 input-required¶
当状态变为 input-required 时,从状态消息或相关 Artifact 中读取 Agent 提出的问题,并在 UI 中明确展示可选项和上下文。用户作答后,发送一条新的普通 A2A 用户消息,并复用该 Task 的 contextId:
{
"kind": "message",
"role": "user",
"messageId": "msg_answer_01",
"contextId": "ctx_123",
"parts": [
{
"kind": "text",
"text": "将结果保存到知识库"
}
]
}
当前通用入口没有在本文档中承诺独立的“恢复 Task”SDK 方法。继续执行仍走 message/send 或 message/stream;不要自行构造未确认的输入提交方法。
持久化与运维建议¶
将 Agent 选择器、Task
id、contextId、状态、最后事件序号和业务记录关联保存。状态更新应满足幂等性;迟到或重复事件不能让终态回退到
working。取消、失败和超时分别记录。客户端超时不代表服务端 Task 已失败。
Artifact 可能包含较大的结构化数据。按类型投影,限制日志大小,并遵守工作区的数据访问规则。
排查时先核对 JSON-RPC
id与 Taskid是否混用,再检查 Agent 选择器、鉴权、最后事件序号和终态事件。
返回消息查看建流和 SSE 解析示例。