콘텐츠로 이동

02-구조

02. 구조 — 시스템 프롬프트·도구 카탈로그·디스패처

섹션 제목: “02. 구조 — 시스템 프롬프트·도구 카탈로그·디스패처”

Claude Code가 매 턴 모델에 보내는 시스템 프롬프트는 대략 다음 섹션이 이 순서로 합쳐진다 (역공학 분석 종합).

  1. 정체성 — “You are Claude Code, Anthropic’s official CLI for Claude” 류 헤더.
  2. 환경 정보 — 작업 디렉터리, git 여부, OS, 플랫폼, 모델 ID, 오늘 날짜.
  3. 도구 사용 규칙 — 어떤 도구를 언제 쓰지 말아야 하는지 (예: “find/grep 대신 Glob/Grep 사용”).
  4. 응답 스타일 — 간결함, 이모지 금지, 4줄 이하 등의 출력 정책.
  5. 사용자 디렉티브 — 사용자 글로벌 ~/.claude/CLAUDE.md.
  6. 프로젝트 디렉티브 — 프로젝트 루트 CLAUDE.md.
  7. system-reminder — hooks가 동적으로 주입하는 메시지(이 글에도 보였듯).

CLAUDE.md가 “그저 메모”가 아닌 이유가 여기 있다. 매 메시지마다 시스템 프롬프트의 일부로 다시 들어간다. 길어지면 매 호출마다 토큰 비용을 낸다.

기본 내장 도구는 대략 다음과 같다 (how-claude-code-works-official 및 역공학 자료 종합).

분류도구비고
파일 읽기Read라인 번호 prefix, 이미지/PDF/노트북 지원
파일 쓰기Write, Edit, NotebookEditEdit은 정확 일치 치환
검색Glob, Grepripgrep 기반, find/grep 직접 사용 회피
실행Bashsandboxing/타임아웃/배경 실행 옵션
WebFetch, WebSearch도메인 정책 적용
메타TodoWrite, Task(서브에이전트)계획/위임
동적MCP 도구mcp__<server>__<tool> 네이밍

각 도구는 Ken Huang이 정리한 공통 인터페이스(이름·설명·입력 스키마·canUseTool 훅·실행 함수·결과 직렬화)를 구현한다. 이 균일성 덕에 새 도구 추가가 코어 변경 없이 가능하다.

USER: "이 함수 리팩토링해줘"
[harness] system + history + user → claude.messages.create(...)
ASSISTANT: text("Read 하겠다") + tool_use(Read, {file: "x.py"})
▼ stop_reason == "tool_use"
[harness] dispatch Read → file content
[harness] append tool_result(...) → claude.messages.create(...)
ASSISTANT: text("이렇게 바꾸겠다") + tool_use(Edit, {...})
▼ ... 반복 ...
ASSISTANT: text("완료") , stop_reason == "end_turn"
[harness] 루프 종료

핵심: 사용자는 한 번 말하지만, 모델·하네스 사이에는 N번의 왕복이 일어난다. 사용자에게 보이는 “한 응답” 안에 수십 번의 tool_use/tool_result가 들어 있을 수 있다.

단순히 함수를 부르는 게 아니다. (1) 인자 검증, (2) 권한 게이트 호출, (3) hooks(PreToolUse/PostToolUse) 발화, (4) 출력 절단/요약, (5) 에러 정규화 — 이 다섯 가지를 매 호출마다 한다. 각각이 챕터 4·6의 주제다.