코딩 에이전트가 파일부터 뒤지는 날 — Graft로 탐색 비용을 앞당긴 실측
NanoNets Graft를 Astro 블로그 레포에 색인해 graft ask·grep으로 relatedSlugs 검증 위치를 찾은 과정. npm 전역 설치 실패와 로컬 클론 우회까지 포함한 디버깅 워크플로 회고.

AI에게 “이 버그 어디서 나는지 찾아줘”라고 하면, 응답이 오기 전에 이미 수십 개 파일을 열어보는 패턴이 반복된다. 프롬프트를 구조화해도 탐색 비용은 그대로였다. Notion «디버깅» 메모에 적어 둔 Graft를 이 Astro 블로그 레포에 직접 붙여 보고, “에이전트가 뒤지기 전에 지도를 깔아 두는” 방식이 실제로 통하는지 실측했다.
사실: 설치부터 막혔다
공식 설치 경로는 npm install -g nanonets/graft다. 클라우드 에이전트 VM에서는 전역 경로(/usr/lib/node_modules) 권한이 없어 EACCES로 바로 실패했다. Notion 메모에도 비슷한 사례가 있었는데, @types/node 누락으로 빌드가 깨지는 경우까지 겹친다.
우회는 단순했다.
git clone --depth 1 https://github.com/NanoNets/Graft.git /tmp/graft-test
cd /tmp/graft-test && npm install
cd /workspace && node /tmp/graft-test/dist/cli.js init --yes
init --yes 한 번에 Claude·Cursor용 MCP 설정과 graft build까지 돌아갔다. 이 레포는 TypeScript 소스가 많지 않아 그래프 규모는 12 nodes / 17 edges 수준이었다. 대형 모노레포에서 말하는 수만 노드와는 차원이 다르지만, “작은 레포에서도 동작하는가”를 확인하는 데는 충분했다.
이유: 그래프가 탐색을 앞당기는 지점
Graft는 코드베이스를 심볼·의존 관계 그래프로 색인하고, 에이전트가 graft ask, graft grep, graft callers로 필요한 조각만 가져오게 한다. 파일 전체를 컨텍스트에 넣지 않아도 “어디서 검증하는지” 같은 질문에 답할 수 있다.
실측 예시는 다음과 같다.
node /tmp/graft-test/dist/cli.js ask "relatedSlugs가 어디서 검증되는가" --source
# → content.config.ts, consts.ts, rss.xml.ts 3개 파일만 반환
# graft 출력: tokens saved ≈ 971 (95%)
node /tmp/graft-test/dist/cli.js grep "relatedSlugs"
# → src/content.config.ts L21: relatedSlugs: z.array(z.string()).min(2).max(3),
# graft 출력: tokens saved ≈ 133 (74%)
related-slugs-silent-drop 글에서 다룬 “존재하지 않는 슬러그가 조용히 빠지는” 이슈를 다시 추적할 때, 에이전트가 src/content/ 전체를 훑는 대신 스키마 정의 한 줄로 수렴했다. 디버깅 프롬프트만 고칠 때와 달리, 탐색 단계 자체가 짧아진다.
평가: 어디에 쓰고, 어디에 안 쓰는가
쓸 만한 경우
- 모노레포·다중 패키지에서 “이 함수 바꾸면 뭐가 깨지나”(
graft callers) - 에러 문자열 전수 검색(
graft grep) - PR diff가 닿는 범위(
graft blast) - Cursor·Claude Code에 MCP로 붙여 세션마다 자동 색인
기대를 낮춰야 하는 경우
- 이 블로그처럼 파일 수가 적은 정적 사이트 —
rg나 IDE 검색이 더 빠를 수 있다 - 지원 언어 밖(일부 설정·쉘만 있는 레포) — 노드 수가 거의 안 늘어난다
- 웹 챗봇만 쓰는 워크플로 — CLI·MCP 전제가 필요하다
- 색인 산출물(
.graft/등)을 팀과 공유하지 않으면 동료마다graft build를 다시 돌려야 한다
Notion 메모에 나온 “토큰 90% 절감”은 대형 코드베이스 기준에 가깝다. 여기서는 95%라고 찍혔지만 절대 토큰 수는 작다. 중요한 건 비율이 아니라 잘못된 파일을 덜 읽는다는 점이다.
부연: 에이전트 설정 파일은 커밋하지 않았다
graft init은 .claude/, .cursor/mcp.json, .mcp.json 등을 생성한다. 블로그 글 발행과 무관하고, 팀원마다 로컬 MCP 설정이 달라질 수 있어 이번 실행에서는 커밋 대상에서 제외했다. Graft를 팀 표준으로 쓸 때만 선택적으로 .claude/skills/graft 정도를 버전 관리에 넣는 편이 낫다.
앞으로 장애 회고를 쓸 때는 “프롬프트를 어떻게 썼나”와 함께 “탐색을 몇 파일로 줄였나”를 한 줄이라도 남길 계획이다. graft saved 로그가 그 증거가 된다.
출처
- 내부 실측:
/workspace에서node /tmp/graft-test/dist/cli.js init --yes,ask,grep(2026-08-24). 그래프 12 nodes / 17 edges, relatedSlugs 검증은src/content.config.tsL21. - Notion 시드: «디버깅» — Graft 설치 우회·명령 요약 (민감 경로·고객사 정보 제외).
- NanoNets/Graft — 공개 README·CLI (열람: 2026-08-24)