Claude Code는 어떻게 동작하는가
터미널에서 Claude Code에게 프롬프트 하나를 던지면, 그 뒤에서는 생각보다 많은 일이 일어난다. 이 글은 “프롬프트를 입력하는 순간부터 답이 돌아오기까지” 무슨 일이 벌어지는지를, 바깥의 에이전틱 루프(agentic loop) 와 그 안쪽의 자기회귀 디코딩 루프라는 두 겹의 구조로 풀어본다.
1. 프롬프트가 모델에 닿기까지
터미널을 열고 프롬프트를 입력하면, Claude Code는 그 프롬프트를 그대로 모델에게 보내지 않는다. 먼저 변형을 거친다.
- 시스템 프롬프트: Anthropic이 작성한 기본 프롬프트와, Claude Code가 쓸 수 있는 도구(tool) 정의가 함께 들어간다. 엄밀히 말하면 도구 정의는 Anthropic Messages API에서 시스템 프롬프트와는 별개의
tools파라미터로 전달되지만, 모델은 이를 시스템 수준의 컨텍스트로 함께 받아들인다. - 메시지(messages): 사용 가능한 Skill의 이름·설명이
system-reminder형태로 들어가고,CLAUDE.md의 내용도 여기에 포함된다.
여기서 한 가지 짚고 넘어갈 점. CLAUDE.md는 시스템 프롬프트가 아니라 메시지(첫 user 메시지 안의 system-reminder)로 들어간다. 그런데도 CLAUDE.md의 지시는 보통 일반 질문보다 강하게 작동하는 경향이 있다. 이유는 두 가지다.
- 위치 효과 — 트랜스포머 기반 모델은 컨텍스트의 앞부분과 뒷부분을 상대적으로 더 잘 활용하는 경향이 있다(흔히 “lost in the middle”이라 부른다). 보장은 아니지만 경향성은 분명하다.
- 명시적 강조 —
CLAUDE.md의 지시에는 “이 지시는 기본 동작을 OVERRIDE한다” 같은 강한 문구가 붙어 우선도를 직접 끌어올린다.
이렇게 시스템 프롬프트와 메시지가 합쳐져 하나의 완성된 입력(프롬프트)이 만들어진다.
2. 모델 내부: Transformer와 자기회귀 디코딩
완성된 프롬프트를 Claude 모델이 받으면, 내부에서는 Transformer가 토큰을 하나씩 생성하기 시작한다.
Transformer는 쉽게 말해 “입력이 들어오면 다음 토큰 1개를 내놓는” 장치다. 핵심은 그 다음이다. 방금 생성한 토큰을 다시 입력 끝에 붙여서 또 다음 토큰을 만들고, 이 과정을 끝날 때까지 반복한다. 이렇게 자기 출력을 다시 입력으로 먹으며 한 토큰씩 이어 붙이는 방식을 자기회귀(autoregressive) 디코딩이라고 부른다. (예전 글이나 메모에서 “aggressive decoding”처럼 적기 쉬운데, 정확한 용어는 autoregressive 다.)
이 글에서 Transformer의 내부 동작 원리나 “토큰이 정확히 무엇인가”는 다루지 않는다. 여기서는 “한 번 호출에 한 토큰, 그걸 반복”이라는 그림만 잡으면 충분하다.
3. Thinking, 그리고 Effort / Adaptive Thinking
Claude에는 Effort와 Adaptive Thinking 같은 파라미터가 있는데, 이건 생각(thinking)의 정도를 조절한다.
여기서 Thinking이란, 모델이 입력을 받은 뒤 최종 출력을 내기 전에 먼저 Thinking block을 생성하는 것을 말한다. 비유하자면 답을 쓰기 전에 연습장에 먼저 끄적여 보는 과정이다. Effort나 Adaptive Thinking은 이 연습장을 얼마나 길게 쓸지를 조절한다. 경우에 따라서는 thinking이 아예 일어나지 않을 수도 있다.
4. 모델의 출력: Thinking → tool_use / text
모델은 Thinking을 마친 뒤 출력을 내놓는다. 이 출력은 크게 두 가지다.
- text — 사용자에게 보여주는 텍스트.
- tool_use — sub-agent, grep, glob, read 같은 도구의 사용 요청. 파일을 읽고 쓰거나 검색하는 등 Claude가 쓸 수 있는 도구들이다.
생성 순서는 대략 Thinking → (tool_use들, text) 이다. 그런데 Claude Code 화면에는 보통 text와 tool_use만 보이고 Thinking block은 표시되지 않는다.
이 점이 흔한 오해를 만든다. 예를 들어 “프로젝트를 분석해줘”라고 하면 Claude가 “프로젝트를 분석하겠습니다”라고 답할 때가 있다. 이건 thinking이 아니라, thinking이 끝난 뒤에 tool_use와 함께 생성된 평범한 text일 뿐이다.
중요한 사실 하나. 모델의 입력부터 출력까지, 도구가 실제로 실행되지는 않는다. 모델은 그저 “이 도구를 써 달라”고 요청만 한다. 도구 요청이 있었다면 모델의 마지막 출력에는 stop_reason: tool_use가 담겨, 도구를 실행해야 한다는 신호를 보낸다.
5. Claude Code가 루프를 돌린다
모델이 stop_reason: tool_use로 돌아오면, 이제 Claude Code가 나설 차례다.
- 모델이 요청한 도구들을 실제로 실행한다.
- 요청된 모든 도구가 끝날 때까지 기다린다.
- 각
tool_use와 그 결과(result)를 알맞게 매핑해 컨텍스트에 추가한다. - 그 컨텍스트로 모델을 다시 호출한다.
모델이 더 이상 도구가 필요 없다고 판단하면, 출력의 stop_reason에 end_turn을 담아 “이번 턴을 끝내겠다”고 알린다. Claude Code는 이 신호를 보고 턴을 종료한다.
결국 Claude Code의 동작 방식은 “프롬프트가 들어오면 모델을 반복 호출하는 것” 으로 요약된다. 이 반복 구조를 추상화한 것이 바로 에이전틱 루프다.
6. 루프 속의 루프
흥미로운 점은, 모델 안에서도 루프가 돈다는 것이다.
- 바깥 루프(에이전틱 루프): Claude Code가 모델을 호출하고 → 도구를 실행하고 → 결과를 붙여 다시 호출한다.
- 안쪽 루프(자기회귀 디코딩 루프): 모델 한 번의 호출 안에서, Transformer가 토큰을 하나씩 계속 뽑아낸다.
즉 Claude Code는 루프가 중첩된 구조다. 바깥은 “모델 호출 ↔ 도구 실행”의 에이전틱 루프, 안쪽은 “한 토큰씩”의 자기회귀 디코딩 루프. 우리가 터미널에서 보는 매끈한 한 번의 응답은, 사실 이 두 겹의 루프가 함께 돌아간 결과다.
다루지 않은 것
- Transformer의 구체적인 동작 원리
- 토큰이 정확히 무엇인지
이 둘은 그 자체로 한 편씩 따로 다룰 만한 주제라, 다음 글로 미뤄둔다.