X · 2026-09-17

Jev가 로컬 하네스 라우팅을 해결했다

트윗은 하네스 분기이고, GitHub의 jev-router는 Claude 모델 갈아끼우기다. /model의 Jev Auto는 공식 env 한 줄이다.

Lahfir @mdlahfir · 원문 트윗 · 조회 31,294 · 답글 11 · 재게시 23 · 좋아요 197

읽기 전에

이 글이 묻는 것: 트윗의 Jev, npm의 jev-router, Claude Code /model의 Jev Auto는 같은 물건인가?

멘탈 모델

Jev는 채팅 모델이 아니라 typed classifier다. 그 위에 세 구현이 얹힌다. (1) Lahfir의 하네스 분기 — 공개본은 lahfir/claude-plugins. (2) Pratyush의 모델 분기 — gargpratyush/jev-router, Claude 안에서만. (3) TypeSafe API 자체 — TypeSafe 문서. /model 행은 Claude를 해킹한 결과가 아니라 Claude Code env-vars의 커스텀 옵션 1개다.

권장 읽기 순서

  1. Executive Summary의 세 층 표 (2분).
  2. 팩트체크: npm 404, agent-desktop 오인, 43% 미측정 (3분).
  3. 완역 트윗·영상 → /model 경로 file:line → 실전 가이드. jev-claude를 llmux 별칭 자리에 넣지 말 것.

요약만: 6분. 소스 경로까지: 18분.

선행 개념 (이것만)

  • 하네스 — Claude Code, Codex, Opencode처럼 도구·권한·세션을 가진 실행기.
  • ANTHROPIC_CUSTOM_MODEL_OPTION — /model에 빌트인 뒤 행 1개를 추가. ID 검증 없음.
  • ANTHROPIC_BASE_URL — 요청을 어디로 보낼지. 커스텀이면 모델 이름도 통과.

점검 질문

  1. npm install -g jev-router는 오늘 되는가?
  2. Jev Auto 행을 만드는 env 변수 이름은 무엇인가?
  3. 이 머신에서 jev-claude를 띄우면 llmux 모델이 남는가?

Executive Summary

2026-09-17 05:01 KST, Lahfir는 Jev가 로컬 하네스/모델 라우팅을 해결했다고 썼다. 영상은 node .claude/pick-model.mjs가 디프 리뷰를 Opencode/Gemini 3.8 Flash로 보낸다. 공개된 가까운 구현은 같은 날의 delegate 플러그인이다. 댓글의 jev-router는 Claude 모델만 갈아끼운다.

3층

API / 모델 프록시 / 하네스 플러그인. 영상이 네 번째 비공개 훅.

npm 404

jev-router 패키지는 registry에 없다. clone 후 npm link.

jev-auto

CUSTOM_MODEL_OPTION 센티널. 프록시만 실제 id로 재작성.

llmux 충돌

jev-claude는 ~/.local/bin/claude를 띄운다. 별칭 llmux run을 건너뛴다.

주장 전수

트윗
Claude Code + Codex + Opencode. 예전엔 시스템 프롬프트로 강제. 이제 위임 전 결정론적 훅 + Jev. 기계적→Haiku, 지능적→Opus 서브에이전트, 장기 구현→외부 하네스.
영상
Ghostty, nuxiba/vda-architecture. pick-model.mjs가 opencode · gemini-3.8-flash, conf 0.90 (0.93 / 0.06 / 0.01).
Jev
TypeSafe System One. state+질문 → choice/probabilities/confidence. 생성 없음. TypeSafe 퀵스타트
jev-router
진짜 claude spawn + loopback 프록시. /v1/messages의 model만 재작성. 인증 헤더는 전달만. MIT, 5커밋, stars 12(캡처 시).
/model
ANTHROPIC_CUSTOM_MODEL_OPTION=jev-auto 등 4변수 + BASE_URL. 공식 문서에 있는 계약. 커스텀 행은 1개.
delegate
lahfir/claude-plugins. /delegate:setup, /delegate:route. 스크립트는 JSON만. child_process 없음.
오인
Zee의 OSS 질문에 agent-desktop 카드. computer-use이지 라우터가 아님. lahfir/agent-desktop
43%
README 헤드라인. 이 세션에서 미측정.

팩트체크

신뢰도

B

트윗·영상·세 공개 레포·공식 env 문서는 맞다. README의 npm 설치는 거짓. 43%와 “무료 키”는 미검증. pick-model.mjs는 공개 레포에 없다.

검증일 2026-09-17. 트윗은 aside 로그인 세션으로 영어 원문 추출. 소스는 git clone HEAD a5694a6 / delegate 724676a. npm registry와 Claude Code 문서는 같은 날 조회.

사실

TypeSafe Jev는 System One 모델이고 systemOne API는 state + typed questions를 받는다.

TypeSafe 문서 · TypeSafe 퀵스타트

사실

ANTHROPIC_CUSTOM_MODEL_OPTION은 /model에 커스텀 행 1개를 추가하고, 그 ID는 검증하지 않는다. 커스텀 BASE_URL에서는 모델 이름이 통과한다.

Claude Code env-vars · Claude Code model-config

사실

jev-claude는 위 env를 AUTO_MODEL=jev-auto로 주입하고, 키가 있으면 127.0.0.1 프록시를 ANTHROPIC_BASE_URL로 건다. bin/jev-claude.mjs:21–32, 116–119. src/config.mjs:32.

gargpratyush/jev-router

거짓

README의 npm install -g jev-router는 2026-09-17 기준 설치 경로가 아니다. registry.npmjs.org/jev-router → HTTP 404. @typesafe-ai/sdk 0.6.0은 존재한다.

@typesafe-ai/sdk · 직접 GET 영수증

사실

Lahfir는 하네스 라우터를 MIT로 공개했다. marketplace lahfir-plugins, 플러그인 delegate. 트윗과 같은 날 업데이트.

lahfir/claude-plugins

부분

영상 속 pick-model.mjs는 delegate와 같은 클래스지만 그 파일은 lahfir 공개 레포에서 검색되지 않았다. 공개 등가물은 delegate.mjs다.

lahfir/claude-plugins · 영상 포스터 img/tweet-video-poster.jpg

거짓

agent-desktop은 이 라우팅의 OSS 드롭이 아니다. 데스크톱 computer-use (Apache-2.0, ~1.1k).

lahfir/agent-desktop

불확실

“43% less tokens”는 README 주장. 벤치 방법·커밋이 없다. 이 세션에서 재현하지 않았다.

gargpratyush/jev-router

불확실

README “Get a key from TypeSafe for free.” 문서 인덱스·퀵스타트에 가격/프리티어 문장이 없다. 키 발급 URL만 있다.

TypeSafe 키 콘솔 · TypeSafe 퀵스타트

사실

이 머신: zsh alias claude=llmux run. PATH의 실행 파일은 ~/.local/bin/claude → 2.1.274. jev-claude resolveClaude()는 accessSync라 별칭을 건너뛴다. settings.statusLine이 이미 있어 jev statusline 주입은 스킵된다.

로컬 which/settings.json · Claude Code 설치


원본 (완역)

트윗

Lahfir @mdlahfir, 2026년 9월 17일 오전 5:01.

Jev가 로컬 하네스/모델 라우팅을 해결했습니다.

저는 Claude Code, Codex, Opencode의 조합을 로컬 에이전틱 스택으로 사용하며, 다른 하네스에 대한 라우팅은 항상 시스템 프롬프트/규칙에서 강제되었습니다.

Claude Code가 위임 전에 결정할 수 있는 결정론적 훅으로, Jev는 작업에 따라 올바른 하네스/모델로 라우팅하는 데 도움을 주며, 작업의 강도/지능에 따라 꽤 정확합니다.

기계적 작업은 Haiku로 라우팅됩니다
지능적인 작업은 Opus 하위 에이전트로 라우팅됩니다
장기 실행 구현 작업은 외부 하네스로 라우팅됩니다

pick-model.mjs가 디프 리뷰 작업을 opencode/gemini-3.8-flash로 고른 화면
첨부 영상 17.6초의 포스터. 영상 파일은 이 문서에 넣지 않았다. 명령: node .claude/pick-model.mjs "read the whole staging..integration diff and report findings with file:line". 결과: opencode · openrouter/google/gemini-3.8-flash (harness picked) conf 0.90. 막대: 0.93 / opus 0.06 / sonnet 0.01.

조회 31,294 · 답글 11 · 재게시 23 · 좋아요 197 · 북마크 223 (aside 캡처 시점).

스레드

catman 댓글

유용한 패턴은 정책 기반 라우팅이다. 먼저 작업 복잡도를 분류하고, 기계적 일은 싼 모델로, 깊거나 오래 가는 일은 더 강한 전문가로 보낸다.

Lahfir: “Exactly. 결정 지점이 여러 개인 엔터프라이즈 워크플로에서 큰 쓰임새라고 본다.” 동의 댓글

Pratyush Garg 댓글

나는 Claude Code 사용자 전용으로 하나 만들었다. 여기서 누구나 해볼 수 있다: gargpratyush/jev-router

잘린 /model 피커, 4번 Jev Auto 선택
댓글 첨부. 원본 전체 피커는 jev-router README의 아래 그림.
Claude Code /model 피커에 Jev Auto가 4번 행으로 선택된 화면
jev-router README. Default / Opus / Haiku 다음 4. Jev Auto. “Route each turn to the cheapest model that can do it.”

Lahfir: “This is amazing!”

Zee @mozoobear: “오픈소스 할 건가요?”

Lahfir의 답 카드는 lahfir/agent-desktop — “Agent Desktop gives any agent reliable computer use on the desktop.” 라우터와 다른 물건이다. 같은 날 공개된 가까운 물건은 lahfir/claude-plugins.

WunderCorp: “Nice routing feature! We’ll put this in loki.computer asap.”

Jev란 무엇인가

Jev는 TypeSafe의 System One 모델이다. 문장: state와 typed question을 보내고, 코드가 바로 쓰는 구조화 답을 받는다. 텍스트 생성도 파싱도 없다. 질문 종류는 Choice / Score / Noul. 여러 질문을 한 호출에서 병렬 평가한다. TypeSafe 문서 intent-routing

jev-router는 JS SDK @typesafe-ai/sdkTypeSafeClient.systemOne을 쓴다 (src/router.mjs). delegate는 SDK 없이 POST https://api.typesafe.ai/v1/systemone에 Bearer 키를 붙인다 (delegate.mjs:203). 모델 필드는 jev-latest.

에이전트에게 API 쓰는 법을 가르치는 스킬은 따로 있다. TypeSafe agent skillclaude plugin marketplace add typesafe-ai/skillstypesafe@typesafe-ai. 이것은 /model 행이 아니다.

트윗이 보여 주는 것

트윗의 라우팅 축은 누구를 실행할 것인가다. Haiku와 Opus는 Claude Code 안의 티어고, “외부 하네스”는 Codex/Opencode 같은 다른 CLI 다. 영상은 후자를 보여 준다: 분류기가 하네스 이름과 모델 id를 고르고, 노란 프롬프트에 opencode run -m openrouter/google/gemini-3.8-flash가 남는다.

예전의 방법(시스템 프롬프트에 “이런 일은 Codex로”)은 모델이 잊거나 무시할 수 있다. 훅은 위임 전에 결정한다. delegate 스킬도 같은 계약이다: “The plugin decides. You launch.” 스크립트는 실행하지 않는다.

catman의 “policy-based routing”은 이 구조의 일반형이다. TypeSafe 문서의 intent-routing과 같다: 싼 분류 1회 후, 코드 / 전문 모델 / 사람으로 분기. intent-routing

/model에 Jev Auto가 뜨는 경로

Claude Code는 시작 시 환경변수를 읽어 빌트인 행 뒤에 커스텀 행 하나를 붙인다. Claude Code env-vars Claude Code model-config

변수jev-claude가 넣는 값
ANTHROPIC_CUSTOM_MODEL_OPTIONjev-auto (src/config.mjs:32 AUTO_MODEL)
ANTHROPIC_CUSTOM_MODEL_OPTION_NAMEJev Auto
ANTHROPIC_CUSTOM_MODEL_OPTION_DESCRIPTIONRoute each turn to the cheapest model that can do it
ANTHROPIC_CUSTOM_MODEL_OPTION_SUPPORTED_CAPABILITIESthinking,adaptive_thinking,interleaved_thinking,effort,max_effort
ANTHROPIC_MODEL비어 있으면 jev-auto (세션만. settings에 안 씀)
ANTHROPIC_BASE_URLhttp://127.0.0.1:<loopback port>

주입 위치: bin/jev-claude.mjs autoModelEnv() 21–32행. 키가 있을 때만 startProxy() 후 Object.assign (116–119행). 키 없으면 라우팅 없이 일반 claude를 띄우고 stderr에 경고.

왜 가짜 이름이 통과하나. 공식 문서: 인식 검사는 Anthropic API에서만 돈다. 커스텀 BASE_URL에서는 공급자가 이름을 정의하므로 아무 문자열이나 통과한다. CUSTOM_MODEL_OPTION ID도 검증을 건너뛴다. 그래서 센티널 jev-auto가 프록시에 그대로 도착한다.

프록시 (src/proxy.mjs):

  1. HEAD / → 200. Claude Code가 첫 요청 전 프로브.
  2. /v1/messages가 아니면 그대로 업스트림.
  3. body.model !== 'jev-auto' → 통과. 유저가 고른 모델 + 내부 Haiku 제목/요약 호출.
  4. 새 유저 턴만 Jev에 묻는다: tools가 있고, 마지막 메시지가 user text이고, tool_result가 아님. system-reminder는 지운다.
  5. 같은 대화의 툴 루프는 conversationKey(session_id + 첫 메시지 텍스트 SHA1)로 티어를 핀. 서브에이전트는 키가 달라 새 핀.
  6. applyTier가 실제 id로 바꾸고, Haiku면 thinking/effort/clear_thinking 전략을 벗겨 400을 막는다.
  7. authorization 헤더는 읽지 않고 api.anthropic.com으로 전달.

티어 id (src/config.mjs): haiku claude-haiku-4-5-20251001 (thinking/effort 없음) · sonnet claude-sonnet-5 · opus claude-opus-5 · fable claude-fable-5-1 (JEV_ALLOW_FABLE=1).

UI는 요청한 이름만 보여 준다. 그래서 status line을 주입하려 한다. 이미 statusLine이 있으면 코드를 건드리지 않는다 (bin/jev-claude.mjs:47–55). Enter로 고르면 settings.json.model에 jev-auto가 저장된다. 종료 시 이전 값으로 되돌린다 (src/settings.mjs). 크래시하면 일반 claude가 가짜 이름으로 깨질 수 있다.

라우팅 정책

src/policy.mjs decide(), 테스트 test/policy.test.mjs. 순서:

  1. 프롬프트에 use opus / switch to haiku 류 → 그 티어. Jev를 이긴다.
  2. Jev 실패·타임아웃·모르는 choice → 현재 모델 유지.
  3. confidence < 0.6: 다운그레이드 거부. 업그레이드는 sonnet 천장.
  4. 다운그레이드인데 contextTokens > 20,000 → 거부 (캐시 재작성 비용).
  5. 없는 티어는 위로 치환하되 fable로는 올라가지 않음. fable은 요청됐을 때만.

Jev 질문은 “답의 길이가 아니라 요구되는 추론”을 보라고 못 박는다. README: “answer in one sentence”인 하드 디버그가 Haiku 0.21에서 Opus 0.81로 옮겨졌다 — 저자 측정, 여기선 재현 안 함.

타임아웃: 시도 1.5s, 전체 3s, 재시도 1회. 실패는 라우팅을 막지 않는다 (fail-open).

공개된 것 / 공개되지 않은 것

공개하는 일/model 행
TypeSafe Jev API문서·SDK·콘솔classifier없음
typesafe-ai/skills플러그인 MIT에이전트에게 API 사용법없음
jev-routerGitHub MIT. npm 없음Claude 모델 티어 재작성있음 (jev-auto)
delegate 플러그인GitHub MIT세션/서브에이전트/외부 CLI 선택. 실행 안 함없음
agent-desktopGitHub Apache-2.0데스크톱 computer-use없음
pick-model.mjs영상만분류 + opencode 론치 데모없음
TypeSafe 가격문서에 없음

프롬프트 텍스트는 라우팅 결정 때 TypeSafe로 간다 (jev-router README Limitations). 그 외는 안 간다. delegate도 task 문자열만 state에 넣는다.

이 스택에 넣는 실전 가이드

이 머신 전제: claudellmux run 별칭. 실행 파일은 ~/.local/bin/claude (2.1.274). settings.model은 grok[1m]. statusLine은 bash ~/.claude/statusline-command.sh. ~/.jev-claude.env 없음.

하지 말 것

트윗에 가까운 공개물 — delegate

zbrain은 이미 서브에이전트·trinity·llmux가 있다. 분류만 빌려 오고 론치는 기존 게이트에 두는 편이 맞다.

/plugin marketplace add lahfir/claude-plugins
/plugin install delegate@lahfir-plugins
/delegate:setup
# TYPESAFE_API_KEY를 셸이나 프로젝트 env에
/delegate:route <task>

allowlist의 fits는 “무엇을 주고 무엇을 주지 않는지”를 같이 써야 한다. 칭찬만 있으면 그 옵션이 전부 이긴다. 스크립트는 명령을 돌려줄 뿐 실행하지 않는다. 외부 CLI 론치는 기존 유저 게이트를 유지한다.

모델 라우터를 만져볼 때 — jev-router

git clone https://github.com/gargpratyush/jev-router
cd jev-router && npm install
echo 'JEV_API_KEY=…' > ~/.jev-claude.env
JEV_NO_STATUSLINE=1 node bin/jev-claude.mjs

JEV_NO_STATUSLINE=1: 기존 statusLine을 덮지 못하게. 라우팅 결과는 TUI에 안 보인다. 보려면 ~/.jev-claude.log (JEV_DEBUG=1) 또는 statusline-command.sh에 tmp/jev-claude/<session>.json 읽기를 합친다 — 합치기는 별 작업이다.

이 세션은 구독 Claude만 쓴다. llmux 모델은 없다. 그게 목표면 쓰지 않는다.

직접 /model 행만 달고 싶을 때

프록시 없이 행만 추가하는 것은 공식 계약이다. 다만 센티널 이름을 Anthropic이 받으면 첫 요청이 실패한다. 행 + 재작성은 항상 쌍이다.

추천 순서

  1. delegate를 플러그인으로만 설치하고, 론치 없이 JSON을 본다.
  2. allowlist를 inline / subagent(haiku·opus) 정도로 좁힌다. 외부 CLI는 명시 게이트 뒤에.
  3. jev-claude는 별 바이너리로만. PATH의 claude 별칭은 그대로.
  4. 43%를 믿기 전에 JEV_DEBUG 로그로 턴당 티어를 세어 본다.

원본 링크·인용

본문 인라인 링크가 정본이다. 이 목록은 보조.


기타

캡처 2026-09-17. ui-ux-ref openai. 원문 원문 트윗.