一个291 MB的模型,面对一页写了多个维护周期的说明书,给出的答案是:前置碳滤芯需要"每1个月"更换一次。它同时引用了一句话作为依据——而那句话里根本没有任何周期数字。这个错误被自动校验程序拦了下来。Sloth Drawer这个项目,就是从这次失败开始的。
![]()
作者手上有11台设备,却说不清任何一台上次清洁是什么时候。说明书PDF躺在一个没人打开的抽屉里,"每2个月"这类信息没有和任何记忆绑定。于是他做了Sloth Drawer:一个离线、纯CPU运行的代理,读取你已有的说明书PDF,对找到的每一个周期回到原文中核验,然后为每台设备打印一张维护卡——贴在设备上,这件事就不用再想了。
它是什么
Sloth Drawer由一个Python命令行工具和一个单页网页界面组成。不需要API密钥,不需要云端模型,也不需要租数据库。冷安装耗时3.66秒(uv、空缓存、19个包),因为核心只依赖pypdf和标准库。
用法是把一摞说明书PDF丢进文件夹,然后跑扫描。演示语料是7个品牌的19份空气净化器说明书——只覆盖一个设备品类,因此只有一种卡片版式,也只有一个诚实、可比的基准。
- 扫描:19份说明书,4核CPU上无人值守跑10分14秒
- 出卡:单台设备生成一张卡,HTML(A6打印版)加80列终端卡
- 完成:标记某项已做,到期日在代码里前移
- 报告:输出准确率表格
- 服务:在浏览器里看同一批卡片
网页卡与命令行卡逐字节一致,有测试专门证明这一点。
模型指路,代码引文
整条流水线是:摄入→切块→正则预筛→(可选)270M分诊→1B抽取→校验。基准测试逼出了三个决定。
第一,每次调用只问一个事实,用扁平结构,绝不用数组。作者在4核CPU、7.5 GB内存、无GPU的条件下测了三个模型。在对象数组结构下,phi4-mini返回了{"intervals": []}——结构合法,语义为空。改成扁平结构、对每个形似周期的句子问一次,所有被测模型都通过了。
第二,模型只负责指,代码负责引和算。模型返回一个引文片段,代码随后做四件事:在来源页中定位该片段、扩展到所在整句、从这句话本身重新解析周期、再与模型给出的数字比对。结果分三种:通过、修复(以代码值为准,记录分歧)、拒绝。每张卡上的每个日期都在存储层由你维护的服务日志计算得出,零个日期由模型撰写。
第三,三层级联。正则预筛免费给形似周期的语言打分;在这份语料上,1,325个切块中只有84个真正到达模型,94%在零成本环节被过滤掉。gemma3:270m(291 MB)是可选的yes/no分诊闸门;gemma3:1b(806 MB)在温度0、固定种子、结构化输出格式下做抽取。两个模型都通过Ollama在本地运行,核心安装从不导入任何SDK。
单位换算(90天=3个月、720小时=1个月、区间取中点等)集中在一张表里,同时写进提示词和校验代码,并用测试把两边钉在一起——如果模型的规则和代码的规则发生漂移,每一句"每90天"都会变成一次错误的修复。
校验器才是产品
小模型会对你说谎;要做的是让这个谎到不了一张打印出来的日期。校验器是554行纯Python,不含模型调用,除errors.py外不导入项目内任何模块,AST导入测试强制执行这一点。
运行中一次真实的修复:Winix 5500-2第1页,模型说"每3个月清洁一次"(可水洗碳滤芯那一行),但它的引文漂到了相邻的"……Last Approx. 12 months True HEPA Filter"一行。校验器重新解析被引句子,得到12,于是写入12并记录分歧。今天这张卡上同时有3个月和12个月两项任务,各自引用各自核验过的句子。
作者的核心观点是:抽取流水线不需要更聪明的模型,它需要一段被核验过的引文。把模型输出当作不可信的API响应来设闸,并且从模型只能指向的源文本中重新推导数值——这样即便结构上完美的答案,也可能在自己的引文面前失败。
离线与开放
整套栈运行在你所在的地方:291 MB和806 MB的Gemma权重、4核CPU、无GPU,22,401个token花费$0.00。作者在断网条件下验证了完整的19份说明书运行——在只配置回环的用户加网络命名空间内,内部再起一个Ollama,没有任何对外路由,判定结果完全一致。地下室、车库、气隙网络:这个说法是一条日志,不是一句承诺。
换模型,卡片不变。--model phi4-mini改变代理的行为,接口保持一致——开放权重是让模型成为配置项而非依赖项的唯一条件。换检索后端,卡片也不变:同一张卡既能从本地SQLite FTS5三元组索引产出,也能从Tiger Cloud混合索引(pgvector加pg_textsearch BM25,用倒数排名融合)产出。在实时语料上的对齐测试:4/4查询一致,本地前5的命中都能在云端前20中找到。云索引是增强,从不是前提。
隐私是结构约束,不是承诺。云端表只存切块文本和向量,没有任何一列能装下设备名、序列号、购买日期或服务日志,填充它的代码也从不接触这些。只有说明书文本和向量过网,卡片和到期日留在你的机器上。由于模型必须引用你自己说明书中的逐字子串,它只能指向你本来就拥有的文本,无法夹带一个你没有出处的事实。
格式端到端开放:SQLite、JSON、Markdown报告,以及你已有的PDF。卸载工具之后,它抽取的一切连同引文仍然在你手里。
算得清的回报
手工读19台设备的维护表,认真看的话每台约20分钟——而老实说,你从来不会去看。实测的回报是:把19份PDF丢进文件夹,走开,10分14秒后拿到35个已核验周期、每台一张打印就绪的卡,以及一份准确率报告,告诉你哪13次抽取需要修复、哪7次被拒绝。约37倍的阅读量节省,$0的API成本,永久、离线。此后维护只需一次done或浏览器里一次点击——移动到期日的是代码,不是语言模型。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
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.