에이전트 코드 검색 전에 ripgrep을 쓰는 이유

에이전트에게 “이 심볼이 어디서 쓰이나?”만 던지면, 도구가 넓은 인덱스·시맨틱 검색·파일 열기를 반복하며 컨텍스트를 채웁니다. 그 전에 터미널에서 rg(ripgrep) 로 후보 경로·심볼을 잘라 두면, 에이전트 작업은 이미 좁힌 범위에서 읽고·고치고·검증하는 쪽으로 갑니다.

이 글의 축은 셋입니다. 왜 먼저 rg인가? · 에이전트 codebase search와 차이는? · 결과를 프롬프트에 어떻게 넣나? 요금·플랜·토큰 한도·제휴·창작 후기는 없습니다.

근거는 ripgrep GUIDE·rg(1) man의 ignore·glob·type 동작, 그리고 Cursor 등 에이전트 codebase search를 제품 UI로만 다루는 공개 설명입니다. 여기서는 검색 한도·요금을 지어내지 않습니다.

왜 먼저 rg인가?

한 줄 답: rg는 재현 가능한 CLI 필터입니다. .gitignore/.ignore/.rgignore를 기본으로 존중하고, -g/-t로 파일 집합을 사람이 통제한 뒤, 그 출력을 그대로 프롬프트·티켓에 붙일 수 있습니다.

에이전트만으로 “전체에서 찾아”를 반복하면:

  1. 범위가 대화마다 흔들립니다 — 같은 질문이라도 도구 선택·컨텍스트 잔량에 따라 열리는 파일이 달라질 수 있습니다.
  2. 노이즈가 컨텍스트를 먹습니다 — 벤더·생성물·무관한 확장자가 한 번에 들어오기 쉽습니다(별도 deny는 agent-deny-paths 축).
  3. 사람이 검증할 증거가 약합니다 — “어디를 봤는지”를 PR·이슈에 남기려면 명령어 + 출력이 가장 싸게 남습니다.

rg가 기본으로 건너뛰는 것(GUIDE 기준):

필터기본 동작
gitignore 계열.gitignore, .ignore, .rgignore 존중
hidden.으로 시작하는 파일·디렉터리 스킵
binaryNUL 등이 있는 바이너리 스킵
symlink기본은 follow 안 함(-L로 켜기)

자주 쓰는 범위 축소 예(공개 플래그만):

# 타입·글로브로 1st-party만
rg 'handleSubmit' -t ts -g '!**/*.test.*' -g '!dist/**'

# 경로를 PATH 인자로 더 좁히기
rg 'TODO|FIXME' packages/api/src -n -C 2

# 파일 목록만 (에이전트에 경로 리스트로 넘길 때)
rg -l 'FeatureFlag' -t py apps/

-u/-uu/-uuu는 ignore→hidden→binary를 단계적으로 풀 때입니다. “안 나온다”고 바로 -uuu부터 쓰지 말고, 의도한 소스 트리부터 좁히는 편이 에이전트 전처리에 맞습니다.

하지 말 것:

  • 에이전트에게 레포 루트만 주고 “알아서 검색”만 반복하기.
  • rg 없이 시맨틱 검색 결과만 믿고 패치 범위를 정하기.
  • ignore를 푼 채 node_modules까지 긁은 출력을 통째로 프롬프트에 붙이기.

에이전트 codebase search와 차이는?

한 줄 답: rg는 결정적·로컬·필터 우선 검색이고, 에이전트 codebase search는 제품 UI 도구(인덱스·시맨틱·다파일 탐색)입니다. 대체재가 아니라 전처리 → 에이전트 순서로 쓰면 됩니다.

축rg (CLI)에이전트 codebase search (제품 UI)
입력정규식·리터럴 + glob/type + PATH자연어·심볼·도구가 고른 쿼리
재현성같은 명령 → 같은 출력(워크트리 동일 시)대화·도구 경로·컨텍스트에 따라 달라질 수 있음
필터.gitignore 등 + -g/-t를 사람이 명시제품 ignore·인덱스 규칙(문서의 UI 동작)
산출물stdout 텍스트·경로 목록 → 티켓/프롬프트에 붙이기 쉬움채팅 안 요약·열린 파일 — 증거로 남기려면 별도 추출
역할후보 집합을 자른다잘린 집합 위에서 읽고 수정한다

제품 UI로서의 codebase search는 “비슷한 코드 찾기·관련 파일 열기”에 강합니다. 다만 검색 한도·인덱스 크기·요금은 플랜·시점에 따라 달라지므로 이 글에서 숫자로 단정하지 않습니다. 실무 규칙은 단순합니다.

  1. 문자열이 확실하면 먼저 rg (심볼명, 에러 메시지, feature flag 키).
  2. 이름이 모호하면 rg로 후보 디렉터리를 자른 뒤, 에이전트 검색·읽기를 그 경로 안으로 제한.
  3. 시맨틱이 필요할 때도 “레포 전체”가 아니라 packages/foo처럼 cwd/멘션 범위를 같이 줍니다(monorepo-agent-root 축).
# 사람이 범위 확정
rg -n 'AuthProvider' -t ts packages/web/src

# 그 결과 경로만 에이전트에 넘김 (개념)
# "Only these paths: … Edit login redirect. Do not search outside packages/web/src."

한 줄 원칙: codebase search는 탐색 UI, rg는 범위 계약입니다. 계약을 먼저 쓰고 UI를 그 안에 넣습니다.

결과를 프롬프트에 어떻게 넣나?

한 줄 답: rg 출력에서 경로·줄번호·짧은 컨텍스트만 남기고, 프롬프트에는 목표 + 허용 경로 + 금지 + 검증 명령을 고정 블록으로 넣습니다. 전체 덤프는 넣지 않습니다.

권장 파이프라인:

  1. 검색 — 패턴·-g/-t·PATH를 기록합니다.
  2. 축소 — -l로 파일 목록 → 필요 시 -n -C 2로 소수 파일만 컨텍스트.
  3. 프롬프트 블록 — 아래 템플릿에 붙여 넣습니다.
  4. 에이전트 — 허용 경로 밖 검색·수정을 하지 말라고 Rule/메시지에 명시합니다.
  5. 검증 — 같은 rg 또는 테스트로 전후를 비교합니다.

프롬프트 조각 예:

## Scope (from rg — do not widen)
Command: rg -n 'FeatureFlag\.BETA' -t ts -g '!**/*.test.*' packages/
Hits (path:line):
  packages/api/src/flags.ts:42
  packages/web/src/hooks/useFlags.ts:18

## Task
Change BETA default to false in api; update web hook consumer only.

## Constraints
- Do not search or edit outside the paths above.
- Do not open node_modules/, dist/, or .env*.
- After edit, re-run the same rg and summarize remaining hits.

## Done when
- rg shows only the intended call sites
- unit tests for flags still pass

출력을 넣을 때:

넣기빼기
path:line + 짧은 -C 스니펫node_modules·락파일·바이너리 히트
사용한 정확한 rg 명령“대충 전체에서 찾아봐”
허용/금지 경로 목록스크린샷만으로 범위 설명
재검증용 같은 명령관련 없는 이전 대화 전체
# 프롬프트용으로 파일 목록만
rg -l 'FeatureFlag\.BETA' -t ts packages/ | head -40

# 리뷰용 컨텍스트 (너무 길면 파일을 더 자른 뒤)
rg -n -C 2 'FeatureFlag\.BETA' -t ts packages/api packages/web

팁: 에이전트 규칙(AGENTS.md / Cursor Rule)에 한 줄로 고정할 수 있습니다.

Prefer: run rg with -g/-t to narrow paths before codebase search. Paste path:line hits into the task brief.

한 줄 정리: rg로 후보를 자르고 → path:line을 프롬프트 계약으로 넣고 → 에이전트는 그 범위만 고칩니다.

FAQ

Q. grep -r 대신 꼭 rg여야 하나요?
A. 필수는 아닙니다. 다만 ripgrep은 ignore·glob·type이 기본에 가깝고 출력이 에이전트 전처리에 맞습니다. 팀이 이미 git grep만 써도 같은 전처리 패턴이면 됩니다.

Q. 에이전트가 셸에서 rg를 직접 돌리면 되나요?
A. 가능합니다. 그래도 사람이 먼저 한 번 돌려 범위를 확정한 뒤, 에이전트에게는 “이 명령·이 경로만”을 주는 편이 재현에 유리합니다.

Q. -uuu는 언제 쓰나요?
A. ignore/hidden/binary를 의도적으로 풀 때입니다. 시크릿·벤더가 섞일 수 있으니 에이전트 프롬프트에 그 출력을 그대로 넣지 마십시오.

Q. 시맨틱 검색만으로 부족한 경우는?
A. 정확한 문자열·플래그 키·에러 코드처럼 리터럴이 있을 때입니다. 그때는 rg가 더 싸고 증거가 남습니다.

출처