← All Posts

我做了一个 Agent 通知小工具

codex&dsh的飞书通知工具

我做了一个 Agent 通知小工具#

项目地址:https://github.com/Suxinljh/agent-message-webhook

为什么要做#

用 AI 编程助手久了,会养成一种很别扭的习惯:一边干自己的事,一边每隔几分钟就切回终端瞄一眼——它跑完了吗?卡住了吗?还是又自作主张改了什么?

有一次我让它分析一个交互式应用插件的边界问题,顺手去忙别的。等我想起来回去看,任务早在两个多小时前就结束了,输出规规矩矩躺在那里,改动文件列得清清楚楚。它不急,急的是我:这两个多小时里,我来回看了不下十几次屏幕。

更难受的是失败的时候。任务半路报错,Agent 就那么安安静静地停着,一点声音都没有。你以为它在埋头苦干,其实现场早就散了。

于是我做了这个小工具:当 Agent 的任务完成、失败,或者整个会话结束时,往我的飞书群里推一张卡片消息。人不在电脑前也没关系,手机震一下就知道战况。它最早是 deepseek-harness 仓库里的一个实验性插件,后来觉得这东西不该被绑死在某一个宿主上,就拆了出来,成了独立项目——agent-message-webhook。

怎么做的#

设计上我只守住了两条线。

第一条是「核心不懂宿主」。不管底下跑的是 DeepSeek Harness 还是 Codex CLI,对通知器来说都一样:给我一段会话摘要和一个状态,我还你一张排版好的卡片。所以代码分成两层——核心层只管配置解析、内容提取和发消息;每个平台单独配一个适配器,负责把自己家的事件翻译成核心认识的样子。以后想接新平台,写个小适配器就行,核心一行不用动。

第二条是「零运行时依赖」。这种小工具,要是装依赖的时间比用它的时间还长,就本末倒置了。所以除了 Node.js 自带的模块,一个第三方包都没有,安装秒完成。

实现里有几个小心思,说出来还挺有意思:

  • 飞书的自定义机器人可以开签名校验,防止别人拿到地址乱发消息。签名用的是 HMAC-SHA256,说穿了就是每次发消息前,用一个只有我和机器人知道的密钥,给消息盖一枚带时间戳的章。
  • 对话记录往往很长,而飞书单条消息有体积上限。超过大约三千八百字,工具会自动把对话拆成几张卡片,一张接一张发出去,标题写着「对话记录 2/3」。
  • 默认只取用户的第一句话和助手的最后一句回答。中间那些模型的思考过程、旁白碎碎念,一律不发——通知是给人看的,不是流水账。
  • Codex 那边没有现成的推送事件,只能盯本地会话文件。可文件是边跑边写的,读到半截的行不能当成新消息,所以做了增量读取;启动时先对已有旧会话做静默基线,不然一开机就把历史记录轰炸一遍;推送到哪儿了记在状态文件里,重启也不会重放。

还有一条原则贯穿始终:通知失败绝不能影响 Agent 干活。所有发送都裹着兜底逻辑,网断了、飞书挂了,主流程该干嘛干嘛。

功能特性#

  • 三种事件通知:任务完成(蓝色卡片)、任务失败(红色卡片)、会话结束
  • 卡片自带摘要、状态、耗时、Token 消耗和修改文件列表
  • 可选附带完整对话记录,超长自动拆分多张卡片
  • 支持 HMAC-SHA256 签名校验
  • 思考过程、过程旁白全部过滤,只留干货
  • 零运行时依赖,Node.js 20 以上即可运行

效果预览与配置图解#

介绍#

Agent 任务完成时,飞书群里会收到这样一张通知卡片(摘要 + 状态 + 对话记录):

DSH 任务完成通知卡片

添加#

在飞书群设置中添加「自定义机器人」:

添加飞书自定义机器人

设置#

在机器人设置页拿到 webhook URL;建议同时开启签名校验,把得到的密钥用作 FEISHU_SIGN_SECRET:

设置飞书自定义机器人

怎么使用#

前置动作只有一步:在飞书群里添加「自定义机器人」,拿到 webhook 地址。建议顺手开启签名校验,把密钥也记下来。两者都通过环境变量注入:

Terminal window
export FEISHU_WEBHOOK_URL='https://open.feishu.cn/open-apis/bot/v2/hook/xxx'
export FEISHU_SIGN_SECRET='xxx'

之后按场景三选一:

挂在 DeepSeek Harness 上。 复制仓库里的 cordis.patch.yml 模板,把里面的路径改成你机器上的实际位置,加载即可。此后 Agent 每轮结束自动上报。

监听 Codex CLI。 一条命令常驻:

Terminal window
npx amw watch-codex

它会盯着 Codex 的会话目录,每轮结束推一条消息,中断的任务按「失败」处理。建议用 launchd 或 pm2 挂在后台。

当库用。 如果你的程序自己管理 Agent 生命周期,也可以直接引用它的几个函数,自己决定什么时候发、发什么。README 里有完整说明和配置表。

注意点#

有几个坑,是我自己踩过、或者在这次开源前的检查里才意识到的:

webhook 地址就是钥匙。 任何拿到这个地址的人,都能往你的群里发消息。所以千万别把它写进代码提交到仓库,走环境变量最稳。万一泄露,去飞书后台删掉机器人重建,一分钟的事。

通知的内容会出网。 任务描述、对话摘录,都会经过飞书的服务器。如果项目涉密或有合规要求,先想清楚再开。工具支持关闭对话区、限制长度,但出不出网这个决定,只能你自己做。

截图和绝对路径是隐私重灾区。 这次公开仓库前我把整个项目扫了一遍,才发现配置示例里留着自己电脑的完整路径,用户名明晃晃写在里面。文档截图更要小心——设置页面里经常藏着头像、组织名这类东西。公开之前,多看一眼总没错。

小工具也要管住自己。 通知这东西,做多了惹人烦。所以它默认只在三个节点开口:任务完成、任务失败、会话结束;子 Agent 的动静默认不报,思考过程默认不发。安静,才让每一次响动都有意义。

写在最后#

它是个很小的工具,解决的是一个很小的烦恼:不用再一遍遍切回终端,充当人肉轮询器。AI 替我们干活之后,「等结果」这件事本身也值得被自动化掉——活儿干完了,吱一声就好。

代码在这里,感兴趣的朋友可以看看:https://github.com/Suxinljh/agent-message-webhook