中文EN

dsh-tool-invoice

toolsnpmMIT

从文本中提取发票号码、日期、购销方、税号与金额/税额/合计,并验算「金额 + 税额 = 价税合计」是否成立,对不上就报出来。

下载量 / Downloads
482

安装

dsh plugin --profile web add dsh-tool-invoice

沙箱测试

这个插件还没测过。提交测试 →

README

发票提取器 —— 让 dsh 把发票读成能对账的数字

提取字段 + 验算 + 汇总台账 —— 把发票里的号码、日期、购销方、金额、税额
抽成结构化字段,同时替你检查 金额 + 税额 = 价税合计 到底成不成立。

给 DeepSeek Harness 用的自建工具插件:3 个工具,把「读发票」从猜数字变成可审计。

Compatibility: built and tested against dsh 0.2.0-rc.2 (preview).
The apply(ctx) plugin spec is stable; verify against your own dsh version if needed.

一行安装

dsh plugin --profile desktop add github:yuehancn/dsh-tool-invoice

支持的 profile:desktop(桌面版)/ web(Web 版)。装完重启 dsh 即可用。


为什么需要它

让模型「看一下这张发票」,你得到的往往是一串看着合理、但没有验算过的数字。

而发票的全部可信度就在于一条恒等式:

金额 + 税额 = 价税合计

这个插件做三件普通正则做不到的事:

1. 验算,而不是抄写 —— 每条检查都同时给出「应该是什么」和「读到了什么」,

差了多少。对不上就是能行动的线索,而不是一个可疑的数字。

2. 给每条字段留下证据 —— 每个值都带着匹配到的标签(销售方名称)

和原句。会计可以复核,而不是盲信。

3. 不乱猜 —— ¥1130.00 单独出现时可能是金额、税额或合计。

所以每条规则都要求自己的标签在场,没有标签就报「未识别」,

而不是挑一个看着像的。

不 mock 一个字节:288 条断言对着真实 @deepseek-ai/dsh-tools 与真实子进程跑过。


三个工具

invoice_status

探本插件能不能自己读文件(有没有配文本提取命令),并列出它能识别的全部字段名。

invoice_extract(path | text)

从一份发票里提取字段并验算。可以直接给文件路径,也可以给你已经拿到的文本。

识别的字段:

字段 · 中文标签 · 英文标签

code / number · 发票代码 / 发票号码 · Invoice Code / No.

date · 开票日期 · Date of Issue

seller / buyer · 销售方 / 购买方 · Seller / Buyer

sellerTaxId / buyerTaxId · 纳税人识别号 · Tax ID

amount · 金额(不含税) · Amount Excluding Tax

tax · 税额 · Tax Amount

total · 价税合计(小写) · Total Amount

totalInWords · 价税合计(大写) · Amount in Words

checkCode · 校验码 · Check Code

remark · 备注 · Remarks

返回的三条检查:

检查 · 含义

amount + tax == total · 基本恒等式(容差可配:默认 ±2 分或 ±0.5%)

digits agree with 大写 amount · 小写数字与大写金额是否一致 —— 扫描件出错时这一条最先报警

implied tax rate is a standard bracket · 反推税率是否落在 0/1/3/5/6/9/13% 这些标准档位上

还有一个 faithful 布尔值:所有检查通过 且 号码/日期/合计都在 → true。

绝大多数调用只需要看这一个字段。

invoice_ledger(paths, groupBy, outputName)

把多张发票汇总成台账:总计、按字段分组的小计,并标出

没验算过的行、读不出来的行、以及重复的发票号码(重复报销的经典事故)。

加 outputName 会把台账写成 JSON。


容错到什么程度

真实发票文本很脏,所以解析器刻意宽松:

脏法 · 处理

全角数字 1234 · 折叠成半角

全角标点 ¥ 1,000.00 · 折叠成 ¥ 1,000.00

OCR 把 0 认成 O、1 认成 l · 仅在数字串内部修复(不会碰公司名里的 O)

千分位 1,234.56 / 空格分隔 1 234.56 · 都认

日期 2026年10月02日 / 2026-10-02 / 2026/10/2 / 20261002 · 统一成 YYYY-MM-DD

标签和值不同行(两栏排版) · 支持(标签独占一行时读下一行)

发票号码: 后为空、值在下一行 · 支持(不会把自己的冒号当成值)

红字发票 (1234.56) · 识别为负数

大写金额 壹仟贰佰叁拾肆元伍角陆分 · 解析成 1234.56,并交叉验证

英文发票(Stripe 收据等) · 同样支持

标签必须出现在行首。这是刻意的:Tax 会出现在
Amount Excluding Tax 里面,如果允许任意位置匹配,就会把「不含税金额」
当成税额读走 —— 这是实测踩到过的坑,有专门的回归用例。

配置

# ~/.dsh/profiles/<profile>/cordis.patch.yml
- id: tool-invoice
  config:
    outputDir: C:/Users/you/Documents/invoice-output
    # 想让插件自己读 PDF/图片,就配一个「文件转文本」命令
    textCommand: C:/poppler/Library/bin/pdftotext.exe
    textArgs: ["-layout", "{input}", "{output}"]
    toleranceCents: 2

配置项 · 默认 · 说明

outputDir · invoice-output · 产物目录(中间文本、台账 JSON)

timeoutMs · 600000 · 单次调用预算(10 分钟)

textCommand · 空 · 留空则只接受文本输入;invoice_extract 仍可用

textArgs · ["-layout","{input}","{output}"] · 占位符 {input} / {output}

tolerancePercent · 0.5 · 恒等式的百分比容差

toleranceCents · 2 · 恒等式的分容差

status / extract / ledger · true · 按需关掉某个工具

不配 textCommand 也完全可用 —— 只要你能拿到文本(比如先用

dsh-tool-ocr 插件、或从邮件正文里复制),invoice_extract 就直接可用。

textCommand 只是让你少一步手工。

接 dsh-tool-ocr:把 textCommand 指向 ocr 插件的 CLI 即可,两者串起来

就是「扫描件 → 文本 → 结构化发票」。


安全说明

  • 只用 spawn(command, argsArray) —— 不拼 shell 字符串,

路径里有空格、引号、中文都不会出事(有专门的中文带空格用例)。

  • 只读写你指定的输入文件与 outputDir,不上传、不联网。
  • 文本提取命令是你自己配置的可执行文件,插件不下载、不安装任何东西。

跑测试

mkdir -p node_modules/@deepseek-ai
cp -r "$HOME/.dsh/profiles/desktop/node_modules/@deepseek-ai/." node_modules/@deepseek-ai/
node _test/run-all.mjs

三个套件,288 条断言全绿(对着真实 @deepseek-ai/dsh-tools 跑,不 mock):

套件 · 断言 · 内容

test-logic.mjs · 159 · 全角折叠与 OCR 混淆修复、金额解析(货币符号/千分位/负数/尾随噪声)、中文大写金额解析(含万/亿/角/分)、日期四格式、税号、标签锚定与特异性、三条验算、文档分类、台账汇总/分组/去重

test-integration.mjs · 73 · 模块导出、注册数量、defineTool schema 归一化、三个开关、12 条错误路径、卡片标题、输出渲染

test-e2e.mjs · 56 · 真的起子进程当文本提取器 → 真写文本 → 真提取;提取器退出非零/静默无输出的诊断;4 张发票的台账(含重复号与对不上的行);脏输入(全角+OCR混淆+两栏排版);英文发票;篡改大写金额的交叉验证

test-e2e.mjs 用自带的替身提取器 _test/fixtures/mock-text.mjs,

不需要装 poppler、不需要联网就能跑。


许可

MIT

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:2,最后更新 2026-10-20

链接

GitHub · Homepage · npm

同类插件