Agent 跑了两小时,你一无所知:长程任务的人机通信协议

Designing the Communication Layer Between Humans and Long-Running Agents

上周,一个 FDE 给我发了条消息:「我让 Agent 帮我做一份竞品分析,它说『好的,我开始处理』,然后就消失了。两个小时后我实在忍不住,去群里问『你还在跑吗』,它回了句『是的,还在处理中』。又过了半小时,终于出来了——结果质量不错,但这两个半小时里我完全不知道它在干嘛、做到哪了、有没有卡住。」

这个场景太常见了。而且它暴露了一个大多数 Agent 平台都没认真对待的问题: 长程任务的人机交互设计

不是模型能力的问题,不是工具调用的问题——是 **通信协议 **的问题。Agent 和人之间,缺少一套关于「什么时候说话、说什么、怎么说」的共识。

四层通信协议:心跳/里程碑/异常/交付

两个极端,都不对

目前大多数 Agent 在长程任务上的交互,要么是 太吵,要么是 太静

太吵:每一步都汇报。Agent 拉了一个 API 发一条消息,读了一个文件发一条消息,写了一段分析又发一条消息。群里消息刷屏,人类很快就疲劳了——开始忽略,真正重要的信号反而被淹没。这和那种每小时给你发一封「系统运行正常」邮件的监控系统一样,除了制造噪音没有任何价值。

太静:Agent 闷头干了半天,人类不知道它在做什么、做到哪了、有没有卡住。直到最后出结果(或者超时),人类才有感知。这跟把一个实习生扔在角落干活、三天后才来问进度一样危险。你没法管理一个你看不见的过程。

这两种极端背后是同一个设计缺陷: 没有把「通信」当成一个需要被设计的独立层。大多数开发者把 Agent 的消息输出当作推理过程的副产品——它在想什么就说什么,想完了就不说了。但长程任务的通信不是副产品,它是一个 独立的工程问题,需要自己的协议。

四层通信协议

我把长程任务的人机通信拆解为四层,每层有不同的频率、语义和人类预期:

名称频率人类预期目的
L1心跳每 10-30 分钟可忽略让人知道 Agent 还活着
L2里程碑关键节点可能需要确认阶段性进展 + 是否需要人介入
L3异常即时必须响应阻塞性问题 + 可选方案
L4交付任务结束时需要审核结构化成果 + 反馈入口

这四层不是 Agent 「自己决定要不要发」——它们是被协议规定的。就像 TCP 协议规定了 SYN、ACK、FIN 的顺序一样,长程任务的通信也有自己的「握手」和「挥手」。

L1:心跳——「我还活着」

心跳的目的是消除 存在性焦虑——人类不确定 Agent 是否还在工作时的焦虑。

心跳消息的特征:

  • 极简:一句话,不展开
  • 有进度:当前百分比或阶段
  • 可忽略:人类看了不回也没关系
  • 低频:每 10-30 分钟一次,不是每分钟

「📊 竞品分析进行中,已完成 5/8 个竞品,预计还需 25 分钟。」

心跳 不应该是 Agent 推理过程的自然输出。Agent 在推理过程中会产生大量中间状态——调了什么 API、读了什么文件、做了什么判断。这些是日志,不是心跳。心跳是一个 工程化的定时摘要,由 Harness 层控制频率和内容,不交给模型自己决定。

L2:里程碑——「到这一步了,需要你确认」

当任务到达一个有意义的阶段性成果时,Agent 发一条结构化的更新,并 明确告诉人是否需要介入

「✅ 已完成:从三个数据源拉取了 47 条竞品信息,识别出 3 条数据冲突。

⏳ 下一步:生成对比分析初稿。

❓ 需要你确认:这 3 条冲突数据,用 A 源还是 B 源?」

里程碑消息的特征:

  • 有结构:已完成什么 + 下一步做什么 + 是否需要人介入
  • 有判断:Agent 不是把所有决策都丢给人,而是自己判断了哪些需要确认
  • 有选项:如果需要人决策,给出明确的选项,不是开放式提问

这里有一个微妙的设计原则: 里程碑应该是「有意义的人类可理解节点」,不是 Agent 内部的工程节点。 「已完成 API 调用」不是里程碑,「已完成数据采集,发现 3 条异常」才是。人类不关心 Agent 调了几个 API,关心的是「做到哪一步了,有没有问题」。

L3:异常——「出问题了,这里有方案」

当任务遇到阻塞性错误时, 立即通知,不等下一次心跳。

「⚠️ 任务中断:竞品 C 的官网返回 403,无法获取定价页面。

已尝试:直接访问 2 次,换 User-Agent 1 次,均被拒绝。

影响:竞品 C 的定价数据缺失,分析报告将不完整。

建议:

  1. 跳过竞品 C,报告中注明数据缺失
  2. 你提供竞品 C 的定价截图或文档
  3. 等 30 分钟后重试(可能是临时限流)

请回复 1/2/3,或告诉我其他方案。」

异常消息的特征:

  • 即时:不等到下一次心跳
  • 透明:说清楚试过了什么、为什么失败
  • 有方案:给出 2-3 个可选项,不只报问题
  • 可恢复:人选一个方案,Agent 继续执行

L4:交付——「做完了,这是成果」

任务完成时,不是简单发一句「完成了」,而是交付一个 结构化的成果

「📋 竞品分析报告已完成

摘要:覆盖 8 个竞品,核心差异在定价模式和 API 限额。我方在 API 灵活性上有优势,定价处于中等偏上。

完整报告:[查看文档]

需要你关注

  • 竞品 D 上周刚降价 20%,可能影响下季度策略
  • 竞品 F 的 API 限额数据来自第三方评测,非官方数据

👍 报告有用 / 👎 需要调整(反馈让下次报告更准确)」

交付消息的特征:

  • 摘要先行:不让人打开文档才知道结论
  • 有链接:完整内容放在文档里,消息里只放摘要
  • 有行动项:哪些事需要人类关注或决策
  • 有反馈入口:让协同飞轮转起来

实现层的三个关键设计

协议定义了「该发什么」,但怎么发、在哪发、怎么不打扰,是另一层问题。

设计一:卡片原地进化,不追加消息

长程任务最大的交互杀手是 刷屏。一个跑了两小时的任务,如果每个心跳、每个里程碑都发一条新消息,群里很快就被淹没。

AI 原生的解法是 卡片原地进化——一条消息,随着任务进展不断更新内容。

┌─────────────────────────────────────────┐
│  🤖 竞品分析 Agent                       │
│                                          │
│  状态:运行中 ██████████░░░░ 62%          │
│  耗时:1h 24m                            │
│                                          │
│  ✅ 数据采集(8/8 竞品)                  │
│  ✅ 数据清洗(3 条异常已处理)             │
│  🔄 对比分析(进行中...)                 │
│  ⬜ 报告生成                              │
│  ⬜ 交付审核                              │
│                                          │
│  [查看实时日志]  [暂停]  [取消]            │
└─────────────────────────────────────────┘

任务开始时发出这张卡片。之后的每一次心跳、每一个里程碑,都是 更新这张卡片——状态变了、进度变了、阶段变了,但始终是同一条消息。人类看到的永远是最新状态,不会被历史消息淹没。

任务完成时,这张卡片变成:

┌─────────────────────────────────────────┐
│  🤖 竞品分析 Agent                       │
│                                          │
│  状态:✅ 已完成                          │
│  耗时:2h 11m                            │
│                                          │
│  ✅ 数据采集(8/8 竞品)                  │
│  ✅ 数据清洗(3 条异常已处理)             │
│  ✅ 对比分析                              │
│  ✅ 报告生成                              │
│  ✅ 交付审核                              │
│                                          │
│  摘要:覆盖 8 个竞品,核心差异在定价和限额  │
│                                          │
│  [查看完整报告]  [👍 有用]  [👎 需调整]    │
└─────────────────────────────────────────┘

一张卡片承载了一个任务的完整生命周期。 这就是 AI 原生的交互范式——不是聊天范式里的一条条消息,而是一个有状态的、可交互的任务界面。

钉钉的交互卡片(ActionCard)天然支持这个模式:发一张卡片,后续通过 API 更新卡片内容,人类看到的就是最新版本。

设计二:空闲看门狗——区分「卡死」和「正常的慢」

心跳层有一个隐藏的难题:Agent 跑了很久没发消息,到底是「正在正常处理一个复杂步骤」,还是「已经卡死了」?

如果用固定时间(比如 30 分钟没消息就报警),会误杀正常的长任务——有些分析任务就是要跑很久。如果完全不设超时,卡死的 Agent 会永远挂着。

解法是 空闲看门狗(idle watchdog)——不看墙钟时间,看 活动信号

Agent 还在持续产出事件(消息、工具调用、文件读写)
    → 正常运行,不干预

Agent 超过 N 分钟无任何活动信号
    → 判定为卡死,触发异常通知

Agent 的某个子进程卡住(比如一个 API 调用 hang 住)
    → 工具看门狗兜底,超时终止子进程

这三层超时机制让系统能区分三种状态:

  • 正常的慢:Agent 在持续工作,只是这一步需要时间
  • 静默卡死:Agent 进程在,但不再产出任何信号
  • 工具卡死:Agent 在等一个子任务(API 调用、文件处理),子任务 hang 住了

空闲看门狗的结果会体现在 L3(异常层):

「⚠️ Agent 已 30 分钟无活动信号。 最后动作:调用 CRM API 获取客户列表。 建议:1) 重启任务 2) 查看日志 3) 跳过此步骤」

设计三:多任务合并心跳

当 Agent 同时在跑多个任务时,心跳不应该每个任务各发一条——那又变成了刷屏。

正确做法是 合并心跳

┌─────────────────────────────────────────┐
│  🤖 Agent 运行状态                       │
│                                          │
│  📊 竞品分析    ██████████░░ 62%  预计25m │
│  📋 周报生成    ████████████ 完成  待审核  │
│  📧 客户跟进    ⏸️ 等待 API 恢复          │
│                                          │
│  [展开详情]                               │
└─────────────────────────────────────────┘

一张卡片,所有任务的当前状态一目了然。只有异常(API 恢复)和需要人介入(待审核)的任务才高亮。

协议层的设计原则

把四层通信 + 三个实现设计放在一起,可以提炼出五条原则:

原则一:不打扰。 心跳要低频可忽略,不是每步都汇报。人类注意力的成本比 token 贵得多。

原则二:不隐身。 里程碑要让关键进展可见。管理的前提是可见性——你管不了一个你看不见的过程。

原则三:不等待。 异常要立即通知,不攒到下次心跳。阻塞性问题的响应时间和「下一次心跳还有多久」不应该耦合。

原则四:不甩锅。 需要人决策时给选项,不给开放式问题。Agent 把问题抛给人类的同时,应该把已尝试的方案和可选的下一步一并给出。

原则五:不浪费。 结束时交付结构化成果 + 反馈入口。任务的最后一个动作不是「发一条消息说完成了」,而是交付一个人类可以审核、反馈、迭代的结构化产物。

「什么时候通知」不是推理问题,是设计问题

最强的反方观点可能是:Agent 足够聪明后,可以自己判断什么时候该通知人。不需要硬编码四层协议——让模型自己决定就好。

这个想法听起来合理,但它忽略了一个关键事实:「什么时候通知人」不是一个推理问题,是一个组织设计问题。

不同的人需要不同频率的通知。VP 只想看最终交付;运营主管想看每个里程碑;FDE 想看每一步的细节。同一个任务,对不同的人,四层通信的频率和内容应该完全不同。

不同时间段的通知价值也不同。凌晨三点的异常通知可以攒到早上;下午两点的异常需要立即响应。

这些判断——谁需要知道什么、什么时候需要知道——不是模型能从上下文推理出来的。它取决于组织结构、角色分工、时间上下文,这些信息不在 Agent 的推理窗口里。

所以正确的做法是: 通信协议由 Harness 层实现,不由模型决定。 Harness 负责控制频率、格式化内容、路由到正确的人。模型只负责产出推理结果,Harness 决定哪些结果以什么形式、在什么时间、发给谁。

这也是我在 用完备的 Harness 工程实现 AI 原生协同 中反复强调的:Harness 不是模型的辅助,Harness 是生产环境的骨架。通信协议就是骨架中最关键的一根——它决定了人和 Agent 之间的信任能否建立。

从聊天范式到任务通信范式

回到开头那个 FDE 的体验。

他的 Agent 做了两个半小时的竞品分析,质量不错。但过程中的通信是零——一句「好的,我开始处理」之后就消失了。这不是 Agent 能力的问题,而是 它没有通信协议

如果它有四层通信:

  • 每 20 分钟一次心跳(卡片原地更新进度)
  • 数据采集完成时发一个里程碑(发现 3 条数据冲突,需要确认)
  • 竞品 C 官网 403 时发一个异常(给三个可选方案)
  • 完成时交付一个结构化报告(摘要 + 链接 + 反馈入口)

同样的两个半小时,体验完全不同。人类不会焦虑,不会被刷屏,在需要决策的时候被精准触达,在完成时拿到可审核的成果。

这就是从「聊天范式」到「任务通信范式」的迁移。

聊天范式的假设是:人和 Agent 在对话,每一轮交互都是同步的、即时的。这个假设对短任务成立(问一个问题、写一段文字),对长程任务不成立。

任务通信范式的假设是:Agent 在执行一个有状态的过程,人在监督这个过程。通信的目的不是「对话」,而是 让人以最小成本保持对任务的掌控感

这个迁移不是锦上添花——它是生产型 Agent 从 Demo 走向真正可用的前提条件。在 数字员工驱动的工作流 中,我说过工作流的主语从人变成了 Agent。主语变了之后,通信协议也必须跟着变——因为人不再是每一步的执行者,而是监督者和决策者。监督者需要的不是对话,是 信号

你的 Agent,有通信协议吗?


你在实际使用 Agent 做长程任务时,最困扰你的交互问题是什么?欢迎留言讨论。


See also