# 스킬 테스트 & 반복 개선 가이드 하네스에서 생성한 스킬의 품질을 검증하고 반복적으로 개선하는 방법론. SKILL.md Phase 6의 보충 레퍼런스. --- ## 목차 1. [테스트 프레임워크 개요](#1-테스트-프레임워크-개요) 2. [테스트 프롬프트 작성법](#2-테스트-프롬프트-작성법) 3. [실행 테스트: With-skill vs Baseline](#3-실행-테스트-with-skill-vs-baseline) 4. [정량적 평가: Assertion 기반 채점](#4-정량적-평가-assertion-기반-채점) 5. [전문 에이전트 활용](#5-전문-에이전트-활용) 6. [반복 개선 루프](#6-반복-개선-루프) 7. [Description 트리거 검증](#7-description-트리거-검증) 8. [워크스페이스 구조](#8-워크스페이스-구조) --- ## 1. 테스트 프레임워크 개요 스킬 품질 검증은 **정성적 평가**와 **정량적 평가**의 조합이다. | 평가 유형 | 방법 | 적합한 스킬 | |----------|------|-----------| | **정성적** | 사용자가 산출물을 직접 리뷰 | 문체, 디자인, 창작물 등 주관적 품질 | | **정량적** | assertion 기반 자동 채점 | 파일 생성, 데이터 추출, 코드 생성 등 객관적 검증 가능 | 핵심 루프: **작성 → 테스트 실행 → 평가 → 개선 → 재테스트** --- ## 2. 테스트 프롬프트 작성법 ### 원칙 테스트 프롬프트는 **실제 사용자가 입력할 법한 구체적이고 자연스러운 문장**이어야 한다. 추상적이거나 인공적인 프롬프트는 테스트 가치가 낮다. ### 나쁜 예 ``` "PDF를 처리하라" "데이터를 추출하라" "차트를 생성하라" ``` ### 좋은 예 ``` "다운로드 폴더에 있는 'Q4_매출_최종_v2.xlsx'에서 C열(매출)과 D열(비용)을 사용해서 이익률(%) 열을 추가해줘. 그리고 이익률 기준으로 내림차순 정렬." ``` ``` "이 PDF에서 3페이지 표를 추출해서 CSV로 변환해줘. 표 헤더가 2줄로 되어 있어서 첫 번째 줄은 카테고리, 두 번째 줄이 실제 열 이름이야." ``` ### 프롬프트 다양성 - **공식적 / 캐주얼** 톤 혼합 - **명시적 / 암시적** 의도 혼합 (파일 형식을 직접 말하는 경우 vs 맥락으로 추론해야 하는 경우) - **단순 / 복잡** 작업 혼합 - 일부는 약어, 오타, 캐주얼한 표현 포함 ### 커버리지 2~3개 프롬프트로 시작하되, 다음을 커버하도록 설계: - 핵심 사용 사례 1개 - 엣지 케이스 1개 - (선택) 복합 작업 1개 --- ## 3. 실행 테스트: With-skill vs Baseline ### 3-1. 비교 실행 구조 각 테스트 프롬프트에 대해 두 개의 서브에이전트를 **동시에** 스폰한다: **With-skill 실행:** ``` 프롬프트: "{테스트 프롬프트}" 스킬 경로: {스킬 경로} 출력 경로: _workspace/iteration-N/eval-{id}/with_skill/outputs/ ``` **Baseline 실행:** ``` 프롬프트: "{테스트 프롬프트}" (동일) 스킬: 없음 출력 경로: _workspace/iteration-N/eval-{id}/without_skill/outputs/ ``` ### 3-2. Baseline 선택 | 상황 | Baseline | |------|----------| | 새 스킬 생성 | 스킬 없이 같은 프롬프트 실행 | | 기존 스킬 개선 | 수정 전 스킬 버전 (스냅샷 보존) | ### 3-3. 타이밍 데이터 캡처 서브에이전트 완료 알림에서 `total_tokens`와 `duration_ms`를 **즉시** 저장한다. 이 데이터는 알림 시점에만 접근 가능하고 이후 복구할 수 없다. ```json { "total_tokens": 84852, "duration_ms": 23332, "total_duration_seconds": 23.3 } ``` --- ## 4. 정량적 평가: Assertion 기반 채점 ### 4-1. Assertion 작성 산출물이 객관적으로 검증 가능한 경우, 자동 채점을 위한 assertion을 정의한다. **좋은 assertion:** - 객관적으로 참/거짓 판별 가능 - 서술적인 이름으로 결과만 봐도 무엇을 검사하는지 명확 - 스킬의 핵심 가치를 검증 **나쁜 assertion:** - 스킬 유무와 무관하게 항상 통과하는 것 (예: "출력이 존재한다") - 주관적 판단이 필요한 것 (예: "잘 작성되었다") ### 4-2. 프로그래밍 가능한 검증 assertion이 코드로 검증 가능하면 스크립트로 작성한다. 눈으로 확인하는 것보다 빠르고 신뢰성 있으며, iteration마다 재사용 가능. ### 4-3. Non-discriminating assertion 주의 "두 구성 모두에서 100% 통과"하는 assertion은 스킬의 차별적 가치를 측정하지 못한다. 이런 assertion을 발견하면 제거하거나, 더 도전적인 assertion으로 교체한다. ### 4-4. 채점 결과 스키마 ```json { "expectations": [ { "text": "이익률 열이 추가됨", "passed": true, "evidence": "E열에 'profit_margin_pct' 열 확인" }, { "text": "이익률 기준 내림차순 정렬", "passed": false, "evidence": "정렬 없이 원본 순서 유지됨" } ], "summary": { "passed": 1, "failed": 1, "total": 2, "pass_rate": 0.50 } } ``` --- ## 5. 전문 에이전트 활용 테스트/평가 과정에서 전문 역할의 에이전트를 활용하면 품질이 향상된다. ### 5-1. Grader (채점자) assertion 기반 채점을 수행하고, 산출물에서 검증 가능한 주장(claim)을 추출하여 교차 검증한다. **역할:** - assertion별 통과/실패 판정 + 근거 제시 - 산출물에서 사실적 주장을 추출하고 검증 - eval 자체의 품질에 대한 피드백 (assertion이 너무 쉽거나 모호한 경우 제안) ### 5-2. Comparator (블라인드 비교자) 두 산출물을 A/B로 익명화하여, 어떤 것이 스킬을 사용한 결과인지 모르는 상태에서 품질을 판정한다. **활용 시점:** "새 버전이 정말 더 나은가?"를 엄밀하게 확인하고 싶을 때. 일반적인 반복 개선에서는 생략 가능. **판정 기준:** - 내용: 정확성, 완성도 - 구조: 조직화, 포맷팅, 사용성 - 종합 점수 ### 5-3. Analyzer (분석자) 벤치마크 데이터에서 통계적 패턴을 분석한다: - Non-discriminating assertion (두 구성 모두 통과 → 차별력 없음) - 고분산 eval (결과가 실행마다 크게 달라짐 → 불안정) - 시간/토큰 트레이드오프 (스킬이 품질은 높이지만 비용도 높이는 경우) --- ## 6. 반복 개선 루프 ### 6-1. 피드백 수집 사용자에게 산출물을 보여주고 피드백을 받는다. 빈 피드백은 "이상 없음"으로 해석한다. ### 6-2. 개선 원칙 1. **피드백을 일반화하라** — 테스트 예시에만 맞는 좁은 수정은 오버피팅이다. 원리 수준에서 수정한다. 2. **무게를 벌지 않는 것은 제거하라** — 트랜스크립트를 읽고, 스킬이 에이전트에게 비생산적인 작업을 시키고 있다면 해당 부분을 삭제한다. 3. **Why를 설명하라** — 사용자의 피드백이 간결하더라도, 왜 그것이 중요한지 이해하고 그 이해를 스킬에 반영한다. 4. **반복 작업은 번들링하라** — 모든 테스트 실행에서 동일한 헬퍼 스크립트가 생성되면, `scripts/`에 미리 포함한다. ### 6-3. 반복 절차 ``` 1. 스킬 수정 2. 새 iteration-N+1/ 디렉토리에 모든 테스트 케이스 재실행 3. 사용자에게 결과 제시 (이전 iteration과 비교) 4. 피드백 수집 5. 다시 수정 → 반복 ``` **종료 조건:** - 사용자가 만족 - 피드백이 모두 비어 있음 (모든 산출물 이상 없음) - 의미 있는 개선이 더 이상 없음 ### 6-4. 초안 → 재검토 패턴 스킬 수정 시, 초안을 작성한 후 **새로운 시각으로 다시 읽고** 개선한다. 한 번에 완벽하게 쓰려 하지 말고, 초안-검토 사이클을 거친다. --- ## 7. Description 트리거 검증 ### 7-1. 트리거 Eval 쿼리 작성 20개의 eval 쿼리를 작성한다 — should-trigger 10개 + should-NOT-trigger 10개. **쿼리 품질 기준:** - 실제 사용자가 입력할 법한 구체적이고 자연스러운 문장 - 파일 경로, 개인적 맥락, 열 이름, 회사명 등 구체적 디테일 포함 - 길이, 톤, 형식 다양하게 혼합 - 명확한 정답보다 **경계 케이스(edge case)**에 집중 **Should-trigger 쿼리 (8~10개):** - 다양한 표현의 같은 의도 (공식적/캐주얼) - 스킬/파일 유형을 명시적으로 말하지 않지만 분명히 필요한 경우 - 비주류 사용 사례 - 다른 스킬과 경쟁하지만 이 스킬이 이겨야 하는 경우 **Should-NOT-trigger 쿼리 (8~10개):** - **Near-miss가 핵심** — 키워드가 유사하지만 다른 도구/스킬이 적합한 쿼리 - 명백히 무관한 쿼리("피보나치 함수 작성")는 테스트 가치 없음 - 인접 도메인, 모호한 표현, 키워드 겹침 but 맥락이 다른 경우 ### 7-2. 기존 스킬 충돌 검증 새 스킬의 description이 기존 스킬의 트리거 영역과 겹치지 않는지 확인한다: 1. 기존 스킬 목록의 description을 수집 2. 새 스킬의 should-trigger 쿼리가 기존 스킬을 잘못 트리거하지 않는지 확인 3. 충돌 발견 시 description의 경계 조건을 더 명확히 기술 ### 7-3. 자동 최적화 (선택적 고급 기능) description 최적화가 필요한 경우: 1. 20개 eval 쿼리를 Train(60%) / Test(40%) split 2. 현재 description으로 트리거 정확도 측정 3. 실패 케이스를 분석하여 개선된 description 생성 4. Test set 기준으로 best description 선택 (Train set 기준이 아님 — 과적합 방지) 5. 최대 5회 반복 > 이 과정은 `claude -p`를 사용하는 자동화 스크립트로 수행한다. 토큰 비용이 높으므로 스킬이 충분히 안정화된 후 최종 단계에서 실행한다. --- ## 8. 워크스페이스 구조 테스트/평가 결과를 체계적으로 관리하는 디렉토리 구조: ``` {skill-name}-workspace/ ├── iteration-1/ │ ├── eval-descriptive-name-1/ │ │ ├── eval_metadata.json │ │ ├── with_skill/ │ │ │ ├── outputs/ │ │ │ ├── timing.json │ │ │ └── grading.json │ │ └── without_skill/ │ │ ├── outputs/ │ │ ├── timing.json │ │ └── grading.json │ ├── eval-descriptive-name-2/ │ │ └── ... │ └── benchmark.json ├── iteration-2/ │ └── ... └── evals/ └── evals.json ``` **규칙:** - eval 디렉토리는 숫자가 아닌 **서술적 이름** 사용 (예: `eval-multi-page-table-extraction`) - 각 iteration은 독립 디렉토리에 보존 (이전 iteration 덮어쓰기 금지) - `_workspace/`는 삭제하지 않음 — 사후 검증 및 감사 추적용