Claude Code로 하루 3개 프로젝트, 949 tool calls 후기
어제 하루 Claude Code에서 949번의 tool call이 발생했다. 세션 3개, 약 11시간. 모두 다른 프로젝트였다.
TL;DR 치과 웹사이트(uddental), LLM 멀티에이전트 라우터(llmmixer), 포트폴리오 허브 전환(portfolio-site)을 같은 날 병렬로 진행했다. 핵심 교훈은 “컨텍스트 스위칭은 Claude가, 방향 결정은 내가”였다.
세션 1: 치과 사이트를 4시간 52분 만에 리디자인하다
오전에는 uddental 프로젝트였다. 용인 동백에 있는 유디치과 홈페이지 리디자인.
시작 프롬프트는 단순했다. “메인에서 치과 사진들을 번갈아가면서 보여주고, 거기에 정보를 써줘.” 이게 전부였다. 레이아웃 스케치도, 디자인 시안도 없었다.
Claude가 히어로 슬라이더를 만들었다. 6장의 사진이 4.5초 간격으로 crossfade 전환되고, 그 위에 치과명과 CTA가 올라가는 구조. 여기까지는 잘 됐다.
문제는 그 다음이었다. Date.now()로 현재 진료 상태를 서버에서 렌더링하자 hydration error가 터졌다.
A tree hydrated but some attributes of the server rendered HTML
didn't match the client properties.
원인은 명확했다. 서버 렌더링 시의 시간과 클라이언트에서 다시 계산한 시간이 달랐다. Next.js SSR + Date.now() 조합의 고전적인 함정. useEffect 안으로 이동하고, 초기 상태는 서버/클라이언트 모두 동일한 값으로 잡아서 해결했다.
이날 Bash를 110번, Edit을 105번 썼다. 비율이 거의 1:1이다. 코드를 읽고 수정하는 작업이 그만큼 반복됐다는 뜻이다.
디자인 방향은 대부분 스크린샷 한 장으로 전달했다. “이렇게” + 스크린샷. Claude는 스크린샷에서 레이아웃을 읽어내고 코드로 옮긴다. 설명을 길게 쓰는 것보다 참고 이미지 하나가 훨씬 빠르다.
세션 2: 빈 레포에서 LLM 라우터를 2시간 35분 만에
오후 세션은 완전히 다른 종류의 작업이었다. llmmixer_claude — Claude, Codex, Gemini를 상황에 따라 라우팅하는 멀티에이전트 오케스트레이터.
레포는 비어있었다. 커밋 하나도 없는 상태.
/Users/jidong/Downloads/SPEC.md를 넘기고 말했다. “구현계획을 조금 촘촘하게 일단 세워서 구현계획 md를 만들어줘.”
그 다음 프롬프트가 이번 세션에서 가장 중요했다.
“각 phase 구현하고 구현사항에 대해 피드백 객관적으로하고, 수정하는 과정을 완벽해질때까지 최대 3번 수행해줘, 그리고 다음 Phase로 넘어가면서 구현해줘”
이게 Claude Code를 쓸 때 가장 효과적인 패턴 중 하나다. 구현 → 셀프 리뷰 → 수정을 최대 3회까지 반복하게 하는 것. “완벽해질 때까지”라는 조건을 붙이면 Claude가 스스로 품질 기준을 세운다.
Phase 0에서 workspace:* 프로토콜 오류가 났다. npm 모노레포에서 흔히 보이는 문제. 패키지 참조 방식을 수정하고 넘어갔다. 여기서 Bash를 149번, Write를 93번 썼다. 새로 만드는 파일이 많을 때 Write가 높아지는 패턴이다. 이 세션에서만 파일 70개 이상이 생겼다.
그런데 이 세션에서 흥미로운 에러가 있었다. Gemini CLI 인증 처리를 구현하다가 posix_spawnp failed가 떴다. 하위 프로세스를 직접 생성하는 코드에서 실행 권한 문제였다. 이런 에러는 Claude한테 에러 로그를 그대로 붙여넣는 게 가장 빠르다. 설명 없이 로그만 던져도 맥락을 파악하고 수정한다.
세션 3: 포트폴리오 사이트를 AI 뉴스 사이트에서 프로젝트 허브로
저녁 세션이 portfolio-site였다.
jidonglab.com은 원래 AI 뉴스 자동화 사이트로 쓰고 있었다. 근데 지인한테 포트폴리오를 보여줄 일이 생기면 항상 문제였다. “AI 뉴스는 잘 되는데, 내가 뭘 만들었는지는 어디서 봐요?” 이 질문에 대답을 못 했다.
그래서 방향을 바꿨다. 프로젝트 포트폴리오 허브로.
구현 스펙은 미리 작성해서 Claude에 넘겼다. 프롬프트는 이렇게 시작했다.
Implement the following plan:
# jidonglab 포트폴리오 허브 리뉴얼
...
자연어 설명보다 마크다운 스펙이 훨씬 정확하다. “이렇게 만들어줘”보다 “이 스펙을 구현해줘”가 결과 품질이 높다. Claude는 스펙을 그대로 따라가기 때문에 방향이 흔들리지 않는다.
이번 세션에서 가장 가치 있던 작업은 parse-sessions.py였다. .claude/projects/ 아래 쌓이는 .jsonl 파일을 파싱해서 빌드 로그를 자동 생성하는 스크립트다. 내가 Claude Code로 작업한 내용이 자동으로 블로그 글로 바뀌는 구조.
지금 이 글도 그 파이프라인을 통해 나온 세션 요약을 기반으로 쓴 것이다.
근데 세션 도중에 GitHub API 403이 떴다.
github api error 403
Admin 페이지에서 프로젝트 상태를 변경할 때 GitHub API를 직접 호출하는 코드가 있었는데, 토큰 권한 설정이 빠져 있었다. 환경변수 확인하고, API 엔드포인트 수정하고, 완전히 돌아갈 때까지 수정했다. 에러 메시지 자체보다 “테스트해서 완벽하게 돌아갈 때까지 수정해”라고 지시하는 게 효과적이다. 중간 에러 상황을 Claude가 알아서 추적하고 수정한다.
하루 동안 배운 것
세 세션을 통틀어서 Bash가 417번, Edit이 200번이었다. Bash가 Edit보다 두 배 많다. 이게 흥미로운 패턴이다. 코드 수정보다 실행 + 확인 + 재실행 사이클이 더 자주 돈다는 뜻이다.
컨텍스트 스위칭을 나는 거의 안 했다. uddental에서 llmmixer로, llmmixer에서 portfolio-site로. 전환할 때마다 Claude는 해당 프로젝트 맥락을 처음부터 읽어들인다. 내가 “지금은 portfolio-site야”라고 말하면 된다.
단, 방향 결정은 여전히 내가 해야 한다. “AI 뉴스 사이트에서 포트폴리오 허브로 바꾸자”는 판단은 Claude가 내릴 수 없다. 그 결정을 내리고 스펙으로 만들어 넘기는 게 내 역할이다.
949번의 tool call 뒤에 남은 건 코드가 아니라, 어디에 집중할지를 결정하는 판단력이다.
Comments 0