文章来源说明:本文由 ZeroOne AI 整理发布,官网与 CSDN 双端同步首发,原文见 www.zeroone-ai.com。
一、问题背景
在企业智能体应用中,可以将"小龙虾"接入飞书,让员工直接在飞书群中与智能体交流。
例如:
用户:
@小龙虾 查询LA生产线当前设备状态
小龙虾:
LA生产线当前共有11台设备在线,设备运行正常。
但是实际部署过程中,经常出现一个非常典型的问题:
小龙虾可以向飞书群发送消息,也可以通过接口查询飞书消息,但是用户在飞书外部群中 @小龙虾 后,小龙虾没有任何响应。
这个问题容易被误认为是:
- AI模型故障
- MCP故障
- Token失效
- 网络故障
- 飞书API故障
实际上,最需要检查的是:
飞书是否把实时消息事件发送给了小龙虾。
二、先理解飞书与小龙虾的两条通信链路
飞书和小龙虾之间实际上存在两个方向。
1. 小龙虾主动发送消息
小龙虾 │ │ HTTP API ▼ 飞书 Open API │ ▼ 飞书群例如小龙虾主动通知:
LA-01设备发生报警,请及时处理。
这个方向正常,只能说明:
小龙虾 → 飞书的通信正常。
2. 飞书主动通知小龙虾
用户在群里发送:
@小龙虾 查询设备状态
通信方向变成:
飞书群 │ ▼ 飞书事件系统 │ ▼ Webhook │ ▼ 小龙虾这个方向属于:
飞书 → 小龙虾如果这一条链路没有建立,那么小龙虾当然不会响应。
因此:
能够发送消息,并不能证明能够接收消息。
这是排查问题时最重要的认识。
三、正确的整体架构
小龙虾与飞书推荐采用事件驱动架构:
飞书 │ 飞书外部群 │ │ @小龙虾 ▼ 飞书事件订阅服务 │ │ HTTPS POST ▼ 公网 Webhook │ ┌──────┴──────┐ │ │ Nginx FRP │ │ └──────┬──────┘ ▼ 小龙虾 Gateway │ ▼ 消息事件解析 │ ▼ 小龙虾 Agent │ ▼ 飞书 Reply API │ ▼ 飞书群其中最重要的是:
飞书事件订阅 ↓ Webhook ↓ 小龙虾 Gateway四、为什么外部群特别容易出现问题?
飞书内部群和外部群并不是完全相同的使用场景。
内部群通常是:
企业员工 + 机器人而外部群可能是:
企业员工 + 客户 + 供应商 + 其他企业用户 + 机器人因此,在测试小龙虾时:
内部群正常,并不一定意味着外部群正常。
需要特别确认机器人应用是否支持加入外部群,以及相关消息事件是否允许触发。
五、第一步:检查飞书事件订阅
进入飞书开放平台,找到小龙虾对应的应用。
检查:
应用 ↓ 事件订阅确认已经配置事件订阅。
核心是让飞书知道:
群里发生消息以后,应该把消息发送到哪里。
例如:
https://xxx.example.com/feishu/event这个地址就是小龙虾的消息入口。
六、第二步:检查消息接收事件
仅仅配置机器人还不够。
需要订阅消息接收事件。
重点检查:
im.message.receive_v1它负责将飞书中的相关消息事件发送给机器人后台。
完整链路:
用户 ↓ 飞书群 ↓ @小龙虾 ↓ im.message.receive_v1 ↓ Webhook ↓ 小龙虾如果没有订阅这个事件:
飞书群 ↓ @小龙虾 ↓ 小龙虾中间没有消息事件传递,小龙虾自然不会响应。
七、第三步:检查机器人权限
需要检查飞书应用的权限配置。
重点关注:
消息 机器人 事件订阅 群聊特别是消息接收相关权限。
修改权限后,还需要注意一个经常被忽略的问题:
权限修改不代表线上应用马上使用了新权限。
通常需要:
修改权限 ↓ 创建应用版本 ↓ 发布版本 ↓ 重新测试如果只是修改了配置,没有发布新的应用版本,实际运行的机器人可能仍然使用旧配置。
八、第四步:检查Webhook地址
如果小龙虾部署在本地服务器:
192.168.20.100:8000不能直接把:
http://192.168.20.100:8000/feishu/event作为飞书事件地址。
因为飞书服务器位于公网。
正确方式应该是:
飞书 │ │ HTTPS ▼ 公网服务器 │ │ FRP ▼ 工厂服务器 │ ▼ 小龙虾例如:
https://claw.example.com/feishu/event公网服务器再通过 FRP 转发:
公网服务器 ↓ 192.168.20.100:8000九、第五步:最关键的测试——Webhook有没有收到消息?
不要一开始就测试AI。
先测试:
小龙虾到底有没有收到飞书消息。
例如使用 FastAPI 建立一个简单Webhook:
from fastapi import FastAPI, Requestapp = FastAPI()
@app.post("/feishu/event") async def feishu_event(request: Request): data = await request.json() print("========== FEISHU EVENT ==========") print(data) return { "code": 0 }
启动:
python server.py然后在飞书外部群:
@小龙虾 测试
观察服务器日志。
十、如果完全没有收到日志
如果服务器没有任何:
FEISHU EVENT那么可以确定:
问题还没有到小龙虾Agent。
应该检查:
飞书 ↓ 事件订阅 ↓ Webhook URL ↓ HTTPS ↓ 公网服务器 ↓ Nginx ↓ FRP ↓ 小龙虾建议逐层测试。
首先从公网服务器测试:
curl https://claw.example.com/feishu/event再检查 Nginx:
systemctl status nginx检查 FRP:
systemctl status frpc最后检查小龙虾:
8000端口是否监听十一、如果Webhook已经收到消息
假设日志已经出现:
========== FEISHU EVENT ==========说明:
飞书 ↓ Webhook ↓ 小龙虾已经正常。
此时问题就进入下一层:
Webhook ↓ 消息解析 ↓ Agent十二、外部群消息中的@信息需要正确解析
用户发送:
@小龙虾 查询LA设备状态
飞书事件中的消息内容可能包含机器人提及信息。
因此不能简单地:
content = message["content"]然后直接发送给AI。
需要进行:
消息解析 ↓ 识别机器人是否被@ ↓ 删除@机器人标记 ↓ 提取真正的问题最终得到:
查询LA设备状态然后:
查询LA设备状态 ↓ 小龙虾 Agent十三、建立统一的消息处理流程
推荐小龙虾不要让Webhook直接调用AI。
采用:
Feishu Webhook ↓ Message Parser ↓ Message Router ↓ Agent ↓ Reply例如:
async def handle_feishu_message(event): message = parse_feishu_message(event) if not message: return if not message.is_mention_bot: return question = message.text.strip() if not question: return answer = await agent.ask(question) await feishu_reply( message_id=message.message_id, content=answer )这样结构更加清晰。
十四、回复应该关联原始消息
用户:
@小龙虾 查询LA设备状态
飞书事件中会携带消息ID。
小龙虾应该保存:
message_id chat_id sender_id然后根据:
message_id回复。
流程:
用户消息 │ │ message_id ▼ 小龙虾 │ ▼ AI处理 │ ▼ Reply message_id │ ▼ 飞书这样能够保证回复与用户问题对应。
十五、增加完整日志
解决智能体"不响应"问题时,日志非常重要。
建议至少记录:
[FEISHU] Event Received [FEISHU] event_type=im.message.receive_v1 [FEISHU] chat_id=oc_xxxxx [FEISHU] message_id=om_xxxxx [FEISHU] mention_bot=true [FEISHU] text=查询LA设备状态 [AGENT] Start [AGENT] Response Success [FEISHU] Reply Success如果出现:
[FEISHU] Event Received但没有:
[AGENT] Start说明消息解析或路由出现问题。
如果有:
[AGENT] Start但没有:
[FEISHU] Reply Success说明回复阶段出现问题。
这样可以快速确定故障位置。
十六、增加消息Trace ID
进一步可以给每条飞书消息增加一个 Trace ID:
FEI-20260904-000001例如:
[FEI-20260904-000001] Event Received [FEI-20260904-000001] Parse Message [FEI-20260904-000001] Agent Start [FEI-20260904-000001] Agent Success [FEI-20260904-000001] Feishu Reply Success以后出现:
为什么小龙虾没有回复?
只需要搜索:
FEI-20260904-000001就可以完整查看一次请求。
十七、最常见的故障与解决方法
现象 | 可能原因 | 解决方法
--- | --- | ---
可以发消息,不能收消息 | 未配置事件订阅 | 开启消息事件
内部群正常,外部群不响应 | 外部群权限/机器人能力限制 | 检查外部群支持
飞书事件没有进入服务器 | Webhook不可访问 | 检查公网HTTPS
Webhook没有日志 | Nginx/FRP问题 | 检查网络转发
收到事件但Agent不工作 | 消息解析失败 | 检查@机器人解析
Agent执行了但没有回复 | Reply API失败 | 检查Token和message_id
修改权限后仍不工作 | 新版本未发布 | 发布应用版本
偶尔重复回复 | 没有消息幂等 | 根据message_id去重
十八、推荐的小龙虾飞书Gateway
最终可以把飞书连接独立成一个:
Feishu Gateway结构:
飞书 │ ▼ Feishu Gateway │ ┌──────────┼──────────┐ │ │ │ Event Parser Reply Receive │ │ │ └──────────┼──────────┘ ▼ 小龙虾AgentGateway只负责:
接收飞书事件 解析消息 识别@机器人 提取用户问题 调用Agent 回复飞书而不负责MES业务逻辑。
这样以后小龙虾即使增加:
MES MQTT ERPNext 数据库 工业设备也不会影响飞书通信层。
十九、最终解决方案
针对"小龙虾能够发送、能够查询,但是不能响应飞书外部群消息"的问题,推荐按照下面顺序处理:
① 检查机器人是否支持外部群 ② 开启飞书事件订阅 ③ 配置消息接收事件 ④ 检查消息接收权限 ⑤ 发布最新应用版本 ⑥ 配置公网HTTPS Webhook ⑦ Nginx / FRP 转发到小龙虾 ⑧ 测试 im.message.receive_v1 ⑨ 检查小龙虾是否收到Event ⑩ 解析@小龙虾消息 ⑪ 将文本交给Agent ⑫ 使用message_id回复飞书
二十、结语
飞书与小龙虾的连接,本质上不是简单的"调用一个API"。
它实际上是一个双向通信系统:
飞书 ↙ ↘ ↙ ↘ 接收事件 API调用 ↓ ↑ ↓ ↑ 小龙虾 Gateway ─────┘ │ ▼ AI Agent其中:
小龙虾 → 飞书解决的是主动发送问题;
飞书 → 小龙虾解决的是事件订阅和消息接收问题。
因此,当出现:
小龙虾可以发消息,也能查询飞书,但 @它没有响应。
第一检查点不应该是AI模型,而应该是:
飞书事件订阅 → Webhook → 外部群消息事件 → 小龙虾Gateway只要这条链路建立起来,再进行消息解析、Agent调用和飞书回复,整个智能体闭环才能真正跑通。
最终形成:
飞书外部群 │ │ @小龙虾 ▼ 飞书 Event │ ▼ Webhook │ ▼ 小龙虾 Gateway │ ▼ AI Agent │ ▼ Feishu Reply API │ ▼ 飞书外部群这就是小龙虾接入飞书后实现"能收、能理解、能处理、能回复"的完整通信闭环。