Agent

OpenClaw 工具调用进度推到飞书

一个 9KB 的 OpenClaw 插件。把 agent 的多步工具调用进度推送到飞书可更新交互卡片——不用轮询、不用猜 agent 卡哪了。

OpenClaw 工具调用进度推到飞书 封面

起因

我日常重度使用飞书,agent 的工作也基本都在飞书里跑。有一天 agent 在跑一个多步任务,我盯着飞书聊天窗,等了快一分钟,不知道它是在执行任务还是卡住了

回 OpenClaw 日志一看——agent 在 web_search 后面又调了三次 web_fetch,每次 5-10 秒。整个过程完全静默,我这边只能干瞪眼。

理论上,OpenClaw 的 before_tool_call / after_tool_call 钩子给了完美的信号,可问题是没有可观察的出口。我不是要写一份事后报告,我想要的是实时的可视化进度

这个插件解决的问题

feishu-progress-card 是 OpenClaw 的一个纯 SDK 插件(没改 OpenClaw 一行代码),它做三件事:

  1. 新消息进来时,在飞书里发一张 🤖 任务进度 · 🟡 进行中 的卡片
  2. 每个工具调用(开始/结束/失败),原地更新同一张卡片,不刷屏
  3. agent 跑完,切到 ✅ 已完成(或 ❌ 失败),把折叠面板里的”执行内容”留在那里供你回看

效果长这样(直接搬的实拍卡片):

🤖 任务进度 · 🟡 进行中
─────────────────────
阶段:🔧 正在调用 web_search
工具调用:2次
已耗时:20s
─────────────────────
📋 执行内容 (2) · 点击展开
─────────────────────
来自 feishu-progress-card 插件

展开折叠面板就能看到刚才那次工具调用的参数预览(敏感字段如 secret / token / api_key / app_id自动脱敏)。

它不是另一个 status bar

我看过 openclaw 把一些工具进度塞进日志、控制台或者独立的 web UI。问题是:你已经盯着飞书了,为什么还要切出去看?

feishu-progress-card 把进度直接送到你正在用的对话里。而且是用飞书原生交互卡片(不是文本不是图片),能折叠、能持续更新、不会污染你的对话流。

几个我特别在意的设计:

  • 节流 1 秒 + 心跳 5 秒——agent 在 5 秒内连续调三个工具,卡片只会更新一次;调完了但 agent 还在思考,发”心跳”保活(“思考中…”),避免飞书的”卡片过期”提示
  • emitChain 按 runId 串行化——同一 run 内的 emit 排队,避免在卡片 PATCH 之前 send 抢到 messageId
  • 失败/超时有专门的状态色(❌ 红色 / ⚠️ 黄色),不是默默混在”已完成”里
  • 重启网关的时候,未完成的 run 会被自动 sweep 成 ✅ 已完成(gateway 重启),不会留下”幽灵”卡片永远停留在进行中

安装

一行命令 + 改两段 openclaw.json

openclaw plugins install ./feishu-progress-card-0.1.0.tgz

openclaw.json

{
  "channels": {
    "feishu": {
      "appId": "cli_xxxxxxxxxxxxxxxx",
      "appSecret": "***"
    }
  },
  "plugins": {
    "entries": {
      "feishu-progress-card": {
        "enabled": true,
        "hooks": { "allowConversationAccess": true }
      }
    }
  }
}

飞书应用凭据(appId / appSecret)按你自己的方式在 channels.feishu 配,任何已有的飞书应用都行,这个插件不挑。

重启 gateway 之后,给 agent 发一条会调工具的消息(“查杭州天气”、“执行 exec sleep 3” 都行),飞书里第一件事就该看到那张 🤖 任务进度 卡片。

实际效果

我装了它之后,再也没有盯着空白聊天窗焦虑过。agent 一开工我就看到卡片跳动,工具一次一次调,参数在折叠面板里清晰展开,最后一切到 ✅ 已完成。整个对话流没有一条”中间报告”消息,只有一张始终在那里的卡片。

特别是长任务(比如跑 5 分钟的代码分析、多步爬虫、批量模型生成),效果最明显:你可以放心去倒杯水,回来扫一眼卡片就知道走到第几步了。

一些技术细节

  • OpenClaw 钩子message_received / before_tool_call / after_tool_call / agent_end
  • 状态持久化~/.openclaw/feishu-progress-card.state.json(runId → messageId 映射,重启后能 sweep)
  • 飞书 APItenant_access_token 缓存 2h,发卡用 im/v1/messages,更新用 PATCH /im/v1/messages/{id}
  • 大小index.js ~25KB,没依赖任何第三方 npm 包(只用了 Node 内置 fs / path

仓库

如果有 bug,或者只是觉得卡片哪里能再好看一点,交给你的openclaw吧,它可以做好。