一个10亿参数的模型,把一份文件改成了同批次里另一份文件的名字。它没有编造新名字,它回收了一个真实存在的名字——这比胡编更危险,因为看起来足够可信,差点就被直接采用。

打开网易新闻 查看精彩图片

事情的起点是一个塞了599个散落文件的下载文件夹:101个PDF、79个表格、129张图片,还有一堆叫 img.png、fp.jpeg 和 1762857107887_floop-plan-4.png 的东西。作者为Hacktoberfest挑战写了一个本地文件整理工具 Tidy Sloth,用Python标准库加Ollama,不联网、不要API密钥。

工具有效。但真正值得说的不是分类,而是模型出错的方式,以及修法为什么不是"换个更好的提示词"。

树懒是架构,不是吉祥物

树懒慢,是因为速度要消耗能量。文件整理有同样的经济学:大多数文件一眼就能判断,拿去问语言模型纯属浪费。所以整条流水线把token当卡路里花:先走规则,扩展名规则把png归到Images、xlsx归到Data、zip归到Archives;用途规则压过扩展名,Invoice-March.pdf进Invoices而不是Documents,Resume-Sanketh.pdf进Resumes;文件名本身够清楚的就直接放过,carprices.csv不需要模型来告诉你它是数据。

只有剩下的硬骨头才交给 llama3.2:1b:时间戳命名的、img.png这类、AC3.json这类。在作者真实的文件夹上,四分之三的文件从未接触过模型。整套把戏就在这里。

然后模型说了谎

小模型不是编辑,作者本来就知道。他没料到的是失败的具体形态。他把一打文件名打包进一个提示,要求逐个给出分类和更干净的名字。模型返回了正好十二个答案,顺序正确,JSON合法,数量对得上。但它悄悄把对应关系挪了位:

  • 1786076876258_SoulTree-Brochure-1 (1).pdf → AC2.pdf
  • 1786076876258_SoulTree-Brochure-1.pdf → Cost-Breakdown-6a61d9864a29092bf3f7159d-1.pdf
  • 1748950125346_out-0.webp → Aadhar-Card.webp
  • 1764919659917_floop-plan-4.png → Copy-of-2024-07-TBC-Banner-Generic-2560x650-1-H1nZTAL.png

每一个名字都属于同一批次里的另一份文件。模型没有幻觉出一个文件名,它回收了一个真实的。这更糟,因为它看起来足够可信,足以被直接发出去。

第一反应是不再相信模型自报的序号,改成按位置匹配。没用——数量本来就是对的,没有东西可抓。剥掉重复的扩展名能修好 thing.pdf.pdf,但修不了这个。

修法:改名只能复用文件自己的词

最终定下的规则很无聊,但有效:一个提议的名字,只有由原文件名里已经存在的词构成时才被接受。SoulTree-Brochure-1.pdf 改成 AC2.pdf,与源文件零个词重合,拒绝,文件保留原名;SoulaceNew2.png 改成 soulace-new-2,词全部重合,接受。

模型可以重组一个文件名,永远不能从别处导入一个。这条规则连同其他不变量写进了15个单元测试,包括模型产出的那五对坏样本,跑完耗时0.002秒。加上守卫之后,同样599个文件跑下来,跨行串名零次,重复扩展名零次。

另外两条救命的规则

没有含义的名字,绝不赋予凭空发明的含义。给一个 01.csv,模型很乐意建议 project-proposal.csv。那不是整理,是虚构,而且无法证伪,你永远不会发现它是错的。现在 01.csv 还是 01.csv,模型只决定分类。

确定性的噪声清除胜过模型的创造力。1762857107887_floop-plan-4.png 变成 floop-plan-4.png,靠的是Python剥掉开头10位以上的消息ID——不花token,不靠猜,Ollama开不开都一样。有一个边界情况:4446563839.pdf 全是数字,剥掉"ID"就什么都不剩,所以只有剥完还留下真实名字时才执行。

整理是破坏性操作,所以默认值很怂

plan 什么都不改,只写出 plan.json 和一份在浏览器里先看的HTML报告;apply 移动文件并写一份带时间戳的清单;undo 反向重放清单,并删掉它自己创建的空文件夹。代码里没有删除路径,重名一律改名,绝不覆盖。

作者在一份40个文件的副本上测了 apply 和 undo:40个文件进10个文件夹,然后全部还原、文件夹清理干净。他刻意还没对真实的下载文件夹执行 apply——计划就摆在那里等审阅,而这正是一个会动你文件的工具该有的工作流。

给想用小模型的人的建议

  • 按位置匹配,不要按模型给的序号。模型输出的 i 字段只是另一个生成的token,不是事实。
  • 数量正确什么都证明不了。十二行都在、形状都对,行与文件之间的映射照样是坏的。
  • 校验来源,而不只是格式。模式校验会让上面每一个坏改名都通过。
  • 给模型最小的、仍然有用的活。这里就是15个文件夹之间做选择,命名基本是机械的。

那14分钟是真的,也确实慢——这是笔记本上的1B模型,大部分时间花在模型上,不是规则上。更大的模型会命名得更好,也更费能量,那反倒背离了树懒的本意。