# AI 에이전트

codebase-memory-mcp를 쓰면 토큰이 10배 준다는데, 과연 진짜일까?

@Hong2026-10-26

이 글에 담긴 코드와 결과는 직접 실행해 측정한 값을 바탕으로 작성했습니다. 실측은 Hong과 팀원들이 진행했고, 그 결과를 바탕으로 AI가 글을 쓰고 Hong이 검토합니다.

실습 코드 내려받기

질문
codebase-memory-mcp를 Claude Code에 붙이면 코드를 찾을 때 쓰는 토큰이 정말 10분의 1로 줄어들까?
답
질문 4개를 조건마다 3번씩 물은 24번에서 입력 토큰 중앙값은 46,556에서 55,468로 19% 늘었고, 그래프 도구는 12번 중 2번만 쓰였으며 정답은 두 조건 모두 12번 중 12번이었다.
조건
2026-10-25, Claude Code 2.1.309 claude -p, Opus 5.5, effort medium, codebase-memory-mcp 0.12.1, rich v15.0.0, 30번

환경

측정일
2026-10-25
도구
codebase-memory-mcp 0.12.1(MIT), 릴리스의 linux-arm64 정적 바이너리를 debian:bookworm-slim 이미지에 넣어 Docker로 실행
Claude Code
2.1.309, --model opus(결과 JSON modelUsage의 모델 ID는 모든 호출에서 claude-opus-5-5), --effort medium
데이터
Textualize/rich v15.0.0(커밋 6ac483c), 파일 553개, Python 파일 213개
반복
질문 4개 × 조건 2개 × 3번 = 24번, 조건별 워밍업 1번씩(집계 제외), 본 측정 뒤 도구 정의를 처음부터 싣는 보조 조건 4번
비용
구독 로그인으로 호출, 금액은 Claude Code가 API 목록 단가로 환산한 추정치(실제 청구액 아님)
목차
  1. codebase-memory-mcp가 하는 일과 공개 수치
  2. 실습 준비
  3. 실습 1: 영향 범위 질문 하나를 두 조건으로
  4. 실습 2: 질문 4개를 3번씩
  5. 실습 3: 도구 정의를 처음부터 모두 실으면
  6. 정리

이번 시간에는 코드 그래프를 MCP 도구로 내주는 codebase-memory-mcp가 Claude Code의 코드 탐색 토큰을 정말 줄이는지 claude -p로 측정하며 배워가는 시간입니다. claude -p는 대화 화면 없이 질문 하나를 보내고 결과를 받는 실행 방식이에요.

같은 질문을 기본 도구만 쓰는 조건과 도구를 붙인 조건에 번갈아 보내, 어떤 도구로 무엇을 읽었는지와 입력 토큰, 정답 여부를 볼게요. 다시 돌리면 숫자가 달라질 수 있고, --model opus가 가리키는 모델도 시간이 지나면 달라질 수 있어요.

codebase-memory-mcp가 하는 일과 공개 수치

codebase-memory-mcp는 저장소를 tree-sitter로 읽어 함수·클래스·호출 관계를 SQLite 그래프로 만들고, 에이전트가 MCP 도구 17개로 그 그래프를 조회하게 하는 C 바이너리예요.

README는 "The project's 31-repository preprint reports 10x lower token use and 2.1x fewer tool calls compared with file-by-file exploration"이라고 적어요. 출처인 논문(arXiv 2603.27277)은 Claude Opus 4.6으로 31개 저장소에서 그래프 도구 에이전트와 파일 읽기·grep 에이전트를 비교했고, 품질 점수는 그래프 쪽이 0.83, 파일 읽기 쪽이 0.92였어요(제1저자 단독 채점).

논문의 토큰 수치는 질문당 약 1,000 대 약 10,000이고 세는 방법은 적혀 있지 않아요. 요청마다 다시 읽는 입력 전체를 세는 이 글의 숫자와 같은 축은 아니고, 같은 축으로 비교할 수 있는 건 질문당 도구 호출 수(논문 2.3 대 4.8)예요.

실습 준비

이 글의 명령은 모두 실습 코드의 codebase-memory-mcp-graph/ 디렉터리에서 실행합니다.

  • lab.sh: 이미지 빌드, 저장소 받기, 설치 결과 확인, 설정 파일 만들기, 인덱스 생성, 측정 순서대로 claude -p 호출을 하위 명령으로 나눈 스크립트
  • summarize.py: 호출 결과(stream-json)를 읽어 정답을 판정하고 도구 호출·토큰을 모으는 스크립트
  • answers.json: 질문 4개와 정답 목록

따라 하시려면 Apple Silicon Mac(이미지가 linux-arm64 바이너리를 받아요), Claude Code 2.1.309와 구독 로그인, Docker, jq, curl이 필요해요. Claude가 Bash로 Mac의 python3를 부르는 회차도 있었어요.

공식 설치는 curl -fsSL https://raw.githubusercontent.com/DeusData/codebase-memory-mcp/main/install.sh | bash예요. 바이너리를 받은 뒤 install이 Claude Code 같은 에이전트 설정에 MCP 서버·훅·스킬을 등록합니다.

여기서는 Mac에 아무것도 설치하지 않으려고 바이너리를 컨테이너 하나에 넣고, 설치기가 쓰는 파일은 프로젝트 범위 설정으로 옮겼어요. MCP 서버·훅·CLI는 같은 바이너리와 캐시를 써야 해서 모두 그 컨테이너에 docker exec로 들어가요.

py312는 Python 스크립트를 컨테이너에서 돌리고, excerpt는 결과 JSON에서 턴·시간·비용·usage만 뽑아요. 아래 블록은 파일로 만들지 말고 실습 디렉터리에서 연 터미널에 그대로 붙여 넣어 주세요. 이후 명령은 모두 이 터미널에서 실행하고, 터미널을 새로 열면 다시 붙여 넣으시면 됩니다.

py312() { docker run --rm -v "$PWD":/w -w /w python:3.12-slim python -I "$@"; }

excerpt() { jq 'select(.type == "result") | {num_turns, duration_ms, total_cost_usd, usage: (.usage | {input_tokens, cache_creation_input_tokens, cache_read_input_tokens, output_tokens})}' "$@"; }

./lab.sh image는 v0.12.1의 codebase-memory-mcp-linux-arm64-portable.tar.gz를 릴리스 checksums.txt의 SHA-256으로 확인하며 받아 이미지를 만들어요. ./lab.sh repo는 rich v15.0.0 커밋의 소스 묶음을 받고 체크섬을 찍습니다(발췌).

chmod +x lab.sh
./lab.sh image
./lab.sh repo
6558836705014286f6e56af8109e5efdbbe5622217cc336a77d2aec25314106c  cache/rich-6ac483c.tar.gz

./lab.sh install_probe는 네트워크 없는 컨테이너 안의 빈 홈 디렉터리에서 공식 install -y --clients=claude를 돌리고, 만들어진 파일을 gen/probe/로 꺼내 목록을 찍어요. 설치기는 ~/.claude.json의 MCP 서버, ~/.claude/settings.json의 훅, 스킬 1개, 에이전트 정의 3개처럼 모두 사용자 범위에 쓰고 CLAUDE.md는 건드리지 않아요.

./lab.sh install_probe

./lab.sh setup은 이 내용을 측정용 파일로 옮깁니다.

  • gen/mcp-tool.json: MCP 서버를 docker exec -i로 띄워요. 설치기의 에이전트 정의가 mcp__codebase-memory-mcp__* 도구 이름을 적어 두어서, 서버 이름도 설치기와 같은 codebase-memory-mcp로 뒀어요.
  • gen/settings-tool.json: 설치기와 같은 PreToolUse Grep|Glob|Bash, PostToolUse Read 훅에, SessionStart는 claude -p에서 도는 startup만 걸었어요(제한 시간 5초). 명령은 docker exec로 hook-augment를 부르고 출력을 기록하는 gen/hook.sh예요.
  • gen/bin/codebase-memory-mcp: 설치기가 CLI를 PATH에 두는 것처럼 도구 조건에서만 PATH에 넣는 docker exec 래퍼예요.
  • 스킬 SKILL.md는 호출마다 저장소 복사본의 .claude/skills/에 넣어요. 에이전트 정의 3개와 SubagentStart 훅은 Task 도구를 두 조건 모두 쓰지 않아 뺐어요.

./lab.sh start는 --network none, 메모리 3GB, CPU 2.5개로 컨테이너를 띄우고 파일 감시를 끈 뒤, 프로젝트 이름을 --name rich로 짧게 정해 인덱스를 만들어요. 훅 명령 hook-augment는 데몬이 없으면 아무것도 내지 않아서, 마지막 daemon start로 데몬을 계속 띄워 둡니다.

./lab.sh setup
./lab.sh start
gen/ 준비 완료
Completed index_repository (3966 ms)
"project":"rich"
"nodes":12652,"edges":27824
"status":"indexed"
28442624 /cbm-cache/rich.db
daemon: started (permanent, pid 118)

인덱스는 4초(3,966ms), 노드 12,652개, 엣지 27,824개, 28MB였어요. 생성과 조회가 모두 네트워크 없는 컨테이너에서 끝나서, 도구가 따로 코드를 LLM·임베딩 API로 보낼 길은 없었어요. 인덱스가 컨테이너 안에 있어 저장소에는 스킬 파일만 생겨요.

실습 1: 영향 범위 질문 하나를 두 조건으로

함수 하나의 시그니처가 바뀌면 직접 영향받는 곳을 찾는 질문이에요. 정답은 함수 12개이고, summarize.py가 답에서 함수 이름과 파일 이름이 가까이 나오는지로 판정해요.

jq -r .q2.question answers.json
rich 저장소에서 `rich/_loop.py`의 `loop_last` 시그니처나 반환 형태가 바뀌면 직접 영향받는 모듈과 함수를 모두 찾아 줘. tests와 docs는 제외. 코드는 수정하지 마.

lab.sh에서 claude -p를 부르는 부분이에요(발췌).

  (cd "work/$dir/rich" && env PATH="$path" CBMLAB_LOG="$ROOT/out/$name.hook.log" ${ts:+ENABLE_TOOL_SEARCH=$ts} \
    perl -e 'alarm shift; exec @ARGV' 900 \
    claude -p "$q" \
      --tools "Bash,Read,Grep,Glob,ToolSearch,Skill" --allowedTools "$allow" \
      --model opus --effort medium \
      --setting-sources project --settings "$ROOT/gen/settings-$dir.json" \
      --strict-mcp-config --mcp-config "$ROOT/gen/mcp-$dir.json" \
      --no-session-persistence --include-hook-events \
      --output-format stream-json --verbose \
      < /dev/null) > "$out" 2> "out/$name.err"

두 조건은 도구 목록, 모델, effort, 질문 문구가 같고, 호출마다 저장소를 새로 풀며 작업 경로 길이(work/base/rich, work/tool/rich)도 같아요. 도구 조건에만 위의 설정 파일과 스킬, PATH 앞의 gen/bin, 그리고 --allowedTools의 mcp__codebase-memory-mcp가 더해져요. claude -p는 허용하지 않은 MCP 호출을 거부하기 때문이에요.

도구 목록에 ToolSearch가 있어 MCP 도구 17개의 정의는 모델이 도구 검색으로 불러올 때만 실려요. Claude Code 기본 동작이고, 자세한 건 MCP 도구 200개, Claude tool search는 맞는 도구를 고를까?에서 다뤘습니다.

./lab.sh run은 워밍업 2번(w1, w2)과 측정 24번을 질문·조건을 고르게 섞은 순서로 돌려요(약 12분).

./lab.sh run

기준 조건 2회차와 도구 조건 6회차가 부른 도구를 순서대로 볼게요(화살표 뒤는 결과 글자 수).

py312 summarize.py show 02-q2-base
py312 summarize.py show 06-q2-tool
1. Grep {"pattern": "loop_last|_loop import|from \\._loop|from \\.\\._loop|import _loop", "output_mode": "content", "glob": "!{tests,docs}/**"} -> 2,115자
2. Read {"file_path": "rich/_loop.py"} -> 1,359자
3. Bash {"command": "cd rich && python3 -I - <<'EOF'\nimport ast,glob\nfor f in sorted(glob.glob(\"*.py\")):\n    src=open(f).read()\n    if \"loop_last\" not -> 1,324자
4. Grep {"pattern": "import rich\\._loop|rich\\._loop|_loop\\.", "path": "rich", "output_mode": "content"} -> 16자
5. Read {"file_path": "rich/tree.py", "offset": 105, "limit": 72} -> 3,209자
1. Grep {"pattern": "loop_last|from \\._loop import|_loop\\b", "path": "rich", "output_mode": "content"} -> 2,218자
2. Read {"file_path": "rich/_loop.py"} -> 1,359자
3. ToolSearch {"query": "select:mcp__codebase-memory-mcp__trace_path,mcp__codebase-memory-mcp__check_index_coverage", "max_results": 2} -> 0자
4. Grep {"pattern": "loop_last", "glob": "!{rich,tests,docs}/**", "output_mode": "content"} -> 16자
5. cbm:trace_path {"function_name": "rich.rich._loop.loop_last", "project": "rich", "direction": "inbound", "depth": 1} -> 612자
6. Bash {"command": "python3 -I -c '\nimport ast,sys,glob\nfor f in sorted(glob.glob(\"rich/*.py\")):\n    t=ast.parse(open(f).read())\n    def walk(n,stack): -> 651자
7. cbm:check_index_coverage {"project": "rich", "paths": ["rich/_loop.py", "rich/_wrap.py", "rich/box.py", "rich/live_render.py", "rich/pretty.py", "rich/screen.py", "rich/table. -> 1,946자
8. Grep {"pattern": "stack|last", "path": "rich/tree.py", "output_mode": "content"} -> 1,250자

두 회차 모두 grep으로 시작했어요. 기준 조건은 Python의 ast로 각 호출을 감싼 함수를 찾았고, 도구 조건은 도구 검색으로 trace_path를 불러와 호출자를 받은 뒤 같은 ast 확인을 했어요. summarize.py trace는 그래프가 돌려준 호출자 목록을 꺼내요.

py312 summarize.py trace 06-q2-tool
function: rich.rich._loop.loop_last
direction: inbound
callers_total: 13
callers_total_relation: eq
callers: 13  (cols: qn hop)
  rich.rich.traceback.py.__file__ 1
  rich.rich.pretty.py.__file__ 1
  rich.rich.text.py.__file__ 1
  rich.rich.traceback.Traceback.__rich_console__ 1
  rich.rich.pretty._Line.expand 1
  rich.rich.box.Box.get_top 1
  rich.rich.box.Box.get_row 1
  rich.rich.box.Box.get_bottom 1
  rich.rich.tree.Tree.__rich_console__ 1
  rich.rich.live_render.LiveRender.__rich_console__ 1
  rich.rich.screen.Screen.__rich_console__ 1
  rich.rich.table.Table._render 1
  rich.rich._wrap.divide_line 1

13개 중 3개가 함수가 아니라 파일(__file__)이에요. pretty.py, text.py, traceback.py에서는 함수 안에 정의한 함수가 loop_last를 부르는데, 그래프는 이 호출을 파일 단위로만 잡아서 Claude가 결국 ast로 다시 찾았어요.

두 회차의 결과 JSON을 볼게요(발췌).

excerpt out/02-q2-base.jsonl out/06-q2-tool.jsonl
{
  "num_turns": 6,
  "duration_ms": 31286,
  "total_cost_usd": 0.125966,
  "usage": {
    "input_tokens": 8,
    "cache_creation_input_tokens": 7799,
    "cache_read_input_tokens": 42110,
    "output_tokens": 2756
  }
}
{
  "num_turns": 9,
  "duration_ms": 40712,
  "total_cost_usd": 0.17344520000000002,
  "usage": {
    "input_tokens": 12,
    "cache_creation_input_tokens": 11500,
    "cache_read_input_tokens": 83286,
    "output_tokens": 3237
  }
}

이 글의 "입력"은 usage의 input_tokens, cache_creation_input_tokens, cache_read_input_tokens의 합이에요. 캐시에서 읽은 토큰도 모델이 다시 읽으니 함께 세서, 기준 49,917, 도구 조건 94,798이에요.

"턴"은 num_turns예요. 이 버전에서는 30번 모두 도구 호출 수 + 1이었고, 한 요청에서 도구를 여러 개 함께 부를 수 있어 모델 요청 수와는 달라요.

summarize.py runs는 요청 수와 첫 요청의 입력도 보여 줘요.

py312 summarize.py runs | grep -E '^(02-q2-base|06-q2-tool)'
02-q2-base: O 12/12, 입력 49,917 (첫 요청 10,183), 요청 4, 6턴, 도구 {'Grep': 2, 'Read': 2, 'Bash': 1}, CLI 0, 읽은 파일 2, 훅 {} 주입 0
06-q2-tool: O 12/12, 입력 94,798 (첫 요청 11,705), 요청 6, 9턴, 도구 {'Grep': 3, 'Read': 1, 'ToolSearch': 1, 'trace_path': 1, 'Bash': 1, 'check_index_coverage': 1}, CLI 0, 읽은 파일 1, 훅 {'SessionStart': 1, 'PreToolUse': 4, 'PostToolUse': 1} 주입 4

도구 조건은 그래프 조회와 확인 호출이 더해져 모델 요청이 4번에서 6번으로 늘었어요. 요청마다 그때까지의 대화가 다시 입력으로 들어가 입력이 1.9배가 됐어요.

첫 요청은 아직 도구를 부르기 전이라, 그 차이 1,522토큰(미뤄 둔 MCP 도구 이름 목록, 서버 안내문, 스킬 한 줄, SessionStart 안내문)이 도구를 붙인 것만으로 요청마다 더해지는 몫이에요. 같은 질문끼리 비교하면 24번 모두 1,522토큰이었어요.

"주입"은 훅이 additionalContext로 맥락을 넣은 횟수예요. PreToolUse 훅은 grep 패턴과 이름이 맞는 그래프 심볼이 있을 때만 그 목록을 붙여요.

실습 2: 질문 4개를 3번씩

질문은 정의와 모든 직접 호출자(q1), 시그니처 변경의 영향 범위(q2), 공개 함수에서 내부 함수까지의 호출 경로(q3), 클래스 상속과 메서드 재정의(q4)를 묻습니다. summarize.py table은 질문·조건별 3번과 전체 12번의 중앙값을 내요. "도구"는 도구 호출 수, "읽은 파일"은 Read로 연 서로 다른 파일 수, "그래프"는 MCP 도구와 CLI로 그래프를 조회한 수예요.

py312 summarize.py table
q1 base: 정답 3/3, 입력 44,064 (쓰기 1,546, 읽기 42,539), 요청 4, 4턴, 도구 3, 읽은 파일 0, 그래프 0, 16.9초
q1 tool: 정답 3/3, 입력 50,686 (쓰기 1,914, 읽기 48,509), 요청 4, 4턴, 도구 3, 읽은 파일 0, 그래프 0, 22.1초
q2 base: 정답 3/3, 입력 49,917 (쓰기 4,207, 읽기 45,279), 요청 4, 6턴, 도구 5, 읽은 파일 1, 그래프 0, 31.3초
q2 tool: 정답 3/3, 입력 94,798 (쓰기 8,594, 읽기 83,286), 요청 6, 8턴, 도구 7, 읽은 파일 1, 그래프 2, 40.7초
q3 base: 정답 3/3, 입력 53,022 (쓰기 6,560, 읽기 46,732), 요청 4, 7턴, 도구 6, 읽은 파일 3, 그래프 0, 20.2초
q3 tool: 정답 3/3, 입력 61,615 (쓰기 7,441, 읽기 54,499), 요청 4, 7턴, 도구 6, 읽은 파일 3, 그래프 0, 31.4초
q4 base: 정답 3/3, 입력 42,120 (쓰기 8,317, 읽기 34,296), 요청 3, 4턴, 도구 3, 읽은 파일 1, 그래프 0, 19.6초
q4 tool: 정답 3/3, 입력 54,440 (쓰기 8,259, 읽기 51,118), 요청 4, 5턴, 도구 4, 읽은 파일 1, 그래프 0, 29.2초
전체 base 12회: 정답 12/12, 입력 46,556 (쓰기 6,421, 읽기 42,601), 요청 4, 4.5턴, 도구 3.5, 읽은 파일 1, 그래프 0, 20.0초, 출력 1,825, $0.1009, 느슨한 규칙 정답 12/12, 입력 합계 579,548
전체 tool 12회: 정답 12/12, 입력 55,468 (쓰기 7,274, 읽기 51,570), 요청 4, 5턴, 도구 4, 읽은 파일 1, 그래프 0, 29.6초, 출력 2,224, $0.1115, 느슨한 규칙 정답 12/12, 입력 합계 748,257

정답은 두 조건 모두 12번 중 12번이었고, 이름과 파일이 답 어디에 있어도 되는 느슨한 규칙으로도 같았어요.

입력 중앙값은 46,556에서 55,468로 19%, 24번 합계로는 579,548에서 748,257로 29% 늘었어요. 네 질문 모두 도구 조건 쪽 중앙값이 컸고, num_turns 중앙값은 4.5 대 5, 도구 호출 중앙값은 3.5 대 4였어요.

그래프 도구를 실제로 부른 회차는 도구 조건 12번 중 q2의 2번뿐이었어요. 나머지 10번은 도구 검색을 하지 않아 MCP 도구 정의가 실리지도 않았고, PATH의 CLI와 스킬은 24번 동안 한 번도 쓰이지 않았어요.

그럼 늘어난 8,912토큰(55,468 − 46,556)은 어디서 왔을까요? 모델 요청 중앙값이 두 조건 모두 4번이라, 요청마다 붙는 1,522토큰이 6,088토큰으로 약 68%를 차지해요.

훅 맥락은 작았어요. 도구 조건 12번에서 훅이 61번 돌아 33번 맥락을 넣었고, 요청 수가 같은 q1 두 회차(18, 22)를 요청별로 비교하면 1,522토큰을 넘는 몫은 약 160~220토큰이었어요. q4에서는 도구 조건 두 회차가 기준 중앙값보다 모델 요청이 한 번 더 많아 입력이 크게 늘었어요.

시간(20.0초 대 29.6초)은 도구 조건의 훅마다 docker exec가 붙어 비교하지 않았어요. 비용 추정($0.1009 대 $0.1115)도 캐시를 읽는 순서에 흔들려 보조로만 봐 주세요.

실습 3: 도구 정의를 처음부터 모두 실으면

ENABLE_TOOL_SEARCH=false로 도구 검색을 끄면 ToolSearch가 빠지고 MCP 도구 정의가 첫 요청부터 실려요. 본 측정을 마친 뒤 이 조건(eager)으로 질문마다 한 번씩 ./lab.sh extra를 돌렸어요.

./lab.sh extra
py312 summarize.py extra
x1-q1-eager: O 5/5, 입력 82,040 (첫 요청 19,120), 요청 4, 7턴, 도구 {'search_graph': 1, 'Grep': 2, 'trace_path': 1, 'check_index_coverage': 1, 'Bash': 1}, CLI 0, 읽은 파일 0, 훅 {'SessionStart': 1, 'PreToolUse': 3} 주입 2
x2-q2-eager: O 12/12, 입력 113,149 (첫 요청 19,142), 요청 5, 7턴, 도구 {'trace_path': 1, 'Grep': 2, 'Bash': 2, 'check_index_coverage': 1}, CLI 0, 읽은 파일 0, 훅 {'SessionStart': 1, 'PreToolUse': 4} 주입 4
x3-q3-eager: O 6/6, 입력 89,395 (첫 요청 19,155), 요청 4, 6턴, 도구 {'trace_path': 1, 'search_graph': 1, 'Bash': 2, 'check_index_coverage': 1}, CLI 0, 읽은 파일 0, 훅 {'SessionStart': 1, 'PreToolUse': 2} 주입 1
x4-q4-eager: O 9/9, 입력 68,350 (첫 요청 19,145), 요청 3, 5턴, 도구 {'query_graph': 1, 'Grep': 2, 'check_index_coverage': 1}, CLI 0, 읽은 파일 0, 훅 {'SessionStart': 1, 'PreToolUse': 2} 주입 3

이번에는 4번 모두 그래프 도구를 불렀고 모두 정답이었어요. 첫 요청은 19,120~19,155토큰으로, 같은 질문의 기준 조건(10,161~10,196)보다 4번 모두 8,959토큰 많았어요.

입력은 68,350~113,149로 같은 질문의 기준 조건 중앙값보다 1.6~2.3배 많았어요. 질문마다 1번씩이라 방향만 보는 숫자예요. 그래프를 쓴 뒤에도 Bash와 Grep으로 소스를 확인하는 호출은 남았어요.

정리

범위: Claude Code 2.1.309의 claude -p, Opus 5.5(claude-opus-5-5), effort medium, codebase-memory-mcp 0.12.1을 Docker 컨테이너 하나에 두고 공식 설치기의 MCP 서버·훅·스킬을 프로젝트 범위로 옮긴 조건 대 기본 도구만 쓴 조건, rich v15.0.0의 코드 탐색 질문 4개를 3번씩 24번, 본 측정 뒤 도구 정의를 처음부터 싣는 보조 조건 4번.

  • Claude Code에 붙여 요청마다 다시 읽는 입력 전체로 재면, 이 저장소와 질문에서는 줄지 않고 늘었어요. 입력 중앙값은 46,556에서 55,468로 19%, 합계는 29% 늘었고, 정답은 두 조건 모두 12번 중 12번, 도구 호출 중앙값은 3.5 대 4였어요.
  • 도구 검색이 켜진 기본 상태에서 모델은 그래프 도구를 12번 중 2번만 불렀어요. 도구 정의를 처음부터 실으면 첫 요청이 8,959토큰 늘었고, 질문마다 1번씩이라 방향만 보는 숫자지만 4번 모두 그래프를 쓰면서 입력은 기준의 1.6~2.3배였어요.
  • 그래프는 함수 안에 정의한 함수의 호출을 파일 단위로만 잡아서, 영향 범위 질문에서는 그래프를 쓰고도 소스를 다시 확인했어요.
  • 도구를 붙이기만 해도 첫 요청이 1,522토큰 늘고, 이 몫이 요청마다 붙어 늘어난 입력의 약 68%였어요. grep 한두 번이면 후보가 나오는 이 규모에서는 아낄 탐색이 거의 없었으니, 탐색이 긴 큰 저장소에서 따로 재 보세요.
  • 인덱스는 네트워크 없는 컨테이너에서 4초, 28MB였어요. Docker로 감쌀 때는 MCP 서버·훅·CLI를 한 컨테이너에서 같은 캐시로 돌리고 daemon start로 데몬을 유지하세요. 데몬이 없으면 훅이 아무것도 넣지 않아요.
내 링크 만들기