Garry Tan의 "Skillify" — AI 에이전트의 실패를 영구적 구조 수정으로 바꾸는 방법론
도입: AI 에이전트의 반복 실패라는 근본적 문제
AI 에이전트가 같은 실수를 반복하는 이유는 명확합니다. 기존 방식은 실패를 그때그때 임시로 패치할 뿐, 에이전트의 핵심 구조를 영구적으로 개선하지 못하기 때문입니다.
Y Combinator CEO Garry Tan은 이 문제에 대한根本적 답을 제시했습니다. 바로 "Skillify" — 일회성 실패를 테스트 가능한 영구적 스킬로 전환하는 10단계 워크플로우입니다.
"It's an opinionated workflow for turning a one-time failure into a permanent structural fix."
이 접근법의 핵심 통찰은 단순합니다: 결정론적工作是 반드시 스크립트로 처리하고, LLM 추론에 의존하지 말 것.
Skillify의 핵심 개념
Skillify는 네 가지 기본 원칙 위에서 작동합니다:
1. 실패를 스킬로 변환
에이전트가 실패할 때마다 그 실패 컨텍스트를 캡처하여 마크다운 절차서 + 결정론적 스크립트 + 단위 테스트로 구성된 스킬 파일로 변환합니다.
2. 검색 가능하도록 등록
생성된 스킬은 Resolver 시스템에 트리거 구문으로 등록되어, 향후 유사한 작업에서 자동으로 호출됩니다.
3. 자동화된 검증
모든 스킬은 단위 테스트와 통합 테스트로 무장하여, 회귀 없이 영구적으로 작동함을 보장합니다.
4. 계층적 품질 게이트
10단계 체크리스트를 통해 스킬이 발견성(AI discoverability)과 안정성(reliability) 모두를 충족해야 합니다.
스킬 파일 구조
skill_name/
├── SKILL.md # 마크다운 절차서
├── script.py # 결정론적 스크립트
├── test_skill.py # 단위 테스트
├── resolver.json # 트리거 조건
└── skill.json # 메타데이터
10단계 스킬 체크리스트
Garry Tan의 GBrain에서 공개된 10단계 체크리스트는 스킬의 품질을 체계적으로 검증합니다:
| 단계 | 요구사항 | 코드 체크 |
|---|---|---|
| 1 | 코드 파일 존재 | .ts/.py 소스 파일 확인 |
| 2 | SKILL.md 존재 | 동반 문서 파일 확인 |
| 3 | 유닛 테스트 | .test.ts 파일 존재 확인 |
| 4 | Resolver 엔트리 | RESOLVER.md 등록 여부 |
| 5 | 트리거 정의 | SKILL.md 프론트매터 트리거 구문 |
| 6 | 도구 정의 | MCP 서버 노출 도구 확인 |
| 7 | Check-resolvable 게이트 | 스킬 트리Integrity 체크 실행 |
| 8 | MECE 컴플라이언스 | 다른 스킬과 트리거 중복 없음 |
| 9 | 버전 관리 | Skillpack 버전 마커 확인 |
| 10 | 문서화 | 명확한 Contract 섹션 존재 |
Skillify 내부 워크플로우
실패 감지에서 스킬 생성까지
실패 발생
↓
skillify.failed() 호출
↓
실패 컨텍스트 캡처 (task_type, task_params, error, context)
↓
SKILL.md 작성 — 실패 원인과 해결 절차를 마크다운으로 문서화
↓
script.py 작성 — 결정론적 스크립트로 문제 해결을 코드로 구현
↓
test_skill.py 작성 — 실패 케이스를 포함한 단위 테스트 생성
↓
resolver.json 업데이트 — 트리거 조건으로 유사 작업 시 자동 호출 등록
↓
스킬 검증 게이트 통과
↓
영구적 스킬로 등록
코드 예시
from skills.orchestration_skills.skillify import get_skillify
skillify = get_skillify()
# 작업 실패 시
skill = skillify.failed(
task_type="target_prioritization",
task_params={"disease": "masld"},
error=Exception("Wrong disease returned"),
context={"plan_id": "abc123"}
)
# 특정 태스크 타입으로 스킬 조회
skill = skillify.get_skill("target_prioritization")
Resolver 시스템 — 자연어를 코드로 연결
Resolver는 GBrain의 "라우팅 테이블"입니다. 자연어 의도를 특정 스킬 파일로 매핑합니다.
RESOLVER.md 구조
| Trigger (자연어) | Skill (경로) |
|---|---|
| "MASLD 타겟 Prioritization 해줘" | skills/target_prioritization/SKILL.md |
| "질병 정보 추출해줘" | skills/disease_extraction/SKILL.md |
check-resolvable 게이트
gbrain check-resolvable 명령어는 네 가지 무결성 검증을 수행합니다:
- Reachability: 모든 스킬이 리졸버를 통해 도달 가능한가?
- MECE Overlap: 여러 스킬이 같은 트리거를 주장하는 않는가?
- MECE Gap: 공통 의도를 처리하는 스킬이 없는 갭이 없는가?
- DRY Violations: 논리가 여러 스킬에 중복되어 있지 않은가?
결정론적 스크립트의 중요성
Skillify의 가장 중요한 설계 원칙 중 하나:
"Deterministic work should ALWAYS use scripts, not LLM inference"
실제 버그 사례
LLM이 의존성의 타겟 컨텍스트를 무시하는 문제가 발생했습니다. 예를 들어, MASLD 쿼리에 대해 Sarcopenia 타겟을 반환하는 오류가 있었죠.
해결 방법: 결정론적 스크립트로 추출을 강제했습니다.
# 모든 질병 추출은 이제 이 함수를 사용
def _extract_disease(disease_query: str) -> list[str]:
"""결정론적 질병 추출 — LLM 추론 없음"""
disease_map = {
"masld": ["NR1H4", "PPARA"],
"sarcopenia": ["FOXO1", "MSTN"],
}
return disease_map.get(disease_query.lower(), [])
Skillpack — 스킬 번들 관리
Skillpack은 에이전트 워크스페이스에 배포되는 스킬과 공유 의존성의 번들입니다.
설치 계약 (Installer Contracts)
| 계약 | 설명 |
|---|---|
| Diff Protection | 대상 파일이 번들과 다르면 --overwrite-local 없이는 스킵 |
| Dependency Closure | 모든 스킬 설치 시 shared_deps 자동 풀 |
| Atomic Updates | 잠금파일(.gbrain-skillpack.lock) + "tmp + rename" 패턴으로 동시 쓰기 보호 |
Skillpack 헬스 리포트
gbrain skillpack-check
# JSON 형태의 에이전트 가독성 리포트 출력
# 상태: "Healthy" 또는 "Needs Attention"
실무 적용: 10단계 실행 가이드
1단계: 실패 컨텍스트 캡처
error_context = {
"task": "사용자 쿼리 처리",
"error": str(e),
"input": task_params,
"timestamp": datetime.now().isoformat()
}
2단계: SKILL.md 작성
---
trigger:
- "질병 타겟 Prioritization"
- "target prioritization for disease"
version: "1.0.0"
---
# Disease Target Prioritization Skill
## Problem
LLM이 잘못된 질병 컨텍스트로 타겟을 반환함.
## Solution
결정론적 매핑 테이블 사용.
3단계: 결정론적 스크립트
# scripts/extract_disease.py
DISEASE_TARGETS = {
"masld": ["NR1H4", "PPARA", "SREBF1"],
"sarcopenia": ["FOXO1", "MSTN", "AKT1"],
}
def extract_targets(disease: str) -> list[str]:
return DISEASE_TARGETS.get(disease.lower(), [])
4단계: 테스트 작성
def test_extract_targets_masld():
result = extract_targets("masld")
assert "NR1H4" in result
assert "PPARA" in result
def test_extract_targets_unknown():
result = extract_targets("unknown_disease")
assert result == []
5~10단계: 통합, 등록, 검증
# Resolver에 등록
gbrain check-resolvable --fix
# 스킬 배포
gbrain skillpack install ./skills/disease_extraction/
# 최종 검증
gbrain skillpack-check
Skillify vs 기존 접근법 비교
| 측면 | 패치 앤 프레이 | Skillify |
|---|---|---|
| 실패 처리 | 임시 패치 | 영구적 스킬 |
| 테스트 | 수동 검증 | 자동 단위/통합 테스트 |
| 발견성 | 없음 | 자연어 트리거로 자동 발견 |
| 회귀 방지 | 보장 없음 | 100% 회귀 방지 |
| 확장성 | 스케일 안 됨 | 스킬 팩으로一键 배포 |
| LLM 의존도 | 높음 | 낮춤 (결정론적 부분) |
전망: AI 에이전트의 영구적 진화
Skillify는 AI 에이전트의 발전 방식을 근본적으로 바꿉니다:
- 경험의 축적: 모든 실패가 영구적 개선으로 이어짐
- 확장 가능한 지식 베이스: 스킬 팩으로 에이전트 간 지식 공유
- 자동화된 품질 보증: 게이트 시스템으로 인간 개입 최소화
- 결정론적 안정성: LLM 추론 범위를 최소화하여 예측 가능한 동작 보장
요약
Garry Tan의 Skillify는 AI 에이전트의 반복 실패 문제를 구조적 설계로 해결하는 방법론입니다. 핵심은 단순합니다:
실패를 버리지 마라 — 스킬로 변환하라.
10단계 워크플로우를 따라 일회성 실패를 마크다운 절차서, 결정론적 스크립트, 단위 테스트로 구성된 영구적 스킬로 전환하면, 에이전트는 같은 실수를 두 번 반복하지 않습니다. 더 이상 임시 패치에 의존하지 않아도 되는 이유입니다.