巡检发现:
- 2196c77 workflow 整文件替换回退破坏(AiChat+Ideas 12项功能)
- B-260615-03 truncated 标志已落地
- AR-8-scroll scrollToBottom smooth 已补
- CR-260615-09 .ai-md 残余:4详情页各21处 scoped .ai-md
(全局 ai-md.css 75行已建,旧副本待清理但非阻塞)
5.9 KiB
5.9 KiB
AI 文件操作工具能力手册
最后更新:2026-06-15 | 基于全量测试验证
工具总览
| 工具 | 用途 | 可靠性 |
|---|---|---|
read_file |
读取文件内容(全文/分页) | ✅ 高 |
write_file |
创建/覆盖写入文件(纯文本) | ✅ 高 |
list_directory |
列出目录内容(含递归/深度控制) | ✅ 高 |
run_command |
执行 shell 命令 | ⚠️ 可执行,但 stdout 不可用 |
read_file
读取文件内容,支持分页。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path |
string | ✅ | 文件路径,支持 / 和 \ |
offset |
number | ❌ | 起始行(0 基索引),默认 0 |
limit |
number | ❌ | 读取行数,默认全部 |
行为规则
offset是 0 基索引:offset=0 → 第 1 行,offset=10 → 第 11 行offset超出总行数 → 返回空内容,不报错limit超出剩余行数 → 返回到末尾,不报错- 空文件 → 返回
{ content: "", lines: 0, size: 0 } - 不存在的文件 → 报错
os error 2 - 二进制文件 → 返回
{ binary: true, content: null, error: "文件非 UTF-8 文本" } - 路径越界(项目目录外)→ 被拦截
返回结构
{
"content": "文件文本内容",
"lines": 30, // 总行数(始终是全量值,非当前页行数)
"size": 145, // 总字节数(始终是全量值)
"path": "..."
}
⚠️
lines和size始终返回全量值,不受 offset/limit 影响。
write_file
创建或覆盖写入文件,纯文本模式。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path |
string | ✅ | 文件路径 |
content |
string | ✅ | 文本内容(UTF-8) |
行为规则
- 自动创建多级父目录:路径中不存在的目录会自动创建
- 覆盖已有文件:直接覆盖,无确认机制(⚠️ 注意安全)
- 返回
old_size(覆盖前大小,新建时为 null)和bytes_written(写入大小) - 支持 emoji、引号、反斜杠、中文等特殊字符
- 路径分隔符
/和\均可 - 中文路径/文件名含空格 → 正常工作
- 空内容(
content="")→ 创建 0 字节文件 - 无法写入二进制数据(NULL 字节等会被当文本处理)
- 路径越界(项目目录外)→ 被拦截
局部修改的正确做法
write_file 是全量覆盖,局部修改需三步:
1. read_file 获取完整内容
2. AI 在内存中替换目标行/文本
3. write_file 写回完整内容
list_directory
列出目录内容,支持递归和深度控制。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
path |
string | ✅ | 目录路径 |
recursive |
boolean | ❌ | 是否递归,默认 false |
max_depth |
number | ❌ | 递归最大深度(配合 recursive) |
skip_noise_dirs |
boolean | ❌ | 跳过 node_modules/.git 等,默认 false |
返回结构
{
"entries": [
{ "name": "src", "type": "directory", "size": 0, "depth": 0 },
{ "name": "main.ts", "type": "file", "size": 466, "depth": 0 }
],
"truncated": false
}
行为规则
type取值:"directory"|"file"depth:0 = 根层级,1 = 一级子目录,以此类推- 不存在的目录 → 报错
os error 3 truncated: false表示结果完整未截断
run_command
执行 shell 命令。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
command |
string | ✅ | shell 命令(非交互式) |
working_dir |
string | ❌ | 工作目录 |
timeout_secs |
number | ❌ | 超时秒数,默认 60 |
⚠️ 已知问题
stdout 始终返回空字符串(已确认是普遍问题):
echo、Write-Output等输出无法被捕获- 命令本身能正常执行(cp/mv/rm/重定向写文件均验证通过)
- stderr 大部分场景也为空
可靠使用的场景
| 场景 | 可靠性 | 示例 |
|---|---|---|
删除文件 rm |
✅ | rm -f path/to/file |
复制文件 cp |
✅ | cp src.txt dst.txt |
移动/重命名 mv |
✅ | mv old.txt new.txt |
创建目录 mkdir |
✅ | mkdir -p deep/nested/dir |
| 写入文件(重定向) | ✅ | echo content > file.txt |
二进制写入 printf |
✅ | printf '\x89PNG' > file.png |
| 超时控制 | ✅ | timeout_secs=3 正确中断 |
| 工作目录切换 | ✅ | working_dir 生效,相对路径可用 |
| 获取命令输出 | ❌ | stdout/stderr 不可用 |
快速参考:常见操作怎么做
| 我想要... | 工具调用 |
|---|---|
| 读文件全文 | read_file(path) |
| 读第 10~15 行 | read_file(path, offset=9, limit=6) |
| 创建新文件 | write_file(path, content) |
| 修改文件中某几行 | read_file → AI 替换 → write_file |
| 追加内容到文件末尾 | read_file → 拼接 → write_file |
| 删除文件 | run_command("rm -f path") |
| 重命名文件 | run_command("mv old new") |
| 列出项目结构 | list_directory(path, recursive=true, max_depth=3) |
| 搜索文件内容 | 分页 read_file 逐段扫描(无原生搜索) |
| 搜索文件名 | list_directory 递归 + AI 过滤(无原生 glob) |
| 写入二进制文件 | run_command("printf '\x89...' > file") |
| 获取文件大小/行数 | read_file(必须读内容,无轻量元信息工具) |
待实现能力(已建任务)
| 能力 | 任务 ID | 优先级 |
|---|---|---|
文件内容搜索 search_in_file |
F-FILE-01 | P1 |
文件局部更新 patch_file |
F-FILE-02 | P1 |
文件元信息 file_info |
F-FILE-03 | P1 |
| run_command stdout 修复 | F-FILE-07 | P1 |
追加写入 append_file |
F-FILE-04 | P2 |
文件名搜索 search_files |
F-FILE-05 | P2 |
| Base64 二进制写入 | F-FILE-06 | P2 |
文件差异对比 diff_file |
F-FILE-08 | P3 |