"일해라" 한 마디로
ADO → 구현 → PR 까지
NEO Frontend (HQN 제품) 에서 실제 운영 중인
Claude Code 자동화 워크플로우의 구성과 동작 원리
NEO Frontend (HQN 제품) 에서 실제 운영 중인
Claude Code 자동화 워크플로우의 구성과 동작 원리
Claude Code CLIremote-settings.json (model=sonnet)CLAUDE.md 자연어 라우팅MWAproduct/hqn/main한국어
planner·reviewer는 텍스트만 반환하고 파일 쓰기 금지(disallowedTools). 오케스트레이터가 handoff.md / review_findings.md에 저장해 메인 컨텍스트 중복을 줄인다.
하는 일
handoff.md에 저장도구
❌ Edit / Write 없음 — 파일 수정 원천 차단
하는 일
handoff.md 읽고 구현yarn tsc --noEmitreview_findings.md 반영 후 재스폰(1회)도구
서브에이전트로 스폰 · 고볼륨 코드 작업은 Sonnet에 집중
하는 일
git diff 기반 리뷰(전체 Read 최소화)도구
❌ Edit / Write 없음 — 리뷰어가 코드 건드리는 사고 원천 차단
Work Item · Repo · PR 조작
wit_my_work_items
wit_update_work_item
repo_create_branch
repo_create_pull_request
wit_link_work_item_to_pull_request
심볼 단위 시맨틱 탐색
get_symbols_overview
find_symbol
find_referencing_symbols
replace_symbol_body
insert_after_symbol
rename_symbol
CTAMultiViewer.tsx 등) 전체 읽기 없이> 일해라 → 메인: ADO MCP wit_my_work_items #68900 CTA 3D 렌더링 프리셋 기능 구현 > 68900 ── 확인 게이트 #1 · 브랜치 생성 전 ── > 네 [planner-opus-4_6] Serena 심볼 탐색 → 핸드오프 반환 → 오케스트레이터: .claude/state/handoff.md 저장 "구현을 시작할까요?" > 네 [implementer-sonnet] handoff.md 기준 수정 · scoped lint pass "바로 리뷰와 커밋을 진행할까요?" > 네 [Preflight] 브랜치명 · 금지경로 · tsc · lint OK [reviewer-opus-4_6] git diff → verdict: ready ── 확인 게이트 #2 ── > 네 → hqn_finish_approval → git commit / push ✓ Draft PR · WI #68900 연결
한 마디로 ADO 조회 → 브랜치 → 구현 시작까지 논스톱
Opus는 계획·리뷰에만, 반복 구현은 Sonnet — 5x 절감
Serena 심볼 단위 탐색으로 컨텍스트 창 절약
.claude/state/ 파일로 핸드오프·findings 전달 — 메인 컨텍스트 중복 적재 억제
CLAUDE.md 레포 체크인 — 개인 설정 무관 동일 워크플로우
guardrails로 위험 작업 전 사용자 확인 강제
자동 메모리로 프로젝트 맥락/피드백 유지
리뷰어(Opus) 스폰 전 저비용 검사로 실패 시 조기 차단
단순 태스크(i18n·CSS 등)는 planner·reviewer Opus 구간을 생략해 비용·대기 완화
Serena/ADO MCP 장애·네트워크 이슈 시 흐름 중단 가능 (ADO 변경은 hqn_guard_mcp_ado로 승인 토큰 검증)
컨텍스트가 길어지면 예상보다 많은 토큰 소비 가능
planner→implementer 계획 전달 과정에서 뉘앙스 유실
복잡 제네릭/동적 import/VTK.js 특수 패턴 부정확 가능
새 팀원의 낯선 표현에 플로우 오진입 가능
표준 플로우에서는 안전 확인이 흐름을 끊을 수 있음 — 단순 작업은 Light pickup으로 일부 완화
CLAUDE.md/skills/agents/settings — 유지보수 부담
브랜치 생성/ADO 상태 변경 간 부분 실패 시 수동 정리
오케스트레이터 · 에이전트 · 스킬 · MCP 네 계층이 한 벌로 맞물려
개인 환경 차이와 무관하게 동일한 품질의 AI 작업 흐름을 보장한다.
Opus 4.6 · Sonnet 4.6 을 에이전트별로 고정하고
도구 접근 범위까지 함께 분리하는 실전 설계
메인 Claude = 사용자와 대화하는 오케스트레이터 CLAUDE.md / skill = "언제 누구를 호출할지" 적힌 규칙 서브에이전트 = 메인이 Agent 도구로 스폰한 별도 프로세스 모델 스플릿 = 역할별 모델을 다르게 배치한 최적화 레이어
사용자: "일해라"
↓
[메인 Claude (Sonnet)] ← 오케스트레이터
├─ planner-opus-4_6 → 핸드오프 텍스트 반환
│ └─ 메인이 handoff.md 저장
├─ implementer-sonnet → handoff.md 읽고 구현
└─ (finish) Preflight → reviewer-opus-4_6
→ git diff · verdict / findings
→ not ready 시 review_findings.md 저장 후 implementer 재스폰(1회)
사용자 최종 승인 후
└─ 메인: finish_approval → commit / push / MCP PR
세 에이전트 모두 Agent 도구로 스폰된다. 메인은 라우팅·확인 게이트·상태 파일 쓰기와 커밋/푸시를 담당한다.
Agent(subagent_type="planner-opus-4_6", ...)
.claude/agents/planner-opus-4_6.md
model: claude-opus-4-6
메인과 다른 모델 · 다른 컨텍스트 · 제한된 도구
---
name: planner-opus-4_6
model: claude-opus-4-6
effort: high
tools: Read, Glob, Grep, Bash,
WebFetch, WebSearch
skills:
- hqn-frontend-guardrails
---
---
name: implementer-sonnet
model: claude-sonnet-4-6
tools: Read, Glob, Grep,
Edit, Write, Bash
skills:
- hqn-frontend-guardrails
---
--- name: reviewer-opus-4_6 model: claude-opus-4-6 effort: high tools: Read, Glob, Grep, Bash skills: - hqn-frontend-guardrails ---
Agent(subagent_type="...", model="opus")
model: claude-opus-4-6
← 이 프로젝트가 쓰는 방식
.claude/settings.json
~/.claude/remote-settings.json → model: "sonnet"
현재 Sonnet 계열
서브에이전트의 모델은 frontmatter가 고정한다. 메인 오케스트레이터 기본값(remote-settings.json의 sonnet 등)과 독립이다.
| 에이전트 | 허용 도구 | 핵심 제한 |
|---|---|---|
| OPUS planner | Read · Glob · Grep · Bash · WebFetch · WebSearch | ❌ Edit/Write — 파일 수정 불가 |
| SONNET implementer | Read · Glob · Grep · Edit · Write · Bash | ❌ WebFetch/WebSearch — 외부 참조 불가 |
| OPUS reviewer | Read · Glob · Grep · Bash | ❌ Edit/Write — 리뷰어가 코드 수정 불가 |
💡 planner가 실수로 파일을 수정하거나, reviewer가 코드를 바꾸는 사고를 도구 레벨에서 원천 차단한다.
| 측면 | 이득 | 트레이드오프 |
|---|---|---|
| 토큰 | 긴 핸드오프 전문을 메인 히스토리에 반복 적재하지 않음 | 파일 내용이 stale하면 재생성·동기화 필요 |
| 격리 | implementer는 handoff.md 중심으로 잡음 적은 구현 |
서브는 대화 맥락 없이 완주 → 핸드오프 품질이 성패 |
| 리뷰 | git diff 중심으로 Opus Read 비용 절감 |
diff만으로는 맥락 부족할 수 있음 |
| 재시도 | not ready 시 findings 파일로 수정 루프 명시 | 재리뷰 1회 제한 등 정책을 스킬/CLAUDE에 맞춰야 함 |
Preflight(브랜치·금지경로·tsc·lint)로 Opus 리뷰어 스폰 자체를 아끼는 구간이 있다.
파일 읽기와 코드 작성이 반복되는 고볼륨 구간이 Sonnet으로 가고, 판단만 하는 저볼륨 구간이 Opus로 간다. 단순 태스크는 Light pickup으로 planner·reviewer Opus 호출을 줄일 수 있다.
planner(Opus)가 전체 파일을 읽어야 해서 토큰 급증 → 가성비 이득 상쇄
심볼 단위 탐색으로 planner가 필요한 부분만 읽음 → Opus 비용 억제
태스크: CTA 뷰어 show/hide 버튼 수정 |
탐색 타깃: handleToggleVisualization + isVisualizationOpen |
대상: CTAMultiViewer.tsx (1,051줄), ResultViewer.tsx (594줄)
| 단계 | Serena 경로 | 표준 경로 (Glob → Grep → Read) |
|---|---|---|
| 파일/심볼 탐색 | find_symbol → ~4,400자 |
Glob × 3 → ~800자 |
| 구조 파악 | get_symbols_overview × 2 → ~5,000자 |
Read(CTAMultiViewer.tsx) → ~52,000자 |
| 타깃 코드 읽기 | find_symbol(include_body=True) → ~100자 |
Read(ResultViewer.tsx) → ~30,000자 |
| 합계 | ~9,500자 ≈ ~2,400 토큰 | ~83,000자 ≈ ~20,750 토큰 |
💡 표준 경로는 함수 하나를 찾기 위해 파일 전체를 컨텍스트에 올린다. Serena는 심볼 트리에서 위치를 파악한 뒤 그 함수 본문만 읽어 파일 크기와 무관하게 토큰이 낮다. planner가 Opus로 실행되는 구조에서는 이 차이가 비용에 직접 기여한다. 2026-04-30: planner 에이전트에 심볼 검색 시 Grep 금지 하드 규칙을 두어 Serena 우회 남용을 줄였다.
.claude/agents/{name}.md — model 필드 포함~/.claude/remote-settings.json 메인 모델 고정.claude/skills/ 에이전트 참조 스킬tools: 필드로 도구 접근 제한Claude Code 기본 기능이므로 외부 라이브러리나 별도 인프라는 불필요하다.
frontmatter 한 줄로 고정되는 모델 선택과, 함께 선언되는 tools 제한이
비용과 안전성을 동시에 지탱하는 구조를 만든다.
PreToolUse 경로·셸·MCP ADO 게이트와 승인 토큰으로 우회를 막고,
PostToolUse 주입과 Skill로 품질을 유도한다
src/pages · src/shared 수정 차단
파괴적 git · 브랜치 생성 · az boards 검증
hqn_guard_mcp_ado.py — WI 업데이트·브랜치·PR에 start/finish 토큰
.edit_context_injected 플래그로 세션당 1회만 주입
사용자 "네"를 JSON 파일로 증명 · TTL 관리
커밋 메시지 형식 · Serena 우선 · 응답 언어
frontend/.claude/ ├── settings.local.json ← 훅 배선 + 권한 설정 ├── agents/ │ ├── planner-opus-4_6.md ← Opus 플래너 │ ├── implementer-sonnet.md ← Sonnet 구현자 │ └── reviewer-opus-4_6.md ← Opus 리뷰어 ├── skills/ │ ├── hqn-frontend-guardrails/ ← 소프트 제약 문서 │ ├── hqn-ado-pickup-task/ · hqn-ado-finish-task/ │ ├── pickup/ · finish/ · tasks/ ← 자연어 단축 라우팅 ├── hooks/scripts/ │ ├── hqn_protect_paths.py ← L1 │ ├── hqn_guard_shell.py ← L2 │ ├── hqn_guard_mcp_ado.py ← L3 MCP ADO │ ├── hqn_after_edit_context.py ← L4 PostToolUse │ ├── hqn_start_approval.py · hqn_finish_approval.py │ └── hqn_session_log.py ← 세션 분석 CLI └── state/ ├── hqn_start_approval.json · hqn_finish_approval.json ├── handoff.md · review_findings.md · complexity_verdict.txt └── .edit_context_injected
FORBIDDEN_PREFIXES = [
FRONTEND_ROOT / 'src' / 'pages',
FRONTEND_ROOT / 'src' / 'shared',
]
대상 파일이 이 prefix 아래면permissionDecision: "deny" 반환 → 도구 실행 취소
Next.js Pages Router — HQN 작업이 전사 라우팅을 건드리면 다른 제품에 영향
전사 공유 컴포넌트/훅 — HQN 단독 변경 시 다른 제품 회귀 위험
💡 절대경로 resolve로 심볼릭 링크나 ../ 우회 차단
정규식 매칭 → 즉시 deny
product/hqn/{type}/{num} 패턴&& / ; / || / 개행 연결)az boards work-item update
start_approval 토큰의 work_item 번호와 일치해야만 허용
Edit/Write 완료 직후
대상이 src/products/hqn/ 또는 src/locales/
hqn_after_edit_context.py
💡 막는 훅이 아니라 검증 리마인더를 주입한다. 플래그는 pickup 시작 시 삭제되어 새 작업마다 다시 1회 주입된다.
{
"repo": "/.../neo",
"branch_type": "feature",
"work_item": "68900",
"approved_at": 1745100000,
"expires_at": 1745103600
}
필수 명령:
git checkout -b product/hqn/feature/68900az boards work-item update --id 68900{
"repo": "/.../neo",
"branch": "product/hqn/feature/68900",
"work_item": "68900",
"approved_at": 1745110000,
"expires_at": 1745117200
}
필수 명령:
git commit ...git push ...az repos pr create ...💡 시작 토큰은 짧게(1h), 완료 토큰은 길게(2h) — 작업 성격에 맞춘 TTL
되돌릴 수 없거나 회귀 위험 큰 것
[HQN][FE]✨feat:형식/스타일 — 틀려도 작업은 유효
$ git checkout -b product/hqn/feature/68900
│
▼ Bash 훅 실행 (hqn_guard_shell.py)
┌───────────────────────────────────────────────┐
│ ① 브랜치명 패턴 일치 ✓ │
│ ② compound 아님 (&&/;/||/개행) ✓ │
│ ③ 현재 브랜치 = product/hqn/main ✓ │
│ ④ 워킹트리 clean ✓ │
│ ⑤ HEAD == origin/product/hqn/main ✓ │
│ ⑥ start_approval 토큰 유효 + 일치 ✓ │
└───────────────────────────────────────────────┘
▼
→ 허용 · 브랜치 생성
💡 한 단계라도 실패하면 즉시 deny — compound command 차단으로 "검증 건너뛰고 생성"을 원천 봉쇄한다.
Claude가 잊어도 훅은 매 호출마다 독립 실행 — 컨텍스트 길이와 무관
planner/implementer/reviewer 어느 누가 호출해도 동일 적용
Claude 추론 오류로 인한 오인 승인 원천 차단
검증 건너뛰고 이어지는 실행 경로 자체를 봉쇄
.gitignore로 부족한 케이스까지 커밋 직전에 차단
규칙 강도가 구현 방식으로 드러남
스크립트에 절대경로 박힘 — 다른 환경/클론 경로에서 조용히 무력화
Edit/Write/Bash 매 호출마다 fork — 누적 지연
복잡 태스크는 만료, 짧은 작업엔 과함 · 만료 메시지는 일부만 [GUARD:*]로 구분
새 팀원이 설정 존재를 모르면 하네스 없이 작업
&&·개행 연결은 차단. grep 패턴 리터럴 안의 && 등은 셸 체이닝과 구분 못함(드묾)
2026-04-30 반영: guard 훅 3종은 예외 시 deny(fail-safe), 컨텍스트 주입 훅만 fail-open.
MCP ADO 경로는 hqn_guard_mcp_ado.py로 CLI와 동일한 토큰 검증이 적용됨.
경로·셸·MCP·PostToolUse·토큰·스킬 여섯 계층이 역할을 나눠 맞물리고,
Claude의 "의지"가 아니라 상태와 검증으로 안전성이 증명된다.
다만 훅은 보조망이지 설계 품질을 대체하지 않는다.