Jev에 '뭔가 안 되는데요'를 분류시키면 무엇이 돌아올까 - Go로 판단 특화 AI의 경계를 탐구하다
요약
TypeSafe AI가 공개한 Jev 모델은 일반 LLM과 달리 문장 생성 없이 사전 정의된 선택지 중 판단 및 확률만 반환하는 'System One Model'입니다. 이 글에서는 Go를 이용해 Jev의 API 호출을 시연하며, 명확한 입력부터 모호한 입력까지 다양한 상황에서 판단 경계를 탐구합니다.
핵심 포인트
- Jev는 문장 생성 없이 선택지 기반의 판단과 확률만 반환하는 모델이다.
- TypeSafe AI는 이를 'System One Model'이라 부르며 Zero Hallucinations를 지향한다.
- 모호한 입력에 대한 Jev의 반응을 관찰하며 판단의 경계를 탐구했다.
- 명확한 입력 시 confidence가 1.00에 고정되는 특성을 보여준다.
2026년 9월, TypeSafe AI에서 Jev라는 AI 모델이 공개되었습니다.
ChatGPT와 같은 일반적인 LLM(Large Language Model)이 문장을 생성하는 것과 달리, Jev는 문장을 전혀 생성하지 않는 모델입니다. 대신, 주어진 텍스트에 대해 사전 정의된 선택지 중에서 판단을 반환하는 데 특화되어 있습니다.1
예를 들어 '상품이 도착했는데 파손되었습니다'라는 문의에 대해 billing / technical / shipping / account / other와 같은 후보군을 제공하면,
shipping = 1.00
billing = 0.00
other = 0.00
...
와 같은 판단 결과와 확률만 반환됩니다. 문장 설명은 없습니다. 명확한 입력의 경우 1위가 확률을 거의 독점하며, confidence도 1.00에 고정됩니다.
그렇다면, '뭔가 안 되는데요'와 같은 모호한 입력을 던지면 어떻게 될까요? 이번에는 Go를 사용하여 Jev의 API를 호출하며 판단의 경계를 탐구해 보았습니다.
참고로 TypeSafe 자체는 신규 계정일 경우 크레딧 없이 API 키 발급이 어렵기 때문에, 여기서는 Qiita 캠페인에서도 안내된 OpenRouter를 경유하여 Jev를 호출했습니다.2
| 일반적인 LLM | Jev |
|---|---|
| 주 목적 | 문장・코드 생성 |
| ... | |
| LLM = 생각해서 글을 쓰는 AI |
Jev = 모호한 조건을 판별하는 AI
로 이해하면 쉽습니다. TypeSafe AI는 이 유형을 System One Model이라고 부릅니다.
| 유형 | 하는 일 | 출력 |
|---|---|---|
| Choice | 여러 후보 중 하나를 선택 | 선택된 후보 + confidence + 각 후보의 probabilities |
| Score | 단계 평가 | 단계의 확률 분포 + 스코어 (float, 0~4) |
| Noul | Yes/No의 확률 판정 | 0.0~1.0 |
TypeSafe AI는 이를 'Zero Hallucinations'라고 표현합니다.1
하지만 이는 올바른 판단을 보장한다는 의미는 아닙니다. 출력이 사전 정의된 선택지에 고정되기 때문에, super_darkness_dragon과 같은 존재하지 않는 값은 반환하지 않지만, shipping을 billing으로 오판할 가능성은 있습니다.
OpenRouter에서 키를 발급하고 환경 변수를 설정합니다.
export TYPESAFE_API_KEY=
입력 | 판정 | confidence |
|---|---|---|
| 상품이 도착했는데 파손되었습니다. 교환할 수 있나요? | shipping | 1.00 |
| ... |
명확한 입력이라면 기대대로, confidence는 1.00에 고착됩니다 (분포도 1위가 거의 모든 것을 차지합니다).
| 유형 | 입력 | 결과 |
|---|---|---|
| Score | 모든 사용자가 로그인할 수 없는 상태가 30분 지속되고 있습니다 | 3.84/4 (critical) |
| Noul | `DROP TABLE users;` |
0.99 (블록 권장) |
| Noul | `SELECT * FROM users WHERE id = 1` |
0.02 (실행 가능) |
Score는 0~4의 5단계(0=trivial ~ 4=critical)를 float으로 반환하는 점에 주의하세요 (3.84처럼 중간값이 될 수 있습니다).
여기까지는 예상대로입니다. 그렇다면, 입력을 모호하게 만들어 보겠습니다.
이것부터가 본론입니다. 같은 Choice 후보에 대해 **단계적으로 모호한 입력**을 던지면서 confidence의 변화를 관찰했습니다.
하나의 문장에 두 가지 주제가 혼재하는 경우입니다.
| 입력 | 판정 | confidence | 2위 | 1위2위차 |
|---|---|---|---|---|
| 상품이 도착했는데 파손되었습니다 (※명확한 입력) | shipping | 1.00 | — | 1.00 |
| ... |
"사용 방법을 몰라서 반품하고 싶어요"는 other=0.38 / technical=0.35 / account=0.26의 삼파전입니다. confidence가 낮을 뿐만 아니라,
재실행하면 1위가 other↔technical로 바뀝니다 (후술할 비결정성 테스트에서 확인). 판정 자체가 불안정해지는 영역입니다.
주어나 목적어가 생략된, 일본어에서 흔한 표현을 던져봅니다.
| 입력 | 판정 | confidence | 2위 | 1위2위차 |
|---|---|---|---|
| 뭔가 작동하지 않는데요 | technical | 0.96 | other 0.03 | 0.94 |
| ... |
예상 밖의 결과: 정보가 줄어들수록 confidence가 낮아지지는 않았습니다. 정보가 제로에 가까운 입력은 망설이는 것이 아니라, 자신감을 가지고 ("죄송합니다"는 other=1.00). confidence가 떨어지는 것은 "여러 실(real) 카테고리가 경쟁할 때"이지, "정보가 없을 때"가 아닙니다. `other`
에 분류되는
내용이 없고 감정이나 긴급도만 전달되는 입력입니다.
| 입력 | 판정 | confidence | 2위 | 1위2위차 |
|---|---|---|---|
| 급히 대응 부탁드립니다!!! | other | 0.99 | technical 0.01 | 0.98 |
| ... |
감정(긴급/분노/감사)은 카테고리 판정을 거의 끌어내리지 않으며, 내용이 없으면 높은 confidence로 `other`
에 떨어집니다. 감정의 강도와 내용 카테고리는 독립적인 축임을 관측할 수 있었습니다.
경어・지시사・문장 끝 생략 등, 일본어 특유의 모호성을 가진 입력입니다.
| 입력 | 판정 | confidence | 2위 | 1위2위차 |
|---|---|---|---|
| 번거로우시겠지만, 지난번 건에 대해 확인해 주실 수 있을까요 | other | 1.00 | — | 1.00 |
| ... |
"상품 도착했는데, 뭔가 달라서..."는 구어체에서도 shipping=0.56을 포착했습니다 (다만 other=0.40으로 근소한 차이). 반면 "지난번 건", "그건" 같은
지시사만 있는 입력은 내용이 없기 때문에 other=1.00에 떨어집니다. 구어체의 흐트러짐에는 내성이 있지만, 문맥 의존적인 지시사는 (당연히) 판정 재료가 되지 못합니다.
모든 테스트 케이스를 나열하면 명확한 경향이 나타났습니다.
명확한 입력: confidence 1.00 1위2위차 1.00 (단정)
2카테고리 혼재: confidence 0.220.73 1위2위차 0.030.62(여기만 낮음)
정보 부족: confidence 0.961.00 1위2위차 0.941.00(자신감 있게 other)
...
당초에는 '모호해질수록 confidence가 낮아진다'고 예상했습니다. 실제는 그렇지 않았고, **confidence가 낮아진 경우는 '여러 실(實) 카테고리가 경쟁하는 2개 카테고리 혼재'일 때만**이었습니다. 정보 부족・감정만・흐릿한 표현은 망설이기보다는 높은 confidence로 `other`에 분류됩니다.
즉, Jev의 confidence는 '입력의 모호함'이 아니라 '**선택지 간 경쟁의 강도**'를 반영하고 있다고 보는 것이 정확합니다.
Noul(파괴적 조작 판정)에서도 명확한 케이스 외를 시도했습니다.
| 입력 | 위험도 | 판정 | 비고 |
|---|---|---|---|
`SELECT * FROM users WHERE id = 1` | 0.02 | 실행 가능 | 베이스라인 (안전) |
`DROP TABLE users;` | 0.99 | 블록 권장 | 베이스라인 (위험) |
`TRUNCATE TABLE users;` | 0.98 | 블록 권장 | DROP과 거의 동등하게 위험하다고 판정 |
`ALTER TABLE users ADD COLUMN email VARCHAR(255);` | 0.07 | 실행 가능 | DDL이라도 비파괴적이면 저위험 |
`UPDATE users SET deleted_at = NOW()` | 0.79 | 사용자 확인 | WHERE 없음 전체 업데이트로 경계 |
`UPDATE users SET name = 'test'` | 0.82 | 사용자 확인 | WHERE 없음 전체 업데이트 |
`UPDATE users SET name = 'test' WHERE id = 1` | 0.59 | 실행 가능 | WHERE 추가로 위험도가 하락
확인된 점:
- **'DDL이라서 위험하다'가 아니다.** `TRUNCATE`는 =0.98로 경계하는 반면, `ALTER ADD COLUMN`은 =0.07입니다. 구문 카테고리가 아니라 '파괴성'을 보고 있습니다. -
**WHERE 유무가 효과적이다.** 같은 `UPDATE users SET name='test'`라도, WHERE 없음=0.82, `WHERE id=1`이 붙으면=0.59입니다. 전체 건인지 1행인지를 위험도에 반영하고 있습니다.
여기까지의 표는 모두 1회 스냅샷입니다. Jev는 **비결정적(non-deterministic)**이며, 동일 입력이라도 호출할 때마다 값이 흔들립니다. 대다수의 케이스에서는 흔들림이 작아 레이블이 바뀌지는 않습니다. 그러나 **임계값 경계**에서는 실해가 발생합니다. 실제로 경계 근처의 케이스를 각 5회 불러 확인했습니다.
| 입력 | 5회 관측 | 불편한 점 |
|---|---|---|
사용법을 몰라서 반품하고 싶어요 (B2) | 1위가 other↔technical로 교체됨. conf 0.21–0.30, 차이 0.02–0.13 | 부서 라우팅의 목적지가 매번 바뀜 |
`UPDATE ... WHERE id = 1` (N7) | noul 0.54–0.61. 임계값 0.60을 넘나듦 | '실행 가능'과 '사용자 확인'이 부를 때마다 바뀜 |
| 상품 도착했는데, 뭔가 달라서... (E3) | shipping에서 안정적. conf 0.44–0.50 | 판정은 안정적. 확신도만 변동 |
`UPDATE ... name='test'` (N6) | noul 0.80–0.83 | 항상 '확인' 범위. 임계값에서 멀리 떨어져 있으면 안정적
E3와 N6처럼, 임계값에서 멀리 떨어져 있으면 흔들려도 결론은 바뀌지 않습니다. 그러나 B2와 N7은 라우팅처나 실행 가능 여부가 **부를 때마다 반전합니다**.
'확률이 돌아온다'는 것과 '매번 같은 값이 돌아오는' 것은 다릅니다. 임계값 경계에서는 마진을 두거나(예: 0.55~0.65는 일괄 '인간 확인'으로 처리) 여러 번 샘플링하여 다수결을 취하는 히스테리시스 설계가 필요합니다.
당초의 가설은 '입력이 모호해질수록 confidence가 낮아진다'였습니다. 실측에서는 이것이 **절반 틀렸습니다**.
- 정보 제로의 '죄송합니다', '도와주세요' → **other=1.00** (망설이지 않음) - 여러 카테고리가 경쟁하는 '사용법을 몰라서 반품하고 싶어요' → **other=0.38 / technical=0.35** (confidence 0.22)
confidence가 떨어지는 것은 '정보가 적을 때'가 아니라 '**여러 실(實) 카테고리가 맞붙을 때**'였습니다. 따라서,
이러한 에스컬레이션 설계는 성립하지만, 이것이 포착하는 것은 '카테고리 충돌 케이스'일 뿐, '정보가 없는 케이스'는 높은 confidence의 `other`로 지나갑니다. `other`의 다발을 별도로 모니터링함으로써 정보 부족 케이스도 커버할 필요가 있습니다.
`TRUNCATE` = 0.98이라고 경계하는 반면, 같은 DDL이라도 `ALTER ADD COLUMN` = 0.07입니다. 게다가 WHERE 유무에 따라 `UPDATE`의 위험도가 0.82에서 0.59로 떨어집니다. 키워드 매칭이 아니라, 조작이 실제로 데이터를 파괴하는지 여부를 의미적으로 판별하고 있다는 점은 규칙 기반 정규표현식으로는 구현하기 어려운 동작입니다.
'이제 그만 좀 하세요'와 같은 분노의 입력은 감정에 휘둘리지 않고 **other=0.99**로 판정되었습니다. 감정의 강도는 카테고리 판정에 거의 영향을 미치지 않습니다.
이는 **카테고리 분류(Choice)와 긴급도 판정(Score / Noul)을 별도의 질문으로 동시에 던지는** 설계가 유효하다는 것을 시사합니다. Jev는 한 번의 요청으로 여러 질문을 평가할 수 있기 때문에, 3
```json
{
"questions": {
"category": { "type": "choice", ... },
...
처럼 내용과 긴급도를 동시에 판정하는 사용 방식이 자연스럽습니다.
검증 중에 걸린 함정으로는, Score가 *int라면 디코드에서 실패한다는 점이 있습니다. API는 3.84와 같은 float을 반환하므로, *float64로 받아야 합니다. 또한 confidence와 각 후보의 probabilities는 별도의 필드로 반환되며, 1위 확률과 confidence가 일치하지 않습니다.
Jev에 명확한 입력을 전달하면 기대하는 판정이 돌아옵니다. 이것 자체는 많은 글에서 소개된 바 있습니다.
이번에 흥미로웠던 점은, 입력을 모호하게 했을 때의 confidence 변화와, 같은 입력이라도 결론이 달라지는 비결정성입니다.
| 발견 | 설계 시사점 |
|---|---|
confidence가 떨어지는 것은 '카테고리 충돌'일 때만. 정보 제로는 높은 confidence로 other에 빠짐 | 낮은 confidence에서 에스컬레이션 + other 다발 모니터링을 조합하기 |
| 같은 입력이라도 임계값 경계에서는 결론이 달라짐 (N7: 0.54~0.61에서 0.60을 넘음) | 경계에 마진 또는 여러 번 샘플링하여 히스테리시스를 적용하기 |
| Noul은 구문이 아니라 파괴성을 봄 (TRUNCATE 0.98 vs ALTER 0.07, WHERE 유무로 0.82→0.59) | 정규표현식보다 견고한 위험 조작 필터에 사용 가능 |
감정과 내용은 독립적인 축 (분노여도 other =0.99) | Choice와 Noul/Score를 동일 요청으로 조합하는 것이 유효 |
| Score는 0~4의 float / confidence와 probabilities는 별개 | 클라이언트의 타입은 float으로 받기 (int면 크래시) |
Jev를 '규칙 기반으로는 구현하기 어렵지만, LLM을 호출할 정도는 아닌 판단 처리'에 사용하려면, confidence를 활용한 설계와 비결정성에 대한 대비가 핵심이 될 것 같습니다.
confidence가 높음 → 자동 처리
confidence가 낮음 → 사람에게 전달
임계값일 때 → 마진을 두기
TypeSafe AI,
Introducing System One Models & Jev, 2026-09-15. Jev의 System One Model로서의 위치 설정, 타입 기반 확률 판정, 가격 등. ↩ ↩2 -
OpenRouter,
Jev Documentation, https://openrouter.ai/docs/guides/community/jev ― OpenRouter 경유 이용 방법과 엔드포인트. ↩ -
Jev에서는 Choice / Score / Noul 등의 타입 기반 질문을 같은 state에 대해 동일 요청으로 평가할 수 있습니다. ↩
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기