- AI 应用
- 大模型
- 本地部署
- 桌面应用
【免费下载链接】ai-file-sorter
Cross-platform desktop application for content-aware file organization and renaming. Supports local and remote LLMs, preview-based workflows, and fully user-controlled changes.
AI File Sorter是一款跨平台、内容感知的智能文件整理工具。本文完整解析它的Headless 无界面集成契约:逐条拆解CLI 命令行参数、机器可读的状态 JSON字段,以及防止多任务互相踩踏的运行时并发锁,帮你在资源管理器扩展或自动化脚本里安全地"无人值守"调用它。
如果你只想把它当 GUI 应用用,那 Headless 模式你可能用不上。但一旦要把它接进 Windows 资源管理器右键、CI 流水线、或你自己的批处理脚本,这套无界面契约就是"稳定接口"——你不需要点开任何窗口,只需要解析一段 JSON。
🧩 什么是 Headless 无界面模式
普通用户双击图标,看到的是主窗口、分类对话框、审查确认面板。而Headless(无界面)模式走的是另一条"中立于 UI"的入口:它不加载任何对话框,只负责
- 解析命令行参数;
- 抢占一把共享的运行时锁;
- 执行与 GUI 完全相同的分析工作流;
- 把每一步进度以JSON的形式打印到
stdout,并(可选地)写入一个状态文件。
💡 对集成者最重要的认知:把
stdout/ 状态文件里的 JSON 当作契约,stderr只当诊断日志。这一条在官方契约文档里被反复强调。
Headless 模式和 GUI 模式共用同一套分析引擎,所以你在 GUI 里看到的"整理前后"效果,命令行里也能 1:1 复现。
🚀 快速开始:一条命令跑通
下面这条命令会对一个文件夹做"分类 + 重命名",把状态写到status.json,并强制走审查流程(只出计划、不真正移动文件):
aifilesorter --headless \ --operation categorize-and-rename \ --path "/home/user/Downloads" \ --status-file "/tmp/aifs/status.json" \ --job-id "demo-001" \ --review-only跑完后你不会看到任何窗口,但status.json里会记录每一步状态,stdout也会同步打印。想先看"它打算怎么动我的文件",用--review-only就对了。
📋 CLI 参数速查表
完整用法(--headless-help也能打印):
Usage: aifilesorter --headless --operation <categorize|rename|categorize-and-rename> \ --path <file-or-folder> [--path <file-or-folder> ...] \ [--status-file <json-file>] [--job-id <id>] \ [--review-file <json-file>] [--review-only|--auto-apply] \ [--include-subdirectories|--no-include-subdirectories] \ [--settings-overrides-file <json-file>] aifilesorter --headless-apply --review-file <json-file> \ [--status-file <json-file>] [--job-id <id>]| 参数 | 作用 | 备注 |
|---|---|---|
--headless | 进入无界面分析模式 | 核心开关 |
--headless-apply | 直接应用一份已保存的审查计划 | 不重新跑分析 |
--headless-help | 打印用法说明 | 立即退出 |
--operation | categorize/rename/categorize-and-rename | 见下节 |
--path | 目标文件或文件夹 | 可重复出现多次 |
--status-file | 把状态 JSON 额外写到此文件 | stdout始终会有 |
--job-id | 任务标识 | 缺省自动生成 |
--review-file | 审查计划 JSON 路径 | 供--headless-apply使用 |
--review-only | 只出审查计划,不改文件 | 与--auto-apply二选一 |
--auto-apply | 跳过审查,直接应用 | 谨慎使用 |
--include-subdirectories | 扫描子文件夹 | 默认关闭 |
--no-include-subdirectories | 显式排除子文件夹 | |
--settings-overrides-file | 注入一次性的设置覆盖(JSON) | 不写回用户配置 |
参数值既可以用
--key value,也可以写成--key=value的内联形式,两种都能被识别。
三种操作模式
categorize:分类并按设置把文件移动到分类文件夹。rename:只应用重命名建议,不移动文件。categorize-and-rename:把上面两种合并成一份可审查的计划。
支持的目标范围
当前契约只接受两种形状:一个文件夹目标;或位于同一个父文件夹里的多个文件。跨文件夹的"搜索结果式"聚合暂不支持(属于后续版本)。传错形状会返回退出码4(不支持)。
🔄 审查与应用:默认"先看后动"
AI File Sorter 的哲学是用户完全掌控每一次变更。Headless 模式继承了这一点,默认不是"静默改写",而是"能出审查计划的工作流":
--review-only:强制只准备审查,不动任何文件;--auto-apply:明确选择"直接应用",适合你完全信任结果的自动化场景;- 都不传时,跟随应用里保存的设置。
一旦进入审查流程,程序会把计划写成一个审查计划文件(JSON),并在状态里告诉你它的路径(reviewFile)。等你(或你的脚本/界面)确认无误后,再用一条命令把这份计划"原样"应用下去:
aifilesorter --headless-apply \ --review-file "/tmp/aifs/status.review.json" \ --status-file "/tmp/aifs/status.json"--headless-apply不重新分析,只回放已批准的计划——这让"人在环中(human-in-the-loop)"的审批流变得既安全又可审计。
📄 状态 JSON 完整字段
每次状态更新(running/completed/failed/ …)都会输出一个 JSON 对象。核心字段如下:
{ "schemaVersion": 1, "status": "running", "operation": "categorize-and-rename", "jobId": "headless-1234-1700000000000", "message": "Headless command accepted and runtime lock acquired.", "error": "", "updatedAtUtc": "2026-03-11T17:43:22.123", "runtime": { "gpuBackend": "cuda", "llamaDevice": "cuda", "ggmlDisableCuda": "0" }, "paths": ["/home/user/Downloads"], "lock": { "owner": "headless", "pid": "1234", "jobId": "headless-1234-1700000000000", "startedAtUtc": "2026-03-11T17:43:22.123", "description": "Headless categorize-and-rename" } }字段速读:
| 字段 | 含义 |
|---|---|
schemaVersion | 状态结构版本,当前恒为1 |
status | 稳定状态值(见下表) |
operation | 本次操作(categorize等) |
jobId | 任务标识,可用于关联日志 |
message/error | 人类可读的状态 / 错误描述 |
updatedAtUtc | 本次更新的时间戳(ISO 8601) |
runtime | GPU 后端等运行环境信息(来自环境变量,存在才出现) |
paths | 你传入的目标路径列表 |
lock | 当前持有锁的元数据(见"并发锁"一节) |
进入"审查 / 应用"阶段后的额外字段
当流程推进到审查或应用时,状态里会追加一份变更明细,供你直接渲染进度条或清单:
{ "status": "review_required", "entryCount": 3, "entries": [ { "source": "/home/user/Downloads/photo1.jpg", "destination": "/home/user/Downloads/Images/20260311_090909.jpg", "fileName": "photo1.jpg", "destinationName": "20260311_090909.jpg", "category": "Images", "subcategory": "", "renameOnly": false, "moved": false, "renamed": false, "skipped": false } ], "movedCount": 0, "renamedCount": 0, "skippedCount": 0, "review": { "entryCount": 3, "requiresApproval": true, "entries": [ "…" ] }, "apply": { "movedCount": 0, "renamedCount": 0, "skippedCount": 0, "undoPlanSaved": false }, "reviewRequired": true, "reviewFile": "/tmp/aifs/status.review.json" }注意running阶段的更新里也可能夹带部分审查预览条目,让你在任务还没跑完时就能先展示"已出的中间结果"。
🚦 稳定状态值 与 退出码
status值 | 什么时候出现 |
|---|---|
running | 任务接受、正在分析 |
review_required | 已生成审查计划,等待批准 |
completed | 全部成功完成 |
failed | 通用失败 |
cancelled | 被停止标记取消 |
blocked | 被锁占用 / 缺 LLM 等前置条件挡住 |
进程退出码则用于脚本判断:
| 退出码 | 常量 | 含义 |
|---|---|---|
0 | Success | 成功 |
1 | Failure | 执行失败 / 被取消 |
2 | Usage | 参数错误、用法不对 |
3 | Busy | 运行时锁被占用,无法执行 |
4 | Unsupported | 目标形状不被支持 |
两个高频的blocked场景值得单独记一下:
① 锁被占用(另一个任务正在跑,退出码3):
{ "status": "blocked", "message": "Another analysis job is already running.", "lock": { "owner": "explorerWorker", "jobId": "explorer-job" } }② 还没有选 LLM(需要先去选模型,退出码1)——状态里会带上机器可读的"该做什么"提示:
{ "status": "blocked", "message": "AI File Sorter needs an LLM selection before this Explorer job can run. …", "actionRequired": "select_llm", "actionLabel": "Select LLM" }看到actionRequired: "select_llm"时,你的界面就知道该弹出"选择 LLM"入口了。
🔐 并发锁:AnalysisRuntimeLock
这是整篇里最容易被低估、也最关键的一节。GUI、资源管理器 Worker、Headless 三种入口共享同一把锁,保证同一时刻只有一个分析/变更任务在动 LLM、缓存和文件。
锁由两个文件构成,都放在"配置目录 /runtime"下:
- 锁文件
analysis-runtime.lock:由操作系统的QLockFile机制持有,真正的互斥主体; - 元数据旁挂文件
analysis-runtime.lock.json:记录"谁在锁着",供界面展示与过期锁恢复。
元数据长这样:
{ "owner": "headless", "pid": 1234, "jobId": "headless-1234-1700000000000", "startedAtUtc": "2026-03-11T17:43:22.123", "description": "Headless categorize" }其中owner的取值有gui/explorerWorker/headless三种,方便你一眼看出"现在被谁占着"。
过期锁自动恢复:如果持有锁的进程已经死了(通过pid探活 + 主机名比对判断),下次try_acquire会主动清掉死锁并重试,避免一次崩溃就把整个运行时"锁死"。
⚠️ 给集成者的忠告:不要假设能安全地对同一运行时并发跑多个分析/变更任务。撞上锁就拿到退出码
3+status: "blocked",正确姿势是排队或稍后重试,而不是绕过锁。
锁的实现见 AnalysisRuntimeLock.cpp,头文件里的Lease用 RAII 保证"拿到就释放、异常也释放",见 AnalysisRuntimeLock.hpp。
🛑 如何中途停止任务
如果任务在--status-file指定了状态文件,那么在状态文件旁创建一个同名的.stop标记文件即可请求停止。程序每 250ms 轮询一次这个标记,一旦发现就请求工作流停止,最终状态变为cancelled。
# 假设状态文件是 /tmp/aifs/status.json touch /tmp/aifs/status.json.stop # 发出"停止"信号这让"长任务可中断"在无人值守场景下也成了可能。
⚙️ 一次性设置覆盖(不改用户配置)
Headless 调用方经常想"这次用点不一样的行为",但不想污染用户已保存的设置。--settings-overrides-file就是干这个的:传入一个 JSON,它只对当前这一次运行生效,运行结束即丢弃,绝不写回配置。
字段都是"可选"的——不写的保持原样,写了的就覆盖本次运行。常用字段示例:
{ "useSubcategories": true, "includeSubdirectories": true, "allowedCategories": ["Images", "Documents", "Software"], "categoryLanguage": "en" }完整可覆盖的字段清单(分类/子分类、白名单、图片/文档按内容分析、是否仅重命名、语言等)见 HeadlessSettingsOverrides.hpp。这一机制是"集成专属行为"的推荐方式,官方配置文档也特别点名,见配置与环境。
🗂️ 典型集成场景
场景 A:资源管理器右键"一键整理"先--headless --review-only生成计划 → 把entries渲染成确认框 → 用户点头后--headless-apply应用。全程无人值守,且每一步都可审计。
场景 B:CI / 定时批处理加--auto-apply直接应用,用退出码0/1/2/3/4决定脚本是重试、告警还是跳过。缺 LLM 时读到actionRequired后发出"请配置 LLM"的工单即可。
场景 C:防冲突的并发调度用status.lock.owner和退出码3判断"是否有人在跑",把多个来源的任务天然串行化,不需要自己再造锁。
🔍 相关文件与源码索引
想深入源码时,按下面这些入口读最快:
- 契约总览:docs/headless-runtime-contract.md
- 命令解析与执行:HeadlessAnalysisCommand.cpp(
ExitCode定义见 HeadlessAnalysisCommand.hpp) - 状态 JSON 生成:HeadlessStatusJson.cpp
- 运行时锁:AnalysisRuntimeLock.cpp
- 设置覆盖字段:HeadlessSettingsOverrides.hpp
- Headless 入口分发:main.cpp
一句话总结:Headless 模式 = 一条 CLI 命令 + 一份状态 JSON + 一把共享锁。把它当"稳定接口"来用——stdout/状态文件是契约、--review-only保证先看后动、退出码3提示你排队——你就能在资源管理器扩展或自动化脚本里,安全、可审计地把 AI File Sorter 的能力接进自己的产品。
- AI 应用
- 大模型
- 本地部署
- 桌面应用
【免费下载链接】ai-file-sorter
Cross-platform desktop application for content-aware file organization and renaming. Supports local and remote LLMs, preview-based workflows, and fully user-controlled changes.
相关推荐
AI File Sorter 架构全景图:面向新手理解 UI、工作流与 Headless 集成的完整分层设计
AI File Sorter 架构全景图:面向新手理解 UI、工作流与 Headless 集成的完整分层设计 AI File Sorter 是一款跨平台的 AI
AI 应用大模型本地部署桌面应用本地模型 vs 远程 API:AI File Sorter 该选哪种方案?一文讲清
本地模型 vs 远程 API:AI File Sorter 该选哪种方案?一文讲清 AI File Sorter 是一款跨平台的 AI 文件整理桌面工具,能根据
AI 应用大模型本地部署桌面应用10 分钟跑通 DLSS Swapper:为指定游戏切换与回退 DLSS 版本
10 分钟跑通 DLSS Swapper:为指定游戏切换与回退 DLSS 版本 你卡在"DLSS 版本动不了"的那一刻 你刚装完一款支持 DLSS 的游戏,进设
桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考