Skip to content

Latest commit

 

History

5 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

deckflow-extract

deckflow-lite 的 C1「拆包器」:把异构输入拆成统一的 Parse Bundle——parse-manifest.json(统一 JSON 信封)+ document.md(五类元素的 markdown 形态)+ assets/(哈希命名的二进制资产)。只拆包,不改写、不裁剪、不解读。

本文档即完整的使用说明。合约与分层设计的内部文档不随仓库发布。

安装

pipx install deckflow-extract

约 4MB,全部是纯 Python wheel,装完即可解析全部受支持格式。 没有二进制依赖,因此跨平台体积恒定、可离线安装、Python 新版本发布当天就能用。

重引擎按需获取,不必在安装时决定:

deckflow-extract install --list      # 可安装能力、体积、当前状态
deckflow-extract install pdf         # 56MB:PDF 表格识别与完整图片提取
deckflow-extract install pptx        # 37MB:PPTX shape/bbox 级定位
deckflow-extract install web         # 21MB:网页正文抽取质量
deckflow-extract install ocr         # 107MB:本地 OCR(必须显式指定)
deckflow-extract install cloud       # 3MB:云端解析所需的 deckops SDK
deckflow-extract uninstall pdf       # 卸载即删目录

引擎装进独立的 sidecar 目录(默认 ~/.deckflow/parse/engines/<能力>/<python 标签>),不污染主环境。传统装法完全保留,Docker / CI / 内网离线可以一次装齐:

pipx install "deckflow-extract[local]"   # = [pdf,pptx,web]

本工具永不隐式安装任何东西:默认只给建议,只有显式 deckflow-extract install--upgrade auto 才会真的下载。

仓库内直接运行(开发模式):

PYTHONPATH=src python3 -m deckflow_extract probe

分层

层 = 用户为这个引擎付出的代价,与产出质量无关(质量单独记在 manifest 的 fidelity 里):

代价 例子
L0 内置 0 pypdf、mammoth、openpyxl、xlrd、stdlib OOXML/ODF/EPUB/iWork 读取器
L1 宿主 0,但不保证存在 Keynote.app(osascript 导出)、LibreOffice、textutil、sips、tesseract
L2 按需 磁盘 + 一次下载 pymupdf4llm、python-pptx、readability-lxml
L3 云端 SDK(3MB)+ API key + 上传 + 配额 deckops SDK 驱动的任务 API

L0 是地板:任何机器、任何受支持格式都能产出一个合规的 Parse Bundle,或一条结构化的补救建议。没有 L1/L2/L3 也能跑完整条 deckflow-lite 流程。

路由不是「层越低越优先」:可用的引擎意味着代价已付清,所以在可用引擎里选保真度最高的;云端因为按次计费,默认永远排最后。

支持格式

deckflow-extract formats               # 完整能力表(每格式的引擎阶梯与当前状态)
deckflow-extract formats --extensions  # 扁平扩展名列表,供 glob 使用
deckflow-extract formats --available   # 只列当前机器上可用的

文档 pdf docx doc rtf odt epub pages md txt、演示 pptx ppt key odp、表格 xlsx xls csv ods numbers、网页 url html、图片 image svg heic、结构化文本 json yaml

音视频与压缩包明确不支持,但会被识别并返回 unsupported-format,不会退化成 unknown-input-type

使用

# 环境探测:格式能力表 + 宿主工具 + 已安装引擎 + 云端配置
deckflow-extract probe

# 解析一个输入 → Parse Bundle 目录(stdout 恰好一行 JSON)
deckflow-extract parse ./report.pdf --out ./report.parse
deckflow-extract parse ./book.xlsx --out ./book.parse
deckflow-extract parse ./deck.key --out ./keynote.parse
deckflow-extract parse https://example.com/post --out ./post.parse
deckflow-extract parse ./notes.md --out ./notes.parse --archive zip

# 云端模式(上传并计入配额)
deckflow-extract install cloud                 # 一次性:装 3MB 的 deckops SDK
deckflow-extract auth login                    # 浏览器登录;凭据与 deckhtml 共用
deckflow-extract parse ./deck.pptx --out ./deck.parse --mode cloud

云端覆盖 pdf / pptx / docx / key / url 五类输入——这是服务端解析器实际支持的集合;其余格式没有云端路径,--mode cloud 会返回 no-cloud-path 并提示改走本地。

鉴权:与 DeckHTML 共用一份凭据

两个工具连的是同一个 Deckflow API,用的是同一套凭据,所以读写同一个文件~/.deckflow/credentials

装了 deckhtml 并登录过,这里不需要再配置一次;反过来也一样,在这里登录,deckhtml 立刻可用。

deckflow-extract auth login                     # 浏览器登录,存下 token
deckflow-extract auth status                    # 当前用的是哪个凭据、来自哪里
deckflow-extract auth logout                    # 清掉存下的 token / api key

printf '%s\n' "$DECKFLOW_API_KEY" | \
  deckflow-extract config set api-key --stdin   # 推荐:secret 不进入进程参数
deckflow-extract config set api-key <key>       # 兼容写法
deckflow-extract config set space-id <id>       # 可选;不设则首次调用时向服务端查询
deckflow-extract config show                    # 已脱敏

命令名与键名刻意和 deckhtml auth login / deckhtml config set api-key 一致——同一个文件,不该有两套词汇。

两种凭据形态都认

形态 来自 请求头 会过期
token 浏览器登录(auth login X-Auth-Token
apiKey 空间的 worker secret(config set api-key Authorization: Bearer 不会

任意一种存在即视为已配置。只认 apiKey 是 0.2.x 的 bug:浏览器登录过的用户明明有可用凭据,却被告知未配置。

token 过期时

终端里(stdin 与 stderr 都是 TTY)用 token 跑云端解析,遇到 401 会像 deckhtml 一样重新打开登录页,拿到新 token 后自动重试。

在非交互环境(agent 子进程、CI)不会——直接返回 unauthorized,hint 里写明跑 deckflow-extract auth login。中途弹浏览器再阻塞五分钟等一个没人会完成的回调,比一个干净的错误糟得多。这和 --upgrade ask 在无 TTY 时退化成 never 是同一条规则。

配了 apiKey 时也不会自动重登:worker secret 不能靠登录续期,而在用户显式配置的 key 旁边悄悄存一个 token,会让下一次解析换一个身份跑——那不是刷新,是替换。

解析顺序

  1. 环境变量:DECKFLOW_API_KEY / DECKFLOW_TOKEN / DECKFLOW_SPACE_ID / DECKFLOW_API_BASEDECKOPS_* 同义)
  2. 共用文件 ~/.deckflow/credentials
  3. 都没有 → 未配置,云端引擎不进路由

环境变量永远压过文件。 想要一次「保证不出网」的运行,光把变量摘掉已经不够了——还要设 DECKFLOW_NO_STORED_CREDENTIALS=1,否则存下的凭据会把刚摘掉的东西又补回来。deckflow-coreparse 已经这么做。

文件位置可以用 DECKFLOW_CONFIG_DIR(或 deckhtml 的 DECKHTML_CONFIG_DIR)改写,两个工具都认。

写文件时的约束

DeckHTML 的 sanitizeConfig 只保留它自己那 6 个键,遇到别的会重写文件。所以这里只写它认识的键apiKey / token / spaceId / apiBase),并且每次写之前重新读一遍再合并——webhookretentionHours 是它的,不能被我们的一次 config set 抹掉。本工具自己的状态放在 DECKFLOW_EXTRACT_HOME 下,不进这个文件。

常用参数:--mode auto|local|cloud--upgrade never|ask|auto(默认 ask,环境变量 DECKFLOW_UPGRADE 等价)、--prefer local|cloud--max-pages--max-table-rows--ocr auto--strict

给调用方 agent 的接口

每次 parse 的 stdout 与 parse-manifest.json 都带同一份评估结果:

字段 含义
tier / fidelity 用了哪一层、拿到的质量向量(text / structure / tables / images / notes / provenance)
gaps[] 源文件里但这次没提出来的东西,含 detected/extractedconfidenceexact 来自容器枚举,heuristic 来自文本推断)
decision usable + recommendedaccept / install / host / cloud / input)+ reason
recommendations[] 每个选项的 capability、收益、代价与是否需要重跑;不可用的选项也会列出并给出 blocked_by,但不内嵌调用方命令
engine_acquisition 显式 --upgrade auto 的安装、自检与最终选中引擎结果;失败但 fallback 可用时状态为 repairable

两条不变量:usable 为真时一定有一条 accept(用户永远可以「就用现在的结果」),没有任何一层能修复的缺口不会产生建议(比如图表内的数据系列,只写 diagnostic)。

skill 侧的读法:status == "parsed"recommended == "accept" 就静默继续;recommended 是其他值时把 priority: high 的选项连同 accept 一起呈现给用户;needs-input 才必须问。

状态机与 deckflow-lite 一致:parsed / repairable / needs-input / blocked,默认退出码恒为 0(读 JSON 判断),--strict 时非 parsed 即非零。缺依赖不再是阻塞态——除非 L0 确实产不出内容,否则永远先出 Bundle 再给建议。

测试

cd deckflow-extract/tests && python3 -m unittest discover

包含体积闸(base 依赖闭包必须是纯 Python 且 ≤10MB)、L0 地板测试、探测精度测试(标为 exact 的计数必须与真值完全相等)与决策矩阵测试。未安装的重引擎测试会跳过。

About

Deckflow C1 extractor: unpack heterogeneous inputs into a self-contained Parse Bundle

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages