evalmine
evalmine
리더보드 점수는 모델 변경이 실제로 운영하는 40여 개 태스크에 어떻게 반영될지 예측한 적이 없습니다. 어떤 모델이 벤치마크 1위를 차지해서 교체했더니, 정작 의존하던 작업에서는 조용히 성능이 떨어지는 경우가 있습니다.
evalmine은 모델 변경에 대해 여러분의 태스크에서 한 가지 질문에 답합니다: 도움이 되었는가, 해가 되었는가, 아니면 같은 결과에 비용만 더 드는가? 여러분이 YAML 스위트(suite)로 태스크를 작성합니다. 이 도구는 두 개 이상의 모델에 걸쳐 태스크를 실행하고, 각 답변을 스키마 검사하고, 시간을 재고, LLM 심사자가 두 순서로 답변을 쌍별 비교하도록 하여 심사자가 먼저 보는 쪽을 선호하는 편향이 상쇄되게 합니다. 그 심사자를 여러분의 선호 라벨과 Cohen's kappa로 평가하고, 심사자가 여러분과 일치한다는 것을 보여주지 못하면 승률을 헤드라인으로 내세우기를 거부합니다. 비용은 특정 날짜에 고정된 가격표에서 산출되며, 알 수 없는 모델은 $0로 계산되는 대신 실행을 실패시킵니다. 보고서는 스위트 해시로 버전 관리되며, 세 가지 도구를 제공하는 MCP 서버로 에이전트가 작업 중간에 평가를 실행할 수 있습니다.
여기 예제 스위트를 가짜 어댑터(fake adapter)로 실행한 결과: 12개 라벨에 대한 kappa 0.25는 0.40 하한선 아래이므로, 0.463 승률은 헤드라인이 아닌 플래그 표시로 출력됩니다. 그 거부가 바로 이 도구가 작동한다는 증거입니다:
$ evalmine run examples/everyday-eight.yaml \
--models anthropic/claude-haiku-4-5,google/gemini-2.5-flash --fake
run 20260823T210009Z_c4545e4e_dbc76614 (everyday-eight)
report: reports/everyday-eight/20260823T210009Z_c4545e4e_dbc76614/report.md
calibration: below_floor - kappa 0.25 (fair) over 12 labels - headline eligible: false
google/gemini-2.5-flash vs anthropic/claude-haiku-4-5: win-rate 0.463 (UNCALIBRATED) [0.325-0.613] over schema-passing pairs only, n=20 - flips 3 - excluded 0
cost: $0.0658 this run (answers $0.0081, judge $0.0578); if uncached $0.0658가짜 어댑터는 결정론적이므로, 위 수치는 깨끗한 체크아웃에서 정확히 재현됩니다. 위 어디에서도 제공자에 접속하거나 비용을 지출하지 않았습니다.

그 프레임의 모든 장면은 실제 실행입니다. vhs docs/demo.tape로 다시 녹화하세요 (vhs, brew install vhs).
상태. v0.1.0, 사전 릴리스. 핵심, 세 가지 제공자 어댑터, 실행 검사 및 MCP 표면은 구현되어 테스트되었습니다; 가격표는 고정된 날짜에 각 제공자의 공개 가격 페이지와 대조 검증되었습니다. 아직 결정 로그 항목은 없습니다 — 아직 안 된 것 참조.
명세: docs/spec.md. 코드가 작성된 기준이 되는 계약이며, README와 충돌할 경우 명세가 우선합니다. 작동 방식에 대한 심층 설명: docs/learning/how-it-works.md (스타일 적용 HTML 렌더링).
빠른 시작
git clone https://github.com/hishamalward/evalmine.git && cd evalmine
python -m venv .venv && . .venv/bin/activate
pip install -e ".[dev]" # add ,mcp -> ".[dev,mcp]" for the MCP serverPython 3.10 이상. 런타임 의존성 세 가지: PyYAML, jsonschema, httpx.
비용 없이 스위트를 검사합니다. validate는 파일을 파싱하고, JSON Schema를 적용하고, 모든 프롬프트를 렌더링하며(일치하지 않는 {{placeholder}}는 하드 오류), 모든 모델 문자열을 가격표에 대해 확인합니다. 네트워크 호출은 0회입니다.
evalmine validate examples/everyday-eight.yaml
# ok: examples/everyday-eight.yaml - 8 tasks, 20 cases, 12 labels; every prompt
# rendered; 3 model strings resolved against prices-2026-08-23.yaml가짜 어댑터로 실행합니다. --fake는 모든 모델 문자열을 내장 결정론적 어댑터로 라우팅합니다: 키 없음, 네트워크 없음, 지출 없음. 아래 두 모델 문자열은 예제 스위트의 12개 인간 라벨이 가리키는 것들이므로, 이 실행은 보정 경로를 끝까지 테스트합니다.
evalmine run examples/everyday-eight.yaml \
--models anthropic/claude-haiku-4-5,google/gemini-2.5-flash --fake실제로 실행합니다. 키는 환경 변수에서만 가져옵니다. .env.example를 복사하고, 저장소 밖에서 채우고, 필요한 것을 export하세요.
export ANTHROPIC_API_KEY=...
export GOOGLE_API_KEY=...
evalmine run examples/everyday-eight.yaml \
--models anthropic/claude-haiku-4-5,google/gemini-2.5-flash \
--max-cost 0.50첫 실시간 호출 전에 사전 점검 비용 추정이 실행됩니다. --max-cost를 초과하면 실행이 거부되고(종료 코드 4) 아무것도 지출되지 않습니다. 어디에도 상한이 없으면 CLI 기본값은 $2.00입니다. 모든 호출은 콘텐츠 해시로 디스크에 캐시되므로 재실행은 무료이고 보고서는 재현 가능합니다; --no-cache는 새 호출을 강제하면서도 여전히 캐시에 기록합니다.
기타 명령: evalmine prices [--for suite.yaml], evalmine last suite.yaml, evalmine report <run-id>, evalmine compare <report_a> <report_b>.
Related MCP server: Coval MCP Server
스위트 파일
하나의 YAML 파일에 태스크, 심사자 구성, 라벨이 들어 있습니다. 제공되는 예제는 examples/everyday-eight.yaml입니다: 20개 케이스에 걸친 8개의 가상 태스크(재작성, 추출, 분류, 설명, 작은 코드 변경), 그중 3개는 출력 스키마를 가지며, 12개의 선호 라벨이 있습니다. 전체 스키마는 명세 §5에 있으며, 형태는 다음과 같습니다:
suite: everyday-eight
version: 1
defaults: { temperature: 0, max_tokens: 700, timeout_s: 60 }
limits: { max_cost_usd: 1.50 }
judge:
model: anthropic/claude-sonnet-4-6
rubric: |
Prefer the answer that a competent colleague would ship without editing.
...
calibration: { min_kappa: 0.40, min_labels: 10, on_below_floor: flag }
tasks:
- id: ticket-triage
kind: classify # a free label, used only to group report rows
prompt: |
Classify this support ticket. Return JSON only.
Ticket:
{{ticket}}
schema: { type: object, required: [category, severity], ... }
rubric: | # appended to the suite rubric for this task
In addition to the suite rubric: ...
cases:
- id: charged-twice
vars: { ticket: "I was charged twice this month..." }
labels:
- { task: ticket-triage, case: charged-twice,
baseline: anthropic/claude-haiku-4-5,
candidate: google/gemini-2.5-flash,
prefer: candidate, note: "team-wide lockout is high, not medium" }이 파일에 대해 의도적으로 설계된 세 가지:
템플릿은 Jinja가 아닙니다. 정확히
{{name}}형태, 한 번만 치환되며, 표현식이나 필터가 없습니다. 일치하는 변수가 없는 플레이스홀더는 로드 시 하드 오류입니다. 조용히 빈 변수가 되는 것은 평가를 조용히 무의미하게 만드는 가장 쉬운 방법이기 때문입니다.알 수 없는 키는 오류입니다. 모든 수준에서 그렇습니다. 오타 난
rubrik:이 무시되면 멀쩡해 보이지만 아무 의미 없는 보고서가 생성됩니다.labels는 이 도구의 신뢰성의 원천입니다. 승률을 보기 전에 기록된 여러분의 판단이며, 심사자는 이에 대해 점수를 받습니다. 라벨이 없는 스위트도 실행은 됩니다; 다만 헤드라인 숫자를 만들 수 없을 뿐입니다.
예제를 여러분의 태스크로 교체하세요. 그것이 이 도구의 존재 이유입니다.
코드 태스크에 대한 실행 검사
프로즈(prose)는 실제로 실행되는 코드의 좋은 대리자가 아닙니다. 케이스는 check를 선언할 수 있습니다: 답변의 코드를 받아($ANSWER는 파일, $ANSWER_TEXT는 텍스트) 작동하면 0으로 종료하는 bash 스니펫입니다. 새 임시 디렉터리에서 타임아웃 하에 실행되며, 환경에서 비밀이 제거되고, 절대 캐시되지 않습니다. 답변의 모든 펜스 블록이 순서대로 각각 자체 픽스처에서 실행됩니다; 마지막 블록이 판정이고 이전 블록들은 그 옆에 기록되므로, 잘못된 블록을 철회하고 두 번째 블록을 작성한 답변은 두 번째 블록으로 점수가 매겨지고 철회가 표시됩니다.
- id: jq-remote
vars: { task: "Write a jq filter ... the JSON is in postings.json" }
check:
setup: 'printf "[{\"t\":\"a\",\"remote\":true}]" > postings.json'
run: 'jq -r "$(cat "$ANSWER")" postings.json | grep -q a'결과 — 통과/실패, 종료 코드, 출력 — 는 answers.jsonl, 스코어카드, HTML 쌍 보기에 답변 옆에 표시되며, 심사자에게는 한 가지 고정 규칙과 함께 제시됩니다: 검사에 실패한 답변은 통과한 답변을 이길 수 없습니다. 명세 §6.6.
보고서 읽는 방법
reports/<suite>/<run-id>/report.md와 함께 report.json, report.html, answers.jsonl, pairs.jsonl이 있습니다. 다음 순서로 읽으세요.
1. 보정(calibration)부터. 의도적으로 승률 위에 인쇄됩니다. 심사자의 판정과 여러분의 라벨 사이의 Cohen's kappa와 Landis-Koch 밴드 이름, 그리고 그 아래 3x3 혼동 행렬을 확인하세요. 단순 일치율 대신 kappa를 쓰는 이유는 한 범주가 지배하면 일치율이 부풀려지기 때문이며, 실제로 그렇게 됩니다: 심사자는 무승부가 안전하다는 것을 배웁니다. 행렬은 심사자가 어떻게 틀렸는지 알려주며, 이것이 중요합니다 — 여러분이 무승부라고 할 때 절대 "무승부"라고 하지 않는 심사자와 체계적으로 새로운 쪽을 선호하는 심사자는 다른 문제입니다. 그 아래의 태스크별 분석은 어디서 틀렸는지 알려줍니다: 하나의 kappa는 재작성 태스크에서는 훌륭하고 분류 태스크에서는 쓸모없는 심사자를 숨길 수 있으며, 평균은 여러분이 놓칠 결과입니다.
2. 신뢰해서는 안 되는 승률. 세 가지 조건 중 하나라도 해당되면 충분합니다:
headline_eligible: false— kappa가 하한선 아래이거나, 라벨이 너무 적거나, 두 평가자가 한 범주만 사용하여 kappa가 정의되지 않은 경우입니다. 보고서는 그 숫자가 헤드라인이 되는 것을 금지하고, 모든 수치에 단검(dagger) 표시를 하며, JSON과 모든 MCP 응답에도 동일한 플래그가 포함되어, 요약을 읽는 에이전트가 주의 사항 없이 숫자를 인용할 수 없습니다.플립률 0.30 초과. 플립은 두 답변의 위치가 바뀌었을 때 심사자가 답을 바꾼 쌍입니다. 약 1/3을 넘으면 승률은 품질이 아니라 제시 순서를 측정하는 것입니다. 보고서는 같은 표에 이를 명시합니다.
작은
n, 또는 줄어드는n. 승률은 스키마 통과 쌍에 대해서만 계산됩니다: 어느 한쪽이 파싱에 실패하거나 스키마에 실패한 쌍은 패배로 처리되지 않고 제외됩니다. 따라서 JSON 생성을 못하는 모델이 형식 실패로 품질 비교에서 지지 않습니다. 대가는n이 줄어든다는 것이며, 그래서 섹션 제목이 "스키마 통과 쌍에 대해서만, n=…"이고n이 같은 화면의 스키마 통과율 없이는 절대 인쇄되지 않는 이유입니다.
숫자를 발표하기 전에 min_kappa를 0.60으로 올리세요. 기본값은 0.40입니다 — 공정~중간 일치의 관례적 하한으로, 라벨이 12개뿐인 첫 스위트가 통과할 수 있을 만큼 낮습니다. 그것은 자신이 라벨링 과정을 기억하면서 숫자를 스스로 사용하기 위한 하한입니다. 0.60 — "상당한(substantial)" — 은 그 기억이 전달되지 않는 다른 사람에게 숫자를 말하기 위한 하한입니다. 이 도구는 첫 스위트를 두 번 실행할 가치가 있도록 관대하게 배포되며; 이 권장 사항은 첫 스위트가 블로그 게시물에 실리지 않도록 하기 위한 것입니다.
3. 그다음 스코어카드, 그리고 비용은 품질과 함께 읽지, 품질 다음에 읽지 마세요. 스키마 통과율(제공자가 스키마를 강제하는 경우 native, 요청만 받은 경우 prompted로 표시 — 둘은 같은 측정이 아니기 때문), 태스크가 실행 검사를 선언한 경우 실행 통과율과 그 n, p50 및 p95 지연 시간과 그 n, 이번 실행 비용과 캐시되지 않았을 때의 비용. 0.55 승률을 3배 비용으로 얻는 후보와 절반 비용으로 얻는 후보는 다른 결정입니다.
4. 태스크별 표, 최악부터 정렬. 헤드라인 승률은 그대로인데 세 개 태스크가 반대 방향으로 0.4씩 움직였다면, 그것이 놓치게 될 결과입니다. evalmine compare A B는 두 실행 사이의 정확히 그 변동 항목들을 출력합니다.
5. report.html과 라벨링 흐름. 모든 실행은 자체 포함 페이지 하나도 작성합니다 — 서버 없음, 의존성 없음, file:// 경로로 열림. 동일한 섹션에 더해, 각 판정 쌍이 모델 이름이 숨겨지고 심사자의 판정이 접혀 있는 상태로 나란히 표시되어, 심사자가 읽은 그대로 답변을 읽을 수 있습니다. 각 쌍 아래에 A 선호 · 무승부 · B 선호가 있고, 라벨 YAML 복사는 스위트에 붙여넣을 labels: 항목을 제공합니다: 30분 수동 편집 대신 10분 클릭으로, 이것이 성장하는 보정 세트와 그렇지 않은 세트의 차이입니다.
보고서에는 형용사가 없고 권장 사항도 없습니다. 판단은 DECISIONS.md에 여러분의 판정으로 작성되며 — 보고서는 매 실행마다 하단에 템플릿을 미리 채워줍니다.
MCP
evalmine-mcp는 정확히 세 가지 도구를 노출하는 stdio MCP 서버로, CLI가 호출하는 것과 동일한 core.py 함수를 호출합니다:
도구 | 기능 | 지출 |
| 스위트를 실행하고 요약과 보고서 경로를 반환 | 상한까지 |
| 두 보고서 간의 차이 | 없음 |
| 스위트의 가장 최근 보고서 | 없음 |
.mcp.json.example을 .mcp.json으로 복사하여 등록하세요. 먼저 엑스트라를 설치하세요: pip install -e ".[mcp]".
핵심은 에이전트가 작업 중간에 평가를 실행할 수 있다는 것입니다 — "이 파일에서 모델을 교체하기 전에 스위트를 실행하고 승률을 알려줘" — 사람이 나중에 보고서를 읽는 대신에 말입니다.
전체 CLI가 아닌 세 가지 도구만 있는 이유는 에이전트용 표면은 결정을 지원하는 가장 작은 동사 집합이어야 하고, 추가 도구 하나마다 아무도 승인하지 않은 돈을 지출하는 또 다른 경로가 되기 때문입니다.
상한, 그리고 에이전트 기본값이 여러분보다 낮은 이유. 상한은 MCP가 재구현하는 CLI 플래그가 아니라 core.run_suite()의 매개변수입니다: 돈을 지출할 수 있는 곳은 정확히 한 곳이며, 그곳에서 상한이 적용됩니다. 에이전트가 max_cost를 제공하면 그것이 사용되지만, EVALMINE_MCP_MAX_COST_CEILING(기본 $5.00)을 초과하는 요청은 클램프되어 실행되는 대신 outright 거부됩니다. 에이전트가 생략하면 상한은 min(suite.limits.max_cost_usd, EVALMINE_MCP_MAX_COST)이며, 기본 $1.00 — CLI의 $2.00의 절반입니다. CLI에서 숫자를 입력한 것은 사람이고 에이전트는 아니기 때문입니다. 상한 초과 실행은 구조화된 거부를 반환하고, 아무것도 지출하지 않으며, 맞추기 위해 조용히 잘리지 않습니다; 잘린 실행은 완전한 것처럼 보이는 더 작은 숫자를 만듭니다.
run_suite는 요약과 경로를 반환하며, 원시 공급자 응답은 절대 반환하지 않습니다. 원시 응답은 디스크의 answers.jsonl에 남아 있습니다. 모든 답변을 에이전트의 컨텍스트로 다시 스트리밍하는 도구는 호출자에게 평가보다 더 많은 비용을 발생시키며, 평가 하네스를 프롬프트에 있는 모든 것에 대한 유출 경로로 바꿔버립니다. suite_path는 또한 EVALMINE_MCP_SUITE_ROOT(기본값: 서버의 작업 디렉터리) 내부에서 해석되어야 합니다.
기존 도구
promptfoo와 Braintrust가 여기서 가장 확실한 도구이며, 둘 다 이 도구보다 훨씬 더 강력합니다.
promptfoo는 훨씬 더 많은 어서션 유형, 웹 뷰어, 레드팀 기능, 그리고 세 개가 아닌 공급자 커버리지를 갖추고 있습니다. Braintrust는 호스팅 플랫폼입니다: 트레이싱, 프로덕션 로그에서 구축된 데이터셋, 실제 UI, 협업, 그리고 누군가의 제품이라는 데서 오는 운영 성숙도를 제공합니다. 폭넓은 기능을 원하거나, 같은 수치를 보는 팀이 있다면 그 중 하나를 사용하세요.
evalmine은 세 가지 더 좁은 이유로 존재합니다.
판정자는 사용자에 맞게 보정되거나, 그 숫자는 출력되지 않습니다. 위 두 도구 모두 LLM 판정자로 점수를 매길 수 있습니다. 하지만 어느 쪽도 사용자의 라벨에 대한 보정을 승률이 인용 가능한지의 관문으로 삼지 않습니다. 그 역전 — 거부가 기본값이라는 것 — 이 전체 논지이며, 어차피 숫자를 출력하는 도구에 덧붙일 수 있는 기능이 아닙니다.
결정 로그는 일급 산출물입니다. 평가의 출력은 숫자가 아니라, 6개월 후에 방어해야 할 결정입니다.
DECISIONS.md는 보고서에 의해 미리 채워지고 사람이 작성하며, 결정의 대상이었던 코드 옆에 있는 저장소에 존재합니다.표면은 한 번에 읽을 수 있을 만큼 작습니다. 네 개의 어댑터, 보고서, 실행 검사를 포함해 약 6,000줄입니다. LLM 프레임워크도, 공급자 SDK도 없습니다 — 문서화된 JSON 엔드포인트에 대한 세 개의 직접 작성한 POST만 있습니다. 그 비용은 실재하며 언급할 가치가 있습니다: 공급자가 API를 변경하면, 우리는 업그레이드가 아니라 고장을 통해 알게 됩니다.
이 세 가지가 중요하지 않다면, 정직한 추천은 promptfoo입니다.
아직 미구현
v0.1.0의 범위를 벗어나며, README가 직접 발견하도록 두지 않고 명시합니다: RAG 또는 검색 평가; 에이전트 또는 다중 턴 궤적; 파인튜닝; 웹 UI; 호스팅 서비스; 세 개 이상의 공급자; 루브릭 자동 생성; 위 세 가지를 넘어서는 MCP 도구.
이 README의 모든 숫자는 가상의 예제 스위트에 대한 가짜 어댑터에서 나온 것입니다. 실제 스위트에 대한 라벨링된 실행은 아직 보정된 숫자나 DECISIONS.md 항목을 생성하지 않았습니다; 그것은 v0.1.0 태그 이전에 이루어질 것입니다.
개발
pip install -e ".[dev,mcp]"
python -m pytest -q # 310 tests, none of which make a network call
python -m ruff check src testsCI는 {ubuntu, macos, windows} x {3.10, 3.13}에서 실행되며, 모든 조합이 모든 테스트를 실행하고, 작업 트리 및 전체 git 히스토리에 대한 비밀 스캔도 수행합니다. 이 저장소에는 어떤 API 키도 있어서는 안 되며, evalmine run은 스위트 파일에 알려진 키 접두사와 일치하는 문자열이 포함된 경우 시작을 거부합니다.
CONTRIBUTING.md를 참조하세요. 변경은 docs/spec.md에서 시작됩니다.
라이선스
MIT. LICENSE를 참조하세요.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceProvides advanced evaluation tools for assessing AI safety, alignment, and performance of LLM outputs. Enables programmatic evaluation of quality, safety metrics like toxicity and PII detection, and operational metrics including carbon footprint and cost estimation.4Apache 2.0
Coval MCP Serverofficial
AlicenseAqualityBmaintenanceEnables AI assistants to interact with Coval's evaluation platform for launching and monitoring evaluation runs, managing agents and test sets, and retrieving evaluation metrics.18331MIT- AlicenseNot gradedqualityAmaintenanceEnables LLM evaluation and observability by uploading documents, building test sets, running RAG pipelines, and automatically scoring answers for groundedness, hallucination risk, retrieval quality, latency, and cost, with tools exposed to MCP-compatible clients.1MIT
- AlicenseNot gradedqualityBmaintenanceExposes a run_suite tool to evaluate whether an AI agent is safe to operate internal web apps, scoring task completion and forbidden-action violations to gate CI/CD pipelines.361Apache 2.0
Related MCP Connectors
Build, validate, and deploy multi-agent AI solutions from any AI environment.
See, price, and control every tool call your AI agents make: policy checks, cost, and audit tools.
Runtime permission, approval, and audit layer for AI agent tool execution.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/hishamalward/evalmine'
If you have feedback or need assistance with the MCP directory API, please join our Discord server