跳到正文

搜索工具精通指南

通过组合使用正确的工具,精通代码搜索与文档导航,实现最高效率

作者:Florian BRUNIAUX | 贡献者:Claude(Anthropic)阅读时间:约 25 分钟最后更新:2026 年 5 月


目录

  1. 快速参考矩阵
  2. 工具对比
  3. 决策树
  4. 组合工作流
  5. 真实场景案例
  6. 性能优化
  7. 常见陷阱
  8. 扩展工具集:scip-search 与 lilmd

快速参考矩阵

我需要…使用这个工具命令示例
查找精确文本rg(搜索工具)rg "authenticate" --type ts
按含义查找grepaigrepai search "user login flow"
查找函数定义Serenaserena find_symbol --name "login"
查找结构模式ast-grepast-grep "async function $F"
查看函数调用者grepaigrepai trace callers "login"
获取文件结构Serenaserena get_symbols_overview
跨文件重构Serena + ast-grep组合工作流
探索未知代码库grepai → Serena发现模式
无 MCP 时查找符号引用(工作树安全)scip-searchscip-search refs AuthService.login
导航大型 Markdown 文档lilmdlilmd read docs/arch.md "Authentication"

工具对比

完整功能矩阵

功能rg(ripgrep)grepaiSerenaast-grep
搜索类型正则/文本语义(含义)符号感知AST 结构
技术原理模式匹配嵌入向量(Ollama)符号解析抽象语法树
速度⚡ ~20ms🐢 ~500ms⚡ ~100ms🕐 ~200ms
安装配置✅ 无需(内置)⚠️ Ollama + 安装⚠️ MCP 配置⚠️ npm install
集成方式✅ 原生(Grep⚠️ MCP 服务器⚠️ MCP 服务器⚠️ 插件
隐私保护✅ 100% 本地✅ 100% 本地✅ 100% 本地✅ 100% 本地
所需上下文项目索引
支持语言所有(文本)所有TS/JS/Py/Rust/GoTS/JS/Py/Rust/Go/C++
调用图❌ 不支持✅ 支持❌ 不支持❌ 不支持
符号追踪❌ 不支持❌ 不支持✅ 支持❌ 不支持
会话记忆❌ 不支持❌ 不支持✅ 支持❌ 不支持
误报率极低极低
学习曲线

Token 消耗对比

工具典型查询消耗 Token返回结果
rg"authenticate"~500仅精确匹配
grepai"auth flow"~2000基于意图的匹配
Serenafind_symbol~1000符号 + 上下文
ast-grepAST 模式~1500结构性匹配

核心洞察:rg 的 Token 效率是语义工具的 4 倍,但智能度低约 10 倍。

扩展工具参考

以下两款工具填补了核心工具栈的空白,详见§ 扩展工具集:

工具类别与现有工具栈对比
scip-search符号索引搜索(SCIP)类似 Serena,但无状态、无需 MCP、工作树安全
lilmdMarkdown 章节导航工具栈中无对等工具(专注文档,非代码)

决策树

第一层:你知道什么?

Plain
你知道确切的文本/模式吗?

├─ 知道 → 使用 rg(ripgrep)
│  ├─ 已知函数名:rg "createSession"
│  ├─ 已知导入:rg "import.*React"
│  └─ 已知模式:rg "async function"

└─ 不知道 → 进入第二层

第二层:你在找什么?

Plain
你的搜索意图是什么?

├─ "按含义/概念查找"
│  → 使用 grepai
│  └─ 示例:grepai search "payment validation logic"

├─ "查找函数/类定义"
│  → 使用 Serena
│  └─ 示例:serena find_symbol --name "UserController"

├─ "按代码结构查找"
│  → 使用 ast-grep
│  └─ 示例:没有错误处理的 async 函数

└─ "理解依赖关系"
   → 使用 grepai trace
   └─ 示例:grepai trace callers "validatePayment"

第二层(工作树 / 无 MCP 环境)

在 CI 环境、git 工作树或任何 MCP 服务器不可用的场景下:

Plain
已知符号名,但无 MCP 可用?

└─ 使用 scip-search(预构建的 SCIP 索引,毫秒级冷启动)
   └─ scip-search refs "AuthService.login" --format json

第三层:优化

Plain
结果太多?

├─ rg → 添加 --type 过滤器或缩小路径范围
├─ grepai → 添加 --path 过滤器或使用 trace
├─ Serena → 按符号类型过滤(function/class)
└─ ast-grep → 为模式添加约束条件

组合工作流

工作流 1:探索未知代码库

目标:快速理解一个新项目

步骤说明

Bash
# 1. 语义发现(grepai)
# 查找与认证相关的文件
grepai search "user authentication and session management"
# → 输出:auth.service.ts, session.middleware.ts, user.controller.ts

# 2. 结构概览(Serena)
# 了解每个文件的结构
serena get_symbols_overview --file auth.service.ts
# → 输出:
#   - class AuthService
#     - login(email, password)
#     - logout(sessionId)
#     - validateSession(token)

# 3. 依赖关系映射(grepai trace)
# 查看 login 的使用情况
grepai trace callers "login"
# → 输出:被 UserController、ApiGateway、AdminPanel 调用

# 4. 精确搜索(rg)
# 查找具体实现细节
rg "validateSession" --type ts -A 5
# → 输出:完整函数及 5 行上下文

结果:4 条命令完成全面理解(相比读取 30+ 个文件)


工作流 2:大规模重构

目标:将 createSession 重命名为 initializeUserSession,涉及 50+ 个文件

步骤说明

Bash
# 1. 影响分析(grepai trace)
# 了解全部范围
grepai trace callers "createSession"
# → 输出:23 个文件中有 47 处调用
grepai trace callees "createSession"
# → 输出:调用了 validateUser、createToken、storeSession

# 2. 结构验证(ast-grep)
# 确保使用模式一致
ast-grep "createSession($$$ARGS)"
# → 输出:所有调用及其参数模式

# 3. 符号感知重构(Serena)
# 精确重命名
serena find_symbol --name "createSession" --include-body true
# → 获取精确定义 + 所有引用

serena replace_symbol_body \
  --name "createSession" \
  --new-name "initializeUserSession"
# → 跨所有文件重命名,保持结构完整

# 4. 验证(rg)
# 确认没有旧引用残留
rg "createSession" --type ts
# → 应返回 0 个结果

结果:在完全了解依赖关系的前提下安全重构


工作流 3:安全审计

目标:查找安全漏洞

步骤说明

Bash
# 1. 语义发现(grepai)
# 查找安全敏感代码
grepai search "SQL query construction"
grepai search "user input validation"
grepai search "password handling"

# 2. 结构模式(ast-grep)
# 查找特定漏洞模式

# SQL 注入风险
ast-grep 'db.query(`${$VAR}`)'

# XSS 风险
ast-grep 'innerHTML = $VAR'

# 缺少错误处理
ast-grep -p 'async function $F($$) { $$BODY }' \
  --without 'try { $$$TRY } catch'

# 3. 依赖追踪(grepai)
# 查看漏洞代码的调用位置
grepai trace callers "executeQuery"
# → 识别所有入口点

# 4. 精确验证(rg)
# 确认发现的问题
rg "innerHTML\s*=" --type ts
rg "password" --type ts | rg -v "hashed"

结果:在数分钟内完成全面的安全审计


真实基准测试

grepai vs grep(2026 年 1 月)

背景:在 Excalidraw(15.5 万行 TypeScript)上进行基准测试作者:YoanDev(grepai 维护者 — 存在潜在偏差)方法:5 个相同的代码发现问题

指标grepgrepai差异
工具调用次数13962-55%
输入 Token 数51k1.3k-97%

要点:语义搜索通过首次尝试即定位相关文件,避免了迭代探索,从而大幅减少 Token 消耗。

局限性

  • 由工具维护者进行的基准测试
  • 单一项目验证(仅 TypeScript)
  • 目前尚无独立验证

来源yoandev.co/grepai-benchmark

注意:本基准测试反映的是 2026 年 1 月的状态,随着 Claude Code 和 grepai 的更新,性能可能有所变化。


工作流 4:框架迁移

目标:将 React 类组件迁移至 Hooks

步骤说明

Bash
# 1. 清单(ast-grep)
# 查找所有类组件
ast-grep 'class $C extends React.Component'
# → 输出:34 个待迁移组件

# 2. 依赖分析(grepai)
# 了解组件间关系
for component in $(ast-grep 'class $C extends' --json | jq -r '.[].name'); do
  grepai trace callers "$component"
done
# → 确定迁移顺序(叶子组件优先)

# 3. 模式检测(ast-grep)
# 识别所使用的生命周期方法
ast-grep 'componentDidMount() { $$BODY }'
ast-grep 'componentWillReceiveProps($$) { $$$BODY }'
# → 映射到等效的 Hooks

# 4. 增量迁移(Serena + ast-grep)
# 逐个组件迁移
serena find_symbol --name "UserProfile" --include-body true
# → 获取完整组件代码

# 使用 ast-grep 进行转换
ast-grep --rewrite \
  --from 'class $C extends React.Component' \
  --to 'const $C = () => { }'

# 5. 验证(rg + grepai)
# 确认迁移成功
rg "React.Component" --type tsx  # 数量应减少
grepai search "component lifecycle methods"  # 查找遗漏项

结果:系统性迁移,破坏性最小


工作流 5:性能优化

目标:识别并修复性能瓶颈

步骤说明

Bash
# 1. 热点发现(grepai)
# 查找性能关键代码
grepai search "heavy computation or loops"
grepai search "database queries in loops"

# 2. 模式检测(ast-grep)
# 查找 N+1 查询模式
ast-grep 'for ($$) { await db.query($$) }'

# 查找缺少 memoization 的情况
ast-grep 'useMemo' --invert-match \
  --in 'const $VAR = $$$'

# 3. 调用图分析(grepai trace)
# 查找热点路径
grepai trace graph "renderUserList" --depth 3
# → 可视化依赖树

# 4. 符号追踪(Serena)
# 追踪函数变化
serena write_memory "perf_baseline" \
  "renderUserList: 450ms avg"

# 优化后
serena write_memory "perf_optimized" \
  "renderUserList: 45ms avg (10x improvement)"

# 5. 验证(rg)
# 确认优化已应用
rg "useMemo|useCallback" --type tsx

结果:数据驱动的性能改进


真实场景案例

场景 1:"我不知道我在找什么"

问题:新项目,没有文档,需要添加功能

解决方案:以语义搜索为先的发现策略

Bash
# 从宽泛的含义开始
grepai search "user profile management"
# → 发现相关文件

# 再通过结构缩小范围
serena get_symbols_overview --file user-profile.service.ts
# → 了解可用函数

# 最后精确搜索细节
rg "updateProfile" --type ts -C 3

场景 2:"这个函数到处都在调用"

问题:需要修改某个函数,但担心破坏其他地方

解决方案:先进行依赖关系映射

Bash
# 1. 查看所有调用者
grepai trace callers "calculateTotal"
# → 发现 47 处调用

# 2. 分析调用上下文
for file in $(grepai trace callers "calculateTotal" --json | jq -r '.[].file'); do
  serena get_symbols_overview --file "$file"
done

# 3. 识别安全与风险调用点
ast-grep 'calculateTotal($ARGS)' --json
# → 按参数模式分组

# 4. 有把握地进行修改
# 现在你已了解所有影响点

场景 3:"查找所有做 X 的代码"

问题:需要在代码库中应用统一的模式

解决方案:结合语义搜索 + 结构搜索

Bash
# 示例:查找所有错误处理代码

# 1. 语义发现
grepai search "error handling and exception management"

# 2. 结构模式
ast-grep 'try { $$$TRY } catch ($ERR) { $$$CATCH }'
ast-grep 'throw new Error($MSG)'

# 3. 验证一致性
rg "catch\s*\(" --type ts | wc -l
# 与 ast-grep 的计数对比,找出异常情况

场景 4:"我需要理解这个模块"

问题:复杂模块,职责不清晰

解决方案:多工具综合分析

Bash
# 1. 获取符号概览(Serena)
serena get_symbols_overview --file payment.module.ts
# → 查看所有导出、类、函数

# 2. 理解依赖关系(grepai)
grepai trace callees "PaymentModule"
# → 该模块依赖什么?

grepai trace callers "PaymentModule"
# → 谁使用了该模块?

# 3. 查找实现模式(ast-grep)
ast-grep 'export class $C' --file payment.module.ts
ast-grep 'async $METHOD($$$)' --file payment.module.ts

# 4. 读取具体实现(rg)
rg "processPayment" --type ts -A 20

性能优化

选择最快的工具

通用原则

  1. 已知精确文本 → 始终优先使用 rg
  2. 不知道精确文本 → 使用 grepai,然后用 rg 验证
  3. 重构 → 使用 Serena 确保符号安全
  4. 大规模迁移 → 使用 ast-grep 确保结构精确

性能基准测试

测试:在 50 万行代码库中查找认证代码

策略耗时结果质量
仅用 rg "auth"0.2s5000+ 误报
仅用 grepai "auth"2.5s50 个相关结果
grepai → rg(组合)2.7s50 个相关且已验证
仅用 Serena 符号1.5s12 个认证函数
ast-grep 模式3.0s8 个认证流程

最优方案:对已知函数名使用 Serena 符号(最快 + 高质量)

并行化策略

针对大型代码库(> 10 万行)

Bash
# 并行运行搜索

# 终端 1:语义发现
grepai search "authentication flow" > /tmp/grepai-results.json &

# 终端 2:符号索引
serena get_symbols_overview --file src/**/*.ts > /tmp/symbols.json &

# 终端 3:模式检测
ast-grep 'async function $F' --json > /tmp/ast-results.json &

# 等待全部完成,然后合并结果
wait
jq -s '.[0] + .[1] + .[2]' \
  /tmp/grepai-results.json \
  /tmp/symbols.json \
  /tmp/ast-results.json

常见陷阱

陷阱 1:用语义搜索查找精确匹配

错误做法

Bash
grepai search "createSession"  # 慢,大材小用

正确做法

Bash
rg "createSession" --type ts  # 快速、精确

原则:如果你知道精确文本,永远不要用语义搜索。


陷阱 2:用 rg 进行概念性搜索

错误做法

Bash
rg "auth.*login.*session" --type ts  # 会遗漏变体

正确做法

Bash
grepai search "authentication and session management"

原则:正则表达式不理解含义,请使用语义工具。


陷阱 3:重构前忽略调用图

错误做法

Bash
# 不检查调用者,直接重构
rg "oldFunction" --type ts | sed 's/oldFunction/newFunction/g'

正确做法

Bash
# 先检查影响范围
grepai trace callers "oldFunction"
# 发现 23 个文件中有 47 处调用
# 然后制定重构策略

原则:修改共享代码前,始终先追踪依赖关系。


陷阱 4:不组合使用工具

错误做法

Bash
# 复杂任务只用一种工具
ast-grep 'async function $F' --json | jq '.[].file' | xargs -I {} vim {}
# 不了解上下文,盲目编辑

正确做法

Bash
# 组合使用,全面理解
ast-grep 'async function $F' --json > /tmp/async.json
for file in $(jq -r '.[].file' /tmp/async.json); do
  serena get_symbols_overview --file "$file"  # 上下文
  grepai trace callers "$(jq -r '.[].name' /tmp/async.json)"  # 使用情况
done

原则:复杂任务需要多角度视角。


陷阱 5:简单搜索过度工程化

错误做法

Bash
# 仅为了找 TODO 注释而配置 grepai + Ollama
grepai search "TODO comments in the code"

正确做法

Bash
rg "TODO" --type ts

原则:使用能解决问题的最简单工具。


工具选择速查表

快速决策矩阵

你的情况使用这个不要用这个
"查找函数 login"rg "login"grepai search "login"
"查找与登录相关的代码"grepai "login flow"rg "login.*"
"安全地重命名函数"Serena find_symbolrg + sed
"谁调用了这个函数?"grepai trace callersrg + grep
"获取文件结构"Serena overviewrg "class
"查找没有 try/catch 的 async"ast-greprg "async.*{"
"迁移 React 类"ast-greprg + 手动操作
"查找 TODO"rg "TODO"其他任何工具

扩展工具集:scip-search 与 lilmd

这两款 CLI 工具填补了 rg/grepai/Serena 工具栈的空白。

scip-search 查询预构建的 SCIP(Sourcegraph 代码智能协议)符号索引。grepai 按语义含义搜索,Serena 需要实时的 MCP 连接,而 scip-search 则基于静态二进制索引运行,冷启动时间仅需毫秒。

属性详情
来源github.com/liza-mas/scip-search
安装`curl -fsSL https://raw.githubusercontent.com/liza-mas/scip-search/main/install.sh
索引格式SCIP(Go、TypeScript、Python、Java、Rust 等)
输出格式单行文本、JSON 或仅位置信息

工作流:scip-search 可替代符号发现时典型的 5-10 次 rg/读取往返操作。

Bash
# 步骤 1:每种语言生成一次 SCIP 索引
scip-typescript index --output index.scip

# 步骤 2:查找符号定义
scip-search find AuthService

# 步骤 3:获取所有引用及行号
scip-search refs AuthService.login --format json

# 步骤 4:仅读取返回的行范围

与 Serena 的对比:Serena 连接到语言服务器并具有会话记忆。scip-search 是无状态的,基于快照运行:无需 MCP,无需持久进程。这使其在工作树和临时 CI 环境中可靠运行,而 Serena 的 LSP 后端在这些环境中可能不可用。

与 grepai 的对比:grepai 按语义意图查找("支付验证逻辑")。scip-search 按精确或近似精确的符号标识符查找。两者可顺序配合使用:grepai 发现概念,scip-search 确认符号。

工作树兼容性:索引是每个仓库的文件,无共享状态。在工作树内运行 scip-typescript index 会为该工作树生成本地索引。


lilmd

lilmd 将 Markdown 文件视为数据库。它返回带有行范围的目录,并支持定向章节读取。智能体读取一篇 2000 行的指南时,只需一次调用即可获取某个章节,而不必读取整个文件。

属性详情
来源github.com/molefrog/lilmd
安装npm install -g lilmd
运行时Node 或 Bun

核心命令

Bash
# 带行范围的目录(含头尾,1 为起始行)
lilmd docs/architecture.md

# 按名称读取章节(默认模糊匹配)
lilmd read docs/architecture.md "Authentication"

# 读取嵌套章节
lilmd read docs/architecture.md "Security > JWT"

# 精确匹配(以 = 开头)
lilmd read docs/architecture.md "=Authentication Flow"

对智能体的特殊价值:目录输出包含每个标题的行范围。智能体解析这些信息后,只请求相关章节,而不是加载整个文件。自然的处理流程是:rg(找到哪个文件)→ lilmd(获取带范围的目录)→ Read lines:N-M(加载特定章节)。这同样适用于 CHANGELOG.md、大型 README 文件和知识库文档。

工作树兼容性:无状态,无索引,按文件运行。适用于任何环境。


安装优先级

推荐安装顺序

  1. 起步:rg(已内置于搜索工具)✅
  2. 下一步:Serena MCP(符号感知,会话记忆)
  3. 然后:grepai(语义搜索 + 调用图)
  4. 如果工作流涉及工作树:scip-search(无状态符号查找,无需 MCP)
  5. 针对大型文档:lilmd(定向 Markdown 章节读取,无需配置)
  6. 最后:ast-grep(结构模式,大规模重构)

理由:90% 的搜索用 rg + Serena 即可完成。语义需求时添加 grepai。工作树或 MCP 不可用的 CI 环境时添加 scip-search。仅在大规模重构时才添加 ast-grep。


总结:六工具工具箱

Plain
┌─────────────────────────────────────────────────────────┐
│                   搜索工具精通                           │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  rg(ripgrep)  →  快速、精确的文本匹配                 │
│  ├─ 适用:90% 的搜索场景                               │
│  └─ 速度:~20ms                                        │
│                                                         │
│  grepai         →  语义搜索 + 调用图                   │
│  ├─ 适用:概念发现、依赖追踪                           │
│  └─ 速度:~500ms(能找到 rg 找不到的内容)             │
│                                                         │
│  Serena         →  符号感知 + 会话记忆                 │
│  ├─ 适用:重构、结构理解                               │
│  └─ 速度:~100ms                                       │
│                                                         │
│  ast-grep       →  AST 结构模式                        │
│  ├─ 适用:大规模迁移、复杂模式                         │
│  └─ 速度:~200ms                                       │
│                                                         │
│  scip-search    →  符号索引(无状态,SCIP)             │
│  ├─ 适用:CI / 工作树 / 无 MCP 环境                   │
│  └─ 速度:~5ms 冷启动                                  │
│                                                         │
│  lilmd          →  Markdown 章节导航                   │
│  ├─ 适用:大型文档,带行范围的目录                     │
│  └─ 速度:即时,无需索引                               │
│                                                         │
│  ═══════════════════════════════════════════════════   │
│                                                         │
│  掌握工具组合,而非单一工具。                           │
│  每种工具都有其最适合的场景,选对工具才是关键。         │
│                                                         │
└─────────────────────────────────────────────────────────┘

延伸阅读


最后更新:2026 年 5 月兼容版本:Claude Code 2.1.7+


来源:飞书 · AI Spark 知识库 | 原文(最新版):https://lcnniolukk80.feishu.cn/wiki/EKWqwKydcirCzDk3WpOcKnjHnFg | 归档:2026-06-04