티스토리 뷰

 

주말 사이 개발자 커뮤니티를 뜨겁게 달군 모델이 하나 있다.

 

TypeSafe AI라는 곳에서 낸 Jev 인데 System One 모델이라는 새 이름까지 붙여서 내놨다.

https://docs.typesafe.ai/introduction (얘네 홈페이지를 너무 러프하게 만들어서 docs에서 보는게 편함)

 

다른 LLM과의 가장 큰 차이는 문장을 안 만든다는 것이다. 가입하면 크레딧을 5달러 주길래 이것 저것 테스트 해봤다.

 

한글이 되는지, 얼마나 쓸 수 있는지, 뭘 시킬 만한지 순서로 적어둔다. 가입부터 첫 호출까지 10분이면 되니 관심 있으면 직접 해보는 게 빠르다.

System One Model : Jev

보통 모델한테 "이 문의 어느 팀으로 보낼까"라고 물으면 이렇게 답한다.

  "결제 관련 문의로 보이므로 결제팀에서 처리하는 것이 적절합니다."

틀린 답은 아닌데 프로그램 입장에선 곤란하다. 이 문장에서 "결제팀"을 꺼내는 코드를 따로 짜야 하고, 어떤 날은 "결제 팀"이라고 띄어 쓰고, 가끔은 있지도 않은 팀 이름을 지어낸다. 한 번쯤 겪어봤을 것이다.

 

Jev는 문장 대신 이렇게 준다.

  결제팀      1.0
  기술지원팀  0.0
  계정팀      0.0

객관식 답안지에 표시만 하는 셈이다. 꺼낼 것도 없고, 목록에 없는 답이 나올 수도 없다. 선택지를 미리 주고 그 안에서만 고르게 만든 구조라서다.

 

빠른 이유도 여기 있다. 문장을 만들려면 글자를 하나씩 이어 붙여야 하는데, 객관식은 한 번에 계산하면 끝난다.

 

물어볼 수 있는 건 세 가지뿐이다.

  noul     예/아니오          확률 하나로 돌아온다
  score    몇 단계짜리 척도    어느 단계인지 소수로 돌아온다
  choice   여럿 중 하나       고른 것 + 선택지별 확률

 

회원 가입 후, 플레이그라운드에 들어가면 이 셋이 빈 양식으로 놓여 있다. choice는 이렇게 생겼다.

{
  "new_choice_1": {
    "type": "choice",
    "instructions": "Which option best fits the state?",
    "criteria": {
      "option_a": "Description of an option",
      "option_b": "Another description of a distinct option",
      "option_c": "Another mutually exclusive option"
    }
  }
}

score 양식의 기본 문구가 재밌다. "한 축의 가장 낮은 단계 / 같은 축의 중간 / 같은 축의 가장 높은 단계"라고 적혀 있다. 그냥 예시가 아니라 규칙을 말해주는 거다. 단계들이 전부 같은 축 위에 순서대로 놓여야 한다. 성격이 다른 항목을 섞으면 척도가 아니라 객관식이 된다.

 

판단할 재료는 state로 따로 넣고, 질문은 여러 개를 한꺼번에 붙일 수 있다.

가입하고 키 받기

가입한 뒤 API Keys에서 키를 하나 만들면 끝이다. 카드 등록 같은 건 없다.

 

 

만들면 목록에 뜨는데 여기서는 앞뒤 몇 글자만 보인다. 전체 값은 만드는 순간 한 번만 보여주니 그때 복사해둬야 한다.

 

가입하면 5달러가 들어와 있다. Monthly credit이라고 적혀 있고 만료는 한 달 뒤다.

 

 

5달러가 얼마나 되는지 감이 잘 안 오는데, 단가를 보면 이야기가 달라진다. 입력 100만 토큰에 0.042달러, 출력은 안 받는다.

 

5달러면 입력 1억 2천만 토큰쯤이다. 아래 예시 한 번 호출에 579토큰 들었으니 20만 번쯤 부를 수 있다. 

 

자동 충전은 기본이 꺼짐이고 카드를 걸어야 켜진다. 실수로 크게 돌려도 크레딧만 쓰고 멈추니 마음 놓고 눌러봐도 된다.

테스트

고객 문의 하나를 놓고 세 타입을 한 번에 물었다. 문의도 선택지 설명도 전부 한글이다.

{
  "state": "어제 결제한 연간 이용권이 두 번 결제됐습니다. 카드 내역에 같은 금액이 두 건 찍혀 있어요. 메일로 세 번 문의드렸는데 답이 없습니다. 오늘 안에 처리 안 되면 카드사에 이의제기하겠습니다.",
  "model": "jev-latest",
  "questions": {
    "team": {
      "type": "choice",
      "instructions": "이 문의는 어느 팀이 맡아야 하는가?",
      "criteria": {
        "결제팀": "중복 결제, 환불, 청구 금액 오류",
        "기술지원팀": "로그인 실패, 오류 화면, 접속 장애",
        "계정팀": "회원가입, 탈퇴, 비밀번호 변경"
      }
    },
    "urgency": {
      "type": "score",
      "instructions": "얼마나 급히 대응해야 하는가?",
      "criteria": ["급하지 않다", "보통이다", "급하다", "당장 처리해야 한다"]
    },
    "wants_refund": {
      "type": "noul",
      "instructions": "고객이 환불을 요구하고 있는가?",
      "criteria": {
        "true": "돈을 돌려달라고 명시적으로 요구한다",
        "false": "문제 해결만 요청하고 환불은 언급하지 않는다"
      }
    }
  }
}

호출은 이렇게 한다. 나는 윈도우에서 Git Bash로 돌렸는데 한글이 섞이니 본문이 깨져서 `There was an error parsing the body`가 떨어졌다. 셸이 인코딩을 바꿔버린 탓이다. JSON을 UTF-8 파일로 저장해서 보내니 바로 됐다.

import os
import requests

resp = requests.post(
    "https://api.typesafe.ai/v1/systemone",
    headers={"Authorization": f"Bearer {os.environ['TYPESAFE_API_KEY']}"},
    json={
        "state": "어제 결제한 연간 이용권이 두 번 결제됐습니다. ...",
        "model": "jev-latest",
        "questions": { ... },   # 위에 쓴 그대로
    },
)

answers = resp.json()["answers"]
print(answers["team"]["choice"], answers["team"]["confidence"])
print(answers["urgency"]["score"])
print(answers["wants_refund"]["noul"])

돌아온 답이다.

결제팀 1.0
2.74
0.24

// response
{
  "model": "jev-1.13.0",
  "answers": {
    "team": {
      "type": "choice",
      "choice": "결제팀",
      "confidence": 1.0,
      "probabilities": { "결제팀": 1.0, "기술지원팀": 0.0, "계정팀": 0.0 }
    },
    "urgency": {
      "type": "score",
      "score": 2.74,
      "confidence": 0.74,
      "legend": { "0": "급하지 않다", "1": "보통이다",
                  "2": "급하다", "3": "당장 처리해야 한다" },
      "probabilities": { "0": 0.0, "1": 0.0, "2": 0.25, "3": 0.75 }
    },
    "wants_refund": { "type": "noul", "noul": 0.24 }
  },
  "usage": { "input_tokens": 579, "output_tokens": 82 }
}

 

한글은 문제없이 읽는다. 문의도 선택지 이름도 설명도 전부 한글인데 헷갈리지 않았다.

 

팀 배정은 결제팀에 확률이 전부 몰렸고, 급한 정도는 2.74가 나왔다. 척도 값은 소수로 돌아오고 legend로 각 단계 뜻까지 같이 준다. 순위 매기는 데 바로 쓰기 좋은 모양이다.

 

걸린 시간은 1.47초. 발표 자료에는 70~500ms라고 적혀 있는데 그건 모델이 계산하는 시간이고, 여기엔 한국에서 미국 서버까지 왕복하는 시간이 붙는다.

 

wants_refund가 0.24로 나온 게 눈에 띄었다. 중복 결제 문의니까 당연히 환불 요구라고 볼 것 같은데 낮게 나왔다. 이유는 내가 쓴 설명에 있다. "돈을 돌려달라고 명시적으로 요구한다"라고 적어뒀는데, 문의를 다시 보면 처리해달라고 했지 환불해달라는 말은 없다. 카드사 이의제기 얘기는 협박이지 환불 요청이 아니고.

그럼 설명을 바꾸면 달라지나 싶어서, 똑같은 문의에 똑같은 예/아니오 질문을 설명만 바꿔 세 개 던져봤다.

"refund_explicit": { "criteria": { "true": "돈을 돌려달라고 명시적으로 요구한다" } }
"refund_likely":   { "criteria": { "true": "환불이나 결제 취소로 이어질 만한 불만이다" } }
"refund_bare":     { "instructions": "환불 건인가?" }

// 결과
  돈을 돌려달라고 명시적으로 요구한다        0.26
  환불이나 결제 취소로 이어질 만한 불만이다   0.92
  설명 없이 "환불 건인가?"                 0.81


같은 글을 놓고 0.26과 0.92가 나온다. 모델이 헷갈린 게 아니라 각각 정확히 물어본 대로 답한 것이다. 이 문의에 "환불해주세요"라는 말은 실제로 없고, 환불로 이어질 가능성은 실제로 높다. 둘 다 맞는 답이다.

설명을 아예 안 준 세 번째가 0.81인 것도 볼 만하다. 비워두면 모델이 알아서 넓게 잡는다. 그러니 **비워두는 건 중립이 아니라 느슨한 쪽을 고른 것**이다.

그래서 이 모델을 쓸 때 진짜 일은 선택지를 고르는 게 아니라 설명을 쓰는 일이 된다. 숫자는 뭘 넣든 나오니까, 무슨 숫자인지는 쓴 사람만 안다.

그런데, 같은 걸 물어도 매번 똑같진 않다.

  결제팀 1.0    2.74    0.24
  결제팀 1.0    2.77    0.27
  결제팀 1.0    2.76    0.26
  결제팀 1.0    2.79    0.25
  결제팀 1.0    2.75    0.25

선택지를 고르는 건 다섯 번 다 같았고, 소수로 나오는 값은 둘째 자리에서 흔들렸다. 폭은 0.03 안쪽이다.

순위를 매기거나 선을 긋는 용도라면 이 정도는 문제가 안 된다. 다만 "0.25 이상이면 처리" 같은 선을 소수점 둘째 자리에 걸어두면 같은 입력이 날마다 다르게 처리될 수 있다. 선은 넉넉하게 긋는 게 낫겠다.

확률이 몰리는 방식도 볼 만했다. 팀 배정에서 결제팀이 1.0이고 나머지 둘은 **정확히 0.0**이다. 애매한 문의를 따로 넣어보니 그때는 두 곳에 0.89와 0.11로 갈리고 나머지는 여전히 0.0이었다. 아무 데나 확률을 뿌리는 게 아니라 헷갈릴 만한 곳에만 나눠준다.

이게 되면 "0.9 넘는 것만 자동 처리하고 나머지는 사람에게" 같은 선을 그을 수 있다. 일반 모델의 확률값으로는 이 선을 못 긋는다. 그 숫자는 "그 단어를 뱉을 확률"이지 "그 판단이 맞을 확률"이 아니라서다.

 

RAG에는 어디에 쓸 수 있을까

RAG 구축 시 고려할 것들을 하나씩 파보는 중이라 이걸 어디에 끼울 수 있을지도 생각해봤다.

못 쓰는 자리부터

임베딩은 대체 못 한다. Jev는 숫자 배열을 안 돌려준다. 색인에 저장할 게 없고, 저장할 게 없으면 비슷한 것 찾기도 안 된다. 검색은 미리 계산해둔 벡터끼리 거리를 재는 건데 그 재료가 안 나온다.

 

후보를 좁히는 단계에도 못 쓴다. 조각이 수십만 개인데 한 덩어리로 넣을 수가 없다. 찾는 일은 여전히 벡터와 키워드가 해야 한다.

그러니 Jev 자리는 이미 좁혀진 다음이다.

쓸 만해 보이는 자리

하나, 리랭킹. 후보 조각마다 "이 조각이 질의에 답하는가"를 예/아니오로 물으면 그 확률이 곧 점수다. 지금 쓰는 크로스인코더 리랭커와 하는 일이 같은 꼴이다. 다만 후보 백 개면 백 번 물어야 한다. 한 번에 넣고 고르게 하는 게 아니다. 순서대로 백 번 부르면 70ms짜리라도 7초니까 묶어서 보내는 게 전제다.

 

둘, 버릴 줄 아는 검색. 이게 더 끌린다. 지금 리랭커 점수는 순위를 매기는 숫자지 확률이 아니다. 0.7이 무슨 뜻인지 모른다. 그래서 답이 아예 없는 질의에도 상위 다섯 개를 꼬박꼬박 돌려준다. 확률이 보정돼 있으면 "0.3 아래면 결과 없음"이라고 선을 그을 수 있다. 엉뚱한 걸 자신 있게 보여주는 것보다 못 찾았다고 하는 편이 나은 경우가 많다.

 

셋, 색인 시점 분류. 지난 글에서 문서를 카테고리로 나눠 자르는 실험을 했는데 그 판별이 딱 choice 질문이다. 문서 한 개당 한 번만 부르면 되니 호출 수도 적다. 

 

넷, 답변 검증. 생성한 답이 근거 조각에 실제로 들어 있는 내용인지를 예/아니오로 묻는 것. 근거 없이 지어낸 문장을 걸러내는 자리다.


축을 열 개쯤 정해두고 조각마다 점수를 매겨 저장하면 그게 저차원 임베딩이 되지 않을까 생각해봤다. 질의도 같은 축으로 재서 가까운 걸 찾으면 되니까. 해석이 된다는 점은 매력적이다. 1024차원 벡터는 왜 이게 뽑혔는지 아무도 모르지만, 이건 "환불 축이 0.9라서"가 나온다.

 

문제는 변별력이다. 조각 하나를 보면 열 개 축 중 실제로 관련 있는 건 한둘이고 나머지는 전부 0 근처다. 그러면 "요금 축만 높은 조각"이 수천 개 생긴다. 수학적으로는 조금씩 다른데 실질적으로는 구분이 안 된다. 1024차원이 낭비처럼 보여도 그 넓이가 조각들을 서로 떨어뜨려 놓는 역할을 하고 있었던 셈이다.

 

축을 누가 정하느냐도 걸린다. 열 개를 정하려면 어떤 질문이 들어올지 미리 알아야 하는데, 새 주제 문서가 들어오면 담을 축이 없다. 임베딩이 무식해 보여도 축을 안 정해도 된다는 게 핵심 장점이었다.

 

그래서 대체가 아니라 거르는 축이나 점수 하나를 더 얹는 쪽이 맞아 보인다.

오픈소스는 없을까?

원본 Jev의 가중치는 안 풀렸다. API로만 쓸 수 있다. 대신 발표 일주일 만에 따라 만든 것들이 올라왔다. 2026년 9월 21일 기준으로 눈에 띄는 건 이 정도다.

 

com-kotobalabs/open-jev-deberta-v3-large

  기반    microsoft/deberta-v3-large
  크기    0.4B
  라이선스 Apache 2.0
  한계    영어 전용, 512토큰(state는 256으로 잘림),
          학습 도메인 세 개(은행 상담·영화 리뷰·위키 예/아니오)
  속도    H100에서 한 state에 질문 10개 28ms

제일 가볍다. 0.4B면 개인 PC에서도 돈다. 쓰는 법도 m.decide(상태, [질문들]) 한 줄이라 붙이기 쉽다. 다만 영어 전용이고 state가 256토큰에서 잘린다.

 

AlexWortega/openjev

  기반    Qwen3.5-4B
  크기    0.8B / 4B / 35B MoE
  라이선스 MIT
  성격    전제와 가설을 같이 읽고 함의·모순·중립을 답하는 크로스인코더
  언어    영어 표기

리랭킹, 채점, 조정, 에이전트 판단에 그대로 쓸 수 있다고 소개한다. Qwen 계열이라 한국어 가능성은 있어 보이는데 모델 카드에 명시는 없다.

 

ekzhang/openjev-sglang

  성격    Jev의 HTTP API를 그대로 흉내 낸 서버
  모델    Qwen3.6-35B-A3B (NVFP4)
  배포    Modal로 B200에 올리거나 로컬 SGLang에 붙이거나

모델이 아니라 서버다. 원본과 같은 모양으로 요청을 받아 오픈 모델에 태워준다. 코드를 안 고치고 갈아끼울 수 있다는 뜻이라 이게 제일 실용적일 수 있다. README에 적힌 기본값도 참고가 된다. 질문 64개까지, 선택지는 2~64개, JSON 2MiB, 분기당 32,768토큰. 원본 API 문서에는 이런 한도가 안 나와 있어서 대략의 감을 여기서 얻었다. 전체 목록은 재현판 트래커에 모여 있다.

 

정리하면 한글로 쓸 거면 아직은 원본 API밖에 없다. 공개된 것들은 영어 쪽에 맞춰져 있고 한국어가 되는지 확인된 건 못 찾았다. 데이터를 밖으로 못 보내는 상황이면 Qwen 기반 쪽을 직접 재보는 수밖에 없어 보인다.

 

마치며

싸고, 빠르고, 한글도 된다. 대신 따져가며 푸는 건 못 한다.

 

LLM을 밀어내는 물건이라기보다는 LLM에 안 물어도 되는 간단한 판단을 빠르게 하는 물건에 가깝다.

 

정리하면 아래와 같다.

  판단이 자주 일어난다        한 건에 몇 원이 아니라 몇 만 건에 몇 천 원
  기준이 매번 같다            같은 질문을 계속 묻는다
  답이 몇 가지로 정해진다      팀 이름, 등급, 예/아니오

하나라도 빠지면 굳이 이걸 쓸 이유가 없다.

아직 정확도까지는 안 재봤다. 다음 글에서 공개 문서를 규칙·작은 언어모델·Jev를 같은 판에 올려볼 생각이다.


크레딧 5달러는 한 달 뒤면 사라진다. 손에 잡히는 판단거리가 있으면 그전에 한 번 넣어보시길.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/09   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함