스킬 리뷰: 새로운 워크플로우를 위한 새로운 산출물
요약
AI 에이전트의 '스킬(Skill)'을 검증하기 위한 새로운 리뷰 프레임워크를 소개합니다. 단순한 스트레스 테스트를 넘어, 라우팅 신호와 출력 계약 등 에이전트 워크플로우의 맥락적 적합성을 평가하는 5차원 체크리스트를 제안합니다.
핵심 포인트
- 스트레스 테스트와 스킬 리뷰의 차이점 명시
- 에이전트 스킬을 위한 5차원 리뷰 프레임워크 제안
- 라우팅 신호, 출력 계약, 일반화 가능성 등 핵심 검증 요소
- 단순 코드 리뷰와 차별화된 에이전트 중심의 검토 방식
서문
본론으로 들어가기에 앞서 솔직하게 말씀드리고 싶은 것이 있습니다. 이 글에 등장하는 프레임워크 중 그 어떤 것도 제 것이 아닙니다. 이곳의 아이디어들은 저보다 훨씬 더 깊고 오래 이 문제에 대해 고민해 온 두 분으로부터 왔으며, 제가 다른 말을 하기 전에 그분들에게 온전한 공로를 돌려야 마땅합니다.
Dan Shapiro — Glowforge의 CEO이자 Wharton 연구원이며, 이 모든 대화에 어휘를 제공해 준 분입니다. 그의 블로그 포스트인 “The Five Levels: from Spicy Autocomplete to the Dark Factory”는 제가 말하고자 하는 모든 것의 개념적 중추입니다. 원문을 읽어보세요. 짧고 날카로우며, 가장 좋은 방식으로 당신을 불편하게 만들 것입니다. danshapiro.com
Issue #11은 Gherkin 품질 스킬을 스트레스 테스트(stress-tested)하여 네 가지 실패 모드(failure modes)를 발견했습니다. 이후 Issue #11은 이를 수정했습니다. 그 결과로 나온 v2.0 스킬은 모든 적대적 입력(adversarial input)을 통과했습니다.
이번 이슈는 가장 먼저 제기되었어야 할 질문을 던집니다: 스트레스 테스트가 무엇이 잘못되었는지 알려주기 전에, 어떻게 스킬을 리뷰할 것인가?
그 답은 중요합니다. 왜냐하면 스트레스 테스트와 스킬 리뷰(skill reviews)는 서로 다른 것을 잡아내기 때문입니다. 스트레스 테스트는 "스킬이 호출되었을 때 작동하는가?"에 답합니다. 리뷰는 "스킬이 그 설명이 암시하는 모든 맥락에서 호출될 준비가 되었는가?"에 답합니다. 이 둘은 상호 보완적입니다. Issue #11과 #12에서 일어났던 것처럼 스트레스 테스트를 먼저 수행하고 리뷰를 나중에 하는 것은 잘못된 순서입니다.
스킬 리뷰가 코드 리뷰와 다른 분야인 이유
코드 리뷰(Code review)는 해결된 문제입니다. 당신은 차이점(diff)을 검토합니다. 로직을 확인합니다. "이 코드가 의도한 대로 작동하는가?"라고 묻고, 승인하거나 수정을 요청합니다.
스킬 리뷰는 해결된 문제가 아닙니다. 리뷰 대상이 다릅니다. 당신은 코드가 올바른지를 묻는 것이 아닙니다. 당신은 다음과 같이 묻습니다:
- 라우팅 신호 (routing signal)가 이 스킬이 작동해야 하는 모든 맥락에서 올바르게 작동하며, 작동해서는 안 되는 맥락에서는 작동하지 않습니까?
- 두 명의 에이전트 (agents)가 출력 계약 (output contract)을 모두 충족하면서도 서로 다른 출력을 생성할 가능성이 있습니까?
- 방법론 (methodology)이 일반화 가능한 추론 (reasoning)을 설명하고 있습니까, 아니면 제시된 예시에만 적용되는 절차 (procedure)를 설명하고 있습니까?
- 스킬이 올바른 출력을 생성할 수 없을 때 명시적으로 실패합니까, 아니면 그럴듯해 보이는 잘못된 출력을 생성합니까?
이 질문들 중 그 어떤 것도 코드를 읽는 것만으로는 답할 수 없습니다. 오직 구조화된 체크리스트 (checklist)를 통해 수행함으로써만 답할 수 있습니다.
5차원 체크리스트
이번 세션에서 구축된 리뷰 프레임워크 (review framework)는 다섯 가지 차원을 다룹니다. 스킬 버전이 승인되기 전에 모든 번호가 매겨진 질문에 답해야 합니다. 스킬을 읽고 "이게 합리적으로 보이나?"라고 묻는 리뷰어는 스킬 리뷰를 수행하고 있는 것이 아닙니다.
차원 1 — 라우팅 신호 (Routing signal)
설명이 한 줄이며 120자 미만입니까? 아티팩트 유형 (artifact type), 도메인 범위 (domain scope), 그리고 방법론 (methodology)을 명시하고 있습니까? 즉, 올바르게 라우팅될 수 있을 만큼 구체적이면서도 오라우팅 (misroute)되지 않을 만큼 일반적입니까?
테스트: 이 스킬로 라우팅되어야 하는 프롬프트 (prompts) 3개와 라우팅되지 않아야 하는 프롬프트 3개를 작성하십시오. 각각을 검증하십시오. 오라우팅 사례가 있다면 기록하십시오.
차원 2 — 출력 계약 (Output contract)
계약이 명시적이고 열거 가능합니까? 즉, 모든 요구사항이 주관적인 판단이 아닌 예/아니오(yes/no)로 확인할 수 있는 항목입니까? 두 명의 에이전트 (agents)가 계약을 모두 충족하면서도 서로 다른 출력을 생성할 수 있습니까? 계약이 스킬이 생성해야 하는 것뿐만 아니라, 생성해서는 안 되는 것도 명시하고 있습니까?
테스트: 다운스트림 소비자 (downstream consumer)를 식별하십시오. 소비자가 스킬의 출력으로 무엇을 하는지 기록하십시오. 해당 소비 패턴에 계약이 충분한지 질문하십시오.
차원 3 — 방법론 (Methodology)
방법론이 추론 (reasoning)을 설명합니까, 아니면 절차 (procedure)를 설명합니까? 방법론 예시에 포함되지 않은 엣지 케이스 (edge case) 입력값 3개를 선택하십시오. 방법론을 수동으로 적용해 보십시오. 각 입력에 대해 올바른 출력을 생성하는지 기록하십시오.
테스트 방법: 에이전트가 제1원리 (first principles)로부터 추론할 수 없는 도메인 지식을 식별하십시오. 이는 암시되는 것이 아니라 명시적으로 기술되어야 합니다.
차원 4 — 멱등성 (Idempotency) 및 안정성
동일한 입력에 대해 세 가지 서로 다른 프레이밍 (framing)을 적용하여 해당 스킬을 적용해 보십시오. 세 가지 모두 구조적으로 동일한 출력을 생성합니까? 이미 올바른 입력에 스킬을 적용해 보십시오. 변경 없이 그대로 반환합니까, 아니면 불필요하게 다시 작성합니까? 스킬의 출력 자체에 스킬을 적용해 보십시오. 변경 없이 그대로 반환합니까?
차원 5 — 실패 모드 (Failure modes)
범위를 벗어난 입력 1개, 모순되는 입력 1개, 빈 입력 1개로 테스트하십시오. 각 경우에 대해 출력을 다음과 같이 분류하십시오: 실패 신호 (FAIL SIGNAL, 명시적 실패, 출력 없음), 그럴듯한 오답 (PLAUSIBLE WRONG, 올바르게 보이지만 오류를 포함함), 또는 올바른 거부 (CORRECT REFUSAL, 실행 가능한 오류 메시지). 모든 '그럴듯한 오답' 결과가 제거되었습니까?
v1.1에 프레임워크 적용하기
v1.1 리뷰는 Issue #11의 스트레스 테스트가 필요해지기 전에 수행되었어야 할 리뷰입니다. 다섯 가지 차원을 모두 검토하면서 스트레스 테스트로는 절대 찾을 수 없었을 발견 사항들을 찾아냈으며, 스트레스 테스트가 찾아낸 실패가 정확히 무엇인지 확인했습니다.
라우팅 신호 (Routing signal) — 120자 제한 대비 137자. 설명이 임계값을 17자 초과했습니다. 많은 에이전트 라우팅 프레임워크는 이 임계값을 넘으면 신호를 잘라내거나 우선순위를 낮춥니다. 초과된 부분에는 "and output contract"가 포함되어 있는데, 이는 스킬 작성자에게는 의미가 있지만 120자 예산으로 라우팅하는 에이전트에게는 보이지 않습니다. Issue #11의 스트레스 테스트는 이를 찾을 수 없었습니다. 스트레스 테스트는 스킬이 호출되었을 때의 동작을 테스트하기 때문입니다. 스킬이 호출되는지 여부는 테스트할 수 없습니다.
출력 계약 (Output contract)이 에이전트의 발산 (divergence)을 허용함. 네 가지의 불충분하게 명시된 요구사항이 두 에이전트가 계약을 모두 충족하면서도 서로 다른 출력을 생성할 수 있게 합니다: 시나리오 제목의 "명시적 (explicit)" 기준, 시나리오 유형별 필수 필드, 결과별 필수 HTTP 상태 코드, 시나리오 유형별 필수 외부 서비스. 스트레스 테스트는 한 에이전트의 출력만을 검증합니다. 동일한 계약을 바탕으로 작업하는 두 번째 에이전트에게 허용된 재량권을 드러낼 수는 없습니다.
Given 절(Given clause) 누락에 따른 방법론적 격차 (Methodology gap). Q3 체크는 용어가 정의되었는지는 묻지만, 전제 조건 상태(precondition state)가 설정되었는지는 묻지 않습니다. Given 절이 없는 시나리오의 경우, 단계(steps) 중 정의되지 않은 명사를 사용하는 것이 없다면 Q3를 통과하게 됩니다. 스트레스 테스트는 잘 구성된 입력값(well-formed inputs)을 사용했으므로, 이러한 격차는 입력 세트의 문제가 아니었습니다.
두 가지 개연성 있는 잘못된(PLAUSIBLE WRONG) 실패 모드 확인:
- UI 시나리오 → API 시나리오로 조용히 변환됨
- 모순된 제약 조건(Contradictory constraints) → 가정(assumptions)으로 문서화되었으나, 시나리오는 그대로 생성됨
두 사례 모두 Issue #11 스트레스 테스트에서 발견된 실패 사례와 정확히 일치합니다. 이 체크리스트를 사용하여 v2.0 이전 버전에서 리뷰를 수행했다면 두 경우 모두 명시적인 종료(explicit termination)를 요구했을 것입니다. 또한, v2.0의 Guard 2와 3은 스트레스 테스트가 필요해지기 전에 이미 구축되었을 수도 있습니다.
v1.1 리뷰 판정: 변경 요청 (CHANGES REQUESTED).
v2.0에 프레임워크 적용
v2.0 리뷰를 통해 네 가지 스트레스 테스트 실패 사례가 수정되었음을 확인했습니다. 또한 스트레스 테스트가 놓쳤던 세 가지 이슈를 발견했습니다.
라우팅 신호(Routing signal)가 현재 179자입니다. v2.0은 이미 실패하고 있었던 v1.1의 신호보다 42자 더 길게 신호를 만들었습니다. ", four pre-flight guards, and a minimal-change"의 추가는 이 스킬(skill)로 라우팅하는 호출자(caller)에게는 무관한 내부 구현 메커니즘을 설명하고 있습니다. 이제 라우팅 신호는 스킬이 무엇을 생성하는지가 아니라, 스킬이 내부적으로 어떻게 작동하는지를 설명하고 있습니다.
Guard 4의 반환 값 형식(return value format)이 두 가지 지침 사이에서 모호합니다. 이것이 이번 세션에서 발견된 가장 중요한 사항입니다. 자세한 내용은 아래에 기록되어 있습니다.
Q5 side-effect assertion 누락에 대한 Guard 4의 공백. 다섯 가지 Guard 4 형식 조건(구체적인 ID, 명명된 서비스, HTTP 상태, UNDERSPECIFIED 패턴 없음, 필드+값 Then 절)을 모두 통과하지만, Q5 side-effect assertion(결제 게이트웨이 호출 횟수, 재고 예약 assertion)이 누락된 시나리오의 경우, Guard 4가 트리거되어 "변경 사항 필요 없음(no changes required)"을 반환합니다. 이 스킬은 불완전한 시나리오에 대해 완료 신호를 보내는 것입니다. Issue #11의 스트레스 테스트(stress tests)는 v2.0이 해결하도록 설계된 네 가지 실패 모드(failure modes)에 집중했기 때문에 이러한 입력 유형을 테스트하지 않았습니다.
두 가지 새로운 에지 케이스(edge cases) 도입:
- Guard 2는 세 개의 API 단계에 대해 부분적인 지원이 가능함에도 불구하고, UI/API 혼합 시나리오(UI 단계 1개, API 단계 3개)를 완전히 거부합니다. 과도하게 광범위한 거부(Over-broad refusal)입니다.
- v2.1 작업 목록: 설명 단축, Guard 4 반환 형식 명확화, Guard 4에 Q5 side-effect 체크 추가, 혼합 UI/API 처리 방식 문서화, Guard 2의 패턴 목록에 추론(reasoning) 추가.
v2.0 리뷰 판정: 의견 포함 승인 (APPROVED WITH COMMENTS).
네 가지 주요 실패 모드가 해결되었습니다. 새로운 이슈들은 차단 요소(blocking)가 아닙니다. v2.0은 v2.1 계획과 함께 정식 버전(canonical version)이 될 준비가 되었습니다.
실제 리뷰 코멘트
PR:
gherkin-scenario-quality-v2.md— Agent-safe Gherkin quality skill
Section: Pre-flight guards → Guard 4 (Idempotency check)
Guard 4에는 서로 충돌하는 두 가지 반환 지침이 있으며, 이 충돌은 에이전트 규모(agent scale)에서 중요하게 작용합니다.
"Return:" 블록에는 어노테이션 코멘트만 표시됩니다:
# SKILL: No changes required — scenario satisfies output contract.
# Five-question diagnostic result: [observations, or "none"]
그런 다음 다음 줄에는 다음과 같이 명시되어 있습니다: "Guard 4가 트리거되면, 입력 시나리오를 변경하지 않은 상태로 반환하십시오."
이것들을 종합하면 다음과 같이 읽힙니다: 주석 블록을 반환하고, '동시에' 입력 시나리오를 반환하십시오. 하지만 스킬 (skill)은 단일 값을 반환합니다. 이 두 지침은 세 가지 가능한 해석을 암시합니다: (a) 주석만 — 시나리오는 출력에 포함되지 않음; (b) 다른 곳에서 사용되는 최소 수정 (minimal-fix) 패턴과 일치하도록 시나리오 앞에 주석을 붙임; 또는 (c) 시나리오 뒤에 주석을 붙임.
스킬의 나머지 부분은 형식 (b)를 사용합니다. Guard 4의 "Return:" 블록은 형식 (a)를 사용합니다. 사람이 출력을 읽고 시나리오를 피처 파일 (feature file)에 수동으로 붙여넣을 때는 이 불일치가 보이지 않습니다. 사람은 주석을 무시하고 시나리오를 붙여넣기 때문입니다. 하지만 자동화된 파이프라인 (automated pipeline)에서는 이것이 보이지 않는 문제가 아닙니다.
구체적인 영향: Guard 4의 출력을 받아 모든 스킬 출력을 피처 파일에 쓰는 다운스트림 에이전트 (downstream agent)는 # SKILL: No changes required 주석을 파일 내에 Gherkin 주석으로 작성하게 됩니다. 50개의 피처 파일에 걸친 파이프라인 규모에서는, 50개의 스킬 내부용 주석이 프로덕션 사양 (production specs)에 커밋되는 결과를 초래합니다. 만약 에이전트가 해석 (a)를 사용하여 주석 블록을 전체 출력으로 취급한다면, 원래의 시나리오는 조용히 폐기되어 두 줄의 주석으로 대체됩니다.
제안하는 수정 사항: Guard 4의 반환 사양을 최소 수정 (minimal-fix) 주석 패턴과 일치시키십시오:
다음 주석을 앞에 붙여 입력 시나리오를 반환하십시오:
# SKILL: No changes required — scenario satisfies output contract.
# Five-question diagnostic result: [observations; "none" if Q1–Q5 find nothing]
...
또는, 주석이 호출자 메타데이터 (caller metadata)이며 Gherkin 출력의 일부가 아니라면, 이를 명시적으로 기술하십시오: "가드 주석은 호출자 메타데이터입니다. 이를 피처 파일에 포함하지 마십시오. 변경되지 않은 시나리오 이전에 별도의 응답 블록으로 반환하십시오."
두 가지 방식 모두 모호성을 제거합니다. 현재의 텍스트는 다운스트림 에이전트가 추측하도록 만들고 있습니다.
이것이 두 리뷰 중 가장 중요한 발견인 이유: v2.0은 에이전트 규모 (agent scale)에서 안전하도록 명시적으로 구축되었습니다. 네 가지 가드 (guards)가 존재하는 이유는 자동화된 파이프라인이 인간 호출자는 조용히 처리할 수 있는 실패 모드 (failure modes)를 생성하기 때문입니다. Guard 4의 반환 값 명세 (return value specification)는 그것이 방지하도록 설계된 것과 동일한 종류의 실패를 겪고 있습니다. 즉, 인간은 출력을 읽을 때 어느 부분이 시나리오이고 어느 부분이 메타데이터인지 알 수 있지만, 자동화된 파이프라인은 그렇지 못합니다. 스트레스 테스트 (stress tests)를 통해 Guard 4가 올바르게 트리거됨을 확인했습니다. 하지만 스트레스 테스트는 스킬을 격리된 상태에서 테스트하기 때문에, Guard 4의 출력이 모든 다운스트림 소비자 (downstream consumers)에게 올바르게 명세되어 있는지는 확인할 수 없었습니다.
스트레스 테스트와 스킬 리뷰 사이의 경계
Issue #11의 스트레스 테스트에서는 세 가지 행동적 실패를 발견했고 네 번째 실패를 확인했습니다. 이번 세션의 리뷰에서는 스트레스 테스트가 도달할 수 없었던 세 가지 발견 사항을 찾아냈습니다:
- 라우팅 신호 (routing signal) 길이: 스킬이 선택되는지 여부만 테스트할 수 있을 뿐, 선택되었을 때 어떻게 동작하는지는 테스트할 수 없음
- Guard 4 반환 값의 모호성: 출력이 무엇을 포함하는지가 아니라, 다운스트림 에이전트가 출력을 가지고 무엇을 하는지를 물어야만 테스트할 수 있음
- Q5 어설션 (assertions) 누락에 대한 Guard 4의 공백: 구조적 누락을 포함하면서 네 가지 가드를 통과하는 입력 유형을 사용해야만 테스트할 수 있음
스트레스 테스트는 "스킬이 작동하는가?"에 답합니다. 리뷰는 "스킬이 모든 컨텍스트에 준비되었는가?"에 답합니다. 스트레스 테스트가 도달할 수 없는 발견 사항들은 스킬이 올바르게 호출되고, 올바른 출력을 생성함에도 불구하고 다운스트림 시스템이 여전히 실패하는 경우들입니다. 이는 해당 소비 패턴에 대해 출력 형식이 명세되지 않았거나, 라우팅 신호가 너무 길어 안정적으로 작동하지 않거나, 혹은 유효한 입력에 대해 가드가 작동했기 때문입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기