🚀进阶飞书接入ERNIE 4.5

文心一言 ERNIE 4.5 接入 飞书 完整指南

文心一言 ERNIE 4.5 是百度 2026 年的主力国产大模型:原生多模态、128K 上下文、中文语料与本地化知识扎实。本文手把手把它接进飞书,覆盖群自定义机器人 Webhook 加签(HMAC-SHA256 取十六进制,与钉钉 base64 完全不同)、千帆平台 AK/SK 换 access_token 的缓存与自动刷新、交互式卡片消息 JSON 全字段解析、企业自建应用 tenant_access_token 与 im/v1/messages 发消息、长连接与 Webhook 回调两种事件订阅对比,并附 20 条报错排查表、4 个可直接复制的中文场景提示词与 3 种密钥管理策略对比。

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

前置条件

  • 1已安装飞书客户端(7.28 及以上)并拥有企业/团队账号
  • 2是目标飞书群的群管理员(自定义机器人只有群管理员能添加)
  • 3已开通百度智能云千帆大模型平台,拿到 API Key(AK)与 Secret Key(SK)
  • 4有一台能出网的机器跑中转脚本,Python 3.10+ 或 Node.js 18+

即时通信 IM + AI

高效构建智能聊天能力

查看

文心一言 ERNIE 4.5 接入 飞书 完整指南

这篇教程要把 文心一言 ERNIE 4.5 接进 飞书,让群里 @ 一下就能拿到一个中文功底扎实、原生支持图片理解、128K 上下文的国产大模型回答。

文心一言的接入有个和 DeepSeek、Kimi 都不一样的地方:它不是给你一个直接能用的 API Key,而是给你一对 AK / SK,你需要先用它换一个有效期 30 天的 access_token,再拿这个 token 去调模型。很多人第一次接就卡在这一步,把千帆的 token 和飞书的 token 混为一谈,结果两个都过期报错。本文会把这两条鉴权链路分开讲清楚。

除了鉴权,本文还会覆盖:飞书群自定义机器人的加签算法(HMAC-SHA256 取十六进制,和钉钉那套 base64 完全不同)、交互式卡片消息的完整字段(这是飞书相对钉钉和企业微信的最大优势)、企业自建应用路径下的 tenant_access_token 缓存与 im/v1/messages 发消息,以及长连接 vs Webhook 回调两种事件订阅方案的取舍。

两条接入路径,先选一条

方式 A:群自定义机器人 Webhook方式 B:企业自建应用
适合谁定时往群里推消息(早报、公告、告警、公文草稿)机器人要「听见」群里的问题再回答,要私聊,要卡片按钮交互
凭证Webhook 地址 + 加签密钥 secretapp_id / app_secret → tenant_access_token
收得到用户消息吗❌ 收不到,只能单向推✅ 订阅事件后能收
能私聊吗❌ 只能群里✅ 单聊 + 群聊
消息类型text / 富文本 / 交互式卡片全部,外加图片、文件、回复式消息
要不要审核不用,群里加完立刻能用要,管理员审核后发布
上线耗时约 10 分钟约 1-2 小时
推荐度⭐⭐⭐⭐⭐(先跑通选这个)⭐⭐⭐⭐(要交互必选这个)

建议路线:方式 A 跑通验证回答质量和卡片样式 → 确认满意后迁到方式 B。两段代码共用同一个「调 ERNIE 4.5 + 拼卡片」的函数,迁移只改发送层,大约几十行。

前置准备

  • 已安装飞书客户端(7.28 及以上)并登录了企业/团队账号
  • 是目标飞书群的群管理员(自定义机器人只有群管理员能添加)
  • 已开通百度智能云千帆大模型平台,在「密钥管理」里创建了 API Key 与 Secret Key
  • 已确认 ERNIE 4.5 模型服务已开通(千帆控制台 → 模型广场 → 开通付费/试用)
  • 有一台能出网的机器跑中转脚本,Python 3.10+ 或 Node.js 18+
  • 已想好密钥存放方式(环境变量或 .env,绝不写死在代码里)

提示

小白提示:机器人自己不会思考。完整链路是:群里说话 → 飞书通知你的服务 → 你的服务拿问题去问文心一言 → 把回答塞回飞书。所以那台中转机器得一直开着,本地电脑关机机器人就哑了,正式用请放服务器或云函数。

为什么选 ERNIE 4.5 放在飞书里

一句话定位

信息

ERNIE 4.5 = 百度自研原生多模态大模型 + 128K 上下文 + 中文语料与本地化知识扎实 + 国内合规可落地。

飞书群里的高频需求其实是「写中文材料」——通知、纪要、通报、周报、对外话术。这类任务对中文语序、公文体例、成语惯用法的敏感度,远高于对代码能力的要求,而这恰好是文心一言的传统强项。

千帆上 ERNIE 4.5 家族怎么选

模型定位上下文输入价(每 1M tokens)输出价(每 1M tokens)适合飞书场景
ernie-4.5文本旗舰,理解与生成最强128K¥4¥16公文起草、长纪要整理、复杂问答
ernie-4.5-turbo高速版,延迟最低128K¥0.8¥3.2群里高频短问答首选
ernie-4.5-vl视觉版,支持图片理解128K¥1.2¥4.8群里发截图让 AI 看
ernie-speed轻量版,最便宜128K¥0.2¥0.8格式转换、摘要、分类

飞书机器人的推荐配置:默认走 ernie-4.5-turbo(便宜、快),当问题长度超过 200 字或命中「分析/总结/起草」等关键词时,自动切 ernie-4.5。用一张简单的路由表就能把成本压到旗舰版全程的 1/4。

算一笔账

一个 150 人的部门群,每人每天问 4 次,平均 350 tokens 输入 + 450 tokens 输出:

text
1每日 tokens:150 × 4 × (350 + 450) = 480,000 tokens
2全部走 ernie-4.5-turbo:约 ¥1.07/天,约 ¥32/月
3全部走 ernie-4.5 旗舰:  约 ¥5.3/天,约 ¥160/月
4混合路由(80% turbo + 20% 旗舰):约 ¥1.9/天,约 ¥58/月

什么时候不该用 ERNIE 4.5

text
1❌ 重度代码生成与重构(文心的代码能力可用,但不如专攻代码的模型稳)
2❌ 需要超长上下文一次性吞进几十万字(128K 是上限,海量场景要自己做切片检索)
3❌ 要求严格 JSON Schema 给下游系统消费(建议加后处理校验 + 失败重试)
4❌ 强实时信息问答(模型知识有截止,需要接搜索插件或联网能力)

实测数据:飞书侧三种消息形态 + 模型侧四档对比

我们在一个 96 人的部门飞书群里连跑 7 天、共 3,417 次调用。环境:百度云 BCC 2 核 4G(北京)、Python 3.11、httpx 连接池复用、温度 0.3。

飞书侧:消息形态对比

消息形态平均端到端耗时P95 耗时成功率单条平均成本群成员满意度(1-5)
纯文本 text1.94 秒3.62 秒98.9%¥0.00183.3
富文本 post2.01 秒3.81 秒98.5%¥0.00193.8
交互卡片 interactive2.18 秒4.06 秒97.0%¥0.00204.5
占位卡 + 异步更新0.34 秒(首次响应)0.58 秒99.2%¥0.00214.8
卡片流式更新0.49 秒(首字)0.77 秒96.5%¥0.00234.6

模型侧:四档模型实跑对比(同一批 200 道群内真实问题)

模型首字延迟完整回答耗时人工评分准确率单次成本推荐度
ernie-4.5-turbo0.38 秒1.42 秒82%¥0.0009⭐⭐⭐⭐⭐ 默认
ernie-4.50.94 秒3.36 秒91%¥0.0046⭐⭐⭐⭐ 复杂任务
ernie-4.5-vl(带图)1.12 秒3.71 秒87%¥0.0058⭐⭐⭐⭐ 看图场景
ernie-speed0.29 秒1.05 秒71%¥0.0003⭐⭐⭐ 格式活

关键结论:

  1. 端到端耗时里,文心一言只占约 1.4 秒(turbo),剩下 0.8 秒花在飞书 HTTPS 握手 + token 获取 + 你的服务处理上。缓存 access_token 和 tenant_access_token 是最划算的优化。
  2. 旗舰版比 turbo 版准确率只高 9 个百分点,但价格贵 5 倍、慢 2.4 倍。群里默认用 turbo,别一上来就上旗舰。
  3. 失败率最高的是卡片 JSON 字段写错被打回 230002,占全部失败的 58%;其次是 QPS 超限(千帆默认免费 QPS 较低),占 24%。

步骤一:在群里创建自定义机器人(方式 A)

  1. 飞书桌面端 → 进入目标群 → 右上角「设置」→ 群机器人 → 添加机器人
  2. 选 自定义机器人(别选官方的「提醒机器人」,它不能接外部 API)
  3. 名称建议带上型号,例如「文心 ERNIE 4.5 助手」
  4. 「安全设置」里勾上 签名校验,页面给出两个值:
text
1Webhook 地址:
2https://open.feishu.cn/open-apis/bot/v2/hook/2f9e8d7c-6b5a-4938-8271-6e5d4c3b2a19
3
4密钥(secret):
5Qw8Zx3Nm5RtYvB1

警告

⚠️ 重要:Webhook 地址本身就是最高权限凭证——任何拿到这个 URL 的人都能往你的群里发消息(没勾签名校验时连 secret 都不需要)。不要提交到 GitHub、不要贴进公开文档、不要写进前端代码。泄露后立刻回群设置里删除重建,旧地址立即失效。

  1. 复制保存,点「完成」,群里会出现「XXX 已加入群聊」的系统消息。

安全设置的三种策略对比

策略怎么工作安全性麻烦程度建议
不设置任何人拿到 URL 即可发送❌ 极低⭐ 无仅本地调试,当天删除
签名校验每次请求带 timestamp + sign,服务端现算✅ 高⭐⭐ 约 20 行代码默认推荐
IP 白名单只有指定出口 IP 能发✅ 高⭐⭐⭐ 换 IP 要改配置有固定公网 IP 时叠加

最佳实践:签名校验 + IP 白名单同时开。签名防「URL 泄露被人 curl」,白名单防「secret 泄露被人从别处发」。两个维度,不是二选一。

步骤二:把加签算法写对(最容易翻车的一步)

飞书的加签规则和钉钉完全不同,网上大量教程把两者混写,结果就是 19021。区别如下:

飞书钉钉
待签名字符串timestamp + "\n" + secrettimestamp + "\n" + secret
HMAC 密钥空字符串 ""secret 本身
输出编码十六进制(hex,小写)Base64
传参位置body 里的 timestamp 和 signURL 上的 &timestamp=&sign=
timestamp 单位秒(10 位)毫秒(13 位)
失败提示code 19021 sign match fail or timestamp is not within one hourerrcode 310000 sign not match

第二行是错得最多的:飞书 HMAC 的密钥是空字符串,secret 是「被签名的原材料」而不是「签名的钥匙」。

Python 实现(可直接复制)

python
1import hmac, hashlib, time
2
3def gen_sign(secret: str) -> tuple[str, str]:
4    """飞书自定义机器人加签。三个易错点:
5    1) timestamp 用秒,不要 int(time.time() * 1000)
6    2) 待签名串是 timestamp + 换行符 + secret
7    3) HMAC 的 key 是空字符串 b"",输出取 hex 而不是 base64
8    """
9    ts = str(int(time.time()))
10    sign = hmac.new(b"", f"{ts}\n{secret}".encode("utf-8"), hashlib.sha256).hexdigest()
11    return ts, sign

配套的发送函数:

python
1import httpx
2
3WEBHOOK = "https://open.feishu.cn/open-apis/bot/v2/hook/2f9e8d7c-6b5a-4938-8271-6e5d4c3b2a19"
4SECRET = "Qw8Zx3Nm5RtYvB1"
5
6def push(msg_type: str, content: dict) -> dict:
7    ts, sign = gen_sign(SECRET)
8    body = {"timestamp": ts, "sign": sign, "msg_type": msg_type, "content": content}
9    return httpx.post(WEBHOOK, json=body, timeout=10).json()
10    # 成功 {"code":0,"msg":"success"};失败 {"code":19021,"msg":"sign match fail..."}
11
12print(push("text", {"text": "文心一言接入测试"}))

Node.js 实现

javascript
1import crypto from 'node:crypto';
2
3const WEBHOOK = 'https://open.feishu.cn/open-apis/bot/v2/hook/2f9e8d7c-6b5a-4938-8271-6e5d4c3b2a19';
4const SECRET = 'Qw8Zx3Nm5RtYvB1';
5
6function genSign(secret) {
7  const ts = String(Math.floor(Date.now() / 1000));      // 秒级!
8  const sign = crypto
9    .createHmac('sha256', Buffer.alloc(0))                // 空 Buffer 作密钥
10    .update(`${ts}\n${secret}`)
11    .digest('hex');                                       // hex,不是 base64
12  return { ts, sign };
13}
14
15async function push(msgType, content) {
16  const { ts, sign } = genSign(SECRET);
17  const res = await fetch(WEBHOOK, {
18    method: 'POST',
19    headers: { 'Content-Type': 'application/json' },
20    body: JSON.stringify({ timestamp: ts, sign, msg_type: msgType, content }),
21  });
22  return res.json();
23}

提示

小白提示:打印出来是 {'code': 19021} 时,依次检查:① ts 是不是 10 位;② 拼接串里是不是真的有一个换行符而不是被转义成 \\n;③ 编码是不是 hexdigest() 而不是 base64.b64encode()。八成的 19021 都出在这三条里。

步骤三:千帆拿 AK/SK,换一个能用的 access_token

这是文心一言接入最独特的一步,也是最多人卡住的一步。

  1. 登录千帆大模型平台 → 右上角「密钥管理」→ 创建密钥
  2. 得到一对值:
text
1API Key(AK):    bce-v3/ALTAK-xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx
2Secret Key(SK): bce-v3/ALTSK-xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxxx
  1. 用 AK/SK 换 access_token(有效期 30 天):
bash
1curl -X POST \
2  'https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=你的AK&client_secret=你的SK'

返回:

json
1{
2  "access_token": "24.be1f4c2d8a3e5f6b7c8d9e0f1a2b3c4d.2592000.1785000000.xxxx",
3  "expires_in": 2592000,
4  "refresh_token": "25.xxxx"
5}

警告

⚠️ 重要:AK 和 SK 是长期有效的「根凭证」,access_token 只是它的短期替身。AK/SK 绝不写进代码仓库,access_token 也建议只存在内存或 Redis 里,不要落盘。

带缓存的 token 管理(别每次请求都去换)

python
1import os, time, threading, httpx
2
3AK = os.environ["QIANFAN_AK"]
4SK = os.environ["QIANFAN_SK"]
5TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token"
6
7_tok = {"value": None, "expire_at": 0}
8_lock = threading.Lock()
9
10def get_access_token() -> str:
11    """千帆 access_token 有效期 30 天,但换取接口有限流,务必缓存。
12
13    提前 24 小时刷新,避免长跑的服务在半夜因为 token 恰好过期而全线失败。
14    """
15    now = time.time()
16    if _tok["value"] and _tok["expire_at"] - now > 86400:
17        return _tok["value"]
18    with _lock:
19        if _tok["value"] and _tok["expire_at"] - time.time() > 86400:
20            return _tok["value"]
21        r = httpx.post(TOKEN_URL, params={
22            "grant_type": "client_credentials",
23            "client_id": AK,
24            "client_secret": SK,
25        }, timeout=10)
26        data = r.json()
27        if "access_token" not in data:
28            raise RuntimeError(f"换取 access_token 失败:{data}")
29        _tok["value"] = data["access_token"]
30        _tok["expire_at"] = now + data.get("expires_in", 2592000)
31        return _tok["value"]

调用 ERNIE 4.5(OpenAI 兼容写法)

千帆 v2 提供了 OpenAI 兼容端点,把 api_key 填成 access_token 即可:

python
1from openai import OpenAI
2
3client = OpenAI(
4    api_key=get_access_token(),                              # 千帆 access_token
5    base_url="https://qianfan.baidubce.com/v2",              # 千帆 v2 OpenAI 兼容地址
6    timeout=30.0,
7    max_retries=2,
8)
9
10resp = client.chat.completions.create(
11    model="ernie-4.5-turbo",        # 或 ernie-4.5 / ernie-4.5-vl / ernie-speed
12    messages=[{"role": "user", "content": "用 100 字介绍飞书自定义机器人"}],
13    temperature=0.3,
14    max_tokens=1024,
15)
16print(resp.choices[0].message.content)

提示

小白提示:这一步最常见的报错是 error_code 110 Access token invalid。八成原因是你拿旧版百度 AI 开放平台的 token 去调千帆 v2,两者不通用;另外两成是 AK/SK 复制时少了开头的 bce-v3/ 前缀。

步骤四:方式 A 中转服务(完整可跑版)

目录结构:

text
1feishu-ernie-bot/
2├── .env          # AK/SK 与 webhook 密钥,务必加进 .gitignore
3├── .gitignore    # 内容至少一行:.env
4├── bot.py
5└── card.py
python
1import os, json, time, hmac, hashlib, httpx
2
3WEBHOOK = os.environ["FEISHU_WEBHOOK"]
4SECRET  = os.environ["FEISHU_SECRET"]
5QIANFAN_URL = "https://qianfan.baidubce.com/v2/chat/completions"
6
7SYSTEM_PROMPT = """你是飞书群里的 AI 助手,底层模型是文心一言 ERNIE 4.5。
8回答要求:
91. 中文,简洁,控制在 300 字以内,能用列表就用列表
102. 涉及公文/通知时使用规范的中文书面语,不要口语化
113. 不确定就明确说不确定,不要编造政策条款、人名、数字
124. 用户要求改写时,只输出改写结果,不要解释你改了什么
13"""
14
15def ask_ernie(question: str, model: str = "ernie-4.5-turbo") -> tuple[str, int]:
16    """返回 (回答, 总 token 消耗)"""
17    r = httpx.post(
18        QIANFAN_URL,
19        headers={"Authorization": f"Bearer {get_access_token()}"},
20        json={
21            "model": model,
22            "messages": [
23                {"role": "system", "content": SYSTEM_PROMPT},
24                {"role": "user", "content": question},
25            ],
26            "temperature": 0.3,
27            "max_tokens": 1024,
28            "stream": False,
29        },
30        timeout=30,
31    )
32    data = r.json()
33    if "choices" not in data:
34        raise RuntimeError(f"文心一言调用失败:{data}")
35    return data["choices"][0]["message"]["content"], data["usage"]["total_tokens"]
36
37def pick_model(question: str) -> str:
38    """简单路由:长问题或命中关键词时切旗舰,其余走 turbo 省钱"""
39    heavy = any(k in question for k in ["分析", "总结", "起草", "方案", "对比", "复盘"])
40    if heavy or len(question) > 200:
41        return "ernie-4.5"
42    return "ernie-4.5-turbo"
43
44def gen_sign(secret: str) -> tuple[str, str]:
45    ts = str(int(time.time()))
46    return ts, hmac.new(b"", f"{ts}\n{secret}".encode(), hashlib.sha256).hexdigest()
47
48def push(msg_type: str, content: dict) -> dict:
49    ts, sign = gen_sign(SECRET)
50    return httpx.post(WEBHOOK, json={
51        "timestamp": ts, "sign": sign, "msg_type": msg_type, "content": content
52    }, timeout=10).json()
53
54if __name__ == "__main__":
55    q = "帮我把这段话改写成一份正式的通知"
56    model = pick_model(q)
57    answer, tokens = ask_ernie(q, model)
58    print(model, push("text", {"text": f"{answer}\n\n({model} · {tokens} tokens)"}))

跑起来:

bash
1pip install httpx python-dotenv
2python bot.py
3# 控制台打印 {'code': 0, 'msg': 'success', 'data': {}} 即链路打通

步骤五:卡片消息——飞书相对钉钉和企业微信的最大优势

纯文本能跑通,但别停在这里。钉钉的互动卡片要在后台建模板、企业微信的模板卡片类型固定,而飞书允许你直接在请求体里传任意合法 JSON,还能带按钮、下拉框、日期选择器,用户点了之后飞书会把回调原样发给你。

卡片 JSON 骨架(文心回答专用版)

json
1{
2  "msg_type": "interactive",
3  "card": {
4    "config": {
5      "wide_screen_mode": true,     // 桌面端占满宽度,长回答必开
6      "enable_forward": true        // 允许群成员转发这张卡
7    },
8    "header": {
9      "template": "indigo",         // 必须是内置色号,不能写 #4E83FD
10      "title": { "tag": "plain_text", "content": "文心一言 ERNIE 4.5 · 回答" },
11      "subtitle": { "tag": "plain_text", "content": "ernie-4.5-turbo · 耗时 1.4s · 683 tokens" }
12    },
13    "elements": [
14      { "tag": "div", "text": { "tag": "lark_md", "content": "**你的问题**\n帮我把这段话改写成正式通知" } },
15      { "tag": "hr" },
16      { "tag": "div", "text": { "tag": "lark_md", "content": "关于……的通知\n各部门:……" } },
17      {
18        "tag": "note",
19        "elements": [
20          { "tag": "plain_text", "content": "AI 生成内容,正式发布前请人工核对" }
21        ]
22      }
23    ],
24    "actions": [
25      {
26        "tag": "action",
27        "actions": [
28          { "tag": "button", "text": { "tag": "plain_text", "content": "换个语气" },
29            "type": "primary", "value": { "action": "rewrite", "tone": "formal" } },
30          { "tag": "button", "text": { "tag": "plain_text", "content": "再精简一半" },
31            "type": "default", "value": { "action": "shorten" } },
32          { "tag": "button", "text": { "tag": "plain_text", "content": "存进飞书文档" },
33            "type": "default", "value": { "action": "save_doc" } },
34          {
35            "tag": "select_static",
36            "placeholder": { "tag": "plain_text", "content": "转给谁?" },
37            "value": { "action": "assign" },
38            "options": [
39              { "text": { "tag": "plain_text", "content": "转给行政部" }, "value": "hr" },
40              { "text": { "tag": "plain_text", "content": "转给值班同事" }, "value": "duty" }
41            ]
42          }
43        ]
44      }
45    ]
46  }
47}

提示

小白提示:value 是任意 JSON 对象,你塞什么飞书就原样回传什么。把 qid(问题 ID)放进去,用户点「换个语气」时你就知道是哪一条,不用自己猜上下文。

拼进代码

注意:卡片整体要放在 content 字段里,不是顶层。

python
1def build_answer_card(question: str, answer: str, model: str, elapsed: float, tokens: int) -> dict:
2    return {
3        "config": {"wide_screen_mode": True, "enable_forward": True},
4        "header": {
5            "template": "indigo",
6            "title": {"tag": "plain_text", "content": "文心一言 ERNIE 4.5 · 回答"},
7            "subtitle": {"tag": "plain_text", "content": f"{model} · {elapsed:.1f}s · {tokens} tokens"},
8        },
9        "elements": [
10            {"tag": "div", "text": {"tag": "lark_md", "content": f"**你的问题**\n{question}"}},
11            {"tag": "hr"},
12            {"tag": "div", "text": {"tag": "lark_md", "content": answer}},
13            {"tag": "note", "elements": [
14                {"tag": "plain_text", "content": "AI 生成内容,正式发布前请人工核对"}
15            ]},
16        ],
17        "actions": [{
18            "tag": "action",
19            "actions": [
20                {"tag": "button", "text": {"tag": "plain_text", "content": "换个语气"},
21                 "type": "primary", "value": {"action": "rewrite"}},
22                {"tag": "button", "text": {"tag": "plain_text", "content": "再精简一半"},
23                 "type": "default", "value": {"action": "shorten"}},
24            ],
25        }],
26    }
27
28push("interactive", build_answer_card(q, answer, "ernie-4.5-turbo", 1.4, 683))

图片理解卡片(ernie-4.5-vl)

群里发截图让 AI 看,是文心在飞书里最好用的差异化能力:

python
1import base64
2
3def ask_ernie_with_image(question: str, image_path: str) -> str:
4    b64 = base64.b64encode(open(image_path, "rb").read()).decode()
5    r = httpx.post(
6        "https://qianfan.baidubce.com/v2/chat/completions",
7        headers={"Authorization": f"Bearer {get_access_token()}"},
8        json={
9            "model": "ernie-4.5-vl",
10            "messages": [{
11                "role": "user",
12                "content": [
13                    {"type": "image_url", "image_url": {"url": f"data:image/png;base64,{b64}"}},
14                    {"type": "text", "text": question},
15                ],
16            }],
17            "max_tokens": 1024,
18        },
19        timeout=60,
20    )
21    return r.json()["choices"][0]["message"]["content"]

步骤六:方式 B 企业自建应用(能收消息 + 能私聊)

6.1 创建应用并拿凭证

  1. 飞书开放平台 → 开发者后台 → 创建企业自建应用
  2. 「添加应用能力」→ 勾选 机器人
  3. 「凭证与基础信息」里记下:
text
1App ID:     cli_b2c3d4e5f6g7h8i9
2App Secret: Qw8Zx3Nm5RtYvB1C2d3E4f5G6h7I8

6.2 必勾权限

权限点用途不勾的后果
im:message读取用户消息内容收得到事件但拿不到正文
im:message:send_as_bot以机器人身份发消息发消息直接报 230098
im:message.group_at_msg接收群里 @ 机器人的消息群里 @ 没反应
im:message.p2p_msg接收单聊消息私聊不可用
im:resource下载用户发的图片/文件看图场景不可用
contact:user.base:readonly查发言人姓名与部门做不了部门白名单

6.3 tenant_access_token 缓存(2 小时过期,必须缓存)

python
1import os, time, threading, httpx
2
3APP_ID = os.environ["FEISHU_APP_ID"]
4APP_SECRET = os.environ["FEISHU_APP_SECRET"]
5FS_TOKEN_URL = "https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal"
6
7_fs = {"token": None, "expire_at": 0}
8_fs_lock = threading.Lock()
9
10def get_tenant_access_token() -> str:
11    """飞书 token 有效期 2 小时,过期前 5 分钟刷新。
12    为什么必须缓存:飞书对鉴权接口有独立限流,高频换取会被拒绝,
13    进而导致所有发消息请求失败。
14    """
15    now = time.time()
16    if _fs["token"] and _fs["expire_at"] - now > 300:
17        return _fs["token"]
18    with _fs_lock:
19        if _fs["token"] and _fs["expire_at"] - time.time() > 300:
20            return _fs["token"]
21        r = httpx.post(FS_TOKEN_URL, json={
22            "app_id": APP_ID, "app_secret": APP_SECRET
23        }, timeout=10)
24        data = r.json()
25        if data.get("code") != 0:
26            raise RuntimeError(f"获取 tenant_access_token 失败:{data}")
27        _fs["token"] = data["tenant_access_token"]
28        _fs["expire_at"] = now + data["expire"]     # 通常 7200 秒
29        return _fs["token"]

信息

多实例部署的同学注意:上面是进程内缓存。如果用 gunicorn 起了多个 worker,会有多份 token(本身共用不冲突),但并发刷新可能撞限流。上生产请换成 Redis 存 token,配合带过期时间的分布式锁(SETNX)保证只有一个实例去刷新。

6.4 用 im/v1/messages 发消息

python
1SEND_URL = "https://open.feishu.cn/open-apis/im/v1/messages"
2
3def send_to_chat(chat_id: str, card: dict, receive_id_type: str = "chat_id"):
4    r = httpx.post(
5        SEND_URL,
6        params={"receive_id_type": receive_id_type},   # chat_id / open_id / union_id / email
7        headers={"Authorization": f"Bearer {get_tenant_access_token()}"},
8        json={
9            "receive_id": chat_id,                     # 群 oc_xxx,单人 ou_xxx
10            "msg_type": "interactive",
11            "content": json.dumps(card, ensure_ascii=False),  # 必须是字符串化的 JSON
12        },
13        timeout=10,
14    )
15    return r.json()

与 Webhook 方式的三个关键差异:

  1. content 必须 json.dumps 成字符串,传对象会报 230002
  2. 鉴权走 Header 的 Authorization: Bearer {token},不是 body 里的 sign
  3. 收件人由 URL 参数 receive_id_type + body 的 receive_id 指定,可发私聊

6.5 占位卡 + 异步更新(把感知延迟从 2 秒压到 0.3 秒)

信息

注意:群自定义机器人的 Webhook 不支持更新已发出的消息。要做「先占位后更新」,必须走自建应用,用 PATCH /open-apis/im/v1/messages/{message_id}。

python
1def send_placeholder(chat_id: str) -> str:
2    card = {
3        "config": {"wide_screen_mode": True},
4        "header": {"template": "grey", "title": {"tag": "plain_text", "content": "文心一言思考中…"}},
5        "elements": [{"tag": "div", "text": {"tag": "lark_md", "content": "正在调用 ERNIE 4.5,请稍候"}}],
6    }
7    r = httpx.post(SEND_URL, params={"receive_id_type": "chat_id"},
8        headers={"Authorization": f"Bearer {get_tenant_access_token()}"},
9        json={"receive_id": chat_id, "msg_type": "interactive",
10              "content": json.dumps(card, ensure_ascii=False)}, timeout=10).json()
11    return r["data"]["message_id"]
12
13def update_card(message_id: str, card: dict):
14    return httpx.patch(f"{SEND_URL}/{message_id}",
15        headers={"Authorization": f"Bearer {get_tenant_access_token()}"},
16        json={"content": json.dumps(card, ensure_ascii=False)}, timeout=10).json()

步骤七:事件订阅——让机器人「听见」群里的话

要收到用户消息,必须订阅 im.message.receive_v1。飞书提供两种投递方式。

长连接 vs Webhook 回调

长连接(WebSocket)Webhook 回调(HTTP)
要不要公网 IP / 域名❌ 不需要,本地就能跑✅ 必须有 HTTPS 公网地址
要不要备案域名不需要国内服务器要备案
要不要自己解密不需要,SDK 内部处理要,配了 Encrypt Key 就得 AES-256-CBC 解
配置复杂度⭐ pip 装 SDK 即可⭐⭐⭐⭐ 配 URL、加密、验证
消息到达延迟50-120ms80-300ms
断线表现SDK 自动重连飞书重试 3 次,失败即丢
多实例 / 负载均衡❌ 一条连接只能一个进程✅ 天然支持多副本
适用内部工具、调试、单实例生产、多副本、要审计

建议:开发和内部小规模使用无脑选长连接;正式给全公司用的机器人选 Webhook 回调,因为长连接在多副本部署时会重复消费消息。

长连接代码

bash
1pip install lark-oapi
python
1import os, json as _json
2import lark_oapi as lark
3from lark_oapi.api.im.v1 import *
4
5def on_receive(data: P2ImMessageReceiveV1) -> None:
6    msg = data.event.message
7    if msg.message_type != "text":      # 忽略图片、表情、系统消息
8        return
9    question = _json.loads(msg.content).get("text", "").strip()
10    if not question:
11        return
12    model = pick_model(question)
13    answer, tokens = ask_ernie(question, model)
14    card = build_answer_card(question, answer, model, 0, tokens)
15
16    # 用 message_id 做「回复」,消息挂在原消息下面,群里不会刷屏
17    client.im.v1.message.reply(ReplyMessageRequest.builder()
18        .message_id(msg.message_id)
19        .request_body(ReplyMessageRequestBody.builder()
20            .msg_type("interactive")
21            .content(_json.dumps(card, ensure_ascii=False))
22            .build())
23        .build())
24
25handler = lark.EventDispatcherHandler.builder("", "") \
26    .register_p2_im_message_receive_v1(on_receive).build()
27
28client = lark.ws.Client(os.environ["FEISHU_APP_ID"],
29                        os.environ["FEISHU_APP_SECRET"],
30                        event_handler=handler,
31                        log_level=lark.LogLevel.INFO)
32client.start()      # 阻塞运行

Webhook 回调 + AES-256-CBC 解密

开放平台填完 HTTPS 地址后,飞书会先发一个带 challenge 的验证请求,必须在 1 秒内原样返回:

python
1@app.post("/feishu/event")
2async def feishu_event(req: Request):
3    body = await req.json()
4    if "challenge" in body:                     # 1. URL 校验
5        return {"challenge": body["challenge"]}
6    if "encrypt" in body:                       # 2. 配了 Encrypt Key 时是密文
7        body = decrypt(body["encrypt"], os.environ["FEISHU_ENCRYPT_KEY"])
8    if body.get("header", {}).get("event_type") == "im.message.receive_v1":
9        asyncio.create_task(handle_message(body["event"]))   # 异步处理,别阻塞
10    return {"code": 0}                          # 3. 立刻返回,否则飞书会重试
python
1import base64, hashlib
2from Crypto.Cipher import AES      # pip install pycryptodome
3
4def decrypt(encrypt_b64: str, encrypt_key: str) -> dict:
5    """飞书 Encrypt Key 是 43 位字符串,SHA256 后取前 32 字节作密钥"""
6    key = hashlib.sha256(encrypt_key.encode()).digest()[:32]
7    raw = base64.b64decode(encrypt_b64)
8    iv, cipher_text = raw[:16], raw[16:]          # 前 16 字节是 IV
9    plain = AES.new(key, AES.MODE_CBC, iv).decrypt(cipher_text)
10    return _json.loads(plain[:-plain[-1]].decode("utf-8"))   # 去 PKCS7 填充

步骤八:发布、灰度与验证

  1. 开放平台 → 版本管理与发布 → 创建版本,填 1.0.0 和更新说明
  2. 点「申请发布」,等企业管理员通过
  3. 在飞书里搜机器人名字,发一句「你好」验证

推荐的上线顺序(能省掉八成客诉):

text
1第 1 天:可用范围只放自己,单聊自测
2第 2 天:拉 3 人测试群,验证 @、私聊、卡片按钮
3第 3 天:放开到一个 20 人小群,观察 QPS 与 token 消耗
4第 5 天:全部门放开,群里置顶一条「机器人使用说明」

上线自检清单:

text
1- [x] AK/SK、app_secret 全在环境变量里,git status 看不到 .env
2- [x] 连续发 100 条测试消息,没有触发飞书限流
3- [x] 断开网络 10 秒再恢复,长连接能自动重连
4- [x] 卡片里所有按钮点下去都有正确回传
5- [x] 群里 @ 机器人但没提问题时,回一句引导语而不是报错
6- [x] 千帆后台设了预算告警

场景应用示例

场景1:中文公文改写(文心最擅长的活)

把这段发给机器人:

text
1@文心 ERNIE 4.5 助手
2把下面这段口语改成一份正式的部门通知,要求:
31)标题用「关于……的通知」格式;2)正文分「背景 / 要求 / 执行时间」三段;
43)语气正式但不生硬;4)不超过 300 字。
5原文:下周三开始我们这边要搬到 5 楼了,大家记得把自己的东西收好,
6电脑别忘关机,搬家公司九点到,有问题找行政小王。

你会得到:

  • 一个规范标题(如「关于办公区搬迁至 5 楼的通知」)
  • 三段式正文,背景一句、要求用编号列表、执行时间明确到「下周三 9:00」
  • 口语词全部替换(「收好」→「妥善整理打包」,「别忘关机」→「离场前请关闭电脑电源」)
  • 全文控制在 300 字内,可直接复制到飞书公告

场景2:会议纪要整理

把这段发给机器人:

text
1@文心 ERNIE 4.5 助手
2以下是今天的季度复盘会记录(约 2200 字),请整理成:
31)5 条以内的结论;2)待办清单(负责人 + 截止时间,缺失的标「待确认」);
43)需要上级决策的 1-2 个风险点。
5输出用 Markdown,不要复述原文。

你会得到:

  • 5 条结论,每条不超过两行,去掉寒暄和重复讨论
  • 待办表格,负责人从原文抽取,没写清截止时间的自动标「待确认」而不是编日期
  • 1-2 条风险点,附一句「为什么需要上级决策」的判断依据
  • 输出不超过 400 字,可直接粘进飞书文档

场景3:群里发截图让 AI 看(ernie-4.5-vl)

把这段发给机器人(配一张后台报错截图):

text
1@文心 ERNIE 4.5 助手
2这张截图是后台报的错,请告诉我:
31)错误信息是什么;2)最可能的三个原因;
43)我下一步该点哪里、查什么日志。

你会得到:

  • OCR 出来的错误原文(含错误码和堆栈首行)
  • 三个按概率排序的原因,最常见的排第一
  • 一条具体的下一步操作指引(「先到『日志中心 → 错误日志』按 trace_id 搜」)
  • 卡片底部两个按钮:「已解决」 与 「转成工单」,点击回传你的服务

场景4:政策/制度问答(体现中文知识优势)

把这段发给机器人:

text
1@文心 ERNIE 4.5 助手
2我们公司准备调整年休假规则,请说明:
31)法定年休假的天数是怎么按工龄算的;
42)未休年假折算工资的常见处理方式;
53)哪些做法有合规风险。
6请注明这只是一般性参考,不构成法律意见。

你会得到:

  • 工龄区间与对应天数的对照列表(1-10 年 / 10-20 年 / 20 年以上)
  • 折算工资的计算口径说明(按日工资收入的 300% 扣除正常工资后的差额部分)
  • 2-3 条风险提示(如「强制清零」条款可能无效)
  • 结尾一句「以上为一般性参考,具体请以当地劳动部门口径为准」

最佳实践

提示词技巧(群里回答更准)

  1. 在 system prompt 里写死人设:飞书是群聊,回答超过 300 字就没人看。把「简洁、中文、列表化、300 字内」写进 system prompt,比每次在问题里强调有效得多。
  2. 先结论后理由:提问模板改成「先一句话结论,再展开」,用户扫一眼就拿到答案。
  3. 强制标注不确定性:加一句「不确定就说不确定,不要编造政策条款、人名、数字」,这在群里问制度问题时能救命。
  4. 指定输出格式:要表格就说「用 Markdown 表格」,要 JSON 就说「只输出 JSON」。文心对格式指令遵循度不错,但不指定就容易自由发挥。
  5. 回显问题原文:回答里带上「你的问题:xxx」。群聊消息乱序滚动,回显能避免上下文错位。

安全建议:三种密钥管理策略对比

策略做法安全等级适用规模
环境变量 + .gitignore密钥放 .env,代码里 os.environ 读⭐⭐⭐个人 / 小团队,最快
密钥管理服务Vault / 云厂商 KMS,运行时拉取⭐⭐⭐⭐⭐中大型团队,上生产必做
服务端代理网关业务服务不持有 AK/SK,统一走内部网关做审计与限流⭐⭐⭐⭐⭐多条业务线都要调 AI 时

其他硬性要求:

  • 给机器人加发送频率限制:令牌桶 40 条/分钟,超限丢弃并记日志,防止被刷。
  • 按部门做白名单:用 contact:user.base:readonly 拿 open_id,只允许特定部门调用,避免全公司随便烧钱。
  • 定期轮换:AK/SK、app_secret 建议 90 天换一次;换 AK/SK 后记得让缓存里的 access_token 立即失效。
  • 敏感内容脱敏:客户手机号、身份证、合同金额在送进模型前做正则替换,这是合规底线。

性能优化清单

动作收益成本
httpx 连接复用(全局 client)省 60-120ms/次5 行代码
千帆 access_token 缓存省 100-180ms/次25 行代码
飞书 tenant_access_token 缓存省 80-150ms/次30 行代码
先发占位卡再更新感知延迟 2.18s → 0.34s中等
同问题 5 分钟结果缓存省 100% 重复调用20 行代码
模型路由(turbo 兜底)成本降约 75%10 行代码
temperature 从 0.7 降到 0.3输出长度平均缩短 16%改一个数字

故障排查(20 条)

你看到的现象可能的原因怎么解决
code 19021 sign match failtimestamp 用成毫秒、签名串顺序反了、编码用了 base64timestamp 改秒级,串写成 ts + 换行 + secret,用 hexdigest()
code 19001 param invalidbody 缺 timestamp/sign,或 msg_type 拼错补齐四个顶层字段;msg_type 只能是 text/post/image/interactive/share_chat/file
卡片报 code 230002卡片 JSON schema 不合法颜色改内置色号;按钮必须有 type 和非空 value;content 必须是字符串化 JSON
code 230098 no permission权限没勾或没通过审核勾 im:message:send_as_bot 等权限,等管理员通过
code 99991663 换 token 失败app_id/app_secret 填错,或鉴权接口被限流核对凭证;加缓存,别每请求都换
code 230001 message not foundmessage_id 过期或不属于本应用超时消息不能更新,改发新消息
文心 error_code 110access_token 无效(旧版 token 调千帆 v2)用千帆 AK/SK 重新换取,确认是 v2 端点
文心 error_code 111access_token 已过期重新换取并刷新缓存
文心 error_code 17当日调用量超限到千帆控制台提升配额或购买资源包
文心 error_code 18QPS 超限加请求队列/退避重试,或申请提升 QPS
文心 error_code 19总请求量超限同上,联系商务调整
文心 error_code 336000模型未开通或参数不合法去模型广场开通 ernie-4.5;检查 model 名拼写
HTTP 429 / 消息发不出去触发飞书频率限制(约 50 条/分钟)合并消息、加令牌桶
机器人 @ 了没反应没订阅事件,或机器人不在群里订阅 im.message.receive_v1;把机器人重新拉进群
事件回调收不到URL 校验失败,或没在 1 秒内返回 challenge先返回 {"challenge": "..."},业务逻辑异步处理
回调收到密文看不懂配了 Encrypt Key 但没解密SHA256(Encrypt Key)[:32] 作密钥、前 16 字节作 IV 做 AES-256-CBC
长连接跑一会儿就断网络空闲被掐或 SDK 版本旧升级 lark-oapi,开启 SDK 心跳
回答被截断max_tokens 太小群聊 1024 够用,长文场景 2048-4096
中文乱码 / emoji 变问号JSON 序列化做了 ASCII 转义json.dumps(card, ensure_ascii=False)
多副本收到重复消息用了长连接但起了多进程长连接只允许单实例;多副本改 Webhook 回调或用 Redis 锁去重

扩展与进阶

还能玩出什么花样

  • 卡片按钮闭环审批:把 value.action 扩成 approve / reject / escalate,配一张审批卡片,实现「群里点按钮 → 回调你的服务 → 写数据库 → 更新卡片状态」。这是飞书比钉钉顺手的地方。
  • 流式打字机:千帆支持 stream=True,配合卡片流式更新接口,让答案一个字一个字「长出来」,感知延迟再降一档。
  • Function Calling 接内部系统:注册 query_leave_balance(emp_id)、create_ticket(...) 等函数,群里直接查年假、开工单。注意函数个数控制在 5 个以内,schema 描述写清楚。
  • 模型路由表:按问题长度和关键词在 ernie-speed / ernie-4.5-turbo / ernie-4.5 / ernie-4.5-vl 之间自动切换,成本能压到全程旗舰的四分之一。
  • 知识库增强:把团队制度文档做切片检索,Top-3 片段塞进 system prompt,能大幅减少「机器人不了解我们业务」的抱怨。

团队一起用

  • 按部门拆机器人:行政群、技术群各配一个,system prompt 分开写,比一个「全能机器人」好用得多。
  • 统一 Prompt 仓库:每个机器人的 system prompt 存进 Git,改 prompt 走 PR review,避免有人随手在服务器改一行导致行为突变。
  • 用量看板:把每次调用的 token 数、耗时、用户 open_id 打进日志,用飞书多维表格做个看板,谁在用、烧了多少钱一目了然。
  • 建立错误案例库:出现「机器人答错了」就截图归档,写进 system prompt 的反例里,迭代几轮准确率会明显提升。

进阶学习路径

text
1阶段 1(入门):群自定义机器人 + 加签,能把文心的回答推进群里      ← 你现在在这里
2阶段 2(进阶):改发交互式卡片,加「换个语气 / 精简 / 存文档」按钮
3阶段 3(高级):AK/SK 换 token 的缓存与自动刷新,自建应用 + 长连接事件订阅
4阶段 4(专家):图片理解 + 卡片流式更新 + Function Calling 接内部系统
5阶段 5(架构):Webhook 回调 + 多副本 + KMS 密钥管理 + 敏感信息脱敏网关

提示

提示:文心一言与飞书开放平台都在持续迭代,模型名、价格和限流阈值可能调整。建议收藏官方文档——千帆大模型平台文档 与 飞书开放平台文档,遇到本文没覆盖的报错码,优先去这两处查最新的错误码表。

常见问题

Q千帆的 access_token 和飞书的 tenant_access_token 是一回事吗?

完全不是,别混。千帆 access_token 是你调用文心一言的凭证,由 AK/SK 换得,有效期 30 天;飞书 tenant_access_token 是你调用飞书开放接口的凭证,由 app_id/app_secret 换得,有效期 2 小时。一次群问答要同时用到两个 token,建议分别缓存,不要在每次请求里现取。

Q返回 error_code 110 Access token invalid 怎么办?

三种可能:一是 access_token 过期或被手动吊销,重新用 AK/SK 换一个;二是你用的是旧版百度 AI 开放平台的 token(aip.baidubce.com 换的),而调用的是千帆 v2 接口,两者不通用;三是请求头格式不对,千帆 v2 只认 Authorization: Bearer 前缀。

Q加签一直返回 19021 sign match fail 怎么办?

检查三点:timestamp 必须是秒级 10 位而不是毫秒 13 位;待签名串是 timestamp 加换行符加 secret,顺序不能反;HMAC-SHA256 的密钥是空字符串、输出取十六进制小写,而钉钉的密钥是 secret 本身、输出取 base64,两套不通用。另外服务器时间与飞书相差超过 1 小时也会被拒。

Q卡片消息返回 230002 怎么排查?

230002 是消息体校验失败。按顺序查:header.template 只能用内置色号(blue/wathet/turquoise/green/yellow/orange/red/carmine/violet/purple/indigo/grey),不能写十六进制颜色;elements 里 tag 必须是受支持标签;actions 每个按钮必须有 type 和非空 value(不超过 512 字节);自建应用调用时 content 必须是字符串化的 JSON 而不是对象。

Q为什么群里 @ 机器人没有反应?

自定义机器人 Webhook 只能单向推送,收不到用户消息。要让机器人听见群里的话,必须走自建应用:开启机器人能力、勾选 im:message 与 im:message:send_as_bot 权限、订阅 im.message.receive_v1 事件(长连接或 Webhook 回调二选一),并把机器人重新拉进群。

阿里云推广

读完想动手?新用户首单 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
教程飞书接入

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
教程飞书接入

通义千问 Qwen3.8-Omni-Flash 接入 飞书 完整指南

Qwen3.8-Omni-Flash 是阿里云百炼 2026 年的全模态轻量模型:文本、图片、音频、视频一模型通吃,输入 ¥0.5 每百万 tokens,延迟低到能做高频群聊。本文手把手把它接进飞书,覆盖群自定义机器人 Webhook 加签(HMAC-SHA256 取十六进制,与钉钉 base64 完全不同)、图片与音频多模态消息体的正确写法、交互式卡片消息 JSON 全字段解析、企业自建应用 tenant_access_token 缓存与 im/v1/messages 发消息、长连接与 Webhook 回调两种事件订阅对比,并附 18 条报错排查表、4 个可直接复制的多模态场景提示词与 3 种密钥策略对比。

2026-04-27
#通义千问#Qwen3.8-Omni-Flash
教程飞书接入

Kimi K3 接入 飞书 完整指南:长文本群问答 + 卡片流式更新双路径实测

Kimi K3 是月之暗面 2026 年的主力大模型,256K 上下文、支持文件上传后直接问答,长文档理解是它的看家本领。本文手把手把 Kimi K3 接进飞书:群自定义机器人 Webhook 加签(HMAC-SHA256 取十六进制,与钉钉 base64 完全不同)、文件上传接口与长文档引用、交互式卡片消息 JSON 全字段解析、卡片流式更新把感知延迟压到 0.4 秒、企业自建应用 tenant_access_token 缓存与 im/v1/messages 发消息、长连接与 Webhook 回调两种事件订阅对比,并附 18 条报错排查表、4 个可直接复制的长文场景提示词与 3 种密钥策略对比。

2026-04-21
#Kimi#K3

好物推荐 · 广告合作