- CLI
- AI 技能
【免费下载链接】cli
The official Lark/飞书 CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Calendar, Mail, Tasks, Meetings, and more, with 200+ commands and 20+ AI Agent Skills.
lark-cli是 Lark/飞书官方维护的命令行工具,覆盖知识库(Wiki)、文档、表格、日历、邮件、任务、会议等核心业务域,内置 200+ 命令与 20+ AI Agent Skills。wiki +node-get是该工具知识库模块中最基础也最关键的一个只读 Shortcut:它负责把知识库节点令牌(node_token)、云文档对象令牌(obj_token)或 Lark/飞书 URL 解析成结构化的节点详情。本文基于仓库中 skills/lark-wiki/references/lark-wiki-node-get.md 编写,并结合作者在 shortcuts/wiki/wiki_node_get.go 中的源码实现与 shortcuts/wiki/wiki_node_get_test.go 的测试用例,完整讲解该命令的用法、参数、输出契约、错误分类与限流策略。读完本文,你将能够在脚本化工作流、AI Agent 编排以及手工排障中熟练使用+node-get,并在任何写操作(移动、复制、删除、建空间)之前准确确认"即将操作的节点到底是什么"。
一、命令定位:一切 Wiki 写操作前的"探路"步骤
知识库(Wiki)中的每个节点都有两套身份:知识库节点令牌(node_token,形如wikcn...)与底层对象令牌(obj_token,形如docx.../sht.../bascn...等),并归属于某个知识空间(space_id)。+node-get的官方定位非常明确——它是+move/+node-copy/+node-delete等写操作之前的 "what am I about to touch?"(我即将操作的是什么?)检查步骤:
- 操作前先用
+node-get拿到space_id、obj_type、parent_node_token等关键字段,避免对错误对象执行写操作; - 用户只给了一个知识库 URL(如
https://feishu.cn/wiki/<token>)时,先用它解析出真实的space_id与node_token,再传递给下游命令; - AI Agent 场景下,它是
wiki +node-list、wiki +member-list、wiki +delete-space等命令的统一"令牌解析器"。
这一点在 skills/lark-wiki/SKILL.md 中被反复强调:例如+delete-space只接受真实的space_id,如果用户只给 URL 或名称,必须先执行lark-cli wiki +node-get --node-token '<wiki_url>' --as user --format json读取data.space_id,再传给它。从源码结构看,+node-delete内部同样先调用node_by_token解析节点并校验空间(见 shortcuts/wiki/wiki_node_delete.go 中的resolveWikiNodeDeleteSpaceID),因此+node-get也可以被视为所有 Wiki 写命令内部解析逻辑的"前置镜像"。
二、基本用法与参数详解
2.1 命令形态
lark-cli wiki +node-get \ --node-token <node_token | obj_token | Lark URL> \ [--space-id <space_id>] \ [--format json|pretty|table|csv|ndjson] \ [--as user|bot]--node-token接受三种输入,且不需要显式声明类型——令牌类型由服务端自动探测:
| 输入类型 | 示例 | 说明 |
|---|---|---|
| 知识库节点令牌 | wikcnExample | Wiki 节点的原生令牌 |
| 云文档对象令牌 | docxExample/shtExample等 | 文档/表格/多维表格等底层对象令牌 |
| Lark/飞书 URL | https://feishu.cn/wiki/<token>、https://feishu.cn/docx/<token> | 命令行会先从 URL 路径中提取令牌 |
2.2 参数一览(Flags)
| Flag | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
--node-token | string | 是 | — | node_token、云文档obj_token,或内嵌其中之一的 Lark URL(如https://feishu.cn/wiki/<token>或https://feishu.cn/docx/<token>)。与同族的+node-delete/+node-copy/+move使用相同的--node-token命名约定。 |
--token | string | —(已弃用) | — | 旧版参数名,为向后兼容仍被接受,但使用时会向 stderr 输出Flag --token has been deprecated, use --node-token instead警告。新脚本应改用--node-token。 |
--space-id | string | 否 | — | 可选的交叉校验:如果解析出的节点不属于该知识空间,命令直接失败 |
--format | enum | 否 | json | json/pretty/table/csv/ndjson |
--as | enum | 否 | auto | 身份user/bot;知识库以用户为中心,建议显式传--as user |
2.3 身份选择:为什么建议显式--as user
知识空间和节点是用户的个人资源,skills/lark-wiki/SKILL.md 明确说明:CLI 的--as默认值是auto,不带--as时常常被解析成bot,此时列出的是应用所属的空间而非用户自己的。因此策略上应优先显式使用--as user;仅当用户明确要求"应用 / bot 视角"时才用--as bot。+node-get同时支持user与bot两种AuthTypes(见 shortcuts/wiki/wiki_node_get.go 中的WikiNodeGet定义)。
三、输出契约:JSON 字段逐一拆解
默认(--format json)输出示例:
{ "space_id": "7160145948494381236", "node_token": "wikcnEXAMPLE", "obj_token": "docxEXAMPLE", "obj_type": "docx", "node_type": "origin", "parent_node_token": "wikcnPARENT", "origin_node_token": "", "title": "Design Spec", "has_child": true, "creator": "ou_xxx", "owner": "ou_yyy", "obj_edit_time": "1700000000", "obj_create_time": "1690000000", "node_create_time": "1690000001", "updated_at": "2023-11-14T22:13:20Z" }各字段含义与来源(对照 shortcuts/wiki/wiki_node_get.go 中wikiNodeGetOutput的实现):
| 字段 | 含义 | 说明 |
|---|---|---|
space_id | 知识空间 ID | 写操作前确认目标空间,+node-get是唯一解析入口 |
node_token | 知识库节点令牌 | 作为节点在 Wiki 中的身份标识 |
obj_token | 底层对象令牌 | 节点背后实际文档/表格/Base 的令牌 |
obj_type | 对象类型 | docx、sheet、bitable、mindnote、slides、file等,以服务端返回为准 |
node_type | 节点类型 | origin(原始节点)或 shortcut(快捷方式) |
parent_node_token | 父节点令牌 | 判断节点在空间树中的位置 |
origin_node_token | 原始节点令牌 | shortcut 节点指向的原始节点;原始节点为空串 |
title | 节点标题 | 如 "Design Spec" |
has_child | 是否含子节点 | true时说明该节点是子树根 |
creator | 创建者 open_id | 优先取node_creator,缺失时回退到creator |
owner | 所有者 open_id | — |
obj_edit_time | 对象编辑时间 | 原始 Unix 秒字符串 |
obj_create_time | 对象创建时间 | 原始 Unix 秒字符串 |
node_create_time | 节点创建时间 | 原始 Unix 秒字符串 |
updated_at | 更新时间 | obj_edit_time格式化为 RFC3339(UTC) |
值得注意的实现细节:
updated_at是obj_edit_time的格式化副本:源码formatWikiTimestamp将 Unix 秒字符串统一转换为 UTC 时区的 RFC3339(如1700000000→2023-11-14T22:13:20Z),保证输出不随运行主机时区漂移;空值或非数字输入返回空串,pretty 视图渲染为-。creator双字段回退:源码先读node_creator,为空时再读creator,对应测试TestWikiNodeGetFallsBackToCreatorWhenNodeCreatorMissing验证了该回退行为。- 输出不合成
url字段:即使 API 响应中携带url,+node-get也会保持既有输出字段不变、不输出url,node_token/obj_token才是精确标识符(对应测试中的断言 "did not expect a url field in +node-get output")。 --space-id交叉校验:当--space-id被指定且与解析结果不一致时,命令以校验错误失败(--space-id %q does not match the resolved node space %q);若 API 未返回space_id,则会向 stderr 输出一条 "could not be verified" 警告,避免调用方误以为校验已生效。
--format pretty会渲染为可读的分行视图(Wiki node:头 + 各字段对齐输出),table/csv/ndjson则分别适合终端表格展示、Excel/CSV 管道与逐行流式消费。
四、令牌解析规则:源码级原理
+node-get的输入处理逻辑集中在 shortcuts/wiki/wiki_node_get.go 的parseWikiNodeGetSpec与tokenAndObjTypeFromWikiURL,其规则可以归纳为四条:
原样透传:原始令牌(不含
://与/?#)直接作为请求参数,不校验前缀、不限制长度——令牌类型与长度合法性完全交给服务端node_by_token探测。对应测试TestParseWikiNodeGetSpecLeavesTokenLengthToServer覆盖了 1 到 128 位长度的各种输入。URL 提取:输入包含
://时,先用url.Parse校验语法,再从路径段中提取令牌。支持路径前缀见下表,提取时只取第一个路径段(wikiPathSegmentAfter),查询参数(?foo=bar)被忽略:URL 路径前缀 含义 /wiki/知识库节点(不推断底层文档类型) /docx/文档对象令牌 /doc/旧版文档 /sheets/表格 /base/多维表格 /mindnote/思维笔记 /slides/幻灯片 /file/文件 前缀映射定义在源码
wikiNodeGetURLObjTypes中,注释强调前缀之间必须互不为前缀(如/docx/不能以/doc/开头),否则 Go map 随机迭代顺序会导致匹配不确定。拒绝半路径:输入包含
/?#但不是完整 URL(如/wiki/wikcnABC)时直接报错partial paths are not accepted,要求要么给原始令牌要么给完整 URL。URL 不用于断言类型:URL 路径只用来提取令牌,绝不拿路径暗示的类型去断言返回的
obj_type——最终obj_type一律以服务端返回值为准。
此外,--node-token与弃用的--token同时给出且值不同时,会直接以校验错误拒绝(提示只用--node-token);两者相同或只给一个时正常工作,这个"冲突前置拦截"逻辑由resolveWikiNodeGetRawToken实现(见对应测试TestResolveWikiNodeGetRawTokenRejectsConflict)。
兼容性:--token与--obj-type
--token是旧版参数名,通过 cobra 的MarkDeprecated注册(PostMount钩子),使用时在 stderr 打印弃用警告,功能照常可用;--obj-type是已弃用且隐藏的兼容参数:旧脚本传入时其值被静默忽略,不产生任何警告与额外输出。URL 路径只用于提取令牌、不断言对象类型;--space-id仍是响应后的交叉校验。
五、底层 API 与请求细节
+node-get背后只调用一个 HTTP 接口:
GET /open-apis/wiki/v2/spaces/node_by_token?token=<token>关键事实(源码RequestParams与测试TestBuildWikiNodeGetDryRunSendsOnlyToken/TestWikiNodeGetShortTokenReachesAPI均验证):
- 请求参数只有
token:--space-id、--obj-type等都不会进入请求;服务端自行判断传入的是 Wiki 令牌还是文档令牌,并校验其长度; - CLI 只做最小前置校验:令牌非空、URL 语法合法、资源名不含非法字符,其余全部放行给服务端;
- dry-run 预览:
--dry-run会输出一条只含token参数的 GET 调用预览(Resolve wiki node from token (token type detected by server)),方便在真实请求前确认将发送的内容。
从更广的视角看,该接口是 Wiki 模块的公共解析原语:+node-delete、+node-copy、+move、+delete-space等命令内部都复用同一接口(见 shortcuts/wiki/wiki_node_lookup.go 中的lookupWikiNode),这正是+node-get输出"可直接管道给下游写命令"的底层原因。
六、业务错误码:HTTP 200 不等于成功
这是+node-get排障中最重要的认知:这些 HTTP 200 响应携带非零业务码,且使用相同输入重试无效(终端业务错误):
| Code | 含义 | 应对动作 |
|---|---|---|
131005 | Wiki 节点不存在 | 检查令牌,或获取最新的 Wiki 链接 |
131006 | 当前用户或应用/bot 身份无权访问该节点或空间 | 这是资源访问权限问题,不是应用 scope 授权问题。不要重试同一请求、不要通过重新授权或切换身份试错;请节点所有者或 Wiki 管理员授予读权限,或改用可访问的资源 |
131012 | Wiki 节点已被删除 | 不要重试同一节点令牌;重新发现节点或索要最新 Wiki 链接 |
131013 | 资源令牌无效 | 不要切换身份或重新授权;修正 URL/令牌 |
131014 | 文档未挂载到 Wiki | 停止 Wiki 解析;改用对应的 docs/sheets/base/drive 命令,或提供 Wiki URL/node_token |
131016 | 令牌过短 | 提供完整令牌或文档 URL;不要用同一输入重试 |
131001(非法请求)与网关错误仍可能返回 HTTP 4xx/5xx。
源码层面,这些码的归类与恢复提示由wikiNodeGetProblem(调用 shortcuts/wiki/wiki_node_lookup.go 的wikiNodeLookupProblem)完成,测试TestWikiNodeGetMountedClassifiesTerminalBusinessErrors逐项断言了错误分类(SubtypeNotFound/SubtypeInvalidParameters/SubtypeFailedPrecondition)与提示文本;131006额外强制Retryable=false,其提示由wikiPermissionDeniedHint统一给出,明确"不要重试、不要切换身份试错";131013/131016的提示还会追加"提供完整的原始obj_token"的恢复指引。这些终端错误全部不可重试——修复方向永远是换令牌、换操作或换权限,而不是换一种姿势重发同一请求。
七、限流策略
当收到99991400/rate_limit错误时:
- 不要立即重试;
- 等待
retry_after_seconds,或使用带抖动(jitter)的指数退避; - 总共最多尝试 3 次(1 次初始 + 2 次重试)。
该策略在源码中体现为常量提示wikiNodeGetRateLimitHint,与上游的退避指导合并追加到错误提示中;测试TestWikiNodeGetProblemBoundsRateLimitRetries验证了99991400保持Retryable=true、保留RetryAfterSeconds、并追加限流提示的行为。注意这与上述业务码"不可重试"形成鲜明对比:只有rate_limit才做退避重试。
八、权限要求与典型工作流
8.1 所需 Scope
wiki:node:retrieve该 scope 在 shortcuts/wiki/wiki_node_get.go 的WikiNodeGet.Scopes中声明,测试TestWikiNodeGetSilentlyIgnoresLegacyObjectType还专门断言了该 scope 列表的稳定性。由于解析节点需要 Wiki 读权限,即使后续操作(如删除)还依赖其他 scope,+node-get这一环始终需要wiki:node:retrieve。
8.2 三个高频实战组合
场景一:用 URL 解析出空间 ID,再查空间成员
lark-cli wiki +node-get --node-token 'https://feishu.cn/wiki/<token>' --as user --format json # 读取 data.space_id 后: lark-cli wiki +member-list --space-id <space_id> --as user场景二:写操作前的安全检查
# 移动 / 复制 / 删除前,先确认对象类型、父节点与所属空间 lark-cli wiki +node-get --node-token <node_token> --format table --as user lark-cli wiki +move --node-token <node_token> --space-id <space_id> ... lark-cli wiki +node-copy --node-token <node_token> --space-id <space_id> ... lark-cli wiki +node-delete --node-token <node_token> --space-id <space_id> --yes场景三:给--space-id加交叉校验,防止误操作
lark-cli wiki +node-get --node-token <url> --space-id <期望的空间ID> --format json # 若节点不在该空间,命令立即以校验错误失败九、使用注意事项小结
- 身份优先用
--as user:Wiki 是用户中心资源,auto常解析为 bot 视角,看到的是应用所属空间; - URL 路径只在
/wiki/、/docx/、/doc/、/sheets/、/base/、/mindnote/、/slides/、/file/后提取令牌,其他路径(如 IM 链接)直接报"unsupported URL path"; - 令牌类型永远以服务端返回为准,
--obj-type已被弃用并静默忽略; - 业务错误码不可重试,唯一例外是
99991400限流(最多 3 次尝试); - 输出中
node_token/obj_token是权威标识符,不要依赖合成 URL; - 该命令是纯只读(
Risk: "read"),可以放心用于 AI Agent 的探索步骤,不会改变任何资源状态。
掌握wiki +node-get,就等于掌握了整个飞书知识库命令族的"钥匙"——无论你是在为+node-copy确认源节点、为+node-delete核对空间归属,还是仅仅需要把一个 Wiki URL 翻译成机器可读的 JSON,它都是最快、最稳的第一步。
- CLI
- AI 技能
【免费下载链接】cli
The official Lark/飞书 CLI tool, maintained by the larksuite team — built for humans and AI Agents. Covers core business domains including Messenger, Docs, Base, Sheets, Calendar, Mail, Tasks, Meetings, and more, with 200+ commands and 20+ AI Agent Skills.
相关推荐
lark-cli 飞书知识库 +node-create 命令实战:自动空间解析的知识库节点创建指南
lark cli 飞书知识库 +node create 命令实战:自动空间解析的知识库节点创建指南 导读 :本文围绕 lark cli 的 wiki +node
CLIAI 技能飞书知识库节点移动全攻略:lark-cli `wiki +move` 的 node / docs_to_wiki 双模式详解
飞书知识库节点移动全攻略:lark cli wiki +move 的 node / docs_to_wiki 双模式详解 本文以 Lark 官方 CLI(lar
CLIAI 技能使用 lark-cli 的 `wiki +member-list` 命令查询飞书知识库空间成员
使用 lark cli 的 wiki +member list 命令查询飞书知识库空间成员 导读 wiki +member list 是飞书官方 CLI 工具
CLIAI 技能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考