# opencode的7个基础工具——read、write、edit、multiedit、glob、grep、bash

> 发布于：2026-03-25 | 分类：技术教程 | 原文：https://www.imbailey.cn/post/opencode-7-basic-tools-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 策略，按顺序尝试**：

1. **SimpleReplacer**：精确匹配，一模一样才替换
2. **LineTrimmedReplacer**：忽略行首尾空格后匹配
3. **BlockAnchorReplacer**：用首尾行做锚点，中间部分相似度匹配
4. **WhitespaceNormalizedReplacer**：把多个空格/ tab 归一化成一种再匹配
5. **IndentationFlexibleReplacer**：缩进灵活匹配（允许不同深度的缩进）
6. **EscapeNormalizedReplacer**：处理转义字符（比如 `\n` 和真正换行的差异）
7. **TrimmedBoundaryReplacer**：裁剪边界后匹配
8. **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 的手变得越来越稳定。
