00. The Agent Loop — 모든 것의 시작
이전 이야기에서: 지민은 Claude Code를 설치하고 첫 실행을 했다. Claude가 스스로 파일을 읽고 분석하는 모습에 놀랐다. "이건 그냥 챗봇이 아닌데?" — 하지만 왜 이렇게 작동하는지는 아직 모른다.
옆 자리 현우가 흘끗 봤다. "그거 그냥 챗봇이잖아. 복사-붙여넣기가 좀 편해진 거지."
"One loop & Bash is all you need" — Harness Engineering
진짜 시작점: Claude는 그냥 텍스트를 반환했다
2022년, Anthropic이 Claude를 출시했을 때 Claude는 텍스트를 받고 텍스트를 반환하는 함수였다.
Input: "이 코드의 버그를 찾아줘"
Output: "3번째 줄에서 null 체크가 빠진 것 같습니다..."
도움이 됐다. 그런데 Claude가 아무리 똑똑해도, 실제 파일을 읽을 수 없었고, 터미널을 실행할 수 없었다. 개발자는 Claude의 답을 보고, 직접 코드를 고치고, 에러 메시지를 복사해서 다시 붙여넣어야 했다.
개발자 자신이 루프였다.
전환점: Tool Use의 등장 (2023)
Anthropic은 Claude API에 tool_use라는 기능을 추가했다.
아이디어는 간단했다: "Claude가 텍스트만 반환하는 게 아니라, '이 함수를 실행해줘'라고 요청할 수 있으면 어떨까?"
# Claude의 응답이 이렇게 바뀌었다
response = {
"stop_reason": "tool_use",
"content": [{
"type": "tool_use",
"name": "bash",
"input": {"command": "cat src/main.py"}
}]
}
이제 Claude가 파일을 읽고 싶다고 요청할 수 있었다. 개발자는 그 요청을 실행하고 결과를 돌려주면 됐다.
그런데 이걸 매번 수동으로 하면... 여전히 개발자가 루프다.
The Loop의 발견: 30줄로 만드는 에이전트
누군가 깨달았다. "자동화하면 되잖아."
코드를 몰라도 괜찮다. 이 30줄이 하는 일은 딱 세 가지다:
Agent Loop가 하는 일 (의사코드):
1. 사용자의 질문을 Claude에게 보낸다
2. Claude가 답한다
└─ "할 말이 있어요" → 대답하고 끝
└─ "이 도구를 실행해주세요" → 3번으로
3. 요청받은 도구를 실행한다 (파일 읽기, 터미널 실행 등)
4. 실행 결과를 Claude에게 다시 보낸다
5. 2번으로 돌아간다 → Claude가 "끝"이라고 할 때까지 반복
핵심은 반복이다. Claude가 "이 파일을 읽어줘" → 읽어서 돌려줌 → "이 코드를 실행해줘" → 실행해서 돌려줌 → "다 됐어요" → 끝. 이 반복이 Agent Loop의 전부다.
실제 Python 코드로 보면:
def agent_loop(query): # 사용자 질문을 받는 함수
messages = [{"role": "user", "content": query}] # 대화 기록 시작
while True: # 무한 반복 (끝날 때까지)
response = client.messages.create( # Claude에게 보내기
model=MODEL, messages=messages, tools=TOOLS
)
if response.stop_reason != "tool_use": # Claude가 "끝"이라고 하면
return # → 여기서 멈춤
# Claude가 "이 도구를 실행해줘"라고 요청한 경우:
for block in response.content:
if block.type == "tool_use": # 도구 실행 요청이면
output = run_bash(block.input["command"]) # 실행하고
results.append({"content": output}) # 결과를 모음
messages.append({"role": "user", "content": results})
# ↑ 결과를 Claude에게 다시 보냄 → while True로 돌아감 → 반복!
while True= "Claude가 끝이라고 할 때까지 계속 돌아" (반복문)client.messages.create(...)= "Claude에게 메시지를 보내고 답을 받아" (API 호출)run_bash(...)= "터미널에서 명령어를 실행해" (도구 실행)messages.append(...)= "대화 기록에 추가해" (기억 쌓기)
이게 전부다. 30줄.
Claude는 이제 스스로 파일을 읽고, 코드를 실행하고, 결과를 보고, 다음 행동을 결정한다. 개발자가 중간에서 복사-붙여넣기를 할 필요가 없다.
핵심 통찰: "모델이 에이전트다"
여기서 중요한 인식의 전환이 일어났다.
흔한 오해: "에이전트를 만들려면 복잡한 프레임워크, 프롬프트 체인, 의사결정 트리가 필요하다."
실제: 에이전트는 이미 Claude 안에 있다.
DeepMind의 DQN, OpenAI Five, AlphaStar... 이 모든 AI 에이전트들이 증명한 것은 하나다: 에이전트는 수십억 번의 학습을 통해 행동하는 법을 배운 모델이다. 코드로 만들어지는 게 아니다.
Claude는 이미 생각하고, 계획하고, 행동하는 법을 안다. 우리가 해야 할 일은 Claude가 일할 수 있는 환경을 만드는 것이다.
Harness: 환경을 설계하는 일
이 환경을 Harness(하네스) 라고 부른다.
Harness = Tools + Knowledge + Context + Permissions
Tools: Claude의 손 — 파일 읽기, 코드 실행, API 호출
Knowledge: Claude의 기억 — 프로젝트 정보, 규칙, 도메인 지식
Context: Claude의 단기 메모리 — 지금까지 한 일
Permissions: Claude의 경계 — 무엇을 할 수 있고 없는지
Claude Code는 이 Harness다.
Claude Code는 Claude를 똑똑하게 만들지 않는다. Claude는 이미 똑똑하다. Claude Code는 Claude에게 손, 눈, 작업 공간을 준다.
Claude Code의 본질
Claude Code를 분해하면:
Claude Code = agent loop (기반)
+ tools (Read, Write, Bash, Glob, Grep, ...) ← 손
+ CLAUDE.md (프로젝트 지식) ← 기억
+ skills (on-demand 지식) ← 전문 지식
+ /compact (context 압축) ← 메모리 관리
+ subagents (context 격리) ← 집중력
+ hooks (permission governance) ← 경계
+ rules (구조화된 지식) ← 조직된 기억
+ MCPs (외부 툴) ← 확장된 손
이 목록의 모든 항목은 Harness 설계 결정이다. 각 항목은 특정 문제를 해결하기 위해 추가됐다. 그리고 각 항목이 추가될 때마다, 새로운 문제가 드러났다.