dsh-daily-documents
v0.1.0
Published
Local office document parsing (PDF/DOCX/XLSX/PPTX) with citation refs, plus optional VLM OCR, for the DeepSeek Harness (developer preview)
Readme
documents
dsh(DeepSeek Harness)插件:本地办公文档解析(PDF / DOCX / XLSX / PPTX + 可选 VLM OCR),把文档转成带来源引用的结构化文本块,供模型和其他插件统一消费。
状态:developer preview。尚未在真实 dsh 运行时中验证,手动验证步骤见下文。
它解决什么问题
dsh 核心与社区插件都没有通用文档解析能力。读一份本地 PDF / 表格 / 幻灯片,通常要模型自己写脚本猜格式。本插件提供 5 个只读工具,核心差异化是引用位置回传:每个内容块都带定位信息——
| 格式 | 引用粒度 | 示例 |
| --- | --- | --- |
| PDF | 页码 | 第 3 页 |
| XLSX | 工作表 + 单元格 | 销售!B4 |
| PPTX | 幻灯片号(含备注页) | 幻灯片 2、幻灯片 1(备注) |
| DOCX | 标题路径(表格另带表序/行号) | 第一章 概述 > 1.1 背景 |
搜索、摘要、问答都可以引用精确位置,而不是"文档里某处"。
工具
document_inspect:快速探测——格式、大小、页数/工作表名/幻灯片数、文档属性(标题/作者等),不提取正文。document_extract:提取结构化内容块(每块带引用)。输出按maxChars截断(默认 20000,硬上限 200000,均可配),截断时最后一个块带…[截断]标记且truncated=true。document_search:关键词搜索,返回命中块的引用位置 + 上下文窗口片段;支持大小写开关、命中数与上下文宽度调节。先搜索定位、再按需提取,避免整文档灌入上下文。spreadsheet_read:XLSX 专用区域读取,A1 区域语法:Sheet1!A1:C10、B2、销售(整表已用区域);空单元格按坐标补空串。区域上限 20000 单元格,防止误读整表撑爆内存。ocr_image:VLM 桥接 OCR(OpenAI 兼容端点),支持 png/jpg/webp/gif。默认关闭;未配置时返回明确的配置说明而不是报错崩溃。
安装与配置
# dsh 配置示例
- id: documents
name: dsh-daily-documents
config:
enabled: true
defaultMaxChars: 20000 # document_extract/search 的默认字符预算
maxMaxChars: 200000 # maxChars 参数的硬上限
searchMaxResults: 20 # document_search 默认最大命中数
vlm: # 可选:VLM OCR 桥接(默认完全关闭、零网络)
enabled: true
baseURL: https://api.openai.com/v1 # 任何 OpenAI 兼容端点
apiKeyEnv: OPENAI_API_KEY # API Key 从该环境变量读取,不写进配置
model: gpt-4o-mini # 需具备视觉能力
timeoutMs: 60000
maxTokens: 4096
# prompt: 自定义默认转写提示词格式支持矩阵
| 格式 | 解析方式 | 正文 | 表格 | 备注/批注 | 元数据 | | --- | --- | --- | --- | --- | --- | | PDF | pdfjs-dist(legacy 构建,lazy import) | ✅ 文本层 | ❌(按纯文本提取) | ❌ | ✅ Title/Author 等 | | DOCX | 自研 XML 遍历(jszip + fast-xml-parser),mammoth 兜底 | ✅ 段落 + 标题层级 | ✅ 逐行 | ❌ | ✅ core/app 属性 | | XLSX | 自研 XML 解析(sharedStrings + worksheets) | ✅ 单元格值 | ✅ 即内容本身 | ❌ | ✅ core/app 属性 | | PPTX | 自研 XML 解析(slides + notesSlides) | ✅ 逐形状文本 | ❌(按纯文本提取) | ✅ 演讲者备注 | ✅ core/app 属性 | | 图片 | VLM 桥接(ocr_image,默认关) | ✅ 模型转写 | 由模型决定 | — | ❌ |
已知限制(如实声明)
- 扫描版 PDF 没有文本层,
document_extract会得到空块或乱码——需先把页面转成图片再走ocr_image(本插件不做 PDF 渲染)。 - 不支持 .doc / .xls / .ppt 老二进制格式(OLE 复合文档),仅支持 OOXML(.docx/.xlsx/.pptx)。错误信息会明确提示。
- 加密 PDF 不支持(需要密码的会在报错中说明)。
- XLSX 日期/数字按原始值返回:不解析样式表,日期是序列数(如 45292),百分比是小数。需要格式化请结合
spreadsheet_read的坐标自行换算。 - XLSX 不计算公式:公式单元格返回缓存的计算结果(
v值),没有缓存时为空。 - SheetJS(xlsx 包)刻意不用:npm 分发的版本已冻结在 0.18.5(后续版本只发 CDN),且本插件需要单元格坐标级的解析控制,自研解析反而更贴合需求。
- PDF 测试夹具是手写最小 PDF:单行长文本超出页面宽度时 pdf.js 会丢弃越界字符(真实 PDF 的排版不会这样),所以夹具文本保持短行。若未来 pdfjs-dist 升级导致夹具失效,PDF 测试可收缩到"非 PDF 输入报错"等边界用例。
- docx 标题识别依赖
w:outlineLvl或Heading1~9样式;纯手打加粗大字不算标题(Word 里本来也不是标题)。 - VLM OCR 的输出质量完全取决于所配置的模型与端点,本插件只负责协议桥接。
权限透明
本插件对宿主环境的影响面,逐条交代清楚:
- 读写位置:只读用户通过工具参数显式指定的单个文件;不写任何文件、不读目录(目录会被拒绝)。文件大小上限 200MB。
- 网络域名:默认无网络访问。仅当
vlm.enabled=true时,ocr_image会向配置的vlm.baseURL端点发送 POST 请求(图片 base64 + 提示词),别无其他网络行为。 - 凭证:默认不持有任何凭证。VLM OCR 开启时,从
vlm.apiKeyEnv指定的环境变量读取 API Key(默认OPENAI_API_KEY),只用于对该端点的Authorization: Bearer头,不落盘、不日志。 - 确认点:无(全部为只读工具)。
- 日志内容:仅启动行(字符预算、VLM 是否启用及模型名);不记录文档内容、路径或 Key。
手动验证
本仓库的 CI 只覆盖类型检查与纯函数/解析器单测(夹具为程序现场生成的最小 xlsx/pptx/docx 与手写最小 PDF)。接入真实 dsh 后请手动验证:
- 在 dsh 配置中启用本插件,确认启动日志出现
documents: loaded。 - 准备一份真实 PDF/DOCX/XLSX/PPTX,依次调用
document_inspect→document_search(挑一个文中存在的关键词)→document_extract,确认:inspect 的页数/工作表数与 Office 中打开一致;search 命中的引用位置(页码/单元格/slide 号/标题路径)正确;extract 的块文本与原文一致。 - 对一份 XLSX 调用
spreadsheet_read,range 传工作表名!A1:C3,与 Excel 中显示的值对照。 - (可选)配置
vlm后对一张含文字截图调用ocr_image,确认转写结果;再临时删掉环境变量确认报错包含变量名指引。 - 用
document_extract处理一个超过defaultMaxChars的大文档,确认truncated=true且末尾有截断标记。
许可
MIT
