# AI 文件操作工具手册 > 最后更新:2026-06-16 | 基于代码核对(`src-tauri/src/commands/ai/tool_registry.rs`) > > 本文档覆盖 AI 助手可调用的全部文件系统工具。项目/任务/灵感等 CRUD 工具见使用手册。 --- ## 工具总览 | 工具 | 用途 | 风险等级 | 需审批 | |------|------|----------|--------| | `read_file` | 读取文件内容(全文/分页/搜索) | Low | 否 | | `write_file` | 创建/覆盖写入文件(文本 + base64 二进制) | Medium | 是 | | `patch_file` | 局部更新文件(精确匹配替换) | Medium | 是 | | `append_file` | 向文件末尾追加内容 | Medium | 是 | | `file_info` | 获取文件元信息(不读内容) | Low | 否 | | `list_directory` | 列出目录内容(含递归/深度控制) | Low | 否 | | `search_files` | 按文件名模式搜索文件 | Low | 否 | | `rename_file` | 重命名/移动文件(Rust 原生,中文路径无障碍) | Medium | 是 | | `delete_file` | 删除文件(默认软删除可恢复) | High | 是 | | `run_command` | 执行 shell 命令 | High | 是 | > **路径安全**:所有文件工具走 `validate_path` 黑名单(禁止 `..` 路径遍历 + 敏感系统目录 `.ssh`/`.aws`/`.gnupg`)+ `resolve_workspace_path` 双层校验(词法 `starts_with` + `canonicalize` 防 symlink 逃逸)。文件操作限制在 workspace 目录内。 --- ## read_file 读取文件内容,支持分页和行内搜索。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 文件路径(workspace 内) | | `offset` | number | ❌ | 起始行(0 基索引),默认 0 | | `limit` | number | ❌ | 读取行数,默认 200,硬上限 2000 | | `search` | string | ❌ | 搜索模式:按行过滤含该子串的行(大小写敏感) | ### 行为规则 - `offset` 是 **0 基索引**:offset=0 → 第 1 行,offset=10 → 第 11 行 - `offset` 超出总行数 → 返回空内容,**不报错** - 文件大小上限 **1MB**,超出报错 - 二进制文件 → 返回 `{ binary: true, content: null }` - 不存在的文件 → 报错 ### search 模式返回结构 ```json { "path": "...", "size": 145, "search": "keyword", "matches": [{ "line": 12, "content": "匹配行内容" }], "total": 3, "has_more": false } ``` > `line` 为 **1 基行号**(与 offset 的 0 基不同)。最多返回 50 条匹配。 ### 默认(分页)返回结构 ```json { "path": "...", "content": "文件文本内容", "size": 145, "lines": 30 } ``` > `lines` 和 `size` 始终返回**全量值**,不受 offset/limit 影响。 --- ## write_file 创建或覆盖写入文件。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 文件路径 | | `content` | string | ✅ | 内容(UTF-8 文本 或 base64 编码) | | `encoding` | string | ❌ | `"utf-8"`(默认)或 `"base64"`(写二进制:图片/PDF/Excel) | ### 行为规则 - **自动创建多级父目录** - **覆盖已有文件**:覆盖前自动 `.bak` 备份(非空文件),原子写(tmp→rename),成功后清理 `.bak` - **疑似误覆盖检测**:新内容 < 旧内容 10% 时 warn 提示(防全量覆盖事故) - 写入大小上限 **1MB** - `encoding="base64"`:解码后写字节,支持二进制文件 - 返回 `old_size`(覆盖前大小,新建时为 null)和 `bytes_written` ### ⚠️ 局部修改请用 patch_file write_file 是全量覆盖。局部修改用 `patch_file`(精确匹配替换,无需重发整个文件)。 --- ## patch_file 局部更新文件,精确匹配 `old_text` 并替换为 `new_text`。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 目标文件路径 | | `old_text` | string | ✅ | 要替换的精确文本(必须完全匹配含空格/缩进) | | `new_text` | string | ✅ | 替换后的新文本 | | `line` | number | ❌ | 行号辅助定位(快速跳转 + 去歧) | | `expected_hash` | string | ❌ | 文件指纹防脏写(`"{mtime_secs}_{size}"`) | ### 安全机制(三层防御) | 层 | 机制 | 作用 | |----|------|------| | L1 | 文件级 Mutex | 防同文件并发写冲突 | | L2 | old_text 精确匹配 | 防内容错配(不匹配则报错,不修改) | | L3 | expected_hash 指纹 | 防版本漂移(文件被外部修改则拒绝) | | 兜底 | .bak 备份 | 误操作可恢复 | ### 返回结构 ```json { "path": "...", "changed": true, "size_diff": -42, "matches_found": 1, "diff": " context line\n-old line\n+new line\n", "warning": "匹配到 3 处,仅替换第 1 处" } ``` > `diff` 为行级 unified diff,供审批卡展示。多处匹配时仅替换第 1 处并返回 warning。 > 详见 [patch_file 使用指南](./patch_file使用指南.md) --- ## append_file 向文件末尾追加内容,文件不存在则自动创建。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 文件路径 | | `content` | string | ✅ | 追加的文本内容 | ### 返回结构 ```json { "path": "...", "bytes_written": 128, "new_size": 1024 } ``` > 避免 read-merge-write 竞态:日志追加/增量写入直接用此工具。 --- ## file_info 获取文件或目录的元信息,**不读取文件内容**。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 文件/目录路径 | ### 返回结构 ```json { "path": "...", "exists": true, "size": 145, "lines": 30, "modified": 1718400000000, "is_binary": false, "is_dir": false } ``` - `exists: false` 时其余字段不返回 - `lines`:文本文件 `\n` 计数(>2MB 跳过,二进制不返回) - `is_binary`:读前 8KB 检测 `\x00` --- ## list_directory 列出目录内容,支持递归和深度控制。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 目录路径 | | `recursive` | boolean | ❌ | 是否递归,默认 false | | `max_depth` | number | ❌ | 递归最大深度,默认 3 | | `skip_noise_dirs` | boolean | ❌ | 跳过 node_modules/.git/target,默认 **true** | ### 返回结构 ```json { "path": "...", "entries": [ { "name": "src", "type": "directory", "size": 0, "depth": 0 }, { "name": "main.ts", "type": "file", "size": 466, "depth": 0 } ], "truncated": false } ``` --- ## search_files 按文件名模式搜索文件(字符串包含匹配,非 glob)。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 搜索根目录 | | `pattern` | string | ✅ | 文件名匹配模式(子串包含) | | `recursive` | boolean | ❌ | 是否递归,默认 true | ### 返回结构 ```json { "path": "...", "pattern": ".ts", "results": [{ "path": "src/main.ts", "size": 466 }], "total": 5 } ``` > 最多返回 50 条。结构化 JSON 输出,比 parse `find` 命令更可靠。 --- ## rename_file 重命名或移动文件(一个工具覆盖 rename + move)。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `from` | string | ✅ | 源文件路径 | | `to` | string | ✅ | 目标路径 | | `overwrite` | boolean | ❌ | 目标存在时是否覆盖,默认 false(拒绝) | ### 行为规则 - **同卷**:`tokio::fs::rename`(原子操作,Windows 走 `MoveFileExW` UTF-16 API,**中文路径零字符集问题**) - **跨卷**:自动降级 `copy + remove`(非原子,失败回滚删 to 保 from 完整) - 仅支持文件(不支持目录,目录操作用 `run_command`) - 返回 `{ renamed, bytes_moved, cross_volume }` > **为什么不用 run_command mv**:run_command 走 shell.rs 的 PS/cmd 链,中文路径经 GBK 解码 UTF-8 会 mojibake → exit 0 静默失败。此工具 Rust 原生 std::fs 绕开整个 shell 层。 --- ## delete_file 删除文件,默认软删除(移入回收站可恢复)。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `path` | string | ✅ | 文件路径 | | `permanent` | boolean | ❌ | true=硬删除不可恢复,false(默认)=软删除移入 `.trash/` | ### 返回结构 ```json // 软删除 { "path": "...", "deleted": true, "permanent": false, "backed_up": true, "backup_path": ".trash/abc-file.md" } // 硬删除 { "path": "...", "deleted": true, "permanent": true, "backed_up": false } ``` - 仅支持文件(不支持目录) - 软删除文件移到 `workspace/.trash/-`,对齐 `list_trash` 机制 --- ## run_command 在指定工作目录执行 shell 命令。 ### 参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `command` | string | ✅ | shell 命令(非交互式) | | `working_dir` | string | ❌ | 工作目录(默认 workspace 根) | | `timeout_secs` | number | ❌ | 超时秒数,默认 60 | ### 返回结构 ```json { "command": "npm test", "working_dir": "...", "exit_code": 0, "duration_ms": 3200, "stdout": "测试输出...", "stderr": "", "truncated": false } ``` - stdout/stderr 各截断 10KB(尾部保留,报错堆栈在末尾) - `truncated: true` 表示输出被截断 ### 安全边界 - **High 风险**,强制人工审批(审批卡显示 command + working_dir) - 唯一防线:人审 + `validate_path` 黑名单 - 未做命令黑名单/网络检测/资源限制 ### ⚠️ 已知限制 - **中文路径**:shell.rs 在 Windows 走 PS/cmd 链,中文路径经 GBK 解码可能 mojibake → exit 0 静默失败。涉及中文路径的文件操作请用原生工具(`rename_file`/`delete_file` 等) - 非交互式:避免需要用户输入的程序 --- ## 快速参考:常见操作怎么做 | 我想要... | 推荐工具 | |-----------|---------| | 读文件全文 | `read_file(path)` | | 读第 10~15 行 | `read_file(path, offset=9, limit=6)` | | 搜索文件内关键词 | `read_file(path, search="keyword")` | | 创建新文件 | `write_file(path, content)` | | 修改文件中某几行 | `patch_file(path, old_text, new_text)` | | 追加内容到文件末尾 | `append_file(path, content)` | | 写入二进制文件(图片/PDF) | `write_file(path, base64_content, encoding="base64")` | | 重命名/移动文件 | `rename_file(from, to)` | | 删除文件 | `delete_file(path)` | | 获取文件大小/行数/类型 | `file_info(path)` | | 列出项目结构 | `list_directory(path, recursive=true, max_depth=3)` | | 搜索文件名 | `search_files(path, pattern=".ts")` | | 跑测试/构建 | `run_command("npm test")` |