Skill 清单
飞书云文档(docx)能力的四层架构总览。
架构总览
飞书云文档能力分为四层,核心原则:主动查询走 Skill + Tool,文档变更通知走纯 Python 流水线。
分层判断标准
| 层级 | 判断标准 | 开发产出 |
|---|---|---|
| A — Skill | 用户在对话中主动触发文档相关意图 | skills/feishu_doc/SKILL.md |
| B — Tool | AI 需要调用,tool schema 可自描述 | scripts/direct/tools/feishu_doc.py |
| C — 系统能力 | 不需要 AI 感知,在 Tool 内部或后台自动运行 | 工具内部逻辑 / 后台任务 |
| D — 流水线 | Webhook 事件驱动,不经过 agent loop | scripts/feishu_events.py + llm/client.py |
Skill / Tool 汇总
| 名称 | 描述 | 底层 API | 状态 |
|---|---|---|---|
feishu_doc Skill | 飞书云文档 AI 对话技能(SKILL.md) | — | 🔲 待开发 |
search_docs | 语义检索(制度类走 Qdrant)或实时搜索(项目类) | GET /drive/v1/files | 🔲 待开发 |
get_doc_content | 拉取文档内容(纯文本 / 块结构) | GET /docx/v1/documents/:id/raw_content 等 | 🔲 待开发 |
list_folder_docs | 列出目录下的文档 | GET /drive/v1/files | 🔲 待开发 |
get_doc_update_log | 查询文档修改历史 | GET /drive/v1/files/:token/versions | 🔲 待开发 |
create_doc | 创建新的飞书云文档 | POST /docx/v1/documents | 🔲 待开发 |
write_doc_content | 写入 / 更新 / 删除内容块 | POST / PATCH / DELETE blocks 系列 | 🔲 待开发 |
| 云文档 Webhook 流水线 | 文档修改事件 → 增量索引 + 通知订阅者 | drive.file.edit_v1 | 🔲 待开发 |
A 层 — Skill:feishu_doc
SKILL.md 结构
yaml
name: feishu_doc
trigger: 文档|制度|规范|流程|手册|查一下|找一下|文件|更新了吗|在哪里|怎么规定|创建文档|写入
description: >
查询、创建、编辑飞书云文档。支持制度类语义检索和项目文档实时搜索,
可创建新文档并写入结构化内容,文档有更新时主动通知订阅者。
tools:
- search_docs
- get_doc_content
- list_folder_docs
- get_doc_update_log
- create_doc
- write_doc_content
scope: company覆盖的会话场景
| 场景 | 触发词示例 | 涉及工具 |
|---|---|---|
| 制度查询 | "考勤几点打卡" / "报销流程" | search_docs(type=policy) → 语义检索 |
| 项目文档查找 | "找一下 XX 项目的需求文档" | search_docs(type=project) → 实时搜索 |
| 指定文档阅读 | "把这个文档内容发我" | get_doc_content |
| 目录浏览 | "HR 目录下有哪些文件" | list_folder_docs |
| 版本历史查询 | "这个制度上次什么时候改的" | get_doc_update_log |
| 创建文档 | "帮我在 XX 目录建一个文档" | create_doc |
| 写入内容 | "把会议纪要写到这个文档里" | write_doc_content |
| 变更订阅 | "帮我订阅这个文档的更新" | 调用订阅关系写入接口 |
B 层 — Tool 清单
公共行为
所有 Tool 共享以下约定:
- 飞书
tenant_access_token鉴权(C 层自动刷新) - 权限过滤:返回前过滤无权访问的内容
doc_token支持直接传 token 或完整飞书链接(工具层解析)- 错误时返回可读错误说明,不抛异常
1. search_docs — 文档检索
查询飞书云文档,根据文档类型自动选择检索策略。
| 项目 | 说明 |
|---|---|
| 底层 API | GET /drive/v1/files |
| 权限 scope | drive:drive:readonly |
| 限流 | — |
| 参数 | 必填 | 说明 |
|---|---|---|
query | 是 | 用户的自然语言查询 |
scope | 否 | company / department / all(老板/HR) |
doc_type | 否 | policy(制度类,走 Qdrant)/ project(项目类,走实时)/ auto(自动判断) |
C 层联动: doc_type=policy → Qdrant 语义检索;doc_type=project → 飞书 Drive API 实时搜索;doc_type=auto → C 层文档分类判断后路由。
返回内容: 匹配的文档列表(标题、路径、相关段落摘要、链接)
2. get_doc_content — 读取文档内容
读取指定飞书云文档的内容,支持纯文本和块结构两种模式。
| 项目 | 说明 |
|---|---|
| 底层 API — 基本信息 | GET /docx/v1/documents/:document_id |
| 底层 API — 纯文本 | GET /docx/v1/documents/:document_id/raw_content |
| 底层 API — 全量块 | GET /docx/v1/documents/:document_id/blocks |
| 底层 API — 指定块 | GET /docx/v1/documents/:document_id/blocks/:block_id |
| 底层 API — 子块 | GET /docx/v1/documents/:document_id/blocks/:block_id/children |
| 权限 scope | docx:document | docx:document:readonly |
| 限流 | 5 次/秒 |
| 参数 | 必填 | 说明 |
|---|---|---|
doc_token | 是 | 文档 token 或完整飞书链接 |
mode | 否 | text(纯文本)/ blocks(块结构),默认 text |
lang | 否 | 语言:0=默认、1=中文、2=英文 |
max_chars | 否 | 最大返回字符数(默认 8000),超出时截断并提示 |
返回内容: 文档 Markdown 全文 / 块结构 + 最后更新时间 + 文档链接
3. list_folder_docs — 列出目录文档
列出飞书云文档指定目录下的文件列表。
| 项目 | 说明 |
|---|---|
| 底层 API | GET /drive/v1/files |
| 权限 scope | drive:drive:readonly |
| 限流 | — |
| 参数 | 必填 | 说明 |
|---|---|---|
folder_token | 否 | 目录 token,不填则返回根目录 |
keyword | 否 | 按文件名关键词过滤 |
limit | 否 | 最大返回条数(默认 20) |
返回内容: 文件列表(名称、类型、最后修改时间、链接)
4. get_doc_update_log — 查询修改历史
查询指定文档的修改历史记录。
| 项目 | 说明 |
|---|---|
| 底层 API | GET /drive/v1/files/{file_token}/versions |
| 权限 scope | drive:drive:version:readonly |
| 限流 | — |
| 参数 | 必填 | 说明 |
|---|---|---|
doc_token | 是 | 文档 token 或完整链接 |
limit | 否 | 最近 N 条版本记录(默认 5) |
返回内容: 版本历史(修改时间、修改人、版本号)
5. create_doc — 创建文档
创建一篇新的飞书云文档。
| 项目 | 说明 |
|---|---|
| 底层 API | POST /docx/v1/documents |
| 权限 scope | docx:document | docx:document:create |
| 限流 | 3 次/秒 |
| 参数 | 必填 | 说明 |
|---|---|---|
title | 否 | 文档标题(1-800 字符) |
folder_token | 否 | 目标文件夹 token,不填则创建在根目录 |
返回内容: document_id、revision_id、title、文档链接
6. write_doc_content — 写入内容块
向文档写入结构化内容块(文本、标题、列表、代码块、图片等),支持创建、更新、批量更新和删除。
| 项目 | 说明 |
|---|---|
| 底层 API — 创建子块 | POST /docx/v1/documents/:document_id/blocks/:block_id/children |
| 底层 API — 更新块 | PATCH /docx/v1/documents/:document_id/blocks/:block_id |
| 底层 API — 批量更新 | PATCH /docx/v1/documents/:document_id/blocks/batch_update |
| 底层 API — 删除块 | DELETE /docx/v1/documents/:document_id/blocks/:block_id/children/batch_delete |
| 权限 scope | docx:document | docx:document:write_only |
| 限流 | 3 次/秒(含单文档并发编辑,超限 HTTP 429) |
创建子块参数:
| 参数 | 必填 | 说明 |
|---|---|---|
document_id | 是 | 文档 ID |
block_id | 是 | 父块 ID(根块 = 文档 ID) |
children | 是 | 块列表(1-50 个块) |
index | 否 | 插入位置(-1=末尾) |
client_token | 否 | 幂等键,防止重复写入 |
更新块参数:
| 参数 | 必填 | 说明 |
|---|---|---|
document_id | 是 | 文档 ID |
block_id | 是 | 目标块 ID |
| body | 是 | update_text_elements / update_text_style / update_table_property / replace_image |
批量更新: 单次最多 200 个请求。
删除块参数:
| 参数 | 必填 | 说明 |
|---|---|---|
document_id | 是 | 文档 ID |
block_id | 是 | 父块 ID |
start_index | 是 | 起始索引(左闭) |
end_index | 是 | 结束索引(右开) |
block_type 速查:
| 值 | 类型 | 值 | 类型 |
|---|---|---|---|
| 2 | 文本 | 13 | 无序列表 |
| 3 | H1 标题 | 14 | 代码块 |
| 4 | H2 标题 | 27 | 图片 |
| 5 | H3 标题 | ||
| 12 | 有序列表 |
返回内容: 创建/更新后的块列表
C 层 — 系统能力
| 能力 | 说明 | 实现位置 | 状态 |
|---|---|---|---|
| 文档分类判断 | 按目录名规则区分制度类 / 项目类;目录名含「制度」「规范」「流程」「手册」或 Wiki 节点 → 制度类 | Tool 内部 | 🔲 待开发 |
| 向量索引维护 | 制度类文档定期全量同步(每日) + 文档更新时增量写入 Qdrant | 后台任务 | 🔲 待开发 |
| 订阅关系管理 | MongoDB 存储「谁订阅了哪个文档/目录」,支持添加/取消订阅 | Tool 内部 + API | 🔲 待开发 |
| 权限过滤 | 角色 × 文档可见范围,Tool 返回前过滤无权内容;无权限时返回引导提示 | Tool 返回前 | 🔲 待开发 |
| Token 自动刷新 | 复用飞书现有 HTTP 客户端,tenant_access_token 到期前自动续期 | 飞书客户端层 | ✅ 复用现有 |
D 层 — 流水线(文档变更通知)
非 agent loop,事件驱动,LLM 只做变化摘要提炼。
流水线步骤
| 步骤 | 模块 | 说明 |
|---|---|---|
| 1. 接收 Webhook | scripts/feishu_events.py | 监听 drive.file.edit_v1 事件 |
| 2. 查订阅者 | 查询 MongoDB 订阅关系 | 找到订阅此文档/目录的所有用户 |
| 3. 提炼变化摘要 | llm/client.py(同步调用) | 对比新旧内容,输出 1-2 句变化说明 |
| 4. 更新向量索引 | Qdrant 增量写入(制度类专属) | 保持制度检索结果最新 |
| 5. 推送通知 | 飞书消息 API | 按订阅者列表推送(含摘要 + 链接) |
通知内容格式
「{文档名称}」刚刚有更新
修改人:{姓名} · 更新时间:{时间}
主要变化:{AI 提炼的 1-2 句摘要}
→ 查看文档:{链接}失败处理
| 失败场景 | 处理方式 |
|---|---|
| 文档读取失败(无权限) | 跳过摘要提炼,仅发送「{文档名}有更新」+ 链接 |
| LLM 提炼失败 | 降级:仅推送文档标题 + 链接,不含摘要 |
| 无订阅者 | 跳过通知,更新向量索引(如为制度类)后结束 |
飞书 API 权限速查
| Scope | 能力范围 | 适用 Tool |
|---|---|---|
docx:document | 文档创建 + 读取 + 编辑(全能) | 所有 docx Tool |
docx:document:readonly | 仅读取文档内容和块结构 | get_doc_content |
docx:document:create | 仅创建文档 | create_doc |
docx:document:write_only | 仅编辑(写入/更新/删除块) | write_doc_content |
drive:drive:readonly | 云空间文件列表、搜索 | search_docs · list_folder_docs |
drive:drive:version:readonly | 文件版本历史 | get_doc_update_log |
最小权限原则
生产环境建议按 Tool 粒度申请最小 scope,避免使用全能的 docx:document。仅在开发/调试阶段使用全能权限。
关键限制
| 限制项 | 值 | 说明 |
|---|---|---|
| 文档标题长度 | 1 — 800 字符 | create_doc 的 title 参数 |
| 单次创建子块数 | 1 — 50 个 | write_doc_content 创建子块时 children 参数上限 |
| 单次批量更新 | 最多 200 个请求 | batch_update 接口 |
| 分页大小上限 | 500 | blocks / children 列表接口的 page_size |
| 写入限流 | 3 次/秒 | POST / PATCH / DELETE 类接口,含单文档并发编辑 |
| 读取限流 | 5 次/秒 | GET 类接口 |
| 超限响应 | HTTP 429 | 需客户端指数退避重试 |
| 幂等键 | client_token | 创建子块接口支持,防止网络重试导致重复写入 |
| 版本号参数 | document_revision_id = -1 | 表示最新版本,读取块时推荐使用 |
| 子块递归 | with_descendants = true | 获取子块接口可一次性拉取全部后代块 |
| 删除范围 | 左闭右开 | start_index 包含,end_index 不包含 |
复用的现有能力
| 能力 | 本场景用途 | 状态 |
|---|---|---|
| Qdrant 向量库 | 制度类文档语义检索 | ✅ 已实现(memory/searcher.py) |
| Embedder | 文档向量化 | ✅ 已实现(memory/embedder.py) |
| 飞书 HTTP 客户端 | tenant_access_token 鉴权、API 调用 | ✅ 已实现(feishu_bot.py) |
| llm/client.py | D 层变化摘要提炼 | ✅ 已实现 |
| NotificationEngine | 推送防骚扰控制(冷却/时段/上限) | ✅ 已实现 |
| PersonIndex | 修改人 open_id → 中文姓名映射 | ✅ 已实现 |