Claude Code를 200줄 Python으로 직접 만들어보기
How to code Claude Code in 200 lines of code
TL;DR Highlight
AI 코딩 에이전트의 핵심 구조가 LLM + 도구 호출 루프라는 걸 200줄 코드로 증명하는 글. 마법처럼 보이는 코딩 에이전트의 실체를 이해하고 직접 만들어볼 수 있다.
Who Should Read
AI 코딩 도구(Claude Code, Cursor 등)를 쓰고 있지만 내부 동작 원리가 궁금한 개발자. 자체 코딩 에이전트를 만들어보고 싶은 개발자.
Core Mechanics
- 코딩 에이전트의 핵심은 놀랍도록 단순하다. 사용자 메시지를 LLM에 보내고, LLM이 도구 호출을 요청하면 로컬에서 실행하고, 결과를 다시 LLM에 돌려주는 루프가 전부다. LLM은 실제로 파일시스템을 건드리지 않고, '이걸 해달라'고 요청만 한다.
- 필요한 도구는 딱 3개: 파일 읽기(read_file), 디렉토리 목록(list_files), 파일 편집(edit_file). 프로덕션 에이전트는 grep, bash, 웹검색 등을 추가하지만, 이 3개만으로도 놀라운 수준의 작업이 가능하다.
- edit_file 도구는 두 가지 모드로 동작한다. old_str이 비어있으면 새 파일 생성, 값이 있으면 해당 문자열을 찾아 new_str로 교체. 실제 IDE는 문자열을 못 찾았을 때의 폴백 로직이 복잡하지만, 기본 동작은 이게 전부다.
- 도구 함수의 docstring이 매우 중요하다. LLM이 어떤 도구를 언제 호출할지 판단하는 데 이 설명을 직접 참고하기 때문에, 도구 설명을 상세하게 쓸수록 에이전트가 더 정확하게 동작한다.
- 도구 정의는 Python 함수의 타입 힌트와 docstring에서 자동으로 JSON Schema를 추출하는 방식으로 처리한다. inspect 모듈로 파라미터 정보를 읽고 Anthropic API가 요구하는 tool 스펙 형식으로 변환한다.
- 메인 루프는 while True 안에서 API 호출 → tool_use 응답 확인 → 로컬 실행 → 결과를 대화 히스토리에 추가하는 과정을 반복한다. tool_use가 아닌 일반 텍스트 응답이 오면 루프가 끝난다.
- 프로덕션 수준으로 가려면 컨텍스트 관리, TODO 리스트(계획 추적), 에러 핸들링, 병렬 도구 호출 등 상당한 추가 작업이 필요하다고 언급하지만, 글에서는 이를 간단한 TODO 항목으로만 남겨둔다.
- Anthropic의 claude-sonnet-4-20250514 모델을 사용하며, 전체 코드가 약 200줄의 Python으로 완성된다. OpenAI 등 다른 LLM 프로바이더로도 동일한 패턴을 적용할 수 있다.
Evidence
- TODO 리스트가 에이전트 성능의 핵심이라는 의견이 여러 댓글에서 반복됐다. Claude Code는 매 프롬프트마다 미완료 TODO를 주입해서 LLM이 '할 일이 남았다'는 걸 잊지 않게 한다. HolmesGPT 팀은 다양한 실험(가설 추적 등)을 했지만 TODO가 항상 가장 효과적이었다고 밝혔고, TODO 도구를 비활성화하면 CTF 문제 해결 능력이 1~2등급 떨어졌다는 실험 결과도 공유됐다.
- 실제 프로덕션 에이전트를 운영하는 개발자가 '월 10억+ 토큰을 처리하는 에이전트를 만들어봤는데, 루프 중간에 사용자가 새 메시지를 보내면 어떻게 할지, 승인/가드레일을 동기로 할지 비동기로 할지, 비동기면 에이전트를 어떻게 다시 깨울지 등 사소해 보이는 문제들이 복합적으로 쌓인다'고 경험을 공유했다.
- Thorsten Ball이 2025년 4월에 이미 'How to Build an Agent, or: The Emperor Has No Clothes'라는 거의 동일한 주제의 글을 먼저 썼다는 지적이 있었다. 이 글이 '에이전트의 핵심은 단순하고 진짜 복잡한 건 LLM 자체'라는 관점을 최초로 대중화했다는 평가.
- 도구가 꼭 여러 개 필요한 건 아니라는 반론도 있었다. bash 실행 도구 하나만 있으면 cat, sed, grep 등 모든 걸 할 수 있으니 50줄이면 충분하다는 의견. 다만 전용 도구는 LLM이 더 쉽게 사용할 수 있어서 성능(정확도) 면에서 유리하다고.
- Claude Code가 경쟁 우위를 갖는 이유는 단순 루프가 아니라, Anthropic이 모델 자체를 특정 도구 사용에 맞춰 RL로 학습시켰기 때문이라는 지적도 있었다. 커스텀 도구를 붙이는 것과 모델이 네이티브로 학습한 도구를 쓰는 건 성능 차이가 크다는 것.
How to Apply
- AI 코딩 도구의 동작 원리를 이해하고 싶다면, 글의 200줄 코드를 직접 타이핑해서 돌려보라. read_file, list_files, edit_file 3개 도구만으로 실제 파일 생성/수정이 되는 걸 체험하면 에이전트 구조가 머릿속에 잡힌다.
- 자체 에이전트를 만들 때는 TODO 리스트 주입을 반드시 구현하라. 매 LLM 호출 시 미완료 작업 목록을 시스템 프롬프트나 메시지에 넣어주면 '할 일을 까먹고 조기 종료'하는 문제가 크게 줄어든다.
- 프로덕션 에이전트에서 file edit 도구는 예상보다 어렵다. 문자열 매칭 실패, 들여쓰기 불일치, 중복 매칭 등 엣지 케이스가 많으므로, Sam Saffron의 edit 구현 리서치(gist 링크)를 참고해서 폴백 로직을 설계하라.
- 도구 수를 최소화하고 싶다면 bash 실행 도구 하나로 시작하는 것도 방법이다. 다만 LLM이 실수할 확률이 높아지므로, 자주 쓰는 작업(파일 읽기/쓰기)은 전용 도구로 분리하는 게 정확도 면에서 유리하다.
Code Example
snippet
import anthropic
from pathlib import Path
client = anthropic.Anthropic()
# 도구 3개 정의 (read_file, list_files, edit_file)
# 메인 루프
while True:
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8096,
system="You are a coding agent...",
tools=tool_specs, # JSON Schema로 변환된 도구 목록
messages=conversation
)
# tool_use 응답이면 로컬에서 실행 후 결과를 conversation에 추가
# 텍스트 응답이면 출력하고 루프 종료Terminology
Tool CallingLLM이 '이 함수를 이런 인자로 실행해줘'라고 구조화된 형식으로 요청하는 것. 사람이 비서에게 메모를 건네며 '이거 처리해줘'라고 하는 것과 비슷하다.
Agent Loop사용자 입력 → LLM 추론 → 도구 실행 → 결과 피드백을 반복하는 루프. 에이전트의 핵심 실행 구조.
Early Stopping에이전트가 작업을 다 끝내지 않았는데 '완료했다'고 판단하고 멈춰버리는 문제. TODO 리스트 주입으로 완화할 수 있다.
RL (Reinforcement Learning)모델이 특정 행동(도구 사용 등)을 잘하면 보상을 주고 못하면 패널티를 줘서 학습시키는 방법. 게임 AI 훈련과 같은 원리.
JSON Schema도구의 입출력 형식을 정의하는 표준 포맷. LLM이 어떤 파라미터를 어떤 타입으로 넘겨야 하는지 이해하는 데 사용된다.
Related Resources
- https://www.mihaileric.com/The-Emperor-Has-No-Clothes/
- https://ampcode.com/how-to-build-an-agent
- https://fly.io/blog/everyone-write-an-agent/
- https://github.com/SWE-agent/mini-swe-agent
- https://github.com/badlogic/lemmy/tree/main/apps/claude-trace
- https://github.com/samsaffron/term-llm
- https://gist.github.com/SamSaffron/5ff5f900645a11ef4ed6c87f2