도구 호출 정확도(Tool-Call Accuracy)가 당신을 속이고 있는 이유: 에이전트를 위한 4계층 평가 스택
요약
도구 호출(Tool-calling) 에이전트 평가 시 단순 도구 선택 정확도만 측정할 경우 발생하는 오류를 지적합니다. 에이전트의 성공 여부를 정확히 파악하기 위해 도구 선택, 인자 추출, 결과 활용, 오류 복구의 4계층 평가 스택을 제안합니다.
핵심 포인트
- 도구 선택 정확도만으로는 에이전트의 실제 작업 완료율을 보장할 수 없음
- 평가 지표를 도구 선택, 인자 추출, 결과 활용, 오류 복구로 세분화해야 함
- 세분화된 평가는 실패의 근본 원인을 구체적으로 파악하게 해줌
- 도구 호출이 필요 없는 상황(무관함 버킷)에 대한 평가도 필수적임
도구 호출 (Tool-calling) 에이전트를 평가하는 방식에 대한 제 생각을 완전히 바꿔놓은 추적 사례가 있습니다.
한 에이전트가 항공권을 예약하려고 시도합니다. 에이전트는 departure_date="next Friday"라는 인자와 함께 search_flights를 호출합니다. 엔드포인트(Endpoint)는 ISO 날짜 형식을 기대했기 때문에 400 에러를 반환합니다. 에이전트는 동일한 문자열로 네 번을 재시도한 뒤, 사용자에게 사과하고 포기합니다.
여기서 실제로 저를 괴롭혔던 부분은 이것입니다. 도구 선택 (Tool selection)은 정확했습니다. 모델은 28개의 레지스트리(Registry) 중에서 올바른 함수를 선택했습니다. 저의 도구 선택 정확도는 깔끔하게 1.0을 기록했습니다. 하지만 전체 작업 완료율 (Aggregate task-completion)은 0을 기록했습니다. 그리고 이 두 숫자 중 어느 것도 다음 세 가지 중 무엇이 잘못되었는지 알려주지 않았습니다:
- 인자 (Argument)가 틀렸거나,
- 모델이
400응답 본문 (Body)을 읽지 못했거나, - 재시도 정책 (Retry policy)이 동일한 입력값으로 루프를 돌았거나.
제 평가 (Eval)가 틀린 것이 아니었습니다. 잘못된 질문을 던지고 있었던 것입니다.
"도구 호출 정확도"가 실제로 채점하는 것
만약 당신이 측정하는 유일한 지표가 에이전트가 올바른 도구를 호출했는가뿐이라면, 당신은 실행 (Execution)이 아니라 의도 (Intent)를 테스트하고 있는 것입니다. 도구 선택은 필요조건일 뿐, 충분조건은 아닙니다. 도구 선택은 추적 (Trace)에 올바른 함수 이름이 나타나는 순간 통과되지만, 인자가 쓰레기 값인지, 모델이 반환된 내용을 읽었는지, 혹은 400 에러로부터 회복했는지에 대해서는 완전히 눈을 감고 있습니다.
그것이 바로 간극입니다. 이 지표는 에이전트가 올바른 방식으로 시작했는지를 확인합니다. 프로덕션 (Production) 환경에서는 에이전트가 올바른 방식으로 끝냈는지를 알아야 합니다.
관점의 전환: 하나의 문제가 아니라 네 개의 평가 문제
제가 내면화해야 했던 사실은 도구 호출 평가가 각각 고유한 근본 원인을 가진 네 가지 문제가 쌓여 있는 것이라는 점입니다:
- 도구 선택 (Tool selection): 올바른 도구를 선택했는가, 혹은 올바르게 도구를 사용하지 않았는가
- 인자 추출 (Argument extraction): 스키마 (Schema)에 유효하며 의미론적으로(Semantically) 정확한가
- 결과 활용 (Result utilization): 도구가 반환한 값을 실제로 사용했는가
- 오류 복구 (Error recovery): 재시도했는가, 폴백 (Fallback)했는가, 혹은 에스컬레이션 (Escalate)했는가
이것들을 각각 별도로 점수화하면 "에이전트가 실패했다"라는 모호한 결과가 "항공권 예약 경로에서 날짜 문자열에 대한 인자 추출기가 퇴보했다"라는 구체적인 결과로 압축됩니다. 3일이 걸릴 일을 이분법적 탐색 (Bisect) 한 번으로 끝낼 수 있게 됩니다.
제가 재구축한 것
계층 1: 도구 선택 (모두가 놓치는 버킷 포함)
도구 이름에 대한 F1 점수를 측정함으로써, 28개의 도구가 등록된 레지스트리에서 발생하는 하나의 희귀한 엔드포인트(endpoint)에 대한 성능 저하(regression)가 강력한 전체 평균값 뒤에 숨겨지는 것을 방지합니다:
from fi.evals import evaluate
result = evaluate("function_name_match",
...
거의 모든 게시물이 생략하는 부분은 바로 **무관함 버킷 (irrelevance bucket)**입니다. 이는 정답(gold answer)이 "도구 호출 없음"인 테스트 케이스(인사, 명확화 질문, 모델 내부의 사실적 질문 등)를 의미합니다. 이러한 케이스가 없다면, 프롬프트 수정으로 인해 모델이 모든 입력에 대해 search를 호출하려는 경향이 강해지는 성능 저하를 잡아낼 수 없습니다. BFCL(Berkeley Function Calling Leaderboard)이 정확히 이 이유로 해당 버킷을 추가했습니다. 여러분의 프라이빗 데이터셋에도 동일한 방식으로 이를 구축하십시오.
계층 2: 인자 추출 (Argument extraction)
스키마 검증(Schema validation)이 가장 먼저 실행되며 이는 결정론적(deterministic)입니다. 모델 출력에 Pydantic을 사용하는 것은 가장 저렴한 게이트웨이입니다:
from pydantic import BaseModel, Field, ValidationError
class SearchFlightsArgs(BaseModel):
...
하지만 스키마가 유효하다고 해서 반드시 정답인 것은 아닙니다. departure_date="2026-01-01"은 검증을 통과하지만, 사용자가 "다음 주 금요일"이라고 말했다면 여전히 틀린 것입니다. 이러한 의미론적 클래스(semantic class)는 인자가 사용자의 의도를 제대로 포착했는지 점수를 매기는 LLM 판사(LLM judge)가 필요합니다. customer_id="me"가 다른 사람의 계정을 반환하는 오류는 스키마 검증이 절대 찾아낼 수 없는 실패 사례입니다.
계층 3: 결과 활용 (Result utilization) (대부분의 게시물이 완전히 생략하는 계층)
도구가 값을 반환했습니다. 에이전트가 그 페이로드(payload)를 사용합니까? 세 가지 패턴이 계속해서 나타났습니다:
- 숫자를 뒤집어 의역함: 도구는
amount_cents: 4500을 반환하지만, 에이전트는 "귀하의 $54.00 환불이 처리 중입니다"라고 말합니다. - 이전 모델 지식으로 대체함:
get_account_balance가12_400을 반환했음에도, 모델은 기억하고 있던 "$200 임계값"을 바탕으로 답변합니다. - 1턴에서는 결과를 사용하다가 3턴째에 거기서 벗어남: 올바른 여정(itinerary)을 인용하다가, 나중에는 모순되는 수하물 규정을 지어냅니다.
평가 기준(rubric)은 근거성(Groundedness)입니다. 다만, 컨텍스트 슬롯(context slot)을 검색된 말뭉치(retrieved corpus) 대신 도구의 반환 페이로드로 지정하는 것뿐입니다.
from fi.evals import Evaluator
from fi.evals.templates import Groundedness, ContextAdherence, ChunkAttribution
from fi.testcases import TestCase
...
Layer 4: 오류 복구 (Error recovery)
도구가 4xx 에러를 반환하거나 타임아웃(timeout)이 발생했을 때, 에이전트의 다음 행보는 평가의 대상(eval surface)이 됩니다. 에이전트가 에러를 읽고 수정했나요, 아니면 동일한 잘못된 문자열을 다시 보냈나요? 기본 도구가 작동하지 않을 때 폴백(fallback)을 수행했나요? 합리적인 재시도 제한(retry cap)에서 멈췄나요 (보통 3회가 최소 기준이며, 6회 이상은 루프 가드(loop guard)가 누락되었음을 의미합니다)? 이는 호출당 평가가 아닌, 궤적(trajectory) 수준의 평가입니다.
from fi.evals.metrics.agents import TrajectoryScore, AgentTrajectoryInput
from fi.evals.metrics.agents.types import AgentStep, TaskDefinition
...
이 모든 것이 선택 사항이 아닌 이유: 수학적 근거
k 단계로 구성된 에이전트의 엔드 투 엔드(end-to-end) 성공률은 대략 각 단계별 성공률의 곱과 같습니다.
- 8단계 동안 단계별 성공률이 95%라면, 최종 성공률은 66% 근처에 머뭅니다.
- 8단계 동안 단계별 성공률이 99%라면, 최종 성공률은 92% 근처에 머뭅니다.
개별 단계는 모두 통과(green)하더라도 세션의 3분의 2가 구조적으로 잘못 종료되는 현상은 가설이 아닙니다. 이는 기본적으로 발생하는 수학적 결과이며, 평가(eval)는 통과하지만 프로덕션(production) 환경에서는 망가지는 에이전트를 출시하게 되는 가장 흔한 이유입니다.
해결책:
- 궤적(trajectory)을 하나의 단위로 점수화하십시오 (단계별 루브릭(rubric)은 관문일 뿐이며, 궤적 지표(trajectory metric)가 진실입니다).
- 5단계를 초과하는 모든 과정은 의심스럽게 간주하고 분해(decompose)하십시오.
pass^k일관성 슬라이스(consistency slice)를 확보하십시오: 30개의 어려운 케이스를 _k_번 실행하여, _k_번 모두 성공하는 비율을 측정합니다. 이 수치가 변한다면, 도구(tools)가 아니라 플래너(planner)가 퇴보한 것입니다.
여전히 공개 벤치마크를 사용하는 이유
BFCL이나 τ-bench를 버린 것은 아닙니다. 단지 그것들이 프로덕션의 관문인 척하는 것을 그만두었을 뿐입니다.
- BFCL은 기반 모델이 도구를 호출할 수 있는지 여부(AST, 실행 가능성, 무관성)를 알려줍니다.
- τ-bench는 멀티 턴(multi-turn) 신뢰성에 대해 알려줍니다. GPT-4o조차 리테일(retail) 환경의
pass^8지표에서는 25% 미만의 성능을 보입니다.
두 지표 모두 모델 선택을 위한 하한선(floor)일 뿐입니다. 두 지표 모두 여러분의 레지스트리(registry), 스키마(schema), 에러 코드(error code), 또는 비즈니스 정책(business policy)에 대해서는 아무것도 알지 못합니다. 도구(tool), 인자 엣지 케이스(argument-edge-case), 에러 코드별로 계층화(stratified)하고, 매주 실패한 프로덕션 트레이스(production traces)를 반영한 프라이빗 평가 세트(private eval set)만이 실제 배포를 결정하는 관문이 됩니다.
제가 다르게 할 방식
- 첫날부터 태스크 완료율(task-completion)을 합산하지 말고, 계층별로 점수를 매기십시오. 케이스당 5개의 루브릭(rubric)을 사용하는 것은 비용이 더 들지만, CI(지속적 통합)가 실패했을 때 실패한 계층의 이름이 곧 근본 원인(root cause)이 됩니다.
- 도구 출력물에 대한 근거성(groundedness-on-tool-output)을 검색된 코퍼스(retrieved corpus)에 대한 근거성보다 더 노이즈가 심한 것으로 취급하십시오. 페이로드(payload)는 JSON이며, 루브릭은 필드(field)를 바탕으로 추론합니다. 소규모의 사람이 라벨링한 캘리브레이션 세트(calibration set)를 고정하고, 매달 재조정(re-tune)하십시오.
- 모든 PR(Pull Request)이 아니라 릴리스 후보(release candidates)에 대해
pass^k슬라이스를 실행하십시오. 30개 케이스 × 8번의 롤아웃(rollouts)은 240번의 에이전트 실행을 의미합니다. 적절한 주기라면 가치가 있지만, 커밋마다 관문으로 두기에는 고통스럽습니다.
만약 여러분이 오직 태스크 완료율(task-completion)에만 의존하여 프로덕션에서 도구 호출(tool-calling) 에이전트를 운영하고 있다면, 여러분은 한쪽 눈을 감고 비행하고 있는 것과 같습니다.
여러분의 설정이 궁금합니다
'모든 지표는 녹색(정상)이지만 실제로는 망가진' 트레이스 때문에 고생해 본 분 계신가요? 구체적으로 다음과 같은 점들이 궁금합니다:
- 인자(arguments)를 의미론적(semantically)으로 점수화하시나요, 아니면 스키마 검증(schema validation) 단계에서 멈추시나요?
- 결과 활용: 도구 페이로드(tool payload)를 바탕으로 근거를 확인하시나요, 아니면 검색된 코퍼스(retrieved corpus)만을 대상으로 하시나요?
- 실제 프로덕션 트래픽에 대한 근거성 확인을 위해 LLM-as-judge(판단자로서의 LLM)를 얼마나 신뢰하시나요?
댓글을 남겨주세요, 모두 읽어보겠습니다. 이 4계층 스택은 오픈 소스 평가 SDK로도 작동하므로, 시작하고 싶으시다면 말씀해 주세요. 링크를 공유해 드리겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기