AIDive

영상 팩

Claude Code의 Jev: hint 모드, 게이트웨이 자체 벤치마크, 요청 캡처

읽는 데 13분

TL;DR

  • Claude Code 안에서 jev-gateway는 도구를 강제하지 않습니다. steer: thinking || cached ? "hint" : "tool_choice" 한 줄이, 요청에 extended thinking이나 캐시된 대화가 들어 있는 순간 hint 모드로 전환합니다. 실제 Claude Code 요청은 첫 턴부터 둘 다 갖고 있습니다.
  • hint는 마지막 user 메시지 뒤에 붙는 두 문장짜리 <system-reminder>입니다. 모델은 이를 무시해도 되고, Claude Code가 이미 자체 system reminder를 마지막 블록으로 붙여 둔 경우에는 hint가 아예 붙지 않습니다.
  • 게이트웨이 자체 벤치마크(120 세션)에 따르면, Claude 모델에서 라우팅은 디버깅에서는 이득이고 기능 개발에서는 손해입니다. 기능 작업에서 Opus 5는 입력 토큰 +61%, 요청 수 +47%, 시간 +83%, Sonnet 5는 입력 +16%, 시간 +37%였습니다.
  • Jev가 제대로 먹히는 곳은 Codex입니다. 게이트웨이가 거기서는 도구를 강제하며, Jev는 Codex 요청의 76100%를 유도한 반면 Claude Code 요청은 3451%였습니다.
  • 우리 머신에서 측정한 결과: 깨끗한 Claude Code 2.1.280 요청은 이미 도구 24개와 프리픽스 토큰 47,411개를 싣고 있고, MCP 서버가 있는 일반 환경은 도구 40개와 57,277 토큰을 싣습니다. 게이트웨이는 이 도구 목록을 매 호출마다 Jev에 다시 보냅니다.
  • 가장 별이 많은 Jev 도구인 fast-jev-compaction에는, 최신 Claude Code 빌드에서 훅이 등록되지 않는다는 이슈와 전체 트랜스크립트가 서드파티 API로 나간다는 이슈가 열려 있습니다. 아직은 아닙니다.

측정이 말해 주는 것

Jev는 텍스트 생성기가 아니라 결정 모델입니다. 벤더는 입력을 $0.042 / MTok, 출력은 무료로 책정하고, 엔드 투 엔드 응답 시간을 70ms-500ms로 제시하며, "193.6x faster, 444.6x cheaper"라는 헤드라인 바로 아래에 이 수치들이 "are on the higher end of real world gains"라고 적어 두었습니다 s3. 같은 글은 기준 답안이 GPT-6 Astra와 Fable 5.1의 평균이라서 비교가 OpenAI와 Anthropic 모델 쪽으로 치우친다는 점도 인정합니다 s3.

jev-gateway는 환경 변수 하나로 Claude Code에 연결됩니다. bin/clients.mjs가 ANTHROPIC_BASE_URL을 로컬 게이트웨이로 설정하고 Max 로그인은 건드리지 않습니다 s1. src/adapters/messages.ts에서 게이트웨이는 다음 단계에 어떤 도구가 맞는지 Jev에게 묻고, 그 답을 어떻게 전달할지 결정합니다. 요청에 thinking이 켜져 있거나 cache_control 블록이 있으면 hint를 보냅니다. 그렇지 않으면 tool_choice를 설정합니다 s1. hint의 내용은 이렇습니다. 도구 라우팅 모델이 해당 도구를 가장 관련 있는 다음 단계로 제안하고 있으며, 사용자가 실제로 요청한 것과 맞지 않으면 무시하라는 것입니다. 이 문구는 <system-reminder> 블록으로 마지막 user 메시지에 붙습니다 s1.

Anthropic API는 다른 선택지를 주지 않습니다. 수동 extended thinking이 켜져 있으면 tool_choice: any와 tool_choice: tool은 지원되지 않고 에러를 반환하며, Claude Opus 5.5, Claude Fable 5.1, Claude Mythos 5.1은 thinking 여부와 상관없이 강제 도구 사용에 400을 반환합니다 s4. 게이트웨이의 주석이 놓친 뉘앙스가 하나 있습니다. 문서에 따르면 Claude Opus 5는 thinking이 켜져 있어도 강제 tool choice를 지원합니다 s4. 캐싱의 계층 구조는 tools, system, messages 순서이며, tool_choice를 바꾸면 messages 캐시만 무효화되고 도구 정의를 수정하면 캐시 전체가 무효화됩니다. 게이트웨이가 도구 설명을 고쳐 쓰는 대신 블록을 덧붙이는 이유가 이것입니다 s5.

거의 아무도 인용하지 않는 벤치마크가 게이트웨이 작성자 본인의 것입니다. 모델 6개, 작업 2개, 모드당 5회 실행, 2026-09-18과 19일에 걸친 에이전트 세션 120개이며, GPT 모델은 Codex 0.154, Claude 모델은 Claude Code 2.1에서 돌렸고, 모든 에이전트는 MCP 서버, 플러그인, 스킬이 없는 깨끗한 상태였습니다 s2. chess-bugfix에서는 모든 모델이 라우팅을 쓰면 토큰을 덜 썼고 정확도가 떨어진 모델은 없었습니다. 기능 작업인 chess-san에서는 라우팅이 Opus 5와 Sonnet 5를 뚜렷하게 악화시켰고, 저자들은 원인을 이렇게 짚습니다. 게이트웨이는 Claude 모델에만 hint를 쓰기 때문에, 맞지 않는 hint는 공짜로 무시되지 않고 우회 비용으로 돌아옵니다 s2. 라우팅이 정확도를 떨어뜨린 사례도 한 번 있었습니다. GPT-5.6 Luna는 chess-san을 라우팅 없이 5번 중 5번 풀었지만 라우팅을 쓰면 5번 중 3번이었습니다 s2. 저자들은 입력 토큰의 대부분(80~96%)이 캐시되기 때문에 입력 절감은 같은 양의 출력 토큰 절감보다 금전적 가치가 작다고 덧붙이며, Jev 자체의 비용은 5회 실행당 0.5센트에서 10센트 사이였다고 밝힙니다 s2. 120회 중 한 번, Luna 시리즈의 chess-bugfix.on.3은 에이전트가 /tmp에서 다른 실행의 테스트 스크립트를 찾아냈기 때문에 contaminated로 표시되어 있습니다 s2.

우리 자체 테스트의 계기가 된 README 각주는 이렇습니다. --user-tools를 쓰면 한 환경에서 Claude Code 요청마다 도구 285개와 약 200,000 토큰을 보냈고, 깨끗한 환경은 도구 6개와 7,000 토큰이었습니다 s2. 우리도 같은 자리에서 측정했습니다. 깨끗한 Claude Code 2.1.280 요청은 도구 24개, 도구 정의 87,547자, 과금된 프리픽스 토큰 47,411개(쓰기 16,221, 읽기 31,190)를 싣습니다. 전체 환경은 도구 40개, 정의 93,179자, 프리픽스 토큰 57,277개이고 전부 쓰기입니다. 두 요청 모두 thinking: {type: "adaptive"}와 cache_control 블록 3개를 갖고 tool_choice는 없는데, 이는 messages.ts에서 hint 모드가 고정되는 바로 그 조건입니다 s1. 단순한 "ok" 응답 한 번의 API 환산 비용은 깨끗한 Sonnet 5 실행에서 $0.07, 전체 Fable 5.1 실행에서 $1.15이며, 게이트웨이 런처가 차지하는 것과 같은 자리의 Claude Code 자체 total_cost_usd와 usage 필드에서 읽은 값입니다 s1.

"instant compaction" 스레드(점수 495, 댓글 117개)의 주인공인 fast-jev-compaction 플러그인 s9은 별 개수보다 열린 이슈가 더 중요합니다. #21은 Claude Code 2.1.272에서 session.compact와 turn.complete가 인식되는 훅 이벤트가 아니라서 설치 후 Hooks (0)이 뜬다고 보고하고, #88은 훅이 compaction을 대체할 수 없으며 전체 트랜스크립트가 서드파티 API로 전송된다고 말하고, #65는 compaction 한 번 뒤에 "work done" 보고가 9번 연속 조작되었음을 기록하고, #89는 --resume 시 compaction이 되돌려진다고 말합니다 s7. 스레드의 최다 불만은 84점으로, 벤더의 ToS와 데이터 통제입니다 s9. 스킬 추천 쿡북은 벤더가 에이전트 도구 목록에 대해 공개한 유일하게 측정된 성과입니다. 잘못된 스킬이 로드되는 비율은 16.8%에서 7.3%로, 맞는 스킬이 없는데 스킬이 로드되는 비율은 9.8%에서 4.0%로 떨어집니다 s13.

측정 결과

게이트웨이의 벤치마크이며, 퍼센트는 라우팅을 끈 같은 모델과 비교한 값입니다 s2.

chess-bugfix: 주입된 버그 5개 찾아 고치기

모델 해결, 켬 / 끔 출력 토큰 입력 토큰 LLM 요청 초 Jev 유도
GPT-6 Astra 5/5 · 5/5 1,226 (-57%) 96k (-7%) 5 (0%) 41 (-39%) 100%
GPT-5.6 Sol 5/5 · 5/5 3,211 (-57%) 202k (-40%) 9 (-36%) 78 (-36%) 93%
GPT-5.6 Luna 1/4 · 0/5 10,519 (-12%) 506k (-10%) 19.5 (-15%) 200 (+10%) 86%
Fable 5.1 5/5 · 5/5 8,675 (-13%) 276k (-19%) 14 (-22%) 148 (+6%) 45%
Opus 5 5/5 · 5/5 16,693 (-7%) 406k (-22%) 18 (-14%) 218 (+2%) 38%
Sonnet 5 5/5 · 5/5 16,623 (-41%) 616k (-48%) 26 (-26%) 243 (-25%) 34%

chess-san: 동작하는 엔진에 대수 기보법 추가하기

모델 해결, 켬 / 끔 출력 토큰 입력 토큰 LLM 요청 초 Jev 유도
GPT-6 Astra 5/5 · 5/5 3,663 (0%) 143k (+2%) 7 (0%) 88 (+8%) 95%
GPT-5.6 Sol 5/5 · 5/5 5,096 (-9%) 147k (-39%) 7 (-36%) 78 (-16%) 86%
GPT-5.6 Luna 3/5 · 5/5 6,809 (-14%) 315k (-51%) 14 (-42%) 121 (-14%) 76%
Fable 5.1 5/5 · 5/5 13,497 (-24%) 331k (-27%) 13 (-19%) 167 (-26%) 51%
Opus 5 5/5 · 5/5 20,152 (+22%) 676k (+61%) 25 (+47%) 390 (+83%) 44%
Sonnet 5 5/5 · 5/5 23,487 (+9%) 991k (+16%) 32 (+3%) 327 (+37%) 42%

우리가 직접 캡처한 요청이며, jev-gateway가 차지하는 바로 그 자리입니다 s1.

깨끗한 환경 전체 환경
Claude Code가 고른 모델 claude-sonnet-5 claude-fable-5-1 (사용자 설정, 1M)
요청의 thinking {type: "adaptive"} {type: "adaptive"}
cache_control 블록 3 3
tool_choice 없음 (auto) 없음 (auto)
요청의 도구 수 24 40 (내장 28 + MCP 12)
도구 정의, 글자 수 87,547 93,179
시스템 프롬프트, 글자 수 27,754 12,436
전체 요청, 글자 수 134,882 155,718
과금된 프리픽스 토큰 (캐시 쓰기 + 읽기) 47,411 (쓰기 16,221, 읽기 31,190) 57,277 (전부 쓰기)
출력 토큰 4 4
"ok" 한 번의 API 환산 비용 $0.07 $1.15

프로토콜: 127.0.0.1:8790의 60줄짜리 로깅 프록시가 모든 요청을 https://api.anthropic.com으로 바이트 단위 그대로 전달하면서 요청에 담긴 내용을 기록합니다. bin/clients.mjs가 jev-gateway에 주는 자리와 정확히 같습니다. Claude Code 2.1.280을 헤드리스로, claude -p "Reply with the single word ok. Do not use any tool." --output-format json --max-turns 1로, 추적 파일 1,021개짜리 비공개 Expo 저장소에서 claude.ai 구독으로 실행했습니다. 깨끗한 환경: 빈 디렉터리를 가리키는 CLAUDE_CONFIG_DIR, --strict-mcp-config, --setting-sources project. 전체 환경: 머신의 평소 사용자 설정, 프로젝트 .mcp.json, 사용자 MCP 서버, 설치된 플러그인. 구성당 요청 한 번, 첫 턴만 측정했습니다. Jev 키가 없었으므로 회귀 수치는 게이트웨이 벤치를 재현한 것이 아니라 그대로 옮긴 것입니다.

월요일에 할 일

  • 라우터를 추가하기 전에 먼저 자기 환경을 측정하세요. 로깅 프록시를 띄우고, ANTHROPIC_BASE_URL을 그쪽으로 향하게 한 뒤, claude -p "Reply with the single word ok." --output-format json --max-turns 1을 실행해서 출력의 cache_creation_input_tokens와 cache_read_input_tokens를 읽으세요.
  • 그 요청에 들어 있는 도구 수를 세세요. 거의 안 쓰는 MCP 서버가 목록을 부풀리고 있다면 .mcp.json에서 빼거나 프로젝트별로 범위를 좁히세요. 이 절감은 라우터 유무와 상관없이 모든 요청에 적용됩니다.
  • 그래도 Claude Code에서 Jev를 쓰고 싶다면, jev-gateway 클론에서 src/adapters/messages.ts를 열어 steer 줄을 확인하세요. thinking이나 캐싱이 켜져 있으면 라우팅이 아니라 hint를 사는 셈입니다.
  • 체스 표를 믿기보다 --user-tools로 게이트웨이 벤치를 자기 저장소에서 돌려 보세요. 버그 추적 작업에서 해결/미해결 변화 없이 요청 수가 줄어드는 경우에만 라우팅을 유지하세요.
  • 이슈 #21, #88, #89가 닫히기 전에는 fast-jev-compaction을 설치하지 마세요. 설치 후 /hooks에 훅이 0개보다 많이 나오는지 확인하세요.
  • 키를 붙여 넣기 전에 벤더 ToS를 읽으세요. 라우팅된 모든 요청은 도구 목록과 마지막 메시지를 보내고, compaction 플러그인은 전체 트랜스크립트를 보냅니다.
  • Codex도 쓴다면 거기서 Jev를 먼저 테스트하세요. 벤치에서 효과가 나는 쪽은 강제 tool_choice입니다.

더 알아보기

  • 모델별 강제 도구 사용 표. 어떤 모델이 400을 반환하는지, 어떤 thinking 모드가 any와 tool을 막는지 나와 있습니다 s4.
  • 캐시 무효화 표. tools, system, messages 순서와, 게이트웨이 설계를 설명해 주는 tool_choice 행이 있습니다 s5.
  • jev-gateway 이슈 #24. 세션 내내 변하지 않는 도구 목록이 요청마다 Jev에 다시 전송되며, 대시보드가 보여 주지 않는 비용 중심입니다 s14.
  • 벤치 README의 데이터 무결성 항목. 120회 중 119회는 서로 격리되었고, 한 회는 runs.jsonl에서 contaminated로 표시되었습니다 s2.
  • 코딩 에이전트라는 틀 밖에서, 공개 데이터와 비공개 데이터에 대해 Jev를 분류기나 필터로 쓴 독립적인 분석 s12.
  • 벤더의 평가가 정답이 아니라 모델 두 개를 기준으로 측정하는 이유와, 그것이 헤드라인 배수에 미치는 영향 s11.
  • "Jev가 고르고 LLM이 쓴다"는 분업과 같은 날 수정된 localhost 노출을 짚어 보는 jev-gateway 서드파티 리뷰 s8.
  • 가격과 보조금 문제가 공개적으로 논쟁된 HN 런칭 스레드 s10.

출처

FAQ

jev-gateway가 Claude Code 안에서 도구를 강제하는 경우가 있나요?

요청에 extended thinking도 cache_control 블록도 없을 때만 그렇습니다. 우리가 캡처한 첫 턴 요청에는 깨끗한 환경이든 전체 환경이든 둘 다 있었으므로, 실제로는 게이트웨이가 hint를 보냅니다.

게이트웨이는 왜 도구 설명을 고쳐 써서 더 강하게 유도하지 않나요?

도구 정의를 수정하면 tools, system, messages까지 프롬프트 캐시 전체가 무효화됩니다. 마지막 user 메시지에 블록을 덧붙이면 messages 레벨만 건드리므로, hint를 넣기에 가장 저렴한 자리입니다.

그럼 Jev는 코딩에 쓸모없나요?

아닙니다. 벤치에서는 도구가 강제되고 요청의 76~100%가 유도되는 Codex에서, 그리고 모든 모델의 디버깅 작업에서 이득이 났습니다. 게이트웨이 자체 수치가 뒷받침하지 않는 것은 "가장 저렴한 Claude Code"라는 프레이밍입니다.

fast-jev-compaction을 써 봐도 될까요?

훅 등록 이슈(#21, #88)와 --resume 이슈(#89)가 닫힐 때까지 기다리세요. 그리고 전체 트랜스크립트가 서드파티 API로 나가는 것이 자신의 저장소에서 허용 가능한지 판단하세요.