문장을 정형적인 선택지, 단계 평가, 참/거짓으로 변환하는 처리에서는 생성형 LLM(Large Language Model)에 JSON을 반환하도록 하는 방법이 자주 사용됩니다.
반면, TypeSafe AI의 Jev는 문장을 생성하지 않고, 타입이 지정된 판단과 확률을 반환하는 용도에 한정된 모델입니다.
저희는 이 두 가지를 공개 데이터셋 4종과 난제 세트를 합친 총 821건으로 비교했습니다.
Qiita에는 결과를 간략하게 요약한 선행 기사가 있습니다.
본고에서는 실험 방법, 모든 지표, 통계적 제약, 난제 세트의 답변을 포함한 검증 리포트를 게재합니다.
- 실시일: 2026-09-19 (실행 시각은 UTC로 기재)
- 비교 대상: TypeSafe
jev-1.13.0,
OpenAI gpt-5.4-nano,
OpenAI gpt-4.1-mini,
Ollama qwen3.8 (27.3B, Q4_K_M) - 평가 데이터: 공개 데이터셋 4종에서 각 200건, 기존 난제 세트 21건
- 관련 문서: Jev 단독 검증은 Jev를 21케이스로 검증한 기사에 정리되어 있습니다.
결론
Jev는 속도와 비용 면에서 비교 대상의 범용 LLM을 크게 능가했으며, 확률 보정(calibration)과 재현성에서도 동등하거나 그 이상이었습니다.
응답 시간 중앙값은 약 240ms로, 문제 하나씩 제시하는 공개 데이터셋에서는 OpenAI의 두 모델보다 2.53.7배, 로컬 환경의 qwen3.8보다 6.28.5배 빨랐습니다.
1,000건당 비용은 gpt-5.4-nano의 1/3.91/8.1, gpt-4.1-mini의 1/6.31/12.7 수준이었습니다.
호출 한 번에 5문제를 모아서도 응답 시간은 거의 변하지 않았는데, 이는 LLM이 출력 토큰 증가에 비례하여 느려지는 것과 대조적이었습니다.
정확도 면에서는 어느 데이터셋에서도 Jev가 최고는 아니었습니다.
77 클래스 의도 분류에서는 Jev가 최고(0.790)였으며, gpt-5.4-nano와 qwen3.8 대비 통계적으로 유의미한 차이가 있었습니다.
반면, 영어 트윗의 비꼬는 표현 판단에서는 qwen3.8(0.870)이 Jev(0.805)를 유의하게 능가했습니다.
일본어 리뷰의 감정 분류와 영어 리뷰의 별점 평가에서는 Jev와 gpt-4.1-mini, 그리고 qwen3.8 간의 차이는 오차 범위 내였습니다.
다만, 12개 그룹 비교에 다중 비교 보정(Bonferroni)을 적용하면 유의미한 차이는 어느 것도 남지 않았습니다.
이러한 결과들로부터 Jev는 'LLM보다 항상 똑똑한 분류기'라기보다는, 'LLM과 동등한 판단을 몇 배 빠르게, 1/수십 분의 비용으로, 보정된 확률과 함께 반환하는 컴포넌트'로 위치시키는 것이 적절합니다.
검증 목적
Jev 단독 검증에서는 준비된 입력에 대해 기대했던 판단을 반환하는지 확인했습니다.
하지만 같은 판단을 범용 LLM으로 JSON 스키마를 이용해 구조화 출력했을 경우와 비교하여, Jev가 실용적인 우위를 가지는지 여부는 확인하지 못했습니다.
TypeSafe는 Jev의 특징으로 LLM보다 빠르고 저렴하며, 확률이 보정되어 있고, 타입 오류를 일으키지 않는 점을 들고 있습니다.
본 검증은 이러한 주장들을 공개 데이터셋과 기존 난제 세트를 통해 확인하는 것을 목적으로 했습니다.
비교 축은 다음 여섯 가지입니다.
- 정확도: 수작업 라벨과의 일치율 -
- 확률 보정: 출력된 확률이나 확신도가 실제 정확도와 어느 정도 일치하는지 -
- 응답 시간: 1회 호출에 걸리는 시간 -
- 비용: 실측 토큰 수와 표준 요금에서 도출한 1,000건당 비용 -
- 재현성: 같은 입력을 2번 던졌을 때 답변이 일치하는 비율 -
- 견고성: 완곡 표현, 다국어, 지시 주입 등을 포함하는 난제 세트에서의 동작
| 이름 | 제공처 | 호출 방식 | 지정 모델명 | 비고 |
|---|
| Jev | TypeSafe AI | typesafe-sdk 0.6.0의 TypeSafeClient.system_one | | |
| | | | |
jev-latest (기본값) | 실행 당일 API 응답으로 jev-1.13.0 확인 | | | |
| gpt-5.4-nano | OpenAI | openai 3.16.2의 Chat Completions API | | |
gpt-5.4-nano | 스냅샷 gpt-5.4-nano-2026-03-17이 목록에 존재함. 어느 것으로 해결되었는지는 기록하지 않음 | | | |
| gpt-4.1-mini | OpenAI | 위와 동일 | gpt-4.1-mini | 스냅샷 gpt-4.1-mini-2025-04-14가 목록에 존재함 |
| qwen3.8 | Ollama (로컬) | Ollama HTTP API /api/chat | | |
qwen3.8:latest | 부모 모델 qwen3.8:27b-q4_K_M, 아키텍처 qwen35, 파라미터 수 27,320,697,856, 레이어 65개, 4bit 양자화(Q4_K_M), 모델 파일 17.4GB | | | |
gpt-5.4-nano는 사용 가능한 OpenAI 모델 중 최신 세대의 최소 모델로 선택함.
gpt-4.1-mini는 후보별 확률 분포 (logprobs)를 최대 20개까지 반환하기 때문에, 확률 보정(calibration)을 비교할 상대 모델로 선택함.
qwen3.8은 검증 머신의 GPU (24GB)에 올라가는 범용 모델 중 가장 큰 모델로 선택함.
각 모델의 호출 설정
| 항목 | Jev | gpt-5.4-nano | gpt-4.1-mini | qwen3.8 |
|---|
| 출력 형식 | Choice, Noul, Score의 타입 지정 답변 | JSON 스키마 (strict: true) | JSON 스키마 (strict: true) | JSON 스키마 (Ollama의 format) |
| 추론(사고) 토큰 | 없음 (규격) | `reasoning_effort: | | |
| 시간(UTC) | 내용 |
|---|
| 08:28경 | 4개 모델의 본 실행을, 모델별로 별도 프로세스에서 동시에 시작 |
| ... | |
| 총 3,284회의 호출(4개 모델 × 821건)과 재현성 확인용 1,200회에 걸쳐 실패는 0건이었다. | |
평가 데이터
공개 데이터셋
Hugging Face Hub의 parquet 변환판을 가져와 테스트 분할에서 건수를 줄여 사용했다.
| 이름 | Hugging Face 리포지토리 | 구성과 분할 | 분할 총 건수 | 리비전 | 카드 라이선스 | 출처 논문 | 본 검증 형식 |
|---|
| banking77 | mteb/banking77 | default / test | 3,076 | 18072d2685ea | MIT | arXiv:2003.04807 | Choice (77지) |
| irony | cardiffnlp/tweet_eval | irony / test | 784 | b3a375baf0f4 | unknown | arXiv:2010.12421 | Noul |
| ja_sentiment | tyqiangz/multilingual-sentiments | japanese / test | 3,000 | a3080a58e563 | Apache-2.0 | 명시 없음 (source 열은 amazon_reviews_multi) | Choice (3지) |
| yelp | Yelp/yelp_review_full | yelp_review_full / test | 50,000 | c1f9ee939b7d | other | arXiv:1509.01626 | Score (5단계) |
banking77의 원본(PolyAI/banking77)은 데이터셋 스크립트 형식이라 Hugging Face 변환 서비스가 대응하지 못했다.
따라서 MTEB이 공개한 parquet 버전을 사용했다.
라이선스가 unknown이나 other인 데이터가 있어, 가져온 데이터는 data/에 두고 Git 관리에서 제외했다.
리포지토리에 기록한 것은 행 번호로 만든 항목 ID, 정답 라벨, 각 모델의 예측뿐이다.
추출 방법
각 데이터셋의 테스트 분할에서 Python의 random.Random(42).sample을 사용하여 200행을 비복원 추출했다.
항목 ID는 b77-102와 같이, 데이터셋 접두사와 행 번호를 조합했다.
같은 난수 시드로 재실행하면 같은 200건이 선택된다.
추출된 샘플의 성질은 다음과 같다.
| 데이터셋 | 건수 | 라벨 분포 | 본문 글자 수 (중앙값 / 평균 / 최대) |
|---|
| banking77 | 200 | 77 클래스 중 73 클래스 출현 (최다 7건, 최소 1건) | 44 / 56 / 231 |
| ... | | | |
질문 정의
4개 모델에 동일한 질문 문구와 선택지를 제공했다.
| 데이터셋 | 질문 유형 | 질문 문구 | 선택지 또는 단계 | 정답 레이블 대응 |
|---|
| banking77 | Choice | Which banking customer intent does this message express? | 데이터셋의 label_text 77개(설명 없음, 알파벳 순) | label_text |
| irony | Noul | The tweet is ironic or sarcastic | 참/거짓 | |
label가 1(irony)이면 참 | | | | |
| ja_sentiment | Choice | Overall sentiment of this product review | positive: 리뷰어가 만족함, neutral: 혼합되거나 만족하지도 불만족하지도 않음, negative: 리뷰어가 불만족함 | label 0, 1, 2를 각각 positive, neutral, negative에 대응 |
| yelp | Score | The star rating the reviewer most likely gave in this review | 0: 1 star: 매우 부정적인 경험, 1: 2 stars: 주로 부정적, 2: 3 stars: 혼합되거나 평균적, 3: 4 stars: 주로 긍정적, 4: 5 stars: 우수함, 매우 긍정적 | label 04 (15개 별) |
난이도 높은 세트
단일 검증으로 만든 examples/diverse_cases.py의 21건을 그대로 비교에도 사용했다.
내역은 다음 두 가지이다.
문의 16건: 풍자, 부정, 완곡어법, 감정 혼재, 간사이 사투리, 이모지만, 오타, 프랑스어, 중국어, 지시 주입(instruction injection), 장문 내 매몰, 욕설, 감사, 기호만, 로그 붙여넣기, JSON 형식의 state. 감정(Choice 4지선다), 담당 부서(Choice 4지선다), 긴급성(Noul), 풍자(Noul), 공격성(Score 3단계)의 5가지 질문을 한 번의 호출로 모아서 던졌다. -
추론 및 사실 추출 5건: 잔액 비교, 날짜 비교, 의료 문서의 부정 표현, 코드 오류, 회의록 품질. 케이스별로 전용 질문을 던졌다.
기대값은 사람의 손으로 매겼으며, 정답이 하나로 정해지지 않은 항목에는 매기지 않았다.
기대값이 있는 항목은 42개이다.
실험 방법
Jev 호출
질문 정의를 typesafe-sdk의 Choice, Noul, Score로 변환하고, system_one을 호출했다.
답변 값, 확률, confidence를 그대로 기록했다.
Score의 예측 단계는 반환된 연속 값을 반올림한 정수로 했다.
LLM 호출
LLM에는 다음 시스템 프롬프트를 주었다.
You are a precise classifier embedded in software. Read the input and answer every question using only the allowed values. For each answer also give `confidence`: your probability (0 to 1) that the answer is correct. Output JSON only.
사용자 프롬프트는 입력 본문과 질문 정의로부터 구성했다.
yelp의 예시를 보여준다.
## Input
<리뷰 본문>
## Questions
...
Noul 질문은
| 질문 유형 | answer의 타입 |
|---|
| Choice | 문자열 열거형 (선택지 레이블) |
| Noul | 참/거짓 값 |
| Score | 정수 열거형 (0부터 단계 수 − 1까지) |
yelp에서 사용된 스키마는 다음과 같다.
{
"type": "object",
"properties": {
...
확률 추출 방법
LLM은 확률을 직접 반환하지 않기 때문에, 확신도를 두 가지 방법으로 추출하여 각각 평가했다.
- p: 출력 토큰의 logprobs에서 구한 확률. Jev는 API가 반환하는 확률을 그대로 사용한다. -
conf: LLM이 JSON의 confidence 항목에 기재한 자기 신고 값. Jev는 API가 반환하는 confidence를 사용한다.
LLM의 p는 다음 절차로 구했다.
- 출력된 JSON 문자열에서 각 질문의
answer 값이 차지하는 문자 범위를 특정한다. - 그 범위와 겹치는 토큰의 logprob을 합산하고 지수화하여 '선택한 값의 확률'로 한다.
- 값의 첫 번째 토큰에 대해, 상위 후보(
top_logprobs) 중 선택지 중 하나에 대응하는 것들을 모아 정규화하여 후보 분포를 만든다.
Noul의 P(true)는 후보 분포의 true와 false 비율에서 구했다.
Score의 연속 값은 후보 분포의 단계 번호 기대값으로 했다.
이 방법에는 세 가지 제약이 있다.
첫째, OpenAI의 logprobs는 JSON 스키마로 제약을 걸기 전의 분포이며, 선택지 외의 토큰에도 확률이 할당된다.
둘째, 선택한 값의 첫 번째 토큰이 여러 선택지에 공통되는 경우(banking77의 get_physical_card와 get_disposable_virtual_card 등), 첫 번째 토큰으로는 후보 분포를 얻을 수 없다.
banking77에서 후보 분포를 얻은 경우는 gpt-5.4-nano로 82/200건, gpt-4.1-mini로 84/200건이었다.
셋째, gpt-5.4 계열은 top_logprobs의 상한이 5개여서, 많은 경우에 선택된 토큰의 확률이 거의 1이 되어 다른 후보 정보를 거의 얻을 수 없었다.
qwen3.8에 대해서는 p를 구하지 않았다.
Ollama 0.33.2는 JSON 스키마의 format을 지정했을 때 첫 번째 토큰분만 logprobs를 반환했기 때문이다.
qwen3.8의 확신도는 conf(자기 신고)만으로 평가했다.
평가 지표
| 지표 | 정의 |
|---|
| 정답률 | 예측이 정답 레이블과 일치한 비율. Noul은 answer (Jev는 P(true) > 0.5)로 판정 |
| ... | |
| Noul의 ECE(p)는 P(true)에서 구한 확신도 max(p, 1 − p)와, p > 0.5에 의한 판정의 정오로 계산했다. | |
Score의 ECE(conf)는 confidence를 '예측 단계가 완전히 일치할 확률'로 간주하여 계산했다.
Jev의 Score의 confidence가 그 의미로 설계되었는지 확인하지 못했기 때문에, 이 값은 참고용으로 남긴다.
비용
| 모델 | 입력 (USD / 100만 토큰) | 출력 (USD / 100만 토큰) | 출처 및 확인일 |
|---|---|
| Jev | 0.042 | 무료 | TypeSafe의 Models 페이지 (2026-09-17) |
| ... |
캐시 입력 할인은 고려하지 않았다.
결과
데이터셋별 모든 지표
표 안의 ―는 해당 지표를 얻을 수 없었음을 나타낸다.
$/1k 건은 1,000건당 비용(USD)이다.
banking77 (은행 문의 의도, 77 클래스)
⚠️ [IMG:N] 형식 토큰은 이미지 placeholder 입니다. 번역하지 말고 원래 위치에 그대로 유지하세요.
irony (영어 트윗의 비꼬는 뉘앙스 판별)
| 모델 | 정확도 | AUROC | Brier | ECE(p) | ECE(conf) | 상위 80% 정확도(p) | 상위 80% 정확도(conf) | p50(ms) | p95(ms) | $/1k 건 | n | 실패 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| jev | 0.805 | 0.974 | 0.137 | 0.029 | 0.029 | 0.869 | 0.869 | 238 | 296 | 0.0125 | 200 | 0 |
| ... |
ja_sentiment (일본어 상품 리뷰의 감성, 3 클래스)
| 모델 | 정확도 | Macro-F1 | ECE(p) | ECE(conf) | 상위 80% 정확도(p) | 상위 80% 정확도(conf) | p50(ms) | p95(ms) | $/1k 건 | n | 실패 |
|---|
| jev | 0.825 | 0.801 | 0.121 | 0.113 | 0.894 | 0.887 | 241 | 309 | 0.0180 | 200 | 0 |
| ... | | | | | | | | | | | |
| yelp (영어 리뷰의 별점, 5단계) | | | | | | | | | | | |
| 모델 | 완전 일치 | ±1 이내 | MAE | Spearman | ECE(conf) | 상위 80% 완전 일치(conf) | p50(ms) | p95(ms) | $/1k 건 | n | 실패 |
|---|
| jev | 0.610 | 0.975 | 0.408 | 0.921 | 0.267 | 0.662 | 237 | 295 | 0.0209 | 200 | 0 |
| ... | | | | | | | | | | | |
정확도 신뢰구간과 Jev와의 차이
McNemar 검정의 'Jev만 정답'과 '상대방만 정답'은 동일 항목에서 정오가 불일치한 건수이다.
yelp는 완전 일치로 판별했다.
| 데이터셋 | 모델 | 정답 수/건수 | 정확도 | 95% 신뢰구간 | Jev만 정답 | 상대방만 정답 | p 값 |
|---|
| banking77 | jev | 158/200 | 0.790 | 0.728~0.841 | ― | ― | ― |
| ... | | | | | | | |
| 유의수준 5%에서 차이가 있었던 조합은 다음 5개이다. | | | | | | | |
- Jev가 우세했던 조합: banking77의 gpt-5.4-nano (p = 0.015)와 qwen3.8 (p = 0.016), irony의 gpt-4.1-mini (p = 0.045), yelp의 gpt-5.4-nano (p = 0.010)
- Jev가 열세였던 조합: irony의 qwen3.8 (p = 0.031)
12개 조합에 Bonferroni 보정을 적용하면 유의수준은 약 0.0042가 되어 어느 조합도 유의하지 않게 된다.
200건이라는 건수로는 0.05 전후의 정확도 차이를 확정하기에 검출력이 부족하다.
확률 보정(Calibration)
ECE의 최소값은 다음과 같았다.
| 데이터셋 | ECE가 가장 작은 모델과 지표 | Jev의 ECE (p / conf) |
|---|
| banking77 | Jev의 conf (0.080) | 0.088 / 0.080 |
| ... | | |
| Jev는 4개 데이터셋 중 3개에서 가장 작은 ECE를 보였다 (irony는 동률). | | |
ja_sentiment에서는 gpt-4.1-mini의 자체 신고 신뢰도가 더 잘 보정되었다.
LLM의 logprobs에서 구한 p는 확신도를 과대평가하는 경향이 있었다.
gpt-4.1-mini의 ECE(p)는 banking77에서 0.203, irony에서 0.224로, Jev의 2~8배에 달했다.
자가 보고한 conf는 p보다 보정(calibration)이 더 좋은 경우가 많았지만, 모델과 데이터셋에 따라 편차가 있었다.
qwen3.8의 conf ECE는 0.088~0.309였다.
확신도를 기준으로 사람이 확인하는 운영을 가정했을 때 '상위 80% 정답률'에서는 다음 모델이 가장 높았다.
| 데이터셋 | 가장 높은 모델 및 지표 | Jev |
|---|
| banking77 | Jev (0.875, p와 conf에서 동일) | 0.875 |
| ... | | |
| irony의 AUROC는 Jev가 0.974, gpt-4.1-mini가 0.942, gpt-5.4-nano가 0.914였다. | | |
비꼬는(irony) 여부를 확률로 순위 매기는 능력은 Jev가 가장 높았다.
Brier 스코어는 Jev와 gpt-5.4-nano가 0.137로 나란했고, gpt-4.1-mini는 0.236이었다.
응답 시간
응답 시간은 클라이언트 측에서 측정한 단일 호출의 벽시계 시간이다.
| 데이터셋 | Jev p50 / p95 | gpt-5.4-nano p50 / p95 | gpt-4.1-mini p50 / p95 | qwen3.8 p50 / p95 |
|---|
| banking77 | 244 / 326 | 611 / 859 | 891 / 1122 | 2067 / 2220 |
| ... | | | | |
| 단위는 ms이다. | | | | |
평균, 최소, 최대는 다음과 같았다.
| 데이터셋 | Jev | gpt-5.4-nano | gpt-4.1-mini | qwen3.8 |
|---|
| banking77 | 256 / 198 / 592 | 647 / 532 / 1009 | 888 / 634 / 1312 | 2078 / 1893 / 2321 |
| ... | | | | |
| Jev의 중앙값 대비 각 모델의 중앙값 배율은 다음과 같다. | | | | |
| 데이터셋 | gpt-5.4-nano | gpt-4.1-mini | qwen3.8 |
|---|
| banking77 | 2.5배 | 3.7배 | 8.5배 |
| ... | | | |
| Jev의 응답 시간은 입력 길이(yelp 본문은 중앙값 460자)나 질문 수에도 거의 영향을 받지 않았다. | | | |
질문 1개 데이터셋에서는 약 240ms, 질문을 모아 놓은 난이도 높은 세트에서 247ms였다.
LLM은 답변을 토큰 단위로 생성하기 때문에, 질문이 늘어나고 출력이 길어질수록 느려진다.
gpt-4.1-mini는 질문 1개당 약 800ms, 5개일 때 1,528ms로, 약 1.9배가 되었다.
TypeSafe는 'LLM보다 40200배 빠르다'고 주장하지만, 본 검증 조건(추론이 없는 소형 LLM)에서는 2.513.8배였다.
비교 대상 LLM의 크기나 추론 여부에 따라 배율은 크게 달라진다.
토큰 수와 비용
| 데이터셋 | 모델 | 입력 토큰 평균 | 출력 토큰 평균 | 총 비용 (USD) |
|---|
| banking77 | jev | 1022.9 | 828.3 | 0.00859 |
| ... | | | | |
| 전체 합계는 다음과 같다(재현성 확인의 2회차는 포함하지 않음). | | | | |
| 모델 | 호출 횟수 | 입력 토큰 합계 | 출력 토큰 합계 | 총 비용 (USD) |
|---|
| jev | 821 | 459,199 | 183,370 | 0.0193 |
| ... | | | | |
1,000건당 비용으로 비교했을 때, gpt-5.4-nano는 Jev의 3.98.1배, gpt-4.1-mini는 6.312.7배였다. | | | | |