文章总结: 本文介绍作者使用本地laya模型(基于ModernBERT架构)对484篇Obsidian笔记进行自动分类的完整实践。全程本地运行保护隐私,通过置信度阈值0.25实现166篇自动归位、103篇留置人工处理。文章详细说明了环境配置、类别设计、阈值设定及文件安全移动等关键步骤,强调人机协作理念,并提供GitHub代码链接。
综合评分: 88
文章分类: 实战经验,AI安全,安全工具,安全建设
不调 API,我用本地 laya 模型给 484 篇笔记做了自动分类
原创
adra1n
adra1n
YY的黑板报
2026年9月23日 16:09
天津
在小说阅读器读本章
去阅读
在公众号小说中沉浸阅读
前阵子我给 Obsidian 库做大迁移,旧库 484 篇笔记要重新归类。这个库里装着我这些年的日记、会议记录、技术折腾笔记,说真的,一篇我都不想发给云端 API。
所以我干脆全程本地,用 laya 这个能跑在自己机器上的模型,搭了套文档自动分类。跑完的结果是这样,排除掉索引文件和空壳笔记,269 篇参与判断,166 篇自动归位,103 篇模型自己没把握、留在原地等我人工翻,0 篇失败。
484 篇笔记,从头到尾没出过这台机器。
这套做法谈不上多成熟,我自己也还在摸索,但它完整跑通了。今天把整条链路拆开讲给你听,环境怎么配、喂什么、类别怎么设、阈值怎么定、最后怎么安全地移动文件,每一步都能照着做。
可能有小伙伴纳闷,文档分类这种事,不就是调 GPT 甩个 prompt 吗,让它吐个 JSON 不就完了。
怎么说呢,这招我也用过,但有两个问题一直卡着我。一个就是开头说的隐私,日记和会议记录发出去就收不回来了。另一个更实际,生成式模型给你的分类结果是一个字,不是一个概率。它说这篇是技术文档,可它不会告诉你它有几分把握,你根本没法在代码里写「低于 0.25 就别动」这种规则,因为压根没有置信度可以判断。
laya 不一样,它是个专门做判断的小模型,架构是 ModernBERT,你给它一组选项,它还你每个选项的概率。有了概率,判断就从一句文本变成了可以被代码处理的中间状态,阈值、留置、人工兜底,全靠这个概率才玩得起来。
我跟你说,这一步想通了,后面全是顺的。
先说环境,这是最劝退的一段,我把踩过的坑直接给你。
我这台是 Intel Mac,x86 架构,PyTorch 2.5 往上压根不给这个架构出包,所以 torch 得锁在 2.2.2。transformers 要卡在 4.48 到 4.49 之间,低了不认 ModernBERT 这个架构,高了没必要。numpy 得小于 2,不然跟老版 torch 打架。Python 用 3.11,3.12 跑 torch 2.2 的 compile 会出问题???对,你没看错,版本就是这么娇气。
所以给你的第一个做法是,别在系统 Python 里裸装。建个干净的 venv,按这几个约束把依赖锁一遍,装完先跑一句 import laya 看看报不报错,再往下走。这步花不了十分钟,但跳过它,后面每一个报错都会让你怀疑人生。
环境搞定,真正的设计只有三件事,喂什么、问几个、阈值多少。
第一件,喂什么。模型的输入我做了两档,title 档只喂标题,full 档喂标题加标签加标题层级加正文预览。一开始我图快用 title 档,1.7 秒判一篇,直到它把一篇标题叫「随手记」的笔记判成了生活随笔,我打开一看,正文全是 Nginx 502 的排障记录。
改成 full 档,同一篇直接判成技术文档,置信度 0.327。
差别就在正文那几百字里。空标题的笔记在中文库里太常见了,随手记、备忘、无标题,光看标题等于盲判。full 档慢一些,4.6 秒一篇,但这个时间花得值。所以默认开 full,title 档只留给你批量赶工、且标题都规规矩矩的场景。
第二件,问几个。这里有两条硬约束,都是我撞了墙才知道的。
一是类别别超过 10 个。laya 的选择题输出落在几个不同的校准桶里,6 到 10 个选项的桶温度是校准过的,第 11 个开始会被强行钳到 0.1006,那之后的置信度就是不可信的数字。我把类别写死成 8 类,配置加载时超过 10 类直接报错拒载。宁可噎死,也不能让一个假概率骗我。
二是选项描述必须短。模型给选项文本共用一个 192 token 的窗口,超长直接抛 ValueError。所以每个类别一句话,讲清楚它跟邻居的区别就行。我那 8 类是会议纪要、工作文档、技术文档、学习笔记、读书笔记、生活记录、资料收集、想法灵感,描述全是十几个字的大白话。
顺便还有个省算力的招,一次 system_one 调用可以同时塞好几个问题。我让它一遍推理同时回答两个问题,这篇归哪一类,以及长期价值几分。价值分 0 到 3 共四档,低于阈值就不打标签,笔记本身照常归位。一遍活干两件事,单篇耗时还不翻倍。
第三件,阈值。这是整套东西敢自动移动你文件的底气。
我拿模型把全库跑了一遍打出分布,清晰的技术笔记能到 0.32,模糊的随笔只有 0.13,整体铺在 0.04 到 0.49 之间。阈值我定在 0.25,高于它才移动,低于的留在收件箱。迁移那批留置的 103 篇,我挨个人工翻了一遍,大部分确实是四不像的笔记,模型没把握是对的。
原则就一条,绝不乱挪。模型拿不准的时候,它能给出的最好输出不是错误答案,是闭嘴等着。
还有个坑单独提醒你。laya 给的价值判断 confidence 实测低得离谱,普遍趴在 0.03 到 0.14。所以价值那一路看分数本身,别看 confidence,我的代码里低于 0.15 就挂个提醒标。
阈值也别拍脑袋。先跑 dry-run 把全部置信度打出来看分布,你的库和我的库未必一个样,看着分布定线。两个方向都得试,判太松会乱归位,判太严会全留置。
判断搞定,前后还有两环,处理不好你不敢开自动。
前面是读笔记,frontmatter、标签、标题层级、正文前几百字拼成模型认得的 state,跳过下划线开头的索引和模板文件夹。这步没难度但别偷懒,state 读不全,后面全是垃圾进垃圾出。
后面是移动文件,这里藏着最要命的坑。Obsidian 靠双链组织知识,一篇笔记搬进新文件夹,别的笔记里那些带路径的链接,比如 [[00 收件箱/某篇]],就断了。我的做法是移动完立刻全库扫一遍,把指向旧路径的带路径链接改写成新路径,裸文件名链接 Obsidian 自己能解析,一个字不用动。目标文件夹没有就自动建,文件重名就加序号,绝不覆盖。移动完再往 frontmatter 里写回 category、confidence、value_score 几个字段,方便日后检索。
对了,命令默认永远是 dry-run,必须显式加 –apply 它才真动手。所以第一个动作永远是不带 apply 跑一遍 scan,先看它打算怎么挪,确认过眼神,再放行。
到这里,坦率的讲,成本也得摊开说,不能只画饼。
冷启动 19 秒,torch 加载就是这么慢。。。这个省不掉。full 档单篇 4.6 秒,十来篇笔记一分多钟。所以我也没做什么常驻监听进程,按需触发,说一句「分类笔记」跑一次,干完就退,机器不替我 24 小时空转。第一次配环境大概要花掉你半个下午,版本那几个坑我是挨个撞过来的,愚钝如我,硬试了好几轮。
但你想想看,这套东西换来的是什么。日记躺在自己硬盘里,分类自动化了,拿不准的自动送到你面前人工裁决,每一步判断都带着概率可回溯。
医院急诊科其实就是这个逻辑。最先接你的从来不是医生,是分诊台的护士,她拿标准判断你急不急,急的直接推进抢救室,不急的让你坐着等,真正需要深度判断的重症才轮到医生出手。
我这套就是个分诊台。模型不负责治好病,只负责给出一个带概率的初判,把确定的送走,把不确定的留下来等人。
判断这件事最终还得人来,但判断可以先被产生成概率,人只处理低置信度那条尾巴。我一直觉得,这可能是人机协作里最踏实的一种形态,不是 AI 替你做决定,是 AI 帮你把需要做决定的那一小撮挑出来。
484 篇就是这么处理完的,166 篇自动归位,103 篇进了我的人工队列,一篇没丢,一篇没断链,笔记没出过这台机器。
屏幕前的你如果也有个堆满笔记的库,听我一句,别一上来就全量迁移。先挑十篇你熟得不能再熟的笔记跑一遍判断,看看它给的置信度长什么样,再决定信它多少。代码我放在 GitHub 上: https://github.com/adra2n/obsidian-classify,配置模板抄过去把路径一改就能用。
这套阈值和类别是我这个库试出来的,你的库未必通用,可能有些想法还不成熟,但方向我始终坚信。先让它分诊,再让它动手。
以上,既然看到这里了,如果觉得不错,随手点个赞、在看、转发三连吧,如果想第一时间收到推送,也可以给我个星标⭐~
谢谢你看我的文章,我们,下次再见。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:YY的黑板报 adra1n
adra1n《不调 API,我用本地 laya 模型给 484 篇笔记做了自动分类》