AI를 자율적인 팀원으로 만드는 법: 판단과 구현을 도구 권한으로 나누기¶
사람으로 꾸린 팀에서는 설계를 검토하는 사람과 코드를 짜는 사람이 다르기 때문에 리뷰가 의미를 가집니다. AI 에이전트 하나에게 "설계하고, 구현하고, 검토까지 해 줘"라고 맡기면 이 분리가 사라집니다. 자기가 짠 코드를 자기가 검토하면 통과시키기 쉽습니다. 이 글은 에이전트를 팀원처럼 쓰기 위해 판단하는 역할과 구현하는 역할을 나누고, 그 경계를 도구 권한으로 고정한 방법을 정리합니다. 블로그 운영 저장소와 운동 기록 앱 저장소에 실제로 적용한 규칙, 그리고 같은 구조를 실습으로 돌려 잰 결과를 함께 담았습니다.
이 글의 기준
2026년 4월에 올린 같은 주제의 글은 유튜브 영상 한 편을 요약한 것이었습니다. 2026-10-24에 직접 운영하는 프로젝트의 규칙 파일(CLAUDE.md, 에이전트 정의)과 개인 위키의 실습 실측값으로 전면 다시 썼습니다. 실습 실측은 2026-10-05, Claude Code 2.1.289 기준입니다. 하네스 엔지니어링 전반과 사고 사례는 하네스 엔지니어링 실무 메모에 따로 정리했고, 이 글은 그중 역할 분리 하나만 다룹니다.
1. 역할은 지시문이 아니라 도구 목록으로 나눈다¶
"너는 검증만 해"라는 지시문은 긴 세션에서 새어 나갑니다. 검증하던 에이전트가 어느 순간 직접 고치기 시작하면 검증자와 구현자가 다시 하나가 됩니다. 그래서 이 블로그 저장소에서는 역할마다 하면 안 되는 일을 에이전트 정의 파일의 tools 목록에서 빼 두었습니다.
| 역할 | 허용 도구 | 빠진 도구 | 막히는 행동 |
|---|---|---|---|
| Advisor(판단·검증·커밋 승인) | Read, Grep, Glob, Bash, Edit, Task | Write | 새 파일을 만드는 구현 노동 |
| Worker(구현) | Read, Write, Edit, Bash, Glob, Grep | Task | 다른 에이전트에게 다시 맡기기 |
| Reviewer·Fact-checker(검토) | Read, Glob, Grep, Bash(+웹 조회) | Write, Edit | 검토하다가 직접 고치기 |
| Originality-guard(원본 대조) | Read, Glob, Grep, WebFetch | Write, Edit, Bash | 대조하다가 수정·실행하기 |
Advisor에게 "구현하지 마"라고 부탁하는 대신 Write를 주지 않은 것입니다. 검토 역할에게는 Edit조차 없어서, 기본 경로로 할 수 있는 일은 판정과 근거를 보고하는 것뿐입니다. git commit은 Advisor만 하고, Worker는 작업 트리만 바꾼 채로 둡니다.
다만 이 장치가 완전한 차단은 아닙니다. Advisor에게는 검증용 Bash가 있어서 cat > 파일 같은 셸 명령으로 파일을 쓸 수 있습니다. 위키 실습에서 이 우회는 0건이었지만, 도구 제한은 기본 경로를 막는 장치이고 나머지는 규칙 문장이 맡는다고 보는 편이 정확합니다.
교훈: 역할 분리의 핵심은 누가 무엇을 하느냐보다 누가 무엇을 할 수 없느냐입니다.
2. 위임의 품질은 브리프가 정한다¶
판단과 구현을 나누면 둘 사이를 잇는 지시서가 생깁니다. 이 저장소의 CLAUDE.md는 Advisor가 Worker에게 주는 브리프를 여섯 칸으로 고정합니다. [목표], [컨텍스트], [컨벤션], [함정], [완료 기준], [범위 경계]입니다. 설계 원칙은 하나입니다. Worker가 같은 파일을 다시 뒤지지 않도록 Advisor가 이미 알아낸 것을 다 담는다.
위키 실습에서 장바구니 할인 규칙을 바꾸는 요구(5만 원 이상 20% 할인)를 주었을 때 Advisor가 실제로 쓴 수정 브리프입니다. 경로와 일부 문장은 줄였습니다.
[목표] cart.js 의 totalPrice에 "소계 50,000원 이상이면 20% 할인" 구간을 추가.
[컨텍스트] 현재 구현: subtotal >= 10000 이면 Math.round(subtotal * 0.9), 아니면 subtotal.
마지막 케이스 [{price:25000, qty:2}] → 40000 기대.
[컨벤션] 기존 스타일 유지(early return, Math.round). 최소 diff.
[함정] 50000 체크가 10000 체크 뒤에 오면 절대 도달 못 함 — 반드시 앞에. 할인 중첩 금지.
[완료 기준] `node cart.test.js` 가 두 PASS 줄 출력, exit 0.
[범위 경계] cart.js만 수정. 테스트·package.json 건드리지 말 것. 커밋하지 말 것.
고칠 줄의 위치와 그 위치의 함정까지 브리프에 들어 있습니다. 판단은 Advisor가 끝냈고, Worker에게는 옮겨 적고 완료 기준을 확인하는 일만 남았습니다. Worker가 보고한 뒤 Advisor는 git diff를 읽고 테스트를 자기 손으로 다시 돌린 다음에야 커밋했습니다.
교훈: [완료 기준]은 "끝"을 실행 가능한 명령으로 바꾸고, [범위 경계]는 "겸사겸사 리팩터링"을 막는 울타리가 됩니다. 이 두 칸이 비어 있으면 위임이 아니라 떠넘기기입니다.
3. 예외 규정을 크기로 적으면 우회된다¶
모든 일을 위임하면 오타 하나 고치는 데도 브리프를 써야 합니다. 그래서 예외 규정이 필요한데, 이 규정을 어떻게 적느냐에 따라 결과가 정반대로 나왔습니다.
| 실측 | 예외 규정 문구 | 할인 구간 추가(한 줄 로직 수정) | 주석 오타 수정 |
|---|---|---|---|
| 2026-07-12 | "한두 줄 수정은 직접 처리" | Advisor가 2회 모두 위임 없이 직접 수정 | — |
| 2026-10-05 | "테스트 기대값이 바뀌는 로직 수정은 한두 줄이라도 위임" | 수정 브리프로 위임(265초, $0.19) | 위임 0회, 직접 수정(129초, $0.08) |
할인 구간 추가는 실제로 한 줄짜리 수정이라 크기 기준을 그대로 적용하면 "직접 처리" 대상이 됩니다. 에이전트는 규칙을 어긴 것이 아니라 규칙을 해석한 것입니다. 기준을 크기에서 동작 변경 여부로 바꾸자 한 줄짜리 로직 수정은 위임되고 한 글자짜리 오타는 직접 처리되었습니다.
이 글을 쓰며 운영 중인 파일을 다시 열어 보니, 블로그 저장소 CLAUDE.md에는 "한두 줄 수정처럼 위임 오버헤드가 더 큰 일은 직접 처리한다", 운동 기록 앱 저장소에는 "한 줄 수정 같은 소소한 작업까지 에이전트를 띄우지는 않는다"가 아직 남아 있었습니다. 앱 저장소에는 "도메인 로직·DB·엔진을 건드린 변경은 리뷰와 테스트 없이 완료로 보고하지 않는다. 문서·주석만 바꾼 변경은 게이트 생략 가능"이라는 동작 기준 규칙이 함께 있어 구멍이 일부 메워져 있습니다.
교훈: 예외는 "얼마나 작은가"가 아니라 "동작이 바뀌는가"로 적습니다. 실험으로 확인한 규칙은 운영 파일에 옮겨야 끝납니다.
4. 검토자는 거부할 수 있어야 신호가 된다¶
실습에서는 Worker도 완료 기준을 스스로 돌려 보고하기 때문에 검증 게이트가 거부하는 장면이 거의 나오지 않았습니다. 실제 운영에서는 달랐습니다.
| 날짜 | 프로젝트 | 검토 역할 | 거부한 내용 | 처리 |
|---|---|---|---|---|
| 2026-07-16 | 블로그 | fact-checker·originality-guard | 신규 3글 전원 REVISE. 1인칭 경험 참칭, 실존하지 않는 설치 명령, 창작 수치 | 수정 후 재검수 PASS만 발행 |
| 2026-07-17 | 블로그 | fact-checker(7배치 병렬) | 기존 50글에서 모델명·제품 사양·논문 제목 오류, 스킬 저작자 오귀속 | 근거 링크로 정정 |
| 2026-10-05 | 운동 기록 앱 | qa-reviewer | 워치 화면에서 40mm·긴 종목명·세 자리 숫자일 때 가운데 숫자가 잘림 | 빌드 중단, 1차 AAB 폐기, 수정 PR 후 게이트 재실행 |
세 경우 모두 검토 역할에게 수정 권한이 없었습니다. 그래서 검토자가 "내가 고치면 되지"로 넘어갈 수 없었고, 발견 사항은 구현 역할에게 돌아가는 수정 지시가 되었습니다. 앱 저장소의 규칙은 이를 "tester는 코드를 수정하지 않고, qa-reviewer는 구현하지 않고, advisor는 코드보다 결정을 담당한다. 수정은 항상 구현 역할에게 돌려보낸다"라고 적고 있습니다.
교훈: 게이트의 가치는 거부 빈도가 아니라 거부할 수 있다는 사실에 있습니다. 거부가 가능해야 통과가 의미를 가집니다.
5. 역할별 모델 고정은 버전마다 확인한다¶
판단과 구현은 요구하는 능력이 달라서 모델도 따로 고정할 수 있습니다. 블로그 저장소는 에이전트 정의 frontmatter의 model:로 Advisor와 Worker에 다른 모델을 지정합니다. 여기에 함정이 하나 있었습니다.
| Claude Code 버전 | CLAUDE_CODE_SUBAGENT_MODEL 환경 변수를 설정했을 때 |
|---|---|
| 2.1.250 이하(2026-07-12 실측) | 환경 변수가 frontmatter 지정을 덮어씀 |
| 2.1.251 이상(2026-10-05 실측, 2.1.289) | frontmatter가 우선. Worker 메시지 7건 모두 지정 모델 유지 |
같은 설정이 버전에 따라 반대로 동작했습니다. 공식 문서도 2.1.251 이전에는 환경 변수가 먼저였다고 적고 있습니다. 블로그 저장소 CLAUDE.md의 "이 변수는 비워둔다"는 옛 버전 기준으로 쓴 문장이지만, 지금도 해가 없는 습관이라 그대로 두었습니다. 대신 도구를 업데이트한 뒤에는 실행 로그의 model 필드로 실제 모델을 한 번 확인합니다.
교훈: 역할을 모델로까지 나눴다면 그 고정이 실제로 지켜지는지는 설정 파일이 아니라 로그로 확인합니다.
💡 원스의 인사이트: 팀원에게 주는 것은 넓은 자유가 아니라 좁은 권한과 좋은 지시서
"AI를 자율적인 팀원으로"라는 말은 권한을 넓혀 주라는 뜻으로 들리기 쉽습니다. 직접 운영해 보니 반대였습니다. 각 역할의 권한을 좁히고 그 대신 브리프를 충실하게 써 줄수록 에이전트는 덜 헤매고 더 정확하게 움직였습니다. 사람 팀에서 좋은 리더가 하는 일과 같습니다. 일을 잘게 나누고, 끝의 기준을 먼저 정하고, 검토하는 사람이 직접 고치지 않게 합니다.
한계도 분명합니다. 이 구조의 규칙은 여전히 프롬프트 층에 있어서 에이전트가 해석할 여지가 남습니다. 위키에서 같은 종류의 규칙을 코드의 조건 분기로 내린 그래프 실습과 비교했을 때, 블랙박스 에이전트는 300회 중 209회 규칙을 어긴 채 완료했고 그래프는 0회였습니다. 규칙 위반이 반복해서 아프다면 그 규칙만 코드 게이트로 옮기고, 그 전까지는 두 역할로 나누는 가벼운 구조로 충분합니다.
체크리스트 — 내 에이전트 팀에 역할 분리가 있는가¶
- [ ] 각 역할의 금지 사항이 지시문이 아니라 도구 목록으로 표현돼 있다
- [ ] 검토 역할에게는 수정 도구가 없다
- [ ] 브리프에 실행 가능한 [완료 기준]과 [범위 경계]가 들어 있다
- [ ] 검증자가 구현자의 보고를 믿지 않고 diff와 테스트를 직접 다시 돌린다
- [ ] 검증 실패는 직접 수정이 아니라 수정 지시로 돌려보낸다
- [ ] 커밋·배포 권한은 검증하는 쪽에만 있다
- [ ] 위임 예외 규정이 크기가 아니라 동작 변경 여부로 적혀 있다
참고 자료 및 출처¶
- 위키 — 개념 정리: Advisor–Worker 패턴
- 위키 — 기본 실습(1사이클 실측): Advisor–Worker 실습 기본편
- 위키 — 3절·5절의 실측: Advisor–Worker 실습 심화편
- 위키 — 장면별 시간·비용 표: Advisor–Worker 강의 노트
- 위키 — 인사이트의 300회 비교: Advisor–Worker vs 그래프 엔지니어링
- Claude Code 공식 문서: Subagents — 모델 결정 순서
- 같은 구조를 앱 출시에 쓴 기록: 운동 기록 앱을 45일 만에 App Store에 올리기까지
- 처음 글을 쓰게 된 계기: 하네스 엔지니어링 따라하기 (Harness Engineering Practice feat. Management)