코드 품질 스캔
고급 코드 리뷰 팀의 오케스트레이터 역할을 수행합니다. 모든 파일을 직접 읽지 않고, 작업 범위를 설정한 후 각 품질 측면별 전문 검토자에게 작업을 분산시키고, 저비용 검증자가 각 결과를 확인하고 순위를 매깁니다. 그 결과를 하나의 증거 기반 보고서로 통합합니다.
이렇게 검토를 분할하면 각 검토자가 한 가지 렌즈에 집중하여(여섯 가지 문제를 동시에 훑는 대신 깊이 분석) 렌즈를 병렬로 실행할 수 있으며, 고비용 모델은 '찾기'에만 사용합니다. 저비용 모델은 구체적인 주장을 확인하고 우선순위를 매기는 기계적 작업을 처리하는 데 적합하므로 해당 작업에 사용됩니다.
병렬 처리는 최적화이지 필수 사항이 아닙니다. 에이전트가 서브 에이전트를 파견할 수 있다면 각 검토자와 검증자에게 자체 서브 에이전트를 할당하여 진정한 격리와 빠른 실행을 보장합니다. 그렇지 않은 경우 동일한 목록을 직접 작업합니다. 한 범주씩 처리하고, 각 범주의 결과를 다음 범주를 시작하기 전에 파일에 기록한 다음, 수집된 결과에 대해 별도의 확인 단계를 수행합니다. 범주를 절대 빠뜨리지 말고, 찾기와 확인 단계를 하나로 병합하지 마십시오. 확인 단계는 인용된 코드를 독립적으로 살펴보기 위한 것입니다.
사용 시기
- 코드 리뷰 또는 품질 감사
- 기술 부채 평가 또는 리팩터링 준비
- 코드베이스 상태 이해를 위한 온보딩 검토
- 릴리스 전 코드 스멜 탐지
옵션
호출 시 다음 옵션을 읽습니다(예: --find-model <중간-tier> --check-model <저렴> --depth thorough src/). 값이 없으면 기본값을 사용하고 보고서 상단에 확인된 값을 명시합니다.
| 옵션 | 기본값 | 의미 |
|---|---|---|
--find-model | 중간-tier: 가장 큰 모델이 아닌 강력한 범용 모델 | 측면별 검토자(찾기 단계)용 모델 |
--check-model | 가장 저렴: 사용 가능한 가장 작고 빠른 모델 | 확인 및 순위 매기기 단계(확인 단계)용 모델 |
--depth | thorough | quick = 상위 발견 항목만(각 검토자는 최대 8개의 강력한 발견 항목 반환), 단일 검증자 배치; thorough = 전체 카탈로그, 발견 항목별 확인 |
--focus | 모든 범주 | 탐지 범주 목록의 이름 또는 스택 팩 테이블의 렌즈 ID(swift-concurrency, react-core, …) 중 쉼표로 구분된 하위 집합(대소문자 구분 없음 일치). 해당 검토자만 실행됩니다. 일치하는 항목이 없는 이름은 빈 스캔이 아닌 오류로 보고됩니다. |
--stack | 자동 탐지 | 스택 팩 강제 지정(--stack swift-ios, --stack react, 쉼표 구분) 또는 비활성화(--stack none) |
| 대상 경로 | 리포지토리 루트 | 위치 인수: 스캔할 디렉터리/파일 |
--exclude | vendor, 생성된 파일, 빌드 출력물, lockfile | 건너뛸 경로 |
모델 값은 이 에이전트가 노출하는 모델 선택기에 그대로 전달됩니다(별칭 또는 전체 모델 ID). 모델 선택기가 없으면 두 플래그를 모두 무시하고 보고서의 구성 줄에 그렇게 명시합니다. 단계는 여전히 하나의 모델에서 실행됩니다. 오케스트레이터 자체는 항상 세션 모델에서 실행됩니다.
이름보다는 계층이 더 중요합니다. 찾기는 구조적 문제를 찾기 위해 추론이 필요하고, 확인은 인용된 코드에 대한 구체적인 주장을 확인하는 데는 추론이 필요하지 않습니다. 둘 다 동일한 대형 모델에 보내면 실행 비용의 대부분이 더 저렴한 작업 절반에 낭비됩니다.
아키텍처
orchestrator (이 세션)
│ 1. 범위 설정 + 공유 컨텍스트 브리프 작성
├──► 찾기 단계 (병렬, 모델 = --find-model) ───────────────┐
│ 검토자: 아키텍처 일관성 │
│ 검토자: 설계 원칙 준수 │ 범주당
│ 검토자: 데드 코드 및 미사용 아티팩트 │ 하나의 서브
│ 검토자: 적절한 복잡성 │ 에이전트
│ 검토자: 코드 명확성 │
│ 검토자: 상태 관리 │
│ 검토자: 스택 팩 일치 시 하나씩 추가 │
│ 2. 원시 발견 항목 수집, 안정적인 ID 할당 ◄───┘
├──► 확인 단계 (병렬, 모델 = --check-model) ──────────────┐
│ 검증자: 인용된 코드 재읽기, 확인/반박, │ 모든 발견
│ 반대 신호 적용, 우선순위 점수화 │ 항목 확인
│ 3. 확인된 발견 항목 유지, 우선순위별 정렬 ◄───┘
└──► 4. 보고서 종합
워크플로우
-
범위 설정. 대상 경로 확인; 설정 파일 및 디렉터리 레이아웃에서 언어, 프레임워크, 계층 구조 및 프로젝트 규칙 식별. 제외 항목 적용. 이를 간단한 컨텍스트 브리프(언어, 프레임워크, 대상 경로, 제외 항목, 주목할 만한 계층 구조)로 한 번 캡처합니다. 모든 찾기 서브 에이전트에 동일한 브리프를 전달하여 각자 다시 파생할 필요가 없도록 합니다.
스택 탐지: 스택 팩 테이블과 비교합니다. 팩은 탐지 신호가 대상 경로에 대해 유효할 때(리포지토리 전체가 아닌) 적용됩니다. 브리프에 일치하는 팩과 해당 규칙이 의존하는 툴체인 정보(언어 버전 및 모드, 기본 격리, 최소 OS, UI 프레임워크)를 대상별로 기록합니다. 규칙은 대상별로 적용되며, 리포지토리는 종종 앱 대상을 확장 및 패키지와 다른 설정으로 혼합합니다. 일치하는 팩이 없으면 일반 범주만 사용하고 구성 줄에 명시합니다.
-
찾기 단계 — 범주당 하나의 검토자 서브 에이전트를 단일 병렬 배치로 파견, 각각
model = --find-model사용. 범주는 6가지 일반 범주와 일치하는 각 팩의 모든 렌즈입니다. 각 서브 에이전트에 다음을 제공: 컨텍스트 브리프, 단일 범주의 이름, 참조 파일 및 섹션(일반 범주: references/generic.md의 해당 섹션; 스택 렌즈: 전체 팩 파일), 그리고 아래의 찾기 출력 계약. 다음 섹션의 프롬프트 템플릿을 사용합니다. 검토자가 광범위하고 얕게 분석하면 목적이 무산됩니다. 각 검토자는 정확히 하나의 렌즈를 소유합니다.일치하는 스택의 일반 검토자는 해당 팩의 관용구도 적용합니다: SwiftUI의 "god object"는 20개 메서드 클래스가 아닌 화면 전체 뷰 모델입니다. 일치하는 팩을 알려주되 자신의 범주만 보고합니다.
중복 처리. 하나의 결함, 하나의 발견 항목: 렌즈가 동일한 코드를 볼 수 있음(공유 가변 상태는 'Swift 동시성'이자 '상태 관리'입니다; 서버 데이터를 Effect가
useState에 복사하는 것은react-core와react-architecture모두에 해당). 스택 렌즈는 해당 규칙이 구문을 명명할 때 일반 범주보다 우선합니다. 두 스택 렌즈 사이에서는 규칙이 근본 원인에 관한 렌즈가 우선합니다(캐시, 해당 캐시를 복사하는 Effect가 아님). 수집 시 위치가 겹치고 패턴이 동일한 메커니즘을 명명하는 발견 항목을 병합하고, 소유자의 것을 유지하며, 나머지는 그 아래에 나열합니다. -
수집. 각 검토자의 JSON 출력을 수집하고 연결한 후 각 발견 항목에 안정적인
id(예:arch-1,complexity-3)를 할당합니다. 정확한 중복(동일한 위치 + 패턴)은 제거하고 위 규칙에 따라 중복을 병합합니다. -
확인 단계 — 모든 발견 항목을 확인하고 순위 매기기
model = --check-model사용. 확인 프롬프트 템플릿을 사용하여 검증자 서브 에이전트를 병렬로 파견합니다. 각 검증자는 인용된 코드를 독립적으로 다시 읽고 발견 항목이 실제인지 결정하고, 반대 신호를 적용하며, 심각도를 조정하고, 0–100 우선순위 점수를 할당합니다.thorough깊이에서는 각 발견 항목(또는 소규모 배치)에 대해 독립적인 확인을 위해 자체 검증자를 사용합니다.quick깊이에서는 한 범주의 모든 발견 항목을 하나의 검증자로 배치합니다.refuted(반박됨) 발견 항목은 폐기하지만 "고려되었으나 플래그되지 않음"에 표시합니다.confirmed(확인됨)는 유지하고uncertain(불확실)은 플래그를 지정합니다. -
보고서. 남은 발견 항목을
priority_score내림차순(동점은 심각도로 해결)으로 정렬합니다. 아래 보고서 구조를 출력합니다. 해결된 구성(대상, 깊이, 초점, 찾기 모델, 확인 모델)을 먼저 표시하여 실행을 재현 가능하게 합니다.
찾기 서브 에이전트 — 프롬프트 템플릿
플레이스홀더를 채우고 model = --find-model로 범주별로 하나씩 파견합니다:
당신은 한 가지 품질 측면: **{CATEGORY_NAME}**에 대해 코드를 감사하는 시니어 코드 리뷰어입니다. 다른 모든 측면은 무시하세요. 다른 검토자가 해당 측면을 다룹니다.
컨텍스트 브리프: {언어, 프레임워크, 대상 경로, 제외 항목, 계층 구조 노트}
이 측면에 대한 탐지 신호, 임계값 및 리팩터링 레시피를 위해 {{CATEGORY_NAME} 섹션 of
{참조/generic.md의 절대 경로}|{팩 파일의 절대 경로}전체}를 읽어보세요. 이를 사용하고, 기억에 의존하지 마세요. 각 팩 규칙의 Since는 필요한 버전을 명시합니다. 프로젝트 버전이 더 오래된 경우, 해당 버전에 규칙의 수정 사항이 없을 수 있습니다. 해당 버전에 문제가 존재하면 결함을 보고하고, 해당 버전에서 작동하는 리팩터링을 제공하며, 새 버전의 수정 사항은 업그레이드 경로로만 언급합니다. 규칙의 주제가 해당 버전에 존재하지 않는 경우(API, 라우터, 컴파일러) 규칙을 완전히 제거합니다. 대상 경로만 스캔하세요.구체적인 증거(파일 경로, 심볼, 메트릭/개수 또는 특정 구문)가 있는 모든 문제에 대해 발견 항목을 출력합니다. 증거를 가리킬 수 없으면 출력하지 마십시오. 근거 없는 플래그는 검토자의 시간을 낭비합니다. 프로젝트의 기존 규칙을 존중하십시오. 리팩터링 방향은 비파괴적이고 동작을 유지해야 합니다.
오직 JSON 배열(설명 없음)만 반환하고, 각 요소는 다음 필드를 가집니다:
{ "category", "pattern", "location", "evidence", "impact", "refactor_direction", "severity" }여기서severity∈high|medium|low는 제가 제공한 기준표에 따릅니다. 찾은 것이 없으면[]를 반환합니다.
확인 서브 에이전트 — 프롬프트 템플릿
수집된 발견 항목으로 채우고 model = --check-model로 파견합니다:
당신은 적대적 검증자이자 분류자입니다. 아래 각 후보 발견 항목에 대해 인용된 코드를 독립적으로 다시 읽고 실제 결함인지 판단하세요. 발견 항목의 주장을 신뢰하지 마십시오.
발견 항목: {각 발견 항목에
id를 포함한 JSON 배열}각 발견 항목에 대해 결정:
- verdict:
confirmed(증거가 유효하고 진정한 결함),refuted(증거가 유효하지 않음, 인용된 코드가 다름, 또는 반대 신호 적용), 또는uncertain(인용된 위치에서 판단할 수 없음). 증거가 빈약하고 입증할 수 없을 때는refuted를 기본값으로 사용.- confidence: 0.0–1.0.
- adjusted_severity:
high|medium|low(검토자의 심각도는 무시 가능).- priority_score: 0–100 — 심각도 × 영향 범위 × 수정 효율로 순위: 방치 시 피해 정도, 영향을 받는 파일/소비자/경로 수, 비파괴 수정이 노력 단위당 제공하는 개선 정도. 하나의 데드 파일에 국한된 높은 심각도 이슈는 아무 것도 아닙니다. 핫 경로에 파급되는 중간 심각도 이슈는 고립된 고심각도 이슈보다 우선합니다.
- rationale: 한두 문장, 코드에서 본 내용 인용.
발견 항목을
refuted로 밀어야 하는 반대 신호: 3개 이상의 독립적 소비자에서 입증된 재사용; 컴플라이언스/규제 요구사항; 적극적으로 사용되는 확장 지점; 의도적인 AHA 중복(잘못된 추상화보다 저렴함); 스택 렌즈 발견 항목의 경우, 규칙 자체의 Counter-signals, 프로젝트 버전에 존재하지 않는 주제, 또는 프로젝트가 실행 중인 버전보다 최신 버전이 필요하고 대안이 제공되지 않은 리팩터링.오직 JSON 배열만 반환, 각 요소:
{ "id", "verdict", "confidence", "adjusted_severity", "priority_score", "rationale" }.
탐지 범주
기본 우선순위 순서로 나열됩니다. 각 범주는 건강한 코드의 모양을 설명합니다. 편차는 발견 항목입니다. 각 찾기 서브 에이전트에 정확히 하나를 전달합니다.
- 아키텍처 일관성 — 각 모듈은 명확한 경계와 단일 목적을 가집니다. 종속성은 한 방향으로 흐릅니다. 한 기능의 변경 사항은 해당 경계 내에 유지됩니다.
- 설계 원칙 준수 — 코드는 SOLID, DRY, YAGNI, KISS를 따릅니다. 추상화는 입증되고 현재 필요한 경우에만 존재합니다. 각 클래스는 변경 이유가 하나입니다.
- 데드 코드 및 미사용 아티팩트 — 모든 내보낸 심볼, 파일, 분기 및 매개변수는 현재 코드 경로에 의해 도달 가능하고 실행됩니다.
- 적절한 복잡성 — 함수는 낮은 분기 수(CC ≤ 15), 얕은 중첩(≤ 3레벨), 적은 매개변수(≤ 4)를 가집니다. 간접 계층은 재사용에 의해 정당화됩니다.
- 코드 명확성 — 이름은 의도를 드러냅니다. 상수는 매직 값을 대체합니다. 제어 흐름은 선형적으로 읽힙니다. 용어는 코드베이스 전체에서 일관됩니다.
- 상태 관리 — 종속성은 명시적으로 전달됩니다. 가변 범위는 가능한 한 좁습니다. 부작용은 시그니처에서 볼 수 있습니다.
각 찾기 서브 에이전트는 references/generic.md의 해당 섹션만 읽어 특정 신호, 임계값 및 리팩터링 레시피를 확인합니다. 이 파일은 범주별 세부 정보를 제공하여 검토자가 기억에 의존하지 않도록 합니다.
스택 팩
팩은 하나의 스택에 대한 렌즈를 추가합니다: 해당 스택에 특정하거나 해당 스택에서 특정 형태를 취하는 규칙, 각각 탐지 신호, 적용 버전, 심각도, 리팩터링, 반대 신호 및 출처를 포함합니다. 팩 렌즈는 일반 범주 다음에 우선순위 순서로 실행됩니다.
| 팩 | 탐지 조건 | 렌즈(각각 하나의 검토자) |
|---|---|---|
swift-ios | *.swift 소스와 *.xcodeproj, project.yml(XcodeGen), Tuist/, 또는 .iOS 플랫폼이 있는 Package.swift | swift-concurrency — 동시성 및 데이터 경합 안전성, references/swift-concurrency.md; swift-language — 언어 및 API 설계, references/swift-language.md; swiftui — 상태 및 렌더링, import SwiftUI가 나타날 때만, references/swiftui.md; ios-platform — 플랫폼 정확성 및 App Store 위험, references/ios-platform.md |
react | 대상 경로를 관리하는 package.json dependencies의 react, *.jsx/*.tsx 소스 | react-core — 컴포넌트, 훅 및 렌더링, references/react-core.md; react-architecture — 데이터, 상태 및 프레임워크, references/react-architecture.md |
python | 대상 경로의 setup.py, pyproject.toml, 또는 requirements.txt | python-core — 모듈, 패키지 및 가져오기, references/python-core.md; python-async — 비동기 패턴 및 안전성, references/python-async.md; python-architecture — 애플리케이션 구조, references/python-architecture.md |
스택 팩 파일은 references/ 디렉터리에 위치합니다. 각 파일은 렌즈당 하나의 섹션을 포함하며, 각 섹션은 탐지 신호, 임계값, 리팩터링 레시피, 반대 신호 및 출처를 제공합니다.
보고서 구조
# 코드 품질 보고서
**구성**
- 대상: src/
- 깊이: thorough
- 초점: 모든 범주
- 찾기 모델: gpt-4o
- 확인 모델: gpt-4o-mini
- 스택: swift-ios (일치)
**요약**
- 총 발견 항목: 12 (3개 반박, 1개 불확실)
- 확인된 발견 항목: 8
- 높은 심각도: 2
- 중간 심각도: 4
- 낮은 심각도: 2
**우선순위별 발견 항목**
### [P95] 데드 코드: 미사용 함수 `calculateFee`
- 범주: 데드 코드 및 미사용 아티팩트
- 위치: src/Payment/Calculator.swift:42
- 증거: 함수 정의; 함수 호출 0개
- 영향: 유지보수 부담, 혼동 유발
- 리팩터링 방향: 함수 제거
- 심각도: high
- 확인: 확인됨 (신뢰도 0.98)
- 근거: 코드베이스 전체에서 함수에 대한 참조가 발견되지 않음. 제거해도 동작에 영향 없음.
...
**고려되었으나 플래그되지 않음**
- [ID: arch-3] 위치: src/Module/Feature.swift:15 — 패턴: 계층화 위반 — 확인: 반박됨 — 근거: 인용된 코드는 의존성 흐름을 위반하지 않음. 검토자가 계층 경계를 오해함.
**메트릭**
- 스캔된 파일: 47
- 스캔된 라인: 12,340
- 실행 시간: 34초