WeKnora deployment source with the reviewed wiki identity, summary and recovery fixes
Anydoc / anydoc parser engine (push) Canceled after 0s
App / Format, vet, test, and build (push) Canceled after 0s
CLI / test (macos-latest / go 1.26) (push) Canceled after 0s
CLI / test (ubuntu-latest / go 1.26) (push) Canceled after 0s
CLI / test (windows-latest / go 1.26) (push) Canceled after 0s
Build and Push Docker Image / build-ui (push) Canceled after 0s
Build and Push Docker Image / build-docreader (push) Canceled after 0s
Build and Push Docker Image / build-sandbox (push) Canceled after 0s
Build and Push Docker Image / build-app (amd64, linux/amd64, ubuntu-latest) (push) Canceled after 0s
Build and Push Docker Image / build-app (arm64, linux/arm64, ubuntu-24.04-arm) (push) Canceled after 0s
DocReader / Python tests and Go client tests (push) Canceled after 0s
Build & Publish (dsh-weknora) / Typecheck, test, pack (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (pinned) (push) Canceled after 0s
Build & Publish (dsh-weknora) / End-to-end inside dsh (latest, advisory) (push) Canceled after 0s
Frontend / Test, type-check, and build (push) Canceled after 0s
Go Lint Cache / warm lint cache (.) (push) Canceled after 0s
Go Lint Cache / warm lint cache (cli) (push) Canceled after 0s
Go Lint Cache / warm lint cache (client) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.10) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.11) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.12) (push) Canceled after 0s
Build & Publish (mcp-server) / Test (Python 3.13) (push) Canceled after 0s
Build and Push Docker Image / merge (push) Canceled after 0s
Build & Publish (dsh-weknora) / Publish to npm (push) Canceled after 0s
Build & Publish (mcp-server) / Build sdist + wheel (push) Canceled after 0s
Build & Publish (mcp-server) / Publish to PyPI (push) Canceled after 0s

This commit is contained in:
yawan
2026-09-22 16:19:06 +08:00
commit f7fc992f57
3929 changed files with 1006607 additions and 0 deletions
+130
View File
@@ -0,0 +1,130 @@
---
title: IM集成开发
tags: [集成扩展, IM, 企微, 飞书, Lark, Slack, Telegram, 钉钉, Mattermost]
aliases: [IM集成, IM开发, 企业微信, 即时通讯]
source: IM集成开发文档.md
---
# IM 集成开发
WeKnora 的 IM 集成模块将企业即时通讯平台(企业微信、飞书、Lark、Slack、Telegram、钉钉、Mattermost)接入 WeKnora 知识问答管道,支持在 IM 中直接向 AI 提问并获得实时流式回答。
IM 渠道绑定到 Agent,一个 Agent 可接入多个 IM 渠道。
> IM 渠道中的 Agent 可以使用 [MCP 工具](../核心功能/MCP功能使用说明.md) 和 [Skills 技能](../核心功能/Agent技能系统.md)
## 支持的平台
| 平台 | WebSocket 模式 | Webhook 模式 | 流式输出 |
|------|:-:|:-:|:-:|
| 企业微信 | ✅ | ✅ | ✅ |
| 飞书 | ✅ | ✅ | ✅ (CardKit) |
| Lark(飞书国际版) | ✅ | ✅ | ✅ (CardKit) |
| Slack | ✅ (Socket Mode) | ✅ (Events API) | ✅ |
| Telegram | ✅ (长轮询) | ✅ | ✅ |
| 钉钉 | ✅ (Stream) | ✅ | ✅ (AI 卡片) |
| Mattermost | — | ✅ | ✅ |
## 快速接入指南
### 前置条件
- WeKnora 已部署并运行
- 已创建至少一个 Agent(自定义智能体)
- Agent 已配置好模型和知识库
> Agent 配置模型参见 [内置模型管理](../核心功能/内置模型管理.md)
### 企业微信接入
提供两种模式:
- **WebSocket 模式**(智能机器人,推荐)— 无需公网域名
- **Webhook 模式**(自建应用)— 需要公网回调地址
### 飞书接入
- **WebSocket 模式**(推荐)— 无需公网域名
- **Webhook 模式** — 需要公网回调地址
> 飞书同时也是数据源导入的支持平台,参见 [数据源导入开发](数据源导入开发.md)
### Lark 接入
Lark 是飞书的国际版,IM 接口一致,与飞书共用同一套适配器。接入步骤基本相同,但开放平台
与**权限清单**不同:
- 飞书:<https://open.feishu.cn/>
- Lark:<https://open.larksuite.com/>
> **权限不可套用飞书的清单**:飞书清单混入了数据源连接器(Wiki 同步)用的权限,其中部分在
> Lark 并不存在,整份导入会失败。Lark 只需 IM 相关的 6 项,见
> [IM集成开发文档 — Lark 权限配置](../../IM集成开发文档.md#lark-权限配置)。
> 两朵云的应用互不通用,凭证只在创建它的那朵云上有效。
### Slack 接入
- **Socket Mode**(推荐)— 无需公网域名
- **Events API** — 需要公网回调地址
### Telegram 接入
- **长轮询模式**(推荐)— 无需公网域名
- **Webhook 模式** — 需要 HTTPS 公网回调
### 钉钉接入
- **Stream 模式**(推荐)— 无需公网域名
- **Webhook 模式** — 需要公网回调地址
### Mattermost 接入
- 仅支持 **Webhook 模式**(出站 Webhook + REST API v4)
## 架构设计
系统采用 **Adapter Pattern**,每个平台实现 `im.Adapter` 接口,通过 `AdapterFactory` 动态创建。核心设计模式包括:
| 模式 | 用途 |
|------|------|
| Adapter Pattern | 统一不同 IM 平台的差异 |
| Factory Pattern | 从数据库渠道配置动态创建 Adapter |
| Command Pattern | 可插拔的斜杠指令系统 |
| Producer-Consumer | QA 队列 + Worker Pool |
## 斜杠指令系统
| 指令 | 说明 |
|------|------|
| `/help` | 显示所有可用指令 |
| `/info` | 查看当前绑定智能体信息 |
| `/search` | 对知识库执行混合检索 |
| `/stop` | 取消当前 QA 请求 |
| `/clear` | 清空当前对话记忆 |
## 扩展新平台
接入新的 IM 平台只需 3 步:
1. 实现 `im.Adapter` 接口(可选 `StreamSender`、`FileDownloader`)
2. 注册适配器工厂
3. 前端添加平台选项
> 扩展开发模式与 [添加网络搜索引擎](添加网络搜索引擎.md) 和 [集成向量数据库](集成向量数据库.md) 类似
## 相关主题
- [数据源导入开发](../集成扩展/数据源导入开发.md) — 飞书数据源同步(共享飞书应用凭证)
- [MCP功能使用说明](../核心功能/MCP功能使用说明.md) — Agent 可调用 MCP 工具
- [Agent技能系统](../核心功能/Agent技能系统.md) — Agent 可使用 Skills 技能
- [开发指南](../开发部署/开发指南.md) — 开发环境搭建
---
## 反向链接
- [Home](../Home.md) — Wiki 首页导航
- [数据源导入开发](../集成扩展/数据源导入开发.md) — 同样涉及飞书集成,可共享应用凭证
- [MCP功能使用说明](../核心功能/MCP功能使用说明.md) — IM 中 Agent 可调用 MCP 工具
- [Agent技能系统](../核心功能/Agent技能系统.md) — IM 中 Agent 可使用 Skills
- [版本路线图](../项目概述/版本路线图.md) — IM 集成已完成的里程碑
@@ -0,0 +1,103 @@
---
title: 数据源导入开发
tags: [集成扩展, 数据源, 飞书, 同步, 连接器]
aliases: [数据源导入, DataSource, 数据同步]
source: 数据源导入开发文档.md
---
# 数据源导入开发
WeKnora 的数据源导入模块支持从外部平台(飞书、企业微信、Notion、Confluence 等)自动导入和同步内容到知识库。用户可配置数据源连接,选择需要同步的资源,并通过手动触发或定时调度自动完成内容的增量/全量同步。
数据源绑定到知识库,一个知识库可接入多个数据源。凭证使用 AES-256-GCM 加密存储。
> 数据源导入与 [IM集成开发](../集成扩展/IM集成开发.md) 都涉及飞书集成,可考虑共享飞书应用凭证
## 当前支持的连接器
| 连接器 | 认证方式 | 增量同步 | 删除同步 |
|--------|---------|:-:|:-:|
| 飞书 (Feishu) | OAuth2 (Tenant Access Token) | ✅ | ✅ |
## 快速接入:飞书知识库
1. 创建飞书应用,获取 App ID / App Secret
2. 开通权限:`wiki:wiki:readonly`、`drive:drive:readonly`、`drive:export:readonly`、`docx:document:readonly`
3. 在知识库设置页添加数据源,选择飞书,填写凭证
4. 测试连接,选择知识库空间,配置同步策略
5. 触发首次同步验证
> 注意:飞书国际版(Lark)同样支持,自动适配 `https://open.larksuite.com` 的 API 地址
## 飞书 docx 解析模式与环境变量
飞书新版云文档(docx)的解析路径由环境变量 `FEISHU_DOCX_PARSE_MODE` 控制(作用于 app 服务,对飞书知识库和飞书云盘两个连接器同时生效):
| 模式 | 值 | 解析路径 | 图片与文档关联 | 速度 | docx 内附件 |
|---|---|---|---|---|---|
| export(默认) | 留空 / `export` | 异步导出 -> .docx 二进制 -> docreader 解析 | ✅ 图片 inline 进父文档,`parent_chunk_id` 关联 | 慢 | 丢失 |
| blocks | `blocks` | blocks API -> Markdown | ❌ 图片作为独立知识条目,与文档割裂 | 快 | 保留 |
**优缺点对比:**
- **export**:导出 .docx 交 docreader 解析,图片 inline 进父文档(与普通 docx 上传一致),通过 `parent_chunk_id` 建立同知识条目父子关联,三个场景都能关联图片内容;代价是同步变慢(异步导出 + docx 解析)、docx 内附件丢失、图片 OCR/caption 依赖多模态配置。
- **blocks**:图片 block 渲染成空 `![图片]()` 占位符,图片单独下载成独立知识条目,检索 / Wiki / 智能体无法把图片内容关联回文档;但同步快、保留 docx 内 file block 附件。
配置方法:默认即为 export,无需设置;需要 blocks 模式时在 `.env` 或 `docker-compose.yml` 的 app 服务环境变量中设置 `FEISHU_DOCX_PARSE_MODE=blocks`,重启 app 服务生效。详见 [飞书云盘数据源接入说明](飞书云盘数据源接入说明.md#6-docx-解析模式与环境变量)。
## 架构设计
```
外部平台 API → Connector → ConnectorRegistry → DataSourceService → WeKnora Core (知识入库管道)
```
核心设计模式:
| 模式 | 用途 |
|------|------|
| Adapter Pattern | 统一不同平台的差异 |
| Registry Pattern | 按类型动态查找连接器 |
| Strategy Pattern | SyncMode(增量/全量)、ConflictStrategy(覆盖/跳过) |
| Cursor-based Pagination | 增量同步基于 SyncCursor 跟踪变更 |
## 关键概念
- **DataSource** — 数据源:外部平台连接与知识库的绑定
- **Connector** — 连接器:与外部平台交互的适配层
- **SyncCursor** — 同步游标:增量同步的状态标记
- **FetchedItem** — 拉取到的文档条目
## API 端点
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/v1/datasource/types` | 获取可用连接器类型 |
| POST | `/api/v1/datasource/validate-credentials` | 验证凭证 |
| POST | `/api/v1/datasource` | 创建数据源 |
| GET | `/api/v1/datasource?kb_id=xxx` | 列出数据源 |
| POST | `/api/v1/datasource/:id/sync` | 手动触发同步 |
| POST | `/api/v1/datasource/:id/pause` | 暂停 |
| POST | `/api/v1/datasource/:id/resume` | 恢复 |
## 扩展新连接器
1. 实现 `Connector` 接口(Validate、ListResources、FetchAll、FetchIncremental)
2. 注册连接器到 `ConnectorRegistry`
3. 前端添加配置
> 扩展开发模式与 [添加网络搜索引擎](../集成扩展/添加网络搜索引擎.md) 和 [集成向量数据库](../集成扩展/集成向量数据库.md) 类似
## 相关主题
- [IM集成开发](../集成扩展/IM集成开发.md) — IM 渠道中的飞书集成
- [共享空间说明](../安全认证/共享空间说明.md) — 知识库共享机制
- [常见问题](../运维排障/常见问题.md) — 数据源同步相关故障排查
---
## 反向链接
- [Home](../Home.md) — Wiki 首页导航
- [IM集成开发](../集成扩展/IM集成开发.md) — 同样涉及飞书集成,可共享应用凭证
- [共享空间说明](../安全认证/共享空间说明.md) — 知识库共享与数据源导入互补
- [添加网络搜索引擎](../集成扩展/添加网络搜索引擎.md) — 同类扩展开发模式
@@ -0,0 +1,102 @@
---
title: 添加网络搜索引擎
tags: [集成扩展, 搜索, 网络搜索, Provider]
aliases: [网络搜索, WebSearch, 搜索引擎扩展]
source: 添加新的网络搜索引擎.md
---
# 添加新的网络搜索引擎
本文档说明如何在 WeKnora 中添加一个新的网络搜索引擎类型(如 Brave Search、Searx 等)。
## 架构概述
搜索引擎的 API 端点**硬编码**在代码中,不向用户暴露 BaseURL,从源头消除 SSRF 风险。
```
internal/types/web_search_provider.go # 实体定义 + Provider 类型元数据
internal/infrastructure/web_search/ # Provider 实现(bing/google/duckduckgo/tavily)
internal/container/container.go # DI 注册
internal/types/interfaces/web_search.go # WebSearchProvider 接口
```
> 类似的扩展开发模式参见 [集成向量数据库](../集成扩展/集成向量数据库.md)
## 步骤
以添加 **Brave Search** 为例:
### 1. 注册类型常量
在 `internal/types/web_search_provider.go` 中添加:
```go
WebSearchProviderTypeBrave WebSearchProviderType = "brave"
```
### 2. 添加类型元数据
在 `GetWebSearchProviderTypes()` 中添加:
```go
{
ID: "brave", Name: "Brave Search", Free: false,
RequiresAPIKey: true, Description: "Brave Search API",
DocsURL: "https://brave.com/search/api/",
}
```
### 3. 创建 Provider 实现
新建 `internal/infrastructure/web_search/brave.go`:
- 构造函数签名:`func(types.WebSearchProviderParameters) (interfaces.WebSearchProvider, error)`
- API 端点**硬编码**为常量
- 实现 `interfaces.WebSearchProvider` 接口:`Name()` 和 `Search()`
### 4. 添加参数校验
在 `isValidProviderType()` 中添加新类型。
### 5. DI 注册
在 `registerWebSearchProviders` 中注册。
### 6. 验证
```bash
go build ./...
# 调用 API 验证
curl http://localhost:8080/api/v1/web-search-providers/types
```
## 需要额外参数的情况
如果新引擎需要 API Key 以外的参数:
- **方式一**:使用 `WebSearchProviderParameters.ExtraConfig` 字段
- **方式二**:在 `WebSearchProviderParameters` 中添加专用字段
## 文件变更清单
| 文件 | 操作 |
|------|------|
| `internal/types/web_search_provider.go` | 添加常量 + 类型元数据 |
| `internal/infrastructure/web_search/brave.go` | **新建** Provider 实现 |
| `internal/application/service/web_search_provider.go` | `isValidProviderType` 加新类型 |
| `internal/container/container.go` | `registerWebSearchProviders` 注册 |
## 相关主题
- [集成向量数据库](../集成扩展/集成向量数据库.md) — 同类扩展开发模式(接口实现 + 注册 + DI)
- [MCP功能使用说明](../核心功能/MCP功能使用说明.md) — MCP 也可集成搜索工具
- [常见问题](../运维排障/常见问题.md) — SSRF 白名单配置
---
## 反向链接
- [Home](../Home.md) — Wiki 首页导航
- [集成向量数据库](../集成扩展/集成向量数据库.md) — 同类扩展开发模式
- [MCP功能使用说明](../核心功能/MCP功能使用说明.md) — MCP 搜索工具与网络搜索引擎互补
- [版本路线图](../项目概述/版本路线图.md) — 路线图中的社区组件扩展方向
@@ -0,0 +1,123 @@
---
title: 集成向量数据库
tags: [集成扩展, 向量数据库, 检索引擎, 扩展]
aliases: [向量数据库, VecDB, 向量检索, RetrieveEngine]
source: 使用其他向量数据库.md
---
# 集成新的向量数据库
本文提供了向 WeKnora 项目添加新向量数据库支持的完整指南。通过实现标准化接口和遵循结构化流程,开发者可以高效地集成自定义向量数据库。
> 类似的扩展开发模式参见 [添加网络搜索引擎](../集成扩展/添加网络搜索引擎.md)
## 集成流程
### 1. 实现基础检索引擎接口
```go
type RetrieveEngine interface {
EngineType() types.RetrieverEngineType
Retrieve(ctx context.Context, params types.RetrieveParams) ([]*types.RetrieveResult, error)
Support() []types.RetrieverType
}
```
### 2. 实现存储层接口
实现 `RetrieveEngineRepository` 接口,扩展基础检索引擎能力,添加索引管理功能:
- `Save` / `BatchSave` — 保存索引
- `EstimateStorageSize` — 估算存储空间
- `DeleteByChunkIDList` / `DeleteByKnowledgeIDList` — 删除索引
- `CopyIndices` — 复制索引
### 3. 实现服务层接口
创建 `RetrieveEngineService` 实现,负责索引创建和管理的业务逻辑。
### 4. 添加环境变量配置
```
RETRIEVE_DRIVER=postgres,elasticsearch_v8,your_database
YOUR_DATABASE_ADDR=host:port
YOUR_DATABASE_USERNAME=username
YOUR_DATABASE_PASSWORD=password
```
### 5. 注册检索引擎
在 `internal/container/container.go` 的 `initRetrieveEngineRegistry` 中添加初始化与注册逻辑。
### 6. 定义检索引擎类型常量
在 `internal/types/retriever.go` 中添加新的引擎类型常量。
## 参考实现
建议参考现有实现:
- PostgreSQL: `internal/application/repository/retriever/postgres/`
- ElasticsearchV7: `internal/application/repository/retriever/elasticsearch/v7/`
- ElasticsearchV8: `internal/application/repository/retriever/elasticsearch/v8/`
- Apache Doris 4.1: `internal/application/repository/retriever/doris/`
- Tencent VectorDB: `internal/application/repository/retriever/tencentvectordb/`
## Apache Doris 4.1 集成要点
Doris 是 MPP 风格的分析型 SQL 库,其接入方式与 NoSQL 向量库有几处特殊点:
- **协议**:MySQL 协议(FE 9030)走主链路;HTTP API(FE 8030)走 Stream Load partial update。
- **表结构**:每维度一张 `<DORIS_TABLE_PREFIX>_<dim>` 表,`UNIQUE KEY(id)` + `enable_unique_key_merge_on_write=true`。
- **索引**:INVERTED 索引覆盖过滤字段、`content` 字段使用 `chinese` parser;ANN 索引使用 HNSW + cosine_distance(异步构建,建表后自动轮询 30s 等待 `FINISHED`)。
- **分数语义**:使用 `1 - cosine_distance_approximate(...)`,threshold 比较 `>=`、`ORDER BY DESC`,与 Qdrant cosine 相似度方向一致。
- **关键词检索**:基于 Doris 倒排索引的 `MATCH_ANY`,无需在 Go 端做 jieba 分词。
- **批量字段更新**:`BatchUpdateChunkEnabledStatus` 与 `BatchUpdateChunkTagID` 通过 Stream Load partial update 协议实现,支持 1MiB 自动分批。
环境变量:
```
RETRIEVE_DRIVER=doris
DORIS_ADDR=doris-fe:9030
DORIS_HTTP_PORT=8030
DORIS_DATABASE=weknora
DORIS_USERNAME=root
DORIS_PASSWORD=
DORIS_TABLE_PREFIX=weknora_embeddings
```
启动方式:`docker compose --profile doris up -d`,然后在 FE 上 `CREATE DATABASE weknora;`。
## Tencent VectorDB
WeKnora 内置 Tencent VectorDB 适配器,驱动名为 `tencent_vectordb`。该适配器支持向量检索、基于 BM25 sparse vector 的关键词检索和索引管理,可参与 WeKnora 上层混合检索。
```env
RETRIEVE_DRIVER=tencent_vectordb
TENCENT_VECTORDB_ADDR=http://your-instance.tencentvectordb.com
TENCENT_VECTORDB_USERNAME=root
TENCENT_VECTORDB_API_KEY=your_tencent_vectordb_api_key
TENCENT_VECTORDB_DATABASE=weknora
TENCENT_VECTORDB_COLLECTION=weknora_embeddings
TENCENT_VECTORDB_REPLICA_NUMBER=1
```
`TENCENT_VECTORDB_COLLECTION` 是集合名前缀。WeKnora 会按向量维度创建实际集合,例如 `weknora_embeddings_768`。
`TENCENT_VECTORDB_REPLICA_NUMBER` 是创建集合时使用的副本数,默认 `1`;单节点 QA 环境可设为 `0`,生产环境可按 Tencent VectorDB 集群规模调整。
关键词检索依赖 Tencent VectorDB sparse vector 索引。新建集合会自动创建 `sparse_vector` 索引;旧版本已创建的向量集合如果没有该索引,需要重建集合并重新导入知识库数据后才能启用关键词检索。
## 相关主题
- [添加网络搜索引擎](../集成扩展/添加网络搜索引擎.md) — 同类扩展开发模式(接口实现 + 注册 + DI)
- [知识图谱](../核心功能/知识图谱.md) — 知识图谱功能依赖 Neo4j 而非向量数据库
- [常见问题](../运维排障/常见问题.md) — Embedding 模型配置与向量维度相关
---
## 反向链接
- [Home](../Home.md) — Wiki 首页导航
- [添加网络搜索引擎](../集成扩展/添加网络搜索引擎.md) — 同类扩展开发模式
- [知识图谱](../核心功能/知识图谱.md) — 另一种知识检索方式(基于图而非向量)
- [版本路线图](../项目概述/版本路线图.md) — 路线图中的检索能力扩展方向
@@ -0,0 +1,167 @@
# 飞书云盘数据源使用说明
飞书云盘数据源(`feishu_drive` / `lark_drive`)可以把飞书/Lark 云盘某个文件夹下的文档和文件自动同步到 WeKnora 知识库,支持增量同步、定时同步和子文件夹递归。
---
## 1. 前置条件:创建飞书应用
1. 登录[飞书开放平台](https://open.feishu.cn/app)(Lark 用户使用 [Lark 开放平台](https://open.larksuite.com/app)),创建**企业自建应用**。
2. 记录应用的 **App ID**(`cli_` 开头)和 **App Secret**,配置数据源时需要填写。
3. 按下节表格开通权限,并**发布应用版本**(权限修改后必须重新发布才生效)。
> 注意:飞书(open.feishu.cn)和 Lark(open.larksuite.com)是两个独立体系,应用不通用。同步飞书云盘用飞书应用,同步 Lark Drive 用 Lark 应用,凭据不能混用。
---
## 2. 所需权限(详细)
在应用后台「权限管理」中开通以下 **3 个权限**:
| 权限标识 | 名称 | 用途 | 缺少时的表现 |
|---|---|---|---|
| `drive:drive:readonly` | 查看云空间中的文件 | 列举文件夹内容(list API)、下载云盘普通文件 | 加载文件夹/同步时报 403,提示「需先将文件夹分享给应用所在的群」 |
| `drive:export:readonly` | 导出云文档 | 把 docx/doc/sheet/bitable 导出为 docx/xlsx 再解析 | 云文档类文件同步失败 |
| `docx:document:readonly` | 读取新版文档内容 | 通过 blocks API 解析 docx 文档正文与附件(导出失败时的主路径) | docx 文档解析失败或回退导出也失败 |
说明:
- 与「飞书知识库」连接器相比,云盘**不需要** `wiki:wiki:readonly`,其余权限相同。
- list API 本身还接受 `drive:drive`(读写)或 `space:document:retrieve` 作为替代,但推荐只开只读的 `drive:drive:readonly`,最小授权。
- 权限开通后必须**创建并发布新版本**,否则接口仍报无权限。
---
## 3. 关键一步:把文件夹分享给应用
飞书的权限模型要求:即使应用开通了上述 API 权限,也只能访问**被显式分享给它的文件**。
1. 创建一个飞书(Lark)群或复用某个飞书(Lark)群
2. 将需要导入的**飞书云盘管理者**拉进群
> PS: 不拉进群也会导致没有访问权限
3. 在飞书云盘中打开目标文件夹;
4. 点击「分享」/「··· → 添加协作者」,把文件夹分享给**应用所在的群**(把应用拉进一个群,再将文件夹分享给该群),权限给「可阅读」即可;
5. 子文件夹和其中的文件会随父文件夹一起获得授权,无需逐个分享;
6. 如果之后新增的文件同步报 403,检查该文件是否在这棵已分享的目录树下。
这是一次性操作,但不做的话,加载文件夹会直接报「应用无权访问该文件夹」。
---
## 4. 配置数据源(四步)
入口:知识库 → 设置 → 数据源 → 新建数据源,选择「飞书云盘」。
### 第 1 步:选择类型
选择「飞书云盘」(国际版选「Lark Drive」)。
### 第 2 步:配置凭证
填写 App ID 和 App Secret,点击下一步时系统会自动测试连接(验证 tenant_access_token 能否获取)。此步只验证应用身份,不验证文件夹权限。
### 第 3 步:选择范围
1. 在「云盘文件夹 Token」输入框填入目标文件夹的 `folder_token`,**或直接粘贴文件夹的完整链接**(飞书 `https://xxx.feishu.cn/drive/folder/<token>` 或 Lark `https://xxx.larksuite.com/drive/folder/<token>`,系统按路径自动提取 token,两种链接都支持);
2. 点击「加载」,列出该文件夹下的完整目录树;
3. 勾选要同步的文件/文件夹,支持逐级展开、全选/折叠分支。
注意:
- **不支持云空间根目录**(根目录不分页且不返回快捷方式),必须选择具体文件夹;
- 加载失败时按提示处理:403 → 回到第 3 节分享文件夹;token 无效 → 重新从文件夹 URL 复制。
### 第 4 步:同步策略
| 配置项 | 说明 | 默认值 |
|---|---|---|
| 同步计划 | cron 表达式,默认每 6 小时一次;留空则只手动触发 | `0 0 */6 * * *` |
| 同步模式 | 增量(按修改时间游标)/ 全量 | 增量 |
| 冲突策略 | 内容变更时覆盖 / 跳过 | 覆盖 |
| 同步删除 | 源端删除的文档**只计数,不自动删除知识库内容**,需在知识库手动删除 | 开启 |
保存后数据源开始按策略运行,也可在数据源卡片上手动「触发同步」。
---
## 5. 支持的文件类型
| 云盘类型 | 处理方式 |
|---|---|
| `docx` / `doc`(新旧文档) | blocks API 解析正文与附件,失败时回退导出为 docx 解析 |
| `sheet` / `bitable`(表格/多维表格) | 导出为 xlsx 解析 |
| `file`(普通上传文件,如 PDF/PPT/图片) | 直接下载后按文件类型解析 |
| `shortcut`(快捷方式) | 自动解析为目标文件同步(快捷方式不能指向文件夹) |
| `folder`(文件夹) | 递归遍历 |
| `mindnote` / `slides` / `board` | 不支持,跳过 |
补充行为:
- docx 中的**附件**会作为独立知识条目同步(与父文档关联,父文档更新时自动清理已移除的附件);
- 文档内嵌图片会尝试 OCR/多模态解析,未配置对象存储或 VLM 时自动跳过,不影响正文同步。
---
## 6. docx 解析模式与环境变量
飞书新版云文档(docx)有两种解析路径,由环境变量 `FEISHU_DOCX_PARSE_MODE` 控制。该变量作用于 WeKnora **app 服务**(不是数据源配置),对飞书云盘和飞书知识库两个连接器同时生效。
### 模式对比
| | export(默认) | blocks |
|---|---|---|
| 环境变量值 | 留空 / `export` | `blocks` |
| 解析路径 | 异步导出 API -> .docx 二进制 -> docreader 解析 | blocks API -> Markdown |
| 图片与文档关联 | ✅ 图片 inline 进父文档,`parent_chunk_id` 关联 | ❌ 图片作为独立知识条目,与文档割裂 |
| 检索 / Wiki / 智能体能否关联图片 | 是 | 否 |
| 同步速度 | 慢(异步导出 + docx 解析) | 快 |
| docx 内附件(file block) | 丢失(.docx 导出不含) | 保留,作为独立条目 |
| 所需权限 | `drive:drive:readonly` + `drive:export:readonly` | `drive:drive:readonly` + `drive:export:readonly` + `docx:document:readonly` |
### 为什么图片关联有差异
- **export 模式**:导出 .docx 后由 docreader 解析,图片 inline 进父文档(与普通 docx 上传一致),通过 `parent_chunk_id` 建立同知识条目的父子关联,三个场景都能在一次检索中把图片内容与文档一起返回。
- **blocks 模式**:走 blocks API,图片 block 渲染成空 `![图片]()` 占位符,图片单独下载成独立知识条目,与父文档只有元数据级弱关联。WeKnora 的检索、Wiki 构建、智能体问答链路都不会把图片内容关联回文档,图片和正文是割裂的。
### 配置方法
在 WeKnora 服务的 `.env` 或 `docker-compose.yml` 的 app 服务环境变量中设置:
```env
FEISHU_DOCX_PARSE_MODE=blocks
```
不设置或设为 `export` 即用默认模式。修改后需重启 app 服务生效。
### export 模式的代价
- **同步变慢**:每个 docx 都要走异步导出(创建任务 + 轮询 + 下载)+ docreader 解析,比 blocks API 慢。
- **附件丢失**:docx 内 file block 附件不随 .docx 导出下载,如需附件用 blocks 模式或单独同步。
- **图片内容依赖多模态**:图片 inline 后 OCR/caption 由多模态服务异步生成,未配置对象存储或 VLM 时图片只存储不生成内容(前端展示正常,但检索层面仍弱)。
### 选择建议
- 需要图片内容在检索 / Wiki / 智能体中与文档关联:用默认 **export**。
- 只需文档正文、要保留附件、追求同步速度:用 **blocks**。
---
## 7. 同步行为说明
- **增量同步**:以文件修改时间为游标,只拉取上次同步后变更的内容;中断后从断点续传。
- **部分失败不中断**:某个子文件夹无权限或某个文件下载失败时,该条目记为失败,其余内容继续同步,失败明细可在「同步日志」中查看。
- **更新语义**:内容变更的文件会先删除旧知识条目再重建,解析期间该文档短暂不可用,属正常现象。
- **安全约束**:为避免误删,源端删除的文件不会自动从知识库移除(见第 4 步「同步删除」)。
---
## 8. 常见问题
| 现象 | 原因与处理 |
|---|---|
| 「请输入具体文件夹的 folder_token,不支持云空间根目录」 | 输入为空或粘贴的是根目录链接,换具体文件夹链接 |
| 「应用无权访问该文件夹。请…分享给应用所在的群」 | 未完成第 3 节的分享,或分享的对象不是应用所在的群 |
| 「应用凭证无效或缺少云盘权限」 | App ID/Secret 错误,或第 2 节权限未开通/未发布版本 |
| 「folder_token 不存在或已删除」 | token 复制有误,从文件夹「分享 → 复制链接」重新获取 |
| 同步日志中部分条目失败 | 点开日志看失败阶段:`list_children` 多为子文件夹未授权,`fetch` 多为单文件权限或类型不支持 |
| 知识列表中来源显示 | 云盘同步的文档来源标记为「飞书云盘」,与知识库同步的「飞书」区分 |