我为什么做一个开源的 Mac 清理工具

我一直在用 Mac 清理软件,但每次都卡在同一个地方:它告诉我「这个文件夹 2 GB,可以清理」,我却不知道这是什么、删了会不会出事。结果要么不敢删,要么挨个复制名字去搜。

清理软件本质上是一个会删除你文件的程序。这件事让我很别扭:我把删除权交给它,却看不到它到底删了什么、凭什么判断能删。

所以我花了两周,做了 Pika Clean :一个开源、免费的 Mac 清理工具。它和别的清理软件最大的区别是,删之前,先让 AI 告诉你这个文件是什么、能不能删。

下面讲讲为什么这样做,以及做的过程中几个关键的取舍。

一、为什么开源

理由很简单:一个要删你文件的软件,应该让你能看到它的代码。

闭源的清理软件,你只能相信它的「可以安全删除」。开源之后,任何人都能去看:

  • 它扫描了哪些目录;
  • 删除前做了哪些检查;
  • 发给 AI 的到底是什么数据。

Pika Clean 用 GPLv3 协议开源,全部功能免费,没有 Pro 版,也没有任何统计和埋点。

二、为什么要让 AI 来解释

清理软件的传统做法是维护一份规则库:哪些目录是缓存、哪些能删。问题是 Mac 上的应用太多了,规则库永远追不上。~/Library/Caches 里一个叫 CloudKit 的文件夹、一个叫 familycircled 的文件夹,普通用户根本看不懂。

大模型恰好擅长这个:它见过大量关于 macOS 目录结构的资料,能说出「这是 iCloud 同步服务用的缓存,删了会自动重建,不会丢数据」。

不过把 AI 塞进清理软件,有三个问题必须先想清楚。

1. 发给 AI 的是什么?

只发元数据,不发文件内容。 具体是:路径(主目录换成 ~,不带用户名)、大小、类别、多久没用过。拼哪些字段由 Rust 后端决定,前端改不了。后端的测试会逐个字段检查,确保没有多发。

用户第一次用 AI 前必须先同意。这个检查也放在后端,不只是前端弹一个框。

2. AI 能不能「动手」?

Pika Clean 不内置模型,用的是你自己的 AI:

  • 本机装了 Claude Code,可以直接用;
  • 也可以填任何 OpenAI 兼容的服务,DeepSeek、通义、Kimi、OpenRouter、本机 Ollama 都行。API Key 只存在 macOS 钥匙串里。

调用 Claude Code 这类命令行工具,最大的风险是它本身能读写文件、执行命令。所以调用时:

bash 复制代码
claude -p --safe-mode --tools "" --no-session-persistence
  • --tools "":关掉全部工具,AI 只能返回文字;
  • --safe-mode:不加载用户自己的钩子、插件和 MCP 服务;
  • 在一个新建的空临时目录里运行,用完就删。

我本来也想支持 Codex,但实测我用的那个版本,在只读沙盒下仍然创建了文件,改文件的工具关不掉,所以暂时没接入。

这里还有个容易踩的坑:测试「工具有没有关掉」时,提示词里不能写「不要使用工具」。模型听话不用,会掩盖工具其实还能用的事实。

3. AI 说能删,就删吗?

不会。AI 只给建议,删不删永远由你确认。 即使是「一句话清理」,比如「帮我腾出空间,别动下载的文件」,AI 也只能返回类别名。后端会丢掉扫描报告里不存在的类别,结果只用来帮你勾选,最后还是要你点确认。

另外,AI 只在你点击时才调用,不会在后台偷偷消耗你的额度;同样的问题 30 天内直接走缓存。

三、删除:一个清理软件最该谨慎的地方

AI 只是锦上添花。一个清理软件真正的底线是:不能误删。

Pika Clean 把删除收得很紧:

  • 只有一个删除入口 。整个应用只有 backend/src/remove.rs 能删文件,其他模块一律不碰。
  • 前端不传路径。前端只传扫描报告里的条目编号,后端在自己保存的那份报告里查找对应的文件,查不到就拒绝。这样即使前端被注入了恶意代码,也删不了扫描报告之外的文件。
  • 删除前确认还是同一个文件。扫描时记下每个条目的设备号和 inode,删除前再核对一次,对不上就拒绝,免得同名的新文件被当成旧文件删掉。不看修改时间,因为缓存目录的修改时间一直在变。
  • 防路径逃逸 。条目的上级目录在解析掉符号链接和 .. 之后,必须仍然是扫描时的位置;条目本身是符号链接时只删链接。
  • 个人文件只进废纸篓。缓存、日志这类能重新生成的直接删;下载文件夹里的文件只移到废纸篓,还能一键「放回原处」,而且绝不覆盖已有的同名文件。
  • AI 工具开着时,不删它的缓存。清理 Claude、Cursor 这类工具的缓存前,先查它们是否在运行,在运行就跳过。

这些规则都有测试,全部在临时目录里跑,不碰真实的用户目录。后端目前有 158 个 Rust 测试。

四、为什么用 Tauri + Rust

清理软件要大量和系统打交道:遍历目录、读进程、读传感器、调钥匙串。Rust 做这些很合适,Tauri 让界面能用 React 写。

最直观的收益是体积:安装包大约 10 MB。

性能上也做了不少抠细节的事,举几个例子:

  • 菜单栏图标动画:最开始走常规的「设置图标」接口,每一帧都要重新编码、解码一次图片,实测让应用空闲时多占约 1.5% 的 CPU。改成缓存好图片对象直接切换后,这部分开销就没了。
  • 进程列表 :最开始用 sysinfo 库,它每一轮采样都会重读每个进程的命令行参数。改成直接问内核,每个进程每轮只做两次系统调用,名字和路径只在第一次见到这个进程时查。
  • 采样分档:菜单栏面板打开时才读温度、风扇这些;两个窗口都看不见时,采样间隔从 2 秒放宽到 5 秒,还跳过进程列表。
  • 数字和系统对齐:磁盘大小按 1000 进位(和「访达」一样),内存按 1024 进位、已用内存的算法和「活动监视器」一致。不然用户一对比就会觉得「这软件算错了」。

五、现在能做什么

  • 智能扫描与清理:缓存、日志、废纸篓、旧下载、崩溃转储
  • 卸载软件:连同偏好设置、缓存和支持文件一起删
  • 优化速度:释放内存、管理开机启动项
  • 菜单栏监控:CPU、GPU、内存、磁盘、网络、电池、温度、风扇
  • 开发者深度清理:Xcode、模拟器、Docker、包管理器,以及 Claude、Cursor 等 AI 工具的缓存
  • 空间去向:看清整个启动盘的空间都花在哪了
  • 界面支持简体中文、繁体中文、English、日本語、한국어

六、还没做好的

  • 还没有苹果开发者签名。第一次打开会被系统拦住,要到「系统设置 → 隐私与安全性」点「仍要打开」;如果提示「已损坏」,在终端执行:

    bash 复制代码
    xattr -cr "/Applications/Pika Clean.app"
  • 目前只支持 Apple 芯片的 Mac。

  • 刚开源,肯定还有不少 bug。

最后

如果你也被「这个文件到底能不能删」困扰过,欢迎试试:

欢迎提 issue、提 PR,也欢迎在评论区拍砖。我特别想知道:你清理 Mac 时最头疼的是什么?

相关推荐
古城小栈3 小时前
Rust 学习路线,供初学者参考
开发语言·rust
小熊吃保安1 天前
Windows也能用 Apple Watch 解锁
windows·rust·开源
离歌漠2 天前
《我用 Tauri 做了一个本地开发工具箱》
rust·typescript·vue
小小龙学IT2 天前
Python Polars 高性能数据处理引擎深度解析
开发语言·python·rust·1024程序员节
zzu123zsw2 天前
为什么 Python 做 Agent 总在并发中崩溃?拆解 Blockcell 在 Rust 下的 Host-Cell 隔离与自愈状态机
开发语言·python·rust·大模型·ai agent
hsg772 天前
简述:基于Ubuntu24编译发布rust开发的html+web后端服务的方法
rust·1024程序员节
zzu123zsw2 天前
当 GPU 加速渲染遇上无头组件:拆解 Yororen UI 在 GPUI 生态下的状态解耦与 XML 模板实践
xml·ui·rust·gui·gpui
传奇开心果编程3 天前
【Rust入门练中学】第6课:结构体与方法
开发语言·rust·结构体·编程语言理论·结构体方法·编程通用语言