Production-ready evaluation framework for AI agents — 25 metrics across task completion, accuracy, hallucination, latency, security, and agentic behavior
Project description
Agent Evaluator
AI 에이전트를 위한 프로덕션 레디 평가 프레임워크
함수 위에 데코레이터 한 줄을 추가하는 것만으로 에이전트를 평가할 수 있습니다. LangChain, CrewAI, AutoGen, LangGraph 등 21개 프레임워크를 자동 인식하고, 태스크 완료율부터 보안 취약점까지 25개 지표를 코드 수정 없이 측정합니다.
왜 데코레이터인가?
# ❌ 기존 방식 — 에이전트 코드를 직접 수정, 보일러플레이트 작성 필요
import time, uuid
from datetime import datetime
def my_agent(question, ground_truth):
start = time.time()
response = llm.invoke(question)
elapsed = time.time() - start
task = TaskResult(
task_id=str(uuid.uuid4()), task_type="qa", success=True,
completion_score=1.0,
accuracy_score=compute_accuracy(response, ground_truth), # 직접 계산
execution_time=elapsed, # 직접 측정
tokens_used=extract_tokens(response), # 프레임워크마다 다름
tool_calls=[], attempts=1, errors=[], timestamp=datetime.now(),
question=question, response=str(response), ground_truth=ground_truth,
)
monitor.record_task(task)
return response
# ✅ 데코레이터 방식 — 한 줄 추가, 에이전트 코드 무수정
from agent_evaluator import QuickEval
eval = QuickEval("results/")
@eval.qa # 이 한 줄이 전부
def my_agent(question, ground_truth=""):
return llm.invoke(question) # 에이전트 로직 그대로 유지
데코레이터는 **비침습적(non-invasive)**입니다. 원본 함수의 시그니처·반환값·예외 처리가 변경되지 않으며, 측정이 끝나면 원래 반환값이 그대로 호출자에게 전달됩니다.
데코레이터 동작 원리
호출자
│
▼
@agent_eval / @batch_eval / @conversation_eval
│
├─ [1] 실행 시간 측정 시작
├─ [2] 원본 함수 실행
├─ [3] 프레임워크 어댑터 적용 ← tool_calls · chain_steps · tokens_used 자동 추출
├─ [4] EvalMetadata 병합 ← 함수가 (response, EvalMetadata(...)) 반환 시
├─ [5] TaskResult 자동 구성 ← 24개 필드 완성
├─ [6] PerformanceMonitor.record_task() 호출
│ ├─ Layer 1: TCR · Accuracy · Hallucination · Quality · Latency · Token
│ ├─ Layer 2: Tool · Retry · Coordination · Workflow · Security (5종)
│ └─ Layer 3: DeepEval · Ragas · LangSmith (opt-in)
│
└─ [7] 원본 반환값 그대로 호출자에게 전달
설치
pip install agent-evaluator # 기본 (Layer 1/2 즉시 사용)
pip install "agent-evaluator[llm]" # OpenAI + Anthropic 클라이언트
pip install "agent-evaluator[langchain]" # LangChain / LangGraph
pip install "agent-evaluator[eval]" # DeepEval + Ragas (Layer 3)
pip install "agent-evaluator[serve]" # FastAPI 대시보드
pip install "agent-evaluator[all]" # 권장 — crewai/autogen/otel 제외 전체
pip install "agent-evaluator[full]" # 전체 (⚠️ 10분+ 소요)
3가지 데코레이터
Agent Evaluator의 평가 인터페이스는 호출 패턴에 따라 정확히 3종으로 구성됩니다.
| 데코레이터 | 호출 패턴 | 사용 시나리오 |
|---|---|---|
@agent_eval |
함수 1회 호출 = TaskResult 1건 | 단일 QA · 도구 호출 · RAG · 보안 검사 |
@batch_eval |
함수 1회 호출 = TaskResult N건 | 데이터셋 일괄 평가 · 벤치마크 |
@conversation_eval |
함수 N회 호출 = TaskResult 1건 | 멀티턴 대화 · 챗봇 세션 |
데코레이터 1: @agent_eval
1번 호출 → 1개 TaskResult. 동기·비동기·제너레이터·재시도를 모두 지원합니다.
from agent_evaluator import PerformanceMonitor
from agent_evaluator.decorators import agent_eval
monitor = PerformanceMonitor("results/")
# 기본 — QA 평가
@agent_eval(monitor, task_type="qa")
def agent(question: str, ground_truth: str = "") -> str:
return llm.invoke(question)
# 비동기 함수 — 동일한 데코레이터 사용
@agent_eval(monitor, task_type="qa")
async def async_agent(question: str, ground_truth: str = "") -> str:
return await async_llm.invoke(question)
# 재시도 내장 — 실패 시 자동 재시도, attempts 필드 자동 기록
@agent_eval(monitor, task_type="qa", max_retries=3, delay=1.0, backoff=2.0)
def robust_agent(question: str, ground_truth: str = "") -> str:
return unreliable_llm.invoke(question)
# RAG 에이전트 — rag_mode=True 하나로 context + hallucination 자동 활성
@agent_eval(monitor, task_type="information_retrieval", rag_mode=True, context_arg="context")
def rag_agent(question: str, context: str = "", ground_truth: str = "") -> str:
return retrieval_llm.invoke(question, context)
# 보안 검사 — security_mode=True 로 5개 보안 트래커 임시 활성
@agent_eval(monitor, task_type="qa", security_mode=True)
def secure_agent(question: str, ground_truth: str = "") -> str:
return llm.invoke(question)
# LLM 프레임워크 어댑터 — tool_calls · tokens_used 자동 추출
@agent_eval(monitor, task_type="tool_use", framework="langchain")
def langchain_agent(question: str, ground_truth: str = "") -> str:
return executor.invoke({"input": question})
@agent_eval 주요 파라미터
| 파라미터 | 기본값 | 설명 |
|---|---|---|
task_type |
"qa" |
태스크 유형 (qa · tool_use · information_retrieval · code_generation 등) |
framework |
"native" |
프레임워크 어댑터 (21종 지원) |
auto_detect_framework |
True |
반환값 타입으로 프레임워크 자동 감지 |
question_arg |
"question" |
질문 인자명 |
ground_truth_arg |
"ground_truth" |
정답 인자명 |
context_arg |
None |
RAG 컨텍스트 인자명 |
expected_tools_arg |
None |
기대 툴 목록 인자명 (Tool Selection F1 자동 계산) |
score_fn |
None |
커스텀 정확도 계산 함수 (response, gt) → float |
rag_mode |
False |
context_arg + hallucination 자동 활성 단축 설정 |
security_mode |
False |
보안 지표 이 호출에만 임시 활성 |
enable_hallucination |
False |
Hallucination Detection 이 호출에만 임시 활성 |
enable_llm_judge |
False |
LLM Judge 이 호출에만 임시 활성 |
max_retries |
1 |
실패 시 최대 재시도 횟수 |
delay / backoff |
0.0 / 1.0 |
재시도 대기 시간 / 지수 백오프 계수 |
timeout |
None |
최대 실행 시간(초) |
sample_rate |
1.0 |
기록 샘플링 비율 |
on_record |
None |
기록 직전 콜백 (TaskResult 교체 가능) |
alert_rules |
[] |
조건부 알림 규칙 목록 |
flush_every |
0 |
N건마다 자동 save_to_file() |
preset |
None |
사전 정의 설정 묶음 |
데코레이터 2: @batch_eval
1번 호출 → N개 TaskResult. 질문 리스트를 받아 건별로 독립된 평가 레코드를 생성합니다.
from agent_evaluator.decorators import batch_eval
# 기본 — 리스트 입력, 리스트 반환
@batch_eval(monitor, task_type="qa")
def batch_agent(questions: list, ground_truths: list = None) -> list:
return [llm.invoke(q) for q in questions]
# DataFrame 반환 — accuracy_score · execution_time · tokens_total 등 포함
@batch_eval(monitor, task_type="qa", return_format="dataframe")
def batch_agent_df(questions: list, ground_truths: list = None) -> list:
return [llm.invoke(q) for q in questions]
# 병렬 실행 (async 함수) — asyncio.gather 기반
@batch_eval(monitor, task_type="qa", concurrent=True, max_concurrent=4)
async def parallel_agent(questions: list, ground_truths: list = None) -> list:
return await asyncio.gather(*[async_llm.invoke(q) for q in questions])
# 진행률 콜백 — 대규모 배치 모니터링
@batch_eval(
monitor,
task_type="qa",
return_format="tuple", # (responses, task_results) 반환
on_batch_progress=lambda done, total: print(f"{done}/{total}"),
flush_every=100, # 100건마다 중간 저장
)
def large_batch(questions: list, ground_truths: list = None) -> list:
return [llm.invoke(q) for q in questions]
responses, task_results = large_batch(questions, ground_truths)
@batch_eval 주요 파라미터
| 파라미터 | 기본값 | 설명 |
|---|---|---|
questions_arg |
"questions" |
질문 리스트 인자명 |
ground_truths_arg |
"ground_truths" |
정답 리스트 인자명 |
return_format |
"list" |
반환 형식: "list" · "tuple" · "dataframe" |
concurrent |
False |
async 함수 항목별 병렬 실행 |
max_concurrent |
0 |
병렬 상한 (0 = 무제한) |
shuffle |
False |
처리 순서 무작위화 |
item_timeout |
None |
항목별 최대 처리 시간(초) |
on_batch_progress |
None |
진행률 콜백 (completed, total) → None |
on_batch_complete |
None |
배치 완료 콜백 (results) → None |
on_item_error |
None |
항목 실패 콜백 (index, question, error) → None |
streaming_mode |
False |
메모리 효율적 스트리밍 처리 |
데코레이터 3: @conversation_eval
N번 호출 → 1개 TaskResult. 동일 session_id로 반복 호출하면 내부에서 턴을 누적하다가 max_turns 도달 또는 flush_conversation() 호출 시 세션을 종료하고 지표를 계산합니다.
from agent_evaluator.decorators import conversation_eval
# 기본 — session_id별 자동 누적, max_turns 도달 시 자동 flush
@conversation_eval(monitor, session_id_arg="session_id", max_turns=5)
def chat(question: str, session_id: str = "default") -> str:
return llm.invoke(question)
# 사용 — 동일 session_id로 반복 호출
chat("파이썬 비동기 처리 방법 알려줘", session_id="conv_001")
chat("방금 설명한 방법의 단점은?", session_id="conv_001")
chat("asyncio.gather 예시 코드 보여줘", session_id="conv_001")
# → 5턴 도달 시 자동 flush: context_retention · topic_coherence · progressive_depth 계산
# 수동 flush — 원하는 시점에 세션 종료
from agent_evaluator.decorators import flush_conversation
flush_conversation("conv_001")
# 턴별 콜백 + 세션 스코어 함수
@conversation_eval(
monitor,
max_turns=10,
on_turn=lambda sid, user, resp, meta: print(f"[{sid}] {user[:20]}…"),
session_score_fn=lambda metrics: metrics.overall_score * 100,
flush_every=3, # 세션 3개마다 save_to_file() 자동 호출
)
def advanced_chat(question: str, session_id: str = "s1") -> str:
return llm.invoke(question)
@conversation_eval이 측정하는 지표:
| 지표 | 설명 |
|---|---|
context_retention |
이전 턴 맥락이 후속 응답에 반영된 정도 |
topic_coherence |
대화 전반의 주제 일관성 |
progressive_depth |
대화가 심화될수록 정보 밀도가 높아지는 정도 |
session_completion |
목표 대화 완성도 |
avg_turn_latency |
턴별 평균 응답 시간 |
turn_scores |
턴별 품질 점수 (Optional) |
@conversation_eval 주요 파라미터
| 파라미터 | 기본값 | 설명 |
|---|---|---|
session_id_arg |
"session_id" |
세션 ID 인자명 |
user_arg |
"question" |
사용자 메시지 인자명 |
max_turns |
None |
최대 턴 수 (도달 시 자동 flush) |
max_turns_exceeded_action |
"flush" |
초과 시 동작: "flush" · "warn" · "error" |
flush_on_error |
True |
예외 발생 시 세션 자동 flush |
on_turn |
None |
턴 완료 콜백 (sid, user, response, meta) → None |
on_flush |
None |
세션 종료 콜백 (metrics, session_id) → None |
session_score_fn |
None |
세션 종합 점수 함수 (ConversationMetrics) → float |
turn_score_fn |
None |
턴별 점수 함수 (user, response, meta) → float |
load_previous_session |
False |
이전 세션 이어받기 |
max_session_seconds |
None |
비활성 세션 자동 flush 타이머(초) |
EvalDecorator — 3종 통합 팩토리
공통 설정(monitor, framework, model_name 등)을 한 번만 정의하고 3종 데코레이터 모두에 재사용합니다.
from agent_evaluator.decorators import EvalDecorator
# 공통 설정 한 번 정의
dec = EvalDecorator(
monitor,
framework="langchain",
model_name="gpt-4o-mini",
flush_every=10,
alert_rules=[slow_rule, error_rule],
)
# ── agent_eval 계열 ──────────────────────────────────
@dec(task_type="qa") # agent_eval 직접 호출
def qa_agent(question, ground_truth=""): ...
@dec.with_retry(task_type="qa", max_retries=3) # 재시도 포함
def robust_agent(question, ground_truth=""): ...
# ── batch_eval ───────────────────────────────────────
@dec.batch(task_type="qa", return_format="dataframe")
def batch_agent(questions, ground_truths=None): ...
# ── conversation_eval ────────────────────────────────
@dec.conversation(session_id_arg="sid", max_turns=5)
def chat(question, sid="s1"): ...
# ── task_type 단축 속성 (QuickEval과 동일한 API) ─────
@dec.qa # task_type="qa"
@dec.tool_use # task_type="tool_use"
@dec.rag # task_type="information_retrieval" + rag_mode=True
@dec.code # task_type="code_generation"
@dec.reasoning # task_type="reasoning"
@dec.secure # task_type="qa" + security_mode=True
QuickEval — 1줄 시작 Facade
PerformanceMonitor + EvalDecorator를 1줄로 구성하는 원스톱 진입점입니다.
from agent_evaluator import QuickEval
# 기본 초기화
eval = QuickEval("results/")
# 용도별 팩토리 — 관련 옵션 자동 설정
eval = QuickEval.for_rag("results/") # hallucination_detection=True 기본 활성
eval = QuickEval.for_security("results/") # enable_security_metrics=True 기본 활성
eval = QuickEval.for_llm_judge("results/", model="claude-sonnet-4-6")
# 데코레이터 단축 속성 11종
@eval.qa @eval.tool_use @eval.rag
@eval.code @eval.reasoning @eval.planning
@eval.data_analysis @eval.creative @eval.multi_agent
@eval.secure @eval.streaming
# 배치 · 대화 데코레이터도 동일 인터페이스
@eval.batch(task_type="qa", return_format="dataframe")
def batch_agent(questions, ground_truths=None): ...
@eval.conversation(session_id_arg="sid", max_turns=5)
def chat(question, sid="s1"): ...
# 결과 저장 · 게이팅
eval.save() # results/*.json + *.html
eval.gate(tcr=85, accuracy=70, hallucination=5) # CI/CD 게이트
eval.summary() # 주요 지표 요약 출력
eval.export_to_dataframe() # pd.DataFrame 반환
eval_context — 데코레이터 불가 시 탈출구
외부 라이브러리 함수, lambda, 동적 호출 등 데코레이터를 붙일 수 없는 코드에서 사용합니다. @agent_eval과 동일한 평가를 수행합니다.
from agent_evaluator.decorators import eval_context, get_eval_ctx
# 기본 — with 블록 종료 시 자동 record_task()
with eval_context(monitor, task_type="qa",
question="한국의 수도는?", ground_truth="서울") as ctx:
ctx.response = external_lib.call("한국의 수도는?")
# get_eval_ctx() 로 추가 메타데이터 주입
with eval_context(monitor, task_type="tool_use", question=q) as ctx:
result = external_agent.run(q)
ctx.response = result["output"]
ec = get_eval_ctx()
if ec:
ec.framework = "langchain"
ec.chain_steps = parse_steps(result)
# 비동기
async with eval_context(monitor, task_type="qa", question=q) as ctx:
ctx.response = await async_external.call(q)
EvalMetadata — 추가 메타데이터 주입
3종 데코레이터 모두에서 사용 가능합니다. 반환값을 (response, EvalMetadata(...)) 튜플로 바꾸면 자동 추출 결과를 덮어쓸 수 있습니다.
from agent_evaluator.decorators import EvalMetadata
@agent_eval(monitor, task_type="tool_use")
def agent(question, ground_truth=""):
response = llm.invoke(question)
return response, EvalMetadata(
accuracy_score=0.95, # 커스텀 점수 직접 지정
tool_calls=["search", "calculator"], # 툴 호출 목록
tokens_used={"input": 120, "output": 80},
chain_steps=["search", "parse", "answer"],
agent_interactions=[("planner", "executor", "task_complete")],
)
@conversation_eval에서는 TurnMetadata를 사용합니다.
from agent_evaluator.decorators import TurnMetadata
@conversation_eval(monitor, max_turns=5)
def chat(question: str, session_id: str = "s1") -> str:
response = llm.invoke(question)
return response, TurnMetadata(
model="gpt-4o-mini",
tokens={"input": 50, "output": 30},
tool_calls=["search"],
)
21개 프레임워크 자동 인식
framework= 파라미터 하나로 응답 객체에서 tool_calls, chain_steps, tokens_used 등을 자동 추출합니다.
3종 데코레이터 모두 동일한 framework= 파라미터를 지원합니다.
# 명시적 지정 — IDE 자동완성 지원 (FrameworkLiteral 타입 힌트)
@agent_eval(monitor, task_type="tool_use", framework="langchain")
def lc_agent(question, ground_truth=""): ...
# 자동 감지 (기본 활성 — auto_detect_framework=True)
@agent_eval(monitor, task_type="qa")
def auto_agent(question, ground_truth=""): ...
# batch_eval · conversation_eval에도 동일하게 적용
@batch_eval(monitor, task_type="qa", framework="openai")
def batch_agent(questions, ground_truths=None): ...
@conversation_eval(monitor, max_turns=5, framework="anthropic")
def chat(question, session_id="s1"): ...
# 프레임워크 어댑터 정보 조회
from agent_evaluator.decorators import get_framework_info
info = get_framework_info("langchain")
# → {"name": "LangChain", "extras": "langchain",
# "extracts": ["tool_calls", "chain_steps"], "async_supported": True, ...}
어댑터 전체 목록
| 식별자 | 이름 | 필요 extras | 자동 추출 필드 | async |
|---|---|---|---|---|
langchain |
LangChain | [langchain] |
tool_calls · chain_steps |
✅ |
langgraph |
LangGraph | [langchain] |
state_transitions · graph_traversal · tool_calls · chain_steps |
✅ |
crewai |
CrewAI | [crewai] |
agent_interactions |
❌ |
autogen |
AutoGen | [autogen] |
conversation_turns · tokens_used |
✅ |
dspy |
DSPy | [dspy] |
chain_steps · tokens_used |
❌ |
pydanticai |
PydanticAI | [pydanticai] |
chain_steps · tokens_used |
✅ |
anthropic |
Anthropic | [llm] |
tool_calls · tokens_used |
✅ |
openai |
OpenAI | [llm] |
tool_calls · tokens_used |
✅ |
gemini |
Google Gemini | [llm] |
tool_calls · tokens_used |
✅ |
vertexai |
Vertex AI | [llm] |
tool_calls · tokens_used |
✅ |
cohere |
Cohere | [llm] |
tool_calls · tokens_used |
✅ |
groq |
Groq | [llm] |
tool_calls · tokens_used |
✅ |
mistral |
Mistral AI | [llm] |
tool_calls · tokens_used |
✅ |
bedrock |
AWS Bedrock | [llm] |
tool_calls · tokens_used |
✅ |
ollama |
Ollama | [llm] |
tool_calls · tokens_used |
❌ |
llamaindex |
LlamaIndex | [llm] |
chain_steps |
✅ |
haystack |
Haystack | [llm] |
chain_steps |
✅ |
semantic_kernel |
Semantic Kernel | [llm] |
chain_steps · tokens_used |
✅ |
smolagents |
HuggingFace smolagents | [llm] |
tool_calls · chain_steps |
❌ |
vllm |
vLLM | [llm] |
tool_calls · tokens_used |
✅ |
huggingface |
HuggingFace | [llm] |
chain_steps · tool_calls |
❌ |
오케스트레이션 프레임워크
LangChain
AgentExecutor.invoke() 결과의 intermediate_steps에서 툴 호출과 체인 단계를 자동 추출합니다.
from langchain.agents import AgentExecutor
from agent_evaluator.decorators import agent_eval
# intermediate_steps → tool_calls + chain_steps 자동 변환
# usage_metadata / response_metadata.token_usage → tokens_used 자동 추출
@agent_eval(monitor, task_type="tool_use", framework="langchain")
def lc_agent(question: str, ground_truth: str = "") -> str:
result = agent_executor.invoke({"input": question})
return result # dict 그대로 반환 — "output" 키에서 텍스트 자동 추출
# 프레임워크 전용 별칭 (agent_evaluator.integrations)
from agent_evaluator.integrations import langchain_eval
@langchain_eval(monitor, task_type="tool_use")
def lc_agent2(question: str, ground_truth: str = "") -> str:
return agent_executor.invoke({"input": question})
LangGraph
그래프 실행 결과의 messages 배열에서 상태 전이·그래프 경로·툴 호출을 추출합니다.
__metadata__ 키가 있으면 그래프 메타데이터도 자동 수집합니다.
from langgraph.graph import StateGraph
from agent_evaluator.decorators import agent_eval
# messages → state_transitions + graph_traversal
# ToolMessage / AIMessage → chain_steps + 타임스탬프 기반 실행 시간
@agent_eval(monitor, task_type="tool_use", framework="langgraph")
def lg_agent(question: str, ground_truth: str = "") -> str:
result = graph.invoke({"messages": [("user", question)]})
return result # "messages"[-1].content 자동 추출
from agent_evaluator.integrations import langgraph_eval
@langgraph_eval(monitor, task_type="tool_use")
def lg_agent2(question: str, ground_truth: str = "") -> str:
return graph.invoke({"messages": [("user", question)]})
CrewAI
Crew.kickoff() 결과의 tasks_output에서 에이전트 간 상호작용을 추출합니다.
output_pydantic / output_format (v2.x) 필드를 지원합니다.
from crewai import Crew, Agent, Task
from agent_evaluator.decorators import agent_eval
# tasks_output → agent_interactions 자동 변환
# 주의: CrewAI는 async 미지원 — 동기 함수로만 사용
@agent_eval(monitor, task_type="tool_use", framework="crewai")
def crew_agent(question: str, ground_truth: str = "") -> str:
result = crew.kickoff(inputs={"topic": question})
return str(result)
from agent_evaluator.integrations import crewai_eval
@crewai_eval(monitor, task_type="tool_use")
def crew_agent2(question: str, ground_truth: str = "") -> str:
return str(crew.kickoff(inputs={"topic": question}))
AutoGen
chat_result.messages / chat_history에서 대화 턴과 비용 정보를 추출합니다.
AutoGen 0.4+ async API는 autogen_eval_async 전용 데코레이터를 사용합니다.
from autogen import ConversableAgent
from agent_evaluator.decorators import agent_eval
from agent_evaluator.integrations import autogen_eval, autogen_eval_async
# messages/chat_history → conversation_turns
# cost/usage_summary → tokens_used
@agent_eval(monitor, task_type="qa", framework="autogen")
def autogen_agent(question: str, ground_truth: str = "") -> str:
result = assistant.initiate_chat(user_proxy, message=question, max_turns=3)
return result.summary
# AutoGen 0.4+ async API 전용
@autogen_eval_async(monitor, task_type="qa")
async def autogen_agent_async(question: str, ground_truth: str = "") -> str:
result = await team.run(task=question)
return result.messages[-1].content
LLM 공급자
OpenAI
ChatCompletion 응답의 choices[0].message.tool_calls와 usage.total_tokens를 자동 추출합니다.
Assistants API의 required_action도 지원합니다.
import openai
from agent_evaluator.decorators import agent_eval
client = openai.OpenAI()
@agent_eval(monitor, task_type="tool_use", framework="openai")
def gpt_agent(question: str, ground_truth: str = "") -> str:
return client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": question}],
tools=[...],
) # ChatCompletion 객체 그대로 반환 — choices[0].message.content 자동 추출
Anthropic
Message 응답의 content[].tool_use와 usage.input_tokens/output_tokens를 추출합니다.
캐시 토큰(cache_creation_input_tokens, cache_read_input_tokens, SDK ≥0.29)도 지원합니다.
import anthropic
from agent_evaluator.decorators import agent_eval
client = anthropic.Anthropic()
@agent_eval(monitor, task_type="tool_use", framework="anthropic")
def claude_agent(question: str, ground_truth: str = "") -> str:
return client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": question}],
tools=[...],
) # Message 객체 그대로 반환 — content[0].text 자동 추출
Google Gemini / Vertex AI
GenerateContentResponse의 candidates[0].content.parts[].function_call과 usage_metadata를 추출합니다.
import google.generativeai as genai
from agent_evaluator.decorators import agent_eval
model = genai.GenerativeModel("gemini-1.5-flash")
@agent_eval(monitor, task_type="tool_use", framework="gemini")
def gemini_agent(question: str, ground_truth: str = "") -> str:
return model.generate_content(question) # GenerateContentResponse 그대로 반환
# Vertex AI는 동일한 응답 구조 — framework="vertexai"
@agent_eval(monitor, task_type="tool_use", framework="vertexai")
def vertex_agent(question: str, ground_truth: str = "") -> str:
return vertex_model.generate_content(question)
Cohere
NonStreamedChatResponse의 tool_calls와 meta.tokens를 추출합니다.
스트리밍 응답(finish_reason 속성)도 자동 감지합니다.
import cohere
from agent_evaluator.decorators import agent_eval
co = cohere.Client()
@agent_eval(monitor, task_type="tool_use", framework="cohere")
def cohere_agent(question: str, ground_truth: str = "") -> str:
return co.chat(message=question, tools=[...])
Groq
OpenAI 호환 API 구조 — tool_calls와 usage를 추출합니다.
캐시 토큰(cache_creation_input_tokens, cache_read_input_tokens, v0.9+)도 지원합니다.
from groq import Groq
from agent_evaluator.decorators import agent_eval
client = Groq()
@agent_eval(monitor, task_type="tool_use", framework="groq")
def groq_agent(question: str, ground_truth: str = "") -> str:
return client.chat.completions.create(
model="llama-3.3-70b-versatile",
messages=[{"role": "user", "content": question}],
)
Mistral AI
ChatCompletionResponse의 tool_calls와 usage를 추출합니다.
구버전 function_call 필드도 지원합니다.
from mistralai import Mistral
from agent_evaluator.decorators import agent_eval
client = Mistral()
@agent_eval(monitor, task_type="tool_use", framework="mistral")
def mistral_agent(question: str, ground_truth: str = "") -> str:
return client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": question}],
)
AWS Bedrock
Bedrock Converse API 응답에서 model_id 기반으로 Titan / Mistral on Bedrock / Claude 응답을 분기 처리합니다.
import boto3
from agent_evaluator.decorators import agent_eval
client = boto3.client("bedrock-runtime", region_name="us-east-1")
@agent_eval(monitor, task_type="tool_use", framework="bedrock")
def bedrock_agent(question: str, ground_truth: str = "") -> str:
return client.converse(
modelId="anthropic.claude-3-5-sonnet-20241022-v2:0",
messages=[{"role": "user", "content": [{"text": question}]}],
)
Ollama
ollama.chat() / ollama.generate() 응답의 tool_calls와 prompt_eval_count / eval_count를 추출합니다.
주의: Ollama는 async 미지원입니다.
import ollama
from agent_evaluator.decorators import agent_eval
@agent_eval(monitor, task_type="qa", framework="ollama")
def ollama_agent(question: str, ground_truth: str = "") -> str:
return ollama.chat(
model="llama3.2",
messages=[{"role": "user", "content": question}],
)
AI 프레임워크
DSPy
dspy.Prediction의 _completions 속성에서 체인 단계를 추출합니다.
LM history 전체 multi-step도 지원합니다. 주의: DSPy는 async 미지원입니다.
import dspy
from agent_evaluator.decorators import agent_eval
from agent_evaluator.integrations import dspy_eval
lm = dspy.LM("openai/gpt-4o-mini")
dspy.configure(lm=lm)
@agent_eval(monitor, task_type="qa", framework="dspy")
def dspy_agent(question: str, ground_truth: str = "") -> str:
predictor = dspy.Predict("question -> answer")
return predictor(question=question) # Prediction 객체 → .answer 자동 추출
@dspy_eval(monitor, task_type="qa")
def dspy_agent2(question: str, ground_truth: str = "") -> str:
return dspy.ChainOfThought("question -> answer")(question=question)
PydanticAI
RunResult.all_messages() (우선) 또는 .messages (fallback)에서 체인 단계를 추출합니다.
ToolCallPart / ToolReturnPart / TextPart를 세분화해 추출합니다.
from pydantic_ai import Agent
from agent_evaluator.decorators import agent_eval
from agent_evaluator.integrations import pydanticai_eval
agent = Agent("openai:gpt-4o-mini", system_prompt="...")
@agent_eval(monitor, task_type="qa", framework="pydanticai")
async def pydantic_agent(question: str, ground_truth: str = "") -> str:
result = await agent.run(question)
return result # RunResult 객체 → .data 자동 추출
@pydanticai_eval(monitor, task_type="qa")
async def pydantic_agent2(question: str, ground_truth: str = "") -> str:
return await agent.run(question)
LlamaIndex
Response.source_nodes에서 체인 단계를 추출합니다.
AgentChatResponse.sources의 ToolOutput도 지원합니다.
from llama_index.core import VectorStoreIndex
from agent_evaluator.decorators import agent_eval
index = VectorStoreIndex.from_documents([...])
query_engine = index.as_query_engine()
# source_nodes → chain_steps (score + metadata 포함)
@agent_eval(monitor, task_type="information_retrieval", framework="llamaindex", rag_mode=True)
def llamaindex_agent(question: str, ground_truth: str = "") -> str:
return query_engine.query(question)
Haystack
파이프라인 컴포넌트 출력 dict에서 retriever / generator / reader / embedder / ranker를 chain_steps로 추출합니다.
from haystack import Pipeline
from agent_evaluator.decorators import agent_eval
pipeline = Pipeline()
# ... 컴포넌트 추가 ...
# 컴포넌트 출력 dict → chain_steps
@agent_eval(monitor, task_type="information_retrieval", framework="haystack", rag_mode=True)
def haystack_agent(question: str, ground_truth: str = "") -> str:
return pipeline.run({"query": question})
Semantic Kernel
inner_content에서 OpenAI / Anthropic 백엔드 토큰을 자동 추출합니다.
function_name + plugin_name → "Plugin.function" 형식 툴 호출도 지원합니다.
import semantic_kernel as sk
from agent_evaluator.decorators import agent_eval
kernel = sk.Kernel()
# inner_content → tokens_used (OpenAI/Anthropic 백엔드 자동 감지)
@agent_eval(monitor, task_type="tool_use", framework="semantic_kernel")
async def sk_agent(question: str, ground_truth: str = "") -> str:
result = await kernel.invoke(plugin_name, function_name, input=question)
return str(result)
HuggingFace smolagents
ToolCall 스텝 목록에서 성공/실패 여부와 입력값을 정규화해 tool_calls + chain_steps로 추출합니다.
주의: smolagents는 async 미지원입니다.
from smolagents import CodeAgent, HfApiModel
from agent_evaluator.decorators import agent_eval
model = HfApiModel()
agent = CodeAgent(tools=[...], model=model)
@agent_eval(monitor, task_type="tool_use", framework="smolagents")
def smol_agent(question: str, ground_truth: str = "") -> str:
return agent.run(question)
vLLM
OpenAI 호환 API — choices[0].message.tool_calls와 usage.total_tokens를 추출합니다.
from openai import OpenAI # vLLM은 OpenAI 호환 클라이언트 사용
from agent_evaluator.decorators import agent_eval
client = OpenAI(base_url="http://localhost:8000/v1", api_key="vllm")
@agent_eval(monitor, task_type="qa", framework="vllm")
def vllm_agent(question: str, ground_truth: str = "") -> str:
return client.chat.completions.create(
model="meta-llama/Llama-3.2-3B-Instruct",
messages=[{"role": "user", "content": question}],
)
HuggingFace
pipeline() 결과의 generated_text에서 체인 단계를, actions / tool_calls 필드에서 툴 호출을 추출합니다.
주의: HuggingFace는 async 미지원입니다.
from transformers import pipeline
from agent_evaluator.decorators import agent_eval
pipe = pipeline("text-generation", model="Qwen/Qwen2.5-1.5B-Instruct")
@agent_eval(monitor, task_type="qa", framework="huggingface")
def hf_agent(question: str, ground_truth: str = "") -> str:
return pipe(question, max_new_tokens=200)
자동 감지 (auto_detect_framework=True)
auto_detect_framework=True(기본값)이면 반환 객체의 속성을 검사해 프레임워크를 자동 판별합니다.
| 감지 조건 | 판별 프레임워크 |
|---|---|
stop_reason 속성 존재 (choices 없음) |
anthropic |
choices + usage 속성 존재 |
openai |
candidates + usage_metadata 속성 존재 |
gemini |
meta.tokens 속성 존재 (choices 없음) |
cohere |
x_groq 속성 존재 |
groq |
choices[0].finish_reason == "stop" + mistral 힌트 |
mistral |
ResponseMetadata + bedrock 힌트 |
bedrock |
step_results 속성 존재 |
smolagents |
completions 속성 + DSPy 타입명 |
dspy |
all_messages callable 존재 |
pydanticai |
# framework= 생략 → 자동 감지 (기본값)
@agent_eval(monitor, task_type="qa")
def auto_agent(question: str, ground_truth: str = "") -> str:
return client.chat.completions.create(...) # OpenAI → 자동 "openai" 판별
# 자동 감지 명시적 비활성화 (framework= 고정 우선)
@agent_eval(monitor, task_type="qa", framework="openai", auto_detect_framework=False)
def fixed_agent(question: str, ground_truth: str = "") -> str:
return client.chat.completions.create(...)
25개 지표와 데코레이터 활성화 조건
Layer 1 — 기초 지표 (기본 데코레이터로 자동 활성)
| 지표 | 클래스 | 데코레이터 자동화 | 주요 출력 |
|---|---|---|---|
| Task Completion Rate | TaskCompletionTracker |
항상 활성 | tcr · full_success · partial_success · failures |
| Accuracy | AccuracyEvaluator |
항상 활성 (score_fn 없으면 기본 알고리즘) |
overall_accuracy · median_accuracy · std_accuracy |
| Response Quality | ResponseQualityEvaluator |
response + request 있으면 자동 | dimension_scores · total_score (0–5) · grade |
| Latency | LatencyTracker |
함수 실행 시간 자동 측정 | mean · p50 · p90 · p95 · p99 · std |
| Token Economy | TokenEconomyTracker |
프레임워크 어댑터 자동 추출 | total_tokens · total_cost · estimated_monthly_cost |
| Hallucination | HallucinationDetector |
rag_mode=True 또는 enable_hallucination=True |
hallucination_rate · unsupported_claims_count · by_severity |
Accuracy 계산 방식: Token Overlap(40%) + Jaccard Similarity(30%) + LCS(20%) + 문자 유사도(10%)
Layer 2-A — 에이전틱 지표 (tool_calls · chain_steps 자동 추출 시 활성)
| 지표 | 클래스 | 활성화 조건 | 주요 출력 |
|---|---|---|---|
| Tool Call Analysis | ToolCallAnalyzer |
tool_calls 자동 추출 또는 EvalMetadata |
efficiency_score · redundancy_rate · failure_rate |
| Retry & Correction | RetryCorrectionTracker |
max_retries 파라미터 또는 attempts 필드 |
retry_rate · first_attempt_success_rate · correction_success_rate |
| Tool Selection F1 | ToolSelectionTracker |
expected_tools_arg 파라미터 지정 |
precision · recall · f1_score |
| Agent Coordination | AgentCoordinationTracker |
agent_interactions 자동 추출 |
score · pattern_type · unique_agents |
| Workflow Execution | WorkflowExecutionTracker |
chain_steps · state_transitions 자동 추출 |
step_success_rate · task_success_rate · bottlenecks |
Layer 2-B — 보안 지표 (security_mode=True 또는 Monitor 전역 설정)
| 지표 | 클래스 | 탐지 대상 | 주요 출력 |
|---|---|---|---|
| Input Sanitization | InputSanitizationTracker |
SQL Injection · Command Injection · XSS · Prompt Injection (40개 패턴) | risk_level · threat_count · threat_rate |
| Output Leakage | OutputLeakageDetector |
API 키 · 비밀번호 · 신용카드 · 개인정보 | severity · leakage_count · leakage_rate |
| Tool Authorization | ToolAuthorizationTracker |
비인가 툴 사용 · 위험 파라미터 | compliance_rate · violation_rate · unauthorized_calls |
| Privilege Escalation | PrivilegeEscalationDetector |
guest→admin 권한 상승 체인 | risk_score (0–10) · escalation_detected · escalation_path |
| Tool Chain Attack | ToolChainAttackDetector |
데이터 유출 · 횡적 이동 · 지속성 공격 체인 | confidence (0–1) · attack_types · is_suspicious_chain |
보안 지표 활성화 방법:
# 방법 A: 특정 함수에만 임시 활성 (이 호출만)
@agent_eval(monitor, task_type="qa", security_mode=True)
def secure_agent(question, ground_truth=""): ...
# 방법 B: Monitor 전역 설정 (모든 record_task에 적용)
monitor = PerformanceMonitor("results/", enable_security_metrics=True)
Layer 3 — 하이브리드 평가 (외부 라이브러리)
from agent_evaluator import HybridPerformanceMonitor
monitor = HybridPerformanceMonitor(
use_deepeval=True, # pip install "agent-evaluator[eval]"
use_ragas=True,
output_dir="results/",
)
# HybridPerformanceMonitor는 PerformanceMonitor 상속 — 3종 데코레이터 모두 동일하게 사용
@agent_eval(monitor, task_type="information_retrieval", rag_mode=True, context_arg="context")
def rag_agent(question, context="", ground_truth=""): ...
| 제공자 | 지표 | 조건 |
|---|---|---|
| DeepEval | G-Eval · Hallucination · Toxicity · Bias · Answer Relevancy | pip install "agent-evaluator[eval]" |
| Ragas | Faithfulness · Answer Relevancy · Context Precision · Context Recall | 동일 + context 필드 필요 |
| LangSmith | Latency · Token · Feedback | LANGSMITH_API_KEY 환경변수 |
CI/CD 품질 게이팅
코드에서 직접
eval = QuickEval("results/")
@eval.qa
def agent(question, ground_truth=""): ...
# 평가 실행 후
eval.gate(tcr=85, accuracy=70, quality=3.5, hallucination=5)
# 임계값 미달 시 sys.exit(1) — CI 파이프라인 실패 처리
CLI (GitHub Actions)
- name: Run Evaluation
run: python eval_suite.py --output results/ci.json
- name: Quality Gate
run: |
agent-eval gate results/ci.json \
--tcr 85 --accuracy 70 --p95-latency 3.0 --hallucination 5
agent-eval gate 옵션:
| 옵션 | 설명 |
|---|---|
--tcr N |
Task Completion Rate 최소값 (%) |
--accuracy N |
정확도 최소값 (%) |
--p95-latency N |
P95 지연시간 최대값 (초) |
--hallucination N |
환각 탐지율 최대값 (%) |
--llm-judge N |
LLM Judge 종합 점수 최소값 (0–5) |
--fail-on-regression N |
이전 기준선 대비 허용 하락 비율 (%) |
--junit-xml PATH |
JUnit XML 출력 (CI 연동) |
종료 코드: 0 = 전체 통과 / 1 = 임계값 미달 / 2 = 회귀 감지
조건부 알림
3종 데코레이터 모두 동일한 alert_rules= API를 지원합니다.
from agent_evaluator.decorators import AlertRuleBuilder
slow_rule = AlertRuleBuilder.when_latency_above(3.0, handler=lambda msg, tr: print(f"[SLOW] {msg}"))
error_rule = AlertRuleBuilder.when_accuracy_below(0.7, handler=lambda msg, tr: send_slack(msg))
fail_rule = AlertRuleBuilder.when_completion_below(0.8, handler=lambda msg, tr: send_alert(msg))
# 3종 데코레이터 모두 동일하게 적용
@agent_eval(monitor, task_type="qa", alert_rules=[slow_rule, error_rule])
def agent(question, ground_truth=""): ...
@batch_eval(monitor, task_type="qa", alert_rules=[slow_rule])
def batch_agent(questions, ground_truths=None): ...
@conversation_eval(monitor, max_turns=5, alert_rules=[fail_rule])
def chat(question, session_id="s1"): ...
주기적 자동 저장 (flush_every)
프로세스가 중간에 종료되어도 결과가 보존됩니다. 3종 데코레이터 모두 지원합니다.
@agent_eval(monitor, task_type="qa", flush_every=10, flush_filename="checkpoint")
def agent(question, ground_truth=""): ...
@batch_eval(monitor, task_type="qa", flush_every=5, flush_filename="batch_cp")
def batch_agent(questions, ground_truths=None): ...
# QuickEval에서도 동일
eval = QuickEval("results/", auto_save=True, auto_save_interval=10)
preset — 환경별 설정 묶음
3종 데코레이터 모두 동일한 preset= 파라미터를 지원합니다.
| preset | 자동 적용 설정 | 환경 |
|---|---|---|
"production" |
flush_every=50 · enable_anomaly_detection=True · sample_rate=0.1 |
운영 서버 |
"development" |
enable_llm_judge=True · auto_detect_framework=True |
개발·디버깅 |
"testing" |
sample_rate=1.0 · timeout=10.0 |
단위 테스트 |
"canary" |
sample_rate=0.01 · flush_every=100 |
카나리 배포 |
@agent_eval(monitor, task_type="qa", preset="production")
@batch_eval(monitor, task_type="qa", preset="testing")
@conversation_eval(monitor, max_turns=5, preset="development")
CLI 명령어
| 명령어 | 설명 |
|---|---|
agent-eval init |
대화형 API 키 설정 마법사 |
agent-eval check |
현재 설정 상태 및 API 키 확인 |
agent-eval dashboard [dir] |
FastAPI 대시보드 웹 서버 실행 |
agent-eval gate <result.json> |
CI/CD 품질 게이팅 |
agent-eval dataset build <dir> |
운영 결과에서 골든 데이터셋 자동 추출 |
agent-eval monitor |
Arize Phoenix + OTEL 실시간 모니터링 |
agent-eval --version |
패키지 버전 출력 |
평가 결과 시각화
FastAPI 대시보드
pip install "agent-evaluator[serve]"
agent-eval dashboard results/ --watch # 파일 변경 시 자동 갱신
| URL | 내용 |
|---|---|
http://localhost:8765 |
메인 대시보드 |
http://localhost:8765/slides |
발표용 슬라이드 뷰 |
http://localhost:8765/api/docs |
Swagger API 문서 |
Phoenix 실시간 모니터링
pip install "agent-evaluator[otel]"
agent-eval monitor # http://localhost:6006
에이전트 실행 시 OTLP 스팬이 자동 전송됩니다. Tracing · Evaluators · Datasets · Prompts 4개 메뉴에서 실시간 확인 가능합니다.
공개 API
from agent_evaluator import (
PerformanceMonitor, # 평가 오케스트레이터
QuickEval, # 원스톱 Facade
HybridPerformanceMonitor, # Layer 3 포함 모니터
TaskResult, TaskType, EvaluationReport,
create_taskresult,
evaluation_session, async_evaluation_session,
ConversationSession, ConversationMetrics, ConversationTurn,
LLMJudge,
SimpleTaskAlertRule, AlertRuleBuilder,
)
from agent_evaluator.decorators import (
# ── 3종 핵심 데코레이터 ──────────────────
agent_eval, # 단일 태스크 (1호출 → 1 TaskResult)
batch_eval, # 배치 평가 (1호출 → N TaskResult)
conversation_eval, # 멀티턴 대화 (N호출 → 1 TaskResult)
# ── 통합 팩토리 & 탈출구 ─────────────────
EvalDecorator, # 3종 공통 설정 팩토리
eval_context, # 데코레이터 불가 시 컨텍스트 매니저
# ── 메타데이터 & 유틸리티 ────────────────
EvalMetadata, # agent_eval / batch_eval 추가 메타데이터
TurnMetadata, # conversation_eval 턴별 메타데이터
get_eval_ctx, # 스레드 로컬 평가 컨텍스트 접근
FrameworkLiteral, # 21개 프레임워크 타입 힌트
get_framework_info, # 프레임워크 어댑터 정보 조회
AlertRuleBuilder, # 알림 규칙 팩토리
flush_conversation, # 대화 세션 수동 종료
flush_all_conversations,
)
예제 가이드
cd Evaluator_Examples
# ── 3종 데코레이터 핵심 예제 ─────────────────────────────────
python 18_decorator_eval.py # @agent_eval 기본 예제
python 19_decorator_coverage_expanded.py # 3종 데코레이터 커버리지 검증
python 20_quickeval_demo.py # QuickEval 원스톱 Facade (7섹션)
python 21_layer2_agentic_eval.py # Layer 2 Agentic 활성화 가이드
# ── Layer별 지표 검증 ─────────────────────────────────────────
python 01_quality_eval.py # @agent_eval — Accuracy · Hallucination · Quality
python 02_performance_eval.py # @agent_eval — TCR · Latency · Token Economy
python 03_agentic_eval.py # @agent_eval — Tool · Coordination · Workflow
python 04_security_eval.py # @agent_eval — 보안 5종
python 05_hybrid_eval.py # @batch_eval + HybridPerformanceMonitor — DeepEval · Ragas
# ── 프레임워크별 어댑터 ──────────────────────────────────────
python 06_langchain_eval.py # @agent_eval(framework="langchain")
python 07_langgraph_eval.py # @agent_eval(framework="langgraph")
python 08_crewai_eval.py # @agent_eval(framework="crewai")
python 09_autogen_eval.py # @agent_eval(framework="autogen")
python 10_cross_framework_eval.py # @batch_eval + 멀티 프레임워크 비교
# ── 고급 기능 ────────────────────────────────────────────────
python 11_streaming_eval.py # StreamingEvaluator — 실시간 슬라이딩 윈도우 + ImplicitFeedback
python 12_alerting_eval.py # @agent_eval(alert_rules=[...]) + AlertEngine 패턴 비교
python 13_golden_set_build.py # @batch_eval — 골든 데이터셋 빌더
python 14_anomaly_cost_eval.py # @agent_eval(flush_every=10) — 이상 감지 + 비용 추적
python 15_conversation_eval.py # @conversation_eval
python 16_dashboard_demo.py # save_to_file + Phoenix OTEL 대시보드 연동
python 17_phoenix_verification.py # @agent_eval + Phoenix 4개 메뉴 통합 검증
# ── 인프라 ───────────────────────────────────────────────────
agent-eval monitor # Phoenix 서버 기동 (http://localhost:6006)
agent-eval dashboard --watch # 대시보드 (http://localhost:8765)
프로젝트 구조
agent-evaluator/
├── agent_evaluator/
│ ├── decorators.py # agent_eval · batch_eval · conversation_eval
│ │ # EvalDecorator · eval_context · EvalMetadata · TurnMetadata
│ ├── quick_eval.py # QuickEval — 원스톱 Facade
│ ├── core/
│ │ ├── trackers/
│ │ │ ├── base.py # TaskResult · EvaluationReport · TaskType
│ │ │ ├── layer1.py # Foundation 지표 6종
│ │ │ ├── layer2.py # Agentic 지표 5종
│ │ │ ├── security.py # 보안 지표 5종
│ │ │ ├── monitor.py # PerformanceMonitor (오케스트레이터)
│ │ │ ├── conversation.py # ConversationSession · ConversationMetrics
│ │ │ └── feedback.py # ImplicitFeedbackTracker
│ │ ├── otel/ # OpenTelemetry 통합 ([otel] extras)
│ │ ├── hybrid_monitor.py # HybridPerformanceMonitor
│ │ └── monitor_context.py # evaluation_session · async_evaluation_session
│ ├── integrations/
│ │ ├── llm_judge.py # LLMJudge
│ │ └── metric_adapters.py # DeepEval · Ragas · LangSmith 어댑터
│ ├── serve/ # FastAPI 대시보드 ([serve] extras)
│ ├── cli/ # agent-eval CLI
│ ├── alerts/ # AlertEngine · SimpleTaskAlertRule
│ ├── anomaly/ # AnomalyDetector
│ ├── cost/ # CostTracker · AdaptivePolicy
│ └── datasets/ # GoldenSetBuilder
│
├── Evaluator_Examples/ # 예제 21개
├── tests/ # 1,823개 테스트 함수, 59개 파일
└── pyproject.toml
요구사항
| 패키지 | 버전 | 용도 |
|---|---|---|
numpy |
>=1.20.0, <3.0.0 | 수치 연산 |
pandas |
>=1.3.0, <4.0.0 | 지표 집계 |
python-dotenv |
>=0.19.0, <2.0.0 | 환경변수 관리 |
| Extra | 패키지 | 속도 |
|---|---|---|
[llm] |
openai · anthropic | 빠름 |
[langchain] |
langchain ≥1.0 · langgraph ≥1.0 | 중간 |
[crewai] |
crewai ≥1.0 | 무거움 (단독 격리) |
[autogen] |
pyautogen ≥0.3 | 무거움 (단독 격리) |
[eval] |
deepeval · ragas ≥0.4 · datasets ≥4.0 | 무거움 |
[serve] |
fastapi · uvicorn · jinja2 | 빠름 |
[otel] |
opentelemetry-sdk · arize-phoenix | 중간 |
[all] |
llm + langchain + eval + serve (권장) | 중간 |
[full] |
전체 ⚠️ 10분+ | 매우 무거움 |
개발 환경
git clone https://github.com/bullpeng72/Agent-Evaluator.git
cd Agent-Evaluator
pip install -e ".[dev]"
pytest # 테스트 실행 (1,823개)
ruff check agent_evaluator/ # 린트
ruff format agent_evaluator/ # 포맷
mypy agent_evaluator/ # 타입 검사
변경 이력
v0.7.4 (2026-04-08) — 전체 예제 데코레이터 적용 완료 · layer1 버그 수정 · 문서 현행화
- ✨ 예제 19/21
@agent_eval/@batch_eval/@conversation_eval전면 적용 (02, 03, 17 추가 완성) - 🐛
layer1.py성능 지표 계산 버그 수정 - 🔧 대시보드 템플릿(
dashboard.html.j2등) 마이너 개선 - 📝 테스트 파일 수 60→59 반영, Docs/ 버전·날짜 갱신
- ✅ 21개 예제 전수 실행 검증 완료
v0.7.3 (2026-04-07) — 보안 트래커 실동작 · 커버리지 전면 확대 · Phoenix 통합 완성
- 보안 메트릭 실동작 —
record_task()에서 5개 보안 트래커 누락 호출 버그 수정 (CRITICAL) - 프레임워크 어댑터 확대 — AutoGen
agent_interactions/state_transitions; Haystack/SKtool_calls; PydanticAI/LlamaIndextool_calls; CrewAIstate_transitions - Phoenix 통합 완성 — Prompts 탭(
llm.prompts) + Datasets 탭(dataset.id) +ae.tool_namesspan 속성 추가 - 대시보드 API —
security_incidents_count·has_multimodal·multimodal_task_count목록뷰 노출
v0.7.2 (2026-04-05) — 3종 데코레이터 API 완성 · 21개 프레임워크 어댑터 · 대시보드 API 확장
- 3종 데코레이터 API 완성 —
agent_eval/batch_eval/conversation_eval/EvalDecorator파라미터 일관성 확보;alert_rules·flush_every·preset3종 공통 적용 - 21개 프레임워크 어댑터 —
auto_detect_framework=True기본 활성;FrameworkLiteral타입 힌트;_FRAMEWORK_ADAPTER_META레지스트리 preset파라미터 —production/development/testing/canary3종 데코레이터 공통 지원AlertRuleBuilder—when_accuracy_below()·when_latency_above()·when_completion_below()·when_error()·when_tool_calls_exceed()5개 팩토리 메서드- 대시보드 API 확장 — 50+ 엔드포인트 (필터링 · 집계 · 시계열 · 비교 · 랭킹)
v0.7.1 (2026-04-03) — QuickEval · SimpleTaskAlertRule · DSPy/PydanticAI 통합
QuickEval— 3종 데코레이터 원스톱 Facade;for_rag()·for_security()·for_llm_judge()팩토리SimpleTaskAlertRule— StreamingEvaluator 없이 동작하는 경량 알림; 3종 데코레이터에alert_rules=통합flush_every— 3종 데코레이터 공통 N건마다save_to_file()자동 실행- DSPy / PydanticAI 통합 —
[dspy]·[pydanticai]extras 추가
v0.7.0 (2026-04-01) — Phoenix + OTEL 실시간 모니터링
agent-eval monitorCLI — Arize Phoenix 서버 기동 + OTLP 스팬 수신setup_otel()공개 API;[otel]extras 신규
v0.6.x (2026-03-21 ~ 04-01) — SDK 안정화 · 프레임워크 통합 · 대시보드
- LangChain / LangGraph / CrewAI / AutoGen 4개 완전 지원
- FastAPI 대시보드 · LLMJudge · ConversationSession · Ragas 0.4.x 지원
v0.2.x – v0.5.x — 초기 구현
- Layer 1/2/3 트래커 25개 ·
ConversationSession·evaluation_session초기 구현
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_evaluator-0.7.4.tar.gz.
File metadata
- Download URL: agent_evaluator-0.7.4.tar.gz
- Upload date:
- Size: 704.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c43e17b31f65a81b4e1789e0c51675e49ee7f10b0820b810cafe690a127930b
|
|
| MD5 |
a31fb16c1aea5dd5d356242943f782d2
|
|
| BLAKE2b-256 |
4f9e44d0606df9b43489a5e6a773a937a11fd362b12d50e75e07f77d0bd95e6b
|
File details
Details for the file agent_evaluator-0.7.4-py3-none-any.whl.
File metadata
- Download URL: agent_evaluator-0.7.4-py3-none-any.whl
- Upload date:
- Size: 738.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8fb21121be20b9b7ac4ef6a340aea7e518872804dbc6e86b5d93478636a11d3f
|
|
| MD5 |
4c60111d93da8ca43ed037ce0d6b1340
|
|
| BLAKE2b-256 |
4cc8f4a12c96cdbbbfc9ae4dbb74aa49607f0dfda1c7bcc95442d4714379e465
|