🔥 고급2026-07-256~8분
에이전트 평가 파이프라인 설계: 행동 trace 기반 Ground-truth 구축과 회귀 방지
에이전트는 최종 출력만이 아니라 중간 tool 호출 순서와 인자까지 평가해야 한다. Trace 레코딩과 LLM-as-judge를 결합한 자동 회귀 탐지 파이프라인을 설계한다.
evaluationagentsobservability
에이전트 평가가 어려운 이유
단순 QA와 달리 에이전트는 같은 목표를 여러 tool 호출 경로로 달성할 수 있다. 최종 답변이 정확해도 비효율적인 경로(예: 불필요한 검색 3회)를 사용했다면 비용·지연 문제가 된다. 반대로 경로가 달라도 결과가 맞을 수 있어 단순 exact-match는 무의미하다. 핵심은 행동 trace를 기록하고, 의도 단위로 평가하는 것이다.
Trace 수집과 Ground-truth 구조
tool 호출마다 입력·출력·타임스탬프를 수집한다. Ground-truth는 세 가지 레이어로 구성한다.
- 결과 레이어: 최종 응답이 기대 답변 집합에 포함되는가 (정확도)
- 효율 레이어: tool 호출 횟수가 기준 N회 이하인가 (비용)
- 안전 레이어: 금지 tool 또는 금지 인자가 사용되지 않았는가 (안전)
Ground-truth는 초기에 사람이 20~50개 케이스를 레이블링하고, 이후 프로덕션 trace 중 신뢰도 높은 케이스를 자동 추가한다.
import anthropic
import json
from dataclasses import dataclass, field
from typing import Any
@dataclass
class AgentTrace:
query: str
tool_calls: list[dict] = field(default_factory=list)
final_answer: str = ""
def run_agent_with_trace(query: str) -> AgentTrace:
client = anthropic.Anthropic()
trace = AgentTrace(query=query)
tools = [
{
"name": "search",
"description": "Search documents",
"input_schema": {
"type": "object",
"properties": {"q": {"type": "string"}},
"required": ["q"],
},
}
]
messages = [{"role": "user", "content": query}]
for _ in range(5): # 최대 5턴
resp = client.messages.create(
model="claude-opus-4-5",
max_tokens=1024,
tools=tools,
messages=messages,
)
if resp.stop_reason == "end_turn":
trace.final_answer = resp.content[0].text
break
for block in resp.content:
if block.type == "tool_use":
trace.tool_calls.append(
{"name": block.name, "input": block.input}
)
# 실제 환경에서는 tool 실행 결과를 추가
messages.append({"role": "assistant", "content": resp.content})
messages.append({
"role": "user",
"content": [{"type": "tool_result",
"tool_use_id": block.id,
"content": "mock result"}],
})
break
return trace
def evaluate_trace(trace: AgentTrace, ground_truth: dict) -> dict:
result_ok = trace.final_answer in ground_truth["expected_answers"]
efficiency_ok = len(trace.tool_calls) <= ground_truth["max_tool_calls"]
forbidden = ground_truth.get("forbidden_tools", [])
safety_ok = all(tc["name"] not in forbidden for tc in trace.tool_calls)
return {"result": result_ok, "efficiency": efficiency_ok, "safety": safety_ok}
회귀 탐지와 운영 체크리스트
자동 회귀 탐지 흐름: CI 파이프라인에서 모델 버전 또는 시스템 프롬프트 변경 시 저장된 케이스 전체를 재실행한다. 결과 정확도 기준선 대비 3% 이상 하락, 평균 tool 호출 수 20% 이상 증가 중 하나라도 해당하면 배포를 블록한다.
트레이드오프
- LLM-as-judge로 결과 레이어를 평가하면 비용이 케이스당 약 $0.01~$0.03 발생하지만 사람 레이블링 대비 10배 빠르다.
- Ground-truth 케이스를 50개 미만으로 유지하면 분포 커버리지가 부족해 회귀를 놓친다. 최소 100개, 도메인별 레이어 분리를 권장한다.
운영 체크리스트
- [ ] 모든 tool 호출 trace를 구조화 로그로 영속 저장
- [ ] Ground-truth 케이스 버전 관리 (Git 또는 전용 DB)
- [ ] CI 단계에 평가 파이프라인 연결 및 실패 시 배포 블록
- [ ] 결과·효율·안전 지표를 대시보드에서 별도 추적
- [ ] 월 1회 Ground-truth 케이스 샘플링 재검토 및 갱신