14 KiB
主题资料收集工作流:资源解析与内容验证
由状态 RESOURCE_RESOLVE、CONTENT_VERIFY 加载。
本文档负责资源解析、结构化父级、移动资格、内容验证和 ResourceItem。不得判断相关性、生成移动计划、创建目标、移动资源或执行恢复操作。
本文档只服务 topic_move_collector。进入本文档时,workflow_id 必须是 topic_move_collector;不得把当前任务改路由到其他 workflow。
必读上下文
执行本文档规则前:
- 按
../../lark-shared/SKILL.md处理身份、认证和权限。 - 按
lark-drive-inspect.md处理 URL / token 解析。 - 使用
drive metas batch_query补齐 Drive 资源 owner、标题和 URL。 - 必要时使用
drive permission.members auth读取权限信号;该接口不提供full_access/ 移动权限的直接判定,不能把manage_public等同为可移动。 - 按
../../lark-wiki/references/lark-wiki-node-get.md处理 Wiki 节点解析。 - 按
../../lark-doc/references/lark-doc-fetch.md读取文档内容。 - 需要验证 Sheet 内容时,按
../../lark-sheets/SKILL.md执行。
进入解析与验证阶段前校验
进入本文档后,如果 resource_items 还不存在,当前状态必须是 RESOURCE_RESOLVE。
禁止从 candidate_items 直接进入 CONTENT_VERIFY 或 RELEVANCE_CLASSIFY,也禁止从 RESOURCE_RESOLVE 直接进入 RELEVANCE_CLASSIFY。即使候选项已有标题、URL、摘要或 token,也必须依次执行 RESOURCE_RESOLVE 和 CONTENT_VERIFY;两个状态不得合并。
状态:RESOURCE_RESOLVE
进入条件:候选列表已准备。
必须:
- 为每个
CandidateItem生成稳定resource_id,并转换为标准化ResourceItem。 - 解析 canonical token、资源类型、URL、结构化当前父级、Wiki 节点身份和读取权限状态。
- 对 Wiki 资源同时保留
wiki_node_token和wiki_obj_token。 - 按
move_method补齐owner_id、is_owner、source_move_state、source_parent_write_state、target_write_state、move_permission_state和move_permission_basis。 - 基于
target_location检测不支持的移动方向。 - 未解析成功的资源仍保留在审核分组中,不得静默丢弃。
- 即使搜索结果已经包含标题、URL 或 token,也必须经过本状态生成
ResourceItem;不得从召回结果直接进入相关性分级。 - 只有确认
move_permission_state=movable且target_write_state=confirmed的资源,才能进入后续默认移动链路。 - 解析耗时超过约 60 秒时,必须输出进度提示,之后约每 60 秒提示一次。
解析规则
| 候选类型 | agent 必须执行 |
|---|---|
| Drive URL / token | token 或类型不确定时,使用 drive +inspect。 |
| Wiki URL / token | 使用 drive +inspect 或 wiki +node-get;保留节点身份和对象身份。 |
| 文件夹候选 | 标记为容器;不要当作普通文档做内容验证。 |
| 快捷方式候选 | 能解析源资源时解析源资源;同时保留快捷方式身份。 |
| 无读取权限 | 保留可见元数据,并设置 permission_state=denied。 |
| 无移动权限或移动权限未知 | 保留可见元数据和召回证据,并设置对应 move_permission_state。 |
| 无法解析当前父级 | 设置 current_parent_kind=unknown,保留已知路径,后续计划项设置 rollback_supported=false 和明确 blocker;不得编造父级 token。 |
资源解析进度 UI
当 RESOURCE_RESOLVE 持续超过约 60 秒时,输出当前进度:
资源解析进度:已解析 <resolved_count>/<total_count> 项,已确认可移动 <movable_count> 项,无移动权限 <denied_count> 项,移动权限未知 <unknown_count> 项,解析失败 <failed_count> 项。
当前资源:<title>
继续解析中,不会创建或移动资源。
如果正在处理权限或 owner 元数据,可补充:
当前步骤:解析 owner / 当前父级 / 移动资格。
RESOURCE_RESOLVE 完成后,输出摘要:
资源解析完成:
- 候选总数:N 项
- 可进入内容验证:N 项
- 无移动权限:N 项
- 移动权限未知:N 项
- 解析失败或无读取权限:N 项
下一步会对可移动资源做内容验证;不会创建或移动资源。
资源解析出口门禁
RESOURCE_RESOLVE 完成后必须:
- 将
content_verify_completed重置为false。 - 将下一状态设置为
CONTENT_VERIFY,不得设置为RELEVANCE_CLASSIFY或PLAN_MOVE。 - 不得在本状态生成
relevance、relevance_groups或移动计划。 - 即使可读取正文的资源数量为 0,也必须进入
CONTENT_VERIFY,为每项记录跳过验证原因并输出验证摘要。
移动资格判定
owner 只能作为部分权限证据,不得单独把资源判为 movable。RESOURCE_RESOLVE 必须先按 move_method 记录以下独立状态:
| 字段 | 说明 |
|---|---|
source_move_state |
当前身份是否确认可以对源资源执行对应移动;Drive owner 只可作为 Drive 源资源可管理的证据,Wiki 底层资源 owner 不能证明 Wiki 节点可移动。 |
source_parent_write_state |
当前身份是否确认可编辑源位置;仅 drive_move 必须确认,其他移动方式为 not_required。 |
target_write_state |
当前身份是否确认可写目标位置;待创建目标以父级位置的创建 / 写入权限为准。 |
按移动方式的权限矩阵
move_method |
source_move_state=confirmed 的证据 |
source_parent_write_state |
target_write_state |
|---|---|---|---|
drive_move |
当前用户是可靠解析出的 Drive 资源 owner,或有明确资源可管理证据 | 必须为 confirmed |
必须为 confirmed |
wiki_move_docs_to_wiki |
有明确的 Drive 文档直接迁入权限;仅 owner 元数据不足以证明可直接迁入 | not_required |
必须确认目标 Wiki 节点 / 空间可写 |
wiki_move_node |
有明确的 Wiki 节点 / 源空间移动权限;不得从底层资源 owner 推导 | not_required |
必须确认目标 Wiki 节点 / 空间可写 |
wiki_move_to_drive |
有明确的 Wiki 节点移出权限;不得从底层资源 owner 推导 | not_required |
必须确认目标 Drive 文件夹可写 |
聚合顺序
- 目标方向或资源类型不支持时,设置
move_permission_state=denied、move_permission_basis=["unsupported_direction"]。 - 任一必需状态为
denied时,设置move_permission_state=denied,并在move_permission_basis记录source_denied、source_parent_denied或target_denied。 - 任一必需状态为
unknown时,设置move_permission_state=unknown,并记录对应的source_unknown、source_parent_unknown或target_unknown。 - 只有权限矩阵中的全部必需状态都为
confirmed时,才能设置move_permission_state=movable、move_permission_basis=["permission_matrix_confirmed"]。
注意:
drive permission.members auth不提供full_access或moveaction;不能用view、edit、share或manage_public结果推断源位置或目标位置可写。target_write_state=unknown|denied的资源不得进入高 / 中相关可执行分组或移动计划。move_permission_state=unknown的资源默认不进入内容验证、相关性高 / 中分组或移动计划。- 当
owner_scope=mine但解析出的 owner 不是当前用户时,将该资源视为异常候选,设置source_move_state=unknown和move_permission_state=unknown,不得加入移动计划。
状态:CONTENT_VERIFY
进入条件:资源列表已准备。
必须:
- 本状态不可跳过,也不得与
RESOURCE_RESOLVE或RELEVANCE_CLASSIFY合并;没有可读取正文的资源时仍须执行。 - 只在资源解析后读取支持的内容。
- 按数量、大小和类型能力限制读取范围。
- 结合搜索证据和内容证据;除非标题精确且足够强,否则不要仅凭标题判为高相关。
- 将不可读取资源标记为
unverifiable或permission_denied。 - 不得自动申请权限。
- 为每个资源写入验证状态:已读取内容证据、仅可使用搜索证据、无权限、无移动权限、移动权限未知、无法验证或不支持内容验证。
- 对
move_permission_state=denied|unknown的资源,不再读取正文内容,写入跳过验证原因并保留召回证据;写入跳过原因属于执行本状态,不等于跳过本状态。 - 所有资源都有验证状态或跳过原因后,将
content_verify_completed设置为true并输出验证摘要。 content_verify_completed=true前不得进入RELEVANCE_CLASSIFY。
验证方式
| 资源类型 | 验证方式 |
|---|---|
docx / doc |
允许时使用 docs +fetch --api-version v2。 |
sheet |
使用 sheets +find 查关键词证据,或用 sheets +read 读取有界范围。 |
bitable |
只有必要且已加载 Base 能力时验证。 |
slides |
除非具备幻灯片读取能力,否则使用元数据 / 预览 / 标题证据。 |
file |
仅在支持时使用标题、元数据、预览或导出文本。 |
wiki 节点 |
按 obj_type 验证底层对象;节点本身不是内容 token。 |
folder |
除非用户明确要移动容器,否则通常不作为主题证据移动。 |
内容验证完成 UI
完成 CONTENT_VERIFY 后必须输出:
内容验证完成:
- 已读取内容证据:N 项
- 仅复用搜索证据:N 项
- 因无权限或移动资格跳过:N 项
- 无法验证或不支持验证:N 项
下一步会基于以上证据进行相关性分组;不会创建或移动资源。
如果没有任何资源可以读取正文,仍须输出该摘要,并明确说明所有资源采用的搜索证据或跳过原因。
内容验证出口门禁
CONTENT_VERIFY 完成后必须:
- 确认
content_verify_completed=true,且每个ResourceItem都已有验证状态或跳过原因。 - 将下一状态设置为
RELEVANCE_CLASSIFY。 - 加载
lark-drive-workflow-topic-move-collector-review-plan.md。 - 不得直接进入
PLAN_MOVE。
ResourceItem
{
"resource_id": "稳定资源 ID",
"title": "资源标题",
"resource_type": "doc|docx|sheet|bitable|file|folder|wiki|slides|shortcut",
"url": "资源链接",
"canonical_token": "标准资源 token",
"wiki_node_token": "Wiki 节点 token",
"wiki_obj_token": "Wiki 底层对象 token",
"wiki_obj_type": "Wiki 底层对象类型",
"space_id": "知识空间 ID",
"current_parent_kind": "drive_folder|drive_root|wiki_node|wiki_space_root|unknown",
"current_parent_token": "当前父级 token",
"current_parent_space_id": "当前父级 Wiki space_id",
"current_path": "用于展示的当前位置",
"owner_id": "资源 owner open_id",
"is_owner": "true|false|unknown",
"permission_state": "readable|denied|unknown",
"source_move_state": "confirmed|unknown|denied",
"source_parent_write_state": "confirmed|unknown|denied|not_required",
"move_permission_state": "movable|denied|unknown",
"move_permission_basis": ["权限矩阵证据或阻塞原因"],
"target_write_state": "confirmed|unknown|denied",
"item_resolve_status": "resolved|partial|failed",
"content_verify_state": "verified|search_evidence_only|skipped_by_move_permission|permission_denied|unverifiable|unsupported",
"content_evidence": ["证据"],
"relevance": "high|medium|low|permission_denied|no_move_permission|move_permission_unknown|unverifiable|unsupported_move_target"
}
| 字段 | 说明 |
|---|---|
canonical_token |
内容读取、Drive 对象操作或底层对象操作使用的标准 token;Wiki 节点移动不得使用该字段。 |
resource_id |
资源解析时生成的稳定 ID,用于连接 ResourceItem 和 MovePlanItem。 |
wiki_node_token |
Wiki 节点身份,用于 Wiki 节点移动。 |
wiki_obj_token |
Wiki 节点背后的真实文档 token。 |
current_parent_kind / current_parent_token / current_parent_space_id |
结构化执行前父级,用于 already_at_target 判断和恢复;未知值不得猜测。 |
current_path |
仅用于用户展示的当前位置,不得代替父级 token。 |
owner_id |
资源 owner;Drive 资源优先来自 drive metas batch_query,Wiki 节点优先来自 wiki +node-get。 |
is_owner |
当前用户是否为资源 owner。 |
permission_state |
当前身份下的读取权限状态。 |
source_move_state |
当前身份是否确认能对源资源执行所选 move_method;必须按权限矩阵判断。 |
source_parent_write_state |
Drive 内移动所需的源位置编辑状态;非 drive_move 为 not_required。 |
move_permission_state |
权限矩阵聚合结果;只有 movable 且目标写入状态为 confirmed 才可进入默认移动链路。 |
move_permission_basis |
移动资格判断依据,用于解释为什么纳入或排除。 |
target_write_state |
目标位置是否确认可写。 |
item_resolve_status |
资源项解析状态;不要和 TargetLocation.target_resolve_status 混用。 |
content_verify_state |
内容验证状态或跳过验证原因。 |
content_evidence |
支撑相关性判断的命中证据。 |
relevance |
相关性和可执行性分组。 |