
如果你正琢磨:怎么让既有产品能力被 AI(或 Agent)稳定调用,而不是只靠对接文档和运气拼 prompt——lark-cli 在飞书场景里走通的分层与约定,值得认真读一遍。

前言:lark-cli这个项目到底是干什么的?
想象一个场景:你让 AI 助手帮你做一件事——"帮我在飞书日历上,查一下明天下午的会议安排"。
最容易想到的,往往是「让 AI 直接去调飞书 Open API」:端点怎么选、权限怎么配、参数怎么传、返回里哪一段才是有效信息……全要在一次对话里凑齐、读对——链路一长,任何一环都可能写偏、读错。
lark-cli 做的事情很简单:它充当了 AI 和飞书之间的"翻译官"。 翻译官不止负责把请求译成飞书 API,还事先定好「该怎么说」:子命令、参数、输出格式都有约定。AI 助手要做的,就是按这套约定,把用户意图整理成一串可执行的 lark-cli ... 命令。
↑ "翻译官" |
比如用户想查日程,AI 在搞清意图后,会按约定发起 lark-cli calendar +agenda(查看日历日程),lark-cli 就会自动:
搞清楚用哪个账号 拿到正确的权限令牌 调用正确的飞书 API 把返回结果整理成 AI 能直接读的结构化数据 如果出错,告诉 AI 该怎么修
💡 换个角度看:为什么这是一个"AI Agent 时代"的范本?
越来越多的企业在问同一个问题:我们已有的 SaaS 服务,怎么才能让 AI Agent 直接调用?
答案就在 lark-cli 的设计里。它不是在"重造"飞书的 API,而是在飞书 API 之上包了一层 AI 友好的壳。这个"壳"解决了三个最关键的问题:
- 翻译问题
:AI 先按 lark-cli 暴露的命令口径组织输入;lark-cli 再把这条命令翻译成正确的飞书 API 调用 - 容错问题
:出错了不止告诉你"出错了",还告诉你怎么修——AI 可以自己修 - 安全问题
:AI Agent 可能被恶意 Prompt 操控,所以每一层都要防注入、防越权 如果你有一个 SaaS 产品,想把它的能力开放给 AI Agent,这篇文档就是你的"参考答案"。
一、整体结构:Skills(AI 说明书)+ CLI(执行引擎)
lark-cli 不是一个普通的命令行工具——它是一个双组件系统,由两部分配合工作:
**Skills(AI 技能包)**:一套 Markdown 文档( SKILL.md),安装在 AI Agent 内部。它们教导 AI 飞书的业务知识、API 使用方式、工作流程、约束规则和最佳实践。Skills 回答的核心问题是:"AI 怎么知道该调哪个命令?怎么组合多个命令完成一个复杂任务?"**CLI(命令行工具)**:编译好的 Go 可执行文件,真正负责执行操作——调用飞书 API、处理认证、格式化输出、多层安全过滤。
Skills 和 CLI 的关系,就像"驾驶员培训手册"和"汽车":
光给 AI 一个 CLI 工具(就像给人一辆车但不教他怎么开),AI 不知道该调什么命令 光有 Skills 没有 CLI(就像有驾驶手册但没有车),也到不了目的地 - 两者配合
:Skills 告诉 AI "遇到 X 场景就调用 Y 命令,如果出错就执行 Z 修复",CLI 负责执行
│ AI Agent(Claude Code 等) │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ Skills 层(25+ 个业务域技能包) │ │ │ │ │ │ │ │ lark-shared 认证、权限、安全规则 │ │ │ │ lark-calendar 日历日程操作工作流 │ │ │ │ lark-im 消息收发工作流 │ │ │ │ lark-doc 文档协作工作流 │ │ │ │ lark-task 任务管理工作流 │ │ │ │ lark-vc 视频会议工作流 │ │ │ │ ... 等 25+ 个业务域 │ │ │ │ │ │ │ │ 每个 Skill 包含: │ │ │ │ • 业务域知识(核心概念、资源关系) │ │ │ │ • 工作流程(场景A→步骤1→步骤2→...) │ │ │ │ • 约束规则(如日历API一次只能查40天) │ │ │ │ • 错误恢复策略 │ │ │ │ • Shortcut 推荐(优先使用 +agenda 等) │ │ │ └────────────┬───────────────────────────────┘ │ │ │ Skills 指导 AI 调用正确的命令 │ └───────────────┼──────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────┐ │ lark-cli CLI 二进制文件 │ │ │ │ ┌────────────────────────────────────────────┐ │ │ │ 快捷命令层 (Shortcuts) │ │ │ │ +agenda, +create, +search-user ... │ │ │ │ "说人话就行,一个加号搞定" │ │ │ ├────────────────────────────────────────────┤ │ │ │ API 命令层 │ │ │ │ calendar events list, im messages send... │ │ │ │ "按服务域和资源分类,结构化调用" │ │ │ ├────────────────────────────────────────────┤ │ │ │ 原始 API 层 │ │ │ │ lark-cli api GET /open-apis/... │ │ │ │ "100% 覆盖,任何 API 都能调" │ │ │ ├────────────────────────────────────────────┤ │ │ │ 基础设施层 (internal/) │ │ │ │ 认证、输出格式、安全过滤、配置管理、HTTP │ │ │ │ "所有命令共享的底层能力" │ │ │ └────────────────────────────────────────────┘ │ └──────────────────────────────────────────────────┘ |
为什么要这样设计?
打个比方:你去餐厅吃饭。
- Skills = 菜谱 + 营养指南
。告诉你"这道菜用什么食材、怎么搭配最好、有什么忌口要注意"。AI 靠 Skills 来判断"用户说'明天下午的会'应该走日历流程还是会议流程"、"飞书日历 API 一次只能查 40 天,如果用户要查 3 个月的日程需要自动分段查询"——这些业务知识不在 CLI 代码里,而在 Skills 里。 - 快捷命令 = 套餐
("给我来份今天的推荐午餐"),快、简单 - API 命令 = 菜单点菜
("宫保鸡丁一份,少辣"),有一定自由度 - 原始 API = 直接跟厨师说怎么做
("鸡胸肉切丁,花生炒香……"),完全自由但复杂
Skills 是整个系统的"智能分发层"——它决定了 AI 在什么场景下使用哪一层命令。 没有 Skills,AI 就像一个拿着全套工具箱但不知道哪个工具该用在哪里的新手;有了 Skills,AI 就像一个经验丰富的老师傅,知道在不同情况下选用最合适的工具。
🤖 AI Agent 视角:为什么 Skills + 分层命令设计对 AI Agent 特别重要?
大多数 CLI 工具只提供"命令",不提供"知识"。但 AI Agent 需要在 token 有限、上下文有限的情况下,快速判断该调哪个命令、传什么参数、怎么处理异常。Skills 解决了这个"冷启动"问题:
- Skills 层 → AI 的领域知识库
("遇到这种情况应该怎么处理"——这是最关键的一层,也是大多数 SaaS 工具缺失的一层) - 快捷命令层 → AI 的首选执行入口
(像函数调用一样简单,一个命令对应一个语义意图) - API 命令层 → AI 的备选入口
(按领域分类,结构化,需要时降级到这里) - 原始 API 层 → AI 的最后手段
(任何 API 都能调,不受快捷命令覆盖范围限制)
这种设计保证了一个关键特性:AI Agent 永远不会被"这个功能快捷命令不支持"卡住——Skills 教它如何根据场景降级到更底层的命令,继续完成任务。

二、一个命令的完整旅程
让我们跟踪一个真实命令从头到尾发生了什么:
用户(或 AI)输入:
旅程开始:
注意:在用户输入命令之前,AI Agent 已经按 Skills 的指导完成了决策。Skills 是这场旅程的"起点"。
用户对 AI Agent 说:"帮我看看明天下午有什么安排" → AI Agent 读取已安装的 lark-calendar Skill → Skill 告诉 AI:"查看日程用 lark-cli calendar +agenda,时间参数用 --start" → AI 决策:执行 lark-cli calendar +agenda --start "2026-05-12" (如果没有 Skill,AI 需要自己摸索该调什么命令、传什么参数——很可能出错) 第1步:接待处(启动程序) "有人来了,让我看看他要什么" → 解析命令:calendar +agenda,参数是 start=2026-05-12 第2步:身份验证(管理员) "你是谁?你有什么权限?" → 读取本地配置:哦,是张三的飞书账号 → 检查钥匙串:token 还在这,没过期 ✓ → 检查权限:你有 calendar:read 权限 ✓ 第3步:翻译请求(翻译官) "你要查明天的日程 → 我需要调用飞书的 instance_view API" → 路径:/open-apis/calendar/v4/calendars/primary/events/instance_view → 参数:start_time=..., end_time=... 第4步:发送请求(快递员) "带上你的 token(通行证),去飞书服务器取数据" → HTTP 请求 → 飞书服务器 → 返回日程列表 第5步:处理结果(整理师) "飞书返回了一堆原始数据,让我把它整理好" → 去掉已取消的日程 → 把时间戳转成可读的日期时间 → 去重排序 第6步:格式化输出(包装师) "好了,给你包成标准格式" → { "ok": true, "data": [...日程列表...], "meta": {"count": 5} } 第7步:送达 → 输出到屏幕(AI 可以直接读这个 JSON) |
整个过程中,AI 只需要从已安装的 lark-calendar Skill 中学会 lark-cli calendar +agenda 这一个命令,剩下 6 步全由 lark-cli 自动完成。
三、核心设计:三个"聪明"的设计
设计1:命令的分层——让简单的事简单,让复杂的事可能
快捷命令 API命令 原始API (+agenda) (events list) (api GET ...) │ │ │ │ │ │ 套餐 点菜 自己做 │ │ │ 自动处理 半自动 完全手动 参数智能推断 按分类组织 任意API都能调 |
关键洞察:AI 用最快的方式(快捷命令)完成 80% 的任务,剩下 20% 降级到更灵活的方式。不会因为"快捷命令没覆盖"就做不了。
🤖 对 AI Agent 的意义:这种分层设计本质上是给 AI 提供了一个 "渐进式 API"——AI 优先尝试最高层(最省 token、最不容易出错),失败时自动降级。对于 SaaS 厂商来说,你不需要一次性把所有功能都包装成快捷命令;你可以先提供最常用的 20% 功能作为快捷命令,其余的让 AI 通过原始 API 调用——这大大降低了"AI Agent 化"的成本。
设计2:错误自愈——出错了我不光告诉你"出了什么错",还告诉你"怎么修"
传统程序的错误信息:
普通人/普通AI的反应:😕 什么权限?怎么办?
lark-cli 的错误信息:
| { "ok":false, "error":{ "type":"permission", "message":"你没有 calendar:read 权限", "hint":"请执行: lark-cli auth login --scope \"calendar:calendar:read\"", "console_url":"https://open.feishu.cn/page/scope-apply?..." } } |
AI 的反应:
看到 hint字段 → "哦,需要执行这个命令来授权"看到 console_url→ "用户也可以点这个链接在网页上操作"
这就叫"自愈"——错误信息不止告诉你出错了,还告诉你怎么修。
🤖 对 AI Agent 的意义:这是整个设计里最"AI Native"的部分。普通程序报错后人类去看日志、搜文档、手动修复。AI Agent 看到
hint字段后可以直接执行修复命令。这意味着:你的 SaaS API 的错误信息里如果包含了"修复指令",AI Agent 就能自己处理大量原本需要人工介入的异常场景。 如果你在为自己的 SaaS 设计 AI Agent 接口,这是最值得抄的一个设计。
设计3:安全多层防护——假设每个输入都可能是恶意的
因为 lark-cli 会被 AI Agent 调用,AI Agent 又可能被恶意 Prompt 诱导,所以 lark-cli 对安全格外重视。
就像一个机场的安检流程——不止一道关卡:
│ ▼ 第1关:字符过滤 → "这个数据里有隐藏的控制字符吗?有恶意Unicode吗?" ▼ 第2关:路径安全 → "你让我打开的文件在安全范围内吗?不会跳出沙箱吧?" ▼ 第3关:内容安全 → "返回的数据里有没有试图注入新的AI指令?" ▼ 第4关:输出净化 → "输出里有没有能操控终端的转义序列?" |
🤖 对 AI Agent 的意义:这点怎么强调都不过分。当一个 AI Agent 调用你的 SaaS API 时,它的输入可能来自另一个 AI、一个用户、甚至一个恶意 Prompt。你必须假设每一个参数、每一个文件路径、每一段返回内容都可能是攻击载体。lark-cli 的四层安全过滤是一个可以直接参考的模型。

四、六个关键角色的分工
把 lark-cli 想象成一个公司,有六个部门。特别的是,第一个部门(培训部)不在 CLI 二进制文件里——它以独立的 Skill 文件形式,直接"派驻"到 AI Agent 内部:
📖 培训部(skills/)— AI 的"上岗培训手册"
职责:教导 AI Agent 如何使用飞书、什么场景用什么命令、有哪些业务约束
1. "飞书日历的基础概念是......日程和日历是不同的" 2. "用户说'明天的会' → 应该用 lark-cli calendar +agenda" 3. "注意!飞书日历 API 一次只能查 40 天,超过要自动分段" 4. "如果遇到权限错误 → 检查 hint 字段,执行对应的修复命令" 5. "如果是预约会议 → 必须先读会议预约工作流文档" |
培训部下设 25+ 个业务域小组,每个小组负责一个飞书业务域(日历、消息、文档、任务……),各自维护一份 SKILL.md 文档。这些文档通过 npx skills add larksuite/cli 安装到 AI Agent 中。
关键设计:培训部教的是"什么时候用什么工具",而不是"工具怎么造"。这让 AI 不需要把整个飞书 API 文档背下来就能正确操作。
AI Agent 视角:这是 lark-cli 区别于所有普通 CLI 工具的核心设计。没有培训部(Skills),AI 拿着 CLI 工具也不知道怎么用;有了培训部,AI 就像经过专业培训的员工,知道在每种场景下该做什么。如果你想让自己的 SaaS 被 AI Agent 调用,"培训部"是你最需要补的一课。
🏢 接待部(cmd/)— 命令的"前台"
职责:接收用户输入,分配给正确的处理部门
接待部: "calendar +agenda → 转发给日历快捷命令部门" |
只负责"路由",不干活。
AI Agent 视角:对 AI 来说,"接待部"就是 MCP Server 或 Function Calling 的入口。每个命令都是一个 tool definition,AI 只需要知道命令名和参数就能调用。你设计 SaaS 的 AI 接口时,第一步就是定义这个"命令清单"。
🔑 安保部(Credential System)— 管你是谁、你有什么权限
职责:验证身份、管理令牌
1. "你是谁?" → 查配置文件和钥匙串 2. "你的 token 还有效吗?" → 检查、刷新、不行的就让人重新登录 3. "这个操作需要什么权限?" → 预检查、不够就先告知 |
有意思的设计:安保部支持多种"身份证"来源——
本地开发者:从系统钥匙串读取(macOS 钥匙串 / Windows 凭据管理器) CI/CD 环境:从环境变量读取 AI 沙箱环境:通过 Sidecar 代理(一个独立的认证进程,token 不出沙箱)
AI Agent 视角:这是 SaaS 对接 AI Agent 时最难啃的骨头。AI Agent 可能运行在用户本地、CI/CD 环境、或云端沙箱——每种环境的认证方式都不同。lark-cli 的三种认证来源给出了一个多环境认证的标准答案。特别是 Sidecar 模式——token 不出沙箱,是 AI Agent 安全的最佳实践。
🌐 通信部(API Client)— 和飞书服务器对话
职责:所有与飞书服务器的沟通都经过这里
"带上你的通行证(token),把请求送到飞书服务器,带回结果" |
所有请求都走同一个"门"(DoSDKRequest 函数),这样:
改认证逻辑只要改一个地方 所有请求都有安全头 分页、重试、错误处理统一做
AI Agent 视角:所有请求走同一扇"门",对 AI Agent 意味着——重试、分页、错误处理都是统一的,AI 不需要理解不同 API 的调用差异。如果你在封装自己的 SaaS API 给 AI 用,这是最基础的工程要求:一个统一的 API Client,所有请求经过它。
📝 业务部(Shortcuts)— 实现具体业务功能
职责:每个快捷命令的具体逻辑
这是最多代码的地方(68,000 行)。每个业务(日历、消息、文档……)都是独立的"小组"。
以日历日程查看为例:
1. 解析时间参数(--start, --end) 2. 处理日历API的限制(飞书限制一次只能查40天) → 如果查的时间超过40天,自动切成小块分别查询 3. 合并结果、去重、排序 4. 去掉已取消的日程 5. 把时间戳转成人类可读的时间 6. 格式化输出 |
AI Agent 视角:业务逻辑里最重要的是"帮 AI 处理脏活"——比如飞书限制一次只能查 40 天,业务部自动把大时间范围切成小块分别查询再合并。AI 不需要知道这个限制。好的 SaaS AI 接口应该隐藏所有实现细节和限制,只给 AI 一个干净的语义接口。
📦 输出部(Output System)— 把结果包装成标准格式
职责:确保所有输出都是统一格式,人和 AI 都能读
两种核心输出:
| // 成功时 {"ok":true,"identity":"user","data":{...},"meta":{...}} // 失败时 {"ok":false,"error":{"type":"...","message":"...","hint":"..."}} |
支持五种输出格式:
- JSON
:给 AI 读(完整结构化) - 表格
:给人读(对齐的列) - CSV
:给 Excel 读 - NDJSON
:给工具链读(一行一个 JSON) - Pretty
:给人读(自定义美化的格式)
AI Agent 视角:这是 AI 能"读懂"你的 SaaS 的关键。输出必须是结构化、可预测、自描述的。
{"ok": true, "data": ..., "error": {"hint": "..."}}这个格式之所以好,是因为 AI 可以直接判断ok字段来确认成功或失败,失败时读hint来修复。如果你只能从 lark-cli 抄一个设计,就抄这个输出格式。
五、一张图看懂整个架构
│ 用户:"帮我查明天下午的会" │ └──────────────┬───────────────┘ │ 自然语言 ▼ ┌──────────────────────────────┐ │ 培训部 (skills/) │ │ "培训" AI Agent │ │ │ │ 读取 lark-calendar Skill: │ │ "用户要查日程 → 用 │ │ lark-cli calendar +agenda" │ └──────────────┬───────────────┘ │ 指导 AI 执行 ▼ ┌──────────────────────────────┐ │ AI Agent │ │ lark-cli calendar +agenda │ │ --start "..." │ └──────────────┬───────────────┘ │ 结构化命令 ▼ ┌──────────────────────────────┐ │ 接待部 (cmd/) │ │ "路由到正确部门" │ └──────────────┬───────────────┘ │ ┌─────────────────────────┼─────────────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ 快捷命令 │ │ API 命令 │ │ 原始 API │ │ +agenda │ │ events list │ │ api GET ... │ │ 最简单 │ │ 中等灵活 │ │ 完全灵活 │ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │ │ │ └───────────────────────┼───────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ 中间协调层 │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ 安保部 │ │ 通信部 │ │ │ │验证身份 │ │ 调用飞书API │ │ │ │检查权限 │ │ 处理分页/重试│ │ │ └──────────┘ └──────────────┘ │ │ │ └──────────────────────┬───────────────────────┘ │ ▼ ┌──────────────────────────────────────────────┐ │ 基础设施层 │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ 配置管理 │ │ 密码存储 │ │ │ │多账号切换 │ │ 系统钥匙串加密│ │ │ └──────────┘ └──────────────┘ │ │ │ │ ┌──────────┐ ┌──────────────┐ │ │ │ 安全校验 │ │ 文件系统 │ │ │ │多层防护 │ │ 虚拟化+原子写入│ │ │ └──────────┘ └──────────────┘ │ │ │ └──────────────────────┬───────────────────────┘ │ ▼ ┌──────────────┐ │ 输出部 │ │ 格式化结果 │ │ 包装成JSON │ └──────┬───────┘ │ ▼ ┌──────────────┐ │ 统一输出 │ │ {ok, data} │ └──────────────┘ |

六、这个架构最值得学习的四个点子
点子 0:Skills——给 AI 写一份"上岗培训手册"(最容易被忽视,也最重要)
大多数 SaaS 工具在对接 AI Agent 时的思路是:"我把 API 文档给你(AI),你自己看着办吧。"
lark-cli 的做法不同:它不假设 AI 能自己读懂 API 文档。 它给每个业务域编写了一份"上岗培训手册"——SKILL.md。这份手册不是 API 文档的搬运,而是专门为 AI 编写的:
"用户说'明天的会' → 用 calendar +agenda,不是去拉会议列表" "飞书日历一次只能查 40 天 → 超过的话要自动分段" "创建日程之前 → 必须先读会议预约工作流文档" "权限不足时 → 看 hint 字段,执行对应修复命令"
Skills 是整个系统里"AI Native"程度最高的设计。 它不是改 API,而是在 API 之上加了一层"AI 认知层"。如果只抄一个设计,抄这个。
点子 1:"自愈式"错误处理——不止告诉你出了什么错,还告诉你怎么修
不只是报告"出错了"——而是告诉你怎么修。
这对 AI Agent 特别重要,因为 AI 可以解析 hint 字段、自动执行修复命令。相当于程序出错了能自己"疗伤"。Skills 里也包含了错误恢复策略,所以 AI 在调用命令之前就知道可能遇到什么错误、该怎么处理。
点子 2:命令分层——不强迫 AI 或用户在"简单"和"强大"之间二选一
你想简单就简单,想灵活就灵活。不需要在"易用"和"强大"之间二选一。三层命令系统让用户和 AI 从简单开始,需要时再深入。Skills 告诉 AI 该优先用哪一层:能用 Shortcut 就用 Shortcut,不行再降级到 API 命令,再不行走原始 API。
点子 3:假设所有输入都不可信
这是安全设计的黄金法则。lark-cli 被 AI 调用,AI 可能被恶意 Prompt 操纵,所以:
文件路径要防穿越 返回数据要扫描是否含注入攻击 密码要用系统钥匙串加密 沙箱环境里 token 要用 Sidecar 代理隔离
七、一句话总结
lark-cli 不是一个普通的命令行工具,它是 AI Agent 和飞书之间的"培训师 + 翻译官 + 保安 + 管家"。Skills(AI 技能包)像一本精心编写的上岗培训手册,教导 AI 什么场景用什么命令、有哪些业务约束;CLI 工具则负责执行——把复杂的 API 调用封装成简单的命令,用结构化的输出让 AI 能理解,用自愈式的错误信息让 AI 知道怎么修正,用多层安全防护确保每一步都在控制之中。
如果你想给自己的 SaaS 服务做 AI Agent 对接,记住 lark-cli 给出的答案:API(执行)+ Skills(知识)= 一个 AI 真正能用的 SaaS。
