opencode的7个基础工具——read、write、edit、multiedit、glob、grep、bash
做 AI 编程助手(或类似工具)的核心,就是怎么让 AI 正确地读写文件、执行命令。本质上,LLM 是个"脑子里有很多知识但手很短"的存在——它能推理,但没法直接摸到你的代码。于是需要一套工具,让它能够安全、可控地操作文件系统。
OpenCode(以及其他同类工具如 Claude Code、Cursor)把这套工具抽象成了 7 个核心 API。下面逐一拆解。
1. read — 统一的文件/目录读取入口
它是干什么的
一个字:只读。AI 想看代码,先走这个入口。
设计思想
一个工具同时处理文件和目录,通过检测文件类型来自动决定怎么展示。
文件读取方面:
- 支持分页,
offset和limit参数让 AI 可以"翻页"读大文件 - 自动给每行加上行号,方便 AI 定位(比如报错说"第 42 行有问题")
- 超长的行会自动截断,避免把整个终端撑爆
目录读取方面:
- 返回目录结构,树状展开
- 自动识别符号链接(快捷方式),不会当成普通文件处理
特殊格式(图片、PDF):
- 直接作为附件返回,用 Base64 编码,AI 看到的就是图片本身而不是乱码
- 二进制文件(非文本)通过采样检测,不尝试强行解码
一个有意思的细节:读取文件后会"假装碰了一下"文件(touch),这样会触发 LSP(Language Server Protocol)预加载——相当于提前告诉IDE"这个文件你该关注了",下次分析代码能更快。
核心原则
只读操作,不修改任何内容
2. write — 覆盖式写入 + 自动 diff 生成
它是干什么的
写入文件内容,全量覆盖。
设计思想
这个工具的设计非常谨慎,强调"先确认再执行,写入后验证"。
幂等性 + diff 确认:写入前,工具会对比旧内容和新内容,生成一个 unified diff(就是你在 git diff 里看到的那种格式),展示给用户看"哪里变了"。这样用户能明确知道 AI 想干什么,然后才授权执行。
写入后诊断:写完之后,立刻触发 LSP 诊断,返回当前文件的错误和警告。如果写入把代码写坏了,能马上知道。
事件通知:写入完成后发布一个 File.Edited 事件,其他模块(比如缓存管理器、依赖分析器)收到通知后可以同步更新状态。
核心原则
先确认再执行,写入后验证
3. edit — 智能替换 + 多策略兜底
它是干什么的
基于字符串匹配做局部替换——这是最常用的编辑工具。
设计思想
edit 的核心是 replace(oldString, newString):找到旧的字符串,替换成新的。
但问题是:AI 给出的 oldString 可能和真实代码有细微差别(比如多了几个空格、缩进不一样)。如果直接匹配不上就失败,用户体验会非常差。
所以这里设计了一整套 Replacer 策略,按顺序尝试:
- SimpleReplacer:精确匹配,一模一样才替换
- LineTrimmedReplacer:忽略行首尾空格后匹配
- BlockAnchorReplacer:用首尾行做锚点,中间部分相似度匹配
- WhitespaceNormalizedReplacer:把多个空格/ tab 归一化成一种再匹配
- IndentationFlexibleReplacer:缩进灵活匹配(允许不同深度的缩进)
- EscapeNormalizedReplacer:处理转义字符(比如
\n和真正换行的差异) - TrimmedBoundaryReplacer:裁剪边界后匹配
- ContextAwareReplacer:参考上下文判断是否匹配
简单说:如果精确匹配失败了,不要立刻放弃,换个策略再试试。这样能大幅提高 edit 的成功率。
另外还会自动检测原文件的换行符风格(\n 还是 \r\n),保持原样不动。
核心原则
精确替换,智能兜底,保留原格式
4. multiedit — 批量顺序编辑
它是干什么的
一次确认,执行多次 edit。
设计思想
内部其实就是循环调用 edit,但有一个关键约束:按顺序执行。每次 edit 都基于前一次 edit 之后的结果来继续。这样保证了多次修改之间不会互相干扰。
返回的结果只展示最后一次 edit 的输出和元数据。
核心原则
化零为整,一次确认多次修改
5. glob — 基于 Ripgrep 的模式匹配
它是干什么的
用 glob 模式(如 **/*.ts)搜索文件路径。
设计思想
很多新手实现 glob 可能直接用 fs.glob,但 opencode 选择用 Ripgrep 来做底层遍历。Ripgrep 是 Rust 写的高性能搜索工具,比 Node.js 的 glob 模块快得多。
额外做了几件事:
- 时间排序:搜索结果按修改时间倒序,最新的文件排在前面。AI 通常更需要关注新代码。
- 数量限制:默认最多返回 100 个结果,防止一次搜出几千个文件把上下文撑爆。
- 权限控制:搜索前请求 glob 权限,明确告知 AI 会访问哪些路径。
核心原则
高性能、结果可预期、限制输出
6. grep — 内容搜索 + 结果结构化
它是干什么的
在文件内容中搜索正则表达式。
设计思想
底层也是调用 Ripgrep(rg 命令),解析输出为结构化格式:filePath|lineNum|content。
同样按文件修改时间倒序排列。有意思的是容错处理:如果遇到 broken symlink(损坏的快捷方式),会忽略它继续搜;只有在前两层(文件读取和内容解析)都出问题时才真正失败。
核心原则
精准搜索,结构化输出
7. bash — 命令执行 + 静态分析 + 权限请求
它是干什么的
执行 shell 命令,比如 npm install、git commit、python run.py。
设计思想
这是最危险的工具——也是最需要谨慎设计的。
静态分析在先:执行命令前,先用 tree-sitter(一个代码解析库)解析命令文本,提取出会涉及哪些路径。比如 cd src && rm -rf *.log,能识别出涉及 src 目录。
权限预请求:把命令转换成权限模式(如 npm install → npm *),在执行前向用户请求 bash 权限和 external_directory 权限。明确告诉用户:我要执行这个命令,它会访问这些路径,你同意吗?
流式输出:命令的 stdout 和 stderr 实时流式返回,AI 能看到执行过程,有问题随时调整策略。
⚠️ 注意:bash 无法处理交互式输入(比如要求输入密码的
sudo命令、vim 编辑器等),这类场景需要特殊处理。
核心原则
分析先行,权限明确,安全执行
总结对比
| 工具 | 操作方式 | 核心特点 |
|---|---|---|
| read | 只读 | 统一入口,自动处理多种格式 |
| write | 覆盖 | 全量替换,diff 确认 |
| edit | 替换 | 多策略兜底,保留格式 |
| multiedit | 批量替换 | 复用 edit,顺序执行 |
| glob | 搜索 | 模式匹配,时间排序 |
| grep | 搜索 | 正则匹配,结构化结果 |
| bash | 执行 | 命令分析,权限预请求 |
这套工具设计的精髓在于:给 AI 足够的操作能力,同时用幂等性、diff 确认、权限预请求等机制把风险降到最低。没有哪家公司的 AI 编程工具是靠单一绝招成功的——都是在这些细节上慢慢打磨,让 AI 的手变得越来越稳定。



