dev.to

Count It or Compute It: When a Tool Returns Rows, the Models That Count Them Right Spend the Tokens

세어 줄까, 직접 셀까: 도구가 행을 반환할 때 정확히 세는 모델은 토큰을 더 씁니다

Kaggle 벤치마크에서 모델 10종에 같은 집계 질문을 던지고, 도구가 정답 숫자와 데이터 행 중 무엇을 반환하는지 비교했습니다. 행을 직접 세게 하자 모델 간 정확도 차이가 컸고, 도구가 집계를 맡으면 대부분의 모델이 더 적은 토큰으로 정답을 냈습니다.

AI 요약

에이전트가 검색·데이터베이스·API 도구에서 행 목록을 받은 뒤 개수를 묻는 상황을 대상으로 한 Kaggle 벤치마크입니다. 저자는 질문과 모델을 고정하고 도구가 정확한 개수를 반환하는지, 일치하는 ID 목록을 반환하는지만 바꿨습니다. 그 결과 목록을 모델이 직접 세게 하면 정확도와 토큰 사용량이 크게 갈렸습니다. 도구가 개수를 반환하면 대부분의 모델이 330개 ID를 대상으로 한 질문에 모두 정답을 냈습니다.

실험 구성

모델 10종에 68개 집계 질문을 제시했습니다. 목록 크기는 11개, 110개, 330개였고, 임계값 표현을 바꾼 질문과 시드별 질문을 포함했습니다. “10개 이상”, “10보다 적음”, “5에서 9까지”처럼 여러 표현을 썼으며, 모든 임계값은 목록에 실제로 들어 있는 ID로 설정했습니다. 따라서 >와 >=를 혼동하면 답이 달라집니다.

비교한 작업은 세 가지입니다. count-engine은 도구가 정확한 개수와 최솟값·최댓값을 반환합니다. count-rows-tool은 도구가 일치하는 ID 목록을 반환하고 모델이 직접 셉니다. count-python-tool은 프롬프트에 ID를 모두 넣고, 모델이 이미 정의된 with_ids를 활용해 Python을 실행할 수 있게 합니다. 첫 두 작업에서는 ID가 프롬프트에 나타나지 않으므로, 도구가 숫자를 돌려주는지 목록을 돌려주는지가 차이의 전부입니다. 모델이 보낸 필터도 검사해 잘못된 필터와 잘못된 계산을 구분했습니다.

목록을 직접 세게 했을 때

330개 ID 질문 21개에서 Gemma 4 26B A4B는 20개, Gemini 3.7 Flash는 20개, Gemini 3.8 Flash는 21개를 맞혔습니다. 이 모델들은 질문마다 출력 토큰을 각각 평균 8,153개, 2,785개, 2,742개 썼습니다. 반면 GPT-5.4 nano와 Gemini 2.5 Flash는 각각 0개를 맞혔고, Claude Opus 5는 9개를 맞혔습니다. 이들의 질문당 출력 토큰은 각각 35개, 580개, 579개였습니다. Claude Opus 5는 비교군에서 가장 비싼 모델이었지만 Gemma 4 26B보다 적은 토큰을 쓰고 정답도 적었습니다.

저자는 11개 ID만 놓고 보면 차이가 잘 드러나지 않는다고 설명합니다. “0, 2, 3, 20, 21, 22, 23, 10, 11, 12, 13” 중 10 이상인 수를 세는 질문에는 모든 모델이 정답 8을 냈습니다. 하지만 작은 목록에서의 성공이 330개 목록에서도 이어지지는 않았습니다. 11개 ID 질문 26개에서는 모델 10종 중 8종이 모두 맞혔지만, 330개 질문에서는 그중 다섯 모델이 21개 중 10개 이하만 맞혔습니다.

토큰 사용량과 정확도

목록을 정확히 센 모델은 목록이 커질수록 출력 토큰을 더 쓰는 경향을 보였습니다. Gemma 4 26B는 11개 ID 질문에서 평균 394개 토큰을 썼고, 330개 질문에서는 8,153개를 썼습니다. 반대로 오답이 많은 모델은 목록 크기가 달라져도 토큰 사용량이 거의 그대로였습니다. GPT-5.4 nano는 11개, 110개, 330개 목록에서 모두 질문당 35개 토큰을 썼습니다. 저자는 같은 모델의 여러 실행에서도 모델들이 토큰을 많이 쓰는 그룹과 적게 쓰는 그룹으로 나뉘었다고 보고합니다. 모델 크기나 가격으로 그룹을 예측하지는 못했습니다.

도구가 개수를 반환한 작업에서는 gpt-oss-20b를 제외한 모든 모델이 330개 ID 질문 21개를 모두 맞혔습니다. 각 모델의 질문당 토큰은 35~451개였습니다. gpt-oss-20b는 도구가 준 숫자와 다른 값을 다섯 차례 답했으며, 그 값은 0, 1, 2였습니다. 목록 도구 작업의 오답은 잘못된 필터가 아니라 모델의 계산 실수에서 나왔습니다. 세 차례는 도구를 호출하지 않았고, 한 답은 숫자로 읽을 수 없었습니다.

Python 도구 작업에서는 모델 10종 중 7종이 68개 질문을 모두 맞혔습니다. 다만 모델이 도구를 호출하고 결과를 출력한 뒤 그 값을 답에 옮겨야 했습니다. Gemini 2.5 Flash는 110개와 330개 목록에 관한 질문 42개 중 한 번만 도구를 호출했고, 전체 점수는 37점이었습니다.

저자의 제안과 재현 방법

저자는 개수를 세는 작업을 모델에 맡기지 말고 도구가 처리하라고 제안합니다. 집계 도구가 개수와 최솟값·최댓값을 반환하면 비교 모델들이 적은 토큰으로 대부분의 질문에 정확히 답했습니다. 반대로 행 목록을 반환하면 정확한 모델도 집계 도구보다 5~19배 많은 토큰을 썼습니다. 후속으로는 reasoning 설정을 켜고 끈 같은 모델 비교, 합계·평균·최댓값 계산, 더 복잡한 필터 실험을 제안합니다.

벤치마크 코드와 질문 생성기는 GitHub 저장소 xbill9/devto-kaggle에 공개했습니다. Kaggle CLI와 Python 3을 준비한 뒤 저장소를 복제합니다. python3 tasks/check.py를 실행하면 모델 호출 없이 68개 질문과 목록 크기별 구성을 검사합니다. 각 작업 파일을 Kaggle에 푸시하고 모델별 실행 결과를 내려받은 다음 python3 tasks/report.py results로 표를 다시 만들 수 있습니다. 글은 Kaggle 프록시가 출력 토큰 제한에 따라 호출 비용을 미리 예약하며, 일일 할당량이 부족하면 호출을 거부할 수 있다는 점도 안내합니다.

dev.to 반응

  • @reidmarlow — reasoning 모델에서 토큰이 14~18배 더 드는 결과는 단순한 도구 스키마가 감추는 비용을 가장 분명하게 보여줍니다. 개발자가 REST나 데이터베이스 엔드포인트를 MCP 도구로 감쌀 때 원시 목록을 그대로 내보내는 경우가 많습니다. 유연해 보이기 때문입니다. 하지만 집계를 모델에 맡기면 출력 예산이 빠듯할 때 십 단위 계산을 틀리는 데 그치지 않습니다. 330개 ID가 대화 기록에 들어가면 뒤이은 모든 대화에서 그 토큰에 대한 컨텍스트 캐시와 지연 비용도 발생합니다. 구조화한 개수와 작은 앞부분 샘플을 함께 반환하거나, 목록 조회와 집계 도구를 분리하면 실행 비용을 일정하게 유지하고 대화 기록이 불어나는 일도 막을 수 있습니다.
  • @dexoryn — 330개 ID 결과를 보면 도구 설계에 관한 교훈을 외면하기 어렵습니다. 도구가 이미 개수를 알고 있는데 모델에게 수백 개 행을 다시 세게 하는 일은 더 비싸고 신뢰도도 낮습니다. LLM에게 결정론적인 작업을 맡기기보다 집계 결과를 바로 반환하는 편이 에이전트 구조에 훨씬 적합해 보입니다.

원문: dev.to / 번역·요약: Trawling