본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 31. 15:13

최고의 Claude Code 에이전트는 무엇을 거부하는지로 정의된다

요약

효과적인 Claude Code 서브 에이전트 설계를 위해 '무엇을 해야 하는가'보다 '무엇을 거부해야 하는가'에 집중하는 전략을 제시합니다. 에이전트가 불필요하게 방대한 리뷰를 생성하여 신뢰도를 떨어뜨리는 것을 방지하기 위해 명확한 거부 목록(Refusal lists)을 설정하는 방법론을 다룹니다.

핵심 포인트

  • 에이전트의 유용성은 수행 범위의 제한(거부 목록)에서 결정됨
  • 과도하게 상세한 리뷰는 오히려 중요한 신호를 가려 무시하게 만듦
  • LLM의 의욕적인 특성을 제어하기 위해 명시적인 제약 조건이 필수적임
  • 짧고 정직한 보고서가 길고 부풀려진 보고서보다 가치가 높음

요약(TL;DR) — 제가 Claude Code 서브 에이전트(subagent)를 작성할 때, 가장 중요한 부분은 무엇을 해야 하는지에 대한 지침이 아닙니다. 바로 무엇을 거부해야 하는지에 대한 목록입니다. 이 포스트는 그 이유를 설명하고, 머지(merge)하기 전에 코드 차이(diff)에서 당혹스러운 실수들을 잡아내는 실제 약 50줄 규모의 에이전트(무료, MIT 라이선스)를 살펴보는 과정을 담고 있습니다.

너무 도움이 되려 했던 에이전트
제가 처음으로 작성했던, 유용해 보였던 Claude Code 서브 에이전트는 "코드 리뷰어(code reviewer)"였습니다. 프롬프트(prompt)는 당연한 내용이었습니다: "당신은 시니어 엔지니어입니다. 이 diff를 철저히 검토하세요. 버그, 스타일, 명명 규칙(naming), 아키텍처(architecture), 성능(performance), 보안(security), 그리고 테스트 커버리지(test coverage)에 대해 의견을 남기세요."

기술적으로는 작동했습니다. 리뷰를 생성해냈죠. 그것도 매번 아주 길게 말입니다.

그리고 그것이 문제였습니다. 23가지 사항을 지적하는 리뷰는 당신이 그중 단 하나도 읽지 않도록 훈련시킵니다. "여기에 하드코딩된 API 키를 남겨두었습니다"라는 핵심 신호(signal)는 "이것을 헬퍼(helper)로 추출하는 것을 고려해보세요"와 "이 변수 이름은 더 설명적일 수 있습니다" 사이의 14번째 줄에 파묻혀 있었습니다. 저는 출력물을 대충 훑어보기 시작했습니다. 그러다 결국 무시하기 시작했습니다. 무시하게 되는 에이전트는 에이전트가 없는 것보다 더 나쁩니다. 왜냐하면 지연 시간(latency) 비용을 지불했음에도 불구하고, 스스로 "리뷰는 해결되었다"라고 착각하게 만들기 때문입니다.

해결책은 더 나은 "해야 할 일" 목록이 아니었습니다. 오히려 그 반대였습니다.

거부 목록(Refusal lists)
제 에이전트들을 실제로 유용하게 만든 재정의는 다음과 같습니다: 좋은 에이전트는 정확히 하나의 작업만을 가지며, 할 수 있는 상황일지라도 하지 않을 일들에 대한 명시적인 목록을 가집니다.

"하지 않을 일" 목록이 핵심적인 지지 구조입니다. 대규모 언어 모델(LLM)은 의욕적입니다. 더 철저하고, 더 도움이 되고, 더 포괄적이 될 수 있는 어떤 기회라도 주어지면 그것을 붙잡습니다. 제약이 없다면, 모든 에이전트는 모든 것에 대해 코멘트를 다는 비대하고 일반적인(generalist) 형태로 표류하게 됩니다. 거부 목록은 에이전트가 날카로운 전문성을 유지하도록 붙잡아주는 역할을 합니다.

구체적으로, 거부 목록은 다음과 같이 생겼습니다 (머지 전 검사 에이전트의 예시):

규칙(Rules)

  • 자동 수정 (autofix) 하지 마십시오. 사용자가 수정하고, 당신은 검증합니다.
  • 명명 규칙 (naming), 디자인 (design), 아키텍처 (architecture), 또는 "더 깔끔해질 수 있습니다"와 같은 의견을 남기지 마십시오. 그런 일은 다른 도구들이 합니다. 당신의 역할은 더 좁습니다.
  • 보고서를 부풀리지 마십시오. 차단 요소 (blockers)가 없다면, 한 줄로 그렇게 말하십시오. 길고 부풀려진 보고서보다 짧고 정직한 보고서가 낫습니다.
  • 사용자의 명시적인 요청 없이 파괴적인 작업 (데이터베이스 리셋, 파일을 다시 쓰는 --fix 플래그 등)을 실행하지 마십시오.
  • 검사 도구가 설치되어 있지 않다면 "skipped: "라고 말하십시오. 통과 (pass)한 것처럼 속이지 마십시오. 그곳의 모든 줄은 모델이 방황할 수 있는 문을 닫는 역할을 합니다. "보고서를 부풀리지 마십시오"라는 규칙은 모델이 철저해 보이고 싶어 하기 때문에 존재합니다. "통과한 것처럼 속이지 마십시오"라는 규칙은 모델이 당신에게 좋은 소식을 전하고 싶어 하기 때문에 존재합니다. 당신은 작업을 설명하는 것이 아니라, 행동의 범위를 울타리로 제한하는 것입니다.

실제 사례: 90초짜리 머지 전 검사 (pre-merge check)
제가 실제로 모든 프로젝트에서 사용하는 에이전트를 통해 이를 구체화해 보겠습니다. 이 에이전트의 임무는 단 하나입니다. 당신이 PR (Pull Request)을 올리기 전에, PR 리뷰에서 당신을 당황하게 만들 만한 요소들을 잡아내는 것입니다. 남아있는 console.log, 하드코딩된 키 (hardcoded key), 삭제하는 것을 잊은 .skip, diff에 포함된 .DS_Store 같은 것들 말이죠.

그 형태는 다음과 같습니다 (전체 파일은 GitHub, MIT 라이선스 — 링크는 끝에 있습니다):

name: shipping-coach
description: "최종 머지 전 / 배포 전 검사로 사용하십시오. diff에 대해 빠르고 주관적인 체크리스트를 실행합니다. "ready to ship", "pre-flight", "before I merge", "final check" 시점에 트리거됩니다.
tools: Bash, Read, Grep, Glob

model: inherit

당신은 코드가 배포되기 전 마지막으로 확인하는 눈입니다. 빠르고, 구체적이며, 반박하기 어렵게 행동하십시오.

체크리스트 (Checklist) (가능한 경우 병렬 실행)

1. 디버그 잔해 (Debug residue)

diff에서 다음을 검색하십시오: console.log, print(, debugger, .only(, .skip(, 새로운 TODO/FIXME. 이번 diff에 의해 추가된 (ADDED) 일치 항목만 보고하십시오.

2. 비밀 정보 유출 (Secret leaks)

API 키 형태 (sk-, ghp_, AKIA, AIza), .env 내용, URL 내의 자격 증명 (credentials), 개인 키 (private keys)를 검색하십시오. 일치하는 항목이 있다면 즉시 중단 (stop-the-line) 조치하십시오.

3. 타입 / 린트 / 테스트 상태 (Type / lint / test status)

package.json / Makefile / pyproject.toml에서 프로젝트의 체크 명령어를 감지하십시오. typecheck를 실행한 다음, lint를 실행하고, 그 다음 테스트를 실행하십시오. 첫 번째 실패가 발생하면 중단하십시오.

4. 추적된 불필요한 파일 (Tracked junk)

.DS_Store, .env, node_modules/, .gitignore를 통과하여 몰래 들어온 빌드 결과물(build output)이 있는지 확인하십시오.

출력 형식 (Output format)

배포 전 보고서 (Pre-ship report) (소요 시간: )

차단 요소 (Blockers) (N) <- 차단 요소가 없는 경우 빈 헤딩으로 남겨두며, 절대 생략하지 마십시오.

살펴볼 가치가 있는 항목 (Worth a look) (N)

통과됨 (Passed)

여기에 포함된 세 가지 설계 선택 사항은 언급할 가치가 있습니다. 왜냐하면 이것이 당신이 신뢰하는 에이전트와 당신이 음소거(mute)해버리는 에이전트를 가르는 차이점이기 때문입니다:

  1. "이 diff에 의해 추가된(ADDED) 항목만 보고하십시오." 이 설정이 없다면, 에이전트는 저장소에 이미 존재하는 모든 console.log를 지적할 것이고, 보고서는 즉시 노이즈가 됩니다. 범위(Scope)는 코드베이스가 아니라 diff여야 합니다. 단 한 문장이지만, 신호(signal)의 차이는 엄청납니다.

  2. "Blockers" 섹션이 절대 생략되지 않는 고정된 출력 형식. 차단 요소가 하나도 없을 때조차 헤딩은 유지됩니다 ("Blockers (0)"로 표시). 이것이 까다롭게 들릴 수 있지만, 이는 신뢰 메커니즘입니다. 당신은 보고서의 형태를 학습하게 되고, 따라서 2초 만에 보고서를 읽고 정확히 어디를 봐야 할지 알 수 있습니다. 가변적인 형태의 출력은 매번 다시 읽게 만듭니다.

  3. 도구(tools): Bash, Read, Grep, Glob — 그 외에는 아무것도 없습니다. Write(쓰기)도, Edit(편집)도 없습니다. 에이전트는 도구를 부여받지 않았기 때문에 원하더라도 당신의 파일을 수정할 수 없습니다. 도구 범위 지정(Tool scoping)은 프롬프트가 지킬 것이라고 기대하는 약속이 아니라, 스키마(schema) 수준에서 강제하는 가드레일(guardrail)입니다.

직접 구축해 보십시오.
이 패턴은 일반화될 수 있습니다. 실제 diff로부터 PR 설명을 작성하는 것, 당신의 변경 사항이 깨뜨릴 수 있는 동작을 찾는 것, 의존성(dependencies)을 감사하는 것 등 어떤 좁은 작업이든 선택하여 다음과 같이 에이전트를 작성하십시오:

한 문장으로 명시된 단 하나의 작업.
디스패처(dispatcher)가 실제로 라우팅할 수 있는 설명 — 추상적인 능력에 대한 주장 대신, 트리거 문구("사용자가 X라고 말할 때")로 작성하십시오.
도구 범위 지정 (Tool scoping) — 해당 작업에 필요한 도구만 부여하십시오. 보고만 해야 하는 작업에는 쓰기/편집 (Write/Edit) 권한을 제한하십시오.
출력 형식 — 결과물을 파이프라인으로 연결하거나(pipeable) 빠르게 훑어볼 수 있도록(skimmable) 설정하십시오.
거부 목록 (Refusal list) — 당신이 닫아두려는 문입니다. 이것은 모두가 건너뛰는 부분이지만, 가장 중요한 부분입니다.
파일을 ~/.claude/agents/에 넣기만 하면 Claude Code가 자동으로 인식합니다. 프레임워크도, 설정도 필요 없습니다.

무료 에이전트 + 더 깊이 알아보기
위에서 소개한 shipping-coach 에이전트는 무료이며 MIT 라이선스가 적용됩니다. 전체 내용이 약 50줄 정도의 .md 파일 하나로 구성되어 있어 직접 읽고, 포크(fork)하고

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0