切换主题
文件上传、解析与摄入任务
本页阅读位置
完成第一轮对话后,按当前业务需求深入。Spring 常规声明优先使用 RegistrationManifest 与注解;本页的底层 register / publish 或直连方法供协议细化与兼容集成参考。
使用前准备
- 部署平台,使用应用管理身份创建 mode=MANAGED 的知识草稿版本,并配置分块策略。
- 规划文档标识、租户和访问规则。同一文档在同一草稿中同时只接受一个活跃摄入任务。
- 上传原件,观察任务;完成后检查解析正文和文档摘要,再发布知识库、授权 Agent。
发布后的知识版本和原件索引关联保持冻结。更新文件需要新的知识草稿版本;不能在已发布版本直接替换。
控制台操作
在“知识库”中选择托管版本,打开“管理托管文档”。“文件摄入”区域支持单件原件上传、任务分页与状态刷新。先填写稳定文档标识,再选择重复策略。平台管理员可明确指定文档租户;应用管理员默认使用可信凭据的租户,不能替其他租户上传。
任务完成后点击“刷新任务与索引”。“原件”和“解析正文”通过当前凭据重新检查权限;必要时可在读取窗口输入真实业务用户凭据,读取后清空该输入。失败时不会显示此前的正文。管理凭据能查看任务元数据,不等于有权读取业务文件。
失败任务显示安全错误代码;先检查格式、配置、容量和当前索引,再显式“重试”。“取消”保留之前已生效的文档索引。终态任务可删除,但仍被任一未撤销知识版本引用的原件不能删除。删除会释放该原件占用,不能恢复该任务的解析历史。
支持格式与资源边界
| 格式 | 处理 | 注意事项 |
|---|---|---|
| TXT / MD | 严格 UTF-8;去除开头 BOM | 非 UTF-8、空正文和 NUL 字符拒绝;Markdown 仍按草稿分块策略验证 |
| PDFBox 逐页提取;无文本页走 OCR | 加密/禁止提取、超过 100 页、尺寸异常和超时拒绝 | |
| DOCX | POI 提取段落与表格正文 | 不执行宏、嵌入对象、脚本或外部引用 |
| XLSX | POI 读取工作表与存储的单元格显示值 | 不计算公式、不访问外部数据源;以解析后的字符定位,不能承诺原表格版面 |
| PPTX | POI 提取幻灯片正文 | 页码为幻灯片序号;不执行动画、宏和嵌入对象 |
| PNG / JPG / JPEG | Tesseract OCR | 每张最多 1600 万像素;OCR 质量依赖扫描质量与语言包 |
每原件 1 字节至 4 MiB,multipart 请求最大 5 MiB、元数据最大 8 KiB。解析结果最多 65536 个 UTF-16 字符、100 页,Office 解压总量最多 16 MiB、2000 个条目。单解析 Java 子进程堆 192 MiB、元空间 96 MiB,最长 20 秒;OCR 单次最长 15 秒且限制线程。进程资源限制与总体部署容量都需要考虑:最多 2 个同时解析,OCR 内存受容器/操作系统限制,不能只按平台主 Java 堆计算容量。
跨页分块只返回准确的 UTF-16 定位;只有整个片段位于单页时才返回 page。DOCX/XLSX 的解析页不是原文件印刷页。不能把解析结果理解成像素级版面复原或 OCR 正确率承诺。
Docker 与本地部署
项目 Dockerfile 安装 Tesseract 和 eng / chi_sim 语言包,默认启用中英文 OCR;宿主直接运行 Jar 时必须自行准备真实引擎。
| 环境变量 | 默认 | 作用 |
|---|---|---|
| SPARKTIDE_INGESTION_CAPACITY_BYTES | 67108864 | 实例原件字节额度;4 MiB–1 GiB;Base64 与数据库开销另计 |
| SPARKTIDE_DOCUMENT_PARSER | builtin | 运维选择的 ServiceLoader 解析器标识;不能从上传请求选择插件 |
| SPARKTIDE_OCR_EXECUTABLE | 宿主空;镜像 /usr/bin/tesseract | 绝对可执行文件路径;未配置时扫描页和图片以 OCR_NOT_CONFIGURED 失败 |
| SPARKTIDE_OCR_LANGUAGES | 宿主 eng;镜像 eng+chi_sim | 已安装的语言包名称组合 |
| SPARKTIDE_INGESTION_AUTO | true | 自动任务协调;生产必须启用,false 仅用于隔离验证 |
原件 Base64 与解析版本保存在数据库,不使用用户文件名拼接服务器目录。解析临时目录由服务器创建,处理结束删除;容器以非 root 运行。新增 V13 表随全库备份一起备份,禁止仅备份 st_document。原件可能含业务数据,数据库及备份需要组织已有的访问控制和加密磁盘。
依赖版本与兼容依据在平台决策记录中。插件实现 DocumentParser,通过 META-INF/services/dev.sparktide.parser.DocumentParser 注册,加入部署包后由运维配置标识;插件仍受子进程堆、超时、输出上限和环境隔离约束。必须自行验证插件的格式支持与许可,不允许从上传文件加载代码。
HTTP 上传与查询
bash
curl -X POST "$PLATFORM/v1/apps/$APP/knowledge/project-documents/versions/1.0.0/ingestions" \
-H "Authorization: Bearer $APP_MANAGER" \
-F 'file=@manual.pdf;type=application/octet-stream' \
-F 'metadata={"documentId":"manual","title":"用户手册","duplicatePolicy":"UPSERT"};type=application/json'202 只表示已持久接收,不是解析成功。保存返回 id,再查询任务,不要因网络断开自动重发上传。元数据只允许 documentId、title、source、tenantId、duplicatePolicy、expectedDocumentVersion;未填 title 时使用文件名,source 默认空,tenantId 默认可信凭据租户,duplicatePolicy 默认 UPSERT。文档标识允许 1–128 个字母、数字、点、下划线或横线,禁止单独 . / ..。条件原文版本为 64 位小写 SHA-256。
设 P=/v1/apps/{app}/knowledge/{knowledgeId}/versions/{version}/ingestions:
| 方法与地址 | 用途 | 条件 |
|---|---|---|
| POST P | 上传单件 file 与 JSON metadata part | 管理身份、MANAGED 草稿;202 |
| GET P?limit=20&offset=0 | 任务分页 | 管理身份;limit 1–100,offset 0–1000000 |
| GET P/ | 当前任务元数据 | 管理身份;不含原件/正文/内部身份快照 |
| POST P/{jobId}/cancel | 取消活跃任务 | 管理身份;If-Match=当前 revision |
| POST P/{jobId}/retry | 显式重试失败任务 | 管理身份、草稿;If-Match;重新检查权限和配置 |
| DELETE P/ | 删除终态任务与未被引用的原件 | 管理身份;If-Match;未撤销索引引用时 409 ORIGINAL_IN_USE |
| GET P/{jobId}/original | 鉴权下载原件 | 当前文档 ACL、租户、业务 READ_HISTORY;octet-stream、attachment、no-store |
| GET P/{jobId}/parsed | 鉴权读取解析正文 | 同原件权限,已有成功解析版本;UTF-8 text/plain、no-store |
草稿原件与正文只允许管理身份读取,仍必须满足当前文档 ACL 与租户;发布后业务身份可按授权读取。filename/title/source 等元数据不是授权依据。source 不会被自动请求。所有 API 使用 Bearer 鉴权,无匿名文件链接或 Cookie 下载旁路。任务查询可以在草稿中使用;撤销知识版本、停用应用、撤销凭据或文档 ACL 后,原件与正文读取被拒绝。
状态与版本
QUEUED → PARSING → INDEXING → SUCCEEDED。失败进入 FAILED,取消进入 CANCELLED;任务修订号随状态变更递增。原件与原始散列不会因 retry 改变;attempt 增加并按当前草稿配置重新解析。取消与过时执行器都不能写入索引。执行器失联后标记 INGESTION_WORKER_LOST,显式重试而不透明重放。
成功结果分为 INDEXED(索引已更新)、UNCHANGED(相同正文与策略)和 SKIPPED(保留原索引)。parsedDocumentVersion 是本次解析候选的规范文档散列,parsedContentHash 是解析正文散列,originalHash 是原件字节散列;result.documentVersion 是当前索引文档版本。SKIPPED 时这两种文档版本可能不同,本次原件不能被当成当前回答来源。只有真正 INDEXED 的原件会成为当前文档 ingestion 引用。
原件、解析版本、索引与任务终态事务一致。损坏文件、分块错误、权限改变、草稿定义改变或并发文档修改均保留之前有效索引。任务活跃时禁止发布;解析完成不自动发布,不切换 Agent,也不进行向量/Embedding 处理。
SDK 示例
java
var upload = DocumentUpload.fromFile("manual", Path.of("manual.pdf"))
.title("用户手册")
.duplicatePolicy(DocumentDuplicatePolicy.UPSERT)
.build();
var job = managerClient.uploadDocument("project-documents", "1.0.0", upload)
.toCompletableFuture().get();
var current = managerClient.ingestion("project-documents", "1.0.0", (String) job.get("id"))
.toCompletableFuture().get();
// 确认 SUCCEEDED 后,由有权读取该租户文档的业务身份读取。
byte[] original = readerClient.ingestionContent("project-documents", "1.0.0", (String) job.get("id"), true)
.toCompletableFuture().get();kotlin
val upload = documentUpload("manual", Path.of("manual.pdf")) {
title = "用户手册"
duplicatePolicy = DocumentDuplicatePolicy.UPSERT
}
val job = managerClient.uploadDocumentAwait("project-documents", "1.0.0", upload)
val current = managerClient.ingestionAwait("project-documents", "1.0.0", job["id"] as String)
val text = readerClient.ingestionContentAwait("project-documents", "1.0.0", job["id"] as String, original = false)
.toString(Charsets.UTF_8)Java 示例说明:
DocumentUpload 保存本地原件的有界不可变快照;数组和元数据不能从外部修改。客户端不自动轮询或重试上传。使用 ingestions 分页、cancelIngestion / retryIngestion / deleteIngestion 时传入当前 revision;412 时回读状态并重新确认。ingestionContent 的 original=false 返回 UTF-8 解析正文的 byte[]。
Kotlin 示例说明:
挂起接口桥接 SDK 请求,不把管理身份变成用户身份。业务读取需使用 forUser 配置实际凭据;客户端提交的租户不会替代认证身份。
失败处理
| 错误 | 处理 |
|---|---|
| FILE_TOO_LARGE / PARSED_CONTENT_LIMIT | 拆分文件,不盲目提高全部 JSON API 限制 |
| DOCUMENT_PARSE_FAILED / ENCRYPTED_DOCUMENT | 确认真实格式、解密后另行上传;平台不接受解密密码 |
| OCR_NOT_CONFIGURED / OCR_FAILED / OCR_TIMED_OUT | 部署真实引擎与语言包,检查扫描图;人工确认后重试 |
| OFFICE_EXPANSION_LIMIT / UNSAFE_OFFICE_ARCHIVE | 使用可信来源重新导出普通 OOXML 文件 |
| KNOWLEDGE_DRAFT_CHANGED / DOCUMENT_VERSION_MISMATCH | 回读当前定义或索引,确认是否仍需重试 |
| INGESTION_IN_PROGRESS | 等待现有任务或取消后再上传 |
| INGESTION_STORAGE_LIMIT / INGESTION_JOB_LIMIT | 清理不再需要且未被索引引用的终态任务,或调整部署容量 |
| REVISION_MISMATCH | 回读任务最新 revision;不要自动覆盖并发操作 |
| DOCUMENT_NOT_AVAILABLE / BUSINESS_PERMISSION_DENIED | 核实当前身份与业务授权,不使用管理员绕过正文限制 |
同步文本导入、分块预览和跨版本重建继续按原合同使用。向量检索、附件聊天和质量评估属于独立能力,不能由文件摄入成功推定已实现。
文档来源与验证记录
| 字段 | 内容 |
|---|---|
| 状态 | 已确认 |
| 日期 | 2026-10-01 |
| 来源 | FileIngestion / ParserProcess / IngestionApi / DocumentUpload |
| 责任人 | SparkTide 维护者 |
| 关联任务 | 完整产品落地 K01 |
| 结论 | 上传得到持久任务;只有 SUCCEEDED 且 result.status=INDEXED 才替换当前文档索引 |
| 证据 | 平台 169 项、后台 SDK 实际联调 93 项全部通过;PostgreSQL 容器扫描 PDF/PNG OCR、重启保留及控制台撤权验证通过 |
