Santa Method
다중 에이전트 적대적 검증 프레임워크. 리스트를 만들고, 두 번 확인하세요. 나쁘면 좋아질 때까지 고치세요.
핵심 통찰: 단일 에이전트가 자신의 출력을 검토할 때 출력을 생성한 것과 동일한 편향, 지식 격차, 체계적 오류를 공유합니다. 두 명의 독립적인 검토자가 공유 컨텍스트 없이 검토하면 이러한 실패 모드를 차단합니다.
활성화 시점
다음 상황에서 이 스킬을 호출하세요:
- 출력이 게시, 배포되거나 최종 사용자에게 제공될 때
- 규정 준수, 규제 또는 브랜드 제약이 적용되어야 할 때
- 코드가 사람의 검토 없이 프로덕션으로 배포될 때
- 콘텐츠 정확성이 중요할 때 (기술 문서, 교육 자료, 고객 대상 카피)
- 대량 생성 시 무작위 점검으로 체계적 패턴을 발견할 수 없을 때
- 할루시네이션 위험이 높을 때 (주장, 통계, API 참조, 법적 언어)
내부 초안, 탐색적 연구, 또는 결정론적 확인이 가능한 작업(빌드/테스트/린트 파이프라인 사용)에는 사용하지 마세요.
아키텍처
┌─────────────┐
│ 생성자 │ Phase 1: 리스트 만들기
│ (에이전트 A) │ 결과물 생성
└──────┬───────┘
│ 출력
▼
┌──────────────────────────────┐
│ 이중 독립 검토 │ Phase 2: 두 번 확인
│ │
│ ┌───────────┐ ┌───────────┐ │ 두 에이전트, 동일 루브릭,
│ │ 검토자 B │ │ 검토자 C │ │ 컨텍스트 공유 없음
│ └─────┬─────┘ └─────┬─────┘ │
│ │ │ │
└────────┼──────────────┼────────┘
│ │
▼ ▼
┌──────────────────────────────┐
│ 평결 게이트 │ Phase 3: 착한 아이 vs 나쁜 아이
│ │
│ B 통과 AND C 통과 → 착함 │ 둘 다 통과해야 함.
│ 그 외 → 나쁨 │ 예외 없음.
└──────┬──────────────┬─────────┘
│ │
착함 나쁨
│ │
▼ ▼
[ 배송 ] ┌─────────────┐
│ 수정 루프 │ Phase 4: 좋아질 때까지 수정
│ │
│ 반복++ │ 모든 플래그 수집.
│ if i > MAX: │ 모든 문제 해결.
│ 에스컬레이션│ 두 검토자 재실행.
│ else: │ 수렴할 때까지 반복.
│ goto Ph.2 │
└──────────────┘
단계별 설명
Phase 1: 리스트 만들기 (생성)
주요 작업을 실행합니다. 일반 생성 워크플로우에 변경 사항이 없습니다. Santa Method는 사후 생성 검증 계층이지 생성 전략이 아닙니다.
# 생성기는 정상적으로 실행됩니다
output = generate(task_spec)
Phase 2: 두 번 확인 (독립 이중 검토)
두 검토 에이전트를 병렬로 실행합니다. 중요한 불변 규칙:
- 컨텍스트 격리 — 어떤 검토자도 다른 검토자의 평가를 볼 수 없음
- 동일 루브릭 — 둘 다 동일한 평가 기준을 받음
- 동일 입력 — 둘 다 원본 명세서와 생성된 출력을 받음
- 구조화된 출력 — 각각 산문이 아닌 타입이 있는 평결을 반환
REVIEWER_PROMPT = """
당신은 독립적인 품질 검토자입니다. 이 출력에 대한 다른 검토를 본 적이 없습니다.
## 작업 명세서
{task_spec}
## 검토 대상 출력
{output}
## 평가 루브릭
{rubric}
## 지침
각 루브릭 기준에 대해 출력을 평가하세요. 각각:
- PASS: 기준 완전 충족, 문제 없음
- FAIL: 특정 문제 발견 (정확한 문제 명시)
평가를 구조화된 JSON으로 반환하세요:
{
"verdict": "PASS" | "FAIL",
"checks": [
{"criterion": "...", "result": "PASS|FAIL", "detail": "..."}
],
"critical_issues": ["..."], // 반드시 수정해야 할 차단 문제
"suggestions": ["..."] // 차단하지 않는 개선 제안
}
엄격하게 검토하세요. 당신의 임무는 승인이 아니라 문제를 찾는 것입니다.
"""
# 검토자를 병렬로 실행 (Claude Code 서브에이전트)
review_b = Agent(prompt=REVIEWER_PROMPT.format(...), description="Santa 검토자 B")
review_c = Agent(prompt=REVIEWER_PROMPT.format(...), description="Santa 검토자 C")
# 둘 다 동시에 실행 — 서로의 결과를 보지 않음
루브릭 설계
루브릭은 가장 중요한 입력 요소입니다. 모호한 루브릭은 모호한 검토를 만듭니다. 모든 기준은 객관적인 통과/실패 조건을 가져야 합니다.
| 기준 | 통과 조건 | 실패 신호 |
|---|---|---|
| 사실 정확성 | 모든 주장이 출처 자료 또는 상식으로 확인 가능함 | 조작된 통계, 잘못된 버전 번호, 존재하지 않는 API |
| 할루시네이션 없음 | 허구의 개체, 인용문, URL, 참조 없음 | 존재하지 않는 페이지 링크, 출처 없는 인용문 |
| 완전성 | 명세서의 모든 요구사항이 처리됨 | 누락된 섹션, 건너뛴 엣지 케이스, 불완전한 범위 |
| 규정 준수 | 모든 프로젝트별 제약 조건 통과 | 금지된 용어 사용, 어조 위반, 규제 미준수 |
| 내부 일관성 | 출력 내 모순 없음 | A 섹션에서 X라고 말하고 B 섹션에서 not-X라고 말함 |
| 기술적 정확성 | 코드 컴파일/실행, 알고리즘 타당함 | 구문 오류, 논리 버그, 잘못된 복잡성 주장 |
도메인별 루브릭 확장
콘텐츠/마케팅:
- 브랜드 어조 준수
- SEO 요구사항 충족 (키워드 밀도, 메타 태그, 구조)
- 경쟁사 상표 오용 없음
- CTA 존재 및 올바르게 연결됨
코드:
- 타입 안전성 (
any누출 없음, 적절한 null 처리) - 오류 처리 범위
- 보안 (코드 내 비밀 정보 없음, 입력 검증, 인젝션 방지)
- 새로운 경로에 대한 테스트 적용 범위
규정 준수 민감 영역 (규제, 법률, 금융):
- 결과 보장 또는 입증되지 않은 주장 없음
- 필요한 면책 조항 존재
- 승인된 용어만 사용
- 관할권에 적합한 언어
Phase 3: 착한 아이 vs 나쁜 아이 (평결 게이트)
def santa_verdict(review_b, review_c):
"""두 검토자가 모두 통과해야 합니다. 부분 점수는 없습니다."""
if review_b.verdict == "PASS" and review_c.verdict == "PASS":
return "NICE" # 배송
# 두 검토자의 플래그를 병합하고 중복 제거
all_issues = dedupe(review_b.critical_issues + review_c.critical_issues)
all_suggestions = dedupe(review_b.suggestions + review_c.suggestions)
return "NAUGHTY", all_issues, all_suggestions
왜 둘 다 통과해야 하는가: 한 검토자만 문제를 발견했다면 그 문제는 실제로 존재합니다. 다른 검토자의 사각지대가 바로 Santa Method가 제거하려는 실패 모드입니다.
Phase 4: 좋아질 때까지 수정 (수렴 루프)
MAX_ITERATIONS = 3
for iteration in range(MAX_ITERATIONS):
verdict, issues, suggestions = santa_verdict(review_b, review_c)
if verdict == "NICE":
log_santa_result(output, iteration, "passed")
return ship(output)
# 모든 치명적 문제 수정 (제안사항은 선택 사항)
output = fix_agent.execute(
output=output,
issues=issues,
instruction="플래그가 표시된 문제만 수정하세요. 요청되지 않은 변경 사항을 리팩터링하거나 추가하지 마세요."
)
# 수정된 출력에 대해 두 검토자 모두 재실행 (새 에이전트, 이전 라운드 기억 없음)
review_b = Agent(prompt=REVIEWER_PROMPT.format(output=output, ...))
review_c = Agent(prompt=REVIEWER_PROMPT.format(output=output, ...))
# 반복 횟수 소진 — 에스컬레이션
log_santa_result(output, MAX_ITERATIONS, "escalated")
escalate_to_human(output, issues)
중요: 각 검토 라운드는 새로운 에이전트를 사용합니다. 검토자는 이전 라운드의 기억을 가지고 있어서는 안 됩니다. 이전 컨텍스트는 고정 편향(anchoring bias)을 생성하기 때문입니다.
구현 패턴
패턴 A: Claude Code 서브에이전트 (권장)
서브에이전트는 진정한 컨텍스트 격리를 제공합니다. 각 검토자는 공유 상태 없이 별도의 프로세스입니다.
# Claude Code 세션에서 Agent 도구를 사용하여 검토자 생성
# 두 에이전트는 속도를 위해 병렬로 실행됩니다
# Agent 도구 호출을 위한 의사 코드
reviewer_b = Agent(
description="Santa 검토 B",
prompt=f"이 출력의 품질을 검토하세요...\n\n루브릭:\n{rubric}\n\n출력:\n{output}"
)
reviewer_c = Agent(
description="Santa 검토 C",
prompt=f"이 출력의 품질을 검토하세요...\n\n루브릭:\n{rubric}\n\n출력:\n{output}"
)
패턴 B: 순차적 인라인 (대체)
서브에이전트를 사용할 수 없을 때 명시적 컨텍스트 재설정으로 격리를 시뮬레이션:
- 출력 생성
- 새 컨텍스트: "당신은 검토자 1입니다. 이 루브릭에 대해서만 평가하세요. 문제를 찾으세요."
- 결과를 그대로 기록
- 컨텍스트 완전히 지우기
- 새 컨텍스트: "당신은 검토자 2입니다. 이 루브릭에 대해서만 평가하세요. 문제를 찾으세요."
- 두 검토 결과 비교, 수정, 반복
서브에이전트 패턴이 훨씬 우수합니다. 인라인 시뮬레이션은 검토자 간 컨텍스트 혼합 위험이 있습니다.
패턴 C: 배치 샘플링
대규모 배치(100개 이상)의 경우 모든 항목에 전체 Santa를 적용하는 것은 비용이 많이 듭니다. 계층화 샘플링을 사용하세요:
- Santa를 무작위 샘플(배치의 10-15%, 최소 5개 항목)에 실행
- 실패 유형별로 분류 (할루시네이션, 규정 준수, 완전성 등)
- 체계적 패턴이 발견되면 전체 배치에 대해 대상 수정 적용
- 수정된 배치를 다시 샘플링하고 재검증
- 깨끗한 샘플이 통과할 때까지 계속
import random
def santa_batch(items, rubric, sample_rate=0.15):
sample = random.sample(items, max(5, int(len(items) * sample_rate)))
for item in sample:
result = santa_full(item, rubric)
if result.verdict == "NAUGHTY":
pattern = classify_failure(result.issues)
items = batch_fix(items, pattern) # 패턴과 일치하는 모든 항목 수정
return santa_batch(items, rubric) # 재샘플링
return items # 깨끗한 샘플 → 배치 배송
실패 모드 및 완화
| 실패 모드 | 증상 | 완화 |
|---|---|---|
| 무한 루프 | 수정 후에도 검토자가 계속 새 문제 발견 | 최대 반복 횟수 제한(3회). 에스컬레이션. |
| 도장 찍기 | 두 검토자가 모두 통과시킴 | 적대적 프롬프트: "당신의 임무는 승인이 아니라 문제를 찾는 것입니다." |
| 주관적 표류 | 검토자가 스타일 선호도를 오류로 표시 | 객관적인 통과/실패 기준만 있는 엄격한 루브릭 |
| 수정 회귀 | 문제 A를 수정하면 문제 B 발생 | 각 라운드의 새로운 검토자가 회귀를 발견 |
| 검토자 합의 편향 | 두 검토자 모두 같은 것을 놓침 | 독립성으로 완화되지만 제거되지는 않음. 중요한 출력은 세 번째 검토자 또는 사람 점검 추가. |
| 비용 폭발 | 대규모 출력에서 너무 많은 반복 | 배치 샘플링 패턴. 검증 주기당 예산 제한. |
다른 스킬과의 통합
| 스킬 | 관계 |
|---|---|
| Verification Loop | 결정론적 확인(빌드, 린트, 테스트)에 사용. Santa는 의미론적 확인(정확성, 할루시네이션). verification-loop를 먼저 실행하고 Santa를 나중에 실행. |
| Eval Harness | Santa Method 결과가 평가 메트릭에 제공됨. Santa 실행 전반에 걸친 pass@k를 추적하여 생성기 품질을 시간에 따라 측정. |
| Continuous Learning v2 | Santa 결과가 인스팅트가 됨. 동일 기준의 반복 실패 → 해당 패턴을 피하는 학습된 행동. |
| Strategic Compact | 압축 전에 Santa 실행. 검증 컨텍스트를 중간에 잃지 마세요. |
메트릭
Santa Method 효과를 측정하기 위해 다음을 추적:
- 첫 번째 패스율: 1라운드에서 Santa를 통과하는 출력 비율 (목표: >70%)
- 수렴까지 평균 반복 횟수: NICE까지 평균 라운드 수 (목표: <1.5)
- 이슈 분류: 실패 유형 분포 (할루시네이션 vs. 완전성 vs. 규정 준수)
- 검토자 일치율: 두 검토자가 모두 플래그한 문제 vs. 한 명만 플래그한 문제 비율 (일치율 낮음 = 루브릭 개선 필요)
- 탈출율: 배송 후 발견된 문제 중 Santa가 잡았어야 할 문제 비율 (목표: 0)
비용 분석
Santa Method는 검증 주기당 생성 비용만의 약 2-3배 토큰 비용이 듭니다. 대부분의 고위험 출력에서 이는 저렴한 가격입니다:
Santa 비용 = (생성 토큰) + 2×(라운드당 검증 토큰) × (평균 라운드 수)
Santa가 없는 비용 = (평판 손상) + (수정 노력) + (신뢰 침식)
배치 작업의 경우 샘플링 패턴은 전체 검증 비용의 ~15-20%로 체계적 문제의 >90%를 잡습니다.