A2A 长任务之谜:两分钟以上的活为什么老失败
Hermes 消息平台接入第38篇:A2A 长任务超时问题的三重原因与修复。
A2A 长任务之谜:两分钟以上的活为什么老失败
你是不是也遇到过这种情况:让 Agent 去查个资料、跑个研究,结果等了两分钟,它突然跟你说“抱歉,我忘了”或者直接超时?别急着怪 Agent 偷懒,这很可能是 A2A 协议 在背后捣鬼。
先搞懂 A2A 是啥
A2A(Agent-to-Agent)是 Linux 基金会维护的开放协议,专门解决一个核心问题:让不同机器、不同框架的 Agent 互相打电话。你的 Hermes 可以调用别的 Agent,别人也能通过 HTTP 给你的 Hermes 派活。
什么时候用 A2A?记住一句话:跨机器、跨进程、跨框架 才用它。如果只是同一台机器上多个 Agent 协作,用 delegation(进程内子代理)或者 kanban 看板更合适——A2A 是给“异地恋”准备的。
长任务失败的真正原因
很多新手踩的坑是:A2A 默认超时只有 300 秒(5 分钟),但真正的问题往往出在流式响应上。如果你用的是老的 SendMessage 方法,对方 Agent 吭哧吭哧干了两分钟活,中间一个字节都没回,调用方就以为它死了。
新版的解法是 SendStreamingMessage——让 Agent 边干边汇报:“我正在搜索……”“找到了 3 条结果……”。配合 SSE 流式推送,调用方就知道你还活着,不会傻等。
新命令速览
启用 A2A 很简单:
hermes gateway setup # 选 A2A
或者直接改配置 ~/.hermes/config.yaml:
gateway:
platforms:
a2a:
enabled: true
extra:
port: 9900
关键变化:出站工具集 a2a 默认是关闭的,得手动开:
hermes tools enable a2a --platform cli # 命令行用
hermes tools enable a2a --platform telegram # 聊天平台用
hermes tools enable a2a --platform a2a # 让 A2A 任务还能调别的 Agent(链式调用)
长任务防坑三件套
-
用
a2a_orchestrate做扇出:把任务同时发给多个 Agent,谁先回就用谁(first模式),或者等全部回完再汇总(all模式)。适合“让三个研究员分别总结 arXiv,取最好的”。 -
配置
A2A_REPLY_TIMEOUT:默认 300 秒,如果你的任务确实要跑很久,调大它:
A2A_REPLY_TIMEOUT: 600 # 10 分钟
顺带说一句,那个负责清理“孤儿任务”的后台扫描现在会跟着这个超时走:没到时间绝不会把任务判死(最低 300 秒),只要还有调用方在等,也不会动手。所以就算回复姗姗来迟,也会被存下来,而不是被丢掉。
转发到本地 profile 的会话:历史记录不会自动迁移
如果你把 A2A 请求转发给本机的另一个 profile,现在会直接交给该 profile 的 gateway owner 处理,不再有兜底的 hermes chat 进程去写它的会话数据库。新的转发会话会完整记录 agent、tenant、认证对端和 context ID。
历史转发会话光看标题是认不出来的:旧适配器用 a2a-{agent}-{sanitized-context} 命名,丢掉了 peer 和 tenant 身份;会话 JSONL 日志的文件名同样有损,也没留下完整身份。用户消息文本里出现的对端名字,不算归属元数据。
但历史转发会话无法安全识别:旧适配器用 a2a-{agent}-{sanitized-context} 命名,丢掉了 peer 和 tenant 身份,像 ctx/exact 和 ctx-exact 这种不同 context 可能早就共用了同一份记录。所以遇到标题匹配的历史会话,系统会返回 runtime_coordination_required,而不是把对端硬接到可能无关的历史上,也不会悄悄新建替代会话——原会话 ID、标题和消息都保持不动,通用 CLI resume 也绕不过这个拒绝。
目前不支持自动迁移这些历史转发会话。 恢复需要本地 owner 明确决定会话到 agent/tenant/peer/context 的绑定(尤其是已经混在一起的记录),还要明确启动策略——历史行可能保留了模型和部分参数,但原始 cwd、system prompt 和冻结的工具/配置策略已经没了。标题匹配或当前 profile 配置都补不回旧写入器从未存下的信息。目前没有受支持的迁移命令,也别靠改标题或编辑数据库行来绕过归属检查。
- 开推送通知:长任务跑完主动推给你,不用干等。用
A2A_PUSH_SECRET做 HMAC 签名,安全。
安全模型:默认锁死,手动开锁
新版强调 secure by default:
- 没配 token 就只监听
127.0.0.1,外部根本连不上 - 想对外开放?必须配 bearer token 和
A2A_HOST - 每个对端可以单独配 token(
A2A_PEER_TOKENS="alice:tok1,bob:tok2"),谁是谁清清楚楚 - 防注入:远程 Agent 的消息会被标记为“不可信输入”,不能触发你的斜杠命令
- 防死循环:默认 5 轮对话上限,防止两个 Agent 互相 ping-pong 到天荒地老
快速验证
# 从另一台机器测试你的 Agent 是否在线
curl http://your-host:9900/.well-known/agent-card.json
能看到 Agent Card 就说明服务活着。然后试试:
curl -X POST http://your-host:9900/ \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"SendStreamingMessage","params":{"message":{"role":"user","parts":[{"text":"你好"}]}},"id":1}'
小结
长任务失败不是玄学,多半是没开流式或者超时太短。记住:用 SendStreamingMessage 替代 SendMessage,按需调大 A2A_REPLY_TIMEOUT,复杂任务用 a2a_orchestrate 扇出。下次再遇到两分钟以上的活,先检查这三样,基本都能解决。
📖 官方文档
本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/messaging/a2a