← 返回首页 博客 English version

钉钉机器人 + 自部署 AI 服务 30 分钟复现

从创建企业内部应用到在钉钉群里收到第一条 AI 回复(Stream 模式,免公网 IP,含 4 个报错修法)

2026-08-16 · Leo · 教程 · 15 分钟阅读
TL;DR — 一份 30 分钟复现清单:钉钉开发者后台 → 创建企业内部应用 → 加机器人选 Stream 模式 → 用官方 dingtalk-stream SDK 收发消息 → 接大模型 API → 在钉钉群里 @ 机器人收到 AI 回复。全程不需要公网 IP、不需要配回调 URL,比企业微信那套 AES 回调简单一个量级。文末 4 个常见报错和修法。
⚠️ 先避一个最大的坑:钉钉「自定义机器人」的 webhook 只能往外发收不到员工发来的消息。要做能对话的 AI 助手,必须用企业内部应用 + 机器人,并把机器人消息接收模式选成 Stream 模式。本文全流程按这个走。

第 1 步:创建企业内部应用 + 机器人

📌 拿 AppKey / AppSecret,加机器人选 Stream 模式 5 分钟
  1. 登录 open-dev.dingtalk.com(钉钉开发者后台)→ 应用开发 → 企业内部应用 → 创建应用
  2. 填应用名称/描述 → 创建后进入应用详情,左侧「凭证与基础信息」:记录 AppKeyAppSecret(AppSecret 只显示一次,关闭后需重置才能再看)
  3. 左侧「机器人」→ 添加机器人:填名称、头像,消息接收模式选 Stream 模式(免公网 IP、免回调 URL,SDK 直接长连接)
  4. 保存后,确认机器人出现在应用「版本管理与发布」里——企业内部应用要发布后,企业成员才搜得到这个机器人(见文末报错 2)

第 2 步:跑通最小接收脚本

🐍 dingtalk-stream SDK:收到消息原样回一句 8 分钟

官方 Python SDK(dingtalk-stream)把 WebSocket 长连接、心跳、断线重连都封装好了。安装并保存下面代码为 bot.py

pip install dingtalk-stream
import logging
import dingtalk_stream
from dingtalk_stream import AckMessage


def setup_logger():
    logger = logging.getLogger()
    handler = logging.StreamHandler()
    handler.setFormatter(
        logging.Formatter('%(asctime)s %(name)-8s %(levelname)-8s %(message)s'))
    logger.addHandler(handler)
    logger.setLevel(logging.INFO)
    return logger


class EchoHandler(dingtalk_stream.ChatbotHandler):
    async def process(self, callback: dingtalk_stream.CallbackMessage):
        message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
        content = message.text.content.strip()
        self.logger.info('收到消息: %s' % content)
        self.reply_text('收到:' + content, message)
        return AckMessage.STATUS_OK, 'OK'


def main():
    logger = setup_logger()
    credential = dingtalk_stream.Credential('你的AppKey', '你的AppSecret')
    client = dingtalk_stream.DingTalkStreamClient(credential)
    client.register_callback_handler(
        dingtalk_stream.chatbot.ChatbotMessage.TOPIC, EchoHandler(logger))
    client.start_forever()


if __name__ == '__main__':
    main()

运行 python bot.py,日志出现 连接成功 后,到钉钉群里 @机器人 发一句「你好」,应该收到「收到:你好」。

第 3 步:把消息转给大模型

🤖 接入 DeepSeek API(OpenAI 兼容格式) 10 分钟

EchoHandler 换成调用大模型 API。以 DeepSeek 为例(官网 platform.deepseek.com 充值后创建 API Key,价格在官网定价页实时可查,本文发布时 deepseek-chat 输出约 2 元/百万 tokens):

import requests

API_KEY = '你的DeepSeek API Key'


def ask_ai(text):
    resp = requests.post(
        'https://api.deepseek.com/chat/completions',
        headers={'Authorization': 'Bearer ' + API_KEY},
        json={
            'model': 'deepseek-chat',
            'messages': [{'role': 'user', 'content': text}],
        },
        timeout=30)
    return resp.json()['choices'][0]['message']['content']


class AIHandler(dingtalk_stream.ChatbotHandler):
    async def process(self, callback: dingtalk_stream.CallbackMessage):
        message = dingtalk_stream.ChatbotMessage.from_dict(callback.data)
        content = message.text.content.strip()
        self.logger.info('收到: %s' % content)
        answer = ask_ai(content)
        self.reply_text(answer, message)
        return AckMessage.STATUS_OK, 'OK'

把第 2 步代码里的 EchoHandler 换成 AIHandler,重启脚本,再 @ 机器人提问,收到的就是模型回答。

第 4 步:群里实测对话

💬 @ 机器人:从单句到多轮 3 分钟
  1. 钉钉群 → 设置 → 机器人 → 添加机器人 → 选刚发布的应用机器人
  2. 群里 @机器人 提问,收到回复即说明全流程可用
  3. 想记多轮上下文:把历史消息拼进 messages 数组再发给模型(注意控制长度,超长就只保留最近几轮)
  4. @ 机器人时消息文本会带上「@机器人 」前缀,content.strip() 后建议再 replace('@机器人','') 去掉前缀,避免把机器人名字喂给模型

第 5 步:部署到服务器常驻

🚀 nohup / systemd 后台跑 2 分钟

开发机跑通后,把脚本放到服务器,用 systemd 托管(断线自动拉起,SDK 自身也会自动重连):

sudo tee /etc/systemd/system/dingtalk-bot.service <<'EOF'
[Unit]
Description=DingTalk AI Bot
After=network-online.target

[Service]
WorkingDirectory=/opt/dingbot
ExecStart=/usr/bin/python3 /opt/dingbot/bot.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now dingtalk-bot
sudo journalctl -u dingtalk-bot -f

注意:AppKey/AppSecret 建议从环境变量或密钥文件读,别硬编码进 git 仓库。

30 分钟后,你应该有的东西

  1. 一个钉钉企业内部应用(AppKey/AppSecret 在手)
  2. 一个 Stream 模式机器人,群里 @ 它就能对话
  3. 脚本接了大模型 API,回答有实际内容
  4. 服务在服务器上常驻,重启自动拉起

下一步可以做的:把机器人接进 知识库检索(先查内部文档再回答),或者接到 企业审批/工单系统(收到消息后调内部 API 干活)。这类「IM + AI + 内部系统」的串联,正是 Mule Agent 平台擅长的场景——多个 IM 统一接一个 AI 大脑,一个后台管理。

4 个常见报错和修法

报错 1:连不上,日志报 Invalid client_id or client_secret

AppKey/AppSecret 填错,或复制时带了空格/换行。

✅ 修法:回「凭证与基础信息」页重新复制;确认用的是企业内部应用的 AppKey,不是自定义机器人的 webhook access_token。改了 AppSecret 后要同步改代码里的值。
报错 2:群里搜不到机器人 / @ 不到

应用没发布,或机器人没加进当前群。

✅ 修法:开发者后台 → 应用发布 → 版本管理与发布 → 创建版本并发布到企业;群里 → 设置 → 机器人 → 添加机器人。两个动作缺一不可。
报错 3:连接正常但收不到消息

机器人「消息接收模式」选成了 HTTP 回调(需要公网 URL),或者根本没配接收消息。

✅ 修法:机器人配置页把消息接收模式改成 Stream 模式并保存;确认注册的回调 topic 是 ChatbotMessage.TOPIC(拼写带 Chatbot 的 o)。
报错 4:回复失败,日志报 reply 异常

reply_text 必须在 process 回调里调用——钉钉的回复上下文只在该回调内有效;另外大模型 API 超时也会导致回不上。

✅ 修法:把 ask_ai 的 timeout 设 30 秒以上;如果模型要算很久,先回一句「正在处理…」,再异步算完补发(Stream 模式支持主动发消息)。
💡 想省掉自建这一步? Mule Agent 平台原生支持钉钉、企业微信、飞书等 7 大 IM:同一个 AI 大脑统一接入,消息进来自动路由到知识库/工作流,后台配置不用写代码。官网留邮箱即可约演示。
📮 有问题?邮件 278946228@qq.com,或在博客留言板留言。