Skip to content

Commit c000dc3

Browse files
authored
docs: refine lark-drive knowledge organize workflow (#1253)
Change-Id: I49b4f398d60c5bb073d6c8d61987bd16f1a29c4e
1 parent 256df8c commit c000dc3

6 files changed

Lines changed: 314 additions & 57 deletions

skills/lark-drive/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,12 +295,14 @@ lark-cli drive <resource> <method> [flags] # 调用 API
295295
```
296296

297297
> **重要**:使用原生 API 时,必须先运行 `schema` 查看 `--data` / `--params` 参数结构,不要猜测字段格式。
298+
>
299+
> **高频原生命令:** 读取 Drive 文件夹清单时使用 `drive files list`,必须按 [`references/lark-drive-files-list.md`](references/lark-drive-files-list.md) 的模板通过 `--params``folder_token` / `page_token`,并手动处理分页;不要把 `--page-all` 输出直接交给 JSON 解析脚本。
298300
299301
### files
300302

301303
- `copy` — 复制文件
302304
- `create_folder` — 新建文件夹
303-
- `list` — 获取文件夹下的清单
305+
- `list` — 获取文件夹下的清单;使用前阅读 [`references/lark-drive-files-list.md`](references/lark-drive-files-list.md)
304306
- `patch` — 修改文件标题
305307

306308
### file.comments
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
# drive files list(原生 API:读取 Drive 文件夹清单)
2+
3+
`drive files list` 是原生 API 命令,不是 shortcut。它用于读取 Drive 根目录或某个 Drive 文件夹的直接子项;如果要递归盘点目录树,Agent 必须基于返回的子文件夹 token 继续调用本命令。
4+
5+
## 什么时候使用
6+
7+
| 场景 | 是否使用 | 说明 |
8+
|------|----------|------|
9+
| 盘点一个已确认的 Drive 文件夹树 | 使用 | 从目标 `folder_token` 开始递归列取 |
10+
| 盘点用户明确确认的 Drive 根目录 | 使用 | 第一层用空 `folder_token`,子文件夹继续按普通文件夹递归 |
11+
| 验证移动 / 创建后的实际位置 | 使用 | 读取目标目录直接子项,再按需递归验证 |
12+
| 根据关键词、标题、时间、owner 找资源 | 不使用 | 优先用 `drive +search` |
13+
| 读取 Docx 正文内容 | 不使用 |`docs +fetch --api-version v2` |
14+
| 读取 Sheet / Base 内部数据 | 不使用 | 切到 `lark-sheets` / `lark-base` |
15+
16+
## 标准命令模板
17+
18+
读取普通文件夹:
19+
20+
```bash
21+
lark-cli drive files list \
22+
--params '{"folder_token":"<folder_token>","page_size":200}' \
23+
--format json
24+
```
25+
26+
继续翻页:
27+
28+
```bash
29+
lark-cli drive files list \
30+
--params '{"folder_token":"<folder_token>","page_size":200,"page_token":"<PAGE_TOKEN>"}' \
31+
--format json
32+
```
33+
34+
读取当前用户 Drive 根目录的直接子项:
35+
36+
```bash
37+
lark-cli drive files list \
38+
--params '{"folder_token":"","page_size":200}' \
39+
--format json
40+
```
41+
42+
也可以省略 `folder_token` 字段来请求根目录,但在 Agent 编排中建议显式传空字符串,避免把“忘记传参数”和“确认请求根目录”混在一起。
43+
44+
## 参数规则
45+
46+
1. `folder_token` 必须放在 `--params` JSON 里;不要使用不存在的 `--folder-token` flag。
47+
2. `page_token` 必须放在 `--params` JSON 里;不要依赖 shell 变量拼接不完整的 JSON。
48+
3. `page_size` 建议显式设置为 `200`。如果服务端或环境返回参数错误,再降级到服务端允许的值,并记录降级原因。
49+
4. 调用前如果不确定字段结构,先运行 `lark-cli schema drive.files.list` 查看 `--params` 结构。
50+
51+
## 返回结构与解析
52+
53+
`--format json` 输出中,Agent 只使用 `data` 中符合 `schema drive.files.list` 的 API 返回字段。
54+
55+
常用字段:
56+
57+
| 字段 | 用途 |
58+
|------|------|
59+
| `data.files` | 当前页直接子项列表 |
60+
| `data.has_more` | 当前目录是否还有下一页 |
61+
| `data.next_page_token` | 下一页 token;当 `has_more=true` 时放回 `--params.page_token` |
62+
| `data.files[].type` | 文件类型;等于 `folder` 时可递归 |
63+
| `data.files[].token` | 当前资源 token;文件夹递归时作为下一层 `folder_token` |
64+
| `data.files[].name` | 生成路径和展示标题 |
65+
| `data.files[].url` | 资源浏览器链接 |
66+
| `data.files[].owner_id` | 资源所有者 |
67+
| `data.files[].created_time` / `data.files[].modified_time` | 创建 / 更新时间 |
68+
69+
字段名以 `schema drive.files.list` 为准。Agent MUST 以实际返回为准;如果字段缺失,先用 `schema drive.files.list` 或一页样本确认结构,不要猜测。
70+
71+
## 根目录语义
72+
73+
1. `folder_token` 为空字符串或省略时,请求的是当前调用用户的 Drive 根目录直接子项。
74+
2. 根目录返回值不是递归结果;不能把根目录第一页或直接子项数量当作整个云空间资源总量。
75+
3. 根目录只作为目录树起点。返回的子文件夹必须用其自己的 `folder_token` 继续调用 `drive files list`
76+
4. 根据 schema 描述,根目录第一层清单不支持分页且不返回快捷方式;不要基于根目录响应推断子文件夹内容、根目录第一层快捷方式或无法分页的根目录剩余项已经被覆盖。
77+
78+
## 递归盘点规则
79+
80+
1. 只对返回项中的 `folder` 类型继续递归。
81+
2. 每个目录独立维护分页状态;一个目录的 `page_token` 不可复用于其他目录。
82+
3. 对每个目录持续请求,直到返回 `has_more=false`。非根目录的普通文件夹清单可能返回 `type=shortcut` 条目;不要假设这些条目会携带 `shortcut_info` 目标信息。
83+
4. 递归过程中生成稳定 `path`;不要只保存标题,否则同名资源无法区分。
84+
5. URL、owner、创建时间和更新时间优先使用 `files.list` 返回字段;如果字段缺失或需要批量补齐,再使用 `drive metas batch_query`。不要从标题或路径猜元数据。
85+
6. 深度、数量、每目录页数等限制只能作为内部批次 checkpoint;不能作为递归完成条件。
86+
7. 达到深度 checkpoint 时,把更深层子文件夹加入 continuation queue,并在下一批从这些子文件夹继续,保留原始 `path`
87+
8. 达到数量 checkpoint 时,保存当前目录、当前页 token、剩余目录队列和已收集资源计数,并立即继续下一批;不要进入分析或规划阶段。
88+
89+
### 递归算法
90+
91+
Agent 盘点 Drive 文件夹树时,按以下顺序执行:
92+
93+
1. 初始化待处理队列,放入起点目录:
94+
- 普通文件夹:`{folder_token:"<folder_token>", path:"<folder_name>"}`
95+
- Drive 根目录:`{folder_token:"", path:""}`
96+
2. 从队列取出一个目录,请求第一页。
97+
3.`(folder_token, page_token)` 生成当前页 key;同一页 key 只允许追加一次,避免 retry 时重复计数。
98+
4.`data.files` 取当前页直接子项,按 `dedupe_key` 去重后生成 `path` 并加入结果集。
99+
5. 如果新追加的子项是 `folder`,把子文件夹 token、子路径和 depth 加入队列。
100+
6. 如果 `has_more=true`,取 `data.next_page_token` 继续请求同一目录下一页。
101+
7. 同一目录分页结束后,再处理队列中的下一个目录。
102+
8. 如果达到深度、数量或每目录页数 checkpoint,把当前目录 / 页 token / 剩余队列 / 已访问页 key / dedupe key 写入 continuation queue,并继续下一批。
103+
9. 普通队列和 continuation queue 都为空,且没有分页 blocker 时,才可以认为本次确认范围盘点完成。
104+
105+
简化伪代码:
106+
107+
```text
108+
queue = [root_or_start_folder]
109+
visited_pages = set()
110+
dedupe_keys = set()
111+
while queue not empty:
112+
folder = queue.pop()
113+
page_token = folder.page_token or ""
114+
retry_without_token = 0
115+
while true:
116+
page_key = (folder.folder_token, page_token or "first")
117+
page = drive files list(folder.folder_token, page_token)
118+
if page_key not in visited_pages:
119+
append only files whose dedupe_key is not in dedupe_keys
120+
enqueue newly appended child folders with folder_token, path, and depth
121+
add page_key to visited_pages
122+
if page.has_more != true:
123+
break
124+
next = page.next_page_token
125+
if next is empty:
126+
retry_without_token += 1
127+
if retry_without_token >= 3:
128+
record pagination blocker for folder
129+
break
130+
continue
131+
page_token = next
132+
retry_without_token = 0
133+
```
134+
135+
## 分页与异常
136+
137+
1. 默认手动处理 `has_more` 和返回中的 `next_page_token`
138+
2. 不要使用 `--page-all` 作为脚本 JSON 解析输入;自动翻页输出可能不适合直接 `json.loads`
139+
3. 如果 `has_more=true` 但没有可用的 `next_page_token`,重试同一页最多 3 次。
140+
4. 重试后仍无 continuation token 时,记录受影响的目录和 pagination blocker,停止扩展该目录;不要无限循环,也不要宣称该目录已完整覆盖。
141+
5. 如果触发深度、数量或每目录页数限制,把它视为批处理 checkpoint;在确认范围内继续下一批,而不是把当前结果说成完整。
142+
6. 不要因为达到 `max_depth=3``max_items=500` 或类似单批阈值就结束盘点;只有队列耗尽或遇到权限 / API / 工具预算 blocker 才能结束当前确认范围的盘点。
143+
144+
## JSON 解析规则
145+
146+
1. stdout 是数据通道。脚本解析 JSON 时只读取 stdout。
147+
2. stderr 可能包含刷新 token、进度、warning 或其他提示;不要把 stderr 合并进 JSON 输入,例如不要用 `2>&1` 后再 `json.loads`
148+
3. 使用 `--format json` 保持 stdout 为结构化 JSON;解析 Drive 文件清单时只读取 `data.files` / `data.has_more` / `data.next_page_token` 等 schema 字段。
149+
4. 不要用根目录响应数量或当前页数量推断递归总量;递归总量必须由实际遍历并去重后的资源集合计算。
150+
151+
## 常见错误
152+
153+
| 错误用法 | 问题 | 正确做法 |
154+
|----------|------|----------|
155+
| `lark-cli drive files list --folder-token <token>` | `files.list` 不提供 `--folder-token` flag | 使用 `--params '{"folder_token":"<token>"}'` |
156+
| 根目录返回 N 项就认为云空间只有 N 项 | 根目录只返回直接子项,不是递归结果 | 对返回的子文件夹继续递归 |
157+
| `--page-all \| python json.loads(...)` | 自动翻页输出不适合作为单个 JSON 对象解析 | 手动使用 `page_token` 翻页并逐页解析 |
158+
| `cmd 2>&1` 后解析 JSON | stderr 提示污染 JSON 输入 | 只解析 stdout,stderr 作为日志处理 |

skills/lark-drive/references/lark-drive-workflow-knowledge-organize-analysis.md

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ MUST:
2424
4. Switch to `lark-sheets` / `lark-base` only when sheet / bitable title and path are insufficient.
2525
5. Record read evidence for classification.
2626
6. Continue reading low-confidence resources in internal batches until all supported low-confidence resources in the current inventory are processed or a blocker occurs.
27-
7. Output progress / summary without asking the user to continue between batches.
27+
7. Apply `Analysis Progress Reporting`.
28+
8. Output progress / summary without asking the user to continue between batches.
2829

2930
Exit: low-confidence items are classified or marked `needs_review=true`.
3031

@@ -93,6 +94,30 @@ Output this summary:
9394

9495
- After every 50 processed low-confidence resources.
9596
- Once after low-confidence reading finishes.
97+
- About every 60 seconds during long-running reads, even if fewer than 50 additional resources were processed.
98+
99+
### Analysis Progress Reporting
100+
101+
Applies to `CONTENT_READ`, `ISSUE_ANALYSIS`, and `RULE_GENERATION`.
102+
103+
Rules:
104+
105+
1. For `CONTENT_READ`, use `Low-Confidence Read Summary` as the progress report format.
106+
2. For `ISSUE_ANALYSIS`, if analysis runs longer than about 60 seconds, output progress about every 60 seconds with current stage, processed resource count when known, detected problem type count when known, and the next analysis step.
107+
3. For `RULE_GENERATION`, if classification rule or target-tree generation runs longer than about 60 seconds, output progress about every 60 seconds with current stage, classified item count when known, unresolved item count when known, and target category / path count when known.
108+
4. Progress reports MUST be factual and stage-specific. Do not output generic "still running" messages without counts or the current stage.
109+
5. Do not ask the user to continue between internal batches unless auth, permission, API, target scope, or environment blockers occur.
110+
6. Do not expose internal chain-of-thought, raw tokens, or intermediate rule drafts.
111+
112+
Examples:
113+
114+
```text
115+
分析进度:正在归纳整理问题,已处理 <processed_count>/<resource_count> 项资源,已识别 <problem_type_count> 类问题。继续生成整理思路,不会执行移动或创建。
116+
```
117+
118+
```text
119+
规则生成进度:正在生成分类规则和目标目录,已归类 <classified_count> 项,待人工确认 <needs_review_count> 项。继续生成完整计划前置数据。
120+
```
96121

97122
## State: ISSUE_ANALYSIS
98123

@@ -103,8 +128,9 @@ MUST:
103128
1. Detect problems from organization perspective only. Do not generate research conclusions.
104129
2. Generate an organization approach based on inventory, low-confidence read evidence, and detected problems.
105130
3. Include how non-reused source containers will be handled after their contents are moved.
106-
4. Output `Inventory And Organization Approach Decision`.
107-
5. Stop and wait for the user to confirm the approach before `RULE_GENERATION`.
131+
4. Apply `Analysis Progress Reporting`.
132+
5. Output `Inventory And Organization Approach Decision`.
133+
6. Stop and wait for the user to confirm the approach before `RULE_GENERATION`.
108134

109135
Problem rules:
110136

@@ -161,10 +187,10 @@ MUST output evidence count or example paths. Do not output only abstract judgmen
161187
是否基于这个整理思路生成目标目录和移动 / 创建计划?
162188
163189
你可以选择:
164-
A. 基于这个思路生成目标目录和计划
165-
B. 调整整理思路
166-
C. 查看问题详情
167-
D. 取消本次整理
190+
1. 基于这个思路生成目标目录和计划
191+
2. 调整整理思路
192+
3. 查看问题详情
193+
4. 取消本次整理
168194
```
169195

170196
## State: RULE_GENERATION
@@ -181,7 +207,8 @@ MUST:
181207
6. For non-reused source containers, ensure `target_tree` includes a source-container cleanup target, defaulting to `待人工确认/待清理旧目录`, unless the user explicitly asks to keep source containers in place.
182208
7. Ensure target tree can contain every planned `target_path`.
183209
8. Ensure the target tree contains a manual confirmation target named `待人工确认` unless the user explicitly provides an equivalent name.
184-
9. Continue to `PLAN_GENERATION` without a separate target-tree-only confirmation.
210+
9. Apply `Analysis Progress Reporting`.
211+
10. Continue to `PLAN_GENERATION` without a separate target-tree-only confirmation.
185212

186213
### Classification
187214

0 commit comments

Comments
 (0)