两种搜索维度
| 维度 | 工具 | 底层实现 | 适用场景 |
|---|---|---|---|
| 按名称找文件 | Glob | ripgrep --files + glob 过滤 | ”找到所有测试文件”、“找 config 开头的文件” |
| 按内容找代码 | Grep | ripgrep 正则搜索 | ”哪里定义了这个函数”、“谁在调用这个 API” |
ripgrep 的内嵌方式
Claude Code 不依赖系统安装的 ripgrep——它在src/utils/ripgrep.ts 中实现了三级降级策略:
macOS 代码签名
vendor 模式下的 rg 二进制需要 ad-hoc 签名才能通过 Gatekeeper(codesignRipgrepIfNecessary()):
搜索结果的设计考量
head_limit 与 Token 预算
大型项目的搜索结果可能有数十万条。默认最多返回 250 条匹配——这不是随意选择,而是token 预算的约束:- 每条匹配行约 50-100 token
- 250 条 ≈ 12,500-25,000 token
- 这大约占 200k 上下文窗口的 6-12%
- 超过这个比例,AI 的推理质量会下降
head_limit 参数让 AI 可以按需调整——搜索小项目时可以用更大的值。
按修改时间排序
Glob 默认把最近修改的文件排在前面。这不是默认的文件系统排序,而是刻意的设计决策:src/tools/GlobTool/ 中,ripgrep 的输出在返回给 AI 前按 mtime 排序。
ripgrep 的错误处理
ripgrep 执行有专门的错误恢复链(src/utils/ripgrep.ts):
| 错误 | 处理 |
|---|---|
| EAGAIN(资源不足) | 自动以单线程模式 -j 1 重试 |
| 超时(默认 20s,WSL 60s) | 返回已有部分结果,丢弃可能不完整的最后一行 |
| 缓冲区溢出 | 截断到 20MB,返回已收集的结果 |
| SIGTERM 失效 | 5 秒后升级为 SIGKILL |
ToolSearch:在 50+ 工具中发现目标
当可用工具超过 50 个时(含 MCP 提供的外部工具),AI 可能不知道该用哪个。ToolSearch(src/tools/ToolSearchTool/)提供了工具发现机制。
搜索算法
ToolSearch 实现了基于关键词的加权搜索(searchToolsWithKeywords()):
select: 直接选择
AI 也可以用 select:ToolName 精确选择已知工具。这比搜索更快,且支持逗号分隔的批量选择(select:A,B,C)。
延迟加载(Deferred Tools)
不是所有工具都常驻内存。MCP 工具和低频工具被标记为isDeferredTool,只有在 ToolSearch 选中后才真正加载。这减少了每次 API 调用的 token 开销(工具描述占用大量 token)。
缓存策略
工具描述的获取是 memoized 的——只在延迟工具集合变化时清除缓存:Web 搜索与抓取
AI 的信息获取不局限于本地代码:- WebSearch:搜索互联网获取最新信息
- WebFetch:抓取特定网页内容,转换为 Markdown 供 AI 阅读
ripgrep 的流式输出
对于交互式场景(如 QuickOpen),ripgrep 支持流式输出(ripGrepStream()):