[사이드 프로젝트] 'Jev 호환'이라는 말에 스펙이 없어서 — jevcompat을 만들며 배운 것
댓글 불러오는 중…
댓글 불러오는 중…
jevcompat은 세 가지로 되어 있다.
POST /v1/systemone)가 지켜야 할 것을 번호 붙은 요구사항 48개로 정리한 비공식 스펙이다. 요구사항마다 MUST/SHOULD 수준과 근거 출처가 붙어 있다.jevcompat test URL: 아무 서버에나 이 스펙을 돌린다. 실패하면 원인이 된 요청과 규칙을 어긴 응답 바이트를 같이 보여준다.jevcompat proxy URL: 스펙을 안 지키는 서버 앞에 두면, 고칠 수 있는 건 고치고 고칠 수 없는 건 틀린 답을 넘기지 않고 거부한다.9월 15일 TypeSafe가 Jev를 냈다. 타입이 있는 질문(예/아니오, 선택, 점수)을 넣으면 확률이 붙은 타입 있는 답을 돌려주는 모델이다. 모델은 비공개였고 API는 대기열로만 풀렸다. 그러자 "Jev 호환"을 내건 오픈소스 서버가 9일 만에 100개 가까이 생겼다.
실제로 스타가 많은 26개의 코드를 읽어봤다.
/v1/systemone을 실제로 제공하는 건 14개뿐이었다.confidence의 뜻이 서버마다 달랐다. 최고 확률인 곳, 1·2위 차이인 곳, 1 − 엔트로피인 곳이 있었다."model": "jev-latest"를 받는 방식도 네 가지로 갈렸다."호환"이 무슨 뜻인지 확인할 기준이 없었다. 기준이 될 TypeSafe의 문서, OpenAPI 파일, SDK 두 개도 서로 여덟 군데에서 달랐다.
주변을 먼저 조사했다. 리더보드(JevBench), 캘리브레이션 벤치마크(sys1bench), semantic grep(17개), SQL 연동(25개)은 이미 있었다. 비어 있는 건 API 계약 자체였다. 마크다운이 구현체만 수십 개인 상태에서 CommonMark가 스펙과 테스트로 정리한 것과 같은 구도라고 봤다.
| 서버 | ★ | MUST | 판정 | Jev 클라이언트에서 깨지는 것 |
|---|---|---|---|---|
| kev (0.8B) | 5.8k | 32/32 | 적합 | — |
| decider (0.8B) | 338 | 32/32 | 적합 | — |
| von | 571 | 31/32 | 부적합 | 객체·배열 instructions를 거부 |
| rizzo-flow (1.7B) | 389 | 31/32 | 부적합 | 선택지 26개 초과를 거부 |
| Open-Jev (2B) | 284 | 31/32 | 부적합 | 한쪽만 있는 noul criteria를 거부 |
| laya | 20.1k | 30/32 | 부적합 | 선택지 128개를 거부, SDK가 못 읽는 null legend |
| jeff | 230 | 30/32 | 부적합 | 64개 초과를 거부, score가 자기 확률의 기댓값이 아님 |
| simple-jev (0.8B) | 499 | 29/32 | 부적합 | jev-latest를 거부, 50개 초과를 거부 |
8개 중 2개가 적합했다. 가장 눈에 띈 건 jeff였다. 요청 안의 질문 순서만 뒤집었는데 team 답이 Billing 0.768에서 0.351로 바뀌었다. 질문들이 인코더 패스 하나를 공유하기 때문이다.
검사를 만드는 건 금방이었다. 그다음 일이 훨씬 오래 걸렸다. 이 도구는 남의 오픈소스를 공개적으로 채점한다. 그래서 가장 나쁜 버그는 기능 누락이 아니라 오탐, 즉 멀쩡한 서버에 "MUST 위반"을 붙이는 것이다.
그래서 세 겹으로 검증했다.
1. 모든 검사는 실패할 수 있어야 한다. 레퍼런스 서버(jevcompat mock)는 스펙을 정확히 구현하고, 요구사항마다 결함을 일부러 넣을 수 있다(47종). CI는 세 가지를 확인한다. 깨끗한 서버에서는 전부 통과하는지, 결함마다 해당 요구사항이 실패하는지, 결함 하나가 관계없는 MUST 여러 개로 번지지 않는지. 절대 실패하지 않는 검사는 없는 검사와 같다.
2. 독립 리뷰를 세 번 받았다. 첫 리뷰에서 치명적인 문제가 나왔다. "질문 id를 바꾸면 답이 달라지는가"를 요청 두 번의 차이로 판정했는데, 확률에 노이즈가 있는 정상 서버가 약 25% 확률로 떨어졌다. 테스트는 고정 시드 하나에서 우연히 통과하고 있었다. 지금은 요청을 여러 번 보내 평균을 비교하고, 합동 표준편차로 한계를 잡고, 새로 보낸 두 번째 라운드에서도 같은 방향으로 차이가 나야 실패로 친다. 오탐률은 여러 시드로 테스트한다. 그 밖에 이런 문제들이 있었다.
3. 실서버 결과를 하나씩 사람이 봤다. 8개 서버의 실패를 전부 요청·응답 증거와 대조했다. 여기서 도구 자체의 버그 5개가 더 나왔다.
전부 공개 전에 고쳤다. 최종 보고서에 남은 실패 42개는 모두 실제 위반이다(REVIEW.md).