☰
扣子平台飞书钉钉机器人部署:企业内网智能助手落地指南
2026/10/6 4:22:18 网站建设 项目流程

简介:针对企业内网环境下飞书/钉钉智能助手部署需求,这份实操型指南由技术社区作者整理,面向企业IT管理人员、系统集成工程师、办公自动化开发者及具备一定技术基础的运维人员,重点解决智能办公机器人在内网落地难的问题。资源围绕字节跳动扣子机器人展开,系统讲解从平台注册、应用创建、权限配置、回调设置到工作流搭建、知识库关联及发布测试的完整部署链路;同时深入剖析内网环境中的网络访问限制、数据安全、稳定性与性能优化等核心难点,并针对消息发送失败、权限不足、网络连接异常等高频故障,提供系统性排查思路与解决方案。整包为1个docx文档,压缩后仅33KB,内容精炼,聚焦核心配置,适合结合实际内网环境边操作边对照阅读。已有140人学习下载,可直接支撑企业构建基于知识库的智能问答系统、实现飞书/钉钉端办公自动化流程,也能辅助打通内网系统与外部协作平台的通信链路,是企业团队落地内网智能助手的实用参考。

1. 扣子平台加飞书钉钉机器人:企业内网智能助手部署前必须先想清楚的一件事

如果你的企业已经有人在用扣子(Coze)智能体平台把问答Bot调得头头是道,但真要让它在飞书群里回答"报销到哪一步了""考勤异常怎么处理"时,卡住的往往不是模型效果,而是机器人到底怎么进群、事件从哪里来、消息回到哪里去。我见过太多团队在扣子平台上把知识库、工作流都搭好了,最后倒在一张"事件订阅地址"上:飞书回调验证不过、钉钉机器人只会发消息却收不到@、内网接口根本够不着。这篇笔记把"智能办公基于扣子平台的飞书钉钉机器人部署"拆成一条能照做的路径,覆盖架构选型、Bot编排、双端接入、参数配置和踩坑顺序。适合被安排去落地企业内网智能助手的运维、开发和产品同学,也适合已经把Bot跑通但接不回IM的玩家。

2. 部署前先定架构:机器人形态、内网边界与前置条件

2.1 扣子平台在链条里的位置:编排大脑,但不是终端

扣子(Coze)智能体平台在整个方案里解决的是"理解、检索、编排、调用":对话上下文、企业知识库问答、多步工作流、HTTP请求节点去调内部接口,这些能力全部集中在扣子侧。飞书和钉钉的角色是"终端触点":把员工的问题送进来,把答案送回群里。这个分工决定了部署时哪边该做什么——扣子侧做重活,IM侧做通道,中间用Webhook、事件订阅或OpenAPI连接。

很多团队把"扣子平台"和"飞书钉钉机器人"当成一个大黑匣子,以为在扣子上点了发布就结束了。实际上,扣子Bot被发布到IM渠道之后,飞书/钉钉云端只是把用户消息转发给扣子托管的回调服务,再由扣子执行工作流后把结果写回。一旦工作流里要访问企业内网的系统,这条链路就会出现第三者插足的问题:扣子云端在公网,你的数据库和OA在防火墙后面。这个矛盾必须在动手前解决,否则后面全是返工。

2.2 先分清三类机器人:Webhook、企业自建应用、扣子发布渠道

我在给客户做方案时,第一步永远是确认要用哪一类机器人。飞书和钉钉对"机器人"的定义略有差异,但本质上可以分成三类:

机器人类型能收消息能主动发消息能发卡片部署成本适用场景
自定义Webhook机器人否是部分支持极低告警通知、定时推送
企业自建应用机器人是是是中双向对话、@唤起、内网助手
扣子发布渠道是是依赖渠道低快速验证、不碰内网数据

常见误区是:群里拉个自定义机器人,配个关键词就以为能当智能助手。这类机器人只能单向推送,员工在群里@它,它收不到,自然也不会有"对话"。想做智能办公助手,飞书侧要建"企业自建应用",钉钉侧要建"企业内部应用",把机器人能力挂进应用里。扣子发布渠道适合先跑通对话逻辑,正式接入内网数据时还是回到自建应用这条路上。

2.3 内网数据怎么打通:直接发布与内网中转两种拓扑

企业内网智能助手最核心的问题是"扣子在公网,数据在内网"。常见做法有两种。

拓扑A是扣子直连:Bot直接发布到飞书/钉钉渠道,扣子工作流里的HTTP节点指向一个已发布到公网HTTPS的网关,由网关转发到内网服务。优点是链路短,缺点是内网必须有出口暴露,安全和合规成本高,不少企业IT根本不给开。

拓扑B是内网中转,也是我更推荐的方式:飞书/钉钉的事件回调送到内网部署的机器人网关服务,这个服务收到消息后调用"扣子开放平台的Chat接口"(把用户消息提交给已发布的Bot,拿到结构化回答),再通过IM API把回答发回群里。整条链路中,内网服务只需要主动出网访问扣子的API,不需要为IM云端暴露任何内网端口。钉钉的Stream模式更是内网友好——服务主动维持一条长连接,IM云端把消息推过来,连公网回调地址都省了。

这一节要下结论的话:如果只是做"规章制度问答、话术助手",拓扑A就能跑;只要涉及查库、查单、查人,直接上拓扑B,不要犹豫。

2.4 动手前的五样清单

进入配置前,我一般会先确认下面五样东西,缺一样都不要开工:

  • 扣子账号,确认是个人版还是企业版,企业版才有团队空间和更好的权限隔离;
  • 飞书开放平台管理员权限,能创建企业自建应用;
  • 钉钉开发者后台权限,能创建企业内部应用;
  • 一个可用的内网HTTP服务运行环境,哪怕先在一台开发机上跑也行;
  • 回调地址的HTTPS证书方案,自签证书在飞书/钉钉校验时会直接被拒绝。

把这些准备好,再做扣子侧配置,顺序才不会乱。

3. 在扣子上搭出"会办事"的助手:知识库、工作流与OpenAPI兜底

3.1 最小可用配置顺序:先会话,再知识库,后工作流

进入扣子工作台后,我习惯不急着配一堆节点,而是按"三步走"把最小闭环跑通。

第一步先创建一个Bot,给一套简洁的System Prompt,写明角色、职责边界、回答风格,比如"你是企业IT服务助手,只回答与IT报修、账号权限、网络故障相关的问题,不确定时引导用户转人工"。第二步把企业已有的制度文档、FAQ扔进知识库,让Bot能引用内容回答。第三步才加工作流,把"需要调接口"的动作做成节点。

这套顺序的好处是能快速定位问题出在哪一层:问答不准,多半是知识库或Prompt;接口拿不到数据,才是工作流和网络问题。

3.2 知识库分块与检索参数:不是文档越多越好

知识库是智能助手性价比最高的部分,但参数设置直接影响回答质量。

分块策略上,我一般按"语义段落"切,而不是简单按字符数固定切。钉钉、飞书的文档中心都有大量表格和分条描述,固定字符切会切断上下文。如果文档格式比较规整,可以把每条制度、每个FAQ条目当成独立块。

检索参数有两处必须调:一是"Top K",也就是召回多少块文本进入上下文,我一般设置在4到6;二是"相似度阈值",低于这个阈值就不采用检索结果。阈值太高会答不上来,太低会把不相关内容拼进答案。经验值是阈值从0.35起步,按照回答效果微调。企业知识库里重复率高时,记得开去重,可以明显减少答案里出现多份矛盾的制度文本。

3.3 用HTTP请求节点打通内网接口(或中转网关)

扣子工作流里的"HTTP Request"节点是把能力变成"可办事"的关键。它相当于一个轻量API客户端,把参数拼进URL或Body,把响应解析出来再交给LLM组织成自然语言。

参数推荐配置说明
URL内网网关或公网网关的HTTPS地址拓扑B中指向内网中转服务的开放接口
MethodGET/POST查询类用GET,写入类用POST
HeadersAuthorization: Bearer token网关鉴权,别裸奔
Query按接口文档拼参数时间范围、部门ID等从对话中抽取
BodyJSON格式结构优先,方便后续解析
超时15秒内部接口一般够用,超过就失败
重试1次多试容易产生重复数据

你说"查一下本周考勤异常",扣子先通过LLM把"本周、考勤异常"抽成语义槽,再在工作流里映射成接口输入。问题在于:这个HTTP请求节点是从扣子云端发出的,如果你的接口只在内网,它根本够不到。这正是上一章拓扑B存在的意义——内网中转服务收到IM消息后调用扣子,扣子工作流里的HTTP节点再回过头来调用中转服务暴露的接口,或者干脆由中转服务直接查内网库,把结果当作附加消息提交给扣子。两条路都行,但都要提前在扣子侧把接口地址配好。

3.4 发布到渠道后,用OpenAPI做兜底调用

扣子Bot发布到飞书/钉钉渠道后,日常使用没问题。但内网中转服务如果要自己控制收发时机、想记录完整对话日志,更稳的做法是直接调扣子开放平台的Chat接口。这个接口接收用户消息,返回Bot的完整回复,调用方式如下:

import requests API_BASE = "https://api.coze.cn" # 按账号所在区域选 coze.cn 或 coze.com BOT_ID = "你的Bot_ID" # 扣子Bot发布页可以找到 PAT = "你的个人访问令牌" # 扣子开放平台后台生成 def ask_coze(user_text: str) -> str: payload = { "bot_id": BOT_ID, "user_id": "employee-10001", # 用员工唯一ID,保持会话连续 "stream": False, # 内网中转建议用非流式,等完整结果 "auto_save_history": True, "additional_messages": [ { "role": "user", "content": user_text, "content_type": "text" } ] } resp = requests.post( f"{API_BASE}/v3/chat", json=payload, headers={"Authorization": f"Bearer {PAT}"}, timeout=30 ) data = resp.json() # 取回答内容的字段,具体路径以当时的API返回为准 return data.get("answer") or ""

这段代码是所有内网中转服务的地基。逻辑说明:先用Bot_ID锁定你是调用哪个助手,再用user_id让扣子记住同一员工的上下文,最后关掉流式(stream=False)让接口一次返回完整回答,方便网关在拿到结果后做权限过滤或敏感信息脱敏。参数里那个timeout=30是硬要求,内网出网链路慢时,宁可超时重试也不要让员工对着输入框等一分钟。

如果你已经有现成的飞书/钉钉服务端,把这段函数接进消息回调,就是最简洁的拓扑B实现。

4. 飞书与钉钉接入全流程:从事件回调到卡片消息

4.1 双端接入的公共逻辑:机器人本质是一次双向HTTP对话

无论飞书还是钉钉,双向机器人都是一个模型:员工在群里发消息或@机器人,IM云端把这条消息以事件形式推送到你配置的回调地址(或长连接),你的服务处理完,再调用IM的API把答案发回群或单聊。

理解这一点后,很多配置就不再是玄学。你要准备的其实只有两件事:一是"收",把IM云端的事件接进来并验证来源;二是"发",调用IM API发送文本或卡片。扣子在这条链路里的位置,只是把"收到消息到发出回答"中间那一段替换成了对扣子Bot的调用。

4.2 飞书侧:创建自建应用、订阅事件与加密回调校验

飞书接入的第一步是在开放平台创建企业自建应用,开启"机器人"能力。然后要申请权限,重点是两条:im:message(读取消息)和im:message.group_at_msg(接收群内@消息)。如果是主动推送通知,还会用到im:message:send_as_bot这类发送权限。权限粒度按最小化申请,免得安全评审被驳回。

事件订阅是飞书接入最折磨人的环节。你需要把回调地址配置成公网HTTPS地址,并且飞书会先发一条URL验证请求。如果你开启了Encrypt Key加密,验证请求是加密的,不能直接读challenge字段,必须先解密。

import base64 import hashlib from Crypto.Cipher import AES from Crypto.Util.Padding import unpad def feishu_decrypt(encrypt_key: str, encrypted: str) -> str: # 飞书加密规则:Encrypt Key 取 MD5 后作为 AES-128-CBC 的密钥 key = hashlib.md5(encrypt_key.encode("utf-8")).digest() raw = base64.b64decode(encrypted) iv = raw[: AES.block_size] ciphertext = raw[AES.block_size:] cipher = AES.new(key, AES.MODE_CBC, iv) # 解密后去掉 PKCS#7 填充,还原 JSON 字符串 plaintext = unpad(cipher.decrypt(ciphertext), AES.block_size) return plaintext.decode("utf-8")

配合Flask写一个回调入口时,先解密外层数据,再判断事件类型是不是url_verification,如果是就直接把解密后JSON里的challenge原样返回。很多飞书回调验证失败,就是这一步没有解密,直接把密文当明文返回了。

from flask import Flask, request, jsonify import json app = Flask(__name__) ENCRYPT_KEY = "你的Encrypt Key" @app.route("/feishu/callback", methods=["POST"]) def feishu_callback(): body = request.get_data(as_text=True) event = json.loads(feishu_decrypt(ENCRYPT_KEY, body)) # 首次配置时的地址验证:把 challenge 原样返回即可 if event.get("type") == "url_verification": return jsonify({"challenge": event["challenge"]}) # 其余是真正消息事件,解析后交给扣子处理 # 返回 code=0 表示接收成功,不要在回调里做耗时操作 return jsonify({"code": 0})

逻辑说明:Flask只负责接收和快速应答,真正调用扣子OpenAPI的逻辑不要写在回调函数里同步执行,否则飞书那边等待时间过长会判定失败然后重推。常见做法是回调里把消息塞进本地队列,由后台worker慢慢处理,处理完再通过飞书API发消息。参数说明就两点:challenge返回值必须与解密后的一致,返回结构必须是JSON键challenge;业务处理结果在回调里只返回接收成功码,别把扣子回答放这里返回。

4.3 钉钉侧:加签Webhook与Stream长连接接收

钉钉接入有两条主流路径。

路径一是Webhook机器人加签。这种方式只能发消息,适合告警推送。加签的算法是把当前毫秒时间戳加上密钥拼成字符串,做HMAC-SHA256后Base64,最后URL编码。实现如下:

import time import hmac import hashlib import base64 import urllib.parse def dingtalk_sign(secret: str): timestamp = str(round(time.time() * 1000)) string_to_sign = f"{timestamp}\n{secret}" hmac_code = hmac.new( secret.encode(), string_to_sign.encode(), hashlib.sha256 ).digest() sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) return timestamp, sign

调用时把timestamp和sign拼到Webhook地址上,即可发送消息。这个代码在企业里最常见的用途是定时脚本运行完把结果发到群,比如"每日考勤异常统计"机器人。

路径二是企业内部应用的Stream模式,适合需要双向对话的场景。钉钉和飞书不同,它的Stream模式让内网服务直接跟钉钉云端建立长连接,不需要任何公网回调地址,对企业内网极度友好。最小实现如下:

import dingtalk_stream def handle_message(msg): # 拿到员工发来的文本 user_text = msg.text.content.strip() # 调用扣子OpenAPI拿到回答 reply = ask_coze(user_text) # 把回答作为机器人消息发回原会话 return dingtalk_stream.ReplyMessage.build(msg, text=reply) def main(): client = dingtalk_stream.DingTalkStreamClient({ "client_id": "你的AppKey", "client_secret": "你的AppSecret", }) client.register_callback(dingtalk_stream.ChatbotMessage, handle_message) client.start_forever()

注意,ask_coze就是上一章写的那段Python函数。整个服务跑在公司内网的一台机器上,进程保持长连接,不占用任何公网入站端口,这让网络策略审批简单很多。

4.4 把回答变成表格和卡片:员工要的不是一段话

扣子返回的往往是一段自然语言文本,但在考勤、报修这类场景里,表格比文字更直观。飞书和钉钉都支持卡片消息,卡片里可以放表格和链接。

钉钉侧最简单的是markdown消息:

{ "msgtype": "markdown", "markdown": { "title": "本周考勤异常汇总", "text": "### 考勤异常\n| 部门 | 人数 |\n|---|---|\n| 研发部 | 3 |\n| 市场部 | 1 |\n\n[查看明细](https://oa.example.com/attendance)" } }

飞书侧推荐用interactive卡片类型,里面可以放column_set或多行文本模块实现表格效果。要注意的是,让LLM直接生成卡片JSON非常容易格式翻车。我一般让扣子工作流先输出结构化结果,比如JSON数组,再由中转服务把这批数据映射成卡片模板,这样样式稳定,也不会因为模型输出幻觉导致卡片渲染失败。

5. 部署避坑指南:回调、权限与网络策略的排查顺序

5.1 飞书回调验证失败,密文当明文返回

现象:在飞书开放平台配置事件订阅URL后,点击验证一直报"URL验证失败",但浏览器直接访问这个地址能通,证书也正常。

原因:开启了Encrypt Key加密后,飞书发来的验证请求体是加密后的密文,challenge字段不在明文里。直接把密文里的challenge取出来返回,飞书解密后对不上,自然失败。

解决:按第4.2节的feishu_decrypt先解密,再返回解密后JSON中的challenge字段。如果不想在业务服务里做AES解密,也可以把Encrypt Key留空,只校验Verification Token,缺点是消息体是明文,内网场景下数据敏感度要自己评估。

5.2 钉钉Webhook机器人发消息报"robot code is invalid"

现象:拿自定义机器人Webhook地址测试发送,返回错误码提示robot code无效,或者消息发出去但被过滤了。

原因:自定义机器人在钉钉安全设置里配置了关键词或IP白名单,你发送的内容没命中关键词,被静默拦截;另外这类机器人只能在创建它的群里使用,换群就失效。

解决:做双向对话助手,不要用自定义Webhook机器人,改用企业内部应用的机器人能力。用Stream模式注册回调,用企业内部应用发送消息接口推送,安全性、跨群能力和消息类型都更完整。自定义Webhook只留给告警和通知这类单向场景。

5.3 权限申请了但发不出消息:版本发布才是最后一跳

现象:飞书应用后台明明申请了im:message权限,调用发消息API还是返回权限不足错误;钉钉侧也提示无权限。

原因:权限申请和版本发布是两回事。飞书和钉钉的应用权限都要在创建版本并发布后才会真正生效,开发阶段申请的权限只对沙箱和测试成员可用。很多团队改了权限后不重新发布,光在后台反复看权限列表。

解决:飞书侧在"版本管理与发布"里创建新版本,勾选权限说明,提交申请后等审核;钉钉侧在开发者后台点"保存并发布"。发布后最好退出应用重新进入一次群聊,确保应用版本刷新。

5.4 内网调用扣子OpenAPI超时或连接被重置

现象:拓扑B里,内网服务调用扣子Chat接口频繁超时,报连接重置或SSL错误,但同样的代码在开发机(直连公网)上运行正常。

原因:企业内网出口防火墙或上网代理拦截了特定域名,或者要求域名加白名单。扣子云端节点在国内和海外都有部署,域名选错也会导致跨网访问延迟剧增。

解决:先确认你使用的是与账号区域匹配的API域名,再做两件事:在防火墙或代理上给扣子API域名加白名单;在代码里把超时调到30秒以上,并且对Chat这类耗时接口做好超时后的重试策略。如果公司对出网管控严格,更省心的方案是评估扣子企业版私有化部署,把整个平台放到内网,彻底绕开公网链路。这是后话,但值得在立项时同步评估。

5.5 回调里做了耗时操作,IM端疯狂重推导致消息重复

现象:飞书回调里直接同步调用扣子聊天接口,接口响应超过3秒,员工在群里看到机器人回复了两三次同一句话。

原因:IM云端对回调有超时要求,超时未返回成功码会判定投递失败,于是重新推送事件。而你的服务其实已经处理完了,重推又处理一次,自然重复发送。

解决:回调入口接到事件后立刻返回code:0,把完整消息丢进本地队列或用Redis延迟队列,由独立worker异步处理并发送结果。处理耗时操作期间,可以先用卡片给员工一条"正在查询,请稍候"的临时提示,这也是产品体验上更顺的做法。

6. 上线前的验证与进阶:一条链路自检,再把结果写回多维表格

6.1 在测试群跑一遍真实链路,盯四个日志点

正式开放给全员之前,我会在测试群把链路完整走一遍,同时盯四个位置:

  • 第一个是IM回调:飞书/钉钉后台里看回调是否成功送达,内网服务日志里有没有收到消息;
  • 第二个是扣子调用:中转服务调Chat接口的耗时和返回码,这一步能判断是不是知识库或工作流本身问题;
  • 第三个是发送环节:IM API返回的消息ID,有ID就说明发送成功;
  • 第四个是群内展示:卡片是否渲染正常,表格有没有错列。

这一套走下来,任何一个环节出问题都能立刻定位。建议把中转服务的关键节点日志加上request_id,串起"员工提问、扣子回答、IM发送"整条链路,排查效率能翻倍。

6.2 进阶:把助手结果写进飞书多维表格与钉钉待办

群里问答只是第一步,真正让智能助手产生生产力的地方在于"办结"——把LLM抽取出的结构化信息写回业务系统。飞书多维表格和钉钉待办都有开放API,扣子工作流里有现成插件能直接写多维表格记录。常见做法是:员工对机器人说"帮我记一条:周三下午三点和李总对需求",扣子工作流解析出时间、人物、事项,调用多维表格插件写入新记录,返回一条"已记录"的确认。

如果希望所有写入都经过内网审计,则在拓扑B的中转服务里调用表格API,不走扣子插件,写入逻辑全部由内网服务控制。两种方式各有适用场景:要快就扣子插件,要审计就内网服务收口。

6.3 用双应用做灰度,预留撤回后路

我踩过最大的教训是:一上来就把机器人在全员群发布,结果某个工作流参数配错,机器人一上午回复了三百条错误答案,撤回都没办法。后来我固定了双应用习惯:在IM后台建开发版和生产版两个应用,机器人名字分别叫"助手-测试"和"智能助手"。扣子侧同样建两个Bot,测试版挂测试知识库,生产版挂正式知识库。测试群里用开发版验证新流程,确认无误后,把生产版对应的工作流或知识库更新一下即可,不需要动IM配置。如果新版翻车,只要把生产版应用停用或切换回旧Bot,全体员工完全无感。

这算是我留给后来者的一个习惯:任何改动,哪怕是调一个相似度阈值,都要先在测试群跑一次再上生产。企业内网助手一旦用起来,员工会很依赖它,宁可更新慢一点,也要保证线上稳定。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询