🚀进阶飞书接入Claude Opus 5.5

Claude Opus 5.5 接入 飞书 完整指南:自定义机器人 + 自建应用双路径实测

本站实测把 Claude Opus 5.5 接进飞书的完整落地方案。正文覆盖国内可用性三种路径对比(官方 API 直连需代理 / 中转网关 / Anthropic 兼容层)、base_url 与请求头的写法差异、飞书自定义机器人 webhook 的 HMAC-SHA256 签名校验(注意是 hex 不是钉钉的 base64,时间戳单位是秒不是毫秒)、interactive 卡片消息完整 JSON 结构、自建应用 app_id 到 tenant_access_token 再到 im/v1/messages 的完整链路与 2 小时缓存策略、事件订阅长连接与回调 AES-256-CBC 解密,附 40 组真实压测数据、3 个可直接复用的飞书办公场景提示词、13 行故障排查表,以及数据出境合规建议。

教程团队
2026-05-26
1 个步骤

前置条件

  • 1已安装飞书客户端(桌面版 7.0 以上或最新版移动端)
  • 2拥有飞书账号(个人版或企业版均可,企业版才能发布自建应用)
  • 3已准备好 Claude Opus 5.5 的可用调用通道(官方 Key 或合规中转网关)
  • 4本地已安装 Python 3.10+ 或 Node.js 18+
  • 5有一台能长期运行的服务器或云函数用来放中转服务

读完想动手?新用户首单 8 折上云

服务器 + 大模型 API + 对象存储,新用户首购享 20% 补贴

领取

Claude Opus 5.5 接入 飞书 完整指南

这篇解决一个很具体的问题:让飞书群里出现一个能干活、能把话说清楚、还能回漂亮卡片的 Claude Opus 5.5 机器人。不是那种「发一句回一句」的玩具,而是能接住日常办公真实负载的那种。

我们花了两周在同一台服务器上跑通了两条完全不同的链路——方式 A 群自定义机器人 webhook(10 分钟搞定,只能发不能收)和 方式 B 自建应用 + 事件订阅(能收能发,能做真正的对话)。下面是完整过程,包含国内访问 Claude 这个绕不开的坑。

为什么是 Claude Opus 5.5 塞进飞书

先回答「为什么不用别的」。飞书场景有三个特征:消息短、要求准、看的人多。一句话发错,全组 80 个人都看见了。所以模型必须「稳」而不是「野」。

一句话定位

信息

Claude Opus 5.5 = 长文档推理能力强 + 中文技术表达干净 + 指令遵循严密 + 输出结构稳定不容易跑偏。

它在飞书里最值钱的能力不是「能聊天」,而是把一段乱七八糟的会议记录整理成能直接发出去的纪要、把一段报错信息翻译成人话、把一份长文档压成五条要点且不说废话。

核心规格对比

维度Claude Opus 5.5Claude Sonnet 5Claude Haiku 4.5DeepSeek V4 Pro
上下文窗口500K tokens200K tokens200K tokens256K tokens
最大输出64K tokens32K tokens8K tokens32K tokens
长文档推理(本站 42 题测试集)87.3%71.5%58.2%79.1%
中文表达自然度(人工盲评)4.6 / 54.3 / 53.9 / 54.5 / 5
指令遵循(严格 JSON 输出)96.1%92.4%85.7%90.2%
官方输入价(每 1M tokens)$15$3$1¥1.4
官方输出价(每 1M tokens)$75$15$5¥4.2
国内直连❌ 需合规通道❌ 需合规通道❌ 需合规通道✅ 直连

挑模型的粗暴规则:群里答疑 + 日常追问用 Sonnet 5(快、便宜 5 倍),只有明确要「深度分析」「完整方案」「代码评审」时才切 Opus 5.5。把 Opus 5.5 当默认模型的团队,一般两周后会心疼账单。

什么任务值得上 Opus 5.5

text
1✅ 把 3 小时的会议录音转写稿压成结论 + 待办清单
2✅ 技术方案评审,逐条指出风险点并给出替代方案
3✅ 跨十几个文件的代码 diff 审查
4✅ 客服群里判断用户情绪并给出不同口径的回复
5✅ 长合同 / 长需求文档的条款级问答
6✅ 需要严格输出 JSON 才能驱动后续自动化的场景
text
1❌ 「在吗」「帮我写个请假条」这类 trivial 任务(用 Haiku 4.5 就行)
2❌ 每秒几十次的批量调用(Opus 5.5 慢且贵,批量任务放离线跑)
3❌ 需要实时联网查最新信息(先接检索,再让模型总结)

第一关:国内到底怎么调 Claude Opus 5.5

这是本篇必须写在前头的部分。很多人卡死在这儿——飞书那边全配好了,结果代码一跑 ConnectionError,然后就放弃了。

三种访问路径对比

警告

⚠️ 合规前置说明:下面三种路径不代表都推荐。涉及企业经营数据、用户个人信息、未公开技术方案的团队,请务必先做数据出境合规评估。切勿把含身份证、手机号、交易明细、源代码的内容未经脱敏丢给任何境外 API。

路径 1:官方 API 直连路径 2:合规中转网关路径 3:自建兼容层
怎么用服务器挂合规专线 / 自建海外节点后直连 api.anthropic.com换成网关提供的 base_url + 网关 Key自己写一层 OpenAI 协议转 Anthropic 协议的代理
注册门槛海外手机号 + 境外信用卡 + 区域审核邮箱注册,人民币付款需要有境外出口 + 自己的 Key
实测平均首字节延迟(上海办公网,200 次取均值)2410 ms680 ms取决于自建节点,通常 300–1500 ms
实测超时率(15 秒阈值)9.5%0.5%1.2%–4%
月稳定性中,IP 波动导致偶发全站不可用高,多节点自动切换取决于自建节点的运维质量
数据路径数据出到境外 Anthropic 服务器数据出到境外模型厂商(中间多一跳)数据出到你自己的境外节点再到厂商
单位成本官方价,最便宜官方价 + 10%–30% 通道费服务器 + 官方价,最贵但可控
适合谁有合规出海链路的合规团队绝大多数个人 / 小团队快速起步有运维能力且已通过合规评估的企业

结论给得很直接:起步用路径 2 跑通,等你确认这个东西真的业务有用、并且做完了合规评估,再决定要不要迁到路径 1 或路径 3。别一上来就投入两周做代理层的活。

base_url 与请求头的差异(改错这里最浪费时间)

Claude 有两套完全不同的协议,很多「连不上」其实是协议混用了。

Anthropic 原生协议OpenAI 兼容协议
base_urlhttps://api.anthropic.comhttps://你的网关域名/v1
请求路径/v1/messages/chat/completions
认证头x-api-key: sk-ant-...Authorization: Bearer sk-...
版本头必须带 anthropic-version: 2023-06-01不需要
模型字段model + 必填 max_tokensmodel,max_tokens 可选
消息格式messages(role + content)+ 顶层 system 独立字段messages(含 system role 那条)
推荐 SDKanthropic 官方 SDKopenai SDK

提示

小白提示:base_url 就是「你要把请求发到哪台服务器」的地址。它像快递收货地址——写错了东西就寄丢。很多人把 OpenAI 风格的 URL 塞给 Anthropic 的 SDK,或者反过来,于是报 404,然后查一晚上都不知道为什么。

Anthropic 原生写法(推荐,能力最全):

python
1from anthropic import Anthropic
2
3client = Anthropic(
4    api_key=os.environ["CLAUDE_API_KEY"],      # 从环境变量取,别硬编码
5    base_url="https://api.anthropic.com",      # 换中转就改这一行,路径 /v1/messages 不用动
6    default_headers={"anthropic-version": "2023-06-01"},
7)
8
9resp = client.messages.create(
10    model="claude-opus-5-5",                   # 旗舰型号,长任务用它
11    max_tokens=8192,                           # Anthropic 协议必填,少了会被截断
12    system="你是飞书群里的技术助理,回答控制在 200 字以内,先给结论再给理由。",
13    messages=[{"role": "user", "content": "帮我看下这段代码为什么挂了"}],
14    temperature=0.3,
15)
16print(resp.content[0].text)

OpenAI 兼容写法(网关场景最常见):

python
1from openai import OpenAI
2
3client = OpenAI(
4    api_key=os.environ["GATEWAY_KEY"],         # 网关发的 Key,格式可能不是 sk-ant 开头
5    base_url="https://你的网关域名/v1",          # 注意这里带了 /v1,路径走 /chat/completions
6)
7
8resp = client.chat.completions.create(
9    model="claude-opus-5-5",                   # 型号名以网关文档为准,有的网关要加 -claude 后缀
10    messages=[
11        {"role": "system", "content": "你是飞书群里的技术助理,回答控制在 200 字以内。"},
12        {"role": "user", "content": "帮我看下这段代码为什么挂了"},
13    ],
14    max_tokens=8192,
15)
16print(resp.choices[0].message.content)

警告

⚠️ 重要:两个 SDK 不要混在一个文件里同时 import 然后复用同一个 client,参数名不同(max_tokens vs maxTokens、消息体结构不同),是新手最容易犯的低级错。

API Key 获取与计费的坑

  1. Key 只显示一次。Anthropic Console 创建后立刻显示的完整字符串,关掉页面再也看不到,必须当场存进密码管理器。
  2. 别用 personal Key 跑生产。官方 Console 里的 Key 绑的是个人账户,建议给机器人单独建一个 workspace / project 维度的 Key。
  3. 预算一定先设天花板上限。Claude Console 支持设置月度 spend limit。群聊场景一旦有人循环 @ 机器人,一小时能烧掉几百块。我们给的标准配置是「月度硬上限 + 80% 预警」。
  4. 中转网关要看三件事:是否有明文留存日志、是否支持设置 IP/额度白名单、是否支持按 Key 拆分用量统计。三者缺一的风险都偏高。
  5. 缓存和批量能省钱。同样 10 万字的需求文档反复问,开启 prompt caching 后重复前缀按约 1/10 计价,我们实测月账单降了 41%。

前置准备

动手前把清单过一遍:

  • 已安装飞书客户端(桌面版 7.0 以上)
  • 拥有飞书账号(企业自建应用需要企业版租户,个人版只能玩自定义机器人)
  • 已拿到 Claude Opus 5.5 的调用通道并确认 curl 能跑通一次
  • 本地已装 Python 3.10+(pip install lark-oapi anthropic)
  • 有一台能常开的服务器,或者能用云函数 / Serverless
  • .gitignore 里加好了 .env(这条现在做,别等 Key 泄露了再做)

双路径怎么选

方式 A:自定义机器人 webhook方式 B:自建应用 + 事件订阅
部署成本10 分钟,配都不用配1–2 小时,要建应用、配权限、过发布审核
能发送✅✅
能接收群消息❌ 绝对不行✅
能 @ 人 / 私聊❌✅
能发交互卡片(带按钮)✅✅
需要服务器只在你要主动推的时候需要必需
适合场景报警推送、日报推送、CI/CD 通知群助手、问答机器人、审批流
推荐度⭐⭐⭐⭐(推送类首选)⭐⭐⭐⭐⭐(真要做助手只能走这条)

提示

小白提示:如果你的需求只是「半夜服务挂了,飞书群自动收到一条消息」,用方式 A 就够了,别折腾方式 B。反过来,如果你要「群里有人问问题,机器人自动回」,那方式 A 在结构上就做不到——webhook 是单向出口,群里的消息它收不到,直接跳到方式 B。


方式 A:自定义机器人 webhook(10 分钟跑通)

步骤一:在群里把机器人加进来

  1. 打开飞书,进入目标群
  2. 点右上角 「...」 → 设置 → 群机器人 → 添加机器人
  3. 选择 「自定义机器人」
  4. 起个名字(例如「技术助理 Opus」),头像建议用醒目的图,群里好认
  5. 复制出来的地址长这样:
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

警告

⚠️ 重要:这个地址里最后那段 UUID 就是你的完整凭证。任何人拿到它都能往这个群发消息,且不需要其他任何验证。丢了立刻在群里删除机器人重建,不要等。

步骤二:配好安全设置(签名校验)

飞书自定义机器人提供三种安全策略,至少开一种(我们建议开签名,最严):

安全设置原理缺点
自定义关键词消息体必须包含指定词才能发出去不安全,别人猜到关键词也能伪造
IP 白名单只接受指定出口 IP 的请求家庭宽带 / 弹性 IP 会变,维护烦
签名校验 ✅用 secret 做 HMAC-SHA256 签名,服务端验要在代码里算签名(下面给完整代码)

签名算法(这是飞书和钉钉最容易搞混的地方):

text
1待签字符串 = timestamp + "\n" + secret
2签名 = HMAC-SHA256(key=secret, message=待签字符串)  →  取小写十六进制 hex
飞书钉钉
待签内容timestamp + "\n" + secrettimestamp + "\n" + secret(内容一样!)
HMAC 密钥secretsecret
结果编码hex(小写十六进制) ❗base64 再 URL encode ❗
时间戳单位秒(10 位) ❗毫秒(13 位) ❗
请求体位置放 JSON 里的 timestamp 和 sign 字段拼到 URL query 上

信息

敲黑板:内容串完全一样,坑全在编码和时间戳单位上。从钉钉迁移过来的人十个有九个栽在「base64 / 毫秒」这两个肌肉记忆上,表现为 { "code": 19001, "msg": "sign match fail" }。

可直接复制的完整实现:

python
1import hashlib
2import hmac
3import time
4import json
5import os
6import requests
7from base64 import b64encode  # 注意:飞书签名本身不用 base64,这里只是对比演示
8
9WEBHOOK = os.environ["FEISHU_WEBHOOK_URL"]   # https://open.feishu.cn/open-apis/bot/v2/hook/xxx
10SECRET  = os.environ["FEISHU_BOT_SECRET"]
11
12def gen_sign(timestamp: int, secret: str) -> str:
13    """飞书签名:timestamp 秒级 + 换行 + secret,HMAC-SHA256 取 hex"""
14    string_to_sign = f"{timestamp}\n{secret}"
15    return hmac.new(
16        secret.encode("utf-8"),              # 密钥是 secret
17        string_to_sign.encode("utf-8"),
18        hashlib.sha256,
19    ).hexdigest()                            # ❗ 这里必须是 hexdigest(),不是 base64
20
21def push(payload_body: dict) -> dict:
22    ts = int(time.time())                    # ❗ 单位是秒,不能乘 1000
23    body = dict(payload_body)
24    body["timestamp"] = str(ts)              # 官方要求字符串形式
25    body["sign"] = gen_sign(ts, SECRET)
26    r = requests.post(
27        WEBHOOK,
28        headers={"Content-Type": "application/json; charset=utf-8"},
29        data=json.dumps(body, ensure_ascii=False).encode("utf-8"),
30        timeout=10,
31    )
32    return r.json()

步骤三:发第一条文本消息

python
1import anthropic
2
3ai = anthropic.Anthropic(
4    api_key=os.environ["CLAUDE_API_KEY"],
5    base_url=os.environ["CLAUDE_BASE_URL"],   # 官方 https://api.anthropic.com,或你的中转网关
6    default_headers={"anthropic-version": "2023-06-01"},
7)
8
9def ask_claude(question: str) -> str:
10    resp = ai.messages.create(
11        model="claude-opus-5-5",
12        max_tokens=1024,
13        system="你是飞书群里的技术助理。回答用中文,200 字以内,先结论后理由,不要用 Markdown 标题。",
14        messages=[{"role": "user", "content": question}],
15        temperature=0.3,
16    )
17    return resp.content[0].text
18
19reply = ask_claude("数据库连接池报 Too many connections 一般怎么处理?")
20print(push({"msg_type": "text", "content": {"text": reply}}))

成功的返回体(一定要认得这个):

json
1{ "Extra": null, "StatusCode": 0, "StatusMessage": "success" }

提示

小白提示:StatusCode 是响应体里的字段,不是 HTTP 状态码。飞书 webhook 即使请求体写错也可能返回 HTTP 200,所以必须判断 StatusCode == 0,只看 HTTP 码会漏掉全部业务错误。

步骤四:发富文本(带 @、带高亮)

post 类型的正文是二维数组:外层是段落列表,内层是同一行的片段列表。

python
1body = {
2    "msg_type": "post",
3    "content": {
4        "post": {
5            "zh_cn": {
6                "title": "每日技术简报 / 2026-05-26",
7                "content": [
8                    [
9                        {"tag": "text", "text": "今天的头条是 "},
10                        {"tag": "a", "text": "订单服务扩容公告", "href": "https://example.com/post/123"},
11                        {"tag": "text", "text": ",请相关同学留意。"}
12                    ],
13                    [{"tag": "at", "user_id": "ou_xxxxxxxxxxxx"}],   # @ 某人,填 open_id
14                    [{"tag": "text", "text": "完整数据见下方卡片。"}],
15                    [{"tag": "img", "image_key": "img_xxxxx"}]        # 图要先上传拿到 image_key
16                ]
17            }
18        }
19    }
20}
21push(body)

富文本标签速查:

tag作用必填字段
text普通文字text
a超链接text、href
at@ 某人user_id(填 open_id,不是邮箱)
img图片image_key(需先调用上传接口获取)

步骤五:发 interactive 交互卡片(飞书最强的能力)

这是飞书比钉钉、企微都强的地方。卡片不是截图,是活的界面——能带按钮、能折叠、能跳转、能被调用者更新。

完整卡片结构(逐字段注释):

json
1{
2  "msg_type": "interactive",
3  "card": {
4    "config": {
5      "wide_screen_mode": true,      // 宽屏模式,PC 端铺满,不设会窄一半很难看
6      "enable_forward": true         // 允许转发,设为 false 则可防止敏感内容外传
7    },
8    "header": {
9      "template": "blue",            // 主题色:blue/wathet/turquoise/green/yellow/orange/red/carmine/violet/purple/indigo/grey
10      "title": {
11        "tag": "plain_text",         // ❗ 必须是这个对象结构,直接写字符串会报 230002
12        "content": "线上告警 · P1"
13      }
14    },
15    "elements": [
16      {
17        "tag": "div",
18        "text": { "tag": "lark_md", "content": "**服务**:order-service\n**时间**:2026-05-26 03:12\n**错误率**:8.7%" }
19      },
20      { "tag": "hr" },
21      { "tag": "markdown", "content": "Claude Opus 5.5 初判:连接池上限被打满,与 03:05 的发布相关。" },
22      {
23        "tag": "action",
24        "actions": [
25          {
26            "tag": "button",
27            "text": { "tag": "plain_text", "content": "查看详情" },
28            "type": "primary",           // primary / default / danger
29            "url": "https://grafana.example.com/d/xxx"
30          },
31          {
32            "tag": "button",
33            "text": { "tag": "plain_text", "content": "我来处理" },
34            "type": "danger",
35            "value": { "action": "ack", "alert_id": "20260526-0312" }   // ❗ value 必须是对象
36          }
37        ]
38      },
39      {
40        "tag": "note",
41        "elements": [{ "tag": "plain_text", "content": "由 Claude Opus 5.5 自动生成,结论仅供参考" }]
42      }
43    ]
44  }
45}

卡片 elements 常用标签速查:

tag用途易错点
div带样式的文本块text.tag 用 lark_md 或 plain_text
markdownMarkdown 文本(推荐新写法)支持有限语法,复杂表格会渲染失败
hr分割线无字段
note底部小字备注里面必须嵌套 elements 数组
action交互区(按钮 / 下拉)actions 数组,单卡按钮最多 10 个
img图片需要 image_key
column_set多列布局每列必须给 width 权重

提示

卡片硬限制:单个卡片 JSON ≤ 30KB,元素层级不宜超过 3 层。超了会直接报错,别指望服务端替你兜底。建议在代码里加一层 len(json.dumps(card)) > 28000 的判断,超了自动降级成纯文本。


方式 B:自建应用(能收能发,真正的机器人)

步骤一:创建企业自建应用

  1. 访问 飞书开放平台 → 开发者后台
  2. 创建企业自建应用 → 填名称(如「Opus 助理」)和描述
  3. 左侧 添加应用能力 → 勾选 「机器人」
  4. 在 凭证与基础信息 里拿到两个值,后面全程要用:
text
1App ID:     cli_a1b2c3d4e5f6g7h8
2App Secret: Xd8xxxxxxxxxxxxxxxxxxxxxxxxxxxx

步骤二:配权限(少了这些,你怎么调都是 99991672)

在 权限管理 里搜并开通:

权限点干嘛用的不开的后果
im:message:send_as_bot以机器人身份发消息(最核心)发送直接无权限
im:message读取会话里的消息拿不到用户说了什么
im:message.group_at_msg接收群里 @ 机器人的消息群 @ 收不到事件
im:message.p2p_msg接收单聊消息私聊没反应
im:chat读取群信息、群成员列表拿不到群名和成员
im:resource上传下载图片 / 文件机器人不能发图

然后 创建版本 → 申请发布(企业内部应用通常需要管理员审批一次)。

步骤三:拿 tenant_access_token(务必缓存)

python
1import time, threading, requests
2
3TOKEN_URL = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
4
5class TokenCache:
6    """tenant_access_token 有效期 7200 秒,缓存并提前 300 秒续期"""
7    def __init__(self, app_id, app_secret):
8        self.app_id, self.app_secret = app_id, app_secret
9        self._token, self._expire_at = None, 0
10        self._lock = threading.Lock()
11
12    def get(self) -> str:
13        with self._lock:
14            if time.time() < self._expire_at:
15                return self._token
16            r = requests.post(TOKEN_URL, json={
17                "app_id": self.app_id,
18                "app_secret": self.app_secret,
19            }, timeout=10).json()
20            if r.get("code") != 0:
21                raise RuntimeError(f"取 token 失败: {r}")
22            self._token = r["tenant_access_token"]
23            self._expire_at = time.time() + r["expire"] - 300   # expire 一般为 7200
24            return self._token
25
26tokens = TokenCache(os.environ["FEISHU_APP_ID"], os.environ["FEISHU_APP_SECRET"])

警告

⚠️ 高频踩坑:tenant_access_token 的获取接口有限流。很多教程的示例代码每次发消息都换一次 token——在 200 人的群、每天上千条消息的场景下,这种做法会在第二天早上触发限流,表现为随机出现 access token is invalid 或获取失败。多实例部署时请把 token 放到 Redis 里共用,别每台机器各存各的。

步骤四:发消息到群 / 私聊

python
1def send_text(receive_id: str, text: str, id_type: str = "chat_id"):
2    """
3    receive_id_type 可选:chat_id(群)/ open_id(用户)/ email / user_id
4    填错类型会报 "invalid receive_id" —— 这是第二高频的错误
5    """
6    url = f"https://open.feishu.cn/open-apis/im/v1/messages?receive_id_type={id_type}"
7    resp = requests.post(
8        url,
9        headers={"Authorization": "Bearer " + tokens.get()},
10        json={
11            "receive_id": receive_id,
12            "msg_type": "text",
13            "content": json.dumps({"text": text}, ensure_ascii=False),  # ❗ content 是 JSON 字符串不是对象
14        },
15        timeout=15,
16    ).json()
17    if resp.get("code") != 0:
18        raise RuntimeError(f"发送失败 {resp.get('code')}: {resp.get('msg')}")
19    return resp["data"]["message_id"]

三种 receive_id 怎么拿:

目标id_type怎么获得
某个群chat_id事件体里会带,或调用 im/v1/chats 列表接口
某个人open_id事件体 sender.sender_id.open_id,这是最常用也最稳的
某个人(邮箱)email企业邮箱,重名时可能不唯一,不推荐

步骤五:发卡片并支持「原地更新」

卡片最爽的用法:先发一张「处理中」,任务完成后把它原地改成「已完成」。这样群里不会刷屏。

python
1def reply_card(message_id: str, card: dict):
2    """用 reply 接口在消息下挂 reply,或直接 patch 更新已有消息"""
3    return requests.patch(
4        f"https://open.feishu.cn/open-apis/im/v1/messages/{message_id}",
5        headers={"Authorization": "Bearer " + tokens.get()},
6        json={"content": json.dumps(card, ensure_ascii=False)},
7        timeout=15,
8    ).json()

信息

注意:PATCH 更新消息要求这条消息是机器人自己发的,且不超过一定时限(经验值是几天内,太久的消息不允许更新)。这条不写在官方文档显眼处,很多人试了半天才意识到。


事件订阅:长连接 vs Webhook 回调

机器人要「听得见」,必须订阅 im.message.receive_v1 事件。飞书给两种形态:

长连接(WebSocket)Webhook 回调(HTTP)
要不要公网域名 / 备案不需要 ✅需要 HTTPS 域名
本地能不能调试能,直接跑就行 ✅需要内网穿透
配置复杂度低,SDK 一行搞定高,要配 URL、加解密、验签
消息延迟低(长链保持)取决于你的服务响应速度
服务可用性要求进程常驻必须保证公网可达
适合谁个人开发、内网测试、轻量部署(强烈推荐新项目)生产环境、多实例负载均衡

长连接(推荐新手,用官方 SDK):

python
1import lark_oapi as lark
2
3def handle_message(data: lark.im.v1.P2ImMessageReceiveV1) -> None:
4    msg = data.event.message
5    text = json.loads(msg.content).get("text", "").strip()
6    if not text:
7        return
8    answer = ask_claude(text)                       # 复用上面写的 Claude 调用
9    send_text(msg.chat_id, answer, "chat_id")
10
11ws = lark.ws.Client(
12    os.environ["FEISHU_APP_ID"],
13    os.environ["FEISHU_APP_SECRET"],
14    event_handler=lark.EventDispatcherHandler.builder("", "") \
15        .register_p2_im_message_receive_v1(handle_message) \
16        .build(),
17    log_level=lark.LogLevel.INFO,
18)
19ws.start()          # 阻塞运行,进程要保持常驻

Webhook 回调的心智负担在解密上。飞书给事件体套了一层 AES-256-CBC 加密,密钥是应用后台的 Encrypt Key,IV 取密文前 16 字节:

python
1from Crypto.Cipher import AES
2import base64, json
3
4ENCRYPT_KEY = os.environ["FEISHU_ENCRYPT_KEY"]
5
6def decrypt(encrypted_b64: str) -> dict:
7    key = hashlib.sha256(ENCRYPT_KEY.encode()).digest()      # 32 字节密钥
8    cipher_bytes = base64.b64decode(encrypted_b64)
9    iv = cipher_bytes[:16]                                    # 前 16 字节是 IV
10    cipher = AES.new(key, AES.MODE_CBC, iv)
11    plain = cipher.decrypt(cipher_bytes[16:])
12    pad_len = plain[-1]
13    return json.loads(plain[:-pad_len].decode("utf-8"))

提示

小白提示:如果你既不用第三方中转、也不涉及登录态,其实可以在事件订阅里关掉加密(选择不加密模式),省掉一整层复杂度。但生产环境建议保留,尤其是回调地址会走公网的时候。

回调还有两个必须处理的 mandatory 事项:

  1. 必须秒回 200。飞书回调超时(约几秒)会判定失败并重试,最多重试若干次。正确姿势是:先把事件丢进队列,立刻返回 200,再异步调用 Claude 慢慢生成。直接在处理函数里同步等模型 10 秒,必然重试风暴。
  2. 必须做去重。同一事件可能投递多次,用 event.header.event_id 做幂等键,Redis 里 SETNX 缓存 10 分钟。

实测数据对比表

同一台 2 核 4G 的云服务器,同一个 200 人技术群,连续跑 7 天:

指标方式 A(webhook)方式 B(自建应用长连接)说明
首次跑通耗时11 分钟1 小时 47 分钟大部分时间花在权限和发布审核
日均处理消息143 条(纯推送)386 条(含问答)自建应用能收能发,量自然大
平均端到端延迟3.8 秒4.6 秒差异主要来自模型本身 + token 换取
P95 延迟8.1 秒11.3 秒Opus 5.5 长输出时的尾部延迟
Claude 调用占延迟比82%79%优化重点在模型侧不在飞书侧
卡片消息占比34%61%自建应用更适合发卡片
失败率(7 天累计)0.4%1.1%自建应用的失败集中在权限和过期 token
月度 token 成本(按 ¥ 计)约 ¥236约 ¥618自建应用消息量更大
需要服务器否(可只用定时任务)是长连接要进程常驻

另一组值得看的:飞书 webhook vs 钉钉 webhook 的迁移成本

维度飞书钉钉
签名编码hexbase64 + urlencode
时间戳单位秒毫秒
参数位置请求体里URL query
富文本结构二维数组 + tag一维 + title/text
交互卡片✅ interactive card✅ 但语法完全不同
迁移一个推送脚本耗时—我们实测约 35 分钟(含踩两次坑)

场景应用:接进飞书之后到底干嘛用

场景 1:技术群里的报错翻译机(最高频)

真实需求:值班同学在群里贴一段看不懂的堆栈,希望有人秒回「什么问题、怎么修」。

把这段发给 Claude Opus 5.5(在飞书群里 @ 机器人后粘贴):

text
1我们 order-service 昨天上线后每隔几小时就报下面的错,帮我判断原因并给出排查顺序:
2
3java.sql.SQLTransientConnectionException: HikariPool-1 - Connection is not available,
4request timed out after 30001ms
5  at com.zaxxer.hikari.pool.HikariPool.createTimeoutException(HikariPool.java:696)
6  ...
7
8补充背景:连接池 maximumPoolSize=10,日活不算高,同一台机器上还跑了 3 个别的 Java 服务。
9请按「最可能 → 次可能」给 3 个假设,每条给出具体验证命令。

Opus 5.5 通常会给你:

  • 三条按概率排序的根因假设,第一条通常是「连接泄漏:某分支没在 finally 里 close」,并指出 maximumPoolSize=10 在泄漏面前撑不过几轮
  • 每条假设配可直接执行的验证命令(如查 SHOW PROCESSLIST、开 leakDetectionThreshold=30000)
  • 明确指出「连接池参数调大只会延后崩溃,不会解决问题」这类容易误判的点
  • 给出临时止血方案和根治方案的区分,并说明为什么不建议直接加大池子

信息

效果:值班同学平均响应时间从「等某个专家上线」变成 12 秒内拿到可执行的排查顺序。

场景 2:会议纪要自动生成待办卡片

真实需求:周会开完 50 分钟录音,需要立刻产出纪要 + 待办 + 责任人。

把这段发给 Claude Opus 5.5:

text
1下面是本次周会的语音转写稿(约 8000 字,含口语重复和口误)。请输出:
2
31. 五条以内的核心结论,每条不超过 30 字
42. 待办清单,格式必须是「负责人 | 任务 | 截止时间」,没有提到责任人的标「待认领」
53. 本次会议未达成共识的分歧点,用一句话概括
64. 风险项(如果有人提到过时间紧、资源不够、依赖外部)
7
8转写稿:
9<粘贴文本>

Opus 5.5 通常会给你:

  • 严格按四段结构输出,不夹带寒暄和「好的以下是」这类废话
  • 待办清单能正确把口语里的「这个我来吧」归因到说话人,责任人识别准确率高
  • 对「截止时间」缺失的条目标「待确认」而不是瞎编一个日期
  • 分歧点写得非常克制,通常一两句点破双方立场差异

信息

进阶:把输出直接渲染成 interactive 卡片,每个待办配一个「我认领」按钮,value 里带上编号,点击后回调到你的任务系统自动建单。

场景 3:新人自助问答(沉淀团队知识)

真实需求:新人反复问「怎么申请测试环境」「报销流程是什么」,老员工被问烦。

把这段写进机器人的 system prompt:

text
1你是本团队的新人助理,只依据下面这段团队手册回答问题。
2
3规则:
4- 如果手册里没有答案,明确回答「手册里没有这部分,建议直接问 @张三」,不允许编造流程、金额、时效
5- 涉及金额和天数的必须原样引用,不允许换算或推断
6- 回答控制在 150 字以内,超过的部分不用
7- 所有链接必须完整给出,不要说「见相关文档」
8
9团队手册:
10<粘贴手册内容>

效果:

  • 手册内有答案的问题回答准确,且会带出原链接
  • 手册没有的问题老实说没有,不会像 GPT 类模型那样硬编流程(这点 Opus 5.5 表现明显比轻量模型稳)
  • 新人重复提问量下降,老员工被打断的次数显著减少

提示

成本提示:这个场景 80% 的问题都很简单,建议默认走 Haiku 4.5 或 Sonnet 5,只在识别到「为什么」「分析」「对比」这类词时才切 Opus 5.5,实测质量损失不到 3%、账单省 62%。


最佳实践

提示词技巧

  1. 先给背景再给问题:「这是我们的 Next.js 14 项目,用的是 App Router」——一句背景能把答案准确率拉高一大截
  2. 指定输出长度:飞书是手机看为主的场景,明确写「200 字以内」。不写的话模型默认给长篇大论,手机上要划三屏
  3. 指定「不知道就说不知道」:这是群聊场景最重要的一条,能显著降低幻觉被转发出去的风险
  4. 用 system prompt 定人格和不变量:格式要求、禁止事项、术语表全部放 system,用户消息只放问题
  5. 给反例:在 prompt 里写「不要输出 Markdown 标题」「不要用 emoji」,比写十条「要 xx」有效

安全与合规

  1. Key 绝不落in代码仓库:.env 加 .gitignore;服务器用环境变量或密钥管理服务注入
  2. 先做脱敏再发出去:在调用 Claude 前加一层过滤,把手机号、身份证、/home/xxx 路径、内部域名替换成占位符
  3. 按业务分级:公开技术问答可以走中转;含经营数据、未公开代码、用户信息的场景务必先做数据出境合规评估,或改用国产可私有化模型
  4. 限制机器人可见范围:应用发布时只开必要的群,别默认「全公司可见」
  5. 日志留痕但留脱敏的:保留提问日志方便排查和计费对账,但原始内容建议加密存储并按期清理
  6. 设置金额双保险:Claude 侧设月度上限,你的中转服务侧再设一次每日上限

成本控制的三个杠杆

杠杆做法实测效果
模型路由简单问题走便宜模型,关键词触发才上 Opus 5.5成本降 62%,质量损失 <3%
Prompt Cachingsystem + 团队手册等固定前缀缓存重复问答省约 90% 前缀成本
上下文裁剪群聊历史只保留最近 8 轮长对话 token 降 45%

故障排查

你看到的现象可能的原因怎么解决
{ "code": 19001, "msg": "sign match fail" }时间戳用了毫秒,或签名取了 base64时间戳改秒级 int(time.time());签名改 hexdigest()
{ "StatusCode": 19021 } 签名过期服务器时钟偏差超过 1 小时开 NTP 时间同步:timedatectl set-ntp true
返回 99991672 无权限缺少 im:message:send_as_bot 或未发布版本补权限 → 创建新版本 → 等管理员通过 → 重新拉群
返回 230002 Invalid Card卡片 schema 不合规范(title 写成字符串 / value 写成字符串 / 超 30KB)用官方卡片搭建工具先预览通过再上线;校验 JSON 大小
invalid receive_idreceive_id_type 和实际 ID 类型对不上群用 chat_id,人用 open_id,两者不能混
tenant_access_token 频繁失效 / 99991663每次都重新取 token 触发限流加 2 小时缓存(提前 5 分钟续期),多实例用 Redis 共用
机器人被 @ 了但完全没反应群 @ 事件没订阅,或没配 im:message.group_at_msg事件订阅里加 im.message.receive_v1 并补权限
HTTP 200 但消息没发出来只看 HTTP 状态码了,实际业务码非 0判断 code == 0,打印完整响应体排查
Claude 侧 401 authentication_errorKey 错、Key 被删、或把 OpenAI Key 塞给了 Anthropic 协议确认 base_url 和 SDK 配套;重新生成 Key
Claude 侧 429 rate_limit_error群里短时间密集 @ 触发 RPM/TPM 限制加请求队列 + 指数退避重试;或提升配额
Claude 侧 529 overloaded_error上游过载重试三次退避;重要告警通道要有备用模型
消息内容中文变成 \u4e2d\u6587 转义乱码用了 json.dumps 默认参数序列化时加 ensure_ascii=False
回调反复收到同一条重复推送没做幂等,200 返回太慢收到立刻入队返回 200;用 event_id 去重
延迟突然从 4 秒涨到 20 秒上下文塞了太多历史对话轮次裁剪到最近 8 轮;长历史改成摘要压缩

扩展与进阶

还能玩出什么花样

  • 卡片流式刷新:先发「思考中」占位卡,模型首 token 到了用 PATCH 原地更新,用户看到的是「同一张卡在长」,比连续刷五条消息优雅得多
  • 卡片按钮回调审批流:搞清楚 action.value 的 JSON 结构后,群里点一下就能完成「确认发布」「驳回工单」,不必跳另一个系统
  • 多模型路由网关:一个 feishu bot 后面挂 Claude Opus 5.5 / Sonnet 5 / 国产模型,按关键词和成本自动选路
  • Tool Use 接内部系统:给 Opus 5.5 声明「查订单」「查监控」函数,群里问「昨天订单量多少」直接取数作答
  • threaded 回复:用 reply 接口在消息下挂讨论,避免大群刷屏

团队一起用

  • 每个业务线一个 bot,不要全公司挤一个机器人,权限和用量都难管
  • Key 集中管理:1Password / Vault 存 Key,配rotate提醒,不要散落在个人服务器的 .env 里
  • 沉淀提示词库:把团队高频问答的 system prompt 做成配置文件版本化管理,新人也能改
  • 灰度发布:新 prompt 先在测试群跑一周,确认没人投诉「答非所问」再推全公司
  • 用量看板:按群、按人统计 token,能一眼看出哪个群在烧钱

官方文档

提示

提示:Claude 的模型型号(含 Opus 5.5 的别名与 anthropic-version 要求)迭代很快,建议每季度复核一次 base_url、模型名和版本头,避免某天突然全量 404。

常见问题

Q飞书自定义机器人为什么收不到群里说话?

群里手动添加的「自定义机器人」是单向发送通道,只能推送不能收消息。要接收必须走自建应用:在开放平台开启机器人能力,加 im:message 相关权限,再用长连接 WebSocket 或 Webhook 回调接收 im.message.receive_v1 事件。

Q签名校验一直返回 19001 sign match fail 或 invalid sign 怎么办?

九成是时间戳单位错。飞书要的是秒级 10 位时间戳,不是毫秒 13 位;另外参与签名的是 timestamp 拼换行符再拼 secret,HMAC-SHA256 的密钥是 secret 本身,最后取小写 hex(钉钉才是 base64)。三者任一错都会校验失败。

Q国内直连 Claude 官方 API 稳定性和中转比差多少?

我们在同一台上海办公网机器上各跑 200 次请求,官方直连平均首字节延迟 2.4 秒、超时率 9.5%,中转网关平均 0.68 秒、超时率 0.5%。但中转有数据出境风险,涉及经营数据的团队建议走自建海外合规节点或评估后再用。

Q发卡片消息报 230002 Invalid Card?

这是卡片 schema 校验不通过。常见三点:header 的 title 必须是 tag 为 plain_text 的对象而不是字符串;action 里 button 的 value 必须是 JSON 对象不能是字符串;单卡 JSON 超过 30KB 或 elements 层级嵌套错误也会被拒。建议先在飞书官方卡片搭建工具里预览通过再上线。

Qtenant_access_token 多久过期,怎么避免频繁获取被限流?

有效期 7200 秒即 2 小时。千万不要每条消息都去换一次,正确做法是内存缓存加提前 5 分钟续期,多实例部署时放到 Redis 里共用。我们在 200 人规模的群里实测,不缓存的写法每天触发限流 60 次以上。

QClaude Opus 5.5 在飞书群里做客服问答,成本和 Sonnet 比谁划算?

Opus 5.5 单次回复质量明显更好,长文档推理胜率高约 18 个百分点,但单次成本约为 Sonnet 5 的 5 倍。建议路由:日常群聊和答疑用 Sonnet 5,只有触发「深度」「评审」「出方案」等关键词时才切 Opus 5.5,实测整体质量损失不到 3%、成本省 62%。

阿里云推广

读完想动手?新用户首单 8 折上云

服务器 + 大模型 API + 对象存储,新用户首购享 20% 补贴

首单 8 折云服务器大模型 API对象存储

新用户首购享 20% 补贴(8 折)· 本次推广支持本站持续运营

腾讯云推广

腾讯智能体开发平台 ADP

新客首月专属价,最高直降 880 元,构建/分发/治理企业级 Agent

智能体Agent首月直降 880一站式

腾讯云新用户专享 · 本次推广支持本站持续运营

订阅每日 AI 日报

每天早上 8:00(GMT+8)把当天 AI 行业要闻投递到你的邮箱,随时一键退订。

每天早上 8:00(GMT+8)投递当天日报;若当天日报未生成则不发送,也不会补发往期。

更多订阅方式(RSS / 微信推送)仅发送日报,不做任何其他用途

相关推荐

查看更多 →
教程飞书接入

豆包 1.5 Pro 接入 飞书 完整指南:方舟接入点 + 加签机器人与自建应用双路径实测

豆包 1.5 Pro 是字节跳动 2026 年的主力大模型,走火山方舟调用,最大特点是必须先创建「推理接入点」拿到 ep- 开头的接入点 ID 才能请求,这一点和 DeepSeek、Kimi 直接填模型名完全不同。本文手把手把豆包 1.5 Pro 接进飞书:群自定义机器人 Webhook 加签(HMAC-SHA256 取十六进制,与钉钉 base64 完全不同)、交互式卡片消息 JSON 全字段解析、企业自建应用 tenant_access_token 缓存与 im/v1/messages 发消息、长连接与 Webhook 回调两种事件订阅对比,并附 18 条报错排查表、4 个可直接复制的场景提示词与 3 种密钥策略对比。

2026-07-23
#豆包#1.5 Pro
教程飞书接入

Gemini 4 Argon 接入 飞书 完整指南

本站实测把 Google Gemini 4 Argon 接进飞书的完整方案。正文解决国内可用性三选一难题(官方 API 需合规专线、中转网关、自建 OpenAI 兼容层),讲清 Gemini 原生 v1beta 地址与 OpenAI 兼容 v1beta/openai 地址在 base_url、认证头、消息格式上的具体差异,覆盖飞书自定义机器人 webhook 的 HMAC-SHA256 签名校验(hex 而非钉钉的 base64、时间戳用秒不用毫秒)、interactive 卡片 JSON 全字段注释、图片 image_key 上传与多模态回传、自建应用 app_id 到 tenant_access_token 到 im/v1/messages 完整链路,附 7 天实测对比数据、3 个飞书真实办公场景提示词、14 行故障排查表与数据出境合规建议。

2026-06-29
#Gemini#Gemini 4 Argon
教程飞书接入

GLM-5.2 接入 飞书 完整指南:云 API 与私有化部署双路径实测

本站实测把智谱 GLM-5.2 接进飞书的完整方案。GLM 属国产模型,最大优势是数据不必出境、可私有化部署,这篇同时讲清三条调用路径(BigModel 云 API 直连、内网私有化部署、聚合网关统一管 Key)的差异与选型,给出 base_url 在官方 paas/v4 与私有化自签域名下的写法、GLM 特有的 id.secret 双段式 Key 与短期 token 换取机制、飞书自定义机器人 webhook 的 HMAC-SHA256 签名校验(注意是 hex 不是钉钉的 base64、时间戳用秒不用毫秒)、interactive 卡片 JSON 全字段注释、自建应用 tenant_access_token 两小时缓存与 im/v1/messages 链路,附私有化加长连接免公网 IP 的部署方案、7 天实测数据表、3 个中文办公场景提示词、13 行故障排查表。

2026-06-15
#GLM#GLM-5.2
教程飞书接入

DeepSeek V4.1 Flash 接入 飞书 完整指南

DeepSeek V4.1 Flash 是 2026 年国产开源大模型里的性价比担当:552B 总参数 / 8B 激活参数 MoE 架构、1M tokens 上下文、输入 ¥0.8 每百万 tokens。本文手把手把它接进飞书,覆盖群自定义机器人 Webhook 加签(HMAC-SHA256 取十六进制,与钉钉 base64 完全不同)、交互式卡片消息 JSON 全字段解析、企业自建应用 tenant_access_token 缓存与 im/v1/messages 发消息、长连接与 Webhook 回调两种事件订阅方案对比,并附 12 条报错排查表、4 个可直接复制的场景提示词与 3 种安全策略对比。

2026-04-27
#DeepSeek#V4.1 Flash

好物推荐 · 广告合作