🤖HermesBlog
Hermes 消息平台接入 · 第38篇2026/8/14· Easy Understand Hermes Agent

A2A 长任务之谜:两分钟以上的活为什么老失败

Hermes 消息平台接入第38篇:A2A 长任务超时问题的三重原因与修复。

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(链式调用)

长任务防坑三件套

  1. 用 a2a_orchestrate 做扇出:把任务同时发给多个 Agent,谁先回就用谁(first 模式),或者等全部回完再汇总(all 模式)。适合“让三个研究员分别总结 arXiv,取最好的”。

  2. 配置 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 配置都补不回旧写入器从未存下的信息。目前没有受支持的迁移命令,也别靠改标题或编辑数据库行来绕过归属检查。

  1. 开推送通知:长任务跑完主动推给你,不用干等。用 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