GlobTool:查找文件
这个工具看起来简单,但位置非常关键
GlobTool 做的事很直接:按文件名或通配模式找文件。
但在 Claude Code 的主循环里,它其实承担的是:
把“我大概知道要找什么文件”变成“我已经定位到候选路径”。
很多复杂任务的第一步,都不是直接读文件,而是先缩小范围。
GlobTool 就是这一步的标准入口。
先看它的输入定义
tools/GlobTool/GlobTool.ts:
const inputSchema = z.strictObject({
pattern: z.string().describe('The glob pattern to match files against'),
path: z.string().optional().describe('The directory to search in'),
})
这个 schema 很简单,但设计上很清楚:
pattern:用来表达“想找什么”path:用来限制搜索范围
也就是说,Claude Code 希望模型不要默认全仓库乱扫,而是学会缩小搜索半径。
它是读操作,而且是并发安全的
源码里这几个声明很值得注意:
isConcurrencySafe() {
return true
}
isReadOnly() {
return true
}
isSearchOrReadCommand() {
return { isSearch: true, isRead: false }
}
这说明系统从一开始就把 GlobTool 定义成:
- 只读
- 可并行
- 明确属于“搜索”类工具
这对主循环调度和 UI 展示都很重要。
一张图看它在搜索链里的位置
它不是简单的 find
GlobTool 内部并不是直接把 Bash find 暴露给模型,而是走自己的文件搜索实现:
import { glob } from '../../utils/glob.js'
这意味着:
- 搜索结果结构化
- 权限系统可感知
- 返回值更适合后续模型处理
这和 Bash 命令最大的不同是:
系统知道“你刚刚是在做文件发现”,而不是只看到一串 shell 输出。
它会校验 path 不是乱填的
validateInput() 里有一段很实际的逻辑:
if (path) {
const absolutePath = expandPath(path)
...
if (!stats.isDirectory()) {
return {
result: false,
message: `Path is not a directory: ${path}`,
}
}
}
这说明 GlobTool 很明确地区分:
- 路径是目录
- 路径不存在
- 路径写错了
甚至还会尝试给出 cwd 下的建议路径。
这类细节很像一个真正面向产品的工具,而不只是 SDK demo。
它还会主动限制结果规模
调用逻辑里有一个默认限制:
const limit = globLimits?.maxResults ?? 100
这说明 Claude Code 很清楚一个问题:
文件搜索如果不控量,很容易一次返回几百上千条结果,把上下文浪费掉。
所以 GlobTool 的目标不是“搜得越多越好”,而是“给主循环足够用的候选集”。
它和 GrepTool 的分工
这是最值得记住的一点:
GlobTool:我知道文件大概叫什么GrepTool:我知道文件里大概有什么文本
这两个工具经常被混着看,但从工程角度上它们代表的是两种不同搜索策略。
典型使用路径
最容易误解它的地方
误解一:有 Bash 的 find,Glob 就没必要
不对。
GlobTool 的优势恰恰在于结构化、可控、对主循环更友好。
误解二:Glob 只是 UI 更好看
也不对。
它会影响权限判断、上下文控制和后续工具选择。
误解三:它只是小工具,不重要
搜索工具往往看起来简单,但在 Claude Code 这种系统里,
“先找到正确文件”本身就是一条非常关键的主链路。
小结
GlobTool 的价值可以概括成一句话:
它把“按文件路径模式发现目标文件”做成了 Claude Code 的标准、只读、结构化搜索入口,是很多任务真正开始的第一步。