TL;DR
🔧 阿里把钉钉全产品能力打包成了一套 AI Agent Skill——不是给人看的 API 文档,是给 AI 看的操作指南
🧠 核心设计:意图决策树 + 产品参考文档 + 批处理脚本,三层架构让 AI 精准理解「用户到底想干什么」
🔗 底层走 MCP 协议,所有响应结构化 JSON,AI 开箱即用
🛡️ 内建安全机制:危险操作必须人类确认,批量操作限 30 条
📦 12 个 Python 脚本覆盖考勤、日历、待办、通讯录等高频场景
这篇文章要聊什么
3 月下旬,阿里钉钉团队在 GitHub 上开源了 dingtalk-workspace-cli。一个 CLI 工具,用来操作钉钉工作台的所有功能。
CLI 工具本身不稀奇。真正值得拆解的是它附带的 skills/ 目录——这是阿里为 AI Agent 专门设计的一套 Skill 系统。
我花了几个小时把整个 skills 目录翻了个底朝天,发现一些有意思的设计模式。这些模式不只是「钉钉怎么接 AI」的问题,更是「怎么给 AI 写操作手册」的范式参考。
Skill 的目录结构
先看全景:
skills/
├── SKILL.md # 主入口:AI 读这个文件就够了
├── references/
│ ├── products/ # 各产品的详细命令参考
│ │ ├── aitable.md # AI 表格
│ │ ├── calendar.md # 日历
│ │ ├── chat.md # 群聊与机器人
│ │ ├── contact.md # 通讯录
│ │ ├── todo.md # 待办
│ │ ├── attendance.md # 考勤
│ │ ├── report.md # 日志
│ │ └── ...
│ ├── intent-guide.md # 意图路由指南
│ ├── global-reference.md # 全局配置(认证/标志/输出)
│ ├── field-rules.md # AI表格字段规则
│ └── error-codes.md # 错误码 + 调试流程
├── scripts/ # Python 批处理脚本
│ ├── calendar_free_slot_finder.py
│ ├── todo_batch_create.py
│ ├── attendance_my_record.py
│ └── ...
├── LICENSE
└── NOTICE
这个结构本身就是一个设计决策。把它拆成三层看:
第一层:SKILL.md —— 单一入口真相源
AI Agent 只需要读这一个文件。它包含了「禁止做什么」「必须做什么」「产品总览表」「意图决策树」「核心流程」「错误处理」。这是整个 Skill 系统的索引。
第二层:references/ —— 按需加载的深度文档
SKILL.md 里不写具体命令参数。需要时通过文件引用指向 references/products/xxx.md。AI 判断出用户意图后,再去读对应产品文档。避免一次加载太多上下文。
第三层:scripts/ —— 可执行的自动化脚本
12 个 Python 脚本,处理那些需要多步编排的复杂场景。比如「查所有人的空闲时段找到可以开会的时间」——这种逻辑写在 SKILL.md 里太重了,抽成脚本更干净。
第一个亮点:意图决策树
SKILL.md 里最精彩的部分是意图判断决策树。它用关键词匹配的方式,帮 AI 快速定位用户需求:
用户提到"表格/多维表/AI表格/记录/数据" → aitable
用户提到"审批/请假/报销/出差/加班" → approval
用户提到"考勤/打卡/排班" → attendance
用户提到"日程/日历/会议室/约会" → calendar
用户提到"群聊/建群/群成员/机器人发消息" → chat
用户提到"通讯录/同事/部门/组织架构" → contact
用户提到"DING/紧急消息/电话提醒" → ding
用户提到"日志/日报/周报" → report
用户提到"待办/TODO/任务提醒" → todo
看起来简单,实际上解决了 AI Agent 最头疼的问题——意图歧义。
用户说「帮我建一个项目跟踪表」,是用 AI 表格还是待办?决策树给了明确答案:涉及结构化数据/行列操作 → aitable。
用户说「帮我记一下明天要做的事」,个人待办提醒 → todo。
钉钉团队还额外写了一份 intent-guide.md,专门处理易混淆场景。完整的对照表长这样:
用户说...
真实意图
应该用
不要用
理由
"帮我建一个项目跟踪表"
创建数据表格
aitable
todo
涉及结构化数据/行列操作
"帮我记一下明天要做的事"
创建待办
todo
aitable
个人待办提醒
"帮我看看收到的日报"
日志收件箱
report
todo
钉钉日志系统
"让机器人在群里发通知"
机器人群发
send-by-bot
send-by-webhook
企业内部机器人
"通过 Webhook 发告警到群里"
Webhook 告警
send-by-webhook
send-by-bot
自定义机器人
这种设计的本质是:不要让 AI 猜,直接告诉它边界在哪。
第二个亮点:四步核心流程
SKILL.md 规定了 AI 处理用户请求的四步流程:
1. 意图分类 —— 判断用户指令的核心动词/动作属于哪一类
2. 歧义处理 —— 如果指令模糊或包含多个产品关键字,禁止猜测,必须追问
3. 精准映射 —— 意图清晰后,参考产品总览和决策树选择产品
4. 执行操作 —— 阅读产品参考文件,编写代码或直接调用指令
注意第 2 步:禁止猜测,必须追问。
这是非常重要的设计原则。大部分 AI Agent 的问题不是「不够聪明」,而是「太自信」——用户说了一句模糊的话,AI 直接按自己理解执行,结果删错了数据。
钉钉的做法是强制 AI 在不确定时停下来问人。先把架势做足,确认清楚了再动手。
第三个亮点:严格的安全红线
SKILL.md 开头就列了两个清单:
严格禁止(NEVER DO):
- 不要用 dws 命令以外的方式操作(禁止 curl、HTTP API、浏览器)
- 不要编造 UUID、ID 等标识符,必须从命令返回中提取
- 不要猜测字段名/参数值,操作前必须先查询确认
严格要求(MUST DO):
- 所有命令必须加 --format json 以获取可解析输出
- 危险操作必须先向用户确认,用户同意后才加 --yes 执行
- 单次批量操作不超过 30 条记录
危险操作有明确的清单:
产品
命令
说明
aitable
base delete
删除整个 AI 表格
aitable
record delete
删除记录(支持批量)
calendar
event delete
删除日程
chat
group members remove
移除群成员
todo
task delete
删除待办
执行流程也固定死了:
Step 1 → 展示操作摘要(操作类型 + 目标对象 + 影响范围)
Step 2 → 用户明确回复确认
Step 3 → 加 --yes 执行命令
这套机制的设计哲学:AI 可以帮你做很多事,但删除操作永远需要人类拍板。
第四个亮点:上下文传递表
每个产品参考文档里都有一个「上下文传递表」。以 AI 表格为例:
操作
从返回中提取
用于
base list/search
baseId
所有后续命令的 --base-id
base get
tables[].tableId
--table-id
table get
fields[].fieldId
record 操作的 cells key
record query
recordId
record update/delete
这解决了 AI Agent 的另一个核心难题:多步操作之间的数据流转。
一个典型的工作流——「在 AI 表格里搜索项目,找到某张表,查字段结构,然后新增一条记录」——需要 4 次 API 调用,每次调用的参数依赖上一次的返回值。
上下文传递表把这条链路画清楚了。AI 只需要按表取值、传值就行。
第五个亮点:跨产品工作流
intent-guide.md 里还定义了跨产品编排模式。比如「约张三明天下午开会」:
# 1. 从通讯录搜索同事 userId
dws contact user search --query "张三" --format json
# 2. 创建日历日程
dws calendar event create --title "会议" \
--start "2026-03-15T14:00:00+08:00" \
--end "2026-03-15T15:00:00+08:00" --format json
# 3. 添加参与者(用 step 1 的 userId 和 step 2 的 eventId)
dws calendar participant add --event <EVENT_ID> \
--users <USER_ID> --format json
三个不同的产品(contact → calendar → calendar participant),通过 ID 传递串联成一个完整的业务流程。
再比如「给张三建个待办」:
# 1. 搜索同事
dws contact user search --query "张三" --format json
# 2. 创建待办(用 step 1 的 userId)
dws todo task create --title "任务内容" \
--executors <USER_ID> --format json
这种模式的抽象很漂亮:每个产品是独立的原子操作,跨产品编排通过 ID 粘合。
脚本层:12 个 Python 批处理脚本
scripts 目录里有 12 个 Python 脚本,处理更复杂的场景。我挑一个最有代表性的来看——calendar_free_slot_finder.py,查找多人共同空闲时段。
# 用法
python calendar_free_slot_finder.py \
--users userId1,userId2,userId3 \
--date 2026-03-15 \
--duration 60
这个脚本做了什么:
- 调用
dws calendar busy search查询所有人的忙碌时段 - 合并重叠的忙碌区间(区间合并算法)
- 从工作时间(默认 9:00-18:00)中扣除忙碌区间
- 找到满足会议时长要求的空闲窗口
- 按时间排序输出,第一个标记为「⭐ 推荐」
输出长这样:
🕐 空闲时段查询 (2026-03-15)
参与人: 3 人
会议时长: 60 分钟
工作时间: 9:00 ~ 18:00
==================================================
✅ 找到 2 个可用时段:
⭐ 推荐 10:00 ~ 12:00 (120分钟)
备选1 15:30 ~ 18:00 (150分钟)
它还支持 --dry-run 模式,只打印要执行的 dws 命令但不真正调用。整个脚本不到 200 行。
其他脚本覆盖的场景包括:
脚本
功能
todo_batch_create.py
批量创建待办
todo_daily_summary.py
待办每日摘要
todo_overdue_check.py
逾期待办检查
attendance_my_record.py
个人考勤记录
attendance_team_shift.py
团队排班查询
calendar_schedule_meeting.py
预约会议
calendar_today_agenda.py
今日日程
contact_dept_members.py
部门成员查询
report_inbox_today.py
今日收到的日志
import_records.py
批量导入记录
bulk_add_fields.py
批量添加字段
upload_attachment.py
上传附件
底层架构:发现驱动的管道
DWS CLI 本身的架构也值得说一嘴。它不硬编码任何产品命令,而是用「发现驱动管道」动态注册:
Market Registry ──► Discovery ──► IR ──► CLI (Cobra) ──► Transport (MCP JSON-RPC)
│ │
▼ ▼
mcp.dingtalk.com 缓存(TTL + 过期降级)
五个阶段:
- Market —— 从
mcp.dingtalk.com获取 MCP 服务注册表 - Discovery —— 解析运行时能力,支持磁盘缓存和离线降级
- IR(中间表示) —— 规范化为统一的产品/工具目录
- CLI —— 挂载到 Cobra 命令树,映射 flag 到 MCP 输入参数
- Transport —— 执行 MCP JSON-RPC 调用,支持重试和认证注入
这意味着钉钉后端新增了一个产品,CLI 不需要改代码。只要 MCP 注册表里加了服务描述,dws 自动发现并生成对应的命令行接口。
对我们的启示:怎么给自己的项目写 Skill
把钉钉的 Skill 设计拆解完,几个可以直接借鉴的模式:
1. 单一入口 + 按需加载
SKILL.md 是唯一入口。AI 读完它就知道有哪些能力、怎么选择。详细参数放在子文件里,需要时再读。这比把所有内容塞进一个巨大的 prompt 要高效得多。
2. 意图决策树先行
不要直接列命令。先回答"用户说了什么 → 应该用哪个工具"的映射关系。特别是要把易混淆的场景显式列出来。
3. 上下文传递表是必须的
多步操作的每一步,输入从哪来、输出传给谁,用表格画清楚。AI 不需要理解业务逻辑,只需要按表索骥。
4. 安全红线写在最前面
NEVER DO 和 MUST DO 放在文档最开头。让 AI 先知道不能做什么,再知道能做什么。
5. 危险操作走确认流程
任何删除、修改操作,强制走「展示摘要 → 用户确认 → 执行」三步。不要相信 AI 的判断力。
6. 复杂逻辑抽脚本
SKILL.md 里写流程描述,Python 脚本里写实现逻辑。AI 判断意图后直接调脚本,不用自己生成代码。
安装和使用
想把钉钉 Skill 装到自己的 AI Agent 项目里,一行命令:
# 安装到当前项目
curl -fsSL https://raw.githubusercontent.com/DingTalk-Real-AI/dingtalk-workspace-cli/main/scripts/install-skills.sh | sh
装完之后在 ./.agents/skills/dws/ 目录下就能看到完整的 SKILL.md 和参考文件。
注意,当前项目还在灰度共创阶段。需要企业管理员授权,加入钉钉 DWS 共创群提供 Client ID 完成白名单配置。
最后
钉钉这套 Skill 系统最值得学习的不是「钉钉 API 怎么调」,而是「怎么用文档驱动 AI Agent 的行为」。
意图决策树解决了 AI「听不懂」的问题。上下文传递表解决了 AI「接不上」的问题。安全确认机制解决了 AI「管不住」的问题。
三个问题解决了,AI Agent 就从「聊天机器人」变成了「数字员工」。
全部代码开源在 GitHub:dingtalk-workspace-cli/skills