Hacker News

Fixing Tool-Call Accuracy in vLLM

vLLM의 도구 호출 정확도 개선

Ubicloud는 Kimi K2.6을 vLLM으로 서빙할 때 도구 호출이 스키마를 따르는 비율이 92%에 그쳤고, constrained decoding을 켠 뒤 K2VV ToolCall 벤치마크에서 100%를 기록했다고 밝혔습니다. 이 방식은 형식 오류를 막지만 모델 출력의 의미나 전체 품질까지 보장하지는 않습니다.

에디터 노트

스키마 정확도 100%는 도구 호출 형식이 실행기에 전달될 수 있다는 보장이지, 올바른 도구를 고르거나 적절한 인자를 만들고 작업을 성공시킨다는 보장은 아닙니다. 글의 수치는 K2VV ToolCall에서 Kimi와 DeepSeek을 평가한 결과이며 전체 에이전트 품질을 재시도 방식과 비교한 값은 아닙니다. 댓글에서도 constrained decoding이 출력 분포를 바꿀 수 있어 긴 호출을 다시 생성하는 방식과 비교해야 한다는 질문이 나왔습니다. Ubicloud는 제공사 권장 동작을 재현하는 데 초점을 뒀다고 답했고, vLLM 설정 변경이 정확도 회귀의 원인이었다는 점은 구체적으로 설명했습니다. 따라서 이번 결과가 뒷받침하는 주장은 해당 모델과 설정에서 형식 오류를 없앴다는 데까지입니다.

AI 요약

Ubicloud는 open-weight 모델을 직접 서빙할 때 벤치마크 점수에 못 미치는 결과를 경험했습니다. 특히 여러 차례 도구 호출을 이어가는 에이전트 작업에서는 잘못된 호출이 오류 메시지와 불필요한 문맥을 쌓고 재시도를 유발해 품질과 비용에 영향을 줍니다. Kimi K2.6을 vLLM 0.28로 서빙한 사례에서는 도구 호출 스키마 정확도가 92%였습니다. 호출 25건 중 약 2건이 스키마를 따르지 않았다는 뜻입니다.

도구 호출 스키마와 정확도

에이전트 실행기는 모델에 사용 가능한 도구와 각 도구의 입력 스키마를 전달합니다. 모델이 도구를 호출하면 추론 서버가 모델별 토큰 형식을 JSON 도구 호출로 파싱하고, OpenCode 같은 실행기가 실제 도구를 실행한 뒤 결과를 모델에 돌려줍니다. 도구 이름과 인자 등이 스키마에 맞아야 실행기가 호출을 처리할 수 있습니다.

모델은 다음 토큰을 확률적으로 생성하므로 스키마를 지키지 못할 수 있습니다. 학습 중 접한 도구 이름이나 필드 이름을 현재 환경의 이름 대신 내놓는 경우가 한 예입니다. 가령 현재 도구 이름은 web_search인데 search_web을 출력하거나, location 필드 대신 city_name을 출력할 수 있습니다. 이런 오류는 도구 호출 실패로 이어집니다.

Ubicloud가 사용한 K2VV ToolCall은 2,000개 요청으로 구성됩니다. 도구를 호출할지 결정하는 양상이 Moonshot AI의 서비스와 얼마나 비슷한지 측정하는 trigger similarity와, 생성한 호출이 스키마를 따르는 비율인 schema accuracy를 평가합니다. 후자는 호출이 실제로 실행 가능한 형식인지 나타냅니다.

Constrained decoding 적용

Constrained decoding은 스키마에 맞지 않는 토큰을 생성 단계에서 제외합니다. vLLM은 XGrammar의 구조 태그를 사용해 호출 시작, 도구 이름, 호출 인덱스, 인자 시작, 스키마에 맞는 JSON, 호출 종료 순서로 생성을 제한합니다. 각 단계에서 허용되는 토큰만 선택하게 하므로 생성 뒤 결과를 검사하는 방식과 달리 형식 오류를 런타임에 막습니다. 글은 토큰 마스크를 미리 계산하고 GPU에서 적용해 성능 부담을 낮춘다고 설명합니다.

Moonshot AI는 Kimi에서 constrained decoding을 켜도록 권장하며 자사 API도 이 방식을 사용합니다. Ubicloud는 처음 자체 vLLM 포크에 기능을 넣었고, vLLM이 기능을 지원한 뒤에는 업스트림 구현으로 옮겼습니다. 그러나 이후 정확도가 91%로 다시 떨어졌습니다. 조사 결과 constrained decoding 구현 자체가 틀린 것이 아니라, 사용자가 명시적으로 켜지 않은 요청에서 vLLM의 기본 동작이 바뀐 점이 원인이었습니다. 여러 모델을 지원하는 vLLM은 모델별 호환성 문제를 고려해 기능을 기본값으로 켜지 않았고, 이후 사용자가 엄격한 도구 호출 설정을 지정하도록 --tool-strict-level 플래그를 추가했습니다. Ubicloud는 해당 설정을 켜 Kimi와 DeepSeek 모델을 다시 평가했고, 제공 중인 모델 버전 모두에서 스키마 정확도 100%를 확인한 뒤 배포했다고 밝혔습니다.

Hacker News 반응

  • @jesdo — 모델과 추론·서빙 엔진, constrained decoding 구현을 의도한 출력과 전체 품질이 나오도록 통합하려면 세심한 엔지니어링과 테스트가 필요합니다.
  • @Aurornis — vLLM에는 constrained decoding과 도구 호출 스키마 제한 기능이 이미 있었기 때문에 제목만 보면 vLLM 자체를 고친 것처럼 읽힐 수 있습니다. 실제 문제는 설정과 기본 동작이 시기별로 달라진 점이며, Ubicloud가 벤치마크로 회귀를 찾아낸 점은 높이 평가합니다.
    • @jesdo — 대체로 맞는 설명입니다. Kimi에서 올바르게 동작시키려면 당시에는 코드 변경이 필요했고 설정만으로 해결할 수 없었습니다. 이후 업스트림에서 수정했으며 최신 vLLM에서는 --tool-strict-level parameter 설정으로 대응할 수 있습니다.
  • @hansvm — 스키마에 맞춰 생성하면 모델이 내놓는 토큰 분포가 바뀝니다. 실패한 호출을 다시 시도하는 방식과 실제 품질을 비교한 자료가 있으면 좋겠습니다. 재시도는 토큰을 더 쓰지만 전체 생성 비용에서 차지하는 비중은 작을 수 있습니다.
    • @jesdo — 이번 글은 전체 시스템의 품질보다 자사 서빙 결과가 Kimi 제공사의 동작과 얼마나 일치하는지에 초점을 맞췄습니다. Moonshot AI가 constrained decoding을 권장하고 자사 서비스에서 사용한다는 점은 전체 성능에도 도움이 된다는 뜻으로 볼 수 있지만, 이를 뒷받침하는 수치는 제시하지 않았습니다.
  • @NitpickLawyer — constrained decoding은 문법에 허용된 토큰만 출력하게 합니다. 도구 이름과 인자를 제한할 수 있지만 의미가 올바른지는 보장하지 않습니다. 문법을 이용해 정해진 형식의 계획을 만들 수도 있지만 각 항목이 말이 되는지는 별개의 문제입니다.
  • @Majromax — 코드 생성에도 문법 제약을 적용할 수 있지만 처음 생각하는 것만큼 유용하지 않을 수 있습니다. 문법 오류가 뒤늦게 드러나는 경우가 있고, 모델이 원래 생성하려던 토큰을 강제로 바꾸면 이후 출력의 의미가 나빠질 수 있습니다.
  • @draxen — 한 번의 프롬프트에서 도구 호출 약 300건이 필요한 작업을 한다며, 도구 호출 정확도와 프롬프트 캐싱을 제대로 지원하는 업체가 필요하다고 말했습니다.
  • @bob1029 — 호출 하나의 성공률이 높아도 순차 호출이 많으면 전체 작업 성공률은 크게 낮아질 수 있다고 지적했습니다. 오류 피드백으로 복구할 수 있지만 모델이 계속 잘못된 도구와 인자를 쓰면 작업이 제대로 작동하지 않을 수 있습니다.
  • @docjay — 모델이 search_web을 찾는다면 도구 이름을 그에 맞게 바꾸는 편이 문제를 해결할 수도 있다고 주장했습니다.

원문: Ubicloud / 번역·요약: Trawling