| name | santa-method |
| description | 수렴 루프가 포함된 다중 에이전트 대립적 검증입니다. 두 명의 독립적인 리뷰 에이전트가 모두 통과시켜야 출력이 배포됩니다. |
| origin | Ronald Skelton - Founder, RapportScore.ai |
산타 메서드 (Santa Method)
다중 에이전트 대립적(adversarial) 검증 프레임워크입니다. 명단을 만들고, 두 번 확인하세요. 나쁜(naughty) 결과물이면 착해질(nice) 때까지 수정합니다.
핵심 통찰: 자신의 출력을 스스로 리뷰하는 단일 에이전트는 해당 출력을 생성한 편향, 지식 공백 및 체계적 오류를 공유합니다. 공유된 컨텍스트가 없는 두 명의 독립적인 리뷰어는 이러한 실패 모드를 차단합니다.
활성화 시점
다음과 같은 경우 이 스킬을 호출하세요:
- 출력이 최종 사용자에게 게시, 배포 또는 소비될 때
- 준법(compliance), 규제 또는 브랜드 제약 조건을 강제해야 할 때
- 사람의 검토 없이 코드가 프로덕션에 배포될 때
- 콘텐츠의 정확성이 중요할 때 (기술 문서, 교육 자료, 고객 대상 카피 등)
- 샘플링 검사로는 체계적 패턴을 놓칠 수 있는 대규모 배치 생성 시
- 환각(hallucination) 위험이 높을 때 (주장, 통계, API 참조, 법률 용어 등)
내부 초안 작성, 탐색적 연구 또는 결정론적 검증이 가능한 작업(빌드/테스트/린트 파이프라인 활용)에는 사용하지 마세요.
아키텍처
┌─────────────┐
│ 생성기 │ 1단계: 명단 작성 (Make a List)
│ (에이전트 A) │ 산출물 생성
└──────┬───────┘
│ 출력
▼
┌──────────────────────────────┐
│ 이중 독립 리뷰 │ 2단계: 두 번 확인 (Check It Twice)
│ │
│ ┌───────────┐ ┌───────────┐ │ 동일한 루브릭을 사용하고
│ │ 리뷰어 B │ │ 리뷰어 C │ │ 컨텍스트를 공유하지 않는
│ └─────┬─────┘ └─────┬─────┘ │ 두 명의 에이전트
│ │ │ │
└────────┼──────────────┼────────┘
│ │
▼ ▼
┌──────────────────────────────┐
│ 판정 게이트 │ 3단계: 착한지 나쁜지 (Naughty or Nice)
│ │
│ B 통과 AND C 통과 → NICE │ 둘 다 통과해야 함.
│ 그 외 → NAUGHTY │ 예외 없음.
└──────┬──────────────┬─────────┘
│ │
NICE NAUGHTY
│ │
▼ ▼
[ 배포 ] ┌─────────────┐
│ 수정 사이클 │ 4단계: 착해질 때까지 수정
│ │
│ 반복 횟수++ │ 모든 지적 사항 수집.
│ 만약 i > MAX: │ 모든 문제 수정.
│ 에스컬레이션 │ 리뷰어 둘 다 재실행.
│ 아니면: │ 수렴할 때까지 루프.
│ 2단계로 이동 │
└──────────────┘
단계별 상세 내용
1단계: 명단 작성 (생성)
기본 작업을 수행합니다. 일반적인 생성 워크플로를 변경할 필요는 없습니다. 산타 메서드는 생성 전략이 아니라 생성 후 검증 레이어입니다.
output = generate(task_spec)
2단계: 두 번 확인 (독립적인 이중 리뷰)
두 명의 리뷰 에이전트를 병렬로 생성합니다. 핵심 불변 조건:
- 컨텍스트 격리 — 리뷰어끼리 서로의 평가를 볼 수 없음
- 동일한 루브릭 — 둘 다 동일한 평가 기준을 받음
- 동일한 입력 — 둘 다 원래 사양(spec)과 생성된 출력을 모두 받음
- 구조화된 출력 — 서술형이 아닌 정형화된 판정 결과 반환
REVIEWER_PROMPT = """
당신은 독립적인 품질 리뷰어입니다. 이 출력에 대한 다른 리뷰를 전혀 보지 못한 상태입니다.
## 작업 사양 (Task Specification)
{task_spec}
## 리뷰 대상 출력
{output}
## 평가 루브릭 (Evaluation Rubric)
{rubric}
## 지침
각 루브릭 기준에 따라 출력을 평가하세요. 각 항목에 대해:
- PASS: 기준을 완벽히 충족함, 문제 없음
- FAIL: 구체적인 문제 발견 (정확한 문제 지점 인용)
평가 결과를 구조화된 JSON으로 반환하세요:
{
"verdict": "PASS" | "FAIL",
"checks": [
{"criterion": "...", "result": "PASS|FAIL", "detail": "..."}
],
"critical_issues": ["..."], // 반드시 수정해야 하는 차단 요소
"suggestions": ["..."] // 차단 요소는 아니지만 개선 가능한 권장 사항
}
엄격하게 평가하세요. 당신의 임무는 승인하는 것이 아니라 문제를 찾아내는 것입니다.
"""
review_b = Agent(prompt=REVIEWER_PROMPT.format(...), description="산타 리뷰어 B")
review_c = Agent(prompt=REVIEWER_PROMPT.format(...), description="산타 리뷰어 C")
루브릭(Rubric) 설계
루브릭은 가장 중요한 입력값입니다. 모호한 루브릭은 모호한 리뷰를 낳습니다. 모든 기준은 객관적인 합격/불합격 조건을 가져야 합니다.
| 기준 | 합격 조건 | 불합격 신호 |
|---|
| 사실 정확성 | 모든 주장이 소스 자료나 상식에 근거해 검증 가능함 | 지어낸 통계, 잘못된 버전 번호, 존재하지 않는 API |
| 환각 없음 | 허구의 엔티티, 인용구, URL 또는 참조가 없음 | 존재하지 않는 페이지 링크, 출처 없는 인용구 할당 |
| 완결성 | 사양의 모든 요구 사항이 다루어짐 | 섹션 누락, 예외 케이스 무시, 불충분한 범위 |
| 준수성 | 모든 프로젝트별 제약 조건을 통과함 | 금지어 사용, 톤 위반, 규제 미준수 |
| 내부 일관성 | 출력 내에 모순이 없음 | A 섹션에서는 X라고 하고 B 섹션에서는 X가 아니라고 함 |
| 기술적 정확성 | 코드가 컴파일/실행되며 알고리즘이 견고함 | 구문 오류, 로직 버그, 잘못된 복잡도 주장 |
도메인별 루브릭 확장
콘텐츠/마케팅:
- 브랜드 보이스 준수 여부
- SEO 요구 사항 충족 (키워드 밀도, 메타 태그, 구조)
- 경쟁사 상표권 오용 없음
- CTA(Call to Action) 존재 및 정확한 링크
코드:
- 타입 안전성 (
any 누출 없음, 적절한 널 처리)
- 에러 처리 범위
- 보안 (코드 내 시크릿 없음, 입력 유효성 검사, 인젝션 방지)
- 새로운 경로에 대한 테스트 커버리지
규제 준수 민감 (규제, 법률, 금융):
- 결과 보장이나 근거 없는 주장 없음
- 필수 고지 사항(disclaimers) 포함
- 승인된 용어만 사용
- 관할권에 적합한 언어 사용
3단계: 착한 아이인지 나쁜 아이인지 (판정 게이트)
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
둘 다 통과해야 하는 이유: 한 명의 리뷰어만 문제를 잡아냈더라도 그 문제는 실재하는 것입니다. 다른 리뷰어가 이를 놓친 것이 바로 산타 메서드가 제거하고자 하는 실패 모드입니다.
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 하위 에이전트 (권장)
하위 에이전트는 진정한 의미의 컨텍스트 격리를 제공합니다. 각 리뷰어는 공유된 상태가 없는 별도의 프로세스입니다.
패턴 B: 순차적 인라인 (대안)
하위 에이전트를 사용할 수 없는 경우, 명시적인 컨텍스트 초기화로 격리를 흉내 냅니다:
- 출력 생성
- 새로운 컨텍스트: "당신은 리뷰어 1입니다. 이 루브릭에 대해서만 평가하세요. 문제를 찾으세요."
- 발견 사항을 그대로 기록
- 컨텍스트를 완전히 비움
- 새로운 컨텍스트: "당신은 리뷰어 2입니다. 이 루브릭에 대해서만 평가하세요. 문제를 찾으세요."
- 두 리뷰를 비교하고 수정 후 반복
하위 에이전트 패턴이 훨씬 우수합니다. 인라인 시뮬레이션은 리뷰어 간에 컨텍스트가 섞일 위험이 있습니다.
패턴 C: 배치 샘플링
대량의 배치(100개 이상) 작업 시 모든 항목에 전체 산타 메서드를 적용하는 것은 비용이 많이 듭니다. 층화 추출(stratified sampling)을 사용하세요:
- 무작위 샘플(배치의 10~15%, 최소 5개)에 대해 산타 실행
- 실패 유형별로 분류 (환각, 준수성, 완결성 등)
- 체계적인 패턴이 발견되면 배치 전체에 타겟팅된 수정을 적용
- 수정된 배치를 다시 샘플링하여 재검증
- 깨끗한 샘플이 통과될 때까지 반복
실패 모드 및 완화 방법
| 실패 모드 | 증상 | 완화 방법 |
|---|
| 무한 루프 | 수정 후에도 리뷰어가 계속 새로운 문제를 찾아냄 | 최대 반복 횟수 제한 (3회). 에스컬레이션. |
| 형식적 승인 | 두 리뷰어 모두 모든 것을 통과시킴 | 대립적 프롬프트: "당신의 임무는 승인이 아니라 문제를 찾는 것입니다." |
| 주관적 이탈 | 리뷰어가 오류가 아닌 스타일 선호도를 지적함 | 객관적인 합격/불합격 기준만 있는 촘촘한 루브릭 작성 |
| 수정 회귀 | 문제 A를 고쳤더니 문제 B가 발생함 | 매 라운드 새로운 리뷰어가 회귀 결함을 잡아냄 |
| 리뷰어 합의 편향 | 두 리뷰어 모두 동일한 것을 놓침 | 독립성으로 완화되지만 완벽하진 않음. 중요한 출력은 제3의 리뷰어나 사람이 직접 확인. |
| 비용 폭증 | 큰 출력물에 대해 너무 많은 반복 수행 | 배치 샘플링 패턴 활용. 검증 사이클당 예산 캡 설정. |
다른 스킬과의 통합
| 스킬 | 관계 |
|---|
| Verification Loop | 결정론적 체크(빌드, 린트, 테스트)에 사용. 산타는 의미론적 체크(정확성, 환각)에 사용. verification-loop를 먼저 실행하고 산타를 나중에 실행. |
| Eval Harness | 산타 메서드 결과가 평가 메트릭에 반영됨. 산타 실행 전반의 pass@k를 추적하여 생성기 품질을 측정. |
| Continuous Learning v2 | 산타의 발견 사항이 본능이 됨. 동일한 기준에 대해 반복적으로 실패하면 해당 패턴을 피하도록 학습. |
| Strategic Compact | 압축(compacting) 전에 산타를 실행. 검증 중간에 리뷰 컨텍스트를 잃지 않도록 함. |
메트릭 (지표)
산타 메서드의 효과를 측정하기 위해 다음을 추적하세요:
- 1차 통과율: 1라운드에서 산타를 통과한 출력의 비율 (목표: >70%)
- 수렴까지의 평균 반복 횟수: NICE 판정까지 걸린 평균 라운드 (목표: <1.5)
- 문제 분류: 실패 유형 분포 (환각 vs 완결성 vs 준수성)
- 리뷰어 합치도: 두 리뷰어 모두 지적한 문제 vs 한 명만 지적한 문제의 비율 (낮은 합치도는 루브릭을 더 조여야 함을 의미)
- 탈출율: 배포 후 발견된 문제 중 산타가 잡았어야 할 문제의 비율 (목표: 0)
비용 분석
산타 메서드는 검증 사이클당 생성 비용의 약 2~3배에 해당하는 토큰 비용이 듭니다. 위험도가 높은 출력물의 경우 이는 매우 저렴한 비용입니다:
산타 비용 = (생성 토큰) + 2 × (라운드당 리뷰 토큰) × (평균 라운드 수)
산타를 안 썼을 때의 비용 = (평판 손상) + (수정 노력) + (신뢰 하락)
배치 작업의 경우 샘플링 패턴을 사용하면 전체 검증 비용의 15~20%만으로도 체계적 문제의 90% 이상을 잡아낼 수 있습니다.