Tools 工具组

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 的标准、只读、结构化搜索入口,是很多任务真正开始的第一步。