关于 ripgrep
面向开发 Agent 的代码搜索技能,将 ripgrep 与项目搜索命令结合,用于代码发现、精确匹配和按上下文读取。还提供项目结构梳理、Token 预算、压缩及编辑目标校验流程。
主要功能
- 01文本与语义混合搜索
- 02ripgrep 精确匹配
- 03项目结构与依赖关系图
- 04文件和目录 Token 估算
- 05搜索与压缩工作流
- 06自定义文件类型和忽略规则
适用场景
- 01查找与概念相关的代码
- 02定位某个符号的全部精确匹配
- 03重构前梳理依赖关系
- 04决定源码的读取范围
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ oimiragieo/ agent-studio --skill ripgrep安装后在 Claude Code 中输入/ripgrep确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
commands/ripgrep.mdhooks/post-execute.cjspre-execute.cjsreferences/.ripgreprcGUIDE.mdREADME.mdresearch-requirements.mdrules/ripgrep.mdschemas/input.schema.jsonoutput.schema.jsonscripts/main.cjsquick-search.mjssearch.mjstemplates/implementation-template.md详细介绍
Ripgrep 技能
使用 ripgrep 二进制文件增强代码搜索。注意:发现和排序,以及获取较小的输出载荷时,优先使用 `pnpm search:code`;需要最快的精确字面匹配时,优先使用原始 `rg`。 - 通过 `pnpm search:code` 进行混合代码搜索(BM25 文本 + 语义向量排序) - 使用原始 ripgrep 进行穷尽式模式扫描(返回每个匹配项,不限于排名前 N 项) - 高级正则表达式模式(使用 -P 标志启用 PCRE2) - 通过 .ripgreprc 自定义文件类型定义 - 与 .gitignore 和自定义忽略模式集成⚡ 推荐:混合代码搜索
日常代码发现请使用混合搜索系统:
- 文本搜索可立即使用,无需设置(基于 ripgrep 的 BM25)
- 语义搜索需要一次性构建索引:
pnpm code:index:reindex(使用 GPU 约 12 分钟,使用 CPU 约 17 分钟) - GPU 加速嵌入,使用 fastembed(自动检测 NVIDIA CUDA)
- 内存安全:嵌入在隔离的子进程中运行,以规避 ONNX Runtime 内存泄漏
- 混合评分:互惠排名融合(RRF)结合文本匹配和语义相似度
前置条件
# Build the semantic index (one-time, or after major codebase changes)
pnpm code:index:reindex
# Verify .env has embeddings enabled (should be default)
# HYBRID_EMBEDDINGS=on
# LANCEDB_EMBEDDING_MODE=fastembed
如果不构建索引,pnpm search:code 会退回到纯文本匹配。对于“authentication flow”这类概念查询,如果没有嵌入数据,搜索结果会很差。
搜索命令
# Project structure (directory tree + entry points + dependency graph + Mermaid)
pnpm search:structure
# Token budget analysis (file sizes + token estimates + refactor advice)
pnpm search:tokens .claude/lib # directory analysis
pnpm search:tokens path/to/file.cjs # single file analysis
# Semantic + text hybrid search (concept discovery, ranked results)
# Repeated/similar queries served from cache (~5ms hit vs ~800ms miss)
pnpm search:code "authentication logic"
pnpm search:code "export class User"
# One-shot search + compress + dedup pipeline (for large context tasks)
pnpm search:compress "how does routing work"
# Get file content with line numbers
pnpm search:file src/auth.ts 1 50
# Cache observability (daemon must be running)
pnpm search:code --cache-stats # view hits, misses, entries
pnpm search:code --cache-clear # flush cached results
pnpm search:structure — 了解各项内容的位置
**在进行任何编辑、重构或入门任务之前,请先运行此命令。**它会提供完整的地图:
- 目录树——最多显示 3 层深的文件夹层级(排除 node_modules、.git)
- 入口点——所有 ESM
export和 CJSmodule.exports声明,并附文件:行号引用 - 主要依赖项——导入次数最多的模块(包括
import和require)及其计数,分为:📦外部包(node:test、path、fs、child_process)📁本地模块(导入次数最多的内部文件——这些是架构热点)
- Mermaid 图表——可视化依赖关系图,包含:
- 显示各文件夹导出数量的目录子图
- 外部依赖子图
- 突出显示导入次数最多的本地模块作为枢纽节点
Agent 应如何使用:
- 编辑前:运行
pnpm search:structure,找到负责你需要修改的代码的目录 - 查找热点:计数最高的
📁本地依赖项是连接最多的模块——修改这些模块的影响范围最广 - 查找入口点:导出列表显示哪些文件公开了公共 API——从这里开始阅读
- 了解架构:Mermaid 图表显示哪些目录之间的关联最紧密
- 重构前:依赖计数可以告诉你重命名或移动会影响多少文件
pnpm search:tokens [path] — 了解上下文能容纳多少内容
**在决定如何读取文件或目录之前,先运行此命令。**它会告诉你:
- 每个文件和目录的 Token 估算值(约 4 个字符对应 1 个 Token)
- 可执行建议:直接读取、使用 offset/limit,还是改用 search:code
- 需要特殊处理的 最大文件
- 按 Token 大小排列的 目录排名 — 优先探索哪些子目录
# Check a specific file
pnpm search:tokens .claude/lib/memory/lancedb-client-impl.cjs
# Output: Size: 41.1KB | Tokens: ~10.5K | Advice: △ MEDIUM — use Read with offset/limit
# Check a directory
pnpm search:tokens .claude/lib
# Output: 333 files, 2.0MB, ~527K tokens (too large to read all — use search:code)
# Check the whole project
pnpm search:tokens .
# Output: 12478 files, 61MB, ~16M tokens with per-directory breakdown
Token 预算图例:
✓ OK(<8K Token)— 可以安全地用Read读取整个文件△ MEDIUM(8-32K)— 使用Read的offset/limit参数,或使用search:file⚠ LARGE(32-100K)— 优先使用search:code,而不是完整读取;仅阅读目标段落⚠ OVER(>100K)— 必须使用search:code或调用context-compressor技能
何时调用 context-compressor:
- 目录总量超过 100K Token,且你需要了解整个子系统
- 文件超过 32K Token,且你需要的是摘要,而非特定行
- 你正在构建的提示词会超出上下文窗口限制
重构建议 — 对于超过 15K Token 的源代码文件,该工具会建议拆分:
pnpm search:tokens .claude/hooks/routing
# Output includes:
# ✂ REFACTOR RECOMMENDED: user-prompt-unified.core.cjs (18.2K tokens)
# Split into ~3 modules of ~8K tokens each:
# user-prompt-unified.cjs — thin facade (re-exports)
# user-prompt-unified-impl.cjs — main logic
# user-prompt-unified-helpers.cjs — extracted helpers
这仅适用于源代码文件(.js、.cjs、.mjs、.ts、.py),不适用于数据文件或配置文件。拆分模式遵循代码库中已有的拆分方式(例如,routing-table.cjs → routing-table-data.cjs、index-manager.cjs → index-manager-operations.cjs)。
pnpm search:compress "query" — 一次性完成搜索和压缩
当 search:tokens 显示某个主题涉及超过 32K Token,且你需要压缩后的摘要时使用。
通过一条命令组合完整流程:
- 混合搜索会根据你的查询查找相关文件
- 读取实际文件内容(而不只是文件路径)
- 根据语料库大小自适应设置压缩比例(小型语料库为 0.8,超大型语料库为 0.1)
- 使用 Python 引擎的证据感知模式进行压缩
- 将提取的洞见与现有记忆(patterns.json、gotchas.json)去重
- 输出包含压缩后上下文和分类记忆记录的 JSON
pnpm search:compress "how does the routing system work"
# Returns JSON:
# {
# "ok": true,
# "search": { "query": "...", "hits": 20 },
# "compression": { "mode": "evidence_aware", "skeletonRatio": 0.5 },
# "memoryRecords": { "patterns": [...], "gotchas": [...], "issues": [...], "decisions": [...] },
# "dedupStats": { "total": 24, "kept": 18, "filtered": 6 }
# }
主要功能:
- 自适应压缩:小型语料库(< 8K Token)保留 80%,超大型语料库(>100K)仅保留 10%
- 记忆去重:不会重新保存记忆系统中已有的模式/注意事项
- 证据门控:使用
--fail-on-insufficient-evidence,如果查询未找到有力匹配项,则中止
自动优化(无需操作)
这些功能会在后台运行,无需执行任何命令:
查询缓存 — 重复或语义相似的 search:code 查询会从内存缓存中返回结果(约 5ms,而非约 800ms)。缓存使用余弦相似度(阈值:0.95),因此“路由系统”和“路由如何工作”会共用缓存结果。缓存条目在 5 分钟后过期。缓存驻留在守护进程中,确保跨查询持久保留。
BM25 自动更新 — 编辑文件时,BM25 文本索引会增量更新(每个文件约 10ms)。这意味着 search:code 始终反映最新更改,无需运行 code:index:reindex。只有文本索引会更新;语义嵌入需要完整重新索引。
缓存可观测性:
pnpm search:code --cache-stats # entries, hits, misses, hit rate
pnpm search:code --cache-clear # flush all cached results
搜索模式约定(确定性)
| 模式 | 使用场景 | 延迟 | 输出 |
|---|---|---|---|
pnpm search:structure | 第一步:了解项目布局,找到需要编辑的位置 | 快速 | 目录树 + 导出 + 依赖 + Mermaid |
pnpm search:tokens [path] | 阅读前:检查文件/目录是否适合纳入上下文 | 快速 | Token 估算 + 重构建议 |
pnpm search:code "query" | 概念发现,查找未知路径。自动缓存(重复查询约 5ms) | ~0.2-0.8s(首次),~5ms(缓存) | 精简排序的前 20 项 |
pnpm search:compress "query" | 大型上下文:一次完成搜索 + 压缩 + 去重 | ~2-5s | JSON:压缩后的上下文 + 记忆记录 |
rg -F "literal" | 精确查找符号/字面量,并在编辑前检查锚点 | 最快(约 35ms) | 所有匹配项(不排序) |
Grep(内置) | 审计时进行穷尽式模式扫描 | 快速 | 所有匹配项及上下文 |
必须遵循的选择行为:
- 首先:运行
pnpm search:structure了解情况——掌握目录布局和依赖热点。 - 检查大小:阅读前运行
pnpm search:tokens——确认文件是否适合纳入上下文。 - 然后:运行
pnpm search:code发现概念——查找与任务相关的文件。重复查询会自动缓存。 - 处理大型上下文:需要压缩理解宽泛主题时,运行
pnpm search:compress。它通过一条命令整合搜索 + 自适应压缩 + 记忆去重。 - 编辑前:运行
rg -F验证精确锚点——确认目标位置存在所需符号/函数。 - 审计时:使用
Grep(内置)进行穷尽式扫描——需要所有匹配项,而不只是前 N 项时使用。 - 编辑文件时,BM25 文本索引会自动更新(无需手动操作)。
fzf对人工参与的工作流仍为可选项;自动化流程不得依赖它。
编辑前先定位(Agent 的强制工作流)
在编写或编辑任何文件之前,Agent 必须先定位该文件。盲目编辑会浪费 token 并导致错误。
步骤 1 — 了解情况(每个任务运行一次):
pnpm search:structure
阅读输出,了解:
- 存在哪些目录及其内容
- 哪些模块被导入最多(计数较高的本地依赖
📁) - 公共 API 所在位置(入口点列表)
步骤 2 — 检查 token 预算(读取文件前):
# Is this file safe to Read in full, or do I need search:code?
pnpm search:tokens .claude/lib/memory/lancedb-client-impl.cjs
# Output: △ MEDIUM (10.5K tokens) — use Read with offset/limit
# How big is this directory? Can I read all files?
pnpm search:tokens .claude/lib/routing
# If >32K total → use search:code for discovery, don't try to read everything
步骤 3 — 发现(每个子任务执行一次):
# Find files related to your task concept
pnpm search:code "hook validation pre-tool"
这会返回与概念最相关的文件排名。记下文件路径。
步骤 4 — 精确定位(每次编辑前):
# Confirm exact symbol location with line numbers
rg -F "validateHookInput" -g "*.cjs" -n
# Read the file to understand context (use offset/limit for MEDIUM+ files)
pnpm search:file .claude/lib/utils/hook-input.cjs 1 50
步骤 5 — 检查影响范围(重构前):
# How many files import the module you're about to change?
rg -F "hook-input.cjs" -g "*.cjs" -c
# If 40+ files import it, consider backward-compatible changes
此工作流可避免:
- 在超出上下文容量的文件上浪费 token(先检查 token)
- 编辑错误的文件(不同目录中可能存在名称相似的文件)
- 重构时遗漏调用位置(
rg -c会显示准确计数) - 不清楚影响范围就破坏高导入量模块
- 不必要地触发上下文压缩(提前了解文件大小)
使用 fzf 交互式缩小范围(操作员体验)
当结果集较大时,使用 fzf 交互式缩小 rg/rga 的输出范围。
# rg + fzf + file preview
rg --line-number --no-heading --color=always "auth|token|session" . \
| fzf --ansi --delimiter ":" \
--preview "bat --color=always --style=numbers --highlight-line {2} {1}"
# rga (documents/archives) + fzf
rga --line-number --no-heading --color=always "invoice|receipt|policy" . \
| fzf --ansi --delimiter ":" \
--preview "bat --color=always --style=numbers --line-range=:300 {1}"
高级交互式 ripgrep 启动器模式:
: | rg_prefix='rg --column --line-number --no-heading --color=always --smart-case' \
fzf --ansi --disabled \
--bind 'start:reload:$rg_prefix ""' \
--bind 'change:reload:$rg_prefix {q} || true'
使用约定:
- 使用
fzf进行操作员选择和缩小范围,而不是将其用作搜索后端的替代品。 - 在 Agent 发现/排序工作流中,继续将
pnpm search:code作为默认选项。 - 使用
rg/rga+fzf进行交互式分诊和手动挑选结果。
结构化 + 交互式工作流(人工分诊):
# Structural candidates (ast-grep)
ast-grep -p 'function $NAME($$$) { $$$ }' --lang javascript --files-with-matches .
# Narrow candidates interactively
ast-grep -p 'function $NAME($$$) { $$$ }' --lang javascript --files-with-matches . \
| fzf --ansi --delimiter ":" \
--preview "bat --color=always --style=numbers --line-range=:220 {}"
工作原理
pnpm code:index:reindex构建 BM25 文本索引和 LanceDB 向量嵌入- 嵌入生成在隔离的子进程中运行(如果可用,则使用 GPU 加速)
- 子进程每 50 个批次重启一次,以回收 ONNX 原生内存泄漏
search:code首先检查查询缓存(命中约需 5ms);未命中时,查询 BM25 和向量索引- RRF 将文本和语义排序合并为一个有序结果集
- 结果会被缓存,以供后续相似查询使用(余弦相似度 > 0.95 即为缓存命中)
- 编辑后钩子会增量更新 BM25 文本索引(每个文件约需 10ms)
search:compress在一个流水线中结合搜索、自适应压缩和内存去重
配置
# Semantic search (default: on after running code:index:reindex)
HYBRID_EMBEDDINGS=on
# Embedding engine (fastembed recommended for speed + GPU support)
LANCEDB_EMBEDDING_MODE=fastembed
# Subprocess isolation for ONNX memory safety (default: on)
EMBED_SUBPROCESS=on
# Query cache (auto-caches repeated/similar queries)
SEARCH_CACHE_ENABLED=on # Kill switch: set to off to disable
SEARCH_CACHE_TTL_MS=300000 # Cache TTL: 5 minutes
SEARCH_CACHE_SIMILARITY=0.95 # Cosine threshold for semantic cache hit
# BM25 incremental update after file edits
BM25_INCREMENTAL_UPDATE=on # Kill switch: set to off to disable
# Disable semantic search (text-only, fastest, no index needed)
# HYBRID_EMBEDDINGS=off
# Daemon transport for repeated queries (cache lives here)
HYBRID_SEARCH_DAEMON=on
HYBRID_DAEMON_PREWARM=true
HYBRID_DAEMON_IDLE_MS=600000
# Query cache (caches repeated/similar queries by embedding similarity)
SEARCH_CACHE_ENABLED=on # set to off to disable
SEARCH_CACHE_TTL_MS=300000 # cache entry TTL (5 min)
SEARCH_CACHE_SIMILARITY=0.95 # cosine threshold for cache hit
# BM25 incremental update after file edits
BM25_INCREMENTAL_UPDATE=on # set to off to disable
守护进程 + 预热操作手册
# Start, verify, prewarm
pnpm search:daemon:start
pnpm search:daemon:status
pnpm search:daemon:prewarm
# Search (daemon path)
pnpm search:code "authentication logic"
# Stop daemon
pnpm search:daemon:stop
此代码库的预期延迟情况:
- 守护进程冷启动后的首次查询(未预热):平均约 1.35s
- 预热后的首次查询:平均约 0.40s
- 守护进程暖启动后的重复查询:约 0.18-0.19s
- 直接模式(
HYBRID_SEARCH_DAEMON=off):重复调用 CLI 平均约 0.73s
索引构建性能
| 指标 | 使用 GPU(RTX 4070) | 仅 CPU |
|---|---|---|
| 索引时间(2843 个文件) | 约 12 min | 约 17 min |
| 主进程内存 | 约 200MB | 约 200MB |
| 子进程内存(隔离) | 约 500MB | 约 300MB |
| 所需堆分配 | 4GB | 4GB |
| 磁盘上的索引大小 | 约 6MB(BM25)+ 约 10MB(向量) | 相同 |
实测性能和输出(此代码库)
在此代码库中使用相同的 5 个查询:
| 模式 | 平均延迟 | 平均输出字节数 | 最佳使用场景 |
|---|---|---|---|
pnpm search:code(HYBRID_EMBEDDINGS=off) | 约 227ms | 约 461 bytes | 快速发现并获得紧凑输出 |
pnpm search:code(HYBRID_EMBEDDINGS=on) | 约 734ms | 约 512 bytes | 语义/概念查询 |
原始 rg 字面搜索 | 约 35ms | 约 2478 bytes | 精确查找符号/字面内容 |
解读:
- 对于精确查找字面内容/符号,原始
rg速度最快 - 混合搜索返回的输出负载明显更小(通常能降低 token 压力)
- 嵌入可提升语义召回率,但会增加延迟
决策规则(实用版)
在以下情况下使用 pnpm search:code:
- 查询是概念性/自然语言内容(
"auth flow for refresh tokens") - 需要排序结果和适合 Agent 提示词的精简上下文
- 希望默认减少输出量
在以下情况下使用原始 rg:
- 查询是精确符号/字面内容(
TaskUpdate(、HybridLazyIndexer、精确导出名称) - 需要尽可能快地查找
- 需要高级正则表达式/PCRE2 行为
按文件大小测量(本仓库)
样本大小:4 个小文件(0.5-5KB)、4 个大文件(30-109KB),字面量 Token 查询。
| 分组 | search:code 关闭 | search:code 开启 | rg_repo | rg_file |
|---|---|---|---|---|
| 小文件 | ~230ms / ~2707B | ~600ms / ~2965B | ~34ms / ~17075B | ~15ms / ~1156B |
| 大文件 | ~228ms / ~2354B | ~475ms / ~2847B | ~35ms / ~17811B | ~15ms / ~6564B |
要点:
rg_file速度最快,最适合针对文件的检查。rg_repo仍是全仓库字面量扫描中最快的,但输出负载要大得多。search:code在不同文件大小下延迟更稳定,且通常能减少提示词用量的输出量。
真实场景操作手册(已测试模式)
使用以下场景模式,快速选择合适的搜索方式。
场景 1:事件分诊(根本原因未知)
目标:快速找到可能与生产环境问题相关的热点,同时避免上下文被大量结果淹没。
# 1) Start broad and semantic
pnpm search:code "task status not updating after completion"
# 2) Pivot to exact symbol checks once candidates appear
pnpm search:code "TaskUpdate("
模式:
- 从
search:code开始,获取意图层面的召回结果。 - 确认候选文件后,再用字面量或符号查询缩小范围。
场景 2:快速精确查找(已知标识符)
目标:尽可能快速定位精确的定义或用法。
# Repo-wide exact literal (stable example in this repo)
rg -F "TaskUpdate(" -g "*.cjs" -g "*.js" -g "*.ts" .
# Single-file exact lookup (fastest path)
rg -F "spawnSync" .claude/skills/skill-creator/scripts/create.cjs
模式:
- 使用原始
rg -F搜索精确符号,尤其是针对大文件或已知路径。
场景 3:安全重构准备
目标:在重命名或更改行为之前,枚举调用点并评估影响范围。
# 1) Check blast radius — how many files import this module?
pnpm search:structure
# Look at 📁 local deps: "📁 router-state (22)" = 22 files affected by changes
# 2) Gather broad callsites with semantic search
pnpm search:code "TaskUpdate completed status workflow"
# 3) Get EXACT callsite inventory (every match, not ranked)
rg -F "TaskUpdate(" -g "*.cjs" -g "*.js" -g "*.ts" -c
# Shows count per file — plan your edits across all files
# 4) Verify the specific lines before editing
rg -F "TaskUpdate(" -g "*.cjs" -n -C 2
模式:
- 先使用
search:structure检查依赖数量(影响范围)。 - 使用混合搜索查找可能遗漏的语义变体。
- 使用原始
rg -c统计每个文件中的精确调用点数量。 - 使用原始
rg -n -C 2获取行号和上下文,然后再进行编辑。
场景 4:安全审计扫描
目标:检测风险模式并确认精确且可信度高的匹配项。
对于穷尽式扫描(审计),请使用 rg 或 Grep(内置工具)作为主要工具。
混合搜索会返回排名靠前的前 N 个结果,适合发现线索,但可能遗漏匹配项。
安全审计需要某个模式的所有实例,而不是排名靠前的样本。
# EXHAUSTIVE sweep first (every match, not ranked)
rg -F "shell: true" -g "*.cjs" -g "*.js" -g "*.mjs"
rg -F "JSON.parse(" -g "*.cjs" -g "*.js" --no-heading
rg "eval\(|new Function\(" -g "*.cjs" -g "*.js"
rg -F "child_process" -g "*.cjs" -g "*.js"
# THEN use hybrid for concept discovery (find patterns you didn't think to grep for)
pnpm search:code "command injection shell execution security"
pnpm search:code "prototype pollution unsafe parsing"
# Verify specific findings with file-level rg
rg -F "exec(" .claude/lib/tools/standard-tools.cjs
模式:
- 对于重视完整性的穷尽式扫描(安全、合规),使用
rg/Grep。 - 使用混合搜索发现概念,寻找你此前不知道该用 grep 搜索的模式。
- 绝不要仅凭混合搜索排名靠前的前 N 个结果来断言安全问题。
场景 5:架构入门(新贡献者/Agent)
目标:了解项目结构并确定应在哪里进行修改。
# 1) Get the full project map (directory tree + exports + deps + Mermaid)
pnpm search:structure
# From the output, you'll see:
# - Directory tree: which folders exist and their nesting
# - Entry points: which files export APIs (with file:line)
# - Top dependencies: most-imported local modules (📁) = architectural hotspots
# e.g. "📁 memory-manager.cjs (56)" means 56 files import it — high blast radius
# - Mermaid diagram: visual module graph
# 2) Drill into subsystems by concept
pnpm search:code "routing guard task lifecycle"
pnpm search:code "memory scheduler session context"
# 3) Once you find candidate files, read them
pnpm search:file .claude/lib/routing/router-state.cjs 1 50
# 4) Before editing, confirm exact locations with rg
rg -F "resetToRouterMode" -g "*.cjs" -n
模式:
- 先使用
search:structure——动手之前先了解整体情况。 - 查看本地依赖数最高的
📁项——这些模块中的修改影响范围最广。 - 使用
search:code查找与目标概念相关的文件。 - 使用
search:file查看带行号的特定文件。 - 编辑前使用
rg -F确认精确的符号位置。
场景 6:代码库审计/深入分析
目标:系统地审计代码库中的 Bug、安全问题和死代码。
# 1) Map the project — identify architectural hotspots FIRST
pnpm search:structure
# Key things to note from the output:
# - 📁 local deps with high counts = audit priority (most connected = most risk)
# - Entry points list = public API surface to review
# - Directory tree = scope of what needs auditing
# 2) Exhaustive pattern sweeps with rg (need ALL matches, not top-N)
rg -F "JSON.parse(" -g "*.cjs" -g "*.js" --no-heading
rg -F "shell: true" -g "*.cjs" -g "*.js"
rg "eval\(|new Function\(" -g "*.cjs" -g "*.js"
rg "DEPRECATED|LEGACY|WARN" -g "*.cjs" -g "*.js" -g "*.mjs"
rg -F "catch" -A1 -g "*.cjs" | rg "^\s*\}" # empty catch blocks
# 3) Concept discovery for patterns you didn't think to grep
pnpm search:code "prototype pollution unsafe parsing"
pnpm search:code "race condition concurrent file write"
pnpm search:code "hardcoded secret credential password"
# 4) Cross-reference: find what calls a specific module
pnpm search:code "routing-table-intent"
rg -F "standard-tools" -g "*.cjs" -c # exact import count per file
# 5) Check for dead code: find exports that are never imported
# Compare entry points from search:structure against rg import counts
rg -F "orchestrator-tool.cjs" -g "*.cjs" -c # 0 results = dead module
模式:
- 先使用
search:structure识别热点(高导入量模块 = 审计优先项)。 - 使用
rg/Grep进行穷尽式扫描(安全、死代码、模式匹配)。 - 使用
search:code发现概念(查找此前不知道该用 grep 搜索的内容)。 - 将
search:structure的入口点与rg的导入计数交叉比对,以查找死代码。 - 绝不要仅依赖混合搜索来保证审计的完整性;它返回排名靠前的前 N 个结果,而非所有匹配项。
场景 7:受 Token 限制的 Agent 工作流
目标:在保持检索质量的同时,尽量减少提示词/上下文膨胀。
# Default: semantic search on (compact ranked output, good for agents)
pnpm search:code "workflow task completion guard"
# For fastest possible response when you know exact terms
HYBRID_EMBEDDINGS=off pnpm search:code "TaskUpdate completed"
# For intent-heavy queries where exact terms are unknown
pnpm search:code "why does the task get stuck after agent finishes"
模式:
- 默认使用
HYBRID_EMBEDDINGS=on(精简的排名结果本身就节省 Token)。 - 仅在精确关键词匹配已足够且速度至关重要时,才使用
HYBRID_EMBEDDINGS=off覆盖设置。 - 混合搜索的输出通常比原始
rg输出更短(排名靠前的前 N 个结果,而非所有匹配项)。
可复用查询模式
- 概念查询:
"authentication flow refresh token validation" - 混合查询:
"TaskUpdate completed status" - 精确查询:
"TaskUpdate("(对速度要求较高时,优先使用rg -F) - 结构查询:大规模编辑前使用
pnpm search:structure - 文件深入查询:
pnpm search:file <path> <startLine> <endLine>
仅在以下情况使用原始 ripgrep(如下):
- 高级 PCRE2 正则表达式模式(前瞻/后顾)
search:code不支持的自定义文件类型筛选- 与其他 CLI 工具进行管道集成
概述
此技能通过 @vscode/ripgrep npm 包提供对 ripgrep(rg)的访问,该包会自动下载适用于你平台(Windows、Linux、macOS)的正确二进制文件。它还增强了对现代 JavaScript/TypeScript 项目的文件类型支持。
二进制文件来源:@vscode/ripgrep npm 包(跨平台,自动安装)
- 自动处理 Windows、Linux、macOS 的二进制文件
- 无需手动管理二进制文件
可选配置:bin/.ripgreprc(若存在,将自动使用)
何时使用何种工具
| 工具 | 最适用于 | 权衡 |
|---|---|---|
pnpm search:code | 概念探索、排序结果、Agent 工作流 | 仅返回排名靠前的 N 项,并非穷尽;语义搜索需要索引 |
内置 Grep 工具 | 穷尽式模式扫描、审计、精确计数 | 返回所有匹配项;token 输出量更大 |
通过 Bash 使用原始 rg | PCRE2 正则表达式、管道集成、.ripgreprc 类型 | 需要 Bash 工具;原始输出较多 |
内置 Glob 工具 | 按名称模式查找文件 | 不支持内容搜索 |
用于审计和安全扫描:优先使用内置 Grep——它会返回每个匹配项,而非按排名返回前 N 项。你需要的是完整性,而非排名。
用于探索和入门:优先使用 pnpm search:code——输出精简且经过排序,具备语义理解能力,token 消耗较低。
编辑前精确查找符号:优先使用原始 rg -F——速度最快且结果确定。
快速入门命令
基本搜索
# Search for pattern in all files
node .claude/skills/ripgrep/scripts/search.mjs "pattern"
# Search specific file types
node .claude/skills/ripgrep/scripts/search.mjs "pattern" -tjs
node .claude/skills/ripgrep/scripts/search.mjs "pattern" -tts
# Case-insensitive search
node .claude/skills/ripgrep/scripts/search.mjs "pattern" -i
# Search with context lines
node .claude/skills/ripgrep/scripts/search.mjs "pattern" -C 3
快速搜索预设
# Search JavaScript files (includes .mjs, .cjs)
node .claude/skills/ripgrep/scripts/quick-search.mjs js "pattern"
# Search TypeScript files (includes .mts, .cts)
node .claude/skills/ripgrep/scripts/quick-search.mjs ts "pattern"
# Search all .mjs files specifically
node .claude/skills/ripgrep/scripts/quick-search.mjs mjs "pattern"
# Search .claude directory for hooks
node .claude/skills/ripgrep/scripts/quick-search.mjs hooks "pattern"
# Search .claude directory for skills
node .claude/skills/ripgrep/scripts/quick-search.mjs skills "pattern"
# Search .claude directory for tools
node .claude/skills/ripgrep/scripts/quick-search.mjs tools "pattern"
# Search .claude directory for agents
node .claude/skills/ripgrep/scripts/quick-search.mjs agents "pattern"
# Search all files (no filter)
node .claude/skills/ripgrep/scripts/quick-search.mjs all "pattern"
常见模式
文件类型搜索
# JavaScript files (includes .js, .mjs, .cjs)
rg "function" -tjs
# TypeScript files (includes .ts, .mts, .cts)
rg "interface" -tts
# Config files (.yaml, .yml, .toml, .ini)
rg "port" -tconfig
# Markdown files (includes .md, .mdc)
rg "# Heading" -tmd
高级正则表达式
# Word boundary search
rg "\bfoo\b"
# Case-insensitive
rg "pattern" -i
# Smart case (case-insensitive unless uppercase present)
rg "pattern" -S # Already default in .ripgreprc
# Multiline search
rg "pattern.*\n.*another" -U
# PCRE2 lookahead/lookbehind
rg -P "foo(?=bar)" # Positive lookahead
rg -P "foo(?!bar)" # Negative lookahead
rg -P "(?<=foo)bar" # Positive lookbehind
rg -P "(?<!foo)bar" # Negative lookbehind
筛选
# Exclude directories
rg "pattern" -g "!node_modules/**"
rg "pattern" -g "!.git/**"
# Include only specific directories
rg "pattern" -g ".claude/**"
# Exclude specific file types
rg "pattern" -Tjs # Exclude JavaScript
# Search hidden files
rg "pattern" --hidden
# Search binary files
rg "pattern" -a
上下文和输出
# Show 3 lines before and after match
rg "pattern" -C 3
# Show 2 lines before
rg "pattern" -B 2
# Show 2 lines after
rg "pattern" -A 2
# Show only filenames with matches
rg "pattern" -l
# Show count of matches per file
rg "pattern" -c
# Show line numbers (default in .ripgreprc)
rg "pattern" -n
PCRE2 高级模式
使用 -P 启用 PCRE2 模式,以使用高级功能:
前瞻和后顾
# Find "error" only when followed by "critical"
rg -P "error(?=.*critical)"
# Find "test" not followed by ".skip"
rg -P "test(?!\.skip)"
# Find words starting with capital after "Dr. "
rg -P "(?<=Dr\. )[A-Z]\w+"
# Find function calls not preceded by "await "
rg -P "(?<!await )\b\w+\("
反向引用
# Find repeated words
rg -P "\b(\w+)\s+\1\b"
# Find matching HTML tags
rg -P "<(\w+)>.*?</\1>"
条件表达式
# Match IPv4 or IPv6
rg -P "(\d{1,3}\.){3}\d{1,3}|([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}"
与其他工具集成
与 fzf 搭配(交互式搜索)
# Search and interactively select file
rg --files | fzf
# Search pattern and open in editor
rg "pattern" -l | fzf | xargs code
与 vim 搭配
# Set ripgrep as grep program in .vimrc
set grepprg=rg\ --vimgrep\ --smart-case\ --follow
与其他命令组成管道
# Search and count unique matches
rg "pattern" -o | sort | uniq -c
# Search and replace preview
rg "old" -l | xargs sed -i 's/old/new/g'
性能优化
大型代码库的技巧
- 使用文件类型筛选器:
-tjs比搜索所有文件更快 - 排除大型目录:
-g "!node_modules/**" - 尽可能使用字面字符串:
-F "literal"(禁用正则表达式) - 启用并行搜索:Ripgrep 默认使用所有核心
- 使用 .gitignore:Ripgrep 会自动遵循 .gitignore
基准测试
Ripgrep 通常:
- 比 grep 快 10–100 倍
- 比 ag(The Silver Searcher)快 5–10 倍
- 比 git grep 快 3–5 倍
自定义配置
位于 bin/.ripgreprc 的可选 .ripgreprc 文件(若存在)包含:
# Extended file types
--type-add=js:*.mjs
--type-add=js:*.cjs
--type-add=ts:*.mts
--type-add=ts:*.cts
--type-add=md:*.mdc
--type-add=config:*.yaml
--type-add=config:*.yml
--type-add=config:*.toml
--type-add=config:*.ini
# Default options
--smart-case
--follow
--line-number
框架专用模式
搜索 .claude 目录
# Find all hooks
rg "PreToolUse\|PostToolUse" .claude/hooks/
# Find all skills
rg "^# " .claude/skills/ -tmd
# Find agent definitions
rg "^name:" .claude/agents/ -tmd
# Find workflow steps
rg "^### Step" .claude/workflows/ -tmd
Agent Studio 常见搜索
# Find all TaskUpdate calls
rg "TaskUpdate\(" -tjs -tts
# Find all skill invocations
rg "Skill\(\{" -tjs -tts
# Find all memory protocol sections
rg "## Memory Protocol" -tmd
# Find all BLOCKING enforcement comments
rg "BLOCKING|CRITICAL" -C 2
</execution_process>
<best_practices>
- 使用文件类型筛选器(
-tjs、-tts)加快搜索 - 遵循 .gitignore 模式(默认自动遵循)
- 使用智能大小写进行不区分大小写的搜索(配置默认启用)
- 仅在需要高级功能时启用 PCRE2(
-P) - 使用
-g "!node_modules/**"排除大型目录 - 当模式不包含正则表达式时使用字面搜索(
-F) - 通过
@vscode/ripgrepnpm 包自动管理二进制文件 - 使用快速搜索预设执行常见的 .claude 目录搜索 </best_practices>
node .claude/skills/ripgrep/scripts/search.mjs "TaskUpdate" -tjs -tts
查找所有与安全相关的钩子:
node .claude/skills/ripgrep/scripts/quick-search.mjs hooks "security|SECURITY" -i
使用 PCRE2 搜索函数定义:
node .claude/skills/ripgrep/scripts/search.mjs -P "^function\s+\w+\(" -tjs
</usage_example>
二进制文件管理
搜索脚本使用 @vscode/ripgrep npm 包,它会自动:
- 检测你的平台(Windows、Linux、macOS)
- 在
pnpm install期间下载正确的二进制文件 - 处理所有架构变体(x64、ARM64 等)
无需手动管理二进制文件——npm 包会自动处理一切。
相关技能
铁律
- 务必先运行
pnpm search:structure,在执行任何编辑任务前了解项目布局——不了解目录结构和导入热点就进行编辑,会导致遗漏调用点,并带来影响范围方面的意外。 - 绝不使用排序后的混合搜索结果或 Top-N 搜索结果进行安全审计——审计必须确保完整性;应使用
rg或内置的Grep获取所有匹配项,而非排序后的样本。 - 务必在编辑代码前使用
rg -F验证精确的符号锚点——仅凭语义匹配进行编辑,会遗漏名称相似的函数并导致修改错误文件。 - 绝不让
fzf成为自动化或 Agent 工作流的阻塞依赖——交互式选择仅用于操作员体验;无人值守的 Agent 流程必须保持非交互且可复现。 - 务必使用文件类型筛选器或路径 glob 限定整个仓库的搜索范围——不加范围限制的搜索会将无关匹配项大量带入上下文,并增加令牌成本。
反模式
| 反模式 | 失败原因 | 正确做法 |
|---|---|---|
开始编辑任务前未运行 search:structure | 不了解目录布局会导致编辑错误的文件,并遗漏调用点 | 务必先运行 pnpm search:structure,了解目录层级和导入热点 |
| 使用混合搜索确保安全审计完整性 | 混合搜索返回排名靠前的前 N 个结果,而非所有匹配项;安全审计需要找到每个实例 | 使用 rg/Grep(穷举式)进行安全扫描;仅使用混合搜索发现概念 |
未用 rg -F 确认符号的确切位置就编辑代码 | 语义匹配会包含名称相似的符号;编辑了错误函数却不会有任何提示 | 进行任何代码编辑前,运行 rg -F "exact_symbol" 确认位置和调用点数量 |
将 fzf 设为 Agent 自动化流水线的必需步骤 | fzf 需要交互式输入;当流水线阻塞并等待用户选择时,Agent 无法继续 | 保持 fzf 为可选项,仅供操作人员使用;Agent 工作流必须使用确定性的 rg/search:code |
| 运行不限定范围的全仓库正则搜索 | 大型单体仓库会返回数千个匹配项,导致令牌成本飙升、上下文过载 | 运行全仓库模式前,务必使用 -g "*.cjs"、-tjs 或路径参数限定范围 |
记忆协议(强制)
开始前:
阅读 .claude/context/memory/learnings.md
完成后:
- 新模式 ->
.claude/context/memory/learnings.md - 发现问题 ->
.claude/context/memory/issues.md - 作出决策 ->
.claude/context/memory/decisions.md
假设任务可能中断:如果没有记录在记忆中,就等于没有发生。