AI 에이전트를 만들고 나면 이런 질문이 생겨요.
"이 에이전트가 잘 동작하는 건지 어떻게 알지? 그냥 써보는 것 말고 제대로 측정하는 방법이 있나?"
일반 소프트웨어는 테스트가 간단해요. 같은 입력에 같은 출력이 나오면 패스, 다르면 실패. 근데 AI 에이전트는 비결정적이고, 여러 단계를 거치고, 툴을 호출하고, 컨텍스트를 누적해요. 전통적인 테스트 방식이 안 통해요.
이번 글에서는 에이전트 평가가 왜 어려운지, 무엇을 측정해야 하는지, 어떤 방법으로 측정하는지 정리해 드릴게요.
왜 에이전트 평가는 어려운가
일반 LLM 평가와 에이전트 평가의 차이는 이거예요.
일반 LLM 평가
프롬프트 입력 → 답변 출력 → 정답과 비교
에이전트 평가
목표 입력
→ 툴 호출 결정 (올바른 툴인가?)
→ 툴 실행 (파라미터가 맞는가?)
→ 결과 해석 (제대로 이해했나?)
→ 다음 행동 결정 (방향이 맞나?)
→ ... 반복 ...
→ 최종 결과 (목표를 달성했나?)
평가해야 할 지점이 훨씬 많고, 각 단계가 다음 단계에 영향을 줘요. 한 곳에서 틀리면 에러가 전파돼요.
에이전트 평가를 어렵게 만드는 요인이 세 가지예요.
비결정성 — 같은 질문에도 매번 다른 결과가 나올 수 있어요. 정답이 하나가 아니에요.
다단계 의존성 — 10단계짜리 작업에서 3단계가 틀리면 이후 7단계가 전부 영향을 받아요. 어디서 실패했는지 추적하기 어려워요.
목표의 다차원성 — "고객 문제를 해결했는가"와 "10턴 이내에 해결했는가"와 "적절한 톤으로 대응했는가"를 동시에 평가해야 해요. 하나의 점수로 표현하기 어렵습니다.
무엇을 측정해야 하나 — 5가지 평가 축
축 1: 태스크 완료율 (Task Completion Rate)
가장 기본적인 지표예요. 에이전트가 주어진 목표를 달성했는가를 봐요.
def evaluate_task_completion(agent, test_cases):
results = []
for test in test_cases:
output = agent.run(test["input"])
# 성공 여부 판단
success = check_success(output, test["expected_outcome"])
results.append({
"task": test["input"],
"success": success,
"output": output
})
completion_rate = sum(r["success"] for r in results) / len(results)
return completion_rate
단순히 성공/실패 바이너리로 보는 게 아니라 부분 완료도 측정해야 해요. "목표의 70%를 달성했다"도 의미 있는 정보예요.
축 2: 툴 사용 정확도 (Tool Use Accuracy)
에이전트가 올바른 툴을 올바른 파라미터로 호출했는가를 봐요. 두 가지를 측정해요.
툴 선택 정확도 — 이 상황에서 올바른 툴을 골랐는가.
def evaluate_tool_selection(agent_trace, expected_tools):
selected_tools = [step["tool"] for step in agent_trace if step["type"] == "tool_call"]
correct = sum(t in expected_tools for t in selected_tools)
return correct / len(expected_tools)
파라미터 정확도 — 툴을 올바르게 골랐더라도 파라미터를 잘못 넘기면 실패해요.
def evaluate_tool_arguments(agent_trace, expected_calls):
correct = 0
for actual, expected in zip(agent_trace, expected_calls):
if actual["tool"] == expected["tool"]:
if actual["args"] == expected["args"]:
correct += 1
return correct / len(expected_calls)
Amazon이 수천 개의 에이전트를 구축하면서 발견한 것처럼, 잘못 정의된 툴 스키마가 잘못된 파라미터 전달로 이어지고, 이게 컨텍스트 창을 불필요하게 확장해서 성능을 떨어뜨려요.
축 3: 효율성 (Efficiency)
같은 목표를 달성하더라도 적은 턴, 적은 토큰, 적은 시간으로 달성하는 게 좋아요.
측정 지표는 이렇게 잡아요.
efficiency_metrics = {
"avg_turns": [], # 평균 턴 수
"avg_tokens": [], # 평균 토큰 사용량
"avg_latency_ms": [], # 평균 응답 시간
"avg_cost_usd": [], # 평균 비용
"tool_call_count": [] # 툴 호출 횟수
}
10턴으로 해결할 수 있는 문제를 50턴으로 해결하는 에이전트는 "성공"이지만 프로덕션에서 쓰기 어려워요.
축 4: 신뢰성 (Reliability)
같은 입력에 일관된 결과가 나오는가를 봐요. 비결정적인 에이전트를 여러 번 실행해서 성공률의 분산을 측정해요.
def evaluate_reliability(agent, test_case, n_runs=10):
results = []
for _ in range(n_runs):
output = agent.run(test_case["input"])
success = check_success(output, test_case["expected_outcome"])
results.append(success)
success_rate = sum(results) / n_runs
variance = calculate_variance(results)
return {
"success_rate": success_rate,
"variance": variance,
"consistent": variance < 0.1 # 10% 이하 분산이면 일관성 있음
}
에러 복구도 신뢰성의 일부예요. 툴 호출이 실패했을 때 에이전트가 스스로 재시도하거나 대안을 찾는지 측정해요.
축 5: 안전성 (Safety)
에이전트가 해서는 안 될 행동을 하는지 봐요. 특히 툴을 통해 실제 세계에 영향을 미치는 에이전트에서 중요해요.
safety_checks = [
"위험한 툴을 승인 없이 호출하는가", # DB 삭제, 이메일 발송 등
"민감한 정보를 외부로 유출하는가",
"프롬프트 인젝션 공격에 취약한가",
"허용되지 않은 범위의 작업을 시도하는가"
]
어떻게 측정하나 — 3가지 평가 방법
방법 1: 자동화 Evals
코드로 자동 실행하는 평가예요. 빠르고 반복 가능해서 개발 중에 CI/CD 파이프라인에 넣어서 쓰는 게 좋아요.
단위 평가 (Component-level Eval)
에이전트의 각 구성 요소를 개별적으로 테스트해요.
# 툴 선택만 테스트
def test_tool_selection():
agent = MyAgent()
result = agent.select_tool("서울 날씨 알려줘")
assert result.tool_name == "get_weather"
assert result.args["city"] == "서울"
# 추론만 테스트
def test_reasoning():
agent = MyAgent()
context = "검색 결과: 서울 15도 맑음"
answer = agent.generate_answer("날씨 어때?", context)
assert "15도" in answer or "맑음" in answer
엔드투엔드 평가 (E2E Eval)
전체 작업 흐름을 테스트해요.
test_cases = [
{
"input": "내일 서울 날씨 알려주고 옷차림 추천해줘",
"expected_tools": ["get_weather"],
"success_criteria": lambda output: "도" in output and ("가볍" in output or "따뜻" in output)
},
{
"input": "애플 주가 지금 얼마야",
"expected_tools": ["get_stock_price"],
"success_criteria": lambda output: "$" in output or "달러" in output
}
]
for test in test_cases:
result = agent.run(test["input"])
assert test["success_criteria"](result)
방법 2: LLM-as-Judge (LLM 심판)
다른 LLM이 에이전트의 출력을 평가해요. 정답이 하나가 아닌 주관적인 평가에 유용해요.
def llm_judge(question, agent_output, rubric):
judge_prompt = f"""
다음 에이전트 출력을 평가해줘.
질문: {question}
에이전트 출력: {agent_output}
평가 기준:
{rubric}
1~5점으로 평가하고 이유를 설명해줘.
JSON으로만 답해: {{"score": 점수, "reason": "이유"}}
"""
result = judge_llm.invoke(judge_prompt)
return json.loads(result.content)
# 사용 예시
rubric = """
- 5점: 질문에 완전히 답하고, 정확하고, 도움이 됨
- 3점: 부분적으로 답하거나 약간 부정확함
- 1점: 질문과 관련 없거나 틀린 답변
"""
score = llm_judge(
question="서울 내일 날씨 알려줘",
agent_output="내일 서울은 맑고 기온 18도입니다. 가벼운 겉옷 챙기세요.",
rubric=rubric
)
# {"score": 5, "reason": "날씨 정보가 정확하고 추가 팁도 있음"}
멀티턴 평가에서는 시뮬레이션 유저를 써요. 한 LLM이 에이전트, 다른 LLM이 유저를 연기해서 대화를 시뮬레이션해요.
def simulate_conversation(agent, user_persona, goal, max_turns=10):
messages = []
user_llm = create_user_simulator(persona=user_persona, goal=goal)
for turn in range(max_turns):
# 유저 메시지 생성
user_msg = user_llm.generate_message(messages)
messages.append({"role": "user", "content": user_msg})
# 에이전트 응답
agent_response = agent.respond(messages)
messages.append({"role": "assistant", "content": agent_response})
# 목표 달성 확인
if goal_achieved(messages, goal):
return {"success": True, "turns": turn + 1, "conversation": messages}
return {"success": False, "turns": max_turns, "conversation": messages}
방법 3: 휴먼 평가 (Human Evaluation)
자동화 평가가 못 잡는 뉘앙스, 톤, 사용자 경험을 사람이 직접 평가해요.
평가 항목:
□ 응답이 자연스럽고 이해하기 쉬운가?
□ 사용자의 의도를 제대로 파악했는가?
□ 불필요하게 길거나 짧지 않은가?
□ 오해를 일으킬 수 있는 표현이 없는가?
□ 전체적으로 도움이 됐는가?
자동화 평가와 휴먼 평가를 어떻게 조합하느냐가 중요해요.
개발 단계: 자동화 Evals 위주 (빠른 피드백)
출시 전: 자동화 + LLM 심판 + 휴먼 평가 병행
프로덕션: 지속적 자동 모니터링 + 샘플 휴먼 리뷰
주요 벤치마크
실제로 많이 쓰이는 에이전트 벤치마크들이에요.
SWE-bench — GitHub 실제 이슈를 에이전트가 해결하게 해요. 코딩 에이전트 평가의 표준이에요. 초기 GPT-4 기반 에이전트는 14%만 해결했는데, 2025년에는 60%까지 올라왔어요.
τ-bench / τ2-bench — 멀티턴 대화 에이전트를 평가해요. 한 LLM이 유저를 연기하면서 항공 예약, 쇼핑몰 고객 서비스 같은 시나리오를 시뮬레이션해요. 태스크 완료 + 대화 품질 + 턴 수 제한을 동시에 평가해요.
BrowseComp — 웹 브라우징 에이전트 평가예요. OpenAI Deep Research가 51.5%를 기록했어요.
AgentBench — 운영체제, DB, 웹 쇼핑, 지식 그래프 등 8개 환경에서 에이전트를 테스트해요.
평가 파이프라인 구축
에이전트를 개발할 때 평가를 처음부터 파이프라인에 넣어야 해요.
코드 변경
│
▼
자동화 Evals 실행 (CI/CD)
│
├─ 통과 → 스테이징 배포
└─ 실패 → 알림 + 블록
│
▼
스테이징에서 심층 평가
(LLM 심판 + 휴먼 샘플링)
│
▼
프로덕션 배포
│
▼
지속적 모니터링
(성공률, 지연 시간, 비용 추적)
Anthropic이 강조하는 것처럼 **"eval 점수를 액면 그대로 믿지 말고, 직접 트랜스크립트를 읽어봐야 한다"**는 게 중요해요. 그레이딩이 불공정하거나 태스크가 모호하면 eval이 의미 없거든요.
실전 평가 도구
도구 특징 적합한 용도
| LangSmith | LangChain 네이티브, 트레이싱 강함 | LangGraph 기반 에이전트 |
| DeepEval | 오픈소스, 메트릭 풍부 | 범용 LLM/에이전트 평가 |
| Arize Phoenix | 오픈소스, RAG 평가 강함 | RAG 파이프라인 |
| Galileo | 툴 선택 품질, 세션 성공률 | 프로덕션 에이전트 모니터링 |
마무리
에이전트 평가의 핵심은 세 가지예요.
첫째, 단일 지표로 충분하지 않아요. 태스크 완료율, 툴 정확도, 효율성, 신뢰성, 안전성을 함께 봐야 해요.
둘째, 자동화와 휴먼 평가를 조합해야 해요. 자동화는 빠르고 일관성 있지만 뉘앙스를 못 잡아요. 휴먼은 느리지만 진짜 품질을 잡아요.
셋째, 평가는 개발 시작부터 파이프라인에 넣어야 해요. 출시 직전에 급하게 평가하면 이미 늦어요. 😄
'AI Agent' 카테고리의 다른 글
| AI 에이전트가 기억하는 법 — 단기/장기 메모리 아키텍처와 MemGPT 완전 정리 (0) | 2026.03.26 |
|---|---|
| AI 에이전트 보안 완전 정리 — Prompt Injection 공격과 방어 완전 가이드 (0) | 2026.03.26 |
| AI 에이전트 오케스트레이션 패턴 3가지 — Pipeline, Supervisor, Swarm 실전 비교 (0) | 2026.03.25 |
| LLM 출력 파싱 실패를 없애는 법 — Pydantic으로 JSON 검증 완전 정리 (0) | 2026.03.25 |
| AI 에이전트가 긴 작업을 끝까지 해내는 법 — 컨텍스트 압축 전략 완전 정리 (0) | 2026.03.25 |