- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
本指南围绕 TEN Framework 开源仓库中的dingtalk_bot_tool_python扩展展开,讲解如何将该扩展作为 LLM 可调用工具集成到语音 AI 助手中,使 AI 在对话中识别"通知、提醒、群发"等意图后自动向钉钉群聊发送文本消息。读完本文,你将掌握该扩展的配置项含义、底层签名与发送原理,以及把它接入voice-assistant示例应用的全流程实操方法。
扩展概览:一个"会发消息"的 LLM 工具
dingtalk_bot_tool_python是 TEN Framework 生态中一个 Python 编写的扩展包,位于 ai_agents/agents/ten_packages/extension/dingtalk_bot_tool_python。它本身不参与语音采集、识别或合成,而是作为一个**工具(Tool)**挂载到 LLM 上:当用户说出"帮我通知团队今天下午 3 点开会"这类指令时,LLM 判断应当调用工具,扩展随即通过钉钉群机器人的 Webhook 把消息推送到目标群聊。
其核心特性包括:
- LLM 工具集成:以标准工具元数据向 LLM 注册
send_message工具,支持智能消息发送; - 消息推送:向钉钉群聊发送文本消息(
msgtype: text); - 安全认证:支持钉钉机器人的
access_token与"加签"(HMAC-SHA256 签名)双重校验; - 异步处理:基于
AsyncTenEnv与AsyncLLMToolBaseExtension构建,非阻塞、高性能; - 详细日志:从启动、配置加载、工具注册到消息发送的每个环节都有结构化日志,便于调试与监控。
系统要求
在集成前,请确认环境满足以下条件(依据 manifest.json 与 pyproject.toml 中的声明):
| 要求 | 说明 |
|---|---|
| Python 版本 | 文档要求 3.8+;pyproject.toml中requires-python = ">=3.10",建议按 3.10+ 准备 |
| TEN Runtime Python | >= 0.11(manifest 中ten_runtime_python版本声明为 0.11) |
| TEN AI Base | >= 0.7(manifest 中ten_ai_base版本声明为 0.7) |
| 钉钉群机器人 | 一个有效的自定义机器人 Webhook 及安全凭证 |
依赖仅有一个:requests(用于向钉钉 API 发送 HTTP 请求),requirements.txt中即一行requests,pyproject.toml中进一步限定为requests>=2.34.2。
安装依赖
pip install -r requirements.txt源码结构:从 Addon 注册到消息发送的实现链路
在动手配置前,先梳理扩展的源码结构,有助于理解后续每个配置项的作用。包内关键文件如下:
ai_agents/agents/ten_packages/extension/dingtalk_bot_tool_python/ ├── README.md / README_CN.md # 使用文档 ├── __init__.py # 包初始化 ├── addon.py # Addon 注册入口 ├── extension.py # 扩展核心实现 ├── manifest.json # 扩展清单(依赖、API 声明) ├── property.json # 默认属性(凭证占位) ├── pyproject.toml # Python 工程配置 └── requirements.txt # 依赖列表Addon 注册(addon.py)
addon.py 通过@register_addon_as_extension("dingtalk_bot_tool_python")将扩展注册为名为dingtalk_bot_tool_python的 addon,并在on_create_instance中创建DingTalkBotExtension实例:
@register_addon_as_extension("dingtalk_bot_tool_python") class DingTalkBotAddon(Addon): def on_create_instance(self, ten_env: TenEnv, name: str, context) -> None: ten_env.on_create_instance_done(DingTalkBotExtension(name), context)这就是为什么在图的节点配置中,name与addon都填写dingtalk_bot_tool_python——addon对应注册名,name是图中实例名。
扩展核心(extension.py)
extension.py 是核心实现,包含三大部分:
工具元数据定义:工具名为
send_message,描述为 "Send a message to DingTalk group chat. Use this when user wants to notify team members or send information to DingTalk.",唯一参数content(string 类型、必填),即要发送的消息内容。生命周期方法:
on_start中通过DingTalkBotConfig.create_async(ten_env=ten_env)异步加载配置(对应property.json中的access_token与secret),随后构造tool_register命令并send_cmd发送给主控制器完成工具注册;on_cmd中处理tool_call命令,解析工具名与arguments,命中send_message时调用run_tool执行。消息发送实现:
_send_dingtalk_message方法负责构造 Webhook URL 并 POST 文本消息,其中签名逻辑严格对应钉钉官方"加签"算法:
if secret: timestamp = str(round(time.time() * 1000)) secret_enc = secret.encode("utf-8") string_to_sign = "{}\n{}".format(timestamp, secret) string_to_sign_enc = string_to_sign.encode("utf-8") hmac_code = hmac.new( secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 ).digest() sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) webhook_url = f"{webhook_url}×tamp={timestamp}&sign={sign}"即:以毫秒时间戳timestamp + "\n" + secret作为待签名字符串,用secret作为密钥做 HMAC-SHA256,再经 Base64 编码与 URL 编码得到sign,拼接到 Webhook 上;最终请求体为{"msgtype": "text", "text": {"content": content}}。发送结果以errcode == 0判定成功,失败时把钉钉返回的错误码与错误信息回传给 LLM,方便模型向用户解释原因。
API 契约(manifest.json)
manifest.json 声明了扩展的 API:
- cmd_in:
tool_call,属性含name(string,必填)与arguments(object); - cmd_out:
tool_register,属性tool为包含name、description、parameters(数组格式)的对象,返回结果含response。
api.property.properties.params声明了两个可配置项access_token与secret,与配置章节一一对应。这也印证了配置时需将凭证写入节点的property下(也可包裹在params对象中,取决于图配置写法,BaseConfig.create_async会按声明结构读取)。
配置:获取凭证并写入扩展属性
获取钉钉机器人凭证
- 在钉钉群中添加自定义机器人;
- 机器人类型选择"自定义";
- 设置安全设置(建议同时启用关键词与加签,其中加签会生成
secret); - 从 Webhook 地址中提取
access_token(URL 中access_token=后的部分); - 若启用了加签,保存
secret密钥。
配置文件设置
编辑扩展的 property.json(默认内容为两个空字符串占位):
{ "access_token": "your_dingtalk_access_token_here", "secret": "your_dingtalk_secret_here" }在实际应用中,更推荐把凭证写在应用图(app 的property.json)中对应扩展节点的property字段里,并使用环境变量引用(见下文),避免敏感信息入库。
重要安全提示:
- 不要将包含真实凭证的
property.json提交到版本控制系统; - 建议使用环境变量或密钥管理服务存储敏感信息。
环境变量(可选)
可以通过环境变量注入凭证。TEN 框架的图配置支持${env:VAR_NAME}语法(voice-assistant示例中agora_rtc、stt、llm等节点即使用该语法),因此可将节点属性写成:
"property": { "access_token": "${env:DINGTALK_ACCESS_TOKEN}", "secret": "${env:DINGTALK_SECRET}" }对应的环境变量设置:
export DINGTALK_ACCESS_TOKEN="your_access_token" export DINGTALK_SECRET="your_secret"使用${env:VAR}语法后,真实凭证只存在于运行环境中,property.json可以安全入库。
集成到 voice-assistant 示例:完整三步
原文档给出了把该扩展接入 ai_agents/agents/examples/voice-assistant 示例的详细步骤。以下是基于仓库实际文件(manifest.json 与 property.json)整理的完整流程。
步骤 1:添加扩展依赖
编辑 ai_agents/agents/examples/voice-assistant/tenapp/manifest.json,在dependencies数组中追加(仓库中该文件第 157 行附近是weatherapi_tool_python依赖,可紧随其后添加):
{ "dependencies": [ // ... 其他依赖 ... { "path": "../../../ten_packages/extension/dingtalk_bot_tool_python" } ] }该相对路径从tenapp目录出发指向ai_agents/agents/ten_packages/extension/dingtalk_bot_tool_python,与示例中其他扩展(如weatherapi_tool_python)的写法一致。
步骤 2:添加扩展节点
编辑 ai_agents/agents/examples/voice-assistant/tenapp/property.json,在ten.predefined_graphs[0].graph.nodes数组中追加钉钉扩展节点(示例中weatherapi_tool_python节点之后是合适的插入位置):
{ "type": "extension", "name": "dingtalk_bot_tool_python", "addon": "dingtalk_bot_tool_python", "extension_group": "default", "property": { "access_token": "your_dingtalk_access_token_here", "secret": "your_dingtalk_secret_here" } }步骤 3:注册工具到主控制器
在同一个文件的connections部分,找到main_control的cmd配置(仓库中tool_register连接位于约第 120-128 行,当前source中只有weatherapi_tool_python),把钉钉扩展追加进source数组:
{ "extension": "main_control", "cmd": [ { "names": [ "tool_register" ], "source": [ { "extension": "weatherapi_tool_python" }, { "extension": "dingtalk_bot_tool_python" } ] } ] }这条连接的意义在于:dingtalk_bot_tool_python在on_start中会主动发送tool_register命令,只有把它加入main_control的tool_register来源,主控制器(即 LLM 编排层)才能收到并登记该工具。
完整配置示例
综合以上三步,property.json中修改后的关键结构如下:
{ "ten": { "predefined_graphs": [ { "name": "voice_assistant", "auto_start": true, "graph": { "nodes": [ // ... 其他节点(agora_rtc, stt, llm, tts 等) ... // 添加钉钉扩展节点 { "type": "extension", "name": "dingtalk_bot_tool_python", "addon": "dingtalk_bot_tool_python", "extension_group": "default", "property": { "access_token": "your_dingtalk_access_token_here", "secret": "your_dingtalk_secret_here" } } ], "connections": [ { "extension": "main_control", "cmd": [ // 注册工具到主控制器 { "names": ["tool_register"], "source": [ {"extension": "weatherapi_tool_python"}, {"extension": "dingtalk_bot_tool_python"} // 添加这一行 ] } ] } // ... 其他连接配置 ... ] } } ] } }需要修改的文件与配置参数汇总
需要修改两个文件:
manifest.json(示例约第 157 行):添加扩展路径依赖;property.json(两处修改):一处在nodes中新增扩展节点,另一处在main_control的tool_register连接的source中追加钉钉扩展。
核心配置参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
access_token | string | ✅ | 钉钉机器人的 access token(取自 Webhook URL) |
secret | string | ✅ | 钉钉机器人的加签密钥(启用"加签"安全设置时获得) |
extension_group | string | ✅ | 扩展组,设置为"default"(与weatherapi_tool_python同组,便于统一管理) |
验证配置与运行效果
配置完成后,启动 voice-assistant 应用,观察日志确认扩展正常加载。扩展在on_start阶段会输出以下关键日志(对应 extension.py 中的日志埋点):
[DingTalkBotExtension] ========== on_start BEGIN ========== [DingTalkBotExtension] Config loaded successfully [DingTalkBotExtension] - access_token: SET (length=32) [DingTalkBotExtension] - secret: SET (length=32) [DingTalkBotExtension] Registering tool with parameter array format... [DingTalkBotExtension] Tool registration result: ... [DingTalkBotExtension] ========== on_start END ==========日志会回显access_token与secret是否已设置(仅打印长度,不泄露明文),以及tool_register命令的返回结果,可用于确认工具是否成功注册。
正常运转时,AI 与用户的交互效果如下:
用户: "帮我通知团队今天下午3点开会" AI: "好的,我已经向钉钉群发送了会议通知"钉钉群内收到的消息:
今天下午3点开会当send_message被执行时,日志中会出现run_tool CALLED、DingTalk API response等记录;若errcode == 0,扩展返回成功信息给 LLM,否则会把钉钉的错误码与错误消息回传,便于排查。
常见问题排查
Q:配置后扩展没有加载?
- 检查
manifest.json中dependencies里的路径是否正确指向ai_agents/agents/ten_packages/extension/dingtalk_bot_tool_python; - 确认已运行
task install安装依赖(若使用 TEN Agent 的 Taskfile 工作流),使扩展包被拉取到本地ten_packages目录; - 观察启动日志中是否出现
[DingTalkBotExtension] on_start BEGIN,确认 addon 是否被创建(addon.py 中on_create_instance会打印 "Creating DingTalk Bot Extension instance")。
Q:消息发送失败?
- 检查
access_token与secret是否正确、是否与钉钉后台一致; - 查看日志中的错误码与错误信息(
DingTalk API response中的errcode/errmsg),常见如errcode=310000(签名错误或关键词不匹配)等; - 确认钉钉机器人的安全设置:若启用了"加签",
secret必须正确;若启用了"关键词",消息内容需包含关键词,否则钉钉会拒绝推送。
Q:工具未注册到 LLM?
- 检查
connections中main_control的tool_register连接是否已将dingtalk_bot_tool_python加入source; - 确认
tool_register命令的连接配置正确,且扩展与主控制器在同一图(graph)中; - 确认扩展节点的
extension_group设置为"default",与weatherapi_tool_python保持一致,避免工具注册链路被分组隔离。
小结
dingtalk_bot_tool_python以标准的 LLM 工具形态为 TEN Framework 语音助手补上了"钉钉群消息推送"能力:它通过tool_register完成工具登记,通过tool_call接收 LLM 的调用意图,内部用钉钉官方的 HMAC-SHA256 加签算法构造 Webhook 并发送文本消息,全程异步并输出结构化日志。集成只需在应用的manifest.json与property.json中完成三处修改,即可让 AI 助手在对话中自动完成群通知任务。若需自定义消息类型或扩展更多能力(如 Markdown、ActionCard 消息),可基于 extension.py 中的_send_dingtalk_message方法进一步改造。
- 人工智能
- AI Agent
- 多模态
- 语音
- AI 应用
【免费下载链接】ten-framework
Open-source framework for conversational voice AI agents
相关推荐
C++无锁并发队列完整指南:moodycamel::ConcurrentQueue单头文件集成与预分配调优
C++无锁并发队列完整指南:moodycamel::ConcurrentQueue单头文件集成与预分配调优 最近给一条实时渲染管线做性能分析,profiling
人工智能AI Agent多模态语音AI 应用WePush钉钉消息推送:机器人消息与工作通知的完整实现
WePush钉钉消息推送:机器人消息与工作通知的完整实现 想要实现高效的钉钉消息批量推送吗?WePush作为一款专注批量推送的小而美工具,提供了完整的钉钉消息推
开发工具MeterSphere钉钉机器人消息通知配置指南
MeterSphere钉钉机器人消息通知配置指南 问题背景 在使用MeterSphere测试平台时,许多团队希望通过钉钉机器人接收项目相关的测试通知。近期有用户
测试接口测试测试管理后端前端AI 应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考