Claude Code 등 에이전틱 코딩 도구를 대거 시도해 보며 결국 정착하지 못한 자동화와 워크플로우를 정리했다. 슬래시 명령어, 훅, 프린트 모드, 하위 작업/에이전트 등에서 무엇이 왜 잘 안 됐는지, 그리고 결국 남긴 단순한 규칙과 배운 점을 공유한다.
2025년 7월 30일 작성
Claude Code와 다른 에이전틱 코딩 도구들이 큰 인기를 끌고 있다. 다운로드도 수백만이고, 워크플로우를 단축하는 기능도 계속 늘고 있다. 알다시피 저는 5월에 에이전틱 코딩에 꽤 들떴고, 그때 이후로 추가된 새 기능들을 많이 시험해 봤다. 제 할 일 목록에 있는 것들을 상당한 시간 들여 살펴봤다.
그런데 의외로, 시도했던 것들 중 계속 쓰게 된 게 별로 없었다. 대부분은 오래가지 못했다. 그래서 잘 안 먹힌 것들을 공유하면 흥미롭지 않을까 했다. 이게 곧 그 접근법들이 틀렸다거나 나쁜 아이디어라는 뜻은 아니다. 다만 제가 제대로 작동하게 만들지 못했다는 뜻이다. 다른 분들께도 실패에서 배울 만한 게 있을지 모른다.
제가 쓰는 접근을 가장 잘 요약하면 이렇다.
작동하지 않는 자동화는 생각보다 흔하다. 제가 그걸 쓰지 않게 되거나, 잊어버리거나, 미세 조정만 하다가 끝나기도 한다. 저에게는 실패한 워크플로 도우미를 지우는 게 매우 중요하다. 쓰이지 않는 Claude 명령이 작업공간을 어지럽혀 다른 사람을 헷갈리게 해서는 안 된다.
그래서 저는 대부분 가장 단순한 방식으로 한다. 기계와 더 많이 이야기하고, 더 많은 컨텍스트를 주고, 음성 입력을 계속 켜 두고, 생각의 흐름을 프롬프트에 쏟아 붓는다. 이게 제 워크플로의 95%다. 나머지는 복사/붙여넣기의 적절한 활용 정도다.
슬래시 명령어는 프롬프트를 미리 로드해 세션에서 곧바로 쓸 수 있게 해준다. 저는 이게 더 유용할 줄 알았는데 기대만큼은 아니었다. 쓰긴 쓰지만, 만들어 둔 것들 중 상당수는 결국 한 번도 안 쓰게 됐다.
슬래시 명령어에는 몇 가지 제약이 있어 유용성이 떨어진다. 하나는 인자를 전달하는 방식이 하나뿐이고, 그마저도 비구조적이라는 점이다. 제 용도에는 실전에서 비최적이었다. 또 하나는 Claude Code에서 슬래시 명령어를 쓸 때 그 인자가 파일 기반 자동완성을 지원하지 않는다는 점이다.
이걸 보완하려고, 저는 종종 현재 Git 상태를 사용해 어떤 파일을 대상으로 할지 Claude가 스스로 판단하게 한다. 예컨대 이 블로그에서는 문법 오류를 고치는 명령을 하나 갖고 있다. 자동완성이 없으니 파일명을 일일이 넘기는 게 번거롭기 때문에, 사실상 현재 git status 컨텍스트만으로 거의 전부를 처리한다.
제가 실제로 쓰는 몇 안 되는 슬래시 명령어 중 하나는 이렇다.
git status위 정보를 바탕으로, 언급된 파일(들)의 문법 오류를 고쳐라. 나중에 비교(diff)할 수 있도록 백업을 만들어라(예: file.md를 file.md.bak으로). 백업 파일이 이미 있으면 삭제하라.
블로그 글이 명시적으로 주어졌다면 그것을 고치고, 아니라면 변경사항이 있거나 추적되지 않은 파일들을 고쳐라.
지금은 거의 항상 Claude가 Git status만으로 어떤 파일을 말하는지 알아챈다는 가정하에 일한다. 그래서 대부분의 경우 명시적 인자는 필요 없다.
한때 만들어 놓고 결국 쓰지 않게 된 슬래시 명령어들 중 일부는 다음과 같다.
/fix-bug: GitHub 이슈를 가져오고 추가 컨텍스트를 붙여 버그를 고치라고 하는 명령을 썼다. 그런데 그냥 GitHub 이슈 URL을 언급하고 어떻게 고칠지 제 생각을 말하는 것 대비 의미 있는 개선을 못 봤다./commit: 좋은 커밋 메시지를 쓰게 하려 했지만 제 스타일과 잘 맞지 않았다. 이 명령은 쓰지 않게 됐지만, 아이디어 자체를 포기한 건 아니다./add-tests: 정말 기대했던 명령이다. 개발 중에는 테스트를 건너뛰고, 마지막에 정교한 재사용 프롬프트로 제대로 테스트를 생성하게 하려는 생각이었다. 하지만 이 접근은 자동 테스트 생성 대비 일관된 개선을 보여주지 못했다. 자동 생성 자체도 아직 만족스럽지 않다./fix-nits: 린트 이슈를 고치고 포매터를 돌리는 명령이었다. 근육 기억으로 굳지 못했고, 애초에 Claude가 이런 건 이미 잘한다. CLAUDE.md 파일에 그냥 "fix lint"라고 쓰면 된다. 굳이 슬래시 명령어가 필요 없다./next-todo: 사소한 할 일은 to-do.md 파일에 적어 두고, 다음 항목을 가져와 작업하게 하는 명령이 있었다. 그런데 이 경우에도 워크플로 자동화가 큰 도움은 되지 않았다. 기대보다 훨씬 덜 쓴다.그렇다면 슬래시 명령어를 덜 쓴다면, 대신 무엇을 할까?
LLM이 애매모호하게 동작한다는 특성상, 복사/붙여넣기는 정말, 정말 유용하다. 예컨대 필요할 때 붙여 넣을 링크 모음집을 유지한다. 가끔은 파일들을 미리 가져와 git 무시 폴더에 떨어뜨리고, 그 사실을 언급하기도 한다. 단순하고 쉽고 효과적이다. 물론 컨텍스트를 과하게 오염시키지 않도록 선별은 해야 하지만, 모델이 엉뚱한 곳을 뒤지게 놔두는 것보다는 텍스트를 좀 더 주는 편이 해가 덜하다.
훅을 어떻게든 잘 써 보려 노력했지만 아직 효율 향상을 보지 못했다. 제 문제의 일부는 YOLO 모드를 쓴다는 데 있는 것 같다. 훅이 실제로 실행될 내용을 조작할 수 있으면 좋겠다. 지금 Claude를 유도하는 유일한 방법은 deny 규칙인데, YOLO 모드에서는 이게 통하지 않는다. 예컨대 기본 Python 대신 uv를 쓰게 하려고 훅을 시도했지만 실패했다. 대신 PATH에 기본 실행 파일을 덮어쓰는 래퍼 실행파일들을 미리 올려 놓아 Claude가 올바른 도구를 쓰도록 유도했다.
예를 들면, python 대신 uv run python을 더 안정적으로 쓰게 만드는 제 꼼수는 이렇다:
#!/bin/sh
echo "This project uses uv, please use 'uv run python' instead."
exit 1
.claude/interceptors에 이런 것들을 여러 개 두고, Claude를 실행하기 전에 그 폴더를 PATH 앞에 미리 올린다:
CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR=1 \
PATH="`pwd`/.claude/interceptors:${PATH}" \
claude --dangerously-skip-permissions
또, 적절한 타이밍에 훅을 거는 것도 어렵다고 느꼈다. 긴 편집 세션 끝에 포매터를 돌릴 수 있으면 좋겠다. 현재는 Edit 도구 작업마다 포매터를 돌려야 해서 Claude가 파일을 다시 읽게 만들고, 컨텍스트를 낭비한다. Edit 도구 훅이 있어도 계속 쓸지는 모르겠다.
다른 사람들은 훅을 잘 쓰는지 정말 궁금하다. 트위터에서 꽤 괜찮은 활용법을 봤다는 얘기도 들었지만, 저는 훨씬 더 단순한 해법으로 갔다.
처음에는 Claude의 프린트 모드에 매우 긍정적이었다. 내부적으로 프린트 모드를 사용하는 스크립트를 Claude가 생성하도록 꽤 노력했다. 예를 들어, 대체로 결정적이고 일부만 추론이 필요한 모의 데이터 로딩 스크립트를 Claude Code로 만들게 했다.
문제는 신뢰성을 확보하는 것인데, 제게는 아직 잘 안 됐다. 프린트 모드는 느리고 디버깅이 어렵다. 그래서 개념은 정말 마음에 들지만, 기대만큼 자주 쓰지는 못한다. Claude SDK를 쓰든 커맨드라인의 print 플래그를 쓰든, 기대했던 결과를 얻지 못했다.
제가 프린트 모드에 끌리는 이유는, 순수 추론은 슬롯머신 같기 때문이다. 많은 프로그래밍 작업은 사실 꽤 엄격하고 결정적이다. 린터와 포매터를 사랑하는 이유가 바로 모호함이 없기 때문이다. 완전히 자동화할 수 있는 건 자동화해야 한다. 추론이 필요 없는 작업에 LLM을 쓰는 건 제 기준으로는 잘못된 접근이다.
그래서 프린트 모드가 매력적이다. 잘만 작동한다면 말이다. 커밋 메시지는 LLM이 쓰게 하되, 커밋과 gh pr 같은 명령은 일반 스크립트로. 모의 데이터 로딩은 90%를 결정적으로 만들고 10%만 추론으로.
지금도 쓰긴 하지만, 현재 활용하는 것보다 잠재력이 훨씬 크다고 느낀다.
기본적인 병렬화와 컨텍스트 분리를 위해 Task 도구는 자주 쓴다. Anthropic이 최근 이 과정을 간소화하려는 Agents 기능을 출시했지만, 더 쉬워졌다는 느낌은 못 받았다.
하위 작업과 하위 에이전트는 병렬화를 가능하게 해 주지만, 주의가 필요하다. 특히 읽기와 쓰기가 섞인, 병렬화가 잘 안 되는 작업은 혼란만 키운다. 탐색적 작업을 제외하면 좋은 결과를 얻지 못했다. 하위 에이전트가 컨텍스트를 더 잘 보존해 주긴 해야 하는데, 저는 종종 새 세션을 시작하거나, 생각을 마크다운 파일에 적거나, 아예 챗 인터페이스에서 o3로 바꾸는 편이 더 낫다.
워크플로 자동화에서 흥미로운 점은, 개발자로서 일관되게 따를 엄격한 규칙이 없다면, 기계와 시간을 들여 대화하며 명확한 지시를 하는 편이 공들여 작성한 프롬프트들보다 성과가 낫다는 것이다.
예를 들어 저는 이모지나 커밋 프리픽스를 쓰지 않는다. PR 템플릿도 강제하지 않는다. 결과적으로 기계에게 가르칠 구조가 적다.
또, 제가 만든 워크플로들을 꼼꼼히 평가할 시간과 동기가 부족하다. 그래서 그 가치에 확신을 갖기 어렵다.
컨텍스트 엔지니어링과 관리가 여전히 큰 도전이다. 에이전트가 여러 파일과 명령에서 올바른 데이터를 끌어오도록 돕기 위해 애써도, 아직 안정적으로 성공하지 못한다. 너무 많이, 혹은 너무 적게 끌어온다. 세션이 길어지면 초반 컨텍스트를 잊어버린다. 수동으로 하든 슬래시 명령어로 하든 결과가 너무 랜덤하게 느껴진다. 임기응변으로도 어려운데, 정적인 프롬프트와 명령으로는 더 어렵다.
그래서 지금 제 규칙은 이렇다. 무언가를 자동화하고 싶다면, 먼저 그 일을 몇 번 직접 해 본 뒤에, 자동화를 통해 에이전트가 실제로 더 나은 결과를 내는지 평가한다. 정밀한 과학은 아니지만, 현재는 같은 작업을 세 번 시켜 보고, 결과를 제가 수용할 수 있는지 기준으로 편차를 눈으로 본다.
자동화를 평가하도록 스스로를 강제하면 또 다른 이점이 있다. 무지성으로 도움이 된다고 가정해 버릴 가능성이 줄어든다.
LLM 기반 자동화에는 큰 숨은 위험이 있다. 정신적 이탈을 부추긴다는 점이다. 엔지니어처럼 생각하기를 멈추면 품질이 떨어지고, 시간이 낭비되며, 이해와 학습이 이뤄지지 않는다. LLM만으로도 이미 문제 소지가 충분한데, 자동화에 더 기대면 더더욱 이탈이 쉬워진다. 시간이 지날수록 에이전트의 능력을 과대평가하게 되는 경향이 있다. 거기엔 진짜 위험이 도사리고 있다!
도착한 산출물을 그때그때 리뷰할 수는 있지만, 나중으로 미룰수록 점점 더 어려워진다. LLM이 리팩터링 비용을 낮춰 주고는 있지만, 0이 되는 건 아니며, 회귀도 흔하다.
이 글의 태그는 ai, thoughts 그리고 vibecoding입니다.