3줄 요약
- 브라질 개발자 비니시우스 라나(Vinicius Lana)가 2026년 9월 17일에 공개한 에이전트 평가 저장소다. 도구 100개를 둔 개인 비서 에이전트에서, 다음 도구를 LLM이 직접 고르는 경우와 TypeSafe의 분류기 Jev가 대신 고르는 경우를 같은 과제로 비교한다.
- 모델 7종에 과제 6개를 두 모드로 돌린 결과, 입력 토큰 합계는 180만에서 27만으로 85.1% 줄었고 추정 비용은 8.07달러에서 1.52달러로 내려갔다. 그 대가로 모델 호출 횟수는 157회에서 208회로 늘었고, 요구 단계 이행률은 98.4%에서 92.1%로 떨어졌다.
- 이름이 닮은 도구에 LLM이 걸려 넘어지리라는 이 실험의 출발 가설은 확인되지 않았다. 84회 실행을 통틀어 오답 도구를 부른 것은 한 번뿐인데, 그 한 번을 저지른 쪽이 분류기였다.
환경변수 하나만 다른 두 모드
저장소는 Vercel의 에이전트 프레임워크 eve로 만든 개인 비서 에이전트 하나를 담고 있다. 도구 100개는 전부 목(mock)이고, 모델은 모두 OpenRouter를 거쳐 호출된다. 두 모드는 AGENT_MODE 환경변수 하나로만 달라지며, 시스템 프롬프트, 도구 카탈로그, 평가 코드, 대시보드는 두 모드에서 같다.
AGENT_MODE | 도구를 고르는 주체 | 모델 추론 |
|---|---|---|
llm-direct (기본값) | LLM이 매 단계 도구 100개를 모두 보고 직접 고른다 | 켬 (DIRECT_REASONING, 기본 medium) |
jev-classifier | 모든 모델 단계 직전에 Jev가 대화 상태를 받아 고른다. LLM에게는 선택된 도구 하나만 노출되고, LLM은 인자만 채운다 | 엔드포인트가 허용하는 최저값으로 설정하며, 가능하면 끈다 |
Jev는 텍스트를 생성하지 않는 System One 분류기다. 닫힌 질문에 확률 분포와 신뢰도로 답한다. 라우터는 매번 같은 상태를 놓고 두 가지를 묻는다.
next_tool: 도구 100개에respond_to_user(“할 일이 끝났으니 사용자에게 답하라”)를 더한 101개 선택지 위의choice질문이다.done: “요청된 모든 행동이 이미actions_taken에 들어 있는가"를 묻는noul질문이다.
분류기에는 eve 메시지 이력에서 뽑은 JSON 하나를 넘긴다. 여기에는 사용자 요청 원문, 지금까지 호출한 도구와 인자, 600자로 자른 실행 결과, 어시스턴트 발화가 들어 있다.
라우터는 완료 게이트를 하나 더 거친다. Jev가 respond_to_user를 골라도 done 확률이 임계값(기본 0.5)에 못 미치면, 라우터는 사용자 답변을 보류하고 차순위 도구를 노출한다. 결정마다 선택 도구와 신뢰도, done 값, 상위 5개 후보, 지연 시간, 게이트 발동 여부를 JSONL 한 줄로 남긴다. 이 기록은 대시보드 타임라인에 그대로 나타난다.
저자가 여러 번 강조하는 설계 원칙이 하나 있다. 도구 설명문이 LLM 프롬프트와 Jev의 choice 판단 기준 양쪽에 같은 텍스트로 들어간다는 것이다. 설명의 출처를 하나로 유지하면 두 모드는 “누가 고르는가"를 제외하고 완전히 같아진다.
도구 100개와 과제 6개

카탈로그는 13개 범주로 이루어져 있다. 캘린더와 금융은 각 12개, 여행은 11개, 이메일은 10개다. 스마트홈은 8개, 태스크와 쇼핑은 각 7개다. 연락처, 노트, 메시징, 정보는 각 6개이며, 리마인더와 건강은 각각 5개와 4개다. 목 월드는 결정론적이라 모든 실행이 같은 캘린더와 연락처와 항공편과 지출 내역을 본다.
저자는 이름이 비슷한 도구 쌍 12개를 이 카탈로그에 의도적으로 넣었다. flights_hold와 flights_book, email_send와 email_send_later와 email_draft, transfer_money와 transfer_money_scheduled, task_create와 task_create_subtask, reminder_create와 reminder_create_location, expenses_summary와 expenses_summary_by_merchant 같은 짝이다. 이 중 엉뚱한 쪽을 부르면 보고서에 “오답 도구"로 기록된다.
과제는 기본 3개와 복합 3개로 모두 6개다. 프롬프트는 포르투갈어로 전달된다. 벤치마크 페르소나가 리우와 상파울루를 오가며 헤알과 PIX를 쓰는 브라질 사용자이고, 저장소에 들어 있는 결과도 그 원문 그대로 만들었다. 영어 번역은 대시보드 표시용으로만 따로 들어 있다.
| id | 요청 내용 | 난이도 | 이상 경로 |
|---|---|---|---|
| p1-marina | 내일 오전 마리나와 회의가 있는지 확인하고, 있으면 확인 메일을 보낸 뒤 30분 전 리마인더를 만든다 | 기본 | 3 |
| p2-voo-sp | 금요일 14시 상파울루 회의에 맞춰 리우발 오전 최저가 항공편을 예약하고 캘린더에 넣는다 | 기본 | 3 |
| p3-orcamento | 이번 달 식당 지출을 조회해 800헤알을 넘었으면 예산 점검 태스크를 만들고 요약을 메시지로 보낸다 | 기본 | 3 |
| p4-viagem-completa | 최저가 오전 항공편을 결제 없이 홀드하고, 회의 장소 2km 이내 1박 500헤알 이하 호텔을 예약하고, 금요일 8시부터 18시까지 캘린더를 차단하고, 마리나에게 메시지를 보낸다 | 복합 | 6 |
| p5-reuniao-time | 내일 오후 빈 시간을 찾아 45분 회의를 잡고 두 사람에게 초대를 보낸 뒤, 기존 태스크 안에 서브태스크를 만들고, 내일 8시 발송 예약 메일을 건다 | 복합 | 7 |
| p6-financas | 식당별 지출을 뽑아 상위 3곳으로 체크리스트 노트를 만들고, 25일자 PIX 이체를 예약하고, 귀가 시 알림을 거는 위치 리마인더를 만든다 | 복합 | 4 |
각 과제에는 조건문이나 순서 제약이 하나씩 들어 있다. p2에는 더 싼 오후 항공편이 함정으로 놓여 있고, p3의 실제 식당 지출은 942.50헤알이라 조건 분기가 반드시 발동한다.
채점에는 LLM 저지를 쓰지 않았다. 모든 지표는 이벤트 스트림에서 기계적으로 계산한다. 지표는 모델 호출 수, 도구 호출 수, 여분 호출 수, 오답 도구 호출 수, 이행률, 효율, 토큰 사용량, OpenRouter 공개가를 기준으로 계산한 추정 비용, 추론 문자 수, 소요 시간이다. 이행률은 요구 단계 중 실제로 이행한 비율이다. 효율은 이행률에 이상 호출 수를 실제 호출 수로 나눈 값을 곱해 구하고, 오답 도구를 호출했으면 그 값을 절반으로 낮춘다.
저장소에 버전 관리되어 들어 있는 결과는 모델 7종에 모드 2개와 과제 6개를 곱한 84회 실행분이다. README는 프리셋 8종을 소개하지만 gpt-5.6-sol은 결과에 아직 없고, 저자도 로드맵에 추가 실행 항목으로 적어 두었다.
입력 토큰은 85% 줄고 모델 호출은 32% 늘었다

84회 실행을 두 모드로 합산하면 이렇게 된다.
| 지표 | llm-direct | jev-classifier | 변화 |
|---|---|---|---|
| 입력 토큰 | 1,803,493 | 269,289 | 85.1% 감소 |
| 모델 단계당 입력 토큰 | 11,487 | 1,295 | 88.7% 감소 |
| 출력 토큰 | 40,002 | 29,186 | 27.0% 감소 |
| 추론 문자 | 37,778 | 4,606 | 87.8% 감소 |
| 추정 비용 | 8.07달러 | 1.52달러 | 81.2% 절감 |
| 모델 호출 | 157 | 208 | 32.5% 증가 |
| 도구 호출 | 202 | 165 | 18.3% 감소 |
| 여분 도구 호출 | 22 | 4 | 18건 감소 |
| 오답 도구 호출 | 0 | 1 | 1건 증가 |
| 이행률 평균 | 0.984 | 0.921 | 6.3%p 하락 |
| 효율 평균 | 0.895 | 0.893 | 거의 동률 |
| 이상 경로 완주 | 42회 중 24회 | 42회 중 27회 | 3회 증가 |
| 총 소요 시간 | 839초 | 780초 | 7.0% 단축 |
가장 큰 숫자는 단계당 입력 토큰이다. 직접 모드에서는 모델이 매 단계 도구 100개의 정의를 통째로 다시 받으므로 한 호출에 평균 11,487토큰이 들어간다. 분류기 모드에서는 도구 하나만 노출되므로 같은 값이 1,295토큰으로 내려간다. 카탈로그에 도구를 더 넣을수록 이 격차는 커진다.
모델 호출이 늘어난 까닭 역시 이 설계에 있다. 직접 모드의 모델은 한 번의 응답에서 도구를 여러 개 동시에 부를 수 있어 호출당 평균 1.29개를 처리한다. 분류기 모드는 한 단계에 도구를 하나만 노출하므로 호출당 0.79개에 그치고, 마지막에 답변을 쓰는 단계가 하나 더 붙는다.
한편 총 소요 시간은 분류기 모드가 도리어 7% 짧았다. Jev 결정이 매 단계에 하나씩 추가되는데도 그렇다. 기록된 338건의 Jev 결정은 평균 439밀리초가 걸렸고, 중앙값은 338밀리초, 90분위수는 746밀리초, 최대값은 1,303밀리초였다. 모델 추론을 껐을 때 절약되는 시간이 분류기 호출에 드는 시간보다 컸던 셈이다.
모델별 수치
| 모델 | 입력 토큰(직접) | 입력 토큰(Jev) | 감소 | 비용(직접) | 비용(Jev) | 이행률(직접에서 Jev로) |
|---|---|---|---|---|---|---|
| Qwen 3.8 27B | 322,670 | 38,499 | 88.1% | 0.095달러 | 0.015달러 | 1.00에서 0.92 |
| Claude Fable 5.1 | 355,097 | 44,071 | 87.6% | 3.837달러 | 0.674달러 | 1.00에서 0.86 |
| Claude Opus 5 | 372,853 | 49,467 | 86.7% | 1.987달러 | 0.392달러 | 1.00에서 0.92 |
| DeepSeek V4.1 Flash | 262,215 | 36,094 | 86.2% | 0.085달러 | 0.016달러 | 1.00에서 0.88 |
| GPT-6 Astra | 173,081 | 25,002 | 85.6% | 1.847달러 | 0.349달러 | 1.00에서 0.97 |
| Gemini 3.8 Flash | 214,543 | 50,348 | 76.5% | 0.191달러 | 0.067달러 | 1.00에서 0.97 |
| GPT-5.6 Luna | 103,034 | 25,808 | 75.0% | 0.024달러 | 0.008달러 | 0.89에서 0.93 |
감소폭이 가장 작은 두 모델은 Gemini 3.8 Flash와 GPT-5.6 Luna다. Gemini는 OpenRouter에서 추론을 아예 끌 수 없어 분류기 모드에서도 low로 켜 두어야 했다. GPT-5.6 Luna는 직접 모드에서부터 입력 토큰을 가장 적게 쓰던 모델이라 줄일 여지가 처음부터 좁았다.
이행률은 GPT-5.6 Luna만 예외로 올라갔다. 이 모델은 직접 모드에서 p2 항공편 과제의 요구 단계 3개 중 1개만 이행하고 항공편 검색에서 멈췄는데, 분류기 모드에서는 3개를 모두 이행했다. 과제별로 보면 p2는 7개 모델 평균 이행률이 0.905에서 1.000으로 올랐고, 반대로 p5는 1.000에서 0.738로 떨어졌다.
분류기가 실패하는 세 가지 양상

저자는 발표 자료에서 실패 양상을 세 가지로 정리해 두었다.
먼저 LLM이 인자를 지어낸다. p5에서 LLM은 참석자 이메일 주소를 기억에서 채워 넣는다. 그러면 회의 생성이 일단 성공하고, Jev는 actions_taken만 보므로 연락처를 조회할 이유를 발견하지 못한다. 실제로 7개 모델 중 6개가 p5에서 연락처 조회 단계를 건너뛰고 6개 요구 단계 중 5개만 이행했다. 직접 모드에서는 같은 과제의 이행률이 7개 모델 모두 1.000이었다.
p5에서 가장 낮은 점수를 받은 모델은 Claude Fable 5.1이다. 6개 요구 단계 중 1개만 이행했고 효율은 0.167로 전체 최저였다. 그런데 기록을 열어 보면 실패 경위가 이렇다. Fable은 빈 시간을 찾은 뒤 “페드로와 아나의 이메일 주소를 지금 조회할 수 없고, 지어낸 주소로 초대를 보내고 싶지는 않다"고 답하며 사용자에게 주소를 되물었다. Jev는 그 다음 두 단계에서도 calendar_create_meeting만 다시 골랐고 contacts_search는 끝내 한 번도 노출하지 않았다. 주소를 지어내기를 거부한 모델이 이 벤치마크에서 가장 낮은 점수를 받았다.
다음으로 분류기는 답을 너무 일찍 내놓으려 한다. 완료 게이트가 없으면 남은 단계를 두고도 respond_to_user가 이긴다. done 확률을 묻는 noul 질문이 이를 막으며, 기록된 결정에서 게이트는 5회 발동했다.
마지막으로 분류기 자신도 닮은 이름을 헷갈린다. DeepSeek V4.1 Flash의 p6 실행에서 Jev는 task_create_subtask 대신 task_create를 골랐다. 84회 실행을 통틀어 유일한 오답 도구 호출이다.
같은 양상이 p1에서도 나타났다. 7개 모델 중 3개가 리마인더 생성 단계를 놓쳤다. Claude Opus 5의 최종 답변에는 “9시 30분 리마인더를 만들지 못했다. 리마인더 도구를 지금 쓸 수 없었고 이메일 발송에만 접근할 수 있었다"고 적혀 있다. 그 단계에서 Jev는 리마인더 도구를 노출하지 않았다. 모델은 그것을 도구가 없는 상태로 받아들였다.
저자가 권하는 조합은 세 가지다. 답변 직전의 완료 게이트, 신뢰도가 임계값 아래로 내려가면 선택권을 LLM에게 되돌리는 라우팅, 그리고 수신자를 지정해야 하는 행동에는 사전 조회 단계를 강제하는 규칙이다. 다음 단계로는 범주를 먼저 고르고 도구를 고르는 계층 라우팅, 닫힌 집합 인자도 Jev로 채우는 방식, 그리고 과제당 시드를 늘린 재실행을 적어 두었다.
출발 가설과 다른 관찰
저자가 자기 실험의 출발 가설이 틀렸다고 발표 자료에 그대로 적어 둔 부분이다. 이름이 닮은 도구 쌍 12개를 심어 둔 이유는 도구 100개가 프롬프트에 함께 들어가면 LLM이 형제 도구를 헷갈릴 것이라는 예상 때문이었다. 그런데 직접 모드 42회 실행에서 오답 도구를 부른 모델은 하나도 없었다. 저자의 정리는 이렇다.
지금 카탈로그 상태로는 직접 모드에서 닮은 이름에 걸린 모델이 없었다. LLM이 이름 때문에 길을 잃는다는 가설은 여기서 확인되지 않았다. Jev의 이득은 정확도보다 비용과 단계 규율 쪽에서 나온다.
효율 지표도 0.895와 0.893으로 거의 같게 나왔다. 두 모드에서 뚜렷하게 달라진 수치는 비용뿐이었다.
분류기 모드에서는 도구 정의를 빼는 변화와 모델 추론을 끄는 변화가 함께 적용됐다. 이 수치만으로는 각 변화가 절감에 기여한 정도를 구분할 수 없다. 그래도 추론은 출력 토큰 쪽에서 계산되고 출력 토큰 감소는 27%에 그친 반면 입력 토큰은 85% 줄었으므로, 큰 몫은 카탈로그를 뺀 데서 나왔다고 보는 편이 자연스럽다.
표본 크기도 함께 감안해야 한다. 과제당 실행은 1회씩이고 모델은 7종이며 도구는 전부 목이라 실행 실패가 한 건도 없었다. 84회 실행에서 실패한 도구 호출은 0건이다. 현실의 에이전트가 도구 오류에서 회복하는 능력은 이 벤치마크가 아직 측정하지 못한다.
그럼에도 저장소가 결과 JSON과 분류기 결정 로그를 통째로 버전 관리해 두어서, API 키 없이 저장소만 받아도 대시보드와 발표 자료가 저자의 숫자 그대로 열린다. 위의 표는 전부 그 파일들을 직접 집계해서 만든 것이다.
출처
Vinicius Lana(AI Coders Academy), 2026년 9월 17일 공개. 이 글의 수치는 2026년 9월 18일 시점 main 브랜치의 eval-results/ 파일을 직접 집계했다.
원문: https://github.com/vinilana/jev-eval-agent
본문 삽화는 블로그 글 「느낌적인 느낌을 숫자로 옮기는 일」의 치비 서소영 라인아트를 참조하여 gpt-image-2.5-flare image-to-image로 생성했다.
