평가와 디버깅: Skill이 실제로 도움이 되는지 검증하기
데모에서는 번쩍였는데, 실제 업무에 넣자마자 묘하게 엇나가는 Skill이 있습니다. 필요할 때는 안 켜지고, 필요 없을 때는 괜히 끼어들고, 결과는 그럴듯하지만 실무자는 고개를 갸웃합니다. 이 장의 핵심은 단순합니다. 좋은 Skill은 느낌이 아니라 평가로 증명해야 한다는 것입니다.
이 말은 과장이 아닙니다. 실제 벤치마크 연구에서는 잘 큐레이션된 Skill이 평균 성능을 끌어올렸지만, 모든 작업에서 무조건 도움이 되지는 않았습니다. 어떤 작업에서는 오히려 성능이 떨어지기도 했습니다. 즉, Skill은 "붙이면 무조건 좋아지는 마법 부품"이 아니라, 검증해야만 믿을 수 있는 가설에 가깝습니다.1
왜 Skill 평가는 꼭 필요할까
Skill을 만들고 나면 흔히 이런 착각에 빠집니다.
"몇 번 써봤는데 잘 되던데요?"
문제는 그 몇 번이, 대개 가장 쉬운 예시라는 점입니다. 실제 사용 환경은 늘 더 지저분합니다. 사용자 표현은 제각각이고, 컨텍스트는 길어지고, 도구 출력은 들쭉날쭉하며, 이전 대화의 찌꺼기도 남아 있습니다. Skill은 이런 환경에서 다음 네 가지 방식으로 실패할 수 있습니다.
아예 발동하지 않는다.
엉뚱한 상황에서 발동한다.
발동은 했지만 절차를 잘못 따른다.
결과는 냈지만 품질이 낮거나 비용이 너무 많이 든다.
그래서 Skill 평가는 단순히 "최종 답이 괜찮았는가"만 보는 일이 아닙니다. 더 정확히는 아래 세 질문에 답하는 과정입니다.
언제 켜졌는가: 발동 타이밍이 맞았는가?
무엇을 했는가: 적절한 단계와 도구를 골랐는가?
결과가 정말 좋았는가: 사용자의 목적을 제대로 달성했는가?
이 세 가지를 함께 봐야 Skill을 고칠 수 있습니다. 마지막 결과만 보면 "왜 망했는지"가 안 보이고, 중간 과정만 보면 "그래서 사용자에게 도움이 됐는지"가 안 보입니다.
무엇을 평가해야 하는가
Skill 평가는 보통 네 층으로 나눠 생각하면 편합니다.
| 평가 층 | 핵심 질문 | 대표 지표 |
|---|---|---|
| 발동 | 이 상황에서 Skill이 켜져야 했는가? | Precision, Recall, F1, 과발동률 |
| 과정 | Skill이 올바른 절차를 따랐는가? | 도구 선택 정확도, 인수 정확도, 단계 누락률 |
| 결과 | 최종 산출물이 쓸 만한가? | 작업 성공률, 루브릭 점수, 사실성 |
| 운영 | 실무에서 감당 가능한가? | 지연 시간, 토큰 수, 비용, 안정성 |
초보자는 특히 발동과 결과만 봐도 큰 도움이 됩니다. 하지만 실무로 갈수록 과정과 운영을 빼놓을 수 없습니다. 예를 들어 결과는 맞더라도 도구를 다섯 번 돌아가며 호출해 겨우 답했다면, 그 Skill은 "맞긴 맞는" Skill이지 "좋은" Skill은 아닙니다.
평가 단위를 먼저 정하자: 한 걸음, 한 번, 여러 번
에이전트 시스템에서는 무엇을 관찰하느냐가 중요합니다. 에이전트는 보통 한 번의 모델 호출로 끝나지 않고, 여러 번 생각하고 도구를 쓰고 다시 판단합니다. 그래서 관찰 단위도 나뉩니다. 대표적으로는 단일 실행 단계(run), 한 번의 전체 작업(trace), 여러 턴이 이어진 대화(thread) 수준으로 볼 수 있습니다.2
Skill 평가에 이 개념을 옮기면 다음처럼 이해할 수 있습니다.
단일 단계 평가
가장 작은 단위입니다. 특정 순간에 Skill이 켜졌는지, 어떤 도구를 골랐는지, 인수를 제대로 넣었는지를 봅니다. 마치 "생각의 단위 테스트" 같습니다.
예를 들어 일정 관리 Skill이라면, 사용자가 "내일 오전에 회의 잡아줘"라고 했을 때 곧바로 일정 생성 도구를 부르는지, 아니면 먼저 빈 시간을 조회하는지 볼 수 있습니다.
전체 작업 평가
사용자 요청 하나가 끝날 때까지의 전체 흐름을 봅니다. Skill이 발동했고, 필요한 도구도 썼고, 최종 답도 괜찮았는지 확인합니다. 초보자가 가장 먼저 도입하기 좋은 방식입니다.
다중 턴 평가
여러 번의 대화가 이어질 때 성능이 유지되는지 봅니다. 이전 턴의 기억이 누적되며 오염되지는 않는지, 앞에서 만든 잘못된 가정이 뒤에서 더 큰 실수로 번지지는 않는지 확인합니다.2
짧게 말하면 이렇습니다. 단일 단계는 결정의 품질, 전체 작업은 해결의 품질, 다중 턴은 지속성의 품질을 봅니다.
테스트셋은 작게 시작해도 된다
많은 팀이 평가를 미루는 이유는 테스트셋을 거창하게 생각하기 때문입니다. 하지만 처음부터 수천 개가 필요하지는 않습니다. 오히려 초반에는 작고 또렷한 테스트셋이 더 좋습니다.
초기 테스트셋은 20~50개만 있어도 충분합니다. 대신 구성이 좋아야 합니다. 쉬운 예시만 모으면 안 됩니다. 아래 네 종류를 섞어야 합니다.
평범하게 잘 풀어야 하는 대표 사례
자주 헷갈리는 경계 사례
일부 정보가 빠진 불완전 사례
과거에 실제로 실패했던 사례
에이전트 평가 실무에서는 초기에는 추적 로그를 직접 보며 문제를 이해하고, 실제 사용이 시작되면 운영 로그와 피드백을 모아 데이터셋을 키우고, 규모가 커지면 오프라인 평가 파이프라인으로 회귀를 막는 흐름이 자주 권장됩니다.3 OpenAI의 eval 가이드도 비슷한 방향을 제시합니다. Skill을 테스트 가능하고, 점수화 가능하고, 반복 개선 가능한 대상으로 바꾸라는 것입니다.4
좋은 테스트 케이스에는 보통 다음 정보가 들어갑니다.
| 필드 | 의미 |
|---|---|
| input | 사용자 요청 또는 상황 |
| should_trigger | 이 Skill이 켜져야 하는지 여부 |
| expected_behavior | 꼭 해야 할 행동 요약 |
| must_have | 결과에 반드시 포함되어야 할 요소 |
| must_not | 하면 안 되는 행동이나 금지 내용 |
| expected_tools | 써야 하거나 쓰면 안 되는 도구 |
여기서 중요한 점은 정답 문장을 하나만 두지 않는 것입니다. 에이전트 출력은 표현이 다양할 수 있으므로, 특히 열린 문제에서는 "반드시 들어가야 할 사실"이나 "지켜야 할 루브릭" 형태가 더 튼튼합니다.3
꼭 봐야 할 핵심 지표
Skill 평가 지표는 많지만, 처음에는 몇 개만 제대로 잡아도 충분합니다.
발동 정확도
Skill이 켜질 때의 품질을 봅니다.
Precision(정밀도): 켜진 것들 중 정말 켜져야 했던 비율
Recall(재현율): 켜져야 했던 상황 중 실제로 켜진 비율
F1: 정밀도와 재현율의 균형 점수
쉽게 말해 정밀도는 "괜히 튀어나오지 않느냐", 재현율은 "정작 필요할 때 빠지지 않느냐"입니다.
작업 성공률
최종적으로 사용자의 목표를 달성했는지 봅니다. 가장 직관적인 지표지만, 이것만 보면 왜 실패했는지 모릅니다. 그래서 보조 지표와 함께 봐야 합니다.
루브릭 점수
정답이 하나로 고정되지 않은 작업에서는 루브릭이 중요합니다. 예를 들어 아래처럼 1~5점 척도로 채점할 수 있습니다.
정확성: 사실이 맞는가
완결성: 필요한 내용을 빠뜨리지 않았는가
관련성: 질문에 맞는 답인가
간결성: 군더더기 없이 읽히는가
실행 가능성: 다음 행동으로 이어질 수 있는가
도구 사용 정확도
Skill이 특정 도구를 써야 하는 경우, 올바른 도구를 골랐는지와 인수를 제대로 넣었는지를 봅니다. 여기서 틀리면 결과 품질이 흔들립니다.
비용과 지연 시간
실무에서 종종 무시되지만 아주 중요합니다. 두 버전의 Skill이 같은 품질이라면, 더 빠르고 더 싼 쪽이 이깁니다. 특히 길고 복잡한 Skill은 토큰을 태워가며 "열심히 틀리는" 경우가 있습니다.
반복 안정성
같은 입력을 여러 번 넣었을 때 결과가 심하게 흔들리면 운영이 어렵습니다. 평균 점수만 좋고 분산이 크다면, 사용자 입장에서는 복불복 Skill처럼 느껴집니다.
실패 패턴은 보통 몇 가지로 수렴한다
Skill 디버깅이 막막한 이유는 실패가 제각각처럼 보이기 때문입니다. 그런데 로그를 조금만 모아보면, 실패는 의외로 몇 가지 유형으로 반복됩니다.
| 실패 패턴 | 겉으로 보이는 증상 | 흔한 원인 |
|---|---|---|
| 미발동 | 필요한데 Skill이 안 켜짐 | 설명이 너무 좁음, 예시 부족 |
| 과발동 | 상관없는 작업에도 끼어듦 | 트리거 문구가 너무 넓음 |
| 절차 이탈 | 순서를 빼먹거나 건너뜀 | 지시가 길고 충돌함 |
| 도구 오용 | 잘못된 도구, 잘못된 인수 | 도구 설명이 모호함 |
| 컨텍스트 오염 | 이전 대화에 끌려감 | 불필요한 히스토리 유입 |
| 산출물 저품질 | 말은 그럴듯한데 실무에 못 씀 | 품질 기준이 없음 |
| 고비용 저효율 | 결과는 맞지만 너무 느리고 비쌈 | 단계 과다, 탐색 범위 과잉 |
이 표를 보면 Skill 디버깅이 조금 쉬워집니다. 실패를 "이상하다"로 뭉개지 말고, 어느 패턴에 속하는지 이름을 붙이는 것이 첫 단계입니다. 이름이 붙으면 고칠 위치가 보이기 시작합니다.
그리고 이때 가장 중요한 증거가 트레이스입니다. 전통적인 소프트웨어에서는 스택 트레이스가 단서였다면, 에이전트에서는 실제로 어떤 프롬프트와 도구와 컨텍스트를 거쳐 그런 판단이 나왔는지 보여주는 트레이스가 진짜 단서입니다.2
LLM-as-a-Judge는 언제 쓰는가
이제 많은 팀이 궁금해하는 주제로 가보겠습니다. LLM-as-a-Judge는 말 그대로 다른 LLM의 출력이나 에이전트의 결과를 LLM이 평가하는 방식입니다. 열린 문제에서 특히 유용합니다. 요약, 초안 작성, 분석, 상담 응답처럼 "표현은 다양하지만 품질은 따질 수 있는" 작업에서 강합니다.5
예를 들어 Skill이 만든 결과를 보고 판정 모델이 이렇게 평가할 수 있습니다.
질문에 제대로 답했는가?
반드시 포함해야 할 사실이 들어갔는가?
문체와 형식이 요구사항을 지켰는가?
근거 없는 추측이 섞이지 않았는가?
LLM-as-a-Judge의 장점은 분명합니다. 사람이 일일이 읽지 않아도 대량 평가가 가능하고, 단순 점수뿐 아니라 이유도 함께 남길 수 있습니다.5
하지만 만능 심판은 아닙니다. 그래서 어디에 쓰고, 어디에는 쓰지 않을지 구분해야 합니다.
잘 맞는 경우
정답 표현이 여러 가지일 수 있는 열린 작업
대량 회귀 테스트가 필요한 경우
사람이 매번 읽기엔 비용이 큰 경우
품질 이유를 텍스트로 남기고 싶은 경우
잘 안 맞는 경우
JSON 형식 유효성처럼 코드로 바로 검사 가능한 경우
특정 키 존재 여부처럼 결정론적 검사로 끝나는 경우
매우 높은 법적 책임이 걸려 최종 판정을 자동화하면 안 되는 경우
즉, 형식은 코드로 검사하고, 의미는 LLM으로 검사하는 혼합 방식이 가장 실용적입니다.5
LLM-as-a-Judge의 세 가지 대표 패턴
실무에서 자주 쓰는 패턴은 크게 세 가지입니다.6
직접 점수화
하나의 결과를 루브릭에 따라 1~5점, 1~10점 같은 방식으로 채점합니다. 가장 단순하고 널리 쓰입니다.
예를 들어 "정확성 40%, 완결성 30%, 관련성 20%, 간결성 10%"처럼 가중치를 줄 수 있습니다. 버전 간 장기 추세를 보기 좋습니다.
쌍대 비교
A 버전과 B 버전 결과를 나란히 놓고 어느 쪽이 더 나은지 고르게 합니다. 프롬프트 개정 전후, Skill v1과 v2 비교에 특히 좋습니다. 숫자 점수보다 체감 차이를 빠르게 보기 좋습니다.
루브릭 생성
도메인에 맞는 평가 기준 자체를 먼저 만들고, 그 루브릭으로 다시 점수화합니다. 일반적인 "좋은 답변인가?"보다 "보험 민원 답변으로서 적절한가?"처럼 도메인 맞춤형 평가가 필요할 때 유용합니다.
초보자라면 일단 직접 점수화 + 간단한 코드 검사 조합으로 시작하는 것이 가장 무난합니다.
LLM-as-a-Judge를 맹신하면 생기는 일
LLM 심판도 결국 모델입니다. 따라서 흔들립니다. 어떤 연구와 실무 보고에서는 다음 문제들이 반복적으로 지적됩니다.78
같은 입력인데도 점수가 미세하게 달라진다.
답변 위치에 따라 앞쪽 후보를 더 선호하는 position bias가 생긴다.
긴 답을 괜히 더 좋아하는 verbosity bias가 생긴다.
자기와 비슷한 계열 모델의 답을 더 좋게 보는 self-bias가 생길 수 있다.
사람이 중요하게 보는 포인트와 심판 모델의 포인트가 어긋날 수 있다.
특히 주의할 점은 temperature를 0으로 둬도 완전한 결정론이 보장되지 않는다는 것입니다. 실제로 같은 입력을 반복 평가했을 때 점수가 오락가락하는 사례가 보고되었습니다.7
그래서 LLM-as-a-Judge를 쓸 때는 몇 가지 안전장치를 같이 써야 합니다.
루브릭을 구체적으로 쓴다.
출력 형식을 구조화한다.
가능하면 몇 개의 예시를 넣는다.
쌍대 비교는 순서를 바꿔 두 번 돌린다.
중요한 평가는 여러 번 돌려 평균이나 다수결을 본다.
가능한 경우 사람 평가 샘플로 정렬한다.
형식 검사는 먼저 코드로 거른다.
판정 결과뿐 아니라 이유도 함께 저장한다.
한마디로 요약하면 이렇습니다. LLM 심판은 판사이기 전에 조수입니다. 믿을 만하지만, 검증 가능한 절차 속에 넣어야 더 믿을 수 있습니다.
디버깅은 크게 고치기보다 작게 증명하기
Skill이 기대만큼 동작하지 않을 때, 가장 나쁜 대응은 한 번에 전부 뜯어고치는 것입니다. 설명도 바꾸고, 예시도 바꾸고, 폴더 구조도 바꾸고, 도구 설명도 고치면 무엇이 효과 있었는지 알 수 없습니다.
좋은 디버깅 루프는 보통 이렇게 생깁니다.
실패 슬라이스를 고른다.
전체 평균 점수 말고, 어떤 유형에서 무너지는지 좁힙니다. 예를 들어 "짧은 명령문에서는 잘 되는데, 긴 업무 요청에서 미발동이 많다"처럼요.트레이스를 본다.
실제로 어떤 문맥에서 Skill이 선택되거나 무시됐는지 확인합니다.가설을 하나 세운다.
"트리거 설명이 너무 좁아서 '정리해줘'는 잡는데 '초안 만들어줘'는 못 잡는다"처럼 원인을 한 문장으로 씁니다.최소 변경만 한다.
설명 한 줄, 예시 두 개, 도구 설명 한 항목처럼 작게 바꿉니다.같은 테스트셋으로 다시 돌린다.
개선됐는지, 다른 곳이 망가지진 않았는지 봅니다.회귀를 확인한다.
새로 좋아진 점수만 보지 말고, 원래 잘 되던 사례가 망가지지 않았는지 확인합니다.4
이 방식이 중요한 이유는 Skill 개선이 대개 정답 찾기가 아니라 원인 분리 작업이기 때문입니다.
예시: 회의록 정리 Skill을 어떻게 검증할까
초보자에게 가장 이해하기 쉬운 예시로, 회의 대화를 받아 요약과 액션 아이템을 만드는 Skill을 생각해봅시다.
이 Skill의 목표는 대략 이렇습니다.
회의 내용을 짧게 정리한다.
결정 사항을 뽑는다.
해야 할 일을 사람별로 정리한다.
모르는 정보는 지어내지 않는다.
초기 테스트셋 30개를 만들 수 있습니다.
10개는 또렷한 회의록
10개는 잡음이 섞인 회의록
10개는 책임자나 일정이 빠진 애매한 회의록
각 케이스에는 다음을 붙입니다.
| 항목 | 예시 |
|---|---|
| should_trigger | 회의/대화 요약 요청이면 true |
| must_have | 핵심 결정, 액션 아이템 |
| must_not | 없는 담당자 이름 지어내기 |
| rubric | 정확성, 구조화, 실행 가능성 |
이제 첫 평가를 돌렸더니 이런 결과가 나왔다고 해봅시다.
| 지표 | v1 결과 |
|---|---|
| 발동 Precision | 0.93 |
| 발동 Recall | 0.62 |
| 작업 성공률 | 63% |
| 평균 루브릭 점수 | 3.7 / 5 |
| 평균 지연 시간 | 8.1초 |
겉으로 보면 그럭저럭 괜찮아 보이지만, 자세히 보면 문제가 선명합니다. 정밀도는 높은데 재현율이 낮습니다. 즉, 켜질 때는 대체로 맞지만, 정작 켜져야 할 상황을 많이 놓치고 있다는 뜻입니다.
트레이스를 보니 사용자가 "회의록 정리해줘"라고 말하면 잘 켜지지만, "이 대화에서 결정된 것과 해야 할 일만 뽑아줘"라고 하면 종종 안 켜졌다고 합시다. 그러면 가설은 분명해집니다.
트리거 설명이 '회의록 요약' 표현에 너무 묶여 있어서, 같은 의도의 변형 표현을 잘 못 잡는다.
이제 Skill 설명에 발동 예시를 넓혀 넣고, "결정 사항 정리", "액션 아이템 추출", "대화에서 해야 할 일만 뽑기" 같은 표현을 추가합니다. 그리고 다시 평가합니다.
| 지표 | v1 | v2 |
|---|---|---|
| 발동 Precision | 0.93 | 0.89 |
| 발동 Recall | 0.62 | 0.84 |
| 작업 성공률 | 63% | 78% |
| 평균 루브릭 점수 | 3.7 | 4.2 |
여기서 재미있는 점이 하나 있습니다. 정밀도는 조금 내려갔지만, 재현율과 작업 성공률은 크게 올랐습니다. 이럴 때는 "정밀도 떨어졌으니 실패"가 아니라, 실제 목표에 더 맞는 균형이 무엇인지 판단해야 합니다. 회의록 Skill이라면 대개 약간 넓게 잡더라도 필요한 상황을 놓치지 않는 편이 더 유리할 수 있습니다.
즉, 좋은 평가는 단순히 숫자 하나를 높이는 일이 아니라, 무엇을 더 중요하게 볼지 결정하는 일이기도 합니다.
온라인 평가: 운영이 최고의 선생님이다
오프라인 테스트셋은 출발점입니다. 하지만 에이전트는 실제 사용자 앞에서 예상 못 한 표현과 상황을 계속 만납니다. 그래서 운영 환경은 단순한 배포 장소가 아니라, 새로운 평가 케이스를 발견하는 장소가 됩니다.23
실무에서는 보통 이렇게 연결합니다.
오프라인 테스트셋으로 기본 성능 확인
배포 후 트레이스 수집
사용자 피드백 수집
실패 사례를 새로운 테스트셋에 편입
다음 버전에서 회귀 테스트 수행
이 흐름이 만들어지면 Skill은 점점 팀의 자산이 됩니다. 반대로 이 흐름이 없으면, Skill은 매번 운에 기대는 일회용 프롬프트로 남습니다.
간단한 운영 장치도 큰 도움이 됩니다.
thumbs up/down 같은 사용자 피드백
실패 사례 자동 수집 태그
버전별 점수 비교 대시보드
샘플링된 인간 검토
중요한 것은 "배포 후에도 계속 본다"는 태도입니다. Skill은 한 번 만들고 끝나는 문서가 아니라, 계속 다듬는 작업 절차이기 때문입니다.
평가 루브릭은 Skill 자체의 일부다
좋은 Skill은 대개 실행 지침만 있는 것이 아닙니다. 무엇이 좋은 결과인지에 대한 기준도 함께 갖고 있습니다. 다시 말해 평가 루브릭은 Skill 바깥의 부록이 아니라, Skill 품질을 유지하는 핵심 부품입니다.
예를 들어 어떤 Skill에 아래 문장이 들어 있다면, 그건 단순한 설명이 아니라 평가 기준의 씨앗입니다.
불확실하면 추정하지 말 것
도구 결과와 모순되는 결론을 쓰지 말 것
사용자 요청 범위를 넘어서 과잉 작성하지 말 것
이런 문장들은 나중에 그대로 평가 항목이 됩니다. 그래서 Skill을 설계할 때부터 "무엇을 잘했다고 볼 것인가"를 함께 적어두면, 나중에 평가 체계를 만들기가 훨씬 쉬워집니다.
이 장의 핵심 정리
Skill 평가와 디버깅은 복잡해 보이지만, 본질은 단순합니다.
Skill은 발동, 과정, 결과, 운영 네 층에서 평가한다.
테스트셋은 작게 시작하되, 실패 사례를 꾸준히 편입한다.
평균 점수만 보지 말고 실패 패턴을 이름 붙여 본다.
열린 문제는 LLM-as-a-Judge를 쓰되, 코드 검사와 인간 검토를 섞는다.
수정은 크게 한 번이 아니라, 작게 바꾸고 다시 측정하는 방식으로 한다.
결국 좋은 Skill은 "왠지 똑똑해 보이는 Skill"이 아닙니다. 필요할 때 잘 켜지고, 올바른 절차를 따르고, 사용자에게 실제로 도움이 된다는 사실이 평가로 입증된 Skill입니다.
그리고 바로 그 순간, Skill은 아이디어에서 시스템으로 승격됩니다.
참고
1SkillsBench: Benchmarking How Well Agent Skills Work Across Diverse Tasks
2Agent observability powers agent evaluation
3Agent Evaluation: How to Evaluate LLM Agents
4Testing Agent Skills Systematically with Evals
6Advanced Evaluation: LLM-as-Judge Implementation
7Evaluating AI Agents: Can LLM‑as‑a‑Judge Evaluators Be Trusted?
8LLM-as-a-Judge: How to Build Reliable, Scalable Evaluation for LLM Apps and Agents
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.