会计手工录发票这件事,痛的从来不是"录"本身,而是录完之后没人知道对不对。
一沓发票录进台账,金额、税额、价税合计三列。等到月底对账对不上,再回头一张张翻—— 这时候你已经不知道是哪张出的问题了。
把这活交给 AI,表面上快了很多,实际上风险更大:模型认错一个数字的时候, 它的输出看起来和认对时一模一样。日期是日期,金额是金额,整整齐齐,你没有任何线索。
发票上印着三个数:未税金额、税额、价税合计。它们之间有一个必须成立的关系:
`` 未税 + 税额 = 价税合计 ``
如果 AI 读出来的三个数不满足这个式子,那一定有一个读错了。
这不需要人来判断,是纯算术。所以我把它做成了硬性一步:每张发票读完,代码自己验一遍。
我造了三张发票,前两张正常,第三张故意把合计写错(未税 1200 + 税 120,合计栏写成 1350):
``json { "invoices": 3, "totals": { "net": 4600, "tax": 460, "gross": 5090, "currency": "USD" }, "verification": { "passed": false, "failed_rows": [3], "note": "1 invoice(s) do not add up (net + tax ≠ gross)." } } ``
逐行看:
| # | 未税 | 税 | 合计 | 校验 | 差额 |
|---|---|---|---|---|---|
| 1 | 1000 | 100 | 1100 | ok | |
| 2 | 2400 | 240 | 2640 | ok | |
| 3 | 1200 | 120 | 1350 | FAILED | 30 |
第 3 行被标出来,而且告诉你差 30(1200+120=1320,发票写的 1350)。 不是"这批数据可能有问题",是"第 3 张,差 30,去看它"。
三张的总成本是 $0.000327。
算术全在代码里,模型一个数都不算。模型只负责语义判断——"这一栏印的是税额还是运费"。 这种事几何和正则做不了,得靠模型。但加减法交给模型是最糟的选择:它会算错, 而且算错时同样自信。让模型校验自己等于没校验。
混币种直接拒绝给合计。如果一批里既有美元又有人民币,工具不会给你一个"总额"—— 把两种货币加在一起是个会计错误,给一个看起来能用的错数,比不给更糟。它会明说为什么不给。
读不到的字段留空,不猜。发票上没印买方名称,那一栏就是 null。 一个编出来的买方名字混在真数据里,比空着危险得多。
免注册,一次最多 20 张:
`` curl "https://ainetcafe.com/t/extract_invoices?urls=发票1的URL,发票2的URL" ``
返回结构化台账 + 一个 CSV 下载链接(带 BOM,Excel 打开中文不乱码)。 PDF 直接给链接,扫描件导成 png/jpg 再给。
也可以让 agent 直接调——MCP 接进去之后它叫 extract_invoices。
它不替你做账,只告诉你这批数据能不能进账。 对不上的时候它会说对不上、差多少、是哪一张, 而不是给你一张看起来很整齐的错表。
---
利益披露:ainetcafe.com 是我做的,工具匿名就能用、有免费额度,每次调用返回精确到 $0.0001 的 真实成本(不是 credit 折算,失败不收钱,账单在 ainetcafe.com/spend 随时可查)。 做自校验这一步的原因很实在:市面上做发票识别的产品不少,但没有一个告诉你它这次读得对不对。 在财务场景里,一份不知道对不对的数据,价值接近于零。
给你的 agent 接上 AI 网吧(一行 MCP)→