SW/인공지능

AI Evals란 무엇인가: LLM·RAG·코딩 에이전트를 위한 실전 평가 설계법

얇은생각 2026. 6. 1. 07:30
반응형

AI 기능은 데모까지는 금방 갑니다. 문제는 배포 뒤입니다. 답변은 그럴듯한데 틀리고, 막아야 할 요청은 못 막고, 멀쩡한 질문까지 거절하고, 비용과 지연 시간은 조용히 새어 나갑니다. AI evals는 이 혼란을 감으로 다루지 않게 해 주는 장치입니다. 이 글은 task, eval data, grader라는 최소 구조로 무엇을 먼저 재야 하는지, 어디서 팀이 가장 자주 틀리는지까지 한 번에 정리합니다.

많은 팀이 첫 단추를 잘못 끼웁니다. "모델 성능을 재자"처럼 너무 크게 잡거나, 벤치마크 한 번 돌리고 안심해 버리죠. 하지만 생성형 AI에서 좋은 평가는 모델 전체를 한 번에 재는 일이 아닙니다. 제품에서 실제로 깨지는 행동 하나를 꺼내, 같은 조건과 같은 기준으로 계속 비교할 수 있게 만드는 일에 가깝습니다.

 

세 단계 평가 스테이션을 통과하며 불안정한 AI 출력이 정리된 점수 대시보드로 바뀌는 장면

 

AI evals는 결국 "무엇이 망가졌는지 빨리 찾는 구조"입니다

전통적인 머신러닝은 상대적으로 단순했습니다. 입력이 들어오면 분류 결과나 숫자 예측이 나오고, 정확도나 정밀도 같은 지표로 비교할 수 있었으니까요.

생성형 AI는 다릅니다. LLM은 문단을 쓰고, 코드를 만들고, 툴을 호출하고, 여러 단계를 거쳐 행동합니다. 여기서는 정답이 하나가 아닐 때가 많습니다. 문장이 자연스럽다고 맞는 것도 아니고, 형식만 맞다고 안전한 것도 아닙니다.

그래서 생성형 AI의 평가는 보통 이런 질문으로 쪼개집니다.

  • 이 모델은 위험한 요청을 적절히 거절하는가
  • 이 RAG 답변은 검색된 문서에 실제로 근거를 두는가
  • 이 코딩 에이전트는 실제로 버그를 고치는가
  • 이 시스템은 허용 가능한 비용과 지연 시간 안에서 동작하는가

 

핵심은 하나입니다. "품질"이라는 커다란 단어를 붙잡고 씨름하지 말고, 제품에서 실제로 깨지는 행동 단위로 나눠 보라는 것입니다. 그래야 점수가 흔들렸을 때 어디를 고쳐야 하는지 보입니다.

 

 

AI evals의 최소 구조는 Task, Eval Data, Grader 세 가지입니다

생성형 AI 평가를 가장 덜 헷갈리게 보는 방법은 아래 세 조각으로 분리하는 것입니다.

 

1. Task: 무엇을 측정할지 한 가지 행동으로 고정하기

Task는 평가의 이름표가 아니라 경계선입니다. 무엇을 측정하고, 무엇은 이번 eval에서 보지 않을지를 정합니다.

 

좋은 task는 작고 선명합니다.

  • "유해한 프롬프트를 거절하는가"
  • "번역 결과가 의미를 유지하는가"
  • "검색된 문서에 없는 주장을 만들어내지 않는가"
  • "버그 리포트를 보고 실제로 패치를 만들어 테스트를 통과시키는가"

 

반대로 나쁜 task는 너무 큽니다.

  • "우리 챗봇 품질이 좋은가"
  • "우리 에이전트가 똑똑한가"
  • "모델이 전반적으로 개선됐는가"

 

이런 task는 결국 원인 분석을 막습니다. 점수가 떨어져도 왜 떨어졌는지 모릅니다. 안전성 때문인지, 검색 품질 때문인지, 응답 형식 때문인지, 비용 때문인지 분리가 안 되기 때문입니다.

실무에서는 "한 eval은 한 행동" 원칙이 생각보다 중요합니다. 모델을 고치고 프롬프트를 바꾸고 시스템 구성을 손볼수록, 무엇이 개선됐고 무엇이 깨졌는지를 분리해서 봐야 하기 때문입니다.

 

 

2. Eval Data: 쉬운 예시보다 실패할 예시를 모으기

task를 정했다면 그다음은 eval data입니다. 여기서 가장 흔한 실수는 보기 좋은 정상 케이스만 모으는 것입니다. 그러면 릴리즈 전에는 다 통과하는데 운영에서만 계속 터집니다.

좋은 eval data는 두 가지를 만족해야 합니다.

  1. 다양해야 합니다.
  2. 실패 가능성이 높은 지점을 찔러야 합니다.

 

예를 들어 안전성 eval이라면 명백한 악성 요청만으로는 부족합니다. 경계선에 걸친 질문이 필요합니다. 겉보기에는 무해하지만 실제로는 위험한 요청, 반대로 안전하게 답해도 되는 정상 질문인데 모델이 과잉 방어로 거절할 수 있는 사례가 중요합니다.

여기서 팀이 자주 놓치는 마찰이 있습니다. 보통은 "틀리면 티 나는 사례"를 먼저 모으지만, 실제 품질을 무너뜨리는 건 "애매해서 정책 판단이 흔들리는 사례"인 경우가 많습니다. eval dataset이 너무 깨끗하면 시스템도 현실보다 좋아 보입니다.

그래서 eval data는 보통 이런 재료로 만듭니다.

  • 직접 수집한 실패 사례
  • 운영 로그에서 추출한 까다로운 요청
  • 공개 벤치마크
  • 팀이 의도적으로 만든 adversarial prompt

 

중요한 건 데이터의 양보다 방향입니다. "이 모델이 어디서 삐끗할까"를 겨냥하지 않으면, 샘플이 아무리 많아도 운영에서 도움이 되는 eval이 되기 어렵습니다.

 

 

3. Grader: 출력을 점수로 바꾸는 채점기 만들기

grader는 eval의 중심입니다. 입력과 출력이 있어도 그것을 어떻게 점수화할지 정하지 않으면, 개선과 퇴보를 비교할 수 없습니다.

여기서 기억할 구분은 두 가지입니다.

  • reference-based: 정답이나 기준 답안과 비교하는 방식
  • reference-free: 정답 없이 출력 자체의 속성을 평가하는 방식

 

예를 들어 번역 정확도처럼 비교 기준이 있으면 reference-based가 잘 맞습니다. 반면 안전성, 어조, faithfulness 같은 문제는 정답 문자열 하나로 처리하기 어려워 reference-free 접근이 자주 쓰입니다.

실무에서 많이 쓰는 grader는 아래 세 종류로 정리할 수 있습니다.

 

Grader 종류 잘 맞는 상황 장점 자주 깨지는 지점
코드 기반 grader JSON 형식, 예상 문자열, 테스트 통과 여부처럼 규칙이 명확할 때 빠르고 싸고 반복 가능함 주관적 품질이나 미묘한 차이를 못 잡음
LLM judge 안전성, 근거성, 명료성처럼 코드로 재기 어려울 때 유연하고 적용 범위가 넓음 rubric이 흐리거나 judge가 바뀌면 점수가 흔들릴 수 있음
사람 평가 자동 grader를 교정할 핵심 샘플을 확인할 때 가장 강한 교정 신호를 줌 느리고 비싸서 전수 평가가 어려움

 

자동 grader를 고를 때는 "가장 똑똑한 방법"보다 "가장 덜 흔들리는 방법"을 먼저 봐야 합니다.

예를 들어 JSON 유효성 검사는 LLM judge로 할 이유가 없습니다. 코드로 끝내면 더 빠르고 싸고 재현 가능합니다. 반대로 답변이 문서에 실제로 근거하는지 보는 문제는 문자열 비교로 처리하려 들면 금방 막힙니다. 이런 곳이 LLM judge가 들어갈 자리입니다. LLM judge를 더 파고 싶다면 예전에 정리한 Judging LLMs: AI 언어 모델 평가의 새로운 길을 열다도 이어서 볼 만합니다.

그리고 사람 평가는 모든 것을 대신하는 만능 해법이 아니라, 자동 grader가 제대로 동작하는지 확인하는 기준점으로 두는 편이 현실적입니다. 실제로 OpenAI의 Evaluation best practices도 model grading에는 오차가 생길 수 있으므로 human validation을 함께 두라고 권합니다.

 

 

 

단일 LLM 평가는 "유해한 요청을 잘 막는가"처럼 한 축부터 잘라야 합니다

새 LLM을 학습했거나 프롬프트 세트를 바꿨다면, 가장 먼저 떠오르는 eval 중 하나는 안전성입니다. 예를 들어 "유해한 요청을 적절히 거절하는가"를 task로 잡을 수 있습니다.

이 경우 구조는 비교적 단순합니다.

  • Task: harmful prompt를 거절하는가
  • Eval data: 악성 요청, 경계선 요청, 정상 요청을 섞은 프롬프트 세트
  • Grader: 응답이 거절인지, 실제로 해로운 정보를 제공했는지 판별하는 LLM judge

 

여기서 자주 하는 실수는 거절률 하나만 보는 것입니다. 유해한 질문에 대한 refusal rate만 높아도 좋아 보이지만, harmless prompt까지 마구 거절하면 제품은 실제로 더 나빠집니다.

그래서 최소한 아래 둘은 같이 봐야 합니다.

  • harmful prompt refusal rate
  • harmless prompt answer rate

 

이 둘을 같이 보지 않으면 안전성과 과잉 거절을 구분할 수 없습니다. 실제 서비스에서 사용자가 느끼는 불편은 종종 "막아야 할 걸 못 막음"보다 "괜찮은 것도 못 하게 막음"에서 더 크게 나옵니다.

또 하나, 여기서는 문자열 매칭이 잘 안 먹힙니다. 모델마다 거절 문구는 다르게 나오기 때문입니다. 이런 상황에서 rubric을 준 LLM judge가 유용해집니다. 질문은 단순합니다. "이 응답이 해로운 정보를 실제로 제공했는가, 아니면 적절히 거절했는가?"

이 eval을 한번 만들어 두면 모델 버전별 비교, 카테고리별 약점 분석, 프롬프트 변경 전후 비교가 가능해집니다. 그때부터 eval은 보고서가 아니라 운영 도구가 됩니다.

 

 

검색 단계의 문제와 답변 생성 단계의 문제를 분리해 보여 주는 RAG 구조 다이어그램

 

RAG 평가는 answer quality와 retrieval quality를 섞는 순간 꼬이기 시작합니다

RAG는 같은 답변 품질 문제처럼 보여도 실제 원인이 두 군데에서 나옵니다.

  1. 검색이 틀렸다.
  2. 검색은 괜찮았는데, 모델이 근거 없는 말을 덧붙였다.

 

이 둘을 섞으면 디버깅이 거의 막힙니다. 검색을 고쳐야 할지, 생성 단을 고쳐야 할지 판단이 흐려지기 때문입니다.

그래서 RAG eval에서 흔히 잡는 task가 faithfulness입니다. 질문은 이것입니다. "모델의 답변이 실제로 검색된 문서에 근거하고 있는가?"

이 eval의 구조는 보통 이렇습니다.

  • Task: answer faithfulness
  • Eval data: 질문과, 그 질문에 대해 실제로 retrieve된 문서
  • Grader: 답변 속 주장을 쪼개고, 각 주장이 문서로 뒷받침되는지 보는 LLM judge

 

여기서 metric은 단순합니다. 전체 주장 중 몇 개가 문서로 지지되는지, 즉 support된 claim의 비율을 계산하면 됩니다.

중요한 건 이 eval이 어디까지 보는지입니다. faithfulness eval은 답변 단의 근거성만 봅니다. 검색기가 애초에 엉뚱한 문서를 가져왔는지는 별도 eval이 필요합니다.

이 구분을 놓치면 RAG 개선이 꼬입니다. retrieval이 문제인데 생성 프롬프트만 계속 고치거나, 반대로 모델이 멋대로 꾸며낸 답변인데 검색 chunking만 손대는 식이 됩니다. 둘 다 시간만 잡아먹고 개선 속도는 느립니다.

 

faithfulness eval은 답변의 근거성을 재는 것이지, retrieval 자체의 품질을 재는 eval은 아닙니다.

 

RAG 구조 자체가 아직 헷갈린다면, 기본 흐름은 전에 정리한 RAG: 대규모 언어 모델의 지식 간극 극복하기 글을 먼저 보고 오는 편이 이해가 빠를 수 있습니다.

 

 

코딩 에이전트 평가는 말보다 패치가 통과하는지로 보는 편이 훨씬 낫습니다

코딩 에이전트는 버그 리포트를 읽고, 코드를 탐색하고, 파일을 수정하고, 명령을 실행하는 여러 단계가 얽혀 있습니다. 그래도 eval 설계는 의외로 선명합니다.

가장 실용적인 task 중 하나는 이것입니다.

"주어진 버그 리포트를 보고, 실제로 문제를 고치는 패치를 만들 수 있는가?"

 

이 경우 eval data는 버그 설명과 현재 실패 중인 테스트 케이스로 구성할 수 있습니다. grader는 놀랍도록 단순합니다. 패치를 적용한 뒤 테스트를 돌려서, 실패하던 테스트가 통과하면 pass입니다.

이런 문제에서 코드 기반 grader는 매우 강합니다.

  • 기준이 명확합니다.
  • 결과가 재현 가능합니다.
  • judge 모델의 해석 차이에 덜 흔들립니다.

 

여기서 초보적인 함정도 분명합니다. 테스트가 약하면 eval도 약합니다. 원래 버그를 제대로 잡지 못하는 테스트라면, 에이전트가 엉성한 패치를 내도 통과해 버릴 수 있습니다. 반대로 flaky test가 많으면 좋은 패치도 불안정하게 실패합니다.

즉, 코딩 에이전트 eval의 본질은 "에이전트가 말을 그럴듯하게 했는가"가 아니라 "실패 조건을 실제로 해소했는가"입니다. resolve rate가 중요한 이유가 여기에 있습니다.

보조 지표도 볼 수는 있습니다.

  • 몇 단계 만에 해결했는가
  • 얼마나 많은 compute를 썼는가
  • 불필요한 파일 변경이 많았는가

 

하지만 이 지표들은 본 점수 뒤에 와야 합니다. 테스트도 못 통과하는데 step count만 예쁜 에이전트는 실무에서 큰 의미가 없습니다.

 

 

Grader를 고를 때 팀이 자주 틀리는 네 가지

 

1. 코드로 끝낼 수 있는데 굳이 LLM judge를 붙입니다

형식 검증, exact match, 테스트 통과 여부는 코드로 끝내는 게 맞습니다. LLM judge를 붙일수록 비용과 변동성만 늘고, 나중에 재현성까지 나빠집니다.

 

2. LLM judge 점수를 사실상 정답처럼 다룹니다

LLM judge는 강력하지만 절대 기준은 아닙니다. rubric이 흐리면 점수가 흔들리고, judge 모델이 바뀌면 분포도 달라질 수 있습니다. 중요한 소수 샘플은 사람 평가로 교정해야 하는 이유입니다.

 

3. RAG에서 검색 문제와 생성 문제를 한 점수로 뭉갭니다

faithfulness가 낮다고 해서 retrieval이 나쁜 건 아닐 수 있습니다. 반대로 retrieval recall이 낮아도 답변 문장만 그럴듯하면 겉보기 품질이 좋게 보일 수 있습니다. 이 둘은 분리해서 봐야 원인 분석이 됩니다.

 

4. 에이전트 eval을 너무 작은 장난감 문제로 만듭니다

실제 버그 리포트는 모호하고, 테스트 환경은 지저분하고, 수정 범위는 예상보다 넓습니다. toy task만 통과하는 에이전트는 데모에서는 멋져도 실제 코드베이스에 들어가면 금방 흔들립니다.

 

 

처음 시작할 때는 거대한 평가 체계보다 작은 반복 루프가 더 중요합니다

처음부터 완벽한 eval platform을 만들 필요는 없습니다. 오히려 아래 정도만 있어도 팀은 훨씬 덜 헤맵니다.

최소 시작 템플릿은 이렇습니다.

  1. 제품에서 진짜 중요한 행동 하나를 task로 자릅니다.
  2. 그 행동이 가장 잘 깨지는 사례를 20~50개 정도 모읍니다.
  3. 코드 grader로 끝낼 수 있으면 코드로 끝냅니다.
  4. LLM judge가 필요하면 rubric을 아주 구체적으로 씁니다.
  5. 가장 헷갈리는 샘플 몇 개는 사람 손으로 다시 확인합니다.
  6. 모델, 프롬프트, 시스템 버전이 바뀔 때마다 같은 eval을 반복 실행합니다.

 

이 여섯 단계만 돌아가도 팀의 의사결정이 달라집니다. "이 변경이 좋아 보인다"가 아니라 "같은 조건에서 이 행동 점수가 실제로 좋아졌다"로 말할 수 있게 되기 때문입니다.

 

 

마무리

AI evals는 거창한 연구 주제이기 전에, AI 제품을 덜 불안하게 만드는 운영 장치입니다. 핵심은 어렵지 않습니다. task를 한 가지 행동으로 자르고, 실패하기 쉬운 eval data를 모으고, 그 행동에 맞는 grader를 붙이면 됩니다.

LLM이든, RAG든, 코딩 에이전트든 틀은 비슷합니다. 달라지는 건 무엇을 채점해야 하는지입니다. 이 구분이 잡히면 모델을 바꿨을 때 무엇이 나아졌고 무엇이 망가졌는지 훨씬 빨리 보이기 시작합니다. 이번 주 안에 task 하나만 잘라 20개 샘플로 첫 eval을 돌려 보세요. 그 한 번이 이후의 모든 개선 속도를 바꿉니다.

 

 

FAQ

 

벤치마크 하나만 잘 돌리면 충분하지 않나요?

보통은 부족합니다. 생성형 AI는 안전성, 근거성, 형식 준수, 비용, 지연 시간처럼 깨지는 축이 다르기 때문에, 중요한 행동별로 eval을 나눠야 원인 분석이 됩니다.

 

LLM judge만 있으면 사람 평가는 없어도 되나요?

아닙니다. LLM judge는 빠르고 유연하지만 오차가 생길 수 있습니다. 그래서 중요한 소수 샘플은 사람 평가로 교정해 두는 편이 안전합니다.

반응형