zioinfo-mail/plugins/harness-main/skills/harness/references/skill-testing-guide.md
DESKTOP-TKLFCPR\ython e228faabf5 feat(itsm): G-1~G-12 확장 기능 + 하네스/봇/설치스크립트 구현
G-1: 메신저 Webhook Relay + _send_to_room 실제 httpx 호출 구현
G-2: POST /api/tasks/bulk SR 대량작업 엔드포인트 (최대 100건)
G-3: 라이선스 만료 알림 스케줄러 (매일 09:00 KST)
G-4: 체험판 upgrade_banner 필드 + license.py 배너 로직
G-5: core/auto_rca.py + incidents/problem auto-rca 엔드포인트
G-6: core/deploy_impact.py + vibe impact-analysis 엔드포인트
G-7: core/ticket_classifier.py + SR 생성 시 AI 분류 + ai-suggestion API
G-8: VulnPatchRecord 모델 + vuln_scan 패치추적 4개 엔드포인트
G-9: core/jira_sync.py + gateway Jira/Confluence 연동 엔드포인트
G-10: core/push_notify.py + routers/push.py + PushSubscription 모델
G-11: approvals 다중승인 (위임/서명/기한초과/마감연장)
G-12: alembic.ini + migrations/ + cicd/migrate_to_postgres.sh

하네스: guardia-orchestrator 확장기능 Phase 반영
봇명령어: /sr /status /license /bulk 슬래시 명령어 추가
설치스크립트: setup/ (Ubuntu, CentOS, RHEL, Windows) --test 옵션 포함

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-29 18:18:52 +09:00

11 KiB

스킬 테스트 & 반복 개선 가이드

하네스에서 생성한 스킬의 품질을 검증하고 반복적으로 개선하는 방법론. SKILL.md Phase 6의 보충 레퍼런스.


목차

  1. 테스트 프레임워크 개요
  2. 테스트 프롬프트 작성법
  3. 실행 테스트: With-skill vs Baseline
  4. 정량적 평가: Assertion 기반 채점
  5. 전문 에이전트 활용
  6. 반복 개선 루프
  7. Description 트리거 검증
  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_tokensduration_ms즉시 저장한다. 이 데이터는 알림 시점에만 접근 가능하고 이후 복구할 수 없다.

{
  "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. 채점 결과 스키마

{
  "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/는 삭제하지 않음 — 사후 검증 및 감사 추적용