报税季最烦的不是算税,是那一堆收据。开Uber的、跑DoorDash的、接私活的,在国税局眼里都算小生意。加油、话费、打印墨盒,每一笔都能抵税——前提是你拿得出凭证。于是你攒了一鞋盒皱巴巴的收据,或者手机相册里躺着400张照片。
![]()
到了四月,摆在面前的就两条路:要么掏150到300美元请个记账的帮你分;要么把这一年所有消费的照片,一张张传进某个"免费"记账App。前者贵,后者等于把自己的生活轨迹交出去。
Shoebox想做第三条路。把照片丢进一个文件夹,跑一条命令,剩下的交给跑在你自己笔记本上的视觉模型。
它到底怎么跑
整个流程就两步。先拉模型,再跑脚本:
ollama pull qwen3-vl:8bpython3 shoebox.py ./my_receipts --work "rideshare driver"
然后打开本地页面看结果。模型读每张收据,把它归到对应的IRS Schedule C(自雇收入报税表)行项下,并写一句话解释为什么这么归。你在一页上核对,改掉不对的,勾选"看起来对",导出CSV给会计或报税软件用。
作者跑了一组7张的样例,结果挺有意思:
- Adobe 64.85美元 → 18 办公支出
- 洗车 39.99美元 → 9 车辆费用
- 星巴克 14.48美元 → 24b 餐费(按50%计)
- Shell加油 41.33美元 → 9 车辆费用
- Trader Joe's 22.93美元 → 个人支出(不可抵扣)
- T-Mobile 101.64美元 → 25 水电通讯
- Staples 60.29美元 → 22 办公用品
最妙的是那杯星巴克。收据上印了一行字:"Met client re: logo revisions"(见客户谈logo修改)。模型抓住这行字,把它归成商务餐费,还自动套用了餐费50%的抵扣上限。同时它没把超市那笔算进抵扣里。
两个坑,都是自己修的
第一个坑:模型先选类别,再写理由。作者最初的JSON结构里,category排在reason前面。结果一张加油收据,模型先归成"个人支出",然后写理由论证它其实是可抵扣的车辆费用——自己打自己脸。因为输出是从左往右生成的,它在想清楚之前就已经把答案定死了。把reason挪到category前面,模型就变成先解释再决定。作者还给每个Schedule C行项加了一句话说明,因为8B的模型并不知道"Line 10"到底管什么。两处改完,7张样例全对。
第二个坑:think: false在不同Ollama版本里行为不一样。0.34版上关掉思考,模型会把JSON塞进thinking字段,content留空。升到0.40之后,模型照样推理,400 token的输出上限还没轮到JSON就用光了。修法是哪个字段有内容就读哪个,同时把上限提到3000 token。
这两个修复都没提工单。模型和服务器都在自己机器上,出什么问题一眼就能看见。
为什么这事值得做
作者说得很实在:关掉推理(速度快很多)的时候,模型有一次把话费读成了0.00美元。这就是那个复核页面存在的理由。这个产品不是"AI帮你报税",而是"机器干完枯燥的部分、把需要人看的地方标出来,你花30秒过一遍"。
定价上,作者想卖19美元,一次买断。这个价格成立的前提是每张收据的处理成本为零。云端视觉API按张收费,一个用户几百张收据乘下来,就被逼着做订阅——可这工具一年也就报税季用一次。开源权重让"买一次就归你"这件事重新变得可能。
还有一层是隐私。一年的收据就是你生活的地图:你去哪开车、吃什么、在哪家药店买药、什么时候手头紧。最需要帮忙整理这些单据的人,恰恰是那些靠一单一单结账过日子的零工,而记账App要的正是他们交出这一切。模型跑在自己笔记本上,这个取舍就不存在了。模型下载完之后,Shoebox完全不需要联网。
代码就两个文件:shoebox.py(约200行Python,只用标准库,Pillow可选)和review.html(一页,无框架)。另外还有个make_samples.py,生成假收据,方便你先试不交出自己的。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.