# AI 에이전트

Claude Code에 설명은 생략하라고 하면 출력 토큰이 줄어들까?

@Hong2026-10-26

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

실습 코드 내려받기

질문
Claude Code에 설명은 생략하라고 하면 출력 토큰이 얼마나 줄어들까?
답
한 줄 수정의 출력 중앙값은 지시 없음 713, 세 줄 보고 641, 설명 생략 598토큰으로 마지막 보고만 줄었다. 리뷰에 형식을 걸면 6,227에서 1,886토큰이 됐고, 지적 수는 8개에서 4개로 줄었지만 줄어든 건 주로 부차 지적이었다.
조건
2026-10-26, Claude Code 2.1.309 claude -p, claude-opus-5(effort high), 조건마다 5회, 사용자 설정의 Bash 전체 허용

환경

측정일
2026-10-26
Claude Code
2.1.309(claude --version), 구독 로그인, claude -p --safe-mode --output-format json
모델
--model을 주지 않음, 결과 JSON modelUsage의 모델 ID는 모든 실행에서 claude-opus-5(측정한 컴퓨터의 사용자 설정값)
effort
--effort를 주지 않음, 세션 로그의 요청 기록에 high(측정한 컴퓨터의 사용자 설정값)
권한
실습 1은 --permission-mode acceptEdits, 실습 2는 기본 모드(사용자 설정의 Bash 전체 허용은 --safe-mode에서도 적용됨)
반복
실습 1은 3조건 × 5회, 실습 2는 2조건 × 5회, 조건 순서를 섞어 모두 25회
집계
breakdown.py, summarize.py를 Python 3.12에서 실행
비용
total_cost_usd, 구독 호출을 API 단가로 환산한 추정치(실제 청구액 아님)
목차
  1. 실습 준비
  2. 실습 1: 같은 한 줄 수정에 지시만 세 가지로 바꾸기
  3. 토큰이 아닌 쪽에서 무엇을 잃을까
  4. 실습 2: 코드 리뷰에 출력 형식 걸기
  5. 정리

이번 시간에는 Claude Code가 작업 끝에 내놓는 설명과 보고를 프롬프트 지시로 얼마나 줄여도 되는지를, 세션 로그를 내용 유형별로 나누는 작은 스크립트와 claude -p(대화 화면 없이 한 번 실행하고 끝나는 모드)로 측정하며 배워가는 시간입니다.

Claude Code의 출력에는 마지막 답만 있는 게 아니에요. 파일을 찾고 읽고 고치려고 만드는 도구 호출도 모두 출력 토큰이에요. 출력의 큰 몫은 이런 행동이고, 나머지가 설명하는 몫입니다.

설명 몫은 작지만, 지시로 조절할 수 있는 건 사실상 이 몫뿐이에요. 리뷰처럼 답 자체가 결과물인 작업에서는 출력의 전부이기도 하고요.

그래서 설명을 얼마나 줄여도 되는지, 반복 작업에 형식을 걸면 무엇이 줄고 남는지 볼게요. 다시 돌리면 숫자는 달라질 수 있어요.

실습 준비

이 글의 명령은 모두 실습 코드의 claude-report-format-output/ 디렉터리에서 실행합니다.

  • app/: 실습 대상인 작은 티켓 앱. app/service.py에 담당자 지정 규칙과, 한 사람이 동시에 들 수 있는 진행 중 티켓 수 WIP_LIMIT = 3이 있어요
  • src/tokenlab/, pyproject.toml: 세션 로그 파서(tokenlab.session_jsonl)가 든 측정 패키지
  • breakdown.py: 한 세션의 출력 토큰을 내용 유형별로 나누는 스크립트
  • run.sh, schedule-1.txt, schedule-2.txt: 같은 프롬프트를 claude -p로 반복 실행하는 스크립트와 실행 순서
  • summarize.py: 반복 실행 결과를 조건별 중앙값과 범위로 모으는 스크립트
  • tests/baseline/: 티켓 앱의 기준 테스트(이 글에서 실행하지는 않아요)

Python 3.11 이상으로 패키지를 설치하고 시작 상태를 커밋해 둘게요. 뒤의 git checkout과 run.sh가 이 커밋을 기준으로 해요.

python3 -m venv .venv
.venv/bin/python -m pip install -e .
git init
git add .
git commit -m "start"

출력 토큰은 세션 로그에서 한 덩어리 숫자로만 보여요. 그래서 출력을 내용 유형별로 나눠 주는 breakdown.py를 씁니다.

"""최근 세션의 출력 토큰을 내용 유형별로 분해한다. 사용법: python breakdown.py [세션파일]"""
import collections, json, sys
from pathlib import Path
from tokenlab.session_jsonl import latest_session, iter_events

if len(sys.argv) > 1:
    path = Path(sys.argv[1])
else:
    root = Path.home() / ".claude" / "projects"
    newest_dir = max(root.glob("*/"), key=lambda p: p.stat().st_mtime)
    path = latest_session(newest_dir)

per = {}
for ev in iter_events(path):
    if ev.get("type") != "assistant":
        continue
    m = ev["message"]
    usage = m.get("usage") or {}
    kinds = "+".join(sorted({c["type"] if c["type"] != "tool_use" else c["name"]
                             for c in m.get("content", [])}))
    per[m.get("id")] = (usage.get("output_tokens", 0), kinds)

total = sum(o for o, _ in per.values()) or 1
agg = collections.Counter()
for o, k in per.values():
    agg[k] += o
print(path.name)
print(f'{"출력":>7}  {"비중":>5}  내용')
for k, o in agg.most_common():
    print(f'{o:>7}  {o * 100 // total:>4}%  {k}')
print(f'{total:>7}  100%  합계')

세 덩어리로 나눠서 볼게요.

첫 덩어리는 어느 세션을 볼지 정해요. 인자로 세션 파일 경로를 주면 그 파일을 보고, 안 주면 ~/.claude/projects 아래 가장 최근 디렉터리에서 사용량이 든 최신 세션을 골라요. latest_session이 그냥 최신 파일을 집지 않는 건, 슬래시 명령만 치고 끝낸 세션도 파일은 생기지만 사용량이 비어 있어서 에러 없이 0만 찍히기 때문이에요.

둘째 덩어리는 assistant 이벤트만 남기고 도구 이름이나 text 같은 유형을 라벨로 붙여요. Claude Code는 응답 하나를 내용 조각마다 한 줄씩 쓰고, 그 줄마다 응답 전체의 output_tokens를 똑같이 적어요. 그냥 다 더하면 같은 토큰을 두세 번 세게 되니, 메시지 id를 키로 덮어써서 한 번만 셉니다.

덮어쓰기라서 라벨은 마지막 줄 것이 남아요. 결국 라벨은 그 응답이 무엇으로 끝났는지를 뜻합니다.

마지막 덩어리는 라벨별로 합치고 비중(소수점 버림)을 붙여 큰 순서로 찍어요.

그래서 Edit 줄의 숫자는 Edit 도구가 쓴 토큰이 아니라, 앞의 생각과 설명까지 포함해 Edit으로 끝난 응답이 통째로 쓴 토큰이에요. 이 글에서 "어느 도구가 몇 토큰"이라고 말하지 않는 이유입니다.

실습 1: 같은 한 줄 수정에 지시만 세 가지로 바꾸기

과제는 WIP_LIMIT을 3에서 5로 바꾸는 한 줄 수정이에요. 과제는 그대로 두고 지시만 바꿔 볼게요.

세 조건 모두 새 세션에서 시작합니다. 앞 대화가 남아 있으면 두 번째, 세 번째 조건은 파일을 이미 읽은 상태에서 출발하니, 출력이 줄어든 이유가 프롬프트 때문인지 앞 턴 때문인지 구분이 안 되거든요.

첫 번째는 지시가 없어요. 첫 줄은 소문자 UUID를 변수에 담고, 둘째 줄은 그 아이디로 세션을 새로 엽니다. 이 변수는 뒤의 명령에서 다시 쓰니 같은 터미널에서 이어서 실행해 주세요.

--safe-mode는 CLAUDE.md, 스킬, 플러그인, 훅, MCP 서버 같은 개인 설정을 끄는 옵션이에요. 권한·모델·effort 설정은 그대로 적용돼요.

PLAIN_SESSION_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
claude --safe-mode --session-id "$PLAIN_SESSION_ID"

세션이 열리면 이렇게 입력해 주세요.

app/service.py의 WIP_LIMIT을 3에서 5로 바꿔 줘.

결과로 나오는 답의 길이와 내용을 살펴보세요. 무엇을 왜 바꿨는지 설명도 있을 거예요.

답이 끝나면 Claude Code를 종료해요. 첫 줄은 세션 아이디와 같은 이름의 로그 파일을 찾고, 둘째 줄은 그 경로를 breakdown.py에 넘겨요. 마지막 줄은 바꾼 파일을 되돌려 다음 조건을 같은 상태에서 시작하게 합니다.

PLAIN_LOG="$(find "$HOME/.claude/projects" -type f -name "$PLAIN_SESSION_ID.jsonl" -print -quit)"
.venv/bin/python breakdown.py "$PLAIN_LOG"
git checkout -- app/service.py

두 번째는 세 줄 이내로 보고하라는 지시예요. 아이디만 새로 만들고 같은 순서로 진행합니다.

THREE_LINE_SESSION_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
claude --safe-mode --session-id "$THREE_LINE_SESSION_ID"
app/service.py의 WIP_LIMIT을 3에서 5로 바꿔 줘. 끝나면 결과는 세 줄 이내로만 보고해 줘.
THREE_LINE_LOG="$(find "$HOME/.claude/projects" -type f -name "$THREE_LINE_SESSION_ID.jsonl" -print -quit)"
.venv/bin/python breakdown.py "$THREE_LINE_LOG"
git checkout -- app/service.py

세 번째는 설명을 생략하라는 지시예요.

NO_EXPLAIN_SESSION_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
claude --safe-mode --session-id "$NO_EXPLAIN_SESSION_ID"
app/service.py의 WIP_LIMIT을 3에서 5로 바꿔 줘. 설명은 생략하고 바꾸기만 해 줘.
NO_EXPLAIN_LOG="$(find "$HOME/.claude/projects" -type f -name "$NO_EXPLAIN_SESSION_ID.jsonl" -print -quit)"
.venv/bin/python breakdown.py "$NO_EXPLAIN_LOG"
git checkout -- app/service.py

그런데 한 번씩만 돌리면 값이 얼마나 튀는지 몰라서 순위를 매길 수 없어요. 그래서 이 글의 숫자는 같은 프롬프트를 claude -p로 조건마다 다섯 번씩, 순서를 섞어 돌려서 얻었어요.

run.sh는 schedule-1.txt의 한 줄(three 01처럼 조건과 회차)마다 커밋된 시작 상태를 실습 디렉터리 밖 ../claude-report-format-runs/ 아래에 새로 복제하고, 새 UUID와 프롬프트 원문(prompt_for가 조건 이름을 원문으로 바꿔 줘요)으로 claude -p를 돌려요. 핵심 부분은 이렇습니다(발췌).

  case "$cond" in
    plain|three|noexp)
      (cd "$dir" && claude -p "$prompt" --safe-mode --session-id "$id" --output-format json --permission-mode acceptEdits < /dev/null) > "$dest/result.json" || true ;;
    *)
      (cd "$dir" && claude -p "$prompt" --safe-mode --session-id "$id" --output-format json < /dev/null) > "$dest/result.json" || true ;;
  esac

헤드리스 실행에는 수정 허락을 눌러 줄 사람이 없어서, 실습 1의 세 조건에는 똑같이 --permission-mode acceptEdits(작업 디렉터리 안 파일 수정을 묻지 않고 허용)를 줬어요. 결과 JSON, 세션 로그 사본, git diff는 ../claude-report-format-out/<조건>-<회차>/에 남아요. 둘 다 실습 디렉터리 밖에 두는 건, 대화형 실습에서 Claude가 이 사본들까지 찾아 읽지 않게 하려는 거예요.

summarize.py는 회차마다 breakdown.py를 돌려 표를 저장하고, 조건별로 라벨마다 중앙값과 범위(최솟값~최댓값)를 찍습니다.

chmod +x run.sh
./run.sh schedule-1.txt
.venv/bin/python summarize.py ../claude-report-format-out

열다섯 번 모두 WIP_LIMIT 한 줄만 바뀌었고, 도구는 매번 Bash(grep으로 위치 찾기), Read, Edit 순서였어요. 조건마다 합계가 중앙값에 가까운 회차의 표를 지시 없음, 세 줄 보고, 설명 생략 순서로 놓아 볼게요. 첫 줄의 세션 파일 이름은 <uuid>.jsonl로 바꿔 적었어요.

<uuid>.jsonl
     출력     비중  내용
    204    28%  Edit
    185    25%  Bash
    179    25%  Read
    145    20%  text
    713  100%  합계

<uuid>.jsonl
     출력     비중  내용
    203    31%  Edit
    188    29%  Bash
    178    27%  Read
     72    11%  text
    641  100%  합계

<uuid>.jsonl
     출력     비중  내용
    205    33%  Edit
    193    31%  Bash
    180    29%  Read
     26     4%  text
    604  100%  합계

다섯 번씩 모은 summarize.py 출력은 이렇습니다(발췌).

[plain] 5회, 모델 ['claude-opus-5']
  합계 출력: 중앙값 713 (범위 692~753)
  text: 중앙값 143 (범위 136~184)
  text를 뺀 나머지: 중앙값 569 (범위 549~572)

[three] 5회, 모델 ['claude-opus-5']
  합계 출력: 중앙값 641 (범위 602~667)
  text: 중앙값 79 (범위 40~122)
  text를 뺀 나머지: 중앙값 566 (범위 522~569)

[noexp] 5회, 모델 ['claude-opus-5']
  합계 출력: 중앙값 598 (범위 596~605)
  text: 중앙값 26 (범위 26~26)
  text를 뺀 나머지: 중앙값 572 (범위 570~579)

요약을 시키자 합계 중앙값이 713에서 641로 줄었어요. 생각보다 작죠.

줄어든 건 text 줄(143에서 79)이고 Edit·Bash·Read 줄은 거의 그대로예요. 파일을 찾고 읽고 고치는 행동은 지시를 어떻게 주든 똑같이 해야 하니까요.

출력 절감에는 바닥이 있다는 뜻이에요. 이 과제에서 text를 뺀 나머지는 세 조건 모두 중앙값 570토큰 안팎이었어요. Edit 줄에도 설명이 섞일 수 있으니 text 줄은 마지막 보고에 가깝다고 보시면 됩니다.

그럼 설명 생략은 세 줄 보고보다 더 아꼈을까요? text 줄은 79에서 26으로 더 줄었지만, 합계는 641(602~667)과 598(596~605)로 범위가 겹쳐서 어느 쪽이 출력을 더 적게 쓰는지는 모르겠어요. 극단적인 지시가 극단적인 절감으로 이어지지는 않아요.

합계 차이가 가장 커도 100토큰 안팎(713과 598)이니, 이번에는 토큰이 아닌 쪽도 볼게요.

토큰이 아닌 쪽에서 무엇을 잃을까

위 표와 같은 회차의 마지막 답을 꺼내 볼게요. 지시 없음은 이렇게 답했어요.

`app/service.py:10`의 `WIP_LIMIT`을 3에서 5로 변경했습니다. 24~25번 줄에서 상수를 참조하므로 추가 수정은 필요 없습니다.

참고로 이 값을 3으로 가정한 테스트가 있는지는 확인하지 않았습니다. 원하시면 테스트를 찾아 함께 확인해 드리겠습니다.

세 줄 보고는 이렇게요.

`app/service.py:10`의 `WIP_LIMIT`을 3 → 5로 변경했습니다.
24~25번 줄은 상수를 참조하므로 추가 수정은 없습니다.

설명 생략은 이렇습니다.

`app/service.py:10` → `WIP_LIMIT = 5`

지시 없음(다섯 번 모두)과 세 줄 보고(다섯 번 중 네 번)는 답만 봐도 무엇을 바꿨고 다른 곳은 손댈 필요가 없다는 걸 알 수 있어요. 지시 없음은 다섯 번 모두 테스트 확인을 다음 행동으로 제안했고, 세 줄 보고는 다섯 번 중 한 번만 그랬어요.

설명 생략은 다섯 번 모두 파일과 줄, 새 값만 적은 한 줄이었어요. 무엇이 바뀌었는지는 남았지만, 다른 사용처는 괜찮은지, 테스트를 봐야 하는지 같은 다음 행동의 근거는 빠졌어요. 이번 과제는 한 줄이라 재지 않았지만, 여러 곳을 고친 작업이라면 무엇을 왜 바꿨는지 알려고 diff를 열어야 할 거예요.

text 줄 117토큰(143에서 26)을 아끼려고 사람이 파일을 열게 되면, 절감이 사라진 게 아니라 그 처리가 사람에게 넘어간 거예요. 협업이라면 다음 작업자가 맥락 없이 코드만 받으니 더 비싼 일이 됩니다.

그래서 적당한 설명의 기준은 "답만 보고 다음에 뭘 해야 할지 정할 수 있는 최소 단위"로 잡을게요. 그 아래로 줄인 건 절감으로 치지 않아요. 에이전트를 쓰는 가장 큰 이유는 생산성이고, 그 생산성에는 사람도 들어가니까요.

실습 2: 코드 리뷰에 출력 형식 걸기

매번 "세 줄로 요약해 줘"를 붙이는 건 임시방편이에요. 코드 리뷰처럼 반복하는 작업은 출력 형식을 아예 고정해 두면 되겠죠.

먼저 형식 없이 시켜 볼게요. 여기서도 조건마다 세션을 새로 엽니다.

FREE_SESSION_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
claude --safe-mode --session-id "$FREE_SESSION_ID"
app/service.py를 코드 리뷰해 줘.

자유로운 프롬프트는 길이뿐 아니라 리뷰의 규모도 자유로워요.

리뷰가 문제를 몇 개 찾았는지 세어 두세요. 형식을 걸고 돌린 것과 개수를 비교할 거예요. 리뷰는 파일을 고치지 않으니 되돌릴 건 없어요.

FREE_LOG="$(find "$HOME/.claude/projects" -type f -name "$FREE_SESSION_ID.jsonl" -print -quit)"
.venv/bin/python breakdown.py "$FREE_LOG"

이번에는 프롬프트에 형식을 걸어요.

FORMAT_SESSION_ID="$(uuidgen | tr '[:upper:]' '[:lower:]')"
claude --safe-mode --session-id "$FORMAT_SESSION_ID"
app/service.py를 코드 리뷰해 줘. 결과는 발견한 문제마다 '파일:줄 / 문제 / 수정안' 각 한 줄씩만. 다른 설명은 쓰지 마.
FORMAT_LOG="$(find "$HOME/.claude/projects" -type f -name "$FORMAT_SESSION_ID.jsonl" -print -quit)"
.venv/bin/python breakdown.py "$FORMAT_LOG"

반복 실행은 schedule-2.txt로 해요. 두 조건(rfree, rform)은 파일을 고치지 않으니 권한 옵션 없이 돌렸어요.

측정한 컴퓨터는 사용자 설정의 Bash 전체 허용 덕에 Claude가 재현 코드를 실행할 수 있었어요. 이 허용이 없으면 자유 리뷰의 숫자는 달라질 수 있어요.

문제 개수는 두 기준으로 셌어요. 하나는 리뷰가 바꾸거나 고려하라고 내놓은 모든 지적(테스트·성능·스타일, 다른 파일 지적 포함)이고, 다른 하나는 app/service.py의 동작 문제만이에요. 둘 다 같은 원인을 다르게 말한 것은 하나로, 칭찬과 요약은 빼고, 열 번의 지적을 한 목록으로 모아 한 사람이 셌어요.

센 개수를 회차 디렉터리에 issues.txt(모든 지적)와 issues-service.txt(동작 문제만)로 숫자 하나씩 적어 두면 summarize.py가 같이 모아 줘요.

./run.sh schedule-2.txt
.venv/bin/python summarize.py ../claude-report-format-out

summarize.py 출력은 이렇습니다(발췌).

[rfree] 5회, 모델 ['claude-opus-5']
  합계 출력: 중앙값 6227 (범위 4872~7598)
  text: 중앙값 2769 (범위 1752~3692)
  Bash: 중앙값 2539 (범위 806~2951)
  Read: 중앙값 723 (범위 581~2002)
  비용 추정(USD): 중앙값 0.3257 (범위 0.3062~0.4383)
  찾은 문제 수: 중앙값 8 (범위 7~9)
  service.py 동작 문제 수: 중앙값 5 (범위 4~6)

[rform] 5회, 모델 ['claude-opus-5']
  합계 출력: 중앙값 1886 (범위 1694~2008)
  text: 중앙값 1453 (범위 1261~1573)
  Read: 중앙값 433 (범위 433~435)
  비용 추정(USD): 중앙값 0.1371 (범위 0.1323~0.1402)
  찾은 문제 수: 중앙값 4 (범위 4~6)
  service.py 동작 문제 수: 중앙값 4 (범위 4~5)

형식을 걸자 합계 중앙값이 6,227에서 1,886으로 줄었고 범위도 겹치지 않아요. 비용 추정치 중앙값도 0.3257에서 0.1371달러로 줄었어요.

자유 리뷰는 다섯 번 모두 app/api.py와 기준 테스트까지 살펴보고 Bash로 재현 코드를 돌렸는데, 형식 리뷰는 다섯 번 모두 app/ 안의 파일 세 개만 읽고 끝냈어요. 형식이 작업의 규모까지 묶은 거예요.

그런데 합계만 보고 끝내면 안 돼요. 모든 지적을 세면 중앙값 8개(7~9)에서 4개(4~6)로 줄었고 범위도 겹치지 않아요. 그런데 app/service.py의 동작 문제만 세면 5개(4~6)와 4개(4~5)로 범위가 겹쳐요.

개수가 비슷한데 토큰이 줄었다면 형식이 설명만 깎은 거고, 개수가 확 줄었다면 발견까지 막은 거예요. 모든 지적으로 보면 뒤쪽이고, 동작 문제만 보면 줄었다고 단정할 수 없어요. 무엇이 빠졌는지 보면 이래요.

  • 열 번 모두 찾은 것: move에 WIP 한도 검사가 없어 한도를 우회함, 공백 담당자로 "담당자 없이 진행 불가" 규칙이 뚫림, 같은 사람에게 다시 지정하면 그 티켓까지 세어 거부됨
  • 형식 리뷰에서 줄어든 것(자유 대 형식, 각 5회 중): 저장소에 변경을 쓰지 않음 5회 대 2회, 테스트가 이 규칙들을 덮지 않음 4회 대 0회, 셀 때마다 전체 목록을 정렬함 4회 대 0회, 완료된 티켓에도 담당자 지정 가능 3회 대 2회, title.strip() 두 번 호출 3회 대 1회

핵심 결함 셋은 형식을 걸어도 그대로 찾았어요. 많이 빠진 건 테스트·성능·스타일·다른 파일 같은 부차 지적과 재현 확인이었고, 동작 문제 중에서는 저장소에 변경을 쓰지 않는다는 지적이 5회 대 2회로 줄었어요.

빠진 항목이 필요하다면 "다른 설명은 쓰지 마"를 빼거나 몇 개 이상 찾아 달라고 하한을 주는 식으로 형식을 풀어야 해요. 푼 형식은 이 글에서 재지 않았어요.

형식은 걸고 나서 결과물이 멀쩡한지 보고 조이거나 푸는 거예요.

형식 리뷰의 답 하나(rform-03)는 이렇게 생겼어요(네 줄 중 앞의 두 줄).

app/service.py:24 / WIP_LIMIT을 assign에서만 검사해 OPEN 상태로 무제한 배정한 뒤 move로 IN_PROGRESS 전환하면 한도가 그대로 우회된다 / move()에서 target이 IN_PROGRESS일 때 `_in_progress_count(ticket.assignee) >= WIP_LIMIT`를 함께 검사하도록 옮긴다
app/service.py:24 / 이미 그 담당자에게 배정된 IN_PROGRESS 티켓도 카운트에 포함돼, 같은 사람에게 재배정하는 무해한 호출이 한도에서 거부된다 / 카운트 시 `t.id != ticket_id` 조건을 추가하거나 `ticket.assignee == assignee`면 즉시 반환한다

이 형식은 파일과 줄이 박혀 있어서 열어 보고 맞는지 검증할 수 있고, 줄 단위라 다음 도구 호출에도 바로 쓸 수 있어요.

반복 작업은 이런 형식을 규격으로 정해 지침(CLAUDE.md 같은 파일)에 걸어 두시면, 매번 프롬프트에 붙이지 않으셔도 됩니다.

  • 코드 리뷰: 문제마다 파일과 줄, 문제, 수정안을 각각 한 줄로
  • 조사나 요약: 결론을 먼저 세 줄 안에 주고, 근거는 파일과 줄 목록으로
  • 수정 작업 보고: 무엇을 왜 바꿨는지 세 줄 안에

응답을 짧게 만드는 CLAUDE.md 규칙이 더 궁금하면 claude-token-efficient를 쓰면 응답이 63% 짧아진다는데, 과연 진짜일까? 글을 참고하세요.

정리

범위: Claude Code 2.1.309 claude -p, claude-opus-5(effort high), 사용자 설정에서 Bash 전체 허용, 작은 티켓 앱의 한 줄 수정과 app/service.py 코드 리뷰, 조건마다 5회.

  • 한 줄 수정에서 보고를 줄이라는 지시는 출력 합계 중앙값을 713에서 641(세 줄 보고), 598(설명 생략)로 줄였어요. 줄어든 건 마지막 보고(text 143, 79, 26)뿐이고, 파일을 찾고 읽고 고치는 몫은 570토큰 안팎 그대로였어요. 한 줄 수정처럼 할 일이 정해진 작업에서는 큰 절감을 기대하지 마세요.
  • 설명 생략과 세 줄 보고는 합계 범위가 겹쳐서 어느 쪽이 출력을 더 적게 쓰는지 모르겠어요. 극단적인 지시보다 답만 보고 다음 행동을 정할 수 있는 길이를 기준으로 삼으세요.
  • 설명 생략의 답은 파일과 줄, 새 값만 남기고 다른 사용처나 테스트 같은 다음 행동의 근거를 뺐어요. 다음 행동을 정할 수 없을 만큼 줄이면 절감한 몫이 사람에게 넘어갑니다.
  • 코드 리뷰에 '파일:줄 / 문제 / 수정안' 형식을 걸자 합계 중앙값이 6,227에서 1,886으로 줄었고, Bash가 허용된 이 환경에서 하던 재현 실행도 사라졌어요. 반복하는 리뷰라면 형식을 규격으로 두세요.
  • 모든 지적은 8개에서 4개로 줄었지만, app/service.py 동작 문제만 보면 5개와 4개로 범위가 겹치고 핵심 결함 셋은 열 번 모두 찾았어요. 형식을 건 뒤에는 개수와 빠진 항목을 한 번 보고, 부차 지적까지 필요하면 형식을 푸세요.

이 시리즈의 다음 글에서는 출력을 만드는 쪽, 즉 모델과 사고 깊이를 바꿔 가며 비용과 성공률을 함께 봅니다.

내 링크 만들기