Appearance
内部广播管道的三个可靠性坑
第二部 · Agent 实践 · 第28章
撰写日期:2026-07-10
结论
"知识库上新了就往群里播报一条"听上去是个一次性脚本,但真正把它做成长期在线的管道后,我发现它的难点全在可靠性边缘:重复发、发错格式、发出真名。对一个十人量级的群,一次错误广播的成本远比想象中高——它直接消耗全员对这个通道的信任。
广播管道的核心不是"能发出去",而是"不会发错、不会重发、发错了能撤回"。这三件事必须做在按下发送键之前。
1. 幂等:无锁并发会发重
最隐蔽的坑是重复广播。当"检查有没有新内容 → 发送"这一对动作没有原子性保护时,两次调度(定时轮询 + 手动触发、或两个 worker)可能同时判定"这篇还没播过",于是发两遍。尤其是把待发队列一次性 flush 出去这类操作,若没有锁,并发下几乎必然发重。
修法不能靠"团队会自动忽略重复",得靠机制:
| 手段 | 说明 |
|---|---|
| 去重锁 | 以内容 ID(+ 时间窗)为键,发送前先抢锁,抢不到就跳过 |
| 已发标记 | 发送成功后立刻持久化"已播报"状态,后续调度先查这个标记 |
| 单次语义 | 每篇只播一次,后续编辑不再触发(避免"改个错字又全员通知") |
2. 格式校验:平台的枚举字段会静默拒收
往 IM / 卡片接口发结构化消息时,很多字段(标签、颜色、模板 key)是平台侧的枚举,传了不在白名单里的值,接口可能整条拒收或降级成难看的兜底样式。生成内容的模型并不知道平台白名单,很容易编出一个"看起来合理但不存在"的标签。
所以生成和发送之间要有一道校验层:把模型产出的枚举字段对着平台允许值核一遍,不合法就改写或回退到安全默认值,再发送。原则和注意力路由里那条一致——模型输出里每一个受约束的字段,都需要一个代码层守门员。
3. 脱敏:对外广播的真名默认要处理
广播天然是外扩动作,内容可能被更多人看到、被归档、被其他系统消费。真名在这种通道里就是隐私风险。做法是双保险:生成阶段用昵称/角色替代,发送阶段再过一遍脱敏校验,两道都不放过。
4. 撤回:发错了要能收回
即便前三道都做了,仍会有漏网的错误广播,所以管道要预留撤回能力。经验是:撤回依赖发送时返回的平台消息 ID 和有撤回权限的 bot 凭证——这两样必须在发送时就记录下来,否则事后想撤都定位不到那条消息。把"记录消息 ID"作为发送流程的一部分,而不是等出事才想起来。